source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_alt.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 15.8 KB
Line 
1/*
2 * Copyright 1999-2016 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 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
56 gen = sk_GENERAL_NAME_value(gens, i);
57 ret = i2v_GENERAL_NAME(method, gen, ret);
58 }
59 if (!ret)
60 return sk_CONF_VALUE_new_null();
61 return ret;
62}
63
64STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
65 GENERAL_NAME *gen,
66 STACK_OF(CONF_VALUE) *ret)
67{
68 unsigned char *p;
69 char oline[256], htmp[5];
70 int i;
71 switch (gen->type) {
72 case GEN_OTHERNAME:
73 X509V3_add_value("othername", "<unsupported>", &ret);
74 break;
75
76 case GEN_X400:
77 X509V3_add_value("X400Name", "<unsupported>", &ret);
78 break;
79
80 case GEN_EDIPARTY:
81 X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
82 break;
83
84 case GEN_EMAIL:
85 X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
86 break;
87
88 case GEN_DNS:
89 X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
90 break;
91
92 case GEN_URI:
93 X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
94 break;
95
96 case GEN_DIRNAME:
97 X509_NAME_oneline(gen->d.dirn, oline, 256);
98 X509V3_add_value("DirName", oline, &ret);
99 break;
100
101 case GEN_IPADD:
102 p = gen->d.ip->data;
103 if (gen->d.ip->length == 4)
104 BIO_snprintf(oline, sizeof oline,
105 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
106 else if (gen->d.ip->length == 16) {
107 oline[0] = 0;
108 for (i = 0; i < 8; i++) {
109 BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
110 p += 2;
111 strcat(oline, htmp);
112 if (i != 7)
113 strcat(oline, ":");
114 }
115 } else {
116 X509V3_add_value("IP Address", "<invalid>", &ret);
117 break;
118 }
119 X509V3_add_value("IP Address", oline, &ret);
120 break;
121
122 case GEN_RID:
123 i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
124 X509V3_add_value("Registered ID", oline, &ret);
125 break;
126 }
127 return ret;
128}
129
130int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
131{
132 unsigned char *p;
133 int i;
134 switch (gen->type) {
135 case GEN_OTHERNAME:
136 BIO_printf(out, "othername:<unsupported>");
137 break;
138
139 case GEN_X400:
140 BIO_printf(out, "X400Name:<unsupported>");
141 break;
142
143 case GEN_EDIPARTY:
144 /* Maybe fix this: it is supported now */
145 BIO_printf(out, "EdiPartyName:<unsupported>");
146 break;
147
148 case GEN_EMAIL:
149 BIO_printf(out, "email:%s", gen->d.ia5->data);
150 break;
151
152 case GEN_DNS:
153 BIO_printf(out, "DNS:%s", gen->d.ia5->data);
154 break;
155
156 case GEN_URI:
157 BIO_printf(out, "URI:%s", gen->d.ia5->data);
158 break;
159
160 case GEN_DIRNAME:
161 BIO_printf(out, "DirName:");
162 X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
163 break;
164
165 case GEN_IPADD:
166 p = gen->d.ip->data;
167 if (gen->d.ip->length == 4)
168 BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
169 else if (gen->d.ip->length == 16) {
170 BIO_printf(out, "IP Address");
171 for (i = 0; i < 8; i++) {
172 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
173 p += 2;
174 }
175 BIO_puts(out, "\n");
176 } else {
177 BIO_printf(out, "IP Address:<invalid>");
178 break;
179 }
180 break;
181
182 case GEN_RID:
183 BIO_printf(out, "Registered ID:");
184 i2a_ASN1_OBJECT(out, gen->d.rid);
185 break;
186 }
187 return 1;
188}
189
190static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
191 X509V3_CTX *ctx,
192 STACK_OF(CONF_VALUE) *nval)
193{
194 GENERAL_NAMES *gens = NULL;
195 CONF_VALUE *cnf;
196 int i;
197
198 if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
199 X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
200 return NULL;
201 }
202 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
203 cnf = sk_CONF_VALUE_value(nval, i);
204 if (!name_cmp(cnf->name, "issuer")
205 && cnf->value && strcmp(cnf->value, "copy") == 0) {
206 if (!copy_issuer(ctx, gens))
207 goto err;
208 } else {
209 GENERAL_NAME *gen;
210 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
211 goto err;
212 sk_GENERAL_NAME_push(gens, gen);
213 }
214 }
215 return gens;
216 err:
217 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
218 return NULL;
219}
220
221/* Append subject altname of issuer to issuer alt name of subject */
222
223static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
224{
225 GENERAL_NAMES *ialt;
226 GENERAL_NAME *gen;
227 X509_EXTENSION *ext;
228 int i;
229
230 if (ctx && (ctx->flags == CTX_TEST))
231 return 1;
232 if (!ctx || !ctx->issuer_cert) {
233 X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS);
234 goto err;
235 }
236 i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
237 if (i < 0)
238 return 1;
239 if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL
240 || (ialt = X509V3_EXT_d2i(ext)) == NULL) {
241 X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR);
242 goto err;
243 }
244
245 for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
246 gen = sk_GENERAL_NAME_value(ialt, i);
247 if (!sk_GENERAL_NAME_push(gens, gen)) {
248 X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
249 goto err;
250 }
251 }
252 sk_GENERAL_NAME_free(ialt);
253
254 return 1;
255
256 err:
257 return 0;
258
259}
260
261static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
262 X509V3_CTX *ctx,
263 STACK_OF(CONF_VALUE) *nval)
264{
265 GENERAL_NAMES *gens = NULL;
266 CONF_VALUE *cnf;
267 int i;
268
269 if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
270 X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
271 return NULL;
272 }
273 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
274 cnf = sk_CONF_VALUE_value(nval, i);
275 if (!name_cmp(cnf->name, "email")
276 && cnf->value && strcmp(cnf->value, "copy") == 0) {
277 if (!copy_email(ctx, gens, 0))
278 goto err;
279 } else if (!name_cmp(cnf->name, "email")
280 && cnf->value && strcmp(cnf->value, "move") == 0) {
281 if (!copy_email(ctx, gens, 1))
282 goto err;
283 } else {
284 GENERAL_NAME *gen;
285 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
286 goto err;
287 sk_GENERAL_NAME_push(gens, gen);
288 }
289 }
290 return gens;
291 err:
292 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
293 return NULL;
294}
295
296/*
297 * Copy any email addresses in a certificate or request to GENERAL_NAMES
298 */
299
300static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
301{
302 X509_NAME *nm;
303 ASN1_IA5STRING *email = NULL;
304 X509_NAME_ENTRY *ne;
305 GENERAL_NAME *gen = NULL;
306 int i;
307 if (ctx != NULL && ctx->flags == CTX_TEST)
308 return 1;
309 if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
310 X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS);
311 goto err;
312 }
313 /* Find the subject name */
314 if (ctx->subject_cert)
315 nm = X509_get_subject_name(ctx->subject_cert);
316 else
317 nm = X509_REQ_get_subject_name(ctx->subject_req);
318
319 /* Now add any email address(es) to STACK */
320 i = -1;
321 while ((i = X509_NAME_get_index_by_NID(nm,
322 NID_pkcs9_emailAddress, i)) >= 0) {
323 ne = X509_NAME_get_entry(nm, i);
324 email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
325 if (move_p) {
326 X509_NAME_delete_entry(nm, i);
327 X509_NAME_ENTRY_free(ne);
328 i--;
329 }
330 if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) {
331 X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
332 goto err;
333 }
334 gen->d.ia5 = email;
335 email = NULL;
336 gen->type = GEN_EMAIL;
337 if (!sk_GENERAL_NAME_push(gens, gen)) {
338 X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
339 goto err;
340 }
341 gen = NULL;
342 }
343
344 return 1;
345
346 err:
347 GENERAL_NAME_free(gen);
348 ASN1_IA5STRING_free(email);
349 return 0;
350
351}
352
353GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
354 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
355{
356 GENERAL_NAME *gen;
357 GENERAL_NAMES *gens = NULL;
358 CONF_VALUE *cnf;
359 int i;
360
361 if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
362 X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
363 return NULL;
364 }
365 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
366 cnf = sk_CONF_VALUE_value(nval, i);
367 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
368 goto err;
369 sk_GENERAL_NAME_push(gens, gen);
370 }
371 return gens;
372 err:
373 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
374 return NULL;
375}
376
377GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
378 X509V3_CTX *ctx, CONF_VALUE *cnf)
379{
380 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
381}
382
383GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
384 const X509V3_EXT_METHOD *method,
385 X509V3_CTX *ctx, int gen_type, const char *value,
386 int is_nc)
387{
388 char is_string = 0;
389 GENERAL_NAME *gen = NULL;
390
391 if (!value) {
392 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE);
393 return NULL;
394 }
395
396 if (out)
397 gen = out;
398 else {
399 gen = GENERAL_NAME_new();
400 if (gen == NULL) {
401 X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
402 return NULL;
403 }
404 }
405
406 switch (gen_type) {
407 case GEN_URI:
408 case GEN_EMAIL:
409 case GEN_DNS:
410 is_string = 1;
411 break;
412
413 case GEN_RID:
414 {
415 ASN1_OBJECT *obj;
416 if ((obj = OBJ_txt2obj(value, 0)) == NULL) {
417 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT);
418 ERR_add_error_data(2, "value=", value);
419 goto err;
420 }
421 gen->d.rid = obj;
422 }
423 break;
424
425 case GEN_IPADD:
426 if (is_nc)
427 gen->d.ip = a2i_IPADDRESS_NC(value);
428 else
429 gen->d.ip = a2i_IPADDRESS(value);
430 if (gen->d.ip == NULL) {
431 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
432 ERR_add_error_data(2, "value=", value);
433 goto err;
434 }
435 break;
436
437 case GEN_DIRNAME:
438 if (!do_dirname(gen, value, ctx)) {
439 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
440 goto err;
441 }
442 break;
443
444 case GEN_OTHERNAME:
445 if (!do_othername(gen, value, ctx)) {
446 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
447 goto err;
448 }
449 break;
450 default:
451 X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
452 goto err;
453 }
454
455 if (is_string) {
456 if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL ||
457 !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
458 strlen(value))) {
459 X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
460 goto err;
461 }
462 }
463
464 gen->type = gen_type;
465
466 return gen;
467
468 err:
469 if (!out)
470 GENERAL_NAME_free(gen);
471 return NULL;
472}
473
474GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
475 const X509V3_EXT_METHOD *method,
476 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
477{
478 int type;
479
480 char *name, *value;
481
482 name = cnf->name;
483 value = cnf->value;
484
485 if (!value) {
486 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE);
487 return NULL;
488 }
489
490 if (!name_cmp(name, "email"))
491 type = GEN_EMAIL;
492 else if (!name_cmp(name, "URI"))
493 type = GEN_URI;
494 else if (!name_cmp(name, "DNS"))
495 type = GEN_DNS;
496 else if (!name_cmp(name, "RID"))
497 type = GEN_RID;
498 else if (!name_cmp(name, "IP"))
499 type = GEN_IPADD;
500 else if (!name_cmp(name, "dirName"))
501 type = GEN_DIRNAME;
502 else if (!name_cmp(name, "otherName"))
503 type = GEN_OTHERNAME;
504 else {
505 X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION);
506 ERR_add_error_data(2, "name=", name);
507 return NULL;
508 }
509
510 return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
511
512}
513
514static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
515{
516 char *objtmp = NULL, *p;
517 int objlen;
518
519 if ((p = strchr(value, ';')) == NULL)
520 return 0;
521 if ((gen->d.otherName = OTHERNAME_new()) == NULL)
522 return 0;
523 /*
524 * Free this up because we will overwrite it. no need to free type_id
525 * because it is static
526 */
527 ASN1_TYPE_free(gen->d.otherName->value);
528 if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL)
529 return 0;
530 objlen = p - value;
531 objtmp = OPENSSL_strndup(value, objlen);
532 if (objtmp == NULL)
533 return 0;
534 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
535 OPENSSL_free(objtmp);
536 if (!gen->d.otherName->type_id)
537 return 0;
538 return 1;
539}
540
541static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
542{
543 int ret = 0;
544 STACK_OF(CONF_VALUE) *sk = NULL;
545 X509_NAME *nm;
546
547 if ((nm = X509_NAME_new()) == NULL)
548 goto err;
549 sk = X509V3_get_section(ctx, value);
550 if (!sk) {
551 X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
552 ERR_add_error_data(2, "section=", value);
553 goto err;
554 }
555 /* FIXME: should allow other character types... */
556 ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
557 if (!ret)
558 goto err;
559 gen->d.dirn = nm;
560
561err:
562 if (ret == 0)
563 X509_NAME_free(nm);
564 X509V3_section_free(ctx, sk);
565 return ret;
566}
Note: See TracBrowser for help on using the repository browser.