/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 | } |