/src/boringssl/crypto/x509/v3_info.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 | | #include <string.h> |
17 | | |
18 | | #include <openssl/asn1.h> |
19 | | #include <openssl/asn1t.h> |
20 | | #include <openssl/conf.h> |
21 | | #include <openssl/err.h> |
22 | | #include <openssl/mem.h> |
23 | | #include <openssl/obj.h> |
24 | | #include <openssl/x509.h> |
25 | | |
26 | | #include "internal.h" |
27 | | |
28 | | |
29 | | using namespace bssl; |
30 | | |
31 | | static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( |
32 | | const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret); |
33 | | static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method, |
34 | | const X509V3_CTX *ctx, |
35 | | const STACK_OF(CONF_VALUE) *nval); |
36 | | |
37 | | const X509V3_EXT_METHOD bssl::v3_info = { |
38 | | NID_info_access, |
39 | | X509V3_EXT_MULTILINE, |
40 | | ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), |
41 | | nullptr, |
42 | | nullptr, |
43 | | nullptr, |
44 | | nullptr, |
45 | | nullptr, |
46 | | nullptr, |
47 | | i2v_AUTHORITY_INFO_ACCESS, |
48 | | v2i_AUTHORITY_INFO_ACCESS, |
49 | | nullptr, |
50 | | nullptr, |
51 | | nullptr, |
52 | | }; |
53 | | |
54 | | const X509V3_EXT_METHOD bssl::v3_sinfo = { |
55 | | NID_sinfo_access, |
56 | | X509V3_EXT_MULTILINE, |
57 | | ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), |
58 | | nullptr, |
59 | | nullptr, |
60 | | nullptr, |
61 | | nullptr, |
62 | | nullptr, |
63 | | nullptr, |
64 | | i2v_AUTHORITY_INFO_ACCESS, |
65 | | v2i_AUTHORITY_INFO_ACCESS, |
66 | | nullptr, |
67 | | nullptr, |
68 | | nullptr, |
69 | | }; |
70 | | |
71 | | ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { |
72 | | ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), |
73 | | ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME), |
74 | | } ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) |
75 | | |
76 | | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ACCESS_DESCRIPTION) |
77 | | |
78 | | ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = ASN1_EX_TEMPLATE_TYPE( |
79 | | ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) |
80 | | ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) |
81 | | |
82 | | IMPLEMENT_ASN1_FUNCTIONS_const(AUTHORITY_INFO_ACCESS) |
83 | | |
84 | | static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( |
85 | 46 | const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) { |
86 | 46 | const AUTHORITY_INFO_ACCESS *ainfo = |
87 | 46 | reinterpret_cast<const AUTHORITY_INFO_ACCESS *>(ext); |
88 | 46 | ACCESS_DESCRIPTION *desc; |
89 | 46 | char objtmp[80], *name; |
90 | 46 | CONF_VALUE *vtmp; |
91 | 46 | STACK_OF(CONF_VALUE) *tret = ret; |
92 | | |
93 | 98 | for (size_t i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { |
94 | 70 | STACK_OF(CONF_VALUE) *tmp; |
95 | | |
96 | 70 | desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); |
97 | 70 | tmp = i2v_GENERAL_NAME(method, desc->location, tret); |
98 | 70 | if (tmp == nullptr) { |
99 | 18 | goto err; |
100 | 18 | } |
101 | 52 | tret = tmp; |
102 | 52 | vtmp = sk_CONF_VALUE_value(tret, i); |
103 | 52 | i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); |
104 | | |
105 | 52 | if (OPENSSL_asprintf(&name, "%s - %s", objtmp, vtmp->name) == -1) { |
106 | 0 | goto err; |
107 | 0 | } |
108 | 52 | OPENSSL_free(vtmp->name); |
109 | 52 | vtmp->name = name; |
110 | 52 | } |
111 | 28 | if (ret == nullptr && tret == nullptr) { |
112 | 11 | return sk_CONF_VALUE_new_null(); |
113 | 11 | } |
114 | | |
115 | 17 | return tret; |
116 | 18 | err: |
117 | 18 | if (ret == nullptr && tret != nullptr) { |
118 | 8 | sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); |
119 | 8 | } |
120 | 18 | return nullptr; |
121 | 28 | } |
122 | | |
123 | | static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method, |
124 | | const X509V3_CTX *ctx, |
125 | 59 | const STACK_OF(CONF_VALUE) *nval) { |
126 | 59 | UniquePtr<AUTHORITY_INFO_ACCESS> ainfo(sk_ACCESS_DESCRIPTION_new_null()); |
127 | 59 | if (ainfo == nullptr) { |
128 | 0 | return nullptr; |
129 | 0 | } |
130 | 337 | for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
131 | 314 | const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); |
132 | 314 | UniquePtr<ACCESS_DESCRIPTION> acc(ACCESS_DESCRIPTION_new()); |
133 | 314 | if (acc == nullptr) { |
134 | 0 | return nullptr; |
135 | 0 | } |
136 | 314 | char *ptmp = strchr(cnf->name, ';'); |
137 | 314 | if (!ptmp) { |
138 | 19 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); |
139 | 19 | return nullptr; |
140 | 19 | } |
141 | 295 | CONF_VALUE ctmp; |
142 | 295 | ctmp.name = ptmp + 1; |
143 | 295 | ctmp.value = cnf->value; |
144 | 295 | if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) { |
145 | 9 | return nullptr; |
146 | 9 | } |
147 | 286 | UniquePtr<char> objtmp(OPENSSL_strndup(cnf->name, ptmp - cnf->name)); |
148 | 286 | if (objtmp == nullptr) { |
149 | 0 | return nullptr; |
150 | 0 | } |
151 | 286 | acc->method = OBJ_txt2obj(objtmp.get(), 0); |
152 | 286 | if (!acc->method) { |
153 | 8 | OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT); |
154 | 8 | ERR_add_error_data(2, "value=", objtmp.get()); |
155 | 8 | return nullptr; |
156 | 8 | } |
157 | 278 | if (!PushToStack(ainfo.get(), std::move(acc))) { |
158 | 0 | return nullptr; |
159 | 0 | } |
160 | 278 | } |
161 | 23 | return ainfo.release(); |
162 | 59 | } |