LCOV - code coverage report
Current view: top level - x509v3 - v3_ncons.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 1 175 0.6 %
Date: 2014-08-02 Functions: 1 16 6.2 %
Branches: 0 162 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* v3_ncons.c */
       2                 :            : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
       3                 :            :  * project.
       4                 :            :  */
       5                 :            : /* ====================================================================
       6                 :            :  * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
       7                 :            :  *
       8                 :            :  * Redistribution and use in source and binary forms, with or without
       9                 :            :  * modification, are permitted provided that the following conditions
      10                 :            :  * are met:
      11                 :            :  *
      12                 :            :  * 1. Redistributions of source code must retain the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer. 
      14                 :            :  *
      15                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      16                 :            :  *    notice, this list of conditions and the following disclaimer in
      17                 :            :  *    the documentation and/or other materials provided with the
      18                 :            :  *    distribution.
      19                 :            :  *
      20                 :            :  * 3. All advertising materials mentioning features or use of this
      21                 :            :  *    software must display the following acknowledgment:
      22                 :            :  *    "This product includes software developed by the OpenSSL Project
      23                 :            :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      24                 :            :  *
      25                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      26                 :            :  *    endorse or promote products derived from this software without
      27                 :            :  *    prior written permission. For written permission, please contact
      28                 :            :  *    licensing@OpenSSL.org.
      29                 :            :  *
      30                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      31                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      32                 :            :  *    permission of the OpenSSL Project.
      33                 :            :  *
      34                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      35                 :            :  *    acknowledgment:
      36                 :            :  *    "This product includes software developed by the OpenSSL Project
      37                 :            :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      38                 :            :  *
      39                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      40                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      41                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      42                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      43                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      44                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      45                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      46                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      47                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      48                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      49                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      50                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      51                 :            :  * ====================================================================
      52                 :            :  *
      53                 :            :  * This product includes cryptographic software written by Eric Young
      54                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      55                 :            :  * Hudson (tjh@cryptsoft.com).
      56                 :            :  *
      57                 :            :  */
      58                 :            : 
      59                 :            : 
      60                 :            : #include <stdio.h>
      61                 :            : #include "cryptlib.h"
      62                 :            : #include <openssl/asn1t.h>
      63                 :            : #include <openssl/conf.h>
      64                 :            : #include <openssl/x509v3.h>
      65                 :            : 
      66                 :            : static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
      67                 :            :                                   X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
      68                 :            : static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 
      69                 :            :                                 void *a, BIO *bp, int ind);
      70                 :            : static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
      71                 :            :                                    STACK_OF(GENERAL_SUBTREE) *trees,
      72                 :            :                                    BIO *bp, int ind, char *name);
      73                 :            : static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
      74                 :            : 
      75                 :            : static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
      76                 :            : static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
      77                 :            : static int nc_dn(X509_NAME *sub, X509_NAME *nm);
      78                 :            : static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
      79                 :            : static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
      80                 :            : static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
      81                 :            : static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base);
      82                 :            : 
      83                 :            : const X509V3_EXT_METHOD v3_name_constraints = {
      84                 :            :         NID_name_constraints, 0,
      85                 :            :         ASN1_ITEM_ref(NAME_CONSTRAINTS),
      86                 :            :         0,0,0,0,
      87                 :            :         0,0,
      88                 :            :         0, v2i_NAME_CONSTRAINTS,
      89                 :            :         i2r_NAME_CONSTRAINTS,0,
      90                 :            :         NULL
      91                 :            : };
      92                 :            : 
      93                 :            : ASN1_SEQUENCE(GENERAL_SUBTREE) = {
      94                 :            :         ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
      95                 :            :         ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
      96                 :            :         ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
      97                 :            : } ASN1_SEQUENCE_END(GENERAL_SUBTREE)
      98                 :            : 
      99                 :            : ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
     100                 :            :         ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
     101                 :            :                                                         GENERAL_SUBTREE, 0),
     102                 :            :         ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
     103                 :            :                                                         GENERAL_SUBTREE, 1),
     104                 :            : } ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
     105                 :            :         
     106                 :            : 
     107                 :          0 : IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
     108                 :       9902 : IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
     109                 :            : 
     110                 :          0 : static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
     111                 :            :                                   X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
     112                 :            :         {
     113                 :            :         int i;
     114                 :            :         CONF_VALUE tval, *val;
     115                 :          0 :         STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
     116                 :          0 :         NAME_CONSTRAINTS *ncons = NULL;
     117                 :          0 :         GENERAL_SUBTREE *sub = NULL;
     118                 :          0 :         ncons = NAME_CONSTRAINTS_new();
     119         [ #  # ]:          0 :         if (!ncons)
     120                 :            :                 goto memerr;
     121         [ #  # ]:          0 :         for(i = 0; i < sk_CONF_VALUE_num(nval); i++)
     122                 :            :                 {
     123                 :          0 :                 val = sk_CONF_VALUE_value(nval, i);
     124 [ #  # ][ #  # ]:          0 :                 if (!strncmp(val->name, "permitted", 9) && val->name[9])
     125                 :            :                         {
     126                 :          0 :                         ptree = &ncons->permittedSubtrees;
     127                 :          0 :                         tval.name = val->name + 10;
     128                 :            :                         }
     129 [ #  # ][ #  # ]:          0 :                 else if (!strncmp(val->name, "excluded", 8) && val->name[8])
     130                 :            :                         {
     131                 :          0 :                         ptree = &ncons->excludedSubtrees;
     132                 :          0 :                         tval.name = val->name + 9;
     133                 :            :                         }
     134                 :            :                 else
     135                 :            :                         {
     136                 :          0 :                         X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
     137                 :          0 :                         goto err;
     138                 :            :                         }
     139                 :          0 :                 tval.value = val->value;
     140                 :          0 :                 sub = GENERAL_SUBTREE_new();
     141         [ #  # ]:          0 :                 if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
     142                 :            :                         goto err;
     143         [ #  # ]:          0 :                 if (!*ptree)
     144                 :          0 :                         *ptree = sk_GENERAL_SUBTREE_new_null();
     145 [ #  # ][ #  # ]:          0 :                 if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
     146                 :            :                         goto memerr;
     147                 :          0 :                 sub = NULL;
     148                 :            :                 }
     149                 :            : 
     150                 :            :         return ncons;
     151                 :            : 
     152                 :            :         memerr:
     153                 :          0 :         X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
     154                 :            :         err:
     155         [ #  # ]:          0 :         if (ncons)
     156                 :          0 :                 NAME_CONSTRAINTS_free(ncons);
     157         [ #  # ]:          0 :         if (sub)
     158                 :          0 :                 GENERAL_SUBTREE_free(sub);
     159                 :            : 
     160                 :            :         return NULL;
     161                 :            :         }
     162                 :            :                         
     163                 :            : 
     164                 :            :         
     165                 :            : 
     166                 :          0 : static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
     167                 :            :                                 BIO *bp, int ind)
     168                 :            :         {
     169                 :          0 :         NAME_CONSTRAINTS *ncons = a;
     170                 :          0 :         do_i2r_name_constraints(method, ncons->permittedSubtrees,
     171                 :            :                                         bp, ind, "Permitted");
     172                 :          0 :         do_i2r_name_constraints(method, ncons->excludedSubtrees,
     173                 :            :                                         bp, ind, "Excluded");
     174                 :          0 :         return 1;
     175                 :            :         }
     176                 :            : 
     177                 :          0 : static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
     178                 :            :                                    STACK_OF(GENERAL_SUBTREE) *trees,
     179                 :            :                                    BIO *bp, int ind, char *name)
     180                 :            :         {
     181                 :            :         GENERAL_SUBTREE *tree;
     182                 :            :         int i;
     183         [ #  # ]:          0 :         if (sk_GENERAL_SUBTREE_num(trees) > 0)
     184                 :          0 :                 BIO_printf(bp, "%*s%s:\n", ind, "", name);
     185         [ #  # ]:          0 :         for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++)
     186                 :            :                 {
     187                 :          0 :                 tree = sk_GENERAL_SUBTREE_value(trees, i);
     188                 :          0 :                 BIO_printf(bp, "%*s", ind + 2, "");
     189         [ #  # ]:          0 :                 if (tree->base->type == GEN_IPADD)
     190                 :          0 :                         print_nc_ipadd(bp, tree->base->d.ip);
     191                 :            :                 else
     192                 :          0 :                         GENERAL_NAME_print(bp, tree->base);
     193                 :          0 :                 BIO_puts(bp, "\n");
     194                 :            :                 }
     195                 :          0 :         return 1;
     196                 :            :         }
     197                 :            : 
     198                 :          0 : static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
     199                 :            :         {
     200                 :            :         int i, len;
     201                 :            :         unsigned char *p;
     202                 :          0 :         p = ip->data;
     203                 :          0 :         len = ip->length;
     204                 :          0 :         BIO_puts(bp, "IP:");
     205         [ #  # ]:          0 :         if(len == 8)
     206                 :            :                 {
     207                 :          0 :                 BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
     208                 :          0 :                                 p[0], p[1], p[2], p[3],
     209                 :          0 :                                 p[4], p[5], p[6], p[7]);
     210                 :            :                 }
     211         [ #  # ]:          0 :         else if(len == 32)
     212                 :            :                 {
     213         [ #  # ]:          0 :                 for (i = 0; i < 16; i++)
     214                 :            :                         {
     215                 :          0 :                         BIO_printf(bp, "%X", p[0] << 8 | p[1]);
     216                 :          0 :                         p += 2;
     217         [ #  # ]:          0 :                         if (i == 7)
     218                 :          0 :                                 BIO_puts(bp, "/");
     219         [ #  # ]:          0 :                         else if (i != 15)
     220                 :          0 :                                 BIO_puts(bp, ":");
     221                 :            :                         }
     222                 :            :                 }
     223                 :            :         else
     224                 :          0 :                 BIO_printf(bp, "IP Address:<invalid>");
     225                 :          0 :         return 1;
     226                 :            :         }
     227                 :            : 
     228                 :            : /* Check a certificate conforms to a specified set of constraints.
     229                 :            :  * Return values:
     230                 :            :  *  X509_V_OK: All constraints obeyed.
     231                 :            :  *  X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
     232                 :            :  *  X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
     233                 :            :  *  X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
     234                 :            :  *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:  Unsupported constraint type.
     235                 :            :  *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
     236                 :            :  *  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
     237                 :            : 
     238                 :            :  */
     239                 :            : 
     240                 :          0 : int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
     241                 :            :         {
     242                 :            :         int r, i;
     243                 :            :         X509_NAME *nm;
     244                 :            : 
     245                 :          0 :         nm = X509_get_subject_name(x);
     246                 :            : 
     247         [ #  # ]:          0 :         if (X509_NAME_entry_count(nm) > 0)
     248                 :            :                 {
     249                 :            :                 GENERAL_NAME gntmp;
     250                 :          0 :                 gntmp.type = GEN_DIRNAME;
     251                 :          0 :                 gntmp.d.directoryName = nm;
     252                 :            : 
     253                 :          0 :                 r = nc_match(&gntmp, nc);
     254                 :            : 
     255         [ #  # ]:          0 :                 if (r != X509_V_OK)
     256                 :          0 :                         return r;
     257                 :            : 
     258                 :          0 :                 gntmp.type = GEN_EMAIL;
     259                 :            : 
     260                 :            : 
     261                 :            :                 /* Process any email address attributes in subject name */
     262                 :            : 
     263                 :          0 :                 for (i = -1;;)
     264                 :            :                         {
     265                 :            :                         X509_NAME_ENTRY *ne;
     266                 :          0 :                         i = X509_NAME_get_index_by_NID(nm,
     267                 :            :                                                        NID_pkcs9_emailAddress,
     268                 :            :                                                        i);
     269         [ #  # ]:          0 :                         if (i == -1)
     270                 :            :                                 break;
     271                 :          0 :                         ne = X509_NAME_get_entry(nm, i);
     272                 :          0 :                         gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
     273         [ #  # ]:          0 :                         if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
     274                 :            :                                 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
     275                 :            : 
     276                 :          0 :                         r = nc_match(&gntmp, nc);
     277                 :            : 
     278         [ #  # ]:          0 :                         if (r != X509_V_OK)
     279                 :            :                                 return r;
     280                 :            :                         }
     281                 :            :                 
     282                 :            :                 }
     283                 :            : 
     284         [ #  # ]:          0 :         for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++)
     285                 :            :                 {
     286                 :          0 :                 GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
     287                 :          0 :                 r = nc_match(gen, nc);
     288         [ #  # ]:          0 :                 if (r != X509_V_OK)
     289                 :            :                         return r;
     290                 :            :                 }
     291                 :            : 
     292                 :            :         return X509_V_OK;
     293                 :            : 
     294                 :            :         }
     295                 :            : 
     296                 :          0 : static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
     297                 :            :         {
     298                 :            :         GENERAL_SUBTREE *sub;
     299                 :          0 :         int i, r, match = 0;
     300                 :            : 
     301                 :            :         /* Permitted subtrees: if any subtrees exist of matching the type
     302                 :            :          * at least one subtree must match.
     303                 :            :          */
     304                 :            : 
     305         [ #  # ]:          0 :         for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++)
     306                 :            :                 {
     307                 :          0 :                 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
     308         [ #  # ]:          0 :                 if (gen->type != sub->base->type)
     309                 :          0 :                         continue;
     310 [ #  # ][ #  # ]:          0 :                 if (sub->minimum || sub->maximum)
     311                 :            :                         return X509_V_ERR_SUBTREE_MINMAX;
     312                 :            :                 /* If we already have a match don't bother trying any more */
     313         [ #  # ]:          0 :                 if (match == 2)
     314                 :          0 :                         continue;
     315         [ #  # ]:          0 :                 if (match == 0)
     316                 :          0 :                         match = 1;
     317                 :          0 :                 r = nc_match_single(gen, sub->base);
     318         [ #  # ]:          0 :                 if (r == X509_V_OK)
     319                 :            :                         match = 2;
     320         [ #  # ]:          0 :                 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
     321                 :            :                         return r;
     322                 :            :                 }
     323                 :            : 
     324         [ #  # ]:          0 :         if (match == 1)
     325                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     326                 :            : 
     327                 :            :         /* Excluded subtrees: must not match any of these */
     328                 :            : 
     329         [ #  # ]:          0 :         for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++)
     330                 :            :                 {
     331                 :          0 :                 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
     332         [ #  # ]:          0 :                 if (gen->type != sub->base->type)
     333                 :          0 :                         continue;
     334 [ #  # ][ #  # ]:          0 :                 if (sub->minimum || sub->maximum)
     335                 :            :                         return X509_V_ERR_SUBTREE_MINMAX;
     336                 :            : 
     337                 :          0 :                 r = nc_match_single(gen, sub->base);
     338         [ #  # ]:          0 :                 if (r == X509_V_OK)
     339                 :            :                         return X509_V_ERR_EXCLUDED_VIOLATION;
     340         [ #  # ]:          0 :                 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
     341                 :            :                         return r;
     342                 :            : 
     343                 :            :                 }
     344                 :            : 
     345                 :            :         return X509_V_OK;
     346                 :            : 
     347                 :            :         }
     348                 :            : 
     349                 :          0 : static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
     350                 :            :         {
     351   [ #  #  #  #  :          0 :         switch(base->type)
                   #  # ]
     352                 :            :                 {
     353                 :            :                 case GEN_DIRNAME:
     354                 :          0 :                 return nc_dn(gen->d.directoryName, base->d.directoryName);
     355                 :            : 
     356                 :            :                 case GEN_DNS:
     357                 :          0 :                 return nc_dns(gen->d.dNSName, base->d.dNSName);
     358                 :            : 
     359                 :            :                 case GEN_EMAIL:
     360                 :          0 :                 return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
     361                 :            : 
     362                 :            :                 case GEN_URI:
     363                 :          0 :                 return nc_uri(gen->d.uniformResourceIdentifier,
     364                 :            :                                         base->d.uniformResourceIdentifier);
     365                 :            : 
     366                 :            :                 case GEN_IPADD:
     367                 :          0 :                 return nc_ip(gen->d.iPAddress, base->d.iPAddress);
     368                 :            : 
     369                 :            :                 default:
     370                 :            :                 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
     371                 :            :                 }
     372                 :            : 
     373                 :            :         }
     374                 :            : 
     375                 :            : /* directoryName name constraint matching.
     376                 :            :  * The canonical encoding of X509_NAME makes this comparison easy. It is
     377                 :            :  * matched if the subtree is a subset of the name.
     378                 :            :  */
     379                 :            : 
     380                 :          0 : static int nc_dn(X509_NAME *nm, X509_NAME *base)
     381                 :            :         {
     382                 :            :         /* Ensure canonical encodings are up to date.  */
     383 [ #  # ][ #  # ]:          0 :         if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
     384                 :            :                 return X509_V_ERR_OUT_OF_MEM;
     385 [ #  # ][ #  # ]:          0 :         if (base->modified && i2d_X509_NAME(base, NULL) < 0)
     386                 :            :                 return X509_V_ERR_OUT_OF_MEM;
     387         [ #  # ]:          0 :         if (base->canon_enclen > nm->canon_enclen)
     388                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     389         [ #  # ]:          0 :         if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
     390                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     391                 :          0 :         return X509_V_OK;
     392                 :            :         }
     393                 :            : 
     394                 :          0 : static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
     395                 :            :         {
     396                 :          0 :         char *baseptr = (char *)base->data;
     397                 :          0 :         char *dnsptr = (char *)dns->data;
     398                 :            :         /* Empty matches everything */
     399         [ #  # ]:          0 :         if (!*baseptr)
     400                 :            :                 return X509_V_OK;
     401                 :            :         /* Otherwise can add zero or more components on the left so
     402                 :            :          * compare RHS and if dns is longer and expect '.' as preceding
     403                 :            :          * character.
     404                 :            :          */
     405         [ #  # ]:          0 :         if (dns->length > base->length)
     406                 :            :                 {
     407                 :          0 :                 dnsptr += dns->length - base->length;
     408         [ #  # ]:          0 :                 if (dnsptr[-1] != '.')
     409                 :            :                         return X509_V_ERR_PERMITTED_VIOLATION;
     410                 :            :                 }
     411                 :            : 
     412         [ #  # ]:          0 :         if (strcasecmp(baseptr, dnsptr))
     413                 :            :                         return X509_V_ERR_PERMITTED_VIOLATION;
     414                 :            : 
     415                 :            :         return X509_V_OK;
     416                 :            : 
     417                 :            :         }
     418                 :            : 
     419                 :          0 : static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
     420                 :            :         {
     421                 :          0 :         const char *baseptr = (char *)base->data;
     422                 :          0 :         const char *emlptr = (char *)eml->data;
     423                 :            : 
     424                 :          0 :         const char *baseat = strchr(baseptr, '@');
     425                 :          0 :         const char *emlat = strchr(emlptr, '@');
     426         [ #  # ]:          0 :         if (!emlat)
     427                 :            :                 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
     428                 :            :         /* Special case: inital '.' is RHS match */
     429 [ #  # ][ #  # ]:          0 :         if (!baseat && (*baseptr == '.'))
     430                 :            :                 {
     431         [ #  # ]:          0 :                 if (eml->length > base->length)
     432                 :            :                         {
     433                 :          0 :                         emlptr += eml->length - base->length;
     434         [ #  # ]:          0 :                         if (!strcasecmp(baseptr, emlptr))
     435                 :            :                                 return X509_V_OK;
     436                 :            :                         }
     437                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     438                 :            :                 }
     439                 :            : 
     440                 :            :         /* If we have anything before '@' match local part */
     441                 :            : 
     442         [ #  # ]:          0 :         if (baseat)
     443                 :            :                 {
     444         [ #  # ]:          0 :                 if (baseat != baseptr)
     445                 :            :                         {
     446         [ #  # ]:          0 :                         if ((baseat - baseptr) != (emlat - emlptr))
     447                 :            :                                 return X509_V_ERR_PERMITTED_VIOLATION;
     448                 :            :                         /* Case sensitive match of local part */
     449         [ #  # ]:          0 :                         if (strncmp(baseptr, emlptr, emlat - emlptr))
     450                 :            :                                 return X509_V_ERR_PERMITTED_VIOLATION;
     451                 :            :                         }
     452                 :            :                 /* Position base after '@' */
     453                 :          0 :                 baseptr = baseat + 1;
     454                 :            :                 }
     455                 :          0 :         emlptr = emlat + 1;
     456                 :            :         /* Just have hostname left to match: case insensitive */
     457         [ #  # ]:          0 :         if (strcasecmp(baseptr, emlptr))
     458                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     459                 :            : 
     460                 :            :         return X509_V_OK;
     461                 :            : 
     462                 :            :         }
     463                 :            : 
     464                 :          0 : static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
     465                 :            :         {
     466                 :          0 :         const char *baseptr = (char *)base->data;
     467                 :          0 :         const char *hostptr = (char *)uri->data;
     468                 :          0 :         const char *p = strchr(hostptr, ':');
     469                 :            :         int hostlen;
     470                 :            :         /* Check for foo:// and skip past it */
     471 [ #  # ][ #  # ]:          0 :         if (!p || (p[1] != '/') || (p[2] != '/'))
                 [ #  # ]
     472                 :            :                 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
     473                 :          0 :         hostptr = p + 3;
     474                 :            : 
     475                 :            :         /* Determine length of hostname part of URI */
     476                 :            : 
     477                 :            :         /* Look for a port indicator as end of hostname first */
     478                 :            : 
     479                 :          0 :         p = strchr(hostptr, ':');
     480                 :            :         /* Otherwise look for trailing slash */
     481         [ #  # ]:          0 :         if (!p)
     482                 :          0 :                 p = strchr(hostptr, '/');
     483                 :            : 
     484         [ #  # ]:          0 :         if (!p)
     485                 :          0 :                 hostlen = strlen(hostptr);
     486                 :            :         else
     487                 :          0 :                 hostlen = p - hostptr;
     488                 :            : 
     489         [ #  # ]:          0 :         if (hostlen == 0)
     490                 :            :                 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
     491                 :            : 
     492                 :            :         /* Special case: inital '.' is RHS match */
     493         [ #  # ]:          0 :         if (*baseptr == '.')
     494                 :            :                 {
     495         [ #  # ]:          0 :                 if (hostlen > base->length)
     496                 :            :                         {
     497                 :          0 :                         p = hostptr + hostlen - base->length;
     498         [ #  # ]:          0 :                         if (!strncasecmp(p, baseptr, base->length))
     499                 :            :                                 return X509_V_OK;
     500                 :            :                         }
     501                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     502                 :            :                 }
     503                 :            : 
     504 [ #  # ][ #  # ]:          0 :         if ((base->length != (int)hostlen) || strncasecmp(hostptr, baseptr, hostlen))
     505                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     506                 :            : 
     507                 :            :         return X509_V_OK;
     508                 :            : 
     509                 :            :         }
     510                 :            : 
     511                 :          0 : static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base)
     512                 :            :         {
     513                 :            :         int hostlen, baselen, i;
     514                 :            :         unsigned char *hostptr, *baseptr, *maskptr;
     515                 :          0 :         hostptr = ip->data;
     516                 :          0 :         hostlen = ip->length;
     517                 :          0 :         baseptr = base->data;
     518                 :          0 :         baselen = base->length;
     519                 :            : 
     520                 :            :         /* Invalid if not IPv4 or IPv6 */
     521         [ #  # ]:          0 :         if (! ((hostlen == 4) || (hostlen==16)) )
     522                 :            :                 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
     523         [ #  # ]:          0 :         if (! ((baselen == 8) || (baselen==32)) )
     524                 :            :                 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
     525                 :            : 
     526                 :            :         /* Do not match IPv4 with IPv6 */
     527         [ #  # ]:          0 :         if (hostlen*2 != baselen)
     528                 :            :                 return X509_V_ERR_PERMITTED_VIOLATION;
     529                 :            : 
     530                 :          0 :         maskptr = base->data + hostlen;
     531                 :            : 
     532                 :            :         /* Considering possible not aligned base ipAddress */
     533                 :            :         /* Not checking for wrong mask definition: i.e.: 255.0.255.0*/
     534         [ #  # ]:          0 :         for (i = 0; i < hostlen; i++)
     535         [ #  # ]:          0 :                 if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i]))
     536                 :            :                         return X509_V_ERR_PERMITTED_VIOLATION;
     537                 :            : 
     538                 :            :         return X509_V_OK;
     539                 :            : 
     540                 :            :         }

Generated by: LCOV version 1.9