]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - crypto/openssl/crypto/x509v3/v3_utl.c
MFC: r280297
[FreeBSD/stable/10.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_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
71                                            GENERAL_NAMES *gens);
72 static void str_free(OPENSSL_STRING str);
73 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
74
75 static int ipv4_from_asc(unsigned char *v4, const char *in);
76 static int ipv6_from_asc(unsigned char *v6, const char *in);
77 static int ipv6_cb(const char *elem, int len, void *usr);
78 static int ipv6_hex(unsigned char *out, const char *in, int inlen);
79
80 /* Add a CONF_VALUE name value pair to stack */
81
82 int X509V3_add_value(const char *name, const char *value,
83                      STACK_OF(CONF_VALUE) **extlist)
84 {
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;
110 }
111
112 int X509V3_add_value_uchar(const char *name, const unsigned char *value,
113                            STACK_OF(CONF_VALUE) **extlist)
114 {
115     return X509V3_add_value(name, (const char *)value, extlist);
116 }
117
118 /* Free function for STACK_OF(CONF_VALUE) */
119
120 void X509V3_conf_free(CONF_VALUE *conf)
121 {
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);
131 }
132
133 int X509V3_add_value_bool(const char *name, int asn1_bool,
134                           STACK_OF(CONF_VALUE) **extlist)
135 {
136     if (asn1_bool)
137         return X509V3_add_value(name, "TRUE", extlist);
138     return X509V3_add_value(name, "FALSE", extlist);
139 }
140
141 int X509V3_add_value_bool_nf(char *name, int asn1_bool,
142                              STACK_OF(CONF_VALUE) **extlist)
143 {
144     if (asn1_bool)
145         return X509V3_add_value(name, "TRUE", extlist);
146     return 1;
147 }
148
149 char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
150 {
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;
160 }
161
162 char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
163 {
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;
173 }
174
175 ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
176 {
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;
222 }
223
224 int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
225                          STACK_OF(CONF_VALUE) **extlist)
226 {
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;
236 }
237
238 int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
239 {
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;
259 }
260
261 int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
262 {
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;
270 }
271
272 #define HDR_NAME        1
273 #define HDR_VALUE       2
274
275 /*
276  * #define DEBUG
277  */
278
279 STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
280 {
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;
310 #if 0
311                 printf("%s\n", ntmp);
312 #endif
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);
327 #if 0
328                 printf("%s\n", ntmp);
329 #endif
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);
345 #if 0
346         printf("%s=%s\n", ntmp, vtmp);
347 #endif
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);
356 #if 0
357         printf("%s\n", ntmp);
358 #endif
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;
372
373 }
374
375 /* Delete leading and trailing spaces from a string */
376 static char *strip_spaces(char *name)
377 {
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;
393 }
394
395 /* hex string utilities */
396
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)
401  */
402
403 char *hex_to_string(const unsigned char *buffer, long len)
404 {
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;
422 #ifdef CHARSET_EBCDIC
423     ebcdic2ascii(tmp, tmp, q - tmp - 1);
424 #endif
425
426     return tmp;
427 }
428
429 /*
430  * Give a string of hex digits convert to a buffer
431  */
432
433 unsigned char *string_to_hex(const char *str, long *len)
434 {
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++;
445 #ifdef CHARSET_EBCDIC
446         ch = os_toebcdic[ch];
447 #endif
448         if (ch == ':')
449             continue;
450         cl = *p++;
451 #ifdef CHARSET_EBCDIC
452         cl = os_toebcdic[cl];
453 #endif
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     }
480
481     if (len)
482         *len = q - hexbuf;
483
484     return hexbuf;
485
486  err:
487     if (hexbuf)
488         OPENSSL_free(hexbuf);
489     X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE);
490     return NULL;
491
492  badhex:
493     OPENSSL_free(hexbuf);
494     X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT);
495     return NULL;
496
497 }
498
499 /*
500  * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
501  */
502
503 int name_cmp(const char *name, const char *cmp)
504 {
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;
514 }
515
516 static int sk_strcmp(const char *const *a, const char *const *b)
517 {
518     return strcmp(*a, *b);
519 }
520
521 STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
522 {
523     GENERAL_NAMES *gens;
524     STACK_OF(OPENSSL_STRING) *ret;
525
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;
530 }
531
532 STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
533 {
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;
553 }
554
555 STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
556 {
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;
567 }
568
569 static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
570                                            GENERAL_NAMES *gens)
571 {
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;
595 }
596
597 static void str_free(OPENSSL_STRING str)
598 {
599     OPENSSL_free(str);
600 }
601
602 static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
603 {
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;
624 }
625
626 void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
627 {
628     sk_OPENSSL_STRING_pop_free(sk, str_free);
629 }
630
631 /*
632  * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
633  * with RFC3280.
634  */
635
636 ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
637 {
638     unsigned char ipout[16];
639     ASN1_OCTET_STRING *ret;
640     int iplen;
641
642     /* If string contains a ':' assume IPv6 */
643
644     iplen = a2i_ipadd(ipout, ipasc);
645
646     if (!iplen)
647         return NULL;
648
649     ret = ASN1_OCTET_STRING_new();
650     if (!ret)
651         return NULL;
652     if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
653         ASN1_OCTET_STRING_free(ret);
654         return NULL;
655     }
656     return ret;
657 }
658
659 ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
660 {
661     ASN1_OCTET_STRING *ret = NULL;
662     unsigned char ipout[32];
663     char *iptmp = NULL, *p;
664     int iplen1, iplen2;
665     p = strchr(ipasc, '/');
666     if (!p)
667         return NULL;
668     iptmp = BUF_strdup(ipasc);
669     if (!iptmp)
670         return NULL;
671     p = iptmp + (p - ipasc);
672     *p++ = 0;
673
674     iplen1 = a2i_ipadd(ipout, iptmp);
675
676     if (!iplen1)
677         goto err;
678
679     iplen2 = a2i_ipadd(ipout + iplen1, p);
680
681     OPENSSL_free(iptmp);
682     iptmp = NULL;
683
684     if (!iplen2 || (iplen1 != iplen2))
685         goto err;
686
687     ret = ASN1_OCTET_STRING_new();
688     if (!ret)
689         goto err;
690     if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
691         goto err;
692
693     return ret;
694
695  err:
696     if (iptmp)
697         OPENSSL_free(iptmp);
698     if (ret)
699         ASN1_OCTET_STRING_free(ret);
700     return NULL;
701 }
702
703 int a2i_ipadd(unsigned char *ipout, const char *ipasc)
704 {
705     /* If string contains a ':' assume IPv6 */
706
707     if (strchr(ipasc, ':')) {
708         if (!ipv6_from_asc(ipout, ipasc))
709             return 0;
710         return 16;
711     } else {
712         if (!ipv4_from_asc(ipout, ipasc))
713             return 0;
714         return 4;
715     }
716 }
717
718 static int ipv4_from_asc(unsigned char *v4, const char *in)
719 {
720     int a0, a1, a2, a3;
721     if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
722         return 0;
723     if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
724         || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
725         return 0;
726     v4[0] = a0;
727     v4[1] = a1;
728     v4[2] = a2;
729     v4[3] = a3;
730     return 1;
731 }
732
733 typedef struct {
734     /* Temporary store for IPV6 output */
735     unsigned char tmp[16];
736     /* Total number of bytes in tmp */
737     int total;
738     /* The position of a zero (corresponding to '::') */
739     int zero_pos;
740     /* Number of zeroes */
741     int zero_cnt;
742 } IPV6_STAT;
743
744 static int ipv6_from_asc(unsigned char *v6, const char *in)
745 {
746     IPV6_STAT v6stat;
747     v6stat.total = 0;
748     v6stat.zero_pos = -1;
749     v6stat.zero_cnt = 0;
750     /*
751      * Treat the IPv6 representation as a list of values separated by ':'.
752      * The presence of a '::' will parse as one, two or three zero length
753      * elements.
754      */
755     if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
756         return 0;
757
758     /* Now for some sanity checks */
759
760     if (v6stat.zero_pos == -1) {
761         /* If no '::' must have exactly 16 bytes */
762         if (v6stat.total != 16)
763             return 0;
764     } else {
765         /* If '::' must have less than 16 bytes */
766         if (v6stat.total == 16)
767             return 0;
768         /* More than three zeroes is an error */
769         if (v6stat.zero_cnt > 3)
770             return 0;
771         /* Can only have three zeroes if nothing else present */
772         else if (v6stat.zero_cnt == 3) {
773             if (v6stat.total > 0)
774                 return 0;
775         }
776         /* Can only have two zeroes if at start or end */
777         else if (v6stat.zero_cnt == 2) {
778             if ((v6stat.zero_pos != 0)
779                 && (v6stat.zero_pos != v6stat.total))
780                 return 0;
781         } else
782             /* Can only have one zero if *not* start or end */
783         {
784             if ((v6stat.zero_pos == 0)
785                 || (v6stat.zero_pos == v6stat.total))
786                 return 0;
787         }
788     }
789
790     /* Format result */
791
792     if (v6stat.zero_pos >= 0) {
793         /* Copy initial part */
794         memcpy(v6, v6stat.tmp, v6stat.zero_pos);
795         /* Zero middle */
796         memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
797         /* Copy final part */
798         if (v6stat.total != v6stat.zero_pos)
799             memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
800                    v6stat.tmp + v6stat.zero_pos,
801                    v6stat.total - v6stat.zero_pos);
802     } else
803         memcpy(v6, v6stat.tmp, 16);
804
805     return 1;
806 }
807
808 static int ipv6_cb(const char *elem, int len, void *usr)
809 {
810     IPV6_STAT *s = usr;
811     /* Error if 16 bytes written */
812     if (s->total == 16)
813         return 0;
814     if (len == 0) {
815         /* Zero length element, corresponds to '::' */
816         if (s->zero_pos == -1)
817             s->zero_pos = s->total;
818         /* If we've already got a :: its an error */
819         else if (s->zero_pos != s->total)
820             return 0;
821         s->zero_cnt++;
822     } else {
823         /* If more than 4 characters could be final a.b.c.d form */
824         if (len > 4) {
825             /* Need at least 4 bytes left */
826             if (s->total > 12)
827                 return 0;
828             /* Must be end of string */
829             if (elem[len])
830                 return 0;
831             if (!ipv4_from_asc(s->tmp + s->total, elem))
832                 return 0;
833             s->total += 4;
834         } else {
835             if (!ipv6_hex(s->tmp + s->total, elem, len))
836                 return 0;
837             s->total += 2;
838         }
839     }
840     return 1;
841 }
842
843 /*
844  * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
845  */
846
847 static int ipv6_hex(unsigned char *out, const char *in, int inlen)
848 {
849     unsigned char c;
850     unsigned int num = 0;
851     if (inlen > 4)
852         return 0;
853     while (inlen--) {
854         c = *in++;
855         num <<= 4;
856         if ((c >= '0') && (c <= '9'))
857             num |= c - '0';
858         else if ((c >= 'A') && (c <= 'F'))
859             num |= c - 'A' + 10;
860         else if ((c >= 'a') && (c <= 'f'))
861             num |= c - 'a' + 10;
862         else
863             return 0;
864     }
865     out[0] = num >> 8;
866     out[1] = num & 0xff;
867     return 1;
868 }
869
870 int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
871                              unsigned long chtype)
872 {
873     CONF_VALUE *v;
874     int i, mval;
875     char *p, *type;
876     if (!nm)
877         return 0;
878
879     for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
880         v = sk_CONF_VALUE_value(dn_sk, i);
881         type = v->name;
882         /*
883          * Skip past any leading X. X: X, etc to allow for multiple instances
884          */
885         for (p = type; *p; p++)
886 #ifndef CHARSET_EBCDIC
887             if ((*p == ':') || (*p == ',') || (*p == '.'))
888 #else
889             if ((*p == os_toascii[':']) || (*p == os_toascii[','])
890                 || (*p == os_toascii['.']))
891 #endif
892             {
893                 p++;
894                 if (*p)
895                     type = p;
896                 break;
897             }
898 #ifndef CHARSET_EBCDIC
899         if (*type == '+')
900 #else
901         if (*type == os_toascii['+'])
902 #endif
903         {
904             mval = -1;
905             type++;
906         } else
907             mval = 0;
908         if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
909                                         (unsigned char *)v->value, -1, -1,
910                                         mval))
911             return 0;
912
913     }
914     return 1;
915 }