1 /* $OpenBSD: x509_lib.c,v 1.24 2024/07/13 15:08:58 tb Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5 /* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58 /* X509 v3 extension utilities */
59
60 #include <stdio.h>
61
62 #include <openssl/conf.h>
63 #include <openssl/err.h>
64 #include <openssl/x509v3.h>
65
66 #include "x509_local.h"
67
68 const X509V3_EXT_METHOD *
X509V3_EXT_get_nid(int nid)69 X509V3_EXT_get_nid(int nid)
70 {
71 switch (nid) {
72 case NID_authority_key_identifier:
73 return x509v3_ext_method_authority_key_identifier();
74 case NID_basic_constraints:
75 return x509v3_ext_method_basic_constraints();
76 case NID_certificate_issuer:
77 return x509v3_ext_method_certificate_issuer();
78 case NID_certificate_policies:
79 return x509v3_ext_method_certificate_policies();
80 case NID_crl_distribution_points:
81 return x509v3_ext_method_crl_distribution_points();
82 case NID_crl_number:
83 return x509v3_ext_method_crl_number();
84 case NID_crl_reason:
85 return x509v3_ext_method_crl_reason();
86 #ifndef OPENSSL_NO_CT
87 case NID_ct_cert_scts:
88 return x509v3_ext_method_ct_cert_scts();
89 case NID_ct_precert_poison:
90 return x509v3_ext_method_ct_precert_poison();
91 case NID_ct_precert_scts:
92 return x509v3_ext_method_ct_precert_scts();
93 #endif
94 case NID_delta_crl:
95 return x509v3_ext_method_delta_crl();
96 case NID_ext_key_usage:
97 return x509v3_ext_method_ext_key_usage();
98 case NID_freshest_crl:
99 return x509v3_ext_method_freshest_crl();
100 #ifndef OPENSSL_NO_OCSP
101 case NID_hold_instruction_code:
102 return x509v3_ext_method_hold_instruction_code();
103 case NID_id_pkix_OCSP_CrlID:
104 return x509v3_ext_method_id_pkix_OCSP_CrlID();
105 case NID_id_pkix_OCSP_Nonce:
106 return x509v3_ext_method_id_pkix_OCSP_Nonce();
107 case NID_id_pkix_OCSP_acceptableResponses:
108 return x509v3_ext_method_id_pkix_OCSP_acceptableResponses();
109 case NID_id_pkix_OCSP_archiveCutoff:
110 return x509v3_ext_method_id_pkix_OCSP_archiveCutoff();
111 case NID_id_pkix_OCSP_serviceLocator:
112 return x509v3_ext_method_id_pkix_OCSP_serviceLocator();
113 #endif
114 case NID_info_access:
115 return x509v3_ext_method_info_access();
116 case NID_inhibit_any_policy:
117 return x509v3_ext_method_inhibit_any_policy();
118 case NID_invalidity_date:
119 return x509v3_ext_method_invalidity_date();
120 case NID_issuer_alt_name:
121 return x509v3_ext_method_issuer_alt_name();
122 case NID_issuing_distribution_point:
123 return x509v3_ext_method_issuing_distribution_point();
124 case NID_key_usage:
125 return x509v3_ext_method_key_usage();
126 case NID_name_constraints:
127 return x509v3_ext_method_name_constraints();
128 case NID_netscape_base_url:
129 return x509v3_ext_method_netscape_base_url();
130 case NID_netscape_ca_policy_url:
131 return x509v3_ext_method_netscape_ca_policy_url();
132 case NID_netscape_ca_revocation_url:
133 return x509v3_ext_method_netscape_ca_revocation_url();
134 case NID_netscape_cert_type:
135 return x509v3_ext_method_netscape_cert_type();
136 case NID_netscape_comment:
137 return x509v3_ext_method_netscape_comment();
138 case NID_netscape_renewal_url:
139 return x509v3_ext_method_netscape_renewal_url();
140 case NID_netscape_revocation_url:
141 return x509v3_ext_method_netscape_revocation_url();
142 case NID_netscape_ssl_server_name:
143 return x509v3_ext_method_netscape_ssl_server_name();
144 case NID_policy_constraints:
145 return x509v3_ext_method_policy_constraints();
146 case NID_policy_mappings:
147 return x509v3_ext_method_policy_mappings();
148 case NID_private_key_usage_period:
149 return x509v3_ext_method_private_key_usage_period();
150 #ifndef OPENSSL_NO_RFC3779
151 case NID_sbgp_ipAddrBlock:
152 return x509v3_ext_method_sbgp_ipAddrBlock();
153 case NID_sbgp_autonomousSysNum:
154 return x509v3_ext_method_sbgp_autonomousSysNum();
155 #endif
156 case NID_sinfo_access:
157 return x509v3_ext_method_sinfo_access();
158 case NID_subject_alt_name:
159 return x509v3_ext_method_subject_alt_name();
160 case NID_subject_key_identifier:
161 return x509v3_ext_method_subject_key_identifier();
162 default:
163 return NULL;
164 }
165 };
166 LCRYPTO_ALIAS(X509V3_EXT_get_nid);
167
168 const X509V3_EXT_METHOD *
X509V3_EXT_get(X509_EXTENSION * ext)169 X509V3_EXT_get(X509_EXTENSION *ext)
170 {
171 int nid;
172
173 if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
174 return NULL;
175 return X509V3_EXT_get_nid(nid);
176 }
177 LCRYPTO_ALIAS(X509V3_EXT_get);
178
179 /* Return an extension internal structure */
180
181 void *
X509V3_EXT_d2i(X509_EXTENSION * ext)182 X509V3_EXT_d2i(X509_EXTENSION *ext)
183 {
184 const X509V3_EXT_METHOD *method;
185 const unsigned char *p;
186
187 if ((method = X509V3_EXT_get(ext)) == NULL)
188 return NULL;
189 p = ext->value->data;
190 if (method->it != NULL)
191 return ASN1_item_d2i(NULL, &p, ext->value->length, method->it);
192 return method->d2i(NULL, &p, ext->value->length);
193 }
194 LCRYPTO_ALIAS(X509V3_EXT_d2i);
195
196 /*
197 * This API is only safe to call with known nid, crit != NULL and idx == NULL.
198 * On NULL return, crit acts as a failure indicator: crit == -1 means an
199 * extension of type nid was not present, crit != -1 is fatal: crit == -2
200 * means multiple extensions of type nid are present; if crit is 0 or 1, this
201 * implies the extension was found but could not be decoded.
202 */
203
204 void *
X509V3_get_d2i(const STACK_OF (X509_EXTENSION)* x509_exts,int nid,int * crit,int * idx)205 X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x509_exts, int nid, int *crit,
206 int *idx)
207 {
208 X509_EXTENSION *ext;
209 int lastpos = idx == NULL ? -1 : *idx;
210
211 if (crit != NULL)
212 *crit = -1;
213 if (idx != NULL)
214 *idx = -1;
215
216 /*
217 * Nothing to do if no extensions, unknown nid, or missing extension.
218 */
219
220 if (x509_exts == NULL)
221 return NULL;
222 if ((lastpos = X509v3_get_ext_by_NID(x509_exts, nid, lastpos)) < 0)
223 return NULL;
224 if ((ext = X509v3_get_ext(x509_exts, lastpos)) == NULL)
225 return NULL;
226
227 /*
228 * API madness. Only check for a second extension of type nid if
229 * idx == NULL. Indicate this by setting *crit to -2. If idx != NULL,
230 * don't care and set *idx to the index of the first extension found.
231 */
232
233 if (idx == NULL && X509v3_get_ext_by_NID(x509_exts, nid, lastpos) > 0) {
234 if (crit != NULL)
235 *crit = -2;
236 return NULL;
237 }
238
239 /*
240 * Another beautiful API detail: *crit will be set to 0 or 1, so if the
241 * extension fails to decode, we can deduce this from return value NULL
242 * and crit != -1.
243 */
244
245 if (crit != NULL)
246 *crit = X509_EXTENSION_get_critical(ext);
247 if (idx != NULL)
248 *idx = lastpos;
249
250 return X509V3_EXT_d2i(ext);
251 }
252 LCRYPTO_ALIAS(X509V3_get_d2i);
253
254 int
X509V3_add1_i2d(STACK_OF (X509_EXTENSION)** x509_exts,int nid,void * value,int crit,unsigned long flags)255 X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x509_exts, int nid, void *value,
256 int crit, unsigned long flags)
257 {
258 STACK_OF(X509_EXTENSION) *exts = *x509_exts;
259 X509_EXTENSION *ext = NULL;
260 X509_EXTENSION *existing;
261 int extidx;
262 int errcode = 0;
263 int ret = 0;
264
265 /* See if the extension already exists. */
266 extidx = X509v3_get_ext_by_NID(*x509_exts, nid, -1);
267
268 switch (flags & X509V3_ADD_OP_MASK) {
269 case X509V3_ADD_DEFAULT:
270 /* If the extension exists, adding another one is an error. */
271 if (extidx >= 0) {
272 errcode = X509V3_R_EXTENSION_EXISTS;
273 goto err;
274 }
275 break;
276 case X509V3_ADD_APPEND:
277 /*
278 * XXX - Total misfeature. If the extension exists, appending
279 * another one will invalidate the certificate. Unfortunately
280 * things use this, in particular Viktor's DANE code.
281 */
282 /* Pretend the extension didn't exist and append the new one. */
283 extidx = -1;
284 break;
285 case X509V3_ADD_REPLACE:
286 /* Replace existing extension, otherwise append the new one. */
287 break;
288 case X509V3_ADD_REPLACE_EXISTING:
289 /* Can't replace a non-existent extension. */
290 if (extidx < 0) {
291 errcode = X509V3_R_EXTENSION_NOT_FOUND;
292 goto err;
293 }
294 break;
295 case X509V3_ADD_KEEP_EXISTING:
296 /* If the extension exists, there's nothing to do. */
297 if (extidx >= 0)
298 goto done;
299 break;
300 case X509V3_ADD_DELETE:
301 /* Can't delete a non-existent extension. */
302 if (extidx < 0) {
303 errcode = X509V3_R_EXTENSION_NOT_FOUND;
304 goto err;
305 }
306 if ((existing = sk_X509_EXTENSION_delete(*x509_exts,
307 extidx)) == NULL) {
308 ret = -1;
309 goto err;
310 }
311 X509_EXTENSION_free(existing);
312 existing = NULL;
313 goto done;
314 default:
315 errcode = X509V3_R_UNSUPPORTED_OPTION; /* XXX */
316 ret = -1;
317 goto err;
318 }
319
320 if ((ext = X509V3_EXT_i2d(nid, crit, value)) == NULL) {
321 X509V3error(X509V3_R_ERROR_CREATING_EXTENSION);
322 goto err;
323 }
324
325 /* From here, errors are fatal. */
326 ret = -1;
327
328 /* If extension exists, replace it. */
329 if (extidx >= 0) {
330 existing = sk_X509_EXTENSION_value(*x509_exts, extidx);
331 X509_EXTENSION_free(existing);
332 existing = NULL;
333 if (sk_X509_EXTENSION_set(*x509_exts, extidx, ext) == NULL) {
334 /*
335 * XXX - Can't happen. If it did happen, |existing| is
336 * now a freed pointer. Nothing we can do here.
337 */
338 goto err;
339 }
340 goto done;
341 }
342
343 if (exts == NULL)
344 exts = sk_X509_EXTENSION_new_null();
345 if (exts == NULL)
346 goto err;
347
348 if (!sk_X509_EXTENSION_push(exts, ext))
349 goto err;
350 ext = NULL;
351
352 *x509_exts = exts;
353
354 done:
355 return 1;
356
357 err:
358 if ((flags & X509V3_ADD_SILENT) == 0 && errcode != 0)
359 X509V3error(errcode);
360
361 if (exts != *x509_exts)
362 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
363 X509_EXTENSION_free(ext);
364
365 return ret;
366 }
367 LCRYPTO_ALIAS(X509V3_add1_i2d);
368
369 int
X509V3_add_standard_extensions(void)370 X509V3_add_standard_extensions(void)
371 {
372 return 1;
373 }
374 LCRYPTO_ALIAS(X509V3_add_standard_extensions);
375