LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/x509 - x509_trs.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 19 108 17.6 %
Date: 2015-10-10 Functions: 4 17 23.5 %

          Line data    Source code
       1             : /* x509_trs.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             : 
      60             : #include <stdio.h>
      61             : #include "cryptlib.h"
      62             : #include <openssl/x509v3.h>
      63             : 
      64             : static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b);
      65             : static void trtable_free(X509_TRUST *p);
      66             : 
      67             : static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
      68             : static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
      69             : static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
      70             : 
      71             : static int obj_trust(int id, X509 *x, int flags);
      72             : static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
      73             : 
      74             : /*
      75             :  * WARNING: the following table should be kept in order of trust and without
      76             :  * any gaps so we can just subtract the minimum trust value to get an index
      77             :  * into the table
      78             :  */
      79             : 
      80             : static X509_TRUST trstandard[] = {
      81             :     {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
      82             :     {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth,
      83             :      NULL},
      84             :     {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth,
      85             :      NULL},
      86             :     {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect,
      87             :      NULL},
      88             :     {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign,
      89             :      NULL},
      90             :     {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign,
      91             :      NULL},
      92             :     {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP,
      93             :      NULL},
      94             :     {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
      95             : };
      96             : 
      97             : #define X509_TRUST_COUNT        (sizeof(trstandard)/sizeof(X509_TRUST))
      98             : 
      99             : IMPLEMENT_STACK_OF(X509_TRUST)
     100             : 
     101             : static STACK_OF(X509_TRUST) *trtable = NULL;
     102             : 
     103           0 : static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b)
     104             : {
     105           0 :     return (*a)->trust - (*b)->trust;
     106             : }
     107             : 
     108           0 : int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
     109             :                                                                 int) {
     110             :     int (*oldtrust) (int, X509 *, int);
     111           0 :     oldtrust = default_trust;
     112           0 :     default_trust = trust;
     113           0 :     return oldtrust;
     114             : }
     115             : 
     116         370 : int X509_check_trust(X509 *x, int id, int flags)
     117             : {
     118             :     X509_TRUST *pt;
     119             :     int idx;
     120         370 :     if (id == -1)
     121             :         return 1;
     122             :     /* We get this as a default value */
     123         370 :     if (id == 0) {
     124             :         int rv;
     125           0 :         rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
     126           0 :         if (rv != X509_TRUST_UNTRUSTED)
     127             :             return rv;
     128           0 :         return trust_compat(NULL, x, 0);
     129             :     }
     130         370 :     idx = X509_TRUST_get_by_id(id);
     131         370 :     if (idx == -1)
     132           0 :         return default_trust(id, x, flags);
     133         370 :     pt = X509_TRUST_get0(idx);
     134         370 :     return pt->check_trust(pt, x, flags);
     135             : }
     136             : 
     137           0 : int X509_TRUST_get_count(void)
     138             : {
     139           0 :     if (!trtable)
     140             :         return X509_TRUST_COUNT;
     141           0 :     return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
     142             : }
     143             : 
     144         370 : X509_TRUST *X509_TRUST_get0(int idx)
     145             : {
     146         370 :     if (idx < 0)
     147             :         return NULL;
     148         370 :     if (idx < (int)X509_TRUST_COUNT)
     149         370 :         return trstandard + idx;
     150           0 :     return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
     151             : }
     152             : 
     153         370 : int X509_TRUST_get_by_id(int id)
     154             : {
     155             :     X509_TRUST tmp;
     156             :     int idx;
     157         370 :     if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
     158         370 :         return id - X509_TRUST_MIN;
     159           0 :     tmp.trust = id;
     160           0 :     if (!trtable)
     161             :         return -1;
     162           0 :     idx = sk_X509_TRUST_find(trtable, &tmp);
     163           0 :     if (idx == -1)
     164             :         return -1;
     165           0 :     return idx + X509_TRUST_COUNT;
     166             : }
     167             : 
     168           0 : int X509_TRUST_set(int *t, int trust)
     169             : {
     170           0 :     if (X509_TRUST_get_by_id(trust) == -1) {
     171           0 :         X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
     172           0 :         return 0;
     173             :     }
     174           0 :     *t = trust;
     175           0 :     return 1;
     176             : }
     177             : 
     178           0 : int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
     179             :                    char *name, int arg1, void *arg2)
     180             : {
     181             :     int idx;
     182             :     X509_TRUST *trtmp;
     183             :     /*
     184             :      * This is set according to what we change: application can't set it
     185             :      */
     186           0 :     flags &= ~X509_TRUST_DYNAMIC;
     187             :     /* This will always be set for application modified trust entries */
     188           0 :     flags |= X509_TRUST_DYNAMIC_NAME;
     189             :     /* Get existing entry if any */
     190           0 :     idx = X509_TRUST_get_by_id(id);
     191             :     /* Need a new entry */
     192           0 :     if (idx == -1) {
     193           0 :         if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
     194           0 :             X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
     195           0 :             return 0;
     196             :         }
     197           0 :         trtmp->flags = X509_TRUST_DYNAMIC;
     198             :     } else
     199           0 :         trtmp = X509_TRUST_get0(idx);
     200             : 
     201             :     /* OPENSSL_free existing name if dynamic */
     202           0 :     if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
     203           0 :         OPENSSL_free(trtmp->name);
     204             :     /* dup supplied name */
     205           0 :     if (!(trtmp->name = BUF_strdup(name))) {
     206           0 :         X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
     207           0 :         return 0;
     208             :     }
     209             :     /* Keep the dynamic flag of existing entry */
     210           0 :     trtmp->flags &= X509_TRUST_DYNAMIC;
     211             :     /* Set all other flags */
     212           0 :     trtmp->flags |= flags;
     213             : 
     214           0 :     trtmp->trust = id;
     215           0 :     trtmp->check_trust = ck;
     216           0 :     trtmp->arg1 = arg1;
     217           0 :     trtmp->arg2 = arg2;
     218             : 
     219             :     /* If its a new entry manage the dynamic table */
     220           0 :     if (idx == -1) {
     221           0 :         if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
     222           0 :             X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
     223           0 :             return 0;
     224             :         }
     225           0 :         if (!sk_X509_TRUST_push(trtable, trtmp)) {
     226           0 :             X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
     227           0 :             return 0;
     228             :         }
     229             :     }
     230             :     return 1;
     231             : }
     232             : 
     233           0 : static void trtable_free(X509_TRUST *p)
     234             : {
     235           0 :     if (!p)
     236           0 :         return;
     237           0 :     if (p->flags & X509_TRUST_DYNAMIC) {
     238           0 :         if (p->flags & X509_TRUST_DYNAMIC_NAME)
     239           0 :             OPENSSL_free(p->name);
     240           0 :         OPENSSL_free(p);
     241             :     }
     242             : }
     243             : 
     244           0 : void X509_TRUST_cleanup(void)
     245             : {
     246             :     unsigned int i;
     247           0 :     for (i = 0; i < X509_TRUST_COUNT; i++)
     248           0 :         trtable_free(trstandard + i);
     249           0 :     sk_X509_TRUST_pop_free(trtable, trtable_free);
     250           0 :     trtable = NULL;
     251           0 : }
     252             : 
     253           0 : int X509_TRUST_get_flags(X509_TRUST *xp)
     254             : {
     255           0 :     return xp->flags;
     256             : }
     257             : 
     258           0 : char *X509_TRUST_get0_name(X509_TRUST *xp)
     259             : {
     260           0 :     return xp->name;
     261             : }
     262             : 
     263           0 : int X509_TRUST_get_trust(X509_TRUST *xp)
     264             : {
     265           0 :     return xp->trust;
     266             : }
     267             : 
     268         370 : static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
     269             : {
     270         370 :     if (x->aux && (x->aux->trust || x->aux->reject))
     271           0 :         return obj_trust(trust->arg1, x, flags);
     272             :     /*
     273             :      * we don't have any trust settings: for compatibility we return trusted
     274             :      * if it is self signed
     275             :      */
     276         370 :     return trust_compat(trust, x, flags);
     277             : }
     278             : 
     279           0 : static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
     280             : {
     281           0 :     if (x->aux)
     282           0 :         return obj_trust(trust->arg1, x, flags);
     283             :     return X509_TRUST_UNTRUSTED;
     284             : }
     285             : 
     286           0 : static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
     287             : {
     288         370 :     X509_check_purpose(x, -1, 0);
     289         370 :     if (x->ex_flags & EXFLAG_SS)
     290             :         return X509_TRUST_TRUSTED;
     291             :     else
     292           0 :         return X509_TRUST_UNTRUSTED;
     293             : }
     294             : 
     295           0 : static int obj_trust(int id, X509 *x, int flags)
     296             : {
     297             :     ASN1_OBJECT *obj;
     298             :     int i;
     299             :     X509_CERT_AUX *ax;
     300           0 :     ax = x->aux;
     301           0 :     if (!ax)
     302             :         return X509_TRUST_UNTRUSTED;
     303           0 :     if (ax->reject) {
     304           0 :         for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
     305           0 :             obj = sk_ASN1_OBJECT_value(ax->reject, i);
     306           0 :             if (OBJ_obj2nid(obj) == id)
     307             :                 return X509_TRUST_REJECTED;
     308             :         }
     309             :     }
     310           0 :     if (ax->trust) {
     311           0 :         for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
     312           0 :             obj = sk_ASN1_OBJECT_value(ax->trust, i);
     313           0 :             if (OBJ_obj2nid(obj) == id)
     314             :                 return X509_TRUST_TRUSTED;
     315             :         }
     316             :     }
     317             :     return X509_TRUST_UNTRUSTED;
     318             : }

Generated by: LCOV version 1.10