LCOV - code coverage report
Current view: top level - x509 - x509_cmp.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 74 167 44.3 %
Date: 2014-08-02 Functions: 16 26 61.5 %
Branches: 32 116 27.6 %

           Branch data     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                 :        107 : int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
      68                 :            :         {
      69                 :            :         int i;
      70                 :            :         X509_CINF *ai,*bi;
      71                 :            : 
      72                 :        107 :         ai=a->cert_info;
      73                 :        107 :         bi=b->cert_info;
      74                 :        107 :         i=M_ASN1_INTEGER_cmp(ai->serialNumber,bi->serialNumber);
      75         [ +  + ]:        107 :         if (i) return(i);
      76                 :         57 :         return(X509_NAME_cmp(ai->issuer,bi->issuer));
      77                 :            :         }
      78                 :            : 
      79                 :            : #ifndef OPENSSL_NO_MD5
      80                 :          0 : unsigned long X509_issuer_and_serial_hash(X509 *a)
      81                 :            :         {
      82                 :          0 :         unsigned long ret=0;
      83                 :            :         EVP_MD_CTX ctx;
      84                 :            :         unsigned char md[16];
      85                 :            :         char *f;
      86                 :            : 
      87                 :          0 :         EVP_MD_CTX_init(&ctx);
      88                 :          0 :         f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
      89         [ #  # ]:          0 :         if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
      90                 :            :                 goto err;
      91         [ #  # ]:          0 :         if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
      92                 :            :                 goto err;
      93                 :          0 :         OPENSSL_free(f);
      94         [ #  # ]:          0 :         if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
      95                 :          0 :                 (unsigned long)a->cert_info->serialNumber->length))
      96                 :            :                 goto err;
      97         [ #  # ]:          0 :         if (!EVP_DigestFinal_ex(&ctx,&(md[0]),NULL))
      98                 :            :                 goto err;
      99                 :          0 :         ret=(   ((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
     100                 :          0 :                 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
     101                 :            :                 )&0xffffffffL;
     102                 :            :         err:
     103                 :          0 :         EVP_MD_CTX_cleanup(&ctx);
     104                 :          0 :         return(ret);
     105                 :            :         }
     106                 :            : #endif
     107                 :            :         
     108                 :          0 : int X509_issuer_name_cmp(const X509 *a, const X509 *b)
     109                 :            :         {
     110                 :          0 :         return(X509_NAME_cmp(a->cert_info->issuer,b->cert_info->issuer));
     111                 :            :         }
     112                 :            : 
     113                 :       3735 : int X509_subject_name_cmp(const X509 *a, const X509 *b)
     114                 :            :         {
     115                 :       3735 :         return(X509_NAME_cmp(a->cert_info->subject,b->cert_info->subject));
     116                 :            :         }
     117                 :            : 
     118                 :          0 : int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
     119                 :            :         {
     120                 :          0 :         return(X509_NAME_cmp(a->crl->issuer,b->crl->issuer));
     121                 :            :         }
     122                 :            : 
     123                 :            : #ifndef OPENSSL_NO_SHA
     124                 :          0 : int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
     125                 :            :         {
     126                 :          0 :         return memcmp(a->sha1_hash, b->sha1_hash, 20);
     127                 :            :         }
     128                 :            : #endif
     129                 :            : 
     130                 :      11264 : X509_NAME *X509_get_issuer_name(X509 *a)
     131                 :            :         {
     132                 :      11264 :         return(a->cert_info->issuer);
     133                 :            :         }
     134                 :            : 
     135                 :          0 : unsigned long X509_issuer_name_hash(X509 *x)
     136                 :            :         {
     137                 :          0 :         return(X509_NAME_hash(x->cert_info->issuer));
     138                 :            :         }
     139                 :            : 
     140                 :            : #ifndef OPENSSL_NO_MD5
     141                 :          0 : unsigned long X509_issuer_name_hash_old(X509 *x)
     142                 :            :         {
     143                 :          0 :         return(X509_NAME_hash_old(x->cert_info->issuer));
     144                 :            :         }
     145                 :            : #endif
     146                 :            : 
     147                 :      56863 : X509_NAME *X509_get_subject_name(X509 *a)
     148                 :            :         {
     149                 :      56863 :         return(a->cert_info->subject);
     150                 :            :         }
     151                 :            : 
     152                 :       2565 : ASN1_INTEGER *X509_get_serialNumber(X509 *a)
     153                 :            :         {
     154                 :       2565 :         return(a->cert_info->serialNumber);
     155                 :            :         }
     156                 :            : 
     157                 :          4 : unsigned long X509_subject_name_hash(X509 *x)
     158                 :            :         {
     159                 :          4 :         return(X509_NAME_hash(x->cert_info->subject));
     160                 :            :         }
     161                 :            : 
     162                 :            : #ifndef OPENSSL_NO_MD5
     163                 :          0 : unsigned long X509_subject_name_hash_old(X509 *x)
     164                 :            :         {
     165                 :          0 :         return(X509_NAME_hash_old(x->cert_info->subject));
     166                 :            :         }
     167                 :            : #endif
     168                 :            : 
     169                 :            : #ifndef OPENSSL_NO_SHA
     170                 :            : /* Compare two certificates: they must be identical for
     171                 :            :  * this to work. NB: Although "cmp" operations are generally
     172                 :            :  * prototyped to take "const" arguments (eg. for use in
     173                 :            :  * STACKs), the way X509 handling is - these operations may
     174                 :            :  * involve ensuring the hashes are up-to-date and ensuring
     175                 :            :  * certain cert information is cached. So this is the point
     176                 :            :  * where the "depth-first" constification tree has to halt
     177                 :            :  * with an evil cast.
     178                 :            :  */
     179                 :       3038 : int X509_cmp(const X509 *a, const X509 *b)
     180                 :            : {
     181                 :            :         int rv;
     182                 :            :         /* ensure hash is valid */
     183                 :       3038 :         X509_check_purpose((X509 *)a, -1, 0);
     184                 :       3038 :         X509_check_purpose((X509 *)b, -1, 0);
     185                 :            : 
     186                 :       3038 :         rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
     187         [ +  + ]:       3038 :         if (rv)
     188                 :            :                 return rv;
     189                 :            :         /* Check for match against stored encoding too */
     190 [ +  - ][ +  - ]:         12 :         if (!a->cert_info->enc.modified && !b->cert_info->enc.modified)
     191                 :            :                 {
     192                 :         12 :                 rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len);
     193         [ +  - ]:         12 :                 if (rv)
     194                 :            :                         return rv;
     195                 :         12 :                 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                 :            : 
     203                 :      12099 : int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
     204                 :            :         {
     205                 :            :         int ret;
     206                 :            : 
     207                 :            :         /* Ensure canonical encoding is present and up to date */
     208                 :            : 
     209 [ +  - ][ -  + ]:      12099 :         if (!a->canon_enc || a->modified)
     210                 :            :                 {
     211                 :          0 :                 ret = i2d_X509_NAME((X509_NAME *)a, NULL);
     212         [ #  # ]:          0 :                 if (ret < 0)
     213                 :            :                         return -2;
     214                 :            :                 }
     215                 :            : 
     216 [ +  - ][ -  + ]:      12099 :         if (!b->canon_enc || b->modified)
     217                 :            :                 {
     218                 :          0 :                 ret = i2d_X509_NAME((X509_NAME *)b, NULL);
     219         [ #  # ]:          0 :                 if (ret < 0)
     220                 :            :                         return -2;
     221                 :            :                 }
     222                 :            : 
     223                 :      12099 :         ret = a->canon_enclen - b->canon_enclen;
     224                 :            : 
     225         [ +  + ]:      12099 :         if (ret)
     226                 :            :                 return ret;
     227                 :            : 
     228                 :       6129 :         return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
     229                 :            : 
     230                 :            :         }
     231                 :            : 
     232                 :         21 : unsigned long X509_NAME_hash(X509_NAME *x)
     233                 :            :         {
     234                 :         21 :         unsigned long ret=0;
     235                 :            :         unsigned char md[SHA_DIGEST_LENGTH];
     236                 :            : 
     237                 :            :         /* Make sure X509_NAME structure contains valid cached encoding */
     238                 :         21 :         i2d_X509_NAME(x,NULL);
     239         [ +  - ]:         21 :         if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
     240                 :            :                 NULL))
     241                 :            :                 return 0;
     242                 :            : 
     243                 :         63 :         ret=(   ((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
     244                 :         42 :                 ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
     245                 :            :                 )&0xffffffffL;
     246                 :         21 :         return(ret);
     247                 :            :         }
     248                 :            : 
     249                 :            : 
     250                 :            : #ifndef OPENSSL_NO_MD5
     251                 :            : /* I now DER encode the name and hash it.  Since I cache the DER encoding,
     252                 :            :  * this is reasonably efficient. */
     253                 :            : 
     254                 :          0 : unsigned long X509_NAME_hash_old(X509_NAME *x)
     255                 :            :         {
     256                 :            :         EVP_MD_CTX md_ctx;
     257                 :          0 :         unsigned long ret=0;
     258                 :            :         unsigned char md[16];
     259                 :            : 
     260                 :            :         /* Make sure X509_NAME structure contains valid cached encoding */
     261                 :          0 :         i2d_X509_NAME(x,NULL);
     262                 :          0 :         EVP_MD_CTX_init(&md_ctx);
     263                 :          0 :         EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
     264         [ #  # ]:          0 :         if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
     265         [ #  # ]:          0 :             && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
     266         [ #  # ]:          0 :             && EVP_DigestFinal_ex(&md_ctx,md,NULL))
     267                 :          0 :                 ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
     268                 :          0 :                      ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
     269                 :            :                      )&0xffffffffL;
     270                 :          0 :         EVP_MD_CTX_cleanup(&md_ctx);
     271                 :            : 
     272                 :          0 :         return(ret);
     273                 :            :         }
     274                 :            : #endif
     275                 :            : 
     276                 :            : /* Search a stack of X509 for a match */
     277                 :         57 : X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
     278                 :            :                 ASN1_INTEGER *serial)
     279                 :            :         {
     280                 :            :         int i;
     281                 :            :         X509_CINF cinf;
     282                 :         57 :         X509 x,*x509=NULL;
     283                 :            : 
     284         [ +  - ]:         57 :         if(!sk) return NULL;
     285                 :            : 
     286                 :         57 :         x.cert_info= &cinf;
     287                 :         57 :         cinf.serialNumber=serial;
     288                 :         57 :         cinf.issuer=name;
     289                 :            : 
     290         [ +  - ]:        107 :         for (i=0; i<sk_X509_num(sk); i++)
     291                 :            :                 {
     292                 :        107 :                 x509=sk_X509_value(sk,i);
     293         [ +  + ]:        107 :                 if (X509_issuer_and_serial_cmp(x509,&x) == 0)
     294                 :            :                         return(x509);
     295                 :            :                 }
     296                 :            :         return(NULL);
     297                 :            :         }
     298                 :            : 
     299                 :         20 : X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
     300                 :            :         {
     301                 :            :         X509 *x509;
     302                 :            :         int i;
     303                 :            : 
     304         [ +  + ]:         38 :         for (i=0; i<sk_X509_num(sk); i++)
     305                 :            :                 {
     306                 :         27 :                 x509=sk_X509_value(sk,i);
     307         [ +  + ]:         27 :                 if (X509_NAME_cmp(X509_get_subject_name(x509),name) == 0)
     308                 :            :                         return(x509);
     309                 :            :                 }
     310                 :            :         return(NULL);
     311                 :            :         }
     312                 :            : 
     313                 :      14609 : EVP_PKEY *X509_get_pubkey(X509 *x)
     314                 :            :         {
     315 [ +  - ][ +  - ]:      14609 :         if ((x == NULL) || (x->cert_info == NULL))
     316                 :            :                 return(NULL);
     317                 :      14609 :         return(X509_PUBKEY_get(x->cert_info->key));
     318                 :            :         }
     319                 :            : 
     320                 :         76 : ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
     321                 :            :         {
     322         [ +  - ]:         76 :         if(!x) return NULL;
     323                 :         76 :         return x->cert_info->key->public_key;
     324                 :            :         }
     325                 :            : 
     326                 :            : 
     327                 :       1130 : int X509_check_private_key(X509 *x, EVP_PKEY *k)
     328                 :            :         {
     329                 :            :         EVP_PKEY *xk;
     330                 :            :         int ret;
     331                 :            : 
     332                 :       1130 :         xk=X509_get_pubkey(x);
     333                 :            : 
     334         [ +  - ]:       1130 :         if (xk)
     335                 :       1130 :                 ret = EVP_PKEY_cmp(xk, k);
     336                 :            :         else
     337                 :            :                 ret = -2;
     338                 :            : 
     339   [ -  -  -  + ]:       1130 :         switch (ret)
     340                 :            :                 {
     341                 :            :         case 1:
     342                 :            :                 break;
     343                 :            :         case 0:
     344                 :          0 :                 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
     345                 :          0 :                 break;
     346                 :            :         case -1:
     347                 :          0 :                 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
     348                 :          0 :                 break;
     349                 :            :         case -2:
     350                 :          0 :                 X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
     351                 :            :                 }
     352         [ +  - ]:       1130 :         if (xk)
     353                 :       1130 :                 EVP_PKEY_free(xk);
     354         [ -  + ]:       1130 :         if (ret > 0)
     355                 :            :                 return 1;
     356                 :          0 :         return 0;
     357                 :            :         }
     358                 :            : 
     359                 :            : /* Check a suite B algorithm is permitted: pass in a public key and
     360                 :            :  * the NID of its signature (or 0 if no signature). The pflags is
     361                 :            :  * a pointer to a flags field which must contain the suite B verification
     362                 :            :  * flags.
     363                 :            :  */
     364                 :            : 
     365                 :            : #ifndef OPENSSL_NO_EC
     366                 :            : 
     367                 :          0 : static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
     368                 :            :         {
     369                 :          0 :         const EC_GROUP *grp = NULL;
     370                 :            :         int curve_nid;
     371 [ #  # ][ #  # ]:          0 :         if (pkey && pkey->type == EVP_PKEY_EC)
     372                 :          0 :                 grp = EC_KEY_get0_group(pkey->pkey.ec);
     373         [ #  # ]:          0 :         if (!grp)
     374                 :            :                 return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
     375                 :          0 :         curve_nid = EC_GROUP_get_curve_name(grp);
     376                 :            :         /* Check curve is consistent with LOS */
     377         [ #  # ]:          0 :         if (curve_nid == NID_secp384r1) /* P-384 */
     378                 :            :                 {
     379                 :            :                 /* Check signature algorithm is consistent with
     380                 :            :                  * curve.
     381                 :            :                  */
     382         [ #  # ]:          0 :                 if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
     383                 :            :                         return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
     384         [ #  # ]:          0 :                 if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
     385                 :            :                         return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
     386                 :            :                 /* If we encounter P-384 we cannot use P-256 later */
     387                 :          0 :                 *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
     388                 :            :                 }
     389         [ #  # ]:          0 :         else if (curve_nid == NID_X9_62_prime256v1) /* P-256 */
     390                 :            :                 {
     391         [ #  # ]:          0 :                 if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
     392                 :            :                         return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
     393         [ #  # ]:          0 :                 if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
     394                 :            :                         return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
     395                 :            :                 }
     396                 :            :         else
     397                 :            :                 return X509_V_ERR_SUITE_B_INVALID_CURVE;
     398                 :            : 
     399                 :            :         return X509_V_OK;
     400                 :            :         }
     401                 :            : 
     402                 :        436 : int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
     403                 :            :                                                         unsigned long flags)
     404                 :            :         {
     405                 :            :         int rv, i, sign_nid;
     406                 :        436 :         EVP_PKEY *pk = NULL;
     407                 :            :         unsigned long tflags;
     408         [ -  + ]:        436 :         if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
     409                 :            :                 return X509_V_OK;
     410                 :          0 :         tflags = flags;
     411                 :            :         /* If no EE certificate passed in must be first in chain */
     412         [ #  # ]:          0 :         if (x == NULL)
     413                 :            :                 {
     414                 :          0 :                 x = sk_X509_value(chain, 0);
     415                 :          0 :                 i = 1;
     416                 :            :                 }
     417                 :            :         else
     418                 :            :                 i = 0;
     419                 :            : 
     420         [ #  # ]:          0 :         if (X509_get_version(x) != 2)
     421                 :            :                 {
     422                 :            :                 rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
     423                 :            :                 /* Correct error depth */
     424                 :            :                 i = 0;
     425                 :            :                 goto end;
     426                 :            :                 }
     427                 :            : 
     428                 :          0 :         pk = X509_get_pubkey(x);
     429                 :            :         /* Check EE key only */
     430                 :          0 :         rv = check_suite_b(pk, -1, &tflags);
     431         [ #  # ]:          0 :         if (rv != X509_V_OK)
     432                 :            :                 {
     433                 :            :                 /* Correct error depth */
     434                 :            :                 i = 0;
     435                 :            :                 goto end;
     436                 :            :                 }
     437         [ #  # ]:          0 :         for(; i < sk_X509_num(chain); i++)
     438                 :            :                 {
     439                 :          0 :                 sign_nid = X509_get_signature_nid(x);
     440                 :          0 :                 x = sk_X509_value(chain, i);
     441         [ #  # ]:          0 :                 if (X509_get_version(x) != 2)
     442                 :            :                         {
     443                 :            :                         rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
     444                 :            :                         goto end;
     445                 :            :                         }
     446                 :          0 :                 EVP_PKEY_free(pk);
     447                 :          0 :                 pk = X509_get_pubkey(x);
     448                 :          0 :                 rv = check_suite_b(pk, sign_nid, &tflags);
     449         [ #  # ]:          0 :                 if (rv != X509_V_OK)
     450                 :            :                         goto end;
     451                 :            :                 }
     452                 :            : 
     453                 :            :         /* Final check: root CA signature */
     454                 :          0 :         rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
     455                 :            :         end:
     456         [ #  # ]:          0 :         if (pk)
     457                 :          0 :                 EVP_PKEY_free(pk);
     458         [ #  # ]:          0 :         if (rv != X509_V_OK)
     459                 :            :                 {
     460                 :            :                 /* Invalid signature or LOS errors are for previous cert */
     461         [ #  # ]:          0 :                 if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
     462         [ #  # ]:          0 :                     || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
     463                 :          0 :                         i--;
     464                 :            :                 /* If we have LOS error and flags changed then we are signing
     465                 :            :                  * P-384 with P-256. Use more meaninggul error.
     466                 :            :                  */
     467 [ #  # ][ #  # ]:          0 :                 if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
     468                 :          0 :                         rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
     469         [ #  # ]:          0 :                 if (perror_depth)
     470                 :          0 :                         *perror_depth = i;
     471                 :            :                 }
     472                 :          0 :         return rv;
     473                 :            :         }
     474                 :            : 
     475                 :          0 : int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
     476                 :            :         {
     477                 :            :         int sign_nid;
     478         [ #  # ]:          0 :         if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
     479                 :            :                 return X509_V_OK;
     480                 :          0 :         sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
     481                 :          0 :         return check_suite_b(pk, sign_nid, &flags);
     482                 :            :         }
     483                 :            : 
     484                 :            : #else
     485                 :            : int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
     486                 :            :                                                         unsigned long flags)
     487                 :            :         {
     488                 :            :         return 0;
     489                 :            :         }
     490                 :            : 
     491                 :            : int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
     492                 :            :         {
     493                 :            :         return 0;
     494                 :            :         }
     495                 :            : 
     496                 :            : #endif
     497                 :            : /* Not strictly speaking an "up_ref" as a STACK doesn't have a reference
     498                 :            :  * count but it has the same effect by duping the STACK and upping the ref
     499                 :            :  * of each X509 structure.
     500                 :            :  */
     501                 :         36 : STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
     502                 :            :         {
     503                 :            :         STACK_OF(X509) *ret;
     504                 :            :         int i;
     505                 :         36 :         ret = sk_X509_dup(chain);
     506         [ +  + ]:         93 :         for (i = 0; i < sk_X509_num(ret); i++)
     507                 :            :                 {
     508                 :         57 :                 X509 *x = sk_X509_value(ret, i);
     509                 :         57 :                 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
     510                 :            :                 }
     511                 :         36 :         return ret;
     512                 :            :         }

Generated by: LCOV version 1.9