LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/x509v3 - v3_lib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 34 116 29.3 %
Date: 2015-10-10 Functions: 5 14 35.7 %

          Line data    Source code
       1             : /* v3_lib.c */
       2             : /*
       3             :  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
       4             :  * 1999.
       5             :  */
       6             : /* ====================================================================
       7             :  * Copyright (c) 1999 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 "cryptlib.h"
      63             : #include <openssl/conf.h>
      64             : #include <openssl/x509v3.h>
      65             : 
      66             : #include "ext_dat.h"
      67             : 
      68             : static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
      69             : 
      70             : static int ext_cmp(const X509V3_EXT_METHOD *const *a,
      71             :                    const X509V3_EXT_METHOD *const *b);
      72             : static void ext_list_free(X509V3_EXT_METHOD *ext);
      73             : 
      74           0 : int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
      75             : {
      76           0 :     if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) {
      77           0 :         X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
      78           0 :         return 0;
      79             :     }
      80           0 :     if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
      81           0 :         X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
      82           0 :         return 0;
      83             :     }
      84             :     return 1;
      85             : }
      86             : 
      87           0 : static int ext_cmp(const X509V3_EXT_METHOD *const *a,
      88             :                    const X509V3_EXT_METHOD *const *b)
      89             : {
      90       15423 :     return ((*a)->ext_nid - (*b)->ext_nid);
      91             : }
      92             : 
      93             : DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
      94             :                            const X509V3_EXT_METHOD *, ext);
      95       33770 : IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
      96             :                              const X509V3_EXT_METHOD *, ext);
      97             : 
      98        2924 : const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
      99             : {
     100             :     X509V3_EXT_METHOD tmp;
     101        2924 :     const X509V3_EXT_METHOD *t = &tmp, *const *ret;
     102             :     int idx;
     103        2924 :     if (nid < 0)
     104             :         return NULL;
     105        2924 :     tmp.ext_nid = nid;
     106             :     ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
     107        2924 :     if (ret)
     108        2924 :         return *ret;
     109           0 :     if (!ext_list)
     110             :         return NULL;
     111           0 :     idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
     112           0 :     if (idx == -1)
     113             :         return NULL;
     114           0 :     return sk_X509V3_EXT_METHOD_value(ext_list, idx);
     115             : }
     116             : 
     117        2924 : const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
     118             : {
     119             :     int nid;
     120        2924 :     if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
     121             :         return NULL;
     122        2924 :     return X509V3_EXT_get_nid(nid);
     123             : }
     124             : 
     125           0 : int X509V3_EXT_free(int nid, void *ext_data)
     126             : {
     127           0 :     const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
     128           0 :     if (ext_method == NULL) {
     129           0 :         X509V3err(X509V3_F_X509V3_EXT_FREE,
     130             :                   X509V3_R_CANNOT_FIND_FREE_FUNCTION);
     131           0 :         return 0;
     132             :     }
     133             : 
     134           0 :     if (ext_method->it != NULL)
     135           0 :         ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it));
     136           0 :     else if (ext_method->ext_free != NULL)
     137           0 :         ext_method->ext_free(ext_data);
     138             :     else {
     139           0 :         X509V3err(X509V3_F_X509V3_EXT_FREE,
     140             :                   X509V3_R_CANNOT_FIND_FREE_FUNCTION);
     141           0 :         return 0;
     142             :     }
     143             : 
     144             :     return 1;
     145             : }
     146             : 
     147           0 : int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
     148             : {
     149           0 :     for (; extlist->ext_nid != -1; extlist++)
     150           0 :         if (!X509V3_EXT_add(extlist))
     151             :             return 0;
     152             :     return 1;
     153             : }
     154             : 
     155           0 : int X509V3_EXT_add_alias(int nid_to, int nid_from)
     156             : {
     157             :     const X509V3_EXT_METHOD *ext;
     158             :     X509V3_EXT_METHOD *tmpext;
     159             : 
     160           0 :     if (!(ext = X509V3_EXT_get_nid(nid_from))) {
     161           0 :         X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,
     162             :                   X509V3_R_EXTENSION_NOT_FOUND);
     163           0 :         return 0;
     164             :     }
     165           0 :     if (!
     166             :         (tmpext =
     167             :          (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
     168           0 :         X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE);
     169           0 :         return 0;
     170             :     }
     171           0 :     *tmpext = *ext;
     172           0 :     tmpext->ext_nid = nid_to;
     173           0 :     tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
     174           0 :     return X509V3_EXT_add(tmpext);
     175             : }
     176             : 
     177           0 : void X509V3_EXT_cleanup(void)
     178             : {
     179           0 :     sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
     180           0 :     ext_list = NULL;
     181           0 : }
     182             : 
     183           0 : static void ext_list_free(X509V3_EXT_METHOD *ext)
     184             : {
     185           0 :     if (ext->ext_flags & X509V3_EXT_DYNAMIC)
     186           0 :         OPENSSL_free(ext);
     187           0 : }
     188             : 
     189             : /*
     190             :  * Legacy function: we don't need to add standard extensions any more because
     191             :  * they are now kept in ext_dat.h.
     192             :  */
     193             : 
     194           0 : int X509V3_add_standard_extensions(void)
     195             : {
     196           0 :     return 1;
     197             : }
     198             : 
     199             : /* Return an extension internal structure */
     200             : 
     201        2924 : void *X509V3_EXT_d2i(X509_EXTENSION *ext)
     202             : {
     203             :     const X509V3_EXT_METHOD *method;
     204             :     const unsigned char *p;
     205             : 
     206        2924 :     if (!(method = X509V3_EXT_get(ext)))
     207             :         return NULL;
     208        2924 :     p = ext->value->data;
     209        2924 :     if (method->it)
     210        2924 :         return ASN1_item_d2i(NULL, &p, ext->value->length,
     211             :                              ASN1_ITEM_ptr(method->it));
     212           0 :     return method->d2i(NULL, &p, ext->value->length);
     213             : }
     214             : 
     215             : /*-
     216             :  * Get critical flag and decoded version of extension from a NID.
     217             :  * The "idx" variable returns the last found extension and can
     218             :  * be used to retrieve multiple extensions of the same NID.
     219             :  * However multiple extensions with the same NID is usually
     220             :  * due to a badly encoded certificate so if idx is NULL we
     221             :  * choke if multiple extensions exist.
     222             :  * The "crit" variable is set to the critical value.
     223             :  * The return value is the decoded extension or NULL on
     224             :  * error. The actual error can have several different causes,
     225             :  * the value of *crit reflects the cause:
     226             :  * >= 0, extension found but not decoded (reflects critical value).
     227             :  * -1 extension not found.
     228             :  * -2 extension occurs more than once.
     229             :  */
     230             : 
     231       11173 : void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
     232             :                      int *idx)
     233             : {
     234             :     int lastpos, i;
     235             :     X509_EXTENSION *ex, *found_ex = NULL;
     236       11173 :     if (!x) {
     237        3300 :         if (idx)
     238           0 :             *idx = -1;
     239        3300 :         if (crit)
     240         330 :             *crit = -1;
     241             :         return NULL;
     242             :     }
     243        7873 :     if (idx)
     244           0 :         lastpos = *idx + 1;
     245             :     else
     246             :         lastpos = 0;
     247        7873 :     if (lastpos < 0)
     248             :         lastpos = 0;
     249       31492 :     for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
     250       23619 :         ex = sk_X509_EXTENSION_value(x, i);
     251       23619 :         if (OBJ_obj2nid(ex->object) == nid) {
     252        2924 :             if (idx) {
     253           0 :                 *idx = i;
     254             :                 found_ex = ex;
     255           0 :                 break;
     256        2924 :             } else if (found_ex) {
     257             :                 /* Found more than one */
     258           0 :                 if (crit)
     259           0 :                     *crit = -2;
     260             :                 return NULL;
     261             :             }
     262             :             found_ex = ex;
     263             :         }
     264             :     }
     265        7873 :     if (found_ex) {
     266             :         /* Found it */
     267        2924 :         if (crit)
     268           0 :             *crit = X509_EXTENSION_get_critical(found_ex);
     269        2924 :         return X509V3_EXT_d2i(found_ex);
     270             :     }
     271             : 
     272             :     /* Extension not found */
     273        4949 :     if (idx)
     274           0 :         *idx = -1;
     275        4949 :     if (crit)
     276         707 :         *crit = -1;
     277             :     return NULL;
     278             : }
     279             : 
     280             : /*
     281             :  * This function is a general extension append, replace and delete utility.
     282             :  * The precise operation is governed by the 'flags' value. The 'crit' and
     283             :  * 'value' arguments (if relevant) are the extensions internal structure.
     284             :  */
     285             : 
     286           0 : int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
     287             :                     int crit, unsigned long flags)
     288             : {
     289             :     int extidx = -1;
     290             :     int errcode;
     291             :     X509_EXTENSION *ext, *extmp;
     292           0 :     unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
     293             : 
     294             :     /*
     295             :      * If appending we don't care if it exists, otherwise look for existing
     296             :      * extension.
     297             :      */
     298           0 :     if (ext_op != X509V3_ADD_APPEND)
     299           0 :         extidx = X509v3_get_ext_by_NID(*x, nid, -1);
     300             : 
     301             :     /* See if extension exists */
     302           0 :     if (extidx >= 0) {
     303             :         /* If keep existing, nothing to do */
     304           0 :         if (ext_op == X509V3_ADD_KEEP_EXISTING)
     305             :             return 1;
     306             :         /* If default then its an error */
     307           0 :         if (ext_op == X509V3_ADD_DEFAULT) {
     308             :             errcode = X509V3_R_EXTENSION_EXISTS;
     309             :             goto err;
     310             :         }
     311             :         /* If delete, just delete it */
     312           0 :         if (ext_op == X509V3_ADD_DELETE) {
     313           0 :             if (!sk_X509_EXTENSION_delete(*x, extidx))
     314             :                 return -1;
     315           0 :             return 1;
     316             :         }
     317             :     } else {
     318             :         /*
     319             :          * If replace existing or delete, error since extension must exist
     320             :          */
     321           0 :         if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
     322           0 :             (ext_op == X509V3_ADD_DELETE)) {
     323             :             errcode = X509V3_R_EXTENSION_NOT_FOUND;
     324             :             goto err;
     325             :         }
     326             :     }
     327             : 
     328             :     /*
     329             :      * If we get this far then we have to create an extension: could have
     330             :      * some flags for alternative encoding schemes...
     331             :      */
     332             : 
     333           0 :     ext = X509V3_EXT_i2d(nid, crit, value);
     334             : 
     335           0 :     if (!ext) {
     336           0 :         X509V3err(X509V3_F_X509V3_ADD1_I2D,
     337             :                   X509V3_R_ERROR_CREATING_EXTENSION);
     338           0 :         return 0;
     339             :     }
     340             : 
     341             :     /* If extension exists replace it.. */
     342           0 :     if (extidx >= 0) {
     343           0 :         extmp = sk_X509_EXTENSION_value(*x, extidx);
     344           0 :         X509_EXTENSION_free(extmp);
     345           0 :         if (!sk_X509_EXTENSION_set(*x, extidx, ext))
     346             :             return -1;
     347           0 :         return 1;
     348             :     }
     349             : 
     350           0 :     if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
     351             :         return -1;
     352           0 :     if (!sk_X509_EXTENSION_push(*x, ext))
     353             :         return -1;
     354             : 
     355           0 :     return 1;
     356             : 
     357             :  err:
     358           0 :     if (!(flags & X509V3_ADD_SILENT))
     359           0 :         X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
     360             :     return 0;
     361             : }
     362             : 
     363             : IMPLEMENT_STACK_OF(X509V3_EXT_METHOD)

Generated by: LCOV version 1.10