Coverage Report

Created: 2026-03-19 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/x_x509a.cc
Line
Count
Source
1
// Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <stdio.h>
16
17
#include <openssl/asn1.h>
18
#include <openssl/asn1t.h>
19
#include <openssl/evp.h>
20
#include <openssl/obj.h>
21
#include <openssl/x509.h>
22
23
#include "../internal.h"
24
#include "internal.h"
25
26
27
// X509_CERT_AUX routines. These are used to encode additional user
28
// modifiable data about a certificate. This data is appended to the X509
29
// encoding when the *_X509_AUX routines are used. This means that the
30
// "traditional" X509 routines will simply ignore the extra data.
31
32
using namespace bssl;
33
34
BSSL_NAMESPACE_BEGIN
35
36
ASN1_SEQUENCE(X509_CERT_AUX) = {
37
    ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
38
    ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
39
    ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
40
    ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
41
} ASN1_SEQUENCE_END(X509_CERT_AUX)
42
43
IMPLEMENT_ASN1_FUNCTIONS_const(X509_CERT_AUX)
44
45
BSSL_NAMESPACE_END
46
47
1
static X509_CERT_AUX *aux_get(X509Impl *x) {
48
1
  if (!x) {
49
0
    return nullptr;
50
0
  }
51
1
  if (!x->aux && !(x->aux = X509_CERT_AUX_new())) {
52
0
    return nullptr;
53
0
  }
54
1
  return x->aux;
55
1
}
56
57
1
int X509_alias_set1(X509 *x, const uint8_t *name, ossl_ssize_t len) {
58
1
  auto *impl = FromOpaque(x);
59
1
  X509_CERT_AUX *aux;
60
  // TODO(davidben): Empty aliases are not meaningful in PKCS#12, and the
61
  // getters cannot quite represent them. Also erase the object if |len| is
62
  // zero.
63
1
  if (!name) {
64
0
    if (!impl || !impl->aux || !impl->aux->alias) {
65
0
      return 1;
66
0
    }
67
0
    ASN1_UTF8STRING_free(impl->aux->alias);
68
0
    impl->aux->alias = nullptr;
69
0
    return 1;
70
0
  }
71
1
  if (!(aux = aux_get(impl))) {
72
0
    return 0;
73
0
  }
74
1
  if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) {
75
0
    return 0;
76
0
  }
77
1
  return ASN1_STRING_set(aux->alias, name, len);
78
1
}
79
80
0
int X509_keyid_set1(X509 *x, const uint8_t *id, ossl_ssize_t len) {
81
0
  auto *impl = FromOpaque(x);
82
0
  X509_CERT_AUX *aux;
83
  // TODO(davidben): Empty key IDs are not meaningful in PKCS#12, and the
84
  // getters cannot quite represent them. Also erase the object if |len| is
85
  // zero.
86
0
  if (!id) {
87
0
    if (!impl || !impl->aux || !impl->aux->keyid) {
88
0
      return 1;
89
0
    }
90
0
    ASN1_OCTET_STRING_free(impl->aux->keyid);
91
0
    impl->aux->keyid = nullptr;
92
0
    return 1;
93
0
  }
94
0
  if (!(aux = aux_get(impl))) {
95
0
    return 0;
96
0
  }
97
0
  if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) {
98
0
    return 0;
99
0
  }
100
0
  return ASN1_STRING_set(aux->keyid, id, len);
101
0
}
102
103
0
const uint8_t *X509_alias_get0(const X509 *x, int *out_len) {
104
0
  auto *impl = FromOpaque(x);
105
0
  const ASN1_UTF8STRING *alias =
106
0
      impl->aux != nullptr ? impl->aux->alias : nullptr;
107
0
  if (out_len != nullptr) {
108
0
    *out_len = alias != nullptr ? alias->length : 0;
109
0
  }
110
0
  return alias != nullptr ? alias->data : nullptr;
111
0
}
112
113
0
const uint8_t *X509_keyid_get0(const X509 *x, int *out_len) {
114
0
  auto *impl = FromOpaque(x);
115
0
  const ASN1_OCTET_STRING *keyid =
116
0
      impl->aux != nullptr ? impl->aux->keyid : nullptr;
117
0
  if (out_len != nullptr) {
118
0
    *out_len = keyid != nullptr ? keyid->length : 0;
119
0
  }
120
0
  return keyid != nullptr ? keyid->data : nullptr;
121
0
}
122
123
0
int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj) {
124
0
  auto *impl = FromOpaque(x);
125
0
  UniquePtr<ASN1_OBJECT> objtmp(OBJ_dup(obj));
126
0
  if (objtmp == nullptr) {
127
0
    return 0;
128
0
  }
129
0
  X509_CERT_AUX *aux = aux_get(impl);
130
0
  if (aux->trust == nullptr) {
131
0
    aux->trust = sk_ASN1_OBJECT_new_null();
132
0
    if (aux->trust == nullptr) {
133
0
      return 0;
134
0
    }
135
0
  }
136
0
  return PushToStack(aux->trust, std::move(objtmp));
137
0
}
138
139
0
int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj) {
140
0
  auto *impl = FromOpaque(x);
141
0
  UniquePtr<ASN1_OBJECT> objtmp(OBJ_dup(obj));
142
0
  if (objtmp == nullptr) {
143
0
    return 0;
144
0
  }
145
0
  X509_CERT_AUX *aux = aux_get(impl);
146
0
  if (aux->reject == nullptr) {
147
0
    aux->reject = sk_ASN1_OBJECT_new_null();
148
0
    if (aux->reject == nullptr) {
149
0
      return 0;
150
0
    }
151
0
  }
152
0
  return PushToStack(aux->reject, std::move(objtmp));
153
0
}
154
155
0
void X509_trust_clear(X509 *x) {
156
0
  auto *impl = FromOpaque(x);
157
0
  if (impl->aux && impl->aux->trust) {
158
0
    sk_ASN1_OBJECT_pop_free(impl->aux->trust, ASN1_OBJECT_free);
159
0
    impl->aux->trust = nullptr;
160
0
  }
161
0
}
162
163
0
void X509_reject_clear(X509 *x) {
164
0
  auto *impl = FromOpaque(x);
165
0
  if (impl->aux && impl->aux->reject) {
166
0
    sk_ASN1_OBJECT_pop_free(impl->aux->reject, ASN1_OBJECT_free);
167
0
    impl->aux->reject = nullptr;
168
0
  }
169
0
}