Merge branch 'vendor/LIBRESSL'
[dragonfly.git] / crypto / libressl / crypto / x509v3 / v3_utl.c
1 /* $OpenBSD: v3_utl.c,v 1.23 2014/07/13 16:03:10 beck Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999-2003 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 <ctype.h>
61 #include <stdio.h>
62 #include <string.h>
63
64 #include <openssl/bn.h>
65 #include <openssl/conf.h>
66 #include <openssl/err.h>
67 #include <openssl/x509v3.h>
68
69 static char *strip_spaces(char *name);
70 static int sk_strcmp(const char * const *a, const char * const *b);
71 static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
72     GENERAL_NAMES *gens);
73 static void str_free(OPENSSL_STRING str);
74 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
75
76 static int ipv4_from_asc(unsigned char *v4, const char *in);
77 static int ipv6_from_asc(unsigned char *v6, const char *in);
78 static int ipv6_cb(const char *elem, int len, void *usr);
79 static int ipv6_hex(unsigned char *out, const char *in, int inlen);
80
81 /* Add a CONF_VALUE name value pair to stack */
82
83 int
84 X509V3_add_value(const char *name, const char *value,
85     STACK_OF(CONF_VALUE) **extlist)
86 {
87         CONF_VALUE *vtmp = NULL;
88         char *tname = NULL, *tvalue = NULL;
89
90         if (name && !(tname = strdup(name)))
91                 goto err;
92         if (value && !(tvalue = strdup(value)))
93                 goto err;
94         if (!(vtmp = malloc(sizeof(CONF_VALUE))))
95                 goto err;
96         if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null()))
97                 goto err;
98         vtmp->section = NULL;
99         vtmp->name = tname;
100         vtmp->value = tvalue;
101         if (!sk_CONF_VALUE_push(*extlist, vtmp))
102                 goto err;
103         return 1;
104
105 err:
106         X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE);
107         free(vtmp);
108         free(tname);
109         free(tvalue);
110         return 0;
111 }
112
113 int
114 X509V3_add_value_uchar(const char *name, const unsigned char *value,
115     STACK_OF(CONF_VALUE) **extlist)
116 {
117         return X509V3_add_value(name, (const char *)value, extlist);
118 }
119
120 /* Free function for STACK_OF(CONF_VALUE) */
121
122 void
123 X509V3_conf_free(CONF_VALUE *conf)
124 {
125         if (!conf)
126                 return;
127         free(conf->name);
128         free(conf->value);
129         free(conf->section);
130         free(conf);
131 }
132
133 int
134 X509V3_add_value_bool(const char *name, int asn1_bool,
135     STACK_OF(CONF_VALUE) **extlist)
136 {
137         if (asn1_bool)
138                 return X509V3_add_value(name, "TRUE", extlist);
139         return X509V3_add_value(name, "FALSE", extlist);
140 }
141
142 int
143 X509V3_add_value_bool_nf(char *name, int asn1_bool,
144     STACK_OF(CONF_VALUE) **extlist)
145 {
146         if (asn1_bool)
147                 return X509V3_add_value(name, "TRUE", extlist);
148         return 1;
149 }
150
151
152 char *
153 i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
154 {
155         BIGNUM *bntmp = NULL;
156         char *strtmp = NULL;
157
158         if (!a)
159                 return NULL;
160         if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
161             !(strtmp = BN_bn2dec(bntmp)))
162                 X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
163         BN_free(bntmp);
164         return strtmp;
165 }
166
167 char *
168 i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
169 {
170         BIGNUM *bntmp = NULL;
171         char *strtmp = NULL;
172
173         if (!a)
174                 return NULL;
175         if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
176             !(strtmp = BN_bn2dec(bntmp)))
177                 X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
178         BN_free(bntmp);
179         return strtmp;
180 }
181
182 ASN1_INTEGER *
183 s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
184 {
185         BIGNUM *bn = NULL;
186         ASN1_INTEGER *aint;
187         int isneg, ishex;
188         int ret;
189
190         if (!value) {
191                 X509V3err(X509V3_F_S2I_ASN1_INTEGER,
192                     X509V3_R_INVALID_NULL_VALUE);
193                 return 0;
194         }
195         bn = BN_new();
196         if (value[0] == '-') {
197                 value++;
198                 isneg = 1;
199         } else
200                 isneg = 0;
201
202         if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
203                 value += 2;
204                 ishex = 1;
205         } else
206                 ishex = 0;
207
208         if (ishex)
209                 ret = BN_hex2bn(&bn, value);
210         else
211                 ret = BN_dec2bn(&bn, value);
212
213         if (!ret || value[ret]) {
214                 BN_free(bn);
215                 X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
216                 return 0;
217         }
218
219         if (isneg && BN_is_zero(bn))
220                 isneg = 0;
221
222         aint = BN_to_ASN1_INTEGER(bn, NULL);
223         BN_free(bn);
224         if (!aint) {
225                 X509V3err(X509V3_F_S2I_ASN1_INTEGER,
226                     X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
227                 return 0;
228         }
229         if (isneg)
230                 aint->type |= V_ASN1_NEG;
231         return aint;
232 }
233
234 int
235 X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
236     STACK_OF(CONF_VALUE) **extlist)
237 {
238         char *strtmp;
239         int ret;
240
241         if (!aint)
242                 return 1;
243         if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
244                 return 0;
245         ret = X509V3_add_value(name, strtmp, extlist);
246         free(strtmp);
247         return ret;
248 }
249
250 int
251 X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
252 {
253         char *btmp;
254
255         if (!(btmp = value->value))
256                 goto err;
257         if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") ||
258             !strcmp(btmp, "Y") || !strcmp(btmp, "y") ||
259             !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
260                 *asn1_bool = 0xff;
261                 return 1;
262         } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") ||
263             !strcmp(btmp, "N") || !strcmp(btmp, "n") ||
264             !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
265                 *asn1_bool = 0;
266                 return 1;
267         }
268
269 err:
270         X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
271             X509V3_R_INVALID_BOOLEAN_STRING);
272         X509V3_conf_err(value);
273         return 0;
274 }
275
276 int
277 X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
278 {
279         ASN1_INTEGER *itmp;
280
281         if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
282                 X509V3_conf_err(value);
283                 return 0;
284         }
285         *aint = itmp;
286         return 1;
287 }
288
289 #define HDR_NAME        1
290 #define HDR_VALUE       2
291
292 /*#define DEBUG*/
293
294 STACK_OF(CONF_VALUE) *
295 X509V3_parse_list(const char *line)
296 {
297         char *p, *q, c;
298         char *ntmp, *vtmp;
299         STACK_OF(CONF_VALUE) *values = NULL;
300         char *linebuf;
301         int state;
302
303         /* We are going to modify the line so copy it first */
304         if ((linebuf = strdup(line)) == NULL) {
305                 X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
306                 goto err;
307         }
308         state = HDR_NAME;
309         ntmp = NULL;
310
311         /* Go through all characters */
312         for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') &&
313             (c != '\n'); p++) {
314
315                 switch (state) {
316                 case HDR_NAME:
317                         if (c == ':') {
318                                 state = HDR_VALUE;
319                                 *p = 0;
320                                 ntmp = strip_spaces(q);
321                                 if (!ntmp) {
322                                         X509V3err(X509V3_F_X509V3_PARSE_LIST,
323                                             X509V3_R_INVALID_NULL_NAME);
324                                         goto err;
325                                 }
326                                 q = p + 1;
327                         } else if (c == ',') {
328                                 *p = 0;
329                                 ntmp = strip_spaces(q);
330                                 q = p + 1;
331                                 if (!ntmp) {
332                                         X509V3err(X509V3_F_X509V3_PARSE_LIST,
333                                             X509V3_R_INVALID_NULL_NAME);
334                                         goto err;
335                                 }
336                                 X509V3_add_value(ntmp, NULL, &values);
337                         }
338                         break;
339
340                 case HDR_VALUE:
341                         if (c == ',') {
342                                 state = HDR_NAME;
343                                 *p = 0;
344                                 vtmp = strip_spaces(q);
345                                 if (!vtmp) {
346                                         X509V3err(X509V3_F_X509V3_PARSE_LIST,
347                                             X509V3_R_INVALID_NULL_VALUE);
348                                         goto err;
349                                 }
350                                 X509V3_add_value(ntmp, vtmp, &values);
351                                 ntmp = NULL;
352                                 q = p + 1;
353                         }
354
355                 }
356         }
357
358         if (state == HDR_VALUE) {
359                 vtmp = strip_spaces(q);
360                 if (!vtmp) {
361                         X509V3err(X509V3_F_X509V3_PARSE_LIST,
362                             X509V3_R_INVALID_NULL_VALUE);
363                         goto err;
364                 }
365                 X509V3_add_value(ntmp, vtmp, &values);
366         } else {
367                 ntmp = strip_spaces(q);
368                 if (!ntmp) {
369                         X509V3err(X509V3_F_X509V3_PARSE_LIST,
370                             X509V3_R_INVALID_NULL_NAME);
371                         goto err;
372                 }
373                 X509V3_add_value(ntmp, NULL, &values);
374         }
375         free(linebuf);
376         return values;
377
378 err:
379         free(linebuf);
380         sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
381         return NULL;
382
383 }
384
385 /* Delete leading and trailing spaces from a string */
386 static char *
387 strip_spaces(char *name)
388 {
389         char *p, *q;
390
391         /* Skip over leading spaces */
392         p = name;
393         while (*p && isspace((unsigned char)*p))
394                 p++;
395         if (!*p)
396                 return NULL;
397         q = p + strlen(p) - 1;
398         while ((q != p) && isspace((unsigned char)*q))
399                 q--;
400         if (p != q)
401                 q[1] = 0;
402         if (!*p)
403                 return NULL;
404         return p;
405 }
406
407 /* hex string utilities */
408
409 /* Given a buffer of length 'len' return a malloc'ed string with its
410  * hex representation
411  */
412 char *
413 hex_to_string(const unsigned char *buffer, long len)
414 {
415         char *tmp, *q;
416         const unsigned char *p;
417         int i;
418         static const char hexdig[] = "0123456789ABCDEF";
419
420         if (!buffer || !len)
421                 return NULL;
422         if (!(tmp = malloc(len * 3 + 1))) {
423                 X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE);
424                 return NULL;
425         }
426         q = tmp;
427         for (i = 0, p = buffer; i < len; i++, p++) {
428                 *q++ = hexdig[(*p >> 4) & 0xf];
429                 *q++ = hexdig[*p & 0xf];
430                 *q++ = ':';
431         }
432         q[-1] = 0;
433         return tmp;
434 }
435
436 /* Give a string of hex digits convert to
437  * a buffer
438  */
439
440 unsigned char *
441 string_to_hex(const char *str, long *len)
442 {
443         unsigned char *hexbuf, *q;
444         unsigned char ch, cl, *p;
445         if (!str) {
446                 X509V3err(X509V3_F_STRING_TO_HEX,
447                     X509V3_R_INVALID_NULL_ARGUMENT);
448                 return NULL;
449         }
450         if (!(hexbuf = malloc(strlen(str) >> 1)))
451                 goto err;
452         for (p = (unsigned char *)str, q = hexbuf; *p; ) {
453                 ch = *p++;
454                 if (ch == ':')
455                         continue;
456                 cl = *p++;
457                 if (!cl) {
458                         X509V3err(X509V3_F_STRING_TO_HEX,
459                             X509V3_R_ODD_NUMBER_OF_DIGITS);
460                         free(hexbuf);
461                         return NULL;
462                 }
463                 ch = tolower(ch);
464                 cl = tolower(cl);
465
466                 if ((ch >= '0') && (ch <= '9'))
467                         ch -= '0';
468                 else if ((ch >= 'a') && (ch <= 'f'))
469                         ch -= 'a' - 10;
470                 else
471                         goto badhex;
472
473                 if ((cl >= '0') && (cl <= '9'))
474                         cl -= '0';
475                 else if ((cl >= 'a') && (cl <= 'f'))
476                         cl -= 'a' - 10;
477                 else
478                         goto badhex;
479
480                 *q++ = (ch << 4) | cl;
481         }
482
483         if (len)
484                 *len = q - hexbuf;
485
486         return hexbuf;
487
488 err:
489         free(hexbuf);
490         X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE);
491         return NULL;
492
493 badhex:
494         free(hexbuf);
495         X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT);
496         return NULL;
497 }
498
499 /* V2I name comparison function: returns zero if 'name' matches
500  * cmp or cmp.*
501  */
502
503 int
504 name_cmp(const char *name, const char *cmp)
505 {
506         int len, ret;
507         char c;
508
509         len = strlen(cmp);
510         if ((ret = strncmp(name, cmp, len)))
511                 return ret;
512         c = name[len];
513         if (!c || (c=='.'))
514                 return 0;
515         return 1;
516 }
517
518 static int
519 sk_strcmp(const char * const *a, const char * const *b)
520 {
521         return strcmp(*a, *b);
522 }
523
524 STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
525 {
526         GENERAL_NAMES *gens;
527         STACK_OF(OPENSSL_STRING) *ret;
528
529         gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
530         ret = get_email(X509_get_subject_name(x), gens);
531         sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
532         return ret;
533 }
534
535 STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
536 {
537         AUTHORITY_INFO_ACCESS *info;
538         STACK_OF(OPENSSL_STRING) *ret = NULL;
539         int i;
540
541         info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
542         if (!info)
543                 return NULL;
544         for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
545                 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
546                 if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
547                         if (ad->location->type == GEN_URI) {
548                                 if (!append_ia5(&ret,
549                                     ad->location->d.uniformResourceIdentifier))
550                                         break;
551                         }
552                 }
553         }
554         AUTHORITY_INFO_ACCESS_free(info);
555         return ret;
556 }
557
558 STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
559 {
560         GENERAL_NAMES *gens;
561         STACK_OF(X509_EXTENSION) *exts;
562         STACK_OF(OPENSSL_STRING) *ret;
563
564         exts = X509_REQ_get_extensions(x);
565         gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
566         ret = get_email(X509_REQ_get_subject_name(x), gens);
567         sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
568         sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
569         return ret;
570 }
571
572
573 static
574 STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, GENERAL_NAMES *gens)
575 {
576         STACK_OF(OPENSSL_STRING) *ret = NULL;
577         X509_NAME_ENTRY *ne;
578         ASN1_IA5STRING *email;
579         GENERAL_NAME *gen;
580         int i;
581
582         /* Now add any email address(es) to STACK */
583         i = -1;
584
585         /* First supplied X509_NAME */
586         while ((i = X509_NAME_get_index_by_NID(name,
587             NID_pkcs9_emailAddress, i)) >= 0) {
588                 ne = X509_NAME_get_entry(name, i);
589                 email = X509_NAME_ENTRY_get_data(ne);
590                 if (!append_ia5(&ret, email))
591                         return NULL;
592         }
593         for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
594                 gen = sk_GENERAL_NAME_value(gens, i);
595                 if (gen->type != GEN_EMAIL)
596                         continue;
597                 if (!append_ia5(&ret, gen->d.ia5))
598                         return NULL;
599         }
600         return ret;
601 }
602
603 static void
604 str_free(OPENSSL_STRING str)
605 {
606         free(str);
607 }
608
609 static int
610 append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
611 {
612         char *emtmp;
613
614         /* First some sanity checks */
615         if (email->type != V_ASN1_IA5STRING)
616                 return 1;
617         if (!email->data || !email->length)
618                 return 1;
619         if (!*sk)
620                 *sk = sk_OPENSSL_STRING_new(sk_strcmp);
621         if (!*sk)
622                 return 0;
623         /* Don't add duplicates */
624         if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
625                 return 1;
626         emtmp = strdup((char *)email->data);
627         if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
628                 X509_email_free(*sk);
629                 *sk = NULL;
630                 return 0;
631         }
632         return 1;
633 }
634
635 void
636 X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
637 {
638         sk_OPENSSL_STRING_pop_free(sk, str_free);
639 }
640
641 /* Convert IP addresses both IPv4 and IPv6 into an
642  * OCTET STRING compatible with RFC3280.
643  */
644
645 ASN1_OCTET_STRING *
646 a2i_IPADDRESS(const char *ipasc)
647 {
648         unsigned char ipout[16];
649         ASN1_OCTET_STRING *ret;
650         int iplen;
651
652         /* If string contains a ':' assume IPv6 */
653
654         iplen = a2i_ipadd(ipout, ipasc);
655
656         if (!iplen)
657                 return NULL;
658
659         ret = ASN1_OCTET_STRING_new();
660         if (!ret)
661                 return NULL;
662         if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
663                 ASN1_OCTET_STRING_free(ret);
664                 return NULL;
665         }
666         return ret;
667 }
668
669 ASN1_OCTET_STRING *
670 a2i_IPADDRESS_NC(const char *ipasc)
671 {
672         ASN1_OCTET_STRING *ret = NULL;
673         unsigned char ipout[32];
674         char *iptmp = NULL, *p;
675         int iplen1, iplen2;
676
677         p = strchr(ipasc, '/');
678         if (!p)
679                 return NULL;
680         iptmp = strdup(ipasc);
681         if (!iptmp)
682                 return NULL;
683         p = iptmp + (p - ipasc);
684         *p++ = 0;
685
686         iplen1 = a2i_ipadd(ipout, iptmp);
687
688         if (!iplen1)
689                 goto err;
690
691         iplen2 = a2i_ipadd(ipout + iplen1, p);
692
693         free(iptmp);
694         iptmp = NULL;
695
696         if (!iplen2 || (iplen1 != iplen2))
697                 goto err;
698
699         ret = ASN1_OCTET_STRING_new();
700         if (!ret)
701                 goto err;
702         if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
703                 goto err;
704
705         return ret;
706
707 err:
708         free(iptmp);
709         if (ret)
710                 ASN1_OCTET_STRING_free(ret);
711         return NULL;
712 }
713
714
715 int
716 a2i_ipadd(unsigned char *ipout, const char *ipasc)
717 {
718         /* If string contains a ':' assume IPv6 */
719
720         if (strchr(ipasc, ':')) {
721                 if (!ipv6_from_asc(ipout, ipasc))
722                         return 0;
723                 return 16;
724         } else {
725                 if (!ipv4_from_asc(ipout, ipasc))
726                         return 0;
727                 return 4;
728         }
729 }
730
731 static int
732 ipv4_from_asc(unsigned char *v4, const char *in)
733 {
734         int a0, a1, a2, a3;
735         if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
736                 return 0;
737         if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) ||
738             (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
739                 return 0;
740         v4[0] = a0;
741         v4[1] = a1;
742         v4[2] = a2;
743         v4[3] = a3;
744         return 1;
745 }
746
747 typedef struct {
748         /* Temporary store for IPV6 output */
749         unsigned char tmp[16];
750         /* Total number of bytes in tmp */
751         int total;
752         /* The position of a zero (corresponding to '::') */
753         int zero_pos;
754         /* Number of zeroes */
755         int zero_cnt;
756 } IPV6_STAT;
757
758
759 static int
760 ipv6_from_asc(unsigned char *v6, const char *in)
761 {
762         IPV6_STAT v6stat;
763
764         v6stat.total = 0;
765         v6stat.zero_pos = -1;
766         v6stat.zero_cnt = 0;
767
768         /* Treat the IPv6 representation as a list of values
769          * separated by ':'. The presence of a '::' will parse
770          * as one, two or three zero length elements.
771          */
772         if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
773                 return 0;
774
775         /* Now for some sanity checks */
776
777         if (v6stat.zero_pos == -1) {
778                 /* If no '::' must have exactly 16 bytes */
779                 if (v6stat.total != 16)
780                         return 0;
781         } else {
782                 /* If '::' must have less than 16 bytes */
783                 if (v6stat.total == 16)
784                         return 0;
785                 /* More than three zeroes is an error */
786                 if (v6stat.zero_cnt > 3)
787                         return 0;
788                 /* Can only have three zeroes if nothing else present */
789                 else if (v6stat.zero_cnt == 3) {
790                         if (v6stat.total > 0)
791                                 return 0;
792                 }
793                 /* Can only have two zeroes if at start or end */
794                 else if (v6stat.zero_cnt == 2) {
795                         if ((v6stat.zero_pos != 0) &&
796                             (v6stat.zero_pos != v6stat.total))
797                                 return 0;
798                 } else
799                         /* Can only have one zero if *not* start or end */
800                 {
801                         if ((v6stat.zero_pos == 0) ||
802                             (v6stat.zero_pos == v6stat.total))
803                                 return 0;
804                 }
805         }
806
807         /* Format result */
808
809         if (v6stat.zero_pos >= 0) {
810                 /* Copy initial part */
811                 memcpy(v6, v6stat.tmp, v6stat.zero_pos);
812                 /* Zero middle */
813                 memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
814                 /* Copy final part */
815                 if (v6stat.total != v6stat.zero_pos)
816                         memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
817                             v6stat.tmp + v6stat.zero_pos,
818                             v6stat.total - v6stat.zero_pos);
819         } else
820                 memcpy(v6, v6stat.tmp, 16);
821
822         return 1;
823 }
824
825 static int
826 ipv6_cb(const char *elem, int len, void *usr)
827 {
828         IPV6_STAT *s = usr;
829
830         /* Error if 16 bytes written */
831         if (s->total == 16)
832                 return 0;
833         if (len == 0) {
834                 /* Zero length element, corresponds to '::' */
835                 if (s->zero_pos == -1)
836                         s->zero_pos = s->total;
837                 /* If we've already got a :: its an error */
838                 else if (s->zero_pos != s->total)
839                         return 0;
840                 s->zero_cnt++;
841         } else {
842                 /* If more than 4 characters could be final a.b.c.d form */
843                 if (len > 4) {
844                         /* Need at least 4 bytes left */
845                         if (s->total > 12)
846                                 return 0;
847                         /* Must be end of string */
848                         if (elem[len])
849                                 return 0;
850                         if (!ipv4_from_asc(s->tmp + s->total, elem))
851                                 return 0;
852                         s->total += 4;
853                 } else {
854                         if (!ipv6_hex(s->tmp + s->total, elem, len))
855                                 return 0;
856                         s->total += 2;
857                 }
858         }
859         return 1;
860 }
861
862 /* Convert a string of up to 4 hex digits into the corresponding
863  * IPv6 form.
864  */
865
866 static int
867 ipv6_hex(unsigned char *out, const char *in, int inlen)
868 {
869         unsigned char c;
870         unsigned int num = 0;
871
872         if (inlen > 4)
873                 return 0;
874         while (inlen--) {
875                 c = *in++;
876                 num <<= 4;
877                 if ((c >= '0') && (c <= '9'))
878                         num |= c - '0';
879                 else if ((c >= 'A') && (c <= 'F'))
880                         num |= c - 'A' + 10;
881                 else if ((c >= 'a') && (c <= 'f'))
882                         num |=  c - 'a' + 10;
883                 else
884                         return 0;
885         }
886         out[0] = num >> 8;
887         out[1] = num & 0xff;
888         return 1;
889 }
890
891 int
892 X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
893     unsigned long chtype)
894 {
895         CONF_VALUE *v;
896         int i, mval;
897         char *p, *type;
898
899         if (!nm)
900                 return 0;
901
902         for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
903                 v = sk_CONF_VALUE_value(dn_sk, i);
904                 type = v->name;
905                 /* Skip past any leading X. X: X, etc to allow for
906                  * multiple instances
907                  */
908                 for (p = type; *p; p++)
909                         if ((*p == ':') || (*p == ',') || (*p == '.')) {
910                                 p++;
911                                 if (*p)
912                                         type = p;
913                                 break;
914                         }
915                 if (*type == '+') {
916                         mval = -1;
917                         type++;
918                 } else
919                         mval = 0;
920                 if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
921                     (unsigned char *) v->value, -1, -1, mval))
922                         return 0;
923         }
924         return 1;
925 }