VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1g/crypto/x509v3/v3_alt.c@ 84207

最後變更 在這個檔案從84207是 83916,由 vboxsync 提交於 5 年 前

openssl-1.1.1g: Applied and adjusted our OpenSSL changes to 1.1.1g. bugref:9719

檔案大小: 17.1 KB
 
1/*
2 * Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include "internal/cryptlib.h"
12#include <openssl/conf.h>
13#include <openssl/x509v3.h>
14#include "ext_dat.h"
15
16static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
17 X509V3_CTX *ctx,
18 STACK_OF(CONF_VALUE) *nval);
19static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
20 X509V3_CTX *ctx,
21 STACK_OF(CONF_VALUE) *nval);
22static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
23static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
24static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
25static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
26
27const X509V3_EXT_METHOD v3_alt[3] = {
28 {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
29 0, 0, 0, 0,
30 0, 0,
31 (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
32 (X509V3_EXT_V2I)v2i_subject_alt,
33 NULL, NULL, NULL},
34
35 {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
36 0, 0, 0, 0,
37 0, 0,
38 (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
39 (X509V3_EXT_V2I)v2i_issuer_alt,
40 NULL, NULL, NULL},
41
42 {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
43 0, 0, 0, 0,
44 0, 0,
45 (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
46 NULL, NULL, NULL, NULL},
47};
48
49STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
50 GENERAL_NAMES *gens,
51 STACK_OF(CONF_VALUE) *ret)
52{
53 int i;
54 GENERAL_NAME *gen;
55 STACK_OF(CONF_VALUE) *tmpret = NULL, *origret = ret;
56
57 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
58 gen = sk_GENERAL_NAME_value(gens, i);
59 /*
60 * i2v_GENERAL_NAME allocates ret if it is NULL. If something goes
61 * wrong we need to free the stack - but only if it was empty when we
62 * originally entered this function.
63 */
64 tmpret = i2v_GENERAL_NAME(method, gen, ret);
65 if (tmpret == NULL) {
66 if (origret == NULL)
67 sk_CONF_VALUE_pop_free(ret, X509V3_conf_free);
68 return NULL;
69 }
70 ret = tmpret;
71 }
72 if (ret == NULL)
73 return sk_CONF_VALUE_new_null();
74 return ret;
75}
76
77STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
78 GENERAL_NAME *gen,
79 STACK_OF(CONF_VALUE) *ret)
80{
81 unsigned char *p;
82 char oline[256], htmp[5];
83 int i;
84
85 switch (gen->type) {
86 case GEN_OTHERNAME:
87 if (!X509V3_add_value("othername", "<unsupported>", &ret))
88 return NULL;
89 break;
90
91 case GEN_X400:
92 if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
93 return NULL;
94 break;
95
96 case GEN_EDIPARTY:
97 if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
98 return NULL;
99 break;
100
101 case GEN_EMAIL:
102 if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret))
103 return NULL;
104 break;
105
106 case GEN_DNS:
107 if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret))
108 return NULL;
109 break;
110
111 case GEN_URI:
112 if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret))
113 return NULL;
114 break;
115
116 case GEN_DIRNAME:
117 if (X509_NAME_oneline(gen->d.dirn, oline, sizeof(oline)) == NULL
118 || !X509V3_add_value("DirName", oline, &ret))
119 return NULL;
120 break;
121
122 case GEN_IPADD:
123 p = gen->d.ip->data;
124 if (gen->d.ip->length == 4)
125 BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d",
126 p[0], p[1], p[2], p[3]);
127 else if (gen->d.ip->length == 16) {
128 oline[0] = 0;
129 for (i = 0; i < 8; i++) {
130 BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]);
131 p += 2;
132 strcat(oline, htmp);
133 if (i != 7)
134 strcat(oline, ":");
135 }
136 } else {
137 if (!X509V3_add_value("IP Address", "<invalid>", &ret))
138 return NULL;
139 break;
140 }
141 if (!X509V3_add_value("IP Address", oline, &ret))
142 return NULL;
143 break;
144
145 case GEN_RID:
146 i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
147 if (!X509V3_add_value("Registered ID", oline, &ret))
148 return NULL;
149 break;
150 }
151 return ret;
152}
153
154int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
155{
156 unsigned char *p;
157 int i;
158 switch (gen->type) {
159 case GEN_OTHERNAME:
160 BIO_printf(out, "othername:<unsupported>");
161 break;
162
163 case GEN_X400:
164 BIO_printf(out, "X400Name:<unsupported>");
165 break;
166
167 case GEN_EDIPARTY:
168 /* Maybe fix this: it is supported now */
169 BIO_printf(out, "EdiPartyName:<unsupported>");
170 break;
171
172 case GEN_EMAIL:
173 BIO_printf(out, "email:");
174 ASN1_STRING_print(out, gen->d.ia5);
175 break;
176
177 case GEN_DNS:
178 BIO_printf(out, "DNS:");
179 ASN1_STRING_print(out, gen->d.ia5);
180 break;
181
182 case GEN_URI:
183 BIO_printf(out, "URI:");
184 ASN1_STRING_print(out, gen->d.ia5);
185 break;
186
187 case GEN_DIRNAME:
188 BIO_printf(out, "DirName:");
189 X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
190 break;
191
192 case GEN_IPADD:
193 p = gen->d.ip->data;
194 if (gen->d.ip->length == 4)
195 BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
196 else if (gen->d.ip->length == 16) {
197 BIO_printf(out, "IP Address");
198 for (i = 0; i < 8; i++) {
199 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
200 p += 2;
201 }
202 BIO_puts(out, "\n");
203 } else {
204 BIO_printf(out, "IP Address:<invalid>");
205 break;
206 }
207 break;
208
209 case GEN_RID:
210 BIO_printf(out, "Registered ID:");
211 i2a_ASN1_OBJECT(out, gen->d.rid);
212 break;
213 }
214 return 1;
215}
216
217static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
218 X509V3_CTX *ctx,
219 STACK_OF(CONF_VALUE) *nval)
220{
221 const int num = sk_CONF_VALUE_num(nval);
222 GENERAL_NAMES *gens = sk_GENERAL_NAME_new_reserve(NULL, num);
223 int i;
224
225 if (gens == NULL) {
226 X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
227 sk_GENERAL_NAME_free(gens);
228 return NULL;
229 }
230 for (i = 0; i < num; i++) {
231 CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
232
233 if (!name_cmp(cnf->name, "issuer")
234 && cnf->value && strcmp(cnf->value, "copy") == 0) {
235 if (!copy_issuer(ctx, gens))
236 goto err;
237 } else {
238 GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
239
240 if (gen == NULL)
241 goto err;
242 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
243 }
244 }
245 return gens;
246 err:
247 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
248 return NULL;
249}
250
251/* Append subject altname of issuer to issuer alt name of subject */
252
253static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
254{
255 GENERAL_NAMES *ialt;
256 GENERAL_NAME *gen;
257 X509_EXTENSION *ext;
258 int i, num;
259
260 if (ctx && (ctx->flags == CTX_TEST))
261 return 1;
262 if (!ctx || !ctx->issuer_cert) {
263 X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS);
264 goto err;
265 }
266 i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
267 if (i < 0)
268 return 1;
269 if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL
270 || (ialt = X509V3_EXT_d2i(ext)) == NULL) {
271 X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR);
272 goto err;
273 }
274
275 num = sk_GENERAL_NAME_num(ialt);
276 if (!sk_GENERAL_NAME_reserve(gens, num)) {
277 X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
278 goto err;
279 }
280
281 for (i = 0; i < num; i++) {
282 gen = sk_GENERAL_NAME_value(ialt, i);
283 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
284 }
285 sk_GENERAL_NAME_free(ialt);
286
287 return 1;
288
289 err:
290 return 0;
291
292}
293
294static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
295 X509V3_CTX *ctx,
296 STACK_OF(CONF_VALUE) *nval)
297{
298 GENERAL_NAMES *gens;
299 CONF_VALUE *cnf;
300 const int num = sk_CONF_VALUE_num(nval);
301 int i;
302
303 gens = sk_GENERAL_NAME_new_reserve(NULL, num);
304 if (gens == NULL) {
305 X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
306 sk_GENERAL_NAME_free(gens);
307 return NULL;
308 }
309
310 for (i = 0; i < num; i++) {
311 cnf = sk_CONF_VALUE_value(nval, i);
312 if (!name_cmp(cnf->name, "email")
313 && cnf->value && strcmp(cnf->value, "copy") == 0) {
314 if (!copy_email(ctx, gens, 0))
315 goto err;
316 } else if (!name_cmp(cnf->name, "email")
317 && cnf->value && strcmp(cnf->value, "move") == 0) {
318 if (!copy_email(ctx, gens, 1))
319 goto err;
320 } else {
321 GENERAL_NAME *gen;
322 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
323 goto err;
324 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
325 }
326 }
327 return gens;
328 err:
329 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
330 return NULL;
331}
332
333/*
334 * Copy any email addresses in a certificate or request to GENERAL_NAMES
335 */
336
337static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
338{
339 X509_NAME *nm;
340 ASN1_IA5STRING *email = NULL;
341 X509_NAME_ENTRY *ne;
342 GENERAL_NAME *gen = NULL;
343 int i = -1;
344
345 if (ctx != NULL && ctx->flags == CTX_TEST)
346 return 1;
347 if (ctx == NULL
348 || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) {
349 X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS);
350 goto err;
351 }
352 /* Find the subject name */
353 if (ctx->subject_cert)
354 nm = X509_get_subject_name(ctx->subject_cert);
355 else
356 nm = X509_REQ_get_subject_name(ctx->subject_req);
357
358 /* Now add any email address(es) to STACK */
359 while ((i = X509_NAME_get_index_by_NID(nm,
360 NID_pkcs9_emailAddress, i)) >= 0) {
361 ne = X509_NAME_get_entry(nm, i);
362 email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
363 if (move_p) {
364 X509_NAME_delete_entry(nm, i);
365 X509_NAME_ENTRY_free(ne);
366 i--;
367 }
368 if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) {
369 X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
370 goto err;
371 }
372 gen->d.ia5 = email;
373 email = NULL;
374 gen->type = GEN_EMAIL;
375 if (!sk_GENERAL_NAME_push(gens, gen)) {
376 X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
377 goto err;
378 }
379 gen = NULL;
380 }
381
382 return 1;
383
384 err:
385 GENERAL_NAME_free(gen);
386 ASN1_IA5STRING_free(email);
387 return 0;
388
389}
390
391GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
392 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
393{
394 GENERAL_NAME *gen;
395 GENERAL_NAMES *gens;
396 CONF_VALUE *cnf;
397 const int num = sk_CONF_VALUE_num(nval);
398 int i;
399
400 gens = sk_GENERAL_NAME_new_reserve(NULL, num);
401 if (gens == NULL) {
402 X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
403 sk_GENERAL_NAME_free(gens);
404 return NULL;
405 }
406
407 for (i = 0; i < num; i++) {
408 cnf = sk_CONF_VALUE_value(nval, i);
409 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
410 goto err;
411 sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
412 }
413 return gens;
414 err:
415 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
416 return NULL;
417}
418
419GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
420 X509V3_CTX *ctx, CONF_VALUE *cnf)
421{
422 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
423}
424
425GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
426 const X509V3_EXT_METHOD *method,
427 X509V3_CTX *ctx, int gen_type, const char *value,
428 int is_nc)
429{
430 char is_string = 0;
431 GENERAL_NAME *gen = NULL;
432
433 if (!value) {
434 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE);
435 return NULL;
436 }
437
438 if (out)
439 gen = out;
440 else {
441 gen = GENERAL_NAME_new();
442 if (gen == NULL) {
443 X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
444 return NULL;
445 }
446 }
447
448 switch (gen_type) {
449 case GEN_URI:
450 case GEN_EMAIL:
451 case GEN_DNS:
452 is_string = 1;
453 break;
454
455 case GEN_RID:
456 {
457 ASN1_OBJECT *obj;
458 if ((obj = OBJ_txt2obj(value, 0)) == NULL) {
459 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT);
460 ERR_add_error_data(2, "value=", value);
461 goto err;
462 }
463 gen->d.rid = obj;
464 }
465 break;
466
467 case GEN_IPADD:
468 if (is_nc)
469 gen->d.ip = a2i_IPADDRESS_NC(value);
470 else
471 gen->d.ip = a2i_IPADDRESS(value);
472 if (gen->d.ip == NULL) {
473 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
474 ERR_add_error_data(2, "value=", value);
475 goto err;
476 }
477 break;
478
479 case GEN_DIRNAME:
480 if (!do_dirname(gen, value, ctx)) {
481 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
482 goto err;
483 }
484 break;
485
486 case GEN_OTHERNAME:
487 if (!do_othername(gen, value, ctx)) {
488 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
489 goto err;
490 }
491 break;
492 default:
493 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
494 goto err;
495 }
496
497 if (is_string) {
498 if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL ||
499 !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
500 strlen(value))) {
501 X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
502 goto err;
503 }
504 }
505
506 gen->type = gen_type;
507
508 return gen;
509
510 err:
511 if (!out)
512 GENERAL_NAME_free(gen);
513 return NULL;
514}
515
516GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
517 const X509V3_EXT_METHOD *method,
518 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
519{
520 int type;
521
522 char *name, *value;
523
524 name = cnf->name;
525 value = cnf->value;
526
527 if (!value) {
528 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE);
529 return NULL;
530 }
531
532 if (!name_cmp(name, "email"))
533 type = GEN_EMAIL;
534 else if (!name_cmp(name, "URI"))
535 type = GEN_URI;
536 else if (!name_cmp(name, "DNS"))
537 type = GEN_DNS;
538 else if (!name_cmp(name, "RID"))
539 type = GEN_RID;
540 else if (!name_cmp(name, "IP"))
541 type = GEN_IPADD;
542 else if (!name_cmp(name, "dirName"))
543 type = GEN_DIRNAME;
544 else if (!name_cmp(name, "otherName"))
545 type = GEN_OTHERNAME;
546 else {
547 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION);
548 ERR_add_error_data(2, "name=", name);
549 return NULL;
550 }
551
552 return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
553
554}
555
556static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
557{
558 char *objtmp = NULL, *p;
559 int objlen;
560
561 if ((p = strchr(value, ';')) == NULL)
562 return 0;
563 if ((gen->d.otherName = OTHERNAME_new()) == NULL)
564 return 0;
565 /*
566 * Free this up because we will overwrite it. no need to free type_id
567 * because it is static
568 */
569 ASN1_TYPE_free(gen->d.otherName->value);
570 if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL)
571 return 0;
572 objlen = p - value;
573 objtmp = OPENSSL_strndup(value, objlen);
574 if (objtmp == NULL)
575 return 0;
576 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
577 OPENSSL_free(objtmp);
578 if (!gen->d.otherName->type_id)
579 return 0;
580 return 1;
581}
582
583static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
584{
585 int ret = 0;
586 STACK_OF(CONF_VALUE) *sk = NULL;
587 X509_NAME *nm;
588
589 if ((nm = X509_NAME_new()) == NULL)
590 goto err;
591 sk = X509V3_get_section(ctx, value);
592 if (!sk) {
593 X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
594 ERR_add_error_data(2, "section=", value);
595 goto err;
596 }
597 /* FIXME: should allow other character types... */
598 ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
599 if (!ret)
600 goto err;
601 gen->d.dirn = nm;
602
603err:
604 if (ret == 0)
605 X509_NAME_free(nm);
606 X509V3_section_free(ctx, sk);
607 return ret;
608}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette