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