LCOV - code coverage report
Current view: top level - dh - dh_ameth.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 206 389 53.0 %
Date: 2014-08-02 Functions: 15 30 50.0 %
Branches: 100 299 33.4 %

           Branch data     Line data    Source code
       1                 :            : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
       2                 :            :  * project 2006.
       3                 :            :  */
       4                 :            : /* ====================================================================
       5                 :            :  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
       6                 :            :  *
       7                 :            :  * Redistribution and use in source and binary forms, with or without
       8                 :            :  * modification, are permitted provided that the following conditions
       9                 :            :  * are met:
      10                 :            :  *
      11                 :            :  * 1. Redistributions of source code must retain the above copyright
      12                 :            :  *    notice, this list of conditions and the following disclaimer. 
      13                 :            :  *
      14                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      15                 :            :  *    notice, this list of conditions and the following disclaimer in
      16                 :            :  *    the documentation and/or other materials provided with the
      17                 :            :  *    distribution.
      18                 :            :  *
      19                 :            :  * 3. All advertising materials mentioning features or use of this
      20                 :            :  *    software must display the following acknowledgment:
      21                 :            :  *    "This product includes software developed by the OpenSSL Project
      22                 :            :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      23                 :            :  *
      24                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      25                 :            :  *    endorse or promote products derived from this software without
      26                 :            :  *    prior written permission. For written permission, please contact
      27                 :            :  *    licensing@OpenSSL.org.
      28                 :            :  *
      29                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      30                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      31                 :            :  *    permission of the OpenSSL Project.
      32                 :            :  *
      33                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      34                 :            :  *    acknowledgment:
      35                 :            :  *    "This product includes software developed by the OpenSSL Project
      36                 :            :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      37                 :            :  *
      38                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      39                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      40                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      41                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      42                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      43                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      44                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      45                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      46                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      47                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      48                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      49                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      50                 :            :  * ====================================================================
      51                 :            :  *
      52                 :            :  * This product includes cryptographic software written by Eric Young
      53                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      54                 :            :  * Hudson (tjh@cryptsoft.com).
      55                 :            :  *
      56                 :            :  */
      57                 :            : 
      58                 :            : #include <stdio.h>
      59                 :            : #include "cryptlib.h"
      60                 :            : #include <openssl/x509.h>
      61                 :            : #include <openssl/asn1.h>
      62                 :            : #include <openssl/dh.h>
      63                 :            : #include <openssl/bn.h>
      64                 :            : #include "asn1_locl.h"
      65                 :            : #ifndef OPENSSL_NO_CMS
      66                 :            : #include <openssl/cms.h>
      67                 :            : #endif
      68                 :            : 
      69                 :            : extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
      70                 :            : 
      71                 :            : /* i2d/d2i like DH parameter functions which use the appropriate routine
      72                 :            :  * for PKCS#3 DH or X9.42 DH.
      73                 :            :  */
      74                 :            : 
      75                 :          4 : static DH * d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, long length)
      76                 :            :         {
      77         [ +  - ]:          2 :         if (pkey->ameth == &dhx_asn1_meth)
      78                 :          2 :                 return d2i_DHxparams(NULL, pp, length);
      79                 :          0 :         return d2i_DHparams(NULL, pp, length);
      80                 :            :         }
      81                 :            : 
      82                 :          0 : static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
      83                 :            :         {
      84         [ #  # ]:          0 :         if (pkey->ameth == &dhx_asn1_meth)
      85                 :          0 :                 return i2d_DHxparams(a, pp);
      86                 :          0 :         return i2d_DHparams(a, pp);
      87                 :            :         }
      88                 :            : 
      89                 :          4 : static void int_dh_free(EVP_PKEY *pkey)
      90                 :            :         {
      91                 :          4 :         DH_free(pkey->pkey.dh);
      92                 :          4 :         }
      93                 :            : 
      94                 :          1 : static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
      95                 :            :         {
      96                 :            :         const unsigned char *p, *pm;
      97                 :            :         int pklen, pmlen;
      98                 :            :         int ptype;
      99                 :            :         void *pval;
     100                 :            :         ASN1_STRING *pstr;
     101                 :            :         X509_ALGOR *palg;
     102                 :          1 :         ASN1_INTEGER *public_key = NULL;
     103                 :            : 
     104                 :          1 :         DH *dh = NULL;
     105                 :            : 
     106         [ +  - ]:          1 :         if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
     107                 :            :                 return 0;
     108                 :          1 :         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
     109                 :            : 
     110         [ -  + ]:          1 :         if (ptype != V_ASN1_SEQUENCE)
     111                 :            :                 {
     112                 :          0 :                 DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
     113                 :          0 :                 goto err;
     114                 :            :                 }
     115                 :            : 
     116                 :          1 :         pstr = pval;    
     117                 :          1 :         pm = pstr->data;
     118                 :          1 :         pmlen = pstr->length;
     119                 :            : 
     120         [ -  + ]:          1 :         if (!(dh = d2i_dhp(pkey, &pm, pmlen)))
     121                 :            :                 {
     122                 :          0 :                 DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
     123                 :          0 :                 goto err;
     124                 :            :                 }
     125                 :            : 
     126         [ -  + ]:          1 :         if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
     127                 :            :                 {
     128                 :          0 :                 DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
     129                 :          0 :                 goto err;
     130                 :            :                 }
     131                 :            : 
     132                 :            :         /* We have parameters now set public key */
     133         [ -  + ]:          1 :         if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
     134                 :            :                 {
     135                 :          0 :                 DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
     136                 :          0 :                 goto err;
     137                 :            :                 }
     138                 :            : 
     139                 :          1 :         ASN1_INTEGER_free(public_key);
     140                 :          1 :         EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
     141                 :          1 :         return 1;
     142                 :            : 
     143                 :            :         err:
     144         [ #  # ]:          0 :         if (public_key)
     145                 :          0 :                 ASN1_INTEGER_free(public_key);
     146         [ #  # ]:          0 :         if (dh)
     147                 :          0 :                 DH_free(dh);
     148                 :            :         return 0;
     149                 :            : 
     150                 :            :         }
     151                 :            : 
     152                 :          0 : static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
     153                 :            :         {
     154                 :            :         DH *dh;
     155                 :          0 :         void *pval = NULL;
     156                 :            :         int ptype;
     157                 :          0 :         unsigned char *penc = NULL;
     158                 :            :         int penclen;
     159                 :            :         ASN1_STRING *str;
     160                 :          0 :         ASN1_INTEGER *pub_key = NULL;
     161                 :            : 
     162                 :          0 :         dh=pkey->pkey.dh;
     163                 :            : 
     164                 :          0 :         str = ASN1_STRING_new();
     165                 :          0 :         str->length = i2d_dhp(pkey, dh, &str->data);
     166         [ #  # ]:          0 :         if (str->length <= 0)
     167                 :            :                 {
     168                 :          0 :                 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
     169                 :          0 :                 goto err;
     170                 :            :                 }
     171                 :          0 :         pval = str;
     172                 :          0 :         ptype = V_ASN1_SEQUENCE;
     173                 :            : 
     174                 :          0 :         pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
     175         [ #  # ]:          0 :         if (!pub_key)
     176                 :            :                 goto err;
     177                 :            : 
     178                 :          0 :         penclen = i2d_ASN1_INTEGER(pub_key, &penc);
     179                 :            : 
     180                 :          0 :         ASN1_INTEGER_free(pub_key);
     181                 :            : 
     182         [ #  # ]:          0 :         if (penclen <= 0)
     183                 :            :                 {
     184                 :          0 :                 DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
     185                 :          0 :                 goto err;
     186                 :            :                 }
     187                 :            : 
     188         [ #  # ]:          0 :         if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
     189                 :            :                                 ptype, pval, penc, penclen))
     190                 :            :                 return 1;
     191                 :            : 
     192                 :            :         err:
     193         [ #  # ]:          0 :         if (penc)
     194                 :          0 :                 OPENSSL_free(penc);
     195         [ #  # ]:          0 :         if (pval)
     196                 :          0 :                 ASN1_STRING_free(pval);
     197                 :            : 
     198                 :            :         return 0;
     199                 :            :         }
     200                 :            : 
     201                 :            : 
     202                 :            : /* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
     203                 :            :  * that the AlgorithmIdentifier contains the parameters, the private key
     204                 :            :  * is explcitly included and the pubkey must be recalculated.
     205                 :            :  */
     206                 :            :         
     207                 :          1 : static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
     208                 :            :         {
     209                 :            :         const unsigned char *p, *pm;
     210                 :            :         int pklen, pmlen;
     211                 :            :         int ptype;
     212                 :            :         void *pval;
     213                 :            :         ASN1_STRING *pstr;
     214                 :            :         X509_ALGOR *palg;
     215                 :          1 :         ASN1_INTEGER *privkey = NULL;
     216                 :            : 
     217                 :          1 :         DH *dh = NULL;
     218                 :            : 
     219         [ +  - ]:          1 :         if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
     220                 :            :                 return 0;
     221                 :            : 
     222                 :          1 :         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
     223                 :            : 
     224         [ +  - ]:          1 :         if (ptype != V_ASN1_SEQUENCE)
     225                 :            :                         goto decerr;
     226                 :            : 
     227         [ +  - ]:          1 :         if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
     228                 :            :                 goto decerr;
     229                 :            : 
     230                 :            : 
     231                 :          1 :         pstr = pval;    
     232                 :          1 :         pm = pstr->data;
     233                 :          1 :         pmlen = pstr->length;
     234         [ +  - ]:          1 :         if (!(dh = d2i_dhp(pkey, &pm, pmlen)))
     235                 :            :                 goto decerr;
     236                 :            :         /* We have parameters now set private key */
     237         [ -  + ]:          1 :         if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
     238                 :            :                 {
     239                 :          0 :                 DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
     240                 :          0 :                 goto dherr;
     241                 :            :                 }
     242                 :            :         /* Calculate public key */
     243         [ +  - ]:          1 :         if (!DH_generate_key(dh))
     244                 :            :                 goto dherr;
     245                 :            : 
     246                 :          1 :         EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
     247                 :            : 
     248                 :          1 :         ASN1_INTEGER_free(privkey);
     249                 :            : 
     250                 :          1 :         return 1;
     251                 :            : 
     252                 :            :         decerr:
     253                 :          0 :         DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
     254                 :            :         dherr:
     255                 :          0 :         DH_free(dh);
     256                 :          0 :         return 0;
     257                 :            :         }
     258                 :            : 
     259                 :          0 : static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
     260                 :            : {
     261                 :          0 :         ASN1_STRING *params = NULL;
     262                 :          0 :         ASN1_INTEGER *prkey = NULL;
     263                 :          0 :         unsigned char *dp = NULL;
     264                 :            :         int dplen;
     265                 :            : 
     266                 :          0 :         params = ASN1_STRING_new();
     267                 :            : 
     268         [ #  # ]:          0 :         if (!params)
     269                 :            :                 {
     270                 :          0 :                 DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
     271                 :          0 :                 goto err;
     272                 :            :                 }
     273                 :            : 
     274                 :          0 :         params->length = i2d_dhp(pkey, pkey->pkey.dh, &params->data);
     275         [ #  # ]:          0 :         if (params->length <= 0)
     276                 :            :                 {
     277                 :          0 :                 DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
     278                 :          0 :                 goto err;
     279                 :            :                 }
     280                 :          0 :         params->type = V_ASN1_SEQUENCE;
     281                 :            : 
     282                 :            :         /* Get private key into integer */
     283                 :          0 :         prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
     284                 :            : 
     285         [ #  # ]:          0 :         if (!prkey)
     286                 :            :                 {
     287                 :          0 :                 DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
     288                 :          0 :                 goto err;
     289                 :            :                 }
     290                 :            : 
     291                 :          0 :         dplen = i2d_ASN1_INTEGER(prkey, &dp);
     292                 :            : 
     293                 :          0 :         ASN1_INTEGER_free(prkey);
     294                 :            : 
     295         [ #  # ]:          0 :         if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
     296                 :            :                                 V_ASN1_SEQUENCE, params, dp, dplen))
     297                 :            :                 goto err;
     298                 :            : 
     299                 :            :         return 1;
     300                 :            : 
     301                 :            : err:
     302         [ #  # ]:          0 :         if (dp != NULL)
     303                 :          0 :                 OPENSSL_free(dp);
     304         [ #  # ]:          0 :         if (params != NULL)
     305                 :          0 :                 ASN1_STRING_free(params);
     306         [ #  # ]:          0 :         if (prkey != NULL)
     307                 :          0 :                 ASN1_INTEGER_free(prkey);
     308                 :            :         return 0;
     309                 :            : }
     310                 :            : 
     311                 :            : 
     312                 :          0 : static void update_buflen(const BIGNUM *b, size_t *pbuflen)
     313                 :            :         {
     314                 :            :         size_t i;
     315         [ #  # ]:          0 :         if (!b)
     316                 :          0 :                 return;
     317         [ #  # ]:          0 :         if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
     318                 :          0 :                         *pbuflen = i;
     319                 :            :         }
     320                 :            : 
     321                 :          0 : static int dh_param_decode(EVP_PKEY *pkey,
     322                 :            :                                         const unsigned char **pder, int derlen)
     323                 :            :         {
     324                 :            :         DH *dh;
     325         [ #  # ]:          0 :         if (!(dh = d2i_dhp(pkey, pder, derlen)))
     326                 :            :                 {
     327                 :          0 :                 DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
     328                 :          0 :                 return 0;
     329                 :            :                 }
     330                 :          0 :         EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
     331                 :          0 :         return 1;
     332                 :            :         }
     333                 :            : 
     334                 :          0 : static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
     335                 :            :         {
     336                 :          0 :         return i2d_dhp(pkey, pkey->pkey.dh, pder);
     337                 :            :         }
     338                 :            : 
     339                 :          0 : static int do_dh_print(BIO *bp, const DH *x, int indent,
     340                 :            :                                                 ASN1_PCTX *ctx, int ptype)
     341                 :            :         {
     342                 :          0 :         unsigned char *m=NULL;
     343                 :          0 :         int reason=ERR_R_BUF_LIB,ret=0;
     344                 :          0 :         size_t buf_len=0;
     345                 :            : 
     346                 :          0 :         const char *ktype = NULL;
     347                 :            : 
     348                 :            :         BIGNUM *priv_key, *pub_key;
     349                 :            : 
     350         [ #  # ]:          0 :         if (ptype == 2)
     351                 :          0 :                 priv_key = x->priv_key;
     352                 :            :         else
     353                 :            :                 priv_key = NULL;
     354                 :            : 
     355         [ #  # ]:          0 :         if (ptype > 0)
     356                 :          0 :                 pub_key = x->pub_key;
     357                 :            :         else
     358                 :            :                 pub_key = NULL;
     359                 :            : 
     360                 :          0 :         update_buflen(x->p, &buf_len);
     361                 :            : 
     362         [ #  # ]:          0 :         if (buf_len == 0)
     363                 :            :                 {
     364                 :            :                 reason = ERR_R_PASSED_NULL_PARAMETER;
     365                 :            :                 goto err;
     366                 :            :                 }
     367                 :            : 
     368                 :          0 :         update_buflen(x->g, &buf_len);
     369                 :          0 :         update_buflen(x->q, &buf_len);
     370                 :          0 :         update_buflen(x->j, &buf_len);
     371                 :          0 :         update_buflen(x->counter, &buf_len);
     372                 :          0 :         update_buflen(pub_key, &buf_len);
     373                 :          0 :         update_buflen(priv_key, &buf_len);
     374                 :            : 
     375         [ #  # ]:          0 :         if (ptype == 2)
     376                 :            :                 ktype = "DH Private-Key";
     377         [ #  # ]:          0 :         else if (ptype == 1)
     378                 :            :                 ktype = "DH Public-Key";
     379                 :            :         else
     380                 :          0 :                 ktype = "DH Parameters";
     381                 :            : 
     382                 :          0 :         m= OPENSSL_malloc(buf_len+10);
     383         [ #  # ]:          0 :         if (m == NULL)
     384                 :            :                 {
     385                 :            :                 reason=ERR_R_MALLOC_FAILURE;
     386                 :            :                 goto err;
     387                 :            :                 }
     388                 :            : 
     389                 :          0 :         BIO_indent(bp, indent, 128);
     390         [ #  # ]:          0 :         if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
     391                 :            :                 goto err;
     392                 :          0 :         indent += 4;
     393                 :            : 
     394         [ #  # ]:          0 :         if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
     395         [ #  # ]:          0 :         if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
     396                 :            : 
     397         [ #  # ]:          0 :         if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
     398         [ #  # ]:          0 :         if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
     399 [ #  # ][ #  # ]:          0 :         if (x->q && !ASN1_bn_print(bp,"subgroup order:",x->q,m,indent)) goto err;
     400 [ #  # ][ #  # ]:          0 :         if (x->j && !ASN1_bn_print(bp,"subgroup factor:",x->j,m,indent))
     401                 :            :                 goto err;
     402         [ #  # ]:          0 :         if (x->seed)
     403                 :            :                 {
     404                 :            :                 int i;
     405                 :          0 :                 BIO_indent(bp, indent, 128);
     406                 :          0 :                 BIO_puts(bp, "seed:");
     407         [ #  # ]:          0 :                 for (i=0; i < x->seedlen; i++)
     408                 :            :                         {
     409         [ #  # ]:          0 :                         if ((i%15) == 0)
     410                 :            :                                 {
     411         [ #  # ]:          0 :                                 if(BIO_puts(bp,"\n") <= 0
     412         [ #  # ]:          0 :                                    || !BIO_indent(bp,indent+4,128))
     413                 :            :                                     goto err;
     414                 :            :                                 }
     415 [ #  # ][ #  # ]:          0 :                         if (BIO_printf(bp,"%02x%s", x->seed[i],
     416                 :          0 :                                         ((i+1) == x->seedlen)?"":":") <= 0)
     417                 :            :                                 goto err;
     418                 :            :                         }
     419         [ #  # ]:          0 :                 if (BIO_write(bp,"\n",1) <= 0) return(0);
     420                 :            :                 }
     421 [ #  # ][ #  # ]:          0 :         if (x->counter && !ASN1_bn_print(bp,"counter:",x->counter,m,indent))
     422                 :            :                 goto err;
     423         [ #  # ]:          0 :         if (x->length != 0)
     424                 :            :                 {
     425                 :          0 :                 BIO_indent(bp, indent, 128);
     426         [ #  # ]:          0 :                 if (BIO_printf(bp,"recommended-private-length: %d bits\n",
     427                 :          0 :                         (int)x->length) <= 0) goto err;
     428                 :            :                 }
     429                 :            : 
     430                 :            : 
     431                 :            :         ret=1;
     432                 :            :         if (0)
     433                 :            :                 {
     434                 :            : err:
     435                 :          0 :                 DHerr(DH_F_DO_DH_PRINT,reason);
     436                 :            :                 }
     437         [ #  # ]:          0 :         if (m != NULL) OPENSSL_free(m);
     438                 :            :         return(ret);
     439                 :            :         }
     440                 :            : 
     441                 :          0 : static int int_dh_size(const EVP_PKEY *pkey)
     442                 :            :         {
     443                 :          0 :         return(DH_size(pkey->pkey.dh));
     444                 :            :         }
     445                 :            : 
     446                 :          0 : static int dh_bits(const EVP_PKEY *pkey)
     447                 :            :         {
     448                 :          0 :         return BN_num_bits(pkey->pkey.dh->p);
     449                 :            :         }
     450                 :            : 
     451                 :          0 : static int dh_security_bits(const EVP_PKEY *pkey)
     452                 :            :         {
     453                 :          0 :         return DH_security_bits(pkey->pkey.dh);
     454                 :            :         }
     455                 :            : 
     456                 :          2 : static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
     457                 :            :         {
     458   [ +  -  +  - ]:          4 :         if (    BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
     459                 :          2 :                 BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
     460                 :            :                 return 0;
     461         [ +  - ]:          2 :         else if (a->ameth == &dhx_asn1_meth)
     462                 :            :                 {
     463         [ +  - ]:          2 :                 if (BN_cmp(a->pkey.dh->q,b->pkey.dh->q))
     464                 :            :                         return 0;
     465                 :            :                 }
     466                 :            :         return 1;
     467                 :            :         }
     468                 :            : 
     469                 :       3756 : static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
     470                 :            :         {
     471                 :            :         BIGNUM *a;
     472         [ +  + ]:       3756 :         if (src)
     473                 :            :                 {
     474                 :       3754 :                 a = BN_dup(src);
     475         [ +  - ]:       3754 :                 if (!a)
     476                 :            :                         return 0;
     477                 :            :                 }
     478                 :            :         else 
     479                 :            :                 a = NULL;
     480         [ -  + ]:       3756 :         if (*dst)
     481                 :          0 :                 BN_free(*dst);
     482                 :       3756 :         *dst = a;
     483                 :       3756 :         return 1;
     484                 :            :         }
     485                 :            : 
     486                 :       1876 : static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
     487                 :            :         {
     488         [ +  + ]:       1876 :         if (is_x942 == -1)
     489                 :       1875 :                 is_x942 = !!from->q;
     490         [ +  - ]:       1876 :         if (!int_dh_bn_cpy(&to->p, from->p))
     491                 :            :                 return 0;
     492         [ +  - ]:       1876 :         if (!int_dh_bn_cpy(&to->g, from->g))
     493                 :            :                 return 0;
     494         [ +  + ]:       1876 :         if (is_x942)
     495                 :            :                 {
     496         [ +  - ]:          2 :                 if (!int_dh_bn_cpy(&to->q, from->q))
     497                 :            :                         return 0;
     498         [ +  - ]:          2 :                 if (!int_dh_bn_cpy(&to->j, from->j))
     499                 :            :                         return 0;
     500         [ -  + ]:          2 :                 if(to->seed)
     501                 :            :                         {
     502                 :          0 :                         OPENSSL_free(to->seed);
     503                 :          0 :                         to->seed = NULL;
     504                 :          0 :                         to->seedlen = 0;
     505                 :            :                         }
     506         [ -  + ]:          2 :                 if (from->seed)
     507                 :            :                         {
     508                 :          0 :                         to->seed = BUF_memdup(from->seed, from->seedlen);
     509         [ #  # ]:          0 :                         if (!to->seed)
     510                 :            :                                 return 0;
     511                 :          0 :                         to->seedlen = from->seedlen;
     512                 :            :                         }
     513                 :            :                 }
     514                 :            :         else
     515                 :       1874 :                 to->length = from->length;
     516                 :            :         return 1;
     517                 :            :         }
     518                 :            : 
     519                 :            : 
     520                 :       1875 : DH *DHparams_dup(DH *dh)
     521                 :            :         {
     522                 :            :         DH *ret;
     523                 :       1875 :         ret = DH_new();
     524         [ +  - ]:       1875 :         if (!ret)
     525                 :            :                 return NULL;
     526         [ -  + ]:       1875 :         if (!int_dh_param_copy(ret, dh, -1))
     527                 :            :                 {
     528                 :          0 :                 DH_free(ret);
     529                 :          0 :                 return NULL;
     530                 :            :                 }
     531                 :            :         return ret;
     532                 :            :         }
     533                 :            : 
     534                 :          1 : static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
     535                 :            :         {
     536                 :          1 :         return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
     537                 :          1 :                                  from->ameth == &dhx_asn1_meth);
     538                 :            :         }
     539                 :            : 
     540                 :          3 : static int dh_missing_parameters(const EVP_PKEY *a)
     541                 :            :         {
     542 [ +  - ][ +  - ]:          3 :         if (!a->pkey.dh->p || !a->pkey.dh->g)
     543                 :            :                 return 1;
     544                 :          3 :         return 0;
     545                 :            :         }
     546                 :            : 
     547                 :          0 : static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
     548                 :            :         {
     549         [ #  # ]:          0 :         if (dh_cmp_parameters(a, b) == 0)
     550                 :            :                 return 0;
     551         [ #  # ]:          0 :         if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
     552                 :            :                 return 0;
     553                 :            :         else
     554                 :          0 :                 return 1;
     555                 :            :         }
     556                 :            : 
     557                 :          0 : static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
     558                 :            :                                                         ASN1_PCTX *ctx)
     559                 :            :         {
     560                 :          0 :         return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
     561                 :            :         }
     562                 :            : 
     563                 :          0 : static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
     564                 :            :                                                         ASN1_PCTX *ctx)
     565                 :            :         {
     566                 :          0 :         return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
     567                 :            :         }
     568                 :            : 
     569                 :          0 : static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
     570                 :            :                                                         ASN1_PCTX *ctx)
     571                 :            :         {
     572                 :          0 :         return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
     573                 :            :         }
     574                 :            : 
     575                 :          0 : int DHparams_print(BIO *bp, const DH *x)
     576                 :            :         {
     577                 :          0 :         return do_dh_print(bp, x, 4, NULL, 0);
     578                 :            :         }
     579                 :            : 
     580                 :            : #ifndef OPENSSL_NO_CMS
     581                 :            : static int dh_cms_decrypt(CMS_RecipientInfo *ri);
     582                 :            : static int dh_cms_encrypt(CMS_RecipientInfo *ri);
     583                 :            : #endif
     584                 :            : 
     585                 :          4 : static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
     586                 :            :         {
     587      [ +  +  - ]:          4 :         switch (op)
     588                 :            :                 {
     589                 :            : #ifndef OPENSSL_NO_CMS
     590                 :            : 
     591                 :            :                 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
     592         [ +  + ]:          2 :                 if (arg1 == 1)
     593                 :          1 :                         return dh_cms_decrypt(arg2);
     594         [ +  - ]:          1 :                 else if (arg1 == 0)
     595                 :          1 :                         return dh_cms_encrypt(arg2);
     596                 :            :                 return -2;
     597                 :            : 
     598                 :            :                 case ASN1_PKEY_CTRL_CMS_RI_TYPE:
     599                 :          2 :                 *(int *)arg2 = CMS_RECIPINFO_AGREE;
     600                 :          2 :                 return 1;
     601                 :            : #endif
     602                 :            :                 default:
     603                 :            :                 return -2;
     604                 :            :                 }
     605                 :            : 
     606                 :            :         }
     607                 :            : 
     608                 :            : const EVP_PKEY_ASN1_METHOD dh_asn1_meth = 
     609                 :            :         {
     610                 :            :         EVP_PKEY_DH,
     611                 :            :         EVP_PKEY_DH,
     612                 :            :         0,
     613                 :            : 
     614                 :            :         "DH",
     615                 :            :         "OpenSSL PKCS#3 DH method",
     616                 :            : 
     617                 :            :         dh_pub_decode,
     618                 :            :         dh_pub_encode,
     619                 :            :         dh_pub_cmp,
     620                 :            :         dh_public_print,
     621                 :            : 
     622                 :            :         dh_priv_decode,
     623                 :            :         dh_priv_encode,
     624                 :            :         dh_private_print,
     625                 :            : 
     626                 :            :         int_dh_size,
     627                 :            :         dh_bits,
     628                 :            :         dh_security_bits,
     629                 :            : 
     630                 :            :         dh_param_decode,
     631                 :            :         dh_param_encode,
     632                 :            :         dh_missing_parameters,
     633                 :            :         dh_copy_parameters,
     634                 :            :         dh_cmp_parameters,
     635                 :            :         dh_param_print,
     636                 :            :         0,
     637                 :            : 
     638                 :            :         int_dh_free,
     639                 :            :         0
     640                 :            :         };
     641                 :            : 
     642                 :            : const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = 
     643                 :            :         {
     644                 :            :         EVP_PKEY_DHX,
     645                 :            :         EVP_PKEY_DHX,
     646                 :            :         0,
     647                 :            : 
     648                 :            :         "X9.42 DH",
     649                 :            :         "OpenSSL X9.42 DH method",
     650                 :            : 
     651                 :            :         dh_pub_decode,
     652                 :            :         dh_pub_encode,
     653                 :            :         dh_pub_cmp,
     654                 :            :         dh_public_print,
     655                 :            : 
     656                 :            :         dh_priv_decode,
     657                 :            :         dh_priv_encode,
     658                 :            :         dh_private_print,
     659                 :            : 
     660                 :            :         int_dh_size,
     661                 :            :         dh_bits,
     662                 :            :         dh_security_bits,
     663                 :            : 
     664                 :            :         dh_param_decode,
     665                 :            :         dh_param_encode,
     666                 :            :         dh_missing_parameters,
     667                 :            :         dh_copy_parameters,
     668                 :            :         dh_cmp_parameters,
     669                 :            :         dh_param_print,
     670                 :            :         0,
     671                 :            : 
     672                 :            :         int_dh_free,
     673                 :            :         dh_pkey_ctrl
     674                 :            :         };
     675                 :            : #ifndef OPENSSL_NO_CMS
     676                 :            : 
     677                 :          1 : static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
     678                 :            :                                 X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
     679                 :            :         {
     680                 :            :         ASN1_OBJECT *aoid;
     681                 :            :         int atype;
     682                 :            :         void *aval;
     683                 :          1 :         ASN1_INTEGER *public_key = NULL;
     684                 :          1 :         int rv = 0;
     685                 :          1 :         EVP_PKEY *pkpeer = NULL, *pk = NULL;
     686                 :          1 :         DH *dhpeer = NULL;
     687                 :            :         const unsigned char *p;
     688                 :            :         int plen;
     689                 :            : 
     690                 :          1 :         X509_ALGOR_get0(&aoid, &atype, &aval, alg);
     691         [ +  - ]:          1 :         if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
     692                 :            :                 goto err;
     693                 :            :         /* Only absent parameters allowed in RFC XXXX */
     694         [ +  - ]:          1 :         if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
     695                 :            :                 goto err;
     696                 :            : 
     697                 :          1 :         pk = EVP_PKEY_CTX_get0_pkey(pctx);
     698         [ +  - ]:          1 :         if (!pk)
     699                 :            :                 goto err;
     700         [ +  - ]:          1 :         if (pk->type != EVP_PKEY_DHX)
     701                 :            :                 goto err;
     702                 :            :         /* Get parameters from parent key */
     703                 :          1 :         dhpeer = DHparams_dup(pk->pkey.dh);
     704                 :            :         /* We have parameters now set public key */
     705                 :          1 :         plen = ASN1_STRING_length(pubkey);
     706                 :          1 :         p = ASN1_STRING_data(pubkey);
     707         [ +  - ]:          1 :         if (!p || !plen)
     708                 :            :                 goto err;
     709                 :            : 
     710         [ -  + ]:          1 :         if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, plen)))
     711                 :            :                 {
     712                 :          0 :                 DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
     713                 :          0 :                 goto err;
     714                 :            :                 }
     715                 :            : 
     716                 :            :         /* We have parameters now set public key */
     717         [ -  + ]:          1 :         if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
     718                 :            :                 {
     719                 :          0 :                 DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
     720                 :          0 :                 goto err;
     721                 :            :                 }
     722                 :            : 
     723                 :          1 :         pkpeer = EVP_PKEY_new();
     724         [ +  - ]:          1 :         if (!pkpeer)
     725                 :            :                 goto err;
     726                 :          1 :         EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
     727                 :          1 :         dhpeer = NULL;
     728         [ +  - ]:          1 :         if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
     729                 :          1 :                 rv = 1;
     730                 :            :         err:
     731         [ +  - ]:          1 :         if (public_key)
     732                 :          1 :                 ASN1_INTEGER_free(public_key);
     733         [ +  - ]:          1 :         if (pkpeer)
     734                 :          1 :                 EVP_PKEY_free(pkpeer);
     735         [ -  + ]:          1 :         if (dhpeer)
     736                 :          0 :                 DH_free(dhpeer);
     737                 :          1 :         return rv;
     738                 :            :         }
     739                 :            : 
     740                 :          1 : static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
     741                 :            :         {
     742                 :          1 :         int rv = 0;
     743                 :            : 
     744                 :          1 :         X509_ALGOR *alg, *kekalg = NULL;
     745                 :            :         ASN1_OCTET_STRING *ukm;
     746                 :            :         const unsigned char *p;
     747                 :          1 :         unsigned char *dukm = NULL;
     748                 :          1 :         size_t dukmlen = 0;
     749                 :            :         int keylen, plen;
     750                 :            :         const EVP_CIPHER *kekcipher;
     751                 :            :         EVP_CIPHER_CTX *kekctx;
     752                 :            : 
     753         [ +  - ]:          1 :         if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
     754                 :            :                 goto err;
     755                 :            : 
     756                 :            :         /* For DH we only have one OID permissible. If ever any more get
     757                 :            :          * defined we will need something cleverer.
     758                 :            :          */
     759         [ -  + ]:          1 :         if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH)
     760                 :            :                 {
     761                 :          0 :                 DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
     762                 :          0 :                 goto err;
     763                 :            :                 }
     764                 :            : 
     765         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
     766                 :            :                 goto err;
     767                 :            : 
     768         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
     769                 :            :                 goto err;
     770                 :            : 
     771         [ +  - ]:          1 :         if (alg->parameter->type != V_ASN1_SEQUENCE)
     772                 :            :                 goto err;
     773                 :            : 
     774                 :          1 :         p = alg->parameter->value.sequence->data;
     775                 :          1 :         plen = alg->parameter->value.sequence->length;
     776                 :          1 :         kekalg = d2i_X509_ALGOR(NULL, &p, plen);
     777         [ +  - ]:          1 :         if (!kekalg)
     778                 :            :                 goto err;
     779                 :          1 :         kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
     780         [ +  - ]:          1 :         if (!kekctx)
     781                 :            :                 goto err;
     782                 :          1 :         kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
     783 [ +  - ][ +  - ]:          1 :         if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
     784                 :            :                 goto err;
     785         [ +  - ]:          1 :         if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
     786                 :            :                 goto err;
     787         [ +  - ]:          1 :         if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
     788                 :            :                 goto err;
     789                 :            : 
     790                 :          1 :         keylen = EVP_CIPHER_CTX_key_length(kekctx);
     791         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
     792                 :            :                 goto err;
     793                 :            :         /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
     794         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
     795                 :            :                                 OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) <= 0)
     796                 :            :                 goto err;
     797                 :            : 
     798         [ -  + ]:          1 :         if (ukm)
     799                 :            :                 {
     800                 :          0 :                 dukmlen = ASN1_STRING_length(ukm);
     801                 :          0 :                 dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
     802         [ #  # ]:          0 :                 if (!dukm)
     803                 :            :                         goto err;
     804                 :            :                 }
     805                 :            : 
     806         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
     807                 :            :                 goto err;
     808                 :          1 :         dukm = NULL;
     809                 :            : 
     810                 :          1 :         rv = 1;
     811                 :            :         err:
     812         [ +  - ]:          1 :         if (kekalg)
     813                 :          1 :                 X509_ALGOR_free(kekalg);
     814         [ -  + ]:          1 :         if (dukm)
     815                 :          0 :                 OPENSSL_free(dukm);
     816                 :          1 :         return rv;
     817                 :            :         }
     818                 :            : 
     819                 :          1 : static int dh_cms_decrypt(CMS_RecipientInfo *ri)
     820                 :            :         {
     821                 :            :         EVP_PKEY_CTX *pctx;
     822                 :          1 :         pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     823         [ +  - ]:          1 :         if (!pctx)
     824                 :            :                 return 0;
     825                 :            :         /* See if we need to set peer key */
     826         [ +  - ]:          1 :         if (!EVP_PKEY_CTX_get0_peerkey(pctx))
     827                 :            :                 {
     828                 :            :                 X509_ALGOR *alg;
     829                 :            :                 ASN1_BIT_STRING *pubkey;
     830         [ +  - ]:          1 :                 if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
     831                 :            :                                                         NULL, NULL, NULL))
     832                 :          0 :                         return 0;
     833 [ +  - ][ +  - ]:          1 :                 if (!alg || !pubkey)
     834                 :            :                         return 0;
     835         [ -  + ]:          1 :                 if (!dh_cms_set_peerkey(pctx, alg, pubkey))
     836                 :            :                         {
     837                 :          1 :                         DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
     838                 :          0 :                         return 0;
     839                 :            :                         }
     840                 :            :                 }
     841                 :            :         /* Set DH derivation parameters and initialise unwrap context */
     842         [ -  + ]:          1 :         if (!dh_cms_set_shared_info(pctx, ri))
     843                 :            :                 {
     844                 :          0 :                 DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
     845                 :          0 :                 return 0;
     846                 :            :                 }
     847                 :            :         return 1;
     848                 :            :         }
     849                 :            : 
     850                 :          1 : static int dh_cms_encrypt(CMS_RecipientInfo *ri)
     851                 :            :         {
     852                 :            :         EVP_PKEY_CTX *pctx;
     853                 :            :         EVP_PKEY *pkey;
     854                 :            :         EVP_CIPHER_CTX *ctx;
     855                 :            :         int keylen;
     856                 :          1 :         X509_ALGOR *talg, *wrap_alg = NULL;
     857                 :            :         ASN1_OBJECT *aoid;
     858                 :            :         ASN1_BIT_STRING *pubkey;
     859                 :            :         ASN1_STRING *wrap_str;
     860                 :            :         ASN1_OCTET_STRING *ukm;
     861                 :          1 :         unsigned char *penc = NULL, *dukm = NULL;
     862                 :            :         int penclen;
     863                 :          1 :         size_t dukmlen = 0;
     864                 :          1 :         int rv = 0;
     865                 :            :         int kdf_type, wrap_nid;
     866                 :            :         const EVP_MD *kdf_md;
     867                 :          1 :         pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     868         [ +  - ]:          1 :         if (!pctx)
     869                 :            :                 return 0;
     870                 :            :         /* Get ephemeral key */
     871                 :          1 :         pkey = EVP_PKEY_CTX_get0_pkey(pctx);
     872         [ +  - ]:          1 :         if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
     873                 :            :                                                         NULL, NULL, NULL))
     874                 :            :                 goto err;
     875                 :          1 :         X509_ALGOR_get0(&aoid, NULL, NULL, talg);
     876                 :            :         /* Is everything uninitialised? */
     877         [ +  - ]:          1 :         if (aoid == OBJ_nid2obj(NID_undef))
     878                 :            :                 {
     879                 :            :                 ASN1_INTEGER *pubk;
     880                 :          1 :                 pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
     881         [ +  - ]:          1 :                 if (!pubk)
     882                 :            :                         goto err;
     883                 :            :                 /* Set the key */
     884                 :            : 
     885                 :          1 :                 penclen = i2d_ASN1_INTEGER(pubk, &penc);
     886                 :          1 :                 ASN1_INTEGER_free(pubk);
     887         [ +  - ]:          1 :                 if (penclen <= 0)
     888                 :            :                         goto err;
     889                 :          1 :                 ASN1_STRING_set0(pubkey, penc, penclen);
     890                 :          1 :                 pubkey->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
     891                 :          1 :                 pubkey->flags|=ASN1_STRING_FLAG_BITS_LEFT;
     892                 :            : 
     893                 :          1 :                 penc = NULL;
     894                 :          1 :                 X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
     895                 :            :                                                         V_ASN1_UNDEF, NULL);
     896                 :            :                 }
     897                 :            : 
     898                 :            :         /* See if custom paraneters set */
     899                 :          1 :         kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
     900         [ +  - ]:          1 :         if (kdf_type <= 0)
     901                 :            :                 goto err;
     902         [ +  - ]:          1 :         if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
     903                 :            :                 goto err;
     904                 :            : 
     905         [ +  - ]:          1 :         if (kdf_type == EVP_PKEY_DH_KDF_NONE)
     906                 :            :                 {
     907                 :          1 :                 kdf_type = EVP_PKEY_DH_KDF_X9_42;
     908         [ +  - ]:          1 :                 if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
     909                 :            :                         goto err;
     910                 :            :                 }
     911         [ #  # ]:          0 :         else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
     912                 :            :                 /* Unknown KDF */
     913                 :            :                 goto err;
     914         [ +  - ]:          1 :         if (kdf_md == NULL)
     915                 :            :                 {
     916                 :            :                 /* Only SHA1 supported */
     917                 :          1 :                 kdf_md = EVP_sha1();
     918         [ +  - ]:          1 :                 if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
     919                 :            :                         goto err;
     920                 :            :                 }
     921         [ #  # ]:          0 :         else if (EVP_MD_type(kdf_md) != NID_sha1)
     922                 :            :                 /* Unsupported digest */
     923                 :            :                 goto err;
     924                 :            : 
     925         [ +  - ]:          1 :         if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
     926                 :            :                 goto err;
     927                 :            : 
     928                 :            :         /* Get wrap NID */
     929                 :          1 :         ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
     930                 :          1 :         wrap_nid = EVP_CIPHER_CTX_type(ctx);
     931         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
     932                 :            :                 goto err;
     933                 :          1 :         keylen = EVP_CIPHER_CTX_key_length(ctx);
     934                 :            : 
     935                 :            :         /* Package wrap algorithm in an AlgorithmIdentifier */
     936                 :            : 
     937                 :          1 :         wrap_alg = X509_ALGOR_new();
     938         [ +  - ]:          1 :         if (!wrap_alg)
     939                 :            :                 goto err;
     940                 :          1 :         wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
     941                 :          1 :         wrap_alg->parameter = ASN1_TYPE_new();
     942         [ +  - ]:          1 :         if (!wrap_alg->parameter)
     943                 :            :                 goto err;
     944         [ +  - ]:          1 :         if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
     945                 :            :                 goto err;
     946         [ -  + ]:          1 :         if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef)
     947                 :            :                 {
     948                 :          0 :                 ASN1_TYPE_free(wrap_alg->parameter);
     949                 :          0 :                 wrap_alg->parameter = NULL;
     950                 :            :                 }
     951                 :            : 
     952         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
     953                 :            :                 goto err;
     954                 :            : 
     955         [ -  + ]:          1 :         if (ukm)
     956                 :            :                 {
     957                 :          0 :                 dukmlen = ASN1_STRING_length(ukm);
     958                 :          0 :                 dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
     959         [ #  # ]:          0 :                 if (!dukm)
     960                 :            :                         goto err;
     961                 :            :                 }
     962                 :            : 
     963         [ +  - ]:          1 :         if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
     964                 :            :                 goto err;
     965                 :          1 :         dukm = NULL;
     966                 :            : 
     967                 :            :         /* Now need to wrap encoding of wrap AlgorithmIdentifier into
     968                 :            :          * parameter of another AlgorithmIdentifier.
     969                 :            :          */
     970                 :          1 :         penc = NULL;
     971                 :          1 :         penclen = i2d_X509_ALGOR(wrap_alg, &penc);
     972 [ +  - ][ +  - ]:          1 :         if (!penc || !penclen)
     973                 :            :                 goto err;
     974                 :          1 :         wrap_str = ASN1_STRING_new();
     975         [ +  - ]:          1 :         if (!wrap_str)
     976                 :            :                 goto err;
     977                 :          1 :         ASN1_STRING_set0(wrap_str, penc, penclen);
     978                 :          1 :         penc = NULL;
     979                 :          1 :         X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
     980                 :            :                                                 V_ASN1_SEQUENCE, wrap_str);
     981                 :            : 
     982                 :          1 :         rv = 1;
     983                 :            : 
     984                 :            :         err:
     985         [ -  + ]:          1 :         if (penc)
     986                 :          0 :                 OPENSSL_free(penc);
     987         [ +  - ]:          1 :         if (wrap_alg)
     988                 :          1 :                 X509_ALGOR_free(wrap_alg);
     989                 :          1 :         return rv;
     990                 :            :         }
     991                 :            : 
     992                 :            : #endif
     993                 :            : 

Generated by: LCOV version 1.9