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