]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/x509v3/v3_utl.c
Run util/openssl-format-source -v -c .
[thirdparty/openssl.git] / crypto / x509v3 / v3_utl.c
CommitLineData
9aeaf1b4 1/* v3_utl.c */
0f113f3e
MC
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4e5d3a7f 4 * project.
9aeaf1b4
DSH
5 */
6/* ====================================================================
4e5d3a7f 7 * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
9aeaf1b4
DSH
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
0f113f3e 14 * notice, this list of conditions and the following disclaimer.
9aeaf1b4
DSH
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* X509 v3 extension utilities */
60
e527ba09 61#include <stdio.h>
9aeaf1b4 62#include <ctype.h>
e527ba09 63#include "cryptlib.h"
ec577822
BM
64#include <openssl/conf.h>
65#include <openssl/x509v3.h>
0f814687 66#include <openssl/bn.h>
9aeaf1b4 67
9aeaf1b4 68static char *strip_spaces(char *name);
0f113f3e
MC
69static int sk_strcmp(const char *const *a, const char *const *b);
70static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
71 GENERAL_NAMES *gens);
c869da88
DSH
72static void str_free(OPENSSL_STRING str);
73static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
9aeaf1b4 74
4e5d3a7f
DSH
75static int ipv4_from_asc(unsigned char *v4, const char *in);
76static int ipv6_from_asc(unsigned char *v6, const char *in);
77static int ipv6_cb(const char *elem, int len, void *usr);
78static int ipv6_hex(unsigned char *out, const char *in, int inlen);
79
9aeaf1b4
DSH
80/* Add a CONF_VALUE name value pair to stack */
81
ba404b5e 82int X509V3_add_value(const char *name, const char *value,
0f113f3e 83 STACK_OF(CONF_VALUE) **extlist)
9aeaf1b4 84{
0f113f3e
MC
85 CONF_VALUE *vtmp = NULL;
86 char *tname = NULL, *tvalue = NULL;
87 if (name && !(tname = BUF_strdup(name)))
88 goto err;
89 if (value && !(tvalue = BUF_strdup(value)))
90 goto err;
91 if (!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))))
92 goto err;
93 if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null()))
94 goto err;
95 vtmp->section = NULL;
96 vtmp->name = tname;
97 vtmp->value = tvalue;
98 if (!sk_CONF_VALUE_push(*extlist, vtmp))
99 goto err;
100 return 1;
101 err:
102 X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE);
103 if (vtmp)
104 OPENSSL_free(vtmp);
105 if (tname)
106 OPENSSL_free(tname);
107 if (tvalue)
108 OPENSSL_free(tvalue);
109 return 0;
9aeaf1b4
DSH
110}
111
61f5b6f3 112int X509V3_add_value_uchar(const char *name, const unsigned char *value,
0f113f3e
MC
113 STACK_OF(CONF_VALUE) **extlist)
114{
115 return X509V3_add_value(name, (const char *)value, extlist);
116}
61f5b6f3 117
66ab08b1 118/* Free function for STACK_OF(CONF_VALUE) */
9aeaf1b4 119
6b691a5c 120void X509V3_conf_free(CONF_VALUE *conf)
9aeaf1b4 121{
0f113f3e
MC
122 if (!conf)
123 return;
124 if (conf->name)
125 OPENSSL_free(conf->name);
126 if (conf->value)
127 OPENSSL_free(conf->value);
128 if (conf->section)
129 OPENSSL_free(conf->section);
130 OPENSSL_free(conf);
9aeaf1b4
DSH
131}
132
ba404b5e 133int X509V3_add_value_bool(const char *name, int asn1_bool,
0f113f3e 134 STACK_OF(CONF_VALUE) **extlist)
9aeaf1b4 135{
0f113f3e
MC
136 if (asn1_bool)
137 return X509V3_add_value(name, "TRUE", extlist);
138 return X509V3_add_value(name, "FALSE", extlist);
9aeaf1b4
DSH
139}
140
ba404b5e 141int X509V3_add_value_bool_nf(char *name, int asn1_bool,
0f113f3e 142 STACK_OF(CONF_VALUE) **extlist)
9aeaf1b4 143{
0f113f3e
MC
144 if (asn1_bool)
145 return X509V3_add_value(name, "TRUE", extlist);
146 return 1;
9aeaf1b4
DSH
147}
148
6b691a5c 149char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
c74f1eb9 150{
0f113f3e
MC
151 BIGNUM *bntmp = NULL;
152 char *strtmp = NULL;
153 if (!a)
154 return NULL;
155 if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
156 !(strtmp = BN_bn2dec(bntmp)))
157 X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
158 BN_free(bntmp);
159 return strtmp;
c74f1eb9
DSH
160}
161
6b691a5c 162char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
0ca5f8b1 163{
0f113f3e
MC
164 BIGNUM *bntmp = NULL;
165 char *strtmp = NULL;
166 if (!a)
167 return NULL;
168 if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
169 !(strtmp = BN_bn2dec(bntmp)))
170 X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
171 BN_free(bntmp);
172 return strtmp;
0ca5f8b1
DSH
173}
174
6b691a5c 175ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
28a98809 176{
0f113f3e
MC
177 BIGNUM *bn = NULL;
178 ASN1_INTEGER *aint;
179 int isneg, ishex;
180 int ret;
181 if (!value) {
182 X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
183 return 0;
184 }
185 bn = BN_new();
186 if (value[0] == '-') {
187 value++;
188 isneg = 1;
189 } else
190 isneg = 0;
191
192 if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
193 value += 2;
194 ishex = 1;
195 } else
196 ishex = 0;
197
198 if (ishex)
199 ret = BN_hex2bn(&bn, value);
200 else
201 ret = BN_dec2bn(&bn, value);
202
203 if (!ret || value[ret]) {
204 BN_free(bn);
205 X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
206 return 0;
207 }
208
209 if (isneg && BN_is_zero(bn))
210 isneg = 0;
211
212 aint = BN_to_ASN1_INTEGER(bn, NULL);
213 BN_free(bn);
214 if (!aint) {
215 X509V3err(X509V3_F_S2I_ASN1_INTEGER,
216 X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
217 return 0;
218 }
219 if (isneg)
220 aint->type |= V_ASN1_NEG;
221 return aint;
28a98809
DSH
222}
223
6b691a5c 224int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
0f113f3e 225 STACK_OF(CONF_VALUE) **extlist)
9aeaf1b4 226{
0f113f3e
MC
227 char *strtmp;
228 int ret;
229 if (!aint)
230 return 1;
231 if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
232 return 0;
233 ret = X509V3_add_value(name, strtmp, extlist);
234 OPENSSL_free(strtmp);
235 return ret;
9aeaf1b4
DSH
236}
237
6b691a5c 238int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
9aeaf1b4 239{
0f113f3e
MC
240 char *btmp;
241 if (!(btmp = value->value))
242 goto err;
243 if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
244 || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
245 || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
246 *asn1_bool = 0xff;
247 return 1;
248 } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
249 || !strcmp(btmp, "N") || !strcmp(btmp, "n")
250 || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
251 *asn1_bool = 0;
252 return 1;
253 }
254 err:
255 X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
256 X509V3_R_INVALID_BOOLEAN_STRING);
257 X509V3_conf_err(value);
258 return 0;
9aeaf1b4
DSH
259}
260
6b691a5c 261int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
9aeaf1b4 262{
0f113f3e
MC
263 ASN1_INTEGER *itmp;
264 if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
265 X509V3_conf_err(value);
266 return 0;
267 }
268 *aint = itmp;
269 return 1;
9aeaf1b4
DSH
270}
271
0f113f3e
MC
272#define HDR_NAME 1
273#define HDR_VALUE 2
9aeaf1b4 274
0f113f3e
MC
275/*
276 * #define DEBUG
277 */
9aeaf1b4 278
535d79da 279STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
9aeaf1b4 280{
0f113f3e
MC
281 char *p, *q, c;
282 char *ntmp, *vtmp;
283 STACK_OF(CONF_VALUE) *values = NULL;
284 char *linebuf;
285 int state;
286 /* We are going to modify the line so copy it first */
287 linebuf = BUF_strdup(line);
288 state = HDR_NAME;
289 ntmp = NULL;
290 /* Go through all characters */
291 for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
292 p++) {
293
294 switch (state) {
295 case HDR_NAME:
296 if (c == ':') {
297 state = HDR_VALUE;
298 *p = 0;
299 ntmp = strip_spaces(q);
300 if (!ntmp) {
301 X509V3err(X509V3_F_X509V3_PARSE_LIST,
302 X509V3_R_INVALID_NULL_NAME);
303 goto err;
304 }
305 q = p + 1;
306 } else if (c == ',') {
307 *p = 0;
308 ntmp = strip_spaces(q);
309 q = p + 1;
59dbdb51 310#if 0
0f113f3e 311 printf("%s\n", ntmp);
9aeaf1b4 312#endif
0f113f3e
MC
313 if (!ntmp) {
314 X509V3err(X509V3_F_X509V3_PARSE_LIST,
315 X509V3_R_INVALID_NULL_NAME);
316 goto err;
317 }
318 X509V3_add_value(ntmp, NULL, &values);
319 }
320 break;
321
322 case HDR_VALUE:
323 if (c == ',') {
324 state = HDR_NAME;
325 *p = 0;
326 vtmp = strip_spaces(q);
59dbdb51 327#if 0
0f113f3e 328 printf("%s\n", ntmp);
9aeaf1b4 329#endif
0f113f3e
MC
330 if (!vtmp) {
331 X509V3err(X509V3_F_X509V3_PARSE_LIST,
332 X509V3_R_INVALID_NULL_VALUE);
333 goto err;
334 }
335 X509V3_add_value(ntmp, vtmp, &values);
336 ntmp = NULL;
337 q = p + 1;
338 }
339
340 }
341 }
342
343 if (state == HDR_VALUE) {
344 vtmp = strip_spaces(q);
59dbdb51 345#if 0
0f113f3e 346 printf("%s=%s\n", ntmp, vtmp);
9aeaf1b4 347#endif
0f113f3e
MC
348 if (!vtmp) {
349 X509V3err(X509V3_F_X509V3_PARSE_LIST,
350 X509V3_R_INVALID_NULL_VALUE);
351 goto err;
352 }
353 X509V3_add_value(ntmp, vtmp, &values);
354 } else {
355 ntmp = strip_spaces(q);
59dbdb51 356#if 0
0f113f3e 357 printf("%s\n", ntmp);
9aeaf1b4 358#endif
0f113f3e
MC
359 if (!ntmp) {
360 X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
361 goto err;
362 }
363 X509V3_add_value(ntmp, NULL, &values);
364 }
365 OPENSSL_free(linebuf);
366 return values;
367
368 err:
369 OPENSSL_free(linebuf);
370 sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
371 return NULL;
9aeaf1b4
DSH
372
373}
374
375/* Delete leading and trailing spaces from a string */
6b691a5c 376static char *strip_spaces(char *name)
9aeaf1b4 377{
0f113f3e
MC
378 char *p, *q;
379 /* Skip over leading spaces */
380 p = name;
381 while (*p && isspace((unsigned char)*p))
382 p++;
383 if (!*p)
384 return NULL;
385 q = p + strlen(p) - 1;
386 while ((q != p) && isspace((unsigned char)*q))
387 q--;
388 if (p != q)
389 q[1] = 0;
390 if (!*p)
391 return NULL;
392 return p;
9aeaf1b4 393}
175b0942
DSH
394
395/* hex string utilities */
396
0f113f3e
MC
397/*
398 * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
399 * hex representation @@@ (Contents of buffer are always kept in ASCII, also
400 * on EBCDIC machines)
175b0942
DSH
401 */
402
376bf1d4 403char *hex_to_string(const unsigned char *buffer, long len)
175b0942 404{
0f113f3e
MC
405 char *tmp, *q;
406 const unsigned char *p;
407 int i;
408 const static char hexdig[] = "0123456789ABCDEF";
409 if (!buffer || !len)
410 return NULL;
411 if (!(tmp = OPENSSL_malloc(len * 3 + 1))) {
412 X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE);
413 return NULL;
414 }
415 q = tmp;
416 for (i = 0, p = buffer; i < len; i++, p++) {
417 *q++ = hexdig[(*p >> 4) & 0xf];
418 *q++ = hexdig[*p & 0xf];
419 *q++ = ':';
420 }
421 q[-1] = 0;
97d8e82c 422#ifdef CHARSET_EBCDIC
0f113f3e 423 ebcdic2ascii(tmp, tmp, q - tmp - 1);
97d8e82c
RL
424#endif
425
0f113f3e 426 return tmp;
175b0942
DSH
427}
428
0f113f3e
MC
429/*
430 * Give a string of hex digits convert to a buffer
175b0942
DSH
431 */
432
376bf1d4 433unsigned char *string_to_hex(const char *str, long *len)
175b0942 434{
0f113f3e
MC
435 unsigned char *hexbuf, *q;
436 unsigned char ch, cl, *p;
437 if (!str) {
438 X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT);
439 return NULL;
440 }
441 if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1)))
442 goto err;
443 for (p = (unsigned char *)str, q = hexbuf; *p;) {
444 ch = *p++;
97d8e82c 445#ifdef CHARSET_EBCDIC
0f113f3e 446 ch = os_toebcdic[ch];
97d8e82c 447#endif
0f113f3e
MC
448 if (ch == ':')
449 continue;
450 cl = *p++;
97d8e82c 451#ifdef CHARSET_EBCDIC
0f113f3e 452 cl = os_toebcdic[cl];
97d8e82c 453#endif
0f113f3e
MC
454 if (!cl) {
455 X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS);
456 OPENSSL_free(hexbuf);
457 return NULL;
458 }
459 if (isupper(ch))
460 ch = tolower(ch);
461 if (isupper(cl))
462 cl = tolower(cl);
463
464 if ((ch >= '0') && (ch <= '9'))
465 ch -= '0';
466 else if ((ch >= 'a') && (ch <= 'f'))
467 ch -= 'a' - 10;
468 else
469 goto badhex;
470
471 if ((cl >= '0') && (cl <= '9'))
472 cl -= '0';
473 else if ((cl >= 'a') && (cl <= 'f'))
474 cl -= 'a' - 10;
475 else
476 goto badhex;
477
478 *q++ = (ch << 4) | cl;
479 }
175b0942 480
0f113f3e
MC
481 if (len)
482 *len = q - hexbuf;
175b0942 483
0f113f3e 484 return hexbuf;
175b0942 485
0f113f3e
MC
486 err:
487 if (hexbuf)
488 OPENSSL_free(hexbuf);
489 X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE);
490 return NULL;
175b0942 491
0f113f3e
MC
492 badhex:
493 OPENSSL_free(hexbuf);
494 X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT);
495 return NULL;
175b0942
DSH
496
497}
d08d8da4 498
0f113f3e
MC
499/*
500 * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
d08d8da4
DSH
501 */
502
6b691a5c 503int name_cmp(const char *name, const char *cmp)
d08d8da4 504{
0f113f3e
MC
505 int len, ret;
506 char c;
507 len = strlen(cmp);
508 if ((ret = strncmp(name, cmp, len)))
509 return ret;
510 c = name[len];
511 if (!c || (c == '.'))
512 return 0;
513 return 1;
d08d8da4 514}
a91dedca 515
0f113f3e 516static int sk_strcmp(const char *const *a, const char *const *b)
a91dedca 517{
0f113f3e 518 return strcmp(*a, *b);
a91dedca
DSH
519}
520
c869da88 521STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
a91dedca 522{
0f113f3e
MC
523 GENERAL_NAMES *gens;
524 STACK_OF(OPENSSL_STRING) *ret;
5ce278a7 525
0f113f3e
MC
526 gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
527 ret = get_email(X509_get_subject_name(x), gens);
528 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
529 return ret;
a91dedca
DSH
530}
531
c869da88 532STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
67c8e7f4 533{
0f113f3e
MC
534 AUTHORITY_INFO_ACCESS *info;
535 STACK_OF(OPENSSL_STRING) *ret = NULL;
536 int i;
537
538 info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
539 if (!info)
540 return NULL;
541 for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
542 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
543 if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
544 if (ad->location->type == GEN_URI) {
545 if (!append_ia5
546 (&ret, ad->location->d.uniformResourceIdentifier))
547 break;
548 }
549 }
550 }
551 AUTHORITY_INFO_ACCESS_free(info);
552 return ret;
67c8e7f4
DSH
553}
554
c869da88 555STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
a91dedca 556{
0f113f3e
MC
557 GENERAL_NAMES *gens;
558 STACK_OF(X509_EXTENSION) *exts;
559 STACK_OF(OPENSSL_STRING) *ret;
560
561 exts = X509_REQ_get_extensions(x);
562 gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
563 ret = get_email(X509_REQ_get_subject_name(x), gens);
564 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
565 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
566 return ret;
a91dedca
DSH
567}
568
0f113f3e
MC
569static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
570 GENERAL_NAMES *gens)
a91dedca 571{
0f113f3e
MC
572 STACK_OF(OPENSSL_STRING) *ret = NULL;
573 X509_NAME_ENTRY *ne;
574 ASN1_IA5STRING *email;
575 GENERAL_NAME *gen;
576 int i;
577 /* Now add any email address(es) to STACK */
578 i = -1;
579 /* First supplied X509_NAME */
580 while ((i = X509_NAME_get_index_by_NID(name,
581 NID_pkcs9_emailAddress, i)) >= 0) {
582 ne = X509_NAME_get_entry(name, i);
583 email = X509_NAME_ENTRY_get_data(ne);
584 if (!append_ia5(&ret, email))
585 return NULL;
586 }
587 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
588 gen = sk_GENERAL_NAME_value(gens, i);
589 if (gen->type != GEN_EMAIL)
590 continue;
591 if (!append_ia5(&ret, gen->d.ia5))
592 return NULL;
593 }
594 return ret;
a91dedca
DSH
595}
596
c869da88 597static void str_free(OPENSSL_STRING str)
a91dedca 598{
0f113f3e 599 OPENSSL_free(str);
a91dedca
DSH
600}
601
c869da88 602static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
a91dedca 603{
0f113f3e
MC
604 char *emtmp;
605 /* First some sanity checks */
606 if (email->type != V_ASN1_IA5STRING)
607 return 1;
608 if (!email->data || !email->length)
609 return 1;
610 if (!*sk)
611 *sk = sk_OPENSSL_STRING_new(sk_strcmp);
612 if (!*sk)
613 return 0;
614 /* Don't add duplicates */
615 if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
616 return 1;
617 emtmp = BUF_strdup((char *)email->data);
618 if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
619 X509_email_free(*sk);
620 *sk = NULL;
621 return 0;
622 }
623 return 1;
a91dedca
DSH
624}
625
c869da88 626void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
a91dedca 627{
0f113f3e 628 sk_OPENSSL_STRING_pop_free(sk, str_free);
a91dedca 629}
4e5d3a7f 630
0f113f3e
MC
631typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
632 const unsigned char *subject, size_t subject_len,
633 unsigned int flags);
d88926f1 634
a09e4d24
VD
635/* Skip pattern prefix to match "wildcard" subject */
636static void skip_prefix(const unsigned char **p, size_t *plen,
0f113f3e
MC
637 const unsigned char *subject, size_t subject_len,
638 unsigned int flags)
639{
640 const unsigned char *pattern = *p;
641 size_t pattern_len = *plen;
642
643 /*
644 * If subject starts with a leading '.' followed by more octets, and
645 * pattern is longer, compare just an equal-length suffix with the
646 * full subject (starting at the '.'), provided the prefix contains
647 * no NULs.
648 */
649 if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
650 return;
651
652 while (pattern_len > subject_len && *pattern) {
653 if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
654 *pattern == '.')
655 break;
656 ++pattern;
657 --pattern_len;
658 }
659
660 /* Skip if entire prefix acceptable */
661 if (pattern_len == subject_len) {
662 *p = pattern;
663 *plen = pattern_len;
664 }
665}
a09e4d24 666
d88926f1
DSH
667/* Compare while ASCII ignoring case. */
668static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
0f113f3e
MC
669 const unsigned char *subject, size_t subject_len,
670 unsigned int flags)
671{
672 skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
673 if (pattern_len != subject_len)
674 return 0;
675 while (pattern_len) {
676 unsigned char l = *pattern;
677 unsigned char r = *subject;
678 /* The pattern must not contain NUL characters. */
679 if (l == 0)
680 return 0;
681 if (l != r) {
682 if ('A' <= l && l <= 'Z')
683 l = (l - 'A') + 'a';
684 if ('A' <= r && r <= 'Z')
685 r = (r - 'A') + 'a';
686 if (l != r)
687 return 0;
688 }
689 ++pattern;
690 ++subject;
691 --pattern_len;
692 }
693 return 1;
694}
d88926f1
DSH
695
696/* Compare using memcmp. */
697static int equal_case(const unsigned char *pattern, size_t pattern_len,
0f113f3e
MC
698 const unsigned char *subject, size_t subject_len,
699 unsigned int flags)
d88926f1 700{
0f113f3e
MC
701 skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
702 if (pattern_len != subject_len)
703 return 0;
704 return !memcmp(pattern, subject, pattern_len);
d88926f1
DSH
705}
706
0f113f3e
MC
707/*
708 * RFC 5280, section 7.5, requires that only the domain is compared in a
709 * case-insensitive manner.
710 */
d88926f1 711static int equal_email(const unsigned char *a, size_t a_len,
0f113f3e
MC
712 const unsigned char *b, size_t b_len,
713 unsigned int unused_flags)
714{
715 size_t i = a_len;
716 if (a_len != b_len)
717 return 0;
718 /*
719 * We search backwards for the '@' character, so that we do not have to
720 * deal with quoted local-parts. The domain part is compared in a
721 * case-insensitive manner.
722 */
723 while (i > 0) {
724 --i;
725 if (a[i] == '@' || b[i] == '@') {
726 if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
727 return 0;
728 break;
729 }
730 }
731 if (i == 0)
732 i = a_len;
733 return equal_case(a, i, b, i, 0);
734}
735
736/*
737 * Compare the prefix and suffix with the subject, and check that the
738 * characters in-between are valid.
739 */
d88926f1 740static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
0f113f3e
MC
741 const unsigned char *suffix, size_t suffix_len,
742 const unsigned char *subject, size_t subject_len,
743 unsigned int flags)
744{
745 const unsigned char *wildcard_start;
746 const unsigned char *wildcard_end;
747 const unsigned char *p;
748 int allow_multi = 0;
749 int allow_idna = 0;
750
751 if (subject_len < prefix_len + suffix_len)
752 return 0;
753 if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
754 return 0;
755 wildcard_start = subject + prefix_len;
756 wildcard_end = subject + (subject_len - suffix_len);
757 if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
758 return 0;
759 /*
760 * If the wildcard makes up the entire first label, it must match at
761 * least one character.
762 */
763 if (prefix_len == 0 && *suffix == '.') {
764 if (wildcard_start == wildcard_end)
765 return 0;
766 allow_idna = 1;
767 if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
768 allow_multi = 1;
769 }
770 /* IDNA labels cannot match partial wildcards */
771 if (!allow_idna &&
772 subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
773 return 0;
774 /* The wildcard may match a literal '*' */
775 if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
776 return 1;
777 /*
778 * Check that the part matched by the wildcard contains only
779 * permitted characters and only matches a single label unless
780 * allow_multi is set.
781 */
782 for (p = wildcard_start; p != wildcard_end; ++p)
783 if (!(('0' <= *p && *p <= '9') ||
784 ('A' <= *p && *p <= 'Z') ||
785 ('a' <= *p && *p <= 'z') ||
786 *p == '-' || (allow_multi && *p == '.')))
787 return 0;
788 return 1;
789}
790
791#define LABEL_START (1 << 0)
792#define LABEL_END (1 << 1)
793#define LABEL_HYPHEN (1 << 2)
794#define LABEL_IDNA (1 << 3)
d88926f1 795
397a8e74 796static const unsigned char *valid_star(const unsigned char *p, size_t len,
0f113f3e
MC
797 unsigned int flags)
798{
799 const unsigned char *star = 0;
800 size_t i;
801 int state = LABEL_START;
802 int dots = 0;
803 for (i = 0; i < len; ++i) {
804 /*
805 * Locate first and only legal wildcard, either at the start
806 * or end of a non-IDNA first and not final label.
807 */
808 if (p[i] == '*') {
809 int atstart = (state & LABEL_START);
810 int atend = (i == len - 1 || p[i + i] == '.');
811 /*-
812 * At most one wildcard per pattern.
813 * No wildcards in IDNA labels.
814 * No wildcards after the first label.
815 */
816 if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
817 return NULL;
818 /* Only full-label '*.example.com' wildcards? */
819 if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
820 && (!atstart || !atend))
821 return NULL;
822 /* No 'foo*bar' wildcards */
823 if (!atstart && !atend)
824 return NULL;
825 star = &p[i];
826 state &= ~LABEL_START;
827 } else if (('a' <= p[i] && p[i] <= 'z')
828 || ('A' <= p[i] && p[i] <= 'Z')
829 || ('0' <= p[i] && p[i] <= '9')) {
830 if ((state & LABEL_START) != 0
831 && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
832 state |= LABEL_IDNA;
833 state &= ~(LABEL_HYPHEN | LABEL_START);
834 } else if (p[i] == '.') {
835 if ((state & (LABEL_HYPHEN | LABEL_START)) != 0)
836 return NULL;
837 state = LABEL_START;
838 ++dots;
839 } else if (p[i] == '-') {
840 if ((state & LABEL_HYPHEN) != 0)
841 return NULL;
842 state |= LABEL_HYPHEN;
843 } else
844 return NULL;
845 }
846
847 /*
848 * The final label must not end in a hyphen or ".", and
849 * there must be at least two dots after the star.
850 */
851 if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
852 return NULL;
853 return star;
854}
d88926f1
DSH
855
856/* Compare using wildcards. */
857static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
0f113f3e
MC
858 const unsigned char *subject, size_t subject_len,
859 unsigned int flags)
860{
861 const unsigned char *star = NULL;
862
863 /*
864 * Subject names starting with '.' can only match a wildcard pattern
865 * via a subject sub-domain pattern suffix match.
866 */
867 if (!(subject_len > 1 && subject[0] == '.'))
868 star = valid_star(pattern, pattern_len, flags);
869 if (star == NULL)
870 return equal_nocase(pattern, pattern_len,
871 subject, subject_len, flags);
872 return wildcard_match(pattern, star - pattern,
873 star + 1, (pattern + pattern_len) - star - 1,
874 subject, subject_len, flags);
875}
876
877/*
878 * Compare an ASN1_STRING to a supplied string. If they match return 1. If
879 * cmp_type > 0 only compare if string matches the type, otherwise convert it
880 * to UTF8.
a70da5b3
DSH
881 */
882
d88926f1 883static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
0f113f3e
MC
884 unsigned int flags, const char *b, size_t blen,
885 char **peername)
886{
887 int rv = 0;
888
889 if (!a->data || !a->length)
890 return 0;
891 if (cmp_type > 0) {
892 if (cmp_type != a->type)
893 return 0;
894 if (cmp_type == V_ASN1_IA5STRING)
895 rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
896 else if (a->length == (int)blen && !memcmp(a->data, b, blen))
897 rv = 1;
898 if (rv > 0 && peername)
899 *peername = BUF_strndup((char *)a->data, a->length);
900 } else {
901 int astrlen;
902 unsigned char *astr;
903 astrlen = ASN1_STRING_to_UTF8(&astr, a);
904 if (astrlen < 0)
905 return -1;
906 rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
907 if (rv > 0 && peername)
908 *peername = BUF_strndup((char *)astr, astrlen);
909 OPENSSL_free(astr);
910 }
911 return rv;
912}
a70da5b3 913
297c67fc 914static int do_x509_check(X509 *x, const char *chk, size_t chklen,
0f113f3e
MC
915 unsigned int flags, int check_type, char **peername)
916{
917 GENERAL_NAMES *gens = NULL;
918 X509_NAME *name = NULL;
919 int i;
920 int cnid;
921 int alt_type;
922 int san_present = 0;
923 int rv = 0;
924 equal_fn equal;
925
926 /* See below, this flag is internal-only */
927 flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
928 if (check_type == GEN_EMAIL) {
929 cnid = NID_pkcs9_emailAddress;
930 alt_type = V_ASN1_IA5STRING;
931 equal = equal_email;
932 } else if (check_type == GEN_DNS) {
933 cnid = NID_commonName;
934 /* Implicit client-side DNS sub-domain pattern */
935 if (chklen > 1 && chk[0] == '.')
936 flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
937 alt_type = V_ASN1_IA5STRING;
938 if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
939 equal = equal_nocase;
940 else
941 equal = equal_wildcard;
942 } else {
943 cnid = 0;
944 alt_type = V_ASN1_OCTET_STRING;
945 equal = equal_case;
946 }
947
948 if (chklen == 0)
949 chklen = strlen(chk);
950
951 gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
952 if (gens) {
953 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
954 GENERAL_NAME *gen;
955 ASN1_STRING *cstr;
956 gen = sk_GENERAL_NAME_value(gens, i);
957 if (gen->type != check_type)
958 continue;
959 san_present = 1;
960 if (check_type == GEN_EMAIL)
961 cstr = gen->d.rfc822Name;
962 else if (check_type == GEN_DNS)
963 cstr = gen->d.dNSName;
964 else
965 cstr = gen->d.iPAddress;
966 /* Positive on success, negative on error! */
967 if ((rv = do_check_string(cstr, alt_type, equal, flags,
968 chk, chklen, peername)) != 0)
969 break;
970 }
971 GENERAL_NAMES_free(gens);
972 if (rv != 0)
973 return rv;
974 if (!cnid
975 || (san_present
976 && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
977 return 0;
978 }
979 i = -1;
980 name = X509_get_subject_name(x);
981 while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
982 X509_NAME_ENTRY *ne;
983 ASN1_STRING *str;
984 ne = X509_NAME_get_entry(name, i);
985 str = X509_NAME_ENTRY_get_data(ne);
986 /* Positive on success, negative on error! */
987 if ((rv = do_check_string(str, -1, equal, flags,
988 chk, chklen, peername)) != 0)
989 return rv;
990 }
991 return 0;
992}
a70da5b3 993
297c67fc 994int X509_check_host(X509 *x, const char *chk, size_t chklen,
0f113f3e
MC
995 unsigned int flags, char **peername)
996{
997 if (chk == NULL)
998 return -2;
999 /*
1000 * Embedded NULs are disallowed, except as the last character of a
1001 * string of length 2 or more (tolerate caller including terminating
1002 * NUL in string length).
1003 */
1004 if (chklen == 0)
1005 chklen = strlen(chk);
1006 else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
1007 return -2;
1008 if (chklen > 1 && chk[chklen - 1] == '\0')
1009 --chklen;
1010 return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
1011}
a70da5b3 1012
297c67fc 1013int X509_check_email(X509 *x, const char *chk, size_t chklen,
0f113f3e
MC
1014 unsigned int flags)
1015{
1016 if (chk == NULL)
1017 return -2;
1018 /*
1019 * Embedded NULs are disallowed, except as the last character of a
1020 * string of length 2 or more (tolerate caller including terminating
1021 * NUL in string length).
1022 */
1023 if (chklen == 0)
1024 chklen = strlen((char *)chk);
1025 else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
1026 return -2;
1027 if (chklen > 1 && chk[chklen - 1] == '\0')
1028 --chklen;
1029 return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
1030}
a70da5b3
DSH
1031
1032int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
0f113f3e
MC
1033 unsigned int flags)
1034{
1035 if (chk == NULL)
1036 return -2;
1037 return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
1038}
a70da5b3
DSH
1039
1040int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
0f113f3e
MC
1041{
1042 unsigned char ipout[16];
1043 size_t iplen;
1044
1045 if (ipasc == NULL)
1046 return -2;
1047 iplen = (size_t)a2i_ipadd(ipout, ipasc);
1048 if (iplen == 0)
1049 return -2;
1050 return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
1051}
1052
1053/*
1054 * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
1055 * with RFC3280.
4e5d3a7f
DSH
1056 */
1057
1058ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
0f113f3e
MC
1059{
1060 unsigned char ipout[16];
1061 ASN1_OCTET_STRING *ret;
1062 int iplen;
4e5d3a7f 1063
0f113f3e 1064 /* If string contains a ':' assume IPv6 */
4e5d3a7f 1065
0f113f3e 1066 iplen = a2i_ipadd(ipout, ipasc);
520b76ff 1067
0f113f3e
MC
1068 if (!iplen)
1069 return NULL;
4e5d3a7f 1070
0f113f3e
MC
1071 ret = ASN1_OCTET_STRING_new();
1072 if (!ret)
1073 return NULL;
1074 if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
1075 ASN1_OCTET_STRING_free(ret);
1076 return NULL;
1077 }
1078 return ret;
1079}
4e5d3a7f 1080
520b76ff 1081ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
0f113f3e
MC
1082{
1083 ASN1_OCTET_STRING *ret = NULL;
1084 unsigned char ipout[32];
1085 char *iptmp = NULL, *p;
1086 int iplen1, iplen2;
1087 p = strchr(ipasc, '/');
1088 if (!p)
1089 return NULL;
1090 iptmp = BUF_strdup(ipasc);
1091 if (!iptmp)
1092 return NULL;
1093 p = iptmp + (p - ipasc);
1094 *p++ = 0;
1095
1096 iplen1 = a2i_ipadd(ipout, iptmp);
1097
1098 if (!iplen1)
1099 goto err;
1100
1101 iplen2 = a2i_ipadd(ipout + iplen1, p);
1102
1103 OPENSSL_free(iptmp);
1104 iptmp = NULL;
1105
1106 if (!iplen2 || (iplen1 != iplen2))
1107 goto err;
1108
1109 ret = ASN1_OCTET_STRING_new();
1110 if (!ret)
1111 goto err;
1112 if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
1113 goto err;
1114
1115 return ret;
1116
1117 err:
1118 if (iptmp)
1119 OPENSSL_free(iptmp);
1120 if (ret)
1121 ASN1_OCTET_STRING_free(ret);
1122 return NULL;
1123}
520b76ff 1124
96ea4ae9 1125int a2i_ipadd(unsigned char *ipout, const char *ipasc)
0f113f3e
MC
1126{
1127 /* If string contains a ':' assume IPv6 */
1128
1129 if (strchr(ipasc, ':')) {
1130 if (!ipv6_from_asc(ipout, ipasc))
1131 return 0;
1132 return 16;
1133 } else {
1134 if (!ipv4_from_asc(ipout, ipasc))
1135 return 0;
1136 return 4;
1137 }
1138}
520b76ff 1139
4e5d3a7f 1140static int ipv4_from_asc(unsigned char *v4, const char *in)
0f113f3e
MC
1141{
1142 int a0, a1, a2, a3;
1143 if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
1144 return 0;
1145 if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
1146 || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
1147 return 0;
1148 v4[0] = a0;
1149 v4[1] = a1;
1150 v4[2] = a2;
1151 v4[3] = a3;
1152 return 1;
1153}
4e5d3a7f
DSH
1154
1155typedef struct {
0f113f3e
MC
1156 /* Temporary store for IPV6 output */
1157 unsigned char tmp[16];
1158 /* Total number of bytes in tmp */
1159 int total;
1160 /* The position of a zero (corresponding to '::') */
1161 int zero_pos;
1162 /* Number of zeroes */
1163 int zero_cnt;
1164} IPV6_STAT;
4e5d3a7f
DSH
1165
1166static int ipv6_from_asc(unsigned char *v6, const char *in)
0f113f3e
MC
1167{
1168 IPV6_STAT v6stat;
1169 v6stat.total = 0;
1170 v6stat.zero_pos = -1;
1171 v6stat.zero_cnt = 0;
1172 /*
1173 * Treat the IPv6 representation as a list of values separated by ':'.
1174 * The presence of a '::' will parse as one, two or three zero length
1175 * elements.
1176 */
1177 if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
1178 return 0;
1179
1180 /* Now for some sanity checks */
1181
1182 if (v6stat.zero_pos == -1) {
1183 /* If no '::' must have exactly 16 bytes */
1184 if (v6stat.total != 16)
1185 return 0;
1186 } else {
1187 /* If '::' must have less than 16 bytes */
1188 if (v6stat.total == 16)
1189 return 0;
1190 /* More than three zeroes is an error */
1191 if (v6stat.zero_cnt > 3)
1192 return 0;
1193 /* Can only have three zeroes if nothing else present */
1194 else if (v6stat.zero_cnt == 3) {
1195 if (v6stat.total > 0)
1196 return 0;
1197 }
1198 /* Can only have two zeroes if at start or end */
1199 else if (v6stat.zero_cnt == 2) {
1200 if ((v6stat.zero_pos != 0)
1201 && (v6stat.zero_pos != v6stat.total))
1202 return 0;
1203 } else
1204 /* Can only have one zero if *not* start or end */
1205 {
1206 if ((v6stat.zero_pos == 0)
1207 || (v6stat.zero_pos == v6stat.total))
1208 return 0;
1209 }
1210 }
1211
1212 /* Format result */
1213
1214 if (v6stat.zero_pos >= 0) {
1215 /* Copy initial part */
1216 memcpy(v6, v6stat.tmp, v6stat.zero_pos);
1217 /* Zero middle */
1218 memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
1219 /* Copy final part */
1220 if (v6stat.total != v6stat.zero_pos)
1221 memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
1222 v6stat.tmp + v6stat.zero_pos,
1223 v6stat.total - v6stat.zero_pos);
1224 } else
1225 memcpy(v6, v6stat.tmp, 16);
1226
1227 return 1;
1228}
4e5d3a7f
DSH
1229
1230static int ipv6_cb(const char *elem, int len, void *usr)
0f113f3e
MC
1231{
1232 IPV6_STAT *s = usr;
1233 /* Error if 16 bytes written */
1234 if (s->total == 16)
1235 return 0;
1236 if (len == 0) {
1237 /* Zero length element, corresponds to '::' */
1238 if (s->zero_pos == -1)
1239 s->zero_pos = s->total;
1240 /* If we've already got a :: its an error */
1241 else if (s->zero_pos != s->total)
1242 return 0;
1243 s->zero_cnt++;
1244 } else {
1245 /* If more than 4 characters could be final a.b.c.d form */
1246 if (len > 4) {
1247 /* Need at least 4 bytes left */
1248 if (s->total > 12)
1249 return 0;
1250 /* Must be end of string */
1251 if (elem[len])
1252 return 0;
1253 if (!ipv4_from_asc(s->tmp + s->total, elem))
1254 return 0;
1255 s->total += 4;
1256 } else {
1257 if (!ipv6_hex(s->tmp + s->total, elem, len))
1258 return 0;
1259 s->total += 2;
1260 }
1261 }
1262 return 1;
1263}
1264
1265/*
1266 * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
4e5d3a7f
DSH
1267 */
1268
1269static int ipv6_hex(unsigned char *out, const char *in, int inlen)
0f113f3e
MC
1270{
1271 unsigned char c;
1272 unsigned int num = 0;
1273 if (inlen > 4)
1274 return 0;
1275 while (inlen--) {
1276 c = *in++;
1277 num <<= 4;
1278 if ((c >= '0') && (c <= '9'))
1279 num |= c - '0';
1280 else if ((c >= 'A') && (c <= 'F'))
1281 num |= c - 'A' + 10;
1282 else if ((c >= 'a') && (c <= 'f'))
1283 num |= c - 'a' + 10;
1284 else
1285 return 0;
1286 }
1287 out[0] = num >> 8;
1288 out[1] = num & 0xff;
1289 return 1;
1290}
f0dc08e6 1291
a7b1eed5 1292int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
0f113f3e
MC
1293 unsigned long chtype)
1294{
1295 CONF_VALUE *v;
1296 int i, mval;
1297 char *p, *type;
1298 if (!nm)
1299 return 0;
1300
1301 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1302 v = sk_CONF_VALUE_value(dn_sk, i);
1303 type = v->name;
1304 /*
1305 * Skip past any leading X. X: X, etc to allow for multiple instances
1306 */
1307 for (p = type; *p; p++)
f0dc08e6 1308#ifndef CHARSET_EBCDIC
0f113f3e 1309 if ((*p == ':') || (*p == ',') || (*p == '.'))
f0dc08e6 1310#else
0f113f3e
MC
1311 if ((*p == os_toascii[':']) || (*p == os_toascii[','])
1312 || (*p == os_toascii['.']))
f0dc08e6 1313#endif
0f113f3e
MC
1314 {
1315 p++;
1316 if (*p)
1317 type = p;
1318 break;
1319 }
1a15c899 1320#ifndef CHARSET_EBCDIC
0f113f3e 1321 if (*type == '+')
1a15c899 1322#else
0f113f3e 1323 if (*type == os_toascii['+'])
1a15c899 1324#endif
0f113f3e
MC
1325 {
1326 mval = -1;
1327 type++;
1328 } else
1329 mval = 0;
1330 if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
1331 (unsigned char *)v->value, -1, -1,
1332 mval))
1333 return 0;
1334
1335 }
1336 return 1;
1337}