LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/x509v3 - v3_utl.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 533 0.0 %
Date: 2015-10-10 Functions: 0 45 0.0 %

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

Generated by: LCOV version 1.10