LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/x509 - x509_cmp.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 25 160 15.6 %
Date: 2015-10-10 Functions: 7 26 26.9 %

          Line data    Source code
       1             : /* crypto/x509/x509_cmp.c */
       2             : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3             :  * All rights reserved.
       4             :  *
       5             :  * This package is an SSL implementation written
       6             :  * by Eric Young (eay@cryptsoft.com).
       7             :  * The implementation was written so as to conform with Netscapes SSL.
       8             :  *
       9             :  * This library is free for commercial and non-commercial use as long as
      10             :  * the following conditions are aheared to.  The following conditions
      11             :  * apply to all code found in this distribution, be it the RC4, RSA,
      12             :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13             :  * included with this distribution is covered by the same copyright terms
      14             :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15             :  *
      16             :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17             :  * the code are not to be removed.
      18             :  * If this package is used in a product, Eric Young should be given attribution
      19             :  * as the author of the parts of the library used.
      20             :  * This can be in the form of a textual message at program startup or
      21             :  * in documentation (online or textual) provided with the package.
      22             :  *
      23             :  * Redistribution and use in source and binary forms, with or without
      24             :  * modification, are permitted provided that the following conditions
      25             :  * are met:
      26             :  * 1. Redistributions of source code must retain the copyright
      27             :  *    notice, this list of conditions and the following disclaimer.
      28             :  * 2. Redistributions in binary form must reproduce the above copyright
      29             :  *    notice, this list of conditions and the following disclaimer in the
      30             :  *    documentation and/or other materials provided with the distribution.
      31             :  * 3. All advertising materials mentioning features or use of this software
      32             :  *    must display the following acknowledgement:
      33             :  *    "This product includes cryptographic software written by
      34             :  *     Eric Young (eay@cryptsoft.com)"
      35             :  *    The word 'cryptographic' can be left out if the rouines from the library
      36             :  *    being used are not cryptographic related :-).
      37             :  * 4. If you include any Windows specific code (or a derivative thereof) from
      38             :  *    the apps directory (application code) you must include an acknowledgement:
      39             :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40             :  *
      41             :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51             :  * SUCH DAMAGE.
      52             :  *
      53             :  * The licence and distribution terms for any publically available version or
      54             :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55             :  * copied and put under another distribution licence
      56             :  * [including the GNU Public Licence.]
      57             :  */
      58             : 
      59             : #include <stdio.h>
      60             : #include <ctype.h>
      61             : #include "cryptlib.h"
      62             : #include <openssl/asn1.h>
      63             : #include <openssl/objects.h>
      64             : #include <openssl/x509.h>
      65             : #include <openssl/x509v3.h>
      66             : 
      67           0 : int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
      68             : {
      69             :     int i;
      70             :     X509_CINF *ai, *bi;
      71             : 
      72           0 :     ai = a->cert_info;
      73           0 :     bi = b->cert_info;
      74           0 :     i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
      75           0 :     if (i)
      76             :         return (i);
      77           0 :     return (X509_NAME_cmp(ai->issuer, bi->issuer));
      78             : }
      79             : 
      80             : #ifndef OPENSSL_NO_MD5
      81           0 : unsigned long X509_issuer_and_serial_hash(X509 *a)
      82             : {
      83             :     unsigned long ret = 0;
      84             :     EVP_MD_CTX ctx;
      85             :     unsigned char md[16];
      86             :     char *f;
      87             : 
      88           0 :     EVP_MD_CTX_init(&ctx);
      89           0 :     f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
      90           0 :     if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
      91             :         goto err;
      92           0 :     if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f)))
      93             :         goto err;
      94           0 :     OPENSSL_free(f);
      95           0 :     if (!EVP_DigestUpdate
      96           0 :         (&ctx, (unsigned char *)a->cert_info->serialNumber->data,
      97           0 :          (unsigned long)a->cert_info->serialNumber->length))
      98             :         goto err;
      99           0 :     if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL))
     100             :         goto err;
     101           0 :     ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
     102           0 :            ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
     103             :         ) & 0xffffffffL;
     104             :  err:
     105           0 :     EVP_MD_CTX_cleanup(&ctx);
     106           0 :     return (ret);
     107             : }
     108             : #endif
     109             : 
     110           0 : int X509_issuer_name_cmp(const X509 *a, const X509 *b)
     111             : {
     112           0 :     return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
     113             : }
     114             : 
     115         370 : int X509_subject_name_cmp(const X509 *a, const X509 *b)
     116             : {
     117         370 :     return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
     118             : }
     119             : 
     120           0 : int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
     121             : {
     122           0 :     return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
     123             : }
     124             : 
     125             : #ifndef OPENSSL_NO_SHA
     126           0 : int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
     127             : {
     128           0 :     return memcmp(a->sha1_hash, b->sha1_hash, 20);
     129             : }
     130             : #endif
     131             : 
     132        2890 : X509_NAME *X509_get_issuer_name(X509 *a)
     133             : {
     134        2890 :     return (a->cert_info->issuer);
     135             : }
     136             : 
     137           0 : unsigned long X509_issuer_name_hash(X509 *x)
     138             : {
     139           0 :     return (X509_NAME_hash(x->cert_info->issuer));
     140             : }
     141             : 
     142             : #ifndef OPENSSL_NO_MD5
     143           0 : unsigned long X509_issuer_name_hash_old(X509 *x)
     144             : {
     145           0 :     return (X509_NAME_hash_old(x->cert_info->issuer));
     146             : }
     147             : #endif
     148             : 
     149        2950 : X509_NAME *X509_get_subject_name(X509 *a)
     150             : {
     151        2950 :     return (a->cert_info->subject);
     152             : }
     153             : 
     154           0 : ASN1_INTEGER *X509_get_serialNumber(X509 *a)
     155             : {
     156           0 :     return (a->cert_info->serialNumber);
     157             : }
     158             : 
     159           0 : unsigned long X509_subject_name_hash(X509 *x)
     160             : {
     161           0 :     return (X509_NAME_hash(x->cert_info->subject));
     162             : }
     163             : 
     164             : #ifndef OPENSSL_NO_MD5
     165           0 : unsigned long X509_subject_name_hash_old(X509 *x)
     166             : {
     167           0 :     return (X509_NAME_hash_old(x->cert_info->subject));
     168             : }
     169             : #endif
     170             : 
     171             : #ifndef OPENSSL_NO_SHA
     172             : /*
     173             :  * Compare two certificates: they must be identical for this to work. NB:
     174             :  * Although "cmp" operations are generally prototyped to take "const"
     175             :  * arguments (eg. for use in STACKs), the way X509 handling is - these
     176             :  * operations may involve ensuring the hashes are up-to-date and ensuring
     177             :  * certain cert information is cached. So this is the point where the
     178             :  * "depth-first" constification tree has to halt with an evil cast.
     179             :  */
     180           0 : int X509_cmp(const X509 *a, const X509 *b)
     181             : {
     182             :     int rv;
     183             :     /* ensure hash is valid */
     184           0 :     X509_check_purpose((X509 *)a, -1, 0);
     185           0 :     X509_check_purpose((X509 *)b, -1, 0);
     186             : 
     187           0 :     rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
     188           0 :     if (rv)
     189             :         return rv;
     190             :     /* Check for match against stored encoding too */
     191           0 :     if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) {
     192           0 :         rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
     193           0 :         if (rv)
     194             :             return rv;
     195           0 :         return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc,
     196             :                       a->cert_info->enc.len);
     197             :     }
     198             :     return rv;
     199             : }
     200             : #endif
     201             : 
     202        2517 : int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
     203             : {
     204             :     int ret;
     205             : 
     206             :     /* Ensure canonical encoding is present and up to date */
     207             : 
     208        2517 :     if (!a->canon_enc || a->modified) {
     209           0 :         ret = i2d_X509_NAME((X509_NAME *)a, NULL);
     210           0 :         if (ret < 0)
     211             :             return -2;
     212             :     }
     213             : 
     214        2517 :     if (!b->canon_enc || b->modified) {
     215           0 :         ret = i2d_X509_NAME((X509_NAME *)b, NULL);
     216           0 :         if (ret < 0)
     217             :             return -2;
     218             :     }
     219             : 
     220        2517 :     ret = a->canon_enclen - b->canon_enclen;
     221             : 
     222        2517 :     if (ret)
     223             :         return ret;
     224             : 
     225        1440 :     return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
     226             : 
     227             : }
     228             : 
     229           0 : unsigned long X509_NAME_hash(X509_NAME *x)
     230             : {
     231             :     unsigned long ret = 0;
     232             :     unsigned char md[SHA_DIGEST_LENGTH];
     233             : 
     234             :     /* Make sure X509_NAME structure contains valid cached encoding */
     235           0 :     i2d_X509_NAME(x, NULL);
     236           0 :     if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
     237             :                     NULL))
     238             :         return 0;
     239             : 
     240           0 :     ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
     241           0 :            ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
     242             :         ) & 0xffffffffL;
     243           0 :     return (ret);
     244             : }
     245             : 
     246             : #ifndef OPENSSL_NO_MD5
     247             : /*
     248             :  * I now DER encode the name and hash it.  Since I cache the DER encoding,
     249             :  * this is reasonably efficient.
     250             :  */
     251             : 
     252           0 : unsigned long X509_NAME_hash_old(X509_NAME *x)
     253             : {
     254             :     EVP_MD_CTX md_ctx;
     255             :     unsigned long ret = 0;
     256             :     unsigned char md[16];
     257             : 
     258             :     /* Make sure X509_NAME structure contains valid cached encoding */
     259           0 :     i2d_X509_NAME(x, NULL);
     260           0 :     EVP_MD_CTX_init(&md_ctx);
     261           0 :     EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
     262           0 :     if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
     263           0 :         && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
     264           0 :         && EVP_DigestFinal_ex(&md_ctx, md, NULL))
     265           0 :         ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
     266           0 :                ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
     267             :             ) & 0xffffffffL;
     268           0 :     EVP_MD_CTX_cleanup(&md_ctx);
     269             : 
     270           0 :     return (ret);
     271             : }
     272             : #endif
     273             : 
     274             : /* Search a stack of X509 for a match */
     275           0 : X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
     276             :                                      ASN1_INTEGER *serial)
     277             : {
     278             :     int i;
     279             :     X509_CINF cinf;
     280             :     X509 x, *x509 = NULL;
     281             : 
     282           0 :     if (!sk)
     283             :         return NULL;
     284             : 
     285           0 :     x.cert_info = &cinf;
     286           0 :     cinf.serialNumber = serial;
     287           0 :     cinf.issuer = name;
     288             : 
     289           0 :     for (i = 0; i < sk_X509_num(sk); i++) {
     290           0 :         x509 = sk_X509_value(sk, i);
     291           0 :         if (X509_issuer_and_serial_cmp(x509, &x) == 0)
     292             :             return (x509);
     293             :     }
     294             :     return (NULL);
     295             : }
     296             : 
     297           0 : X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
     298             : {
     299             :     X509 *x509;
     300             :     int i;
     301             : 
     302           0 :     for (i = 0; i < sk_X509_num(sk); i++) {
     303           0 :         x509 = sk_X509_value(sk, i);
     304           0 :         if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
     305             :             return (x509);
     306             :     }
     307             :     return (NULL);
     308             : }
     309             : 
     310        4349 : EVP_PKEY *X509_get_pubkey(X509 *x)
     311             : {
     312        4349 :     if ((x == NULL) || (x->cert_info == NULL))
     313             :         return (NULL);
     314        4349 :     return (X509_PUBKEY_get(x->cert_info->key));
     315             : }
     316             : 
     317           0 : ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
     318             : {
     319           0 :     if (!x)
     320             :         return NULL;
     321           0 :     return x->cert_info->key->public_key;
     322             : }
     323             : 
     324         876 : int X509_check_private_key(X509 *x, EVP_PKEY *k)
     325             : {
     326             :     EVP_PKEY *xk;
     327             :     int ret;
     328             : 
     329         876 :     xk = X509_get_pubkey(x);
     330             : 
     331         876 :     if (xk)
     332         876 :         ret = EVP_PKEY_cmp(xk, k);
     333             :     else
     334             :         ret = -2;
     335             : 
     336         876 :     switch (ret) {
     337             :     case 1:
     338             :         break;
     339             :     case 0:
     340           0 :         X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH);
     341           0 :         break;
     342             :     case -1:
     343           0 :         X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH);
     344           0 :         break;
     345             :     case -2:
     346           0 :         X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
     347             :     }
     348         876 :     if (xk)
     349         876 :         EVP_PKEY_free(xk);
     350         876 :     if (ret > 0)
     351             :         return 1;
     352           0 :     return 0;
     353             : }
     354             : 
     355             : /*
     356             :  * Check a suite B algorithm is permitted: pass in a public key and the NID
     357             :  * of its signature (or 0 if no signature). The pflags is a pointer to a
     358             :  * flags field which must contain the suite B verification flags.
     359             :  */
     360             : 
     361             : #ifndef OPENSSL_NO_EC
     362             : 
     363           0 : static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
     364             : {
     365             :     const EC_GROUP *grp = NULL;
     366             :     int curve_nid;
     367           0 :     if (pkey && pkey->type == EVP_PKEY_EC)
     368           0 :         grp = EC_KEY_get0_group(pkey->pkey.ec);
     369           0 :     if (!grp)
     370             :         return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
     371           0 :     curve_nid = EC_GROUP_get_curve_name(grp);
     372             :     /* Check curve is consistent with LOS */
     373           0 :     if (curve_nid == NID_secp384r1) { /* P-384 */
     374             :         /*
     375             :          * Check signature algorithm is consistent with curve.
     376             :          */
     377           0 :         if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
     378             :             return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
     379           0 :         if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
     380             :             return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
     381             :         /* If we encounter P-384 we cannot use P-256 later */
     382           0 :         *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
     383           0 :     } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */
     384           0 :         if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
     385             :             return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
     386           0 :         if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
     387             :             return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
     388             :     } else
     389             :         return X509_V_ERR_SUITE_B_INVALID_CURVE;
     390             : 
     391             :     return X509_V_OK;
     392             : }
     393             : 
     394         370 : int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
     395             :                             unsigned long flags)
     396             : {
     397             :     int rv, i, sign_nid;
     398             :     EVP_PKEY *pk = NULL;
     399             :     unsigned long tflags;
     400         370 :     if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
     401             :         return X509_V_OK;
     402           0 :     tflags = flags;
     403             :     /* If no EE certificate passed in must be first in chain */
     404           0 :     if (x == NULL) {
     405           0 :         x = sk_X509_value(chain, 0);
     406             :         i = 1;
     407             :     } else
     408             :         i = 0;
     409             : 
     410           0 :     if (X509_get_version(x) != 2) {
     411             :         rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
     412             :         /* Correct error depth */
     413             :         i = 0;
     414             :         goto end;
     415             :     }
     416             : 
     417           0 :     pk = X509_get_pubkey(x);
     418             :     /* Check EE key only */
     419           0 :     rv = check_suite_b(pk, -1, &tflags);
     420           0 :     if (rv != X509_V_OK) {
     421             :         /* Correct error depth */
     422             :         i = 0;
     423             :         goto end;
     424             :     }
     425           0 :     for (; i < sk_X509_num(chain); i++) {
     426           0 :         sign_nid = X509_get_signature_nid(x);
     427           0 :         x = sk_X509_value(chain, i);
     428           0 :         if (X509_get_version(x) != 2) {
     429             :             rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
     430             :             goto end;
     431             :         }
     432           0 :         EVP_PKEY_free(pk);
     433           0 :         pk = X509_get_pubkey(x);
     434           0 :         rv = check_suite_b(pk, sign_nid, &tflags);
     435           0 :         if (rv != X509_V_OK)
     436             :             goto end;
     437             :     }
     438             : 
     439             :     /* Final check: root CA signature */
     440           0 :     rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
     441             :  end:
     442           0 :     if (pk)
     443           0 :         EVP_PKEY_free(pk);
     444           0 :     if (rv != X509_V_OK) {
     445             :         /* Invalid signature or LOS errors are for previous cert */
     446           0 :         if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
     447           0 :              || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
     448           0 :             i--;
     449             :         /*
     450             :          * If we have LOS error and flags changed then we are signing P-384
     451             :          * with P-256. Use more meaninggul error.
     452             :          */
     453           0 :         if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
     454             :             rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
     455           0 :         if (perror_depth)
     456           0 :             *perror_depth = i;
     457             :     }
     458           0 :     return rv;
     459             : }
     460             : 
     461           0 : int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
     462             : {
     463             :     int sign_nid;
     464           0 :     if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
     465             :         return X509_V_OK;
     466           0 :     sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
     467           0 :     return check_suite_b(pk, sign_nid, &flags);
     468             : }
     469             : 
     470             : #else
     471             : int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
     472             :                             unsigned long flags)
     473             : {
     474             :     return 0;
     475             : }
     476             : 
     477             : int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
     478             : {
     479             :     return 0;
     480             : }
     481             : 
     482             : #endif
     483             : /*
     484             :  * Not strictly speaking an "up_ref" as a STACK doesn't have a reference
     485             :  * count but it has the same effect by duping the STACK and upping the ref of
     486             :  * each X509 structure.
     487             :  */
     488           0 : STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
     489             : {
     490             :     STACK_OF(X509) *ret;
     491             :     int i;
     492           0 :     ret = sk_X509_dup(chain);
     493           0 :     for (i = 0; i < sk_X509_num(ret); i++) {
     494           0 :         X509 *x = sk_X509_value(ret, i);
     495           0 :         CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
     496             :     }
     497           0 :     return ret;
     498             : }

Generated by: LCOV version 1.10