LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/hx509 - crypto.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 425 1291 32.9 %
Date: 2024-04-21 15:09:00 Functions: 40 84 47.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2004 - 2016 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "hx_locl.h"
      35             : 
      36             : /*-
      37             :  * RFC5758 specifies no parameters for ecdsa-with-SHA<N> signatures
      38             :  * RFC5754 specifies NULL parameters for sha<N>WithRSAEncryption signatures
      39             :  *
      40             :  * XXX: Make sure that the parameters are either NULL in both the tbs and the
      41             :  * signature, or absent from both the tbs and the signature.
      42             :  */
      43             : 
      44             : static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
      45             : 
      46             : static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
      47             : const AlgorithmIdentifier _hx509_signature_sha512_data = {
      48             :     { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
      49             : };
      50             : 
      51             : static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
      52             : const AlgorithmIdentifier _hx509_signature_sha384_data = {
      53             :     { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
      54             : };
      55             : 
      56             : static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
      57             : const AlgorithmIdentifier _hx509_signature_sha256_data = {
      58             :     { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
      59             : };
      60             : 
      61             : static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
      62             : const AlgorithmIdentifier _hx509_signature_sha1_data = {
      63             :     { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
      64             : };
      65             : 
      66             : static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
      67             : const AlgorithmIdentifier _hx509_signature_md5_data = {
      68             :     { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
      69             : };
      70             : 
      71             : static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
      72             : const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
      73             :     { 7, rk_UNCONST(rsa_with_sha512_oid) }, rk_UNCONST(&null_entry_oid)
      74             : };
      75             : 
      76             : static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
      77             : const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
      78             :     { 7, rk_UNCONST(rsa_with_sha384_oid) }, rk_UNCONST(&null_entry_oid)
      79             : };
      80             : 
      81             : static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
      82             : const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
      83             :     { 7, rk_UNCONST(rsa_with_sha256_oid) }, rk_UNCONST(&null_entry_oid)
      84             : };
      85             : 
      86             : static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
      87             : const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
      88             :     { 7, rk_UNCONST(rsa_with_sha1_oid) }, rk_UNCONST(&null_entry_oid)
      89             : };
      90             : 
      91             : static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
      92             : const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
      93             :     { 7, rk_UNCONST(rsa_with_md5_oid) }, rk_UNCONST(&null_entry_oid)
      94             : };
      95             : 
      96             : static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
      97             : const AlgorithmIdentifier _hx509_signature_rsa_data = {
      98             :     { 7, rk_UNCONST(rsa_oid) }, NULL
      99             : };
     100             : 
     101             : static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
     102             : const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
     103             :     { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
     104             : };
     105             : 
     106             : static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
     107             : const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
     108             :     { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
     109             : };
     110             : 
     111             : static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
     112             : const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
     113             :     { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
     114             : };
     115             : 
     116             : static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
     117             : const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
     118             :     { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
     119             : };
     120             : 
     121             : /*
     122             :  *
     123             :  */
     124             : 
     125             : static BIGNUM *
     126         148 : heim_int2BN(const heim_integer *i)
     127             : {
     128          16 :     BIGNUM *bn;
     129             : 
     130         148 :     bn = BN_bin2bn(i->data, i->length, NULL);
     131         148 :     BN_set_negative(bn, i->negative);
     132         148 :     return bn;
     133             : }
     134             : 
     135             : /*
     136             :  *
     137             :  */
     138             : 
     139             : HX509_LIB_FUNCTION int HX509_LIB_CALL
     140         130 : _hx509_set_digest_alg(DigestAlgorithmIdentifier *id,
     141             :                       const heim_oid *oid,
     142             :                       const void *param, size_t length)
     143             : {
     144           0 :     int ret;
     145         130 :     if (param) {
     146         130 :         id->parameters = malloc(sizeof(*id->parameters));
     147         130 :         if (id->parameters == NULL)
     148           0 :             return ENOMEM;
     149         130 :         id->parameters->data = malloc(length);
     150         130 :         if (id->parameters->data == NULL) {
     151           0 :             free(id->parameters);
     152           0 :             id->parameters = NULL;
     153           0 :             return ENOMEM;
     154             :         }
     155         130 :         memcpy(id->parameters->data, param, length);
     156         130 :         id->parameters->length = length;
     157             :     } else
     158           0 :         id->parameters = NULL;
     159         130 :     ret = der_copy_oid(oid, &id->algorithm);
     160         130 :     if (ret) {
     161           0 :         if (id->parameters) {
     162           0 :             free(id->parameters->data);
     163           0 :             free(id->parameters);
     164           0 :             id->parameters = NULL;
     165             :         }
     166           0 :         return ret;
     167             :     }
     168         130 :     return 0;
     169             : }
     170             : 
     171             : /*
     172             :  *
     173             :  */
     174             : 
     175             : static int
     176         225 : rsa_verify_signature(hx509_context context,
     177             :                      const struct signature_alg *sig_alg,
     178             :                      const Certificate *signer,
     179             :                      const AlgorithmIdentifier *alg,
     180             :                      const heim_octet_string *data,
     181             :                      const heim_octet_string *sig)
     182             : {
     183           0 :     const SubjectPublicKeyInfo *spi;
     184           0 :     DigestInfo di;
     185           0 :     unsigned char *to;
     186           0 :     int tosize, retsize;
     187           0 :     int ret;
     188           0 :     RSA *rsa;
     189           0 :     size_t size;
     190           0 :     const unsigned char *p;
     191             : 
     192         225 :     memset(&di, 0, sizeof(di));
     193             : 
     194         225 :     spi = &signer->tbsCertificate.subjectPublicKeyInfo;
     195             : 
     196         225 :     p = spi->subjectPublicKey.data;
     197         225 :     size = spi->subjectPublicKey.length / 8;
     198             : 
     199         225 :     rsa = d2i_RSAPublicKey(NULL, &p, size);
     200         225 :     if (rsa == NULL) {
     201           0 :         ret = ENOMEM;
     202           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     203           0 :         goto out;
     204             :     }
     205             : 
     206         225 :     tosize = RSA_size(rsa);
     207         225 :     to = malloc(tosize);
     208         225 :     if (to == NULL) {
     209           0 :         ret = ENOMEM;
     210           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     211           0 :         goto out;
     212             :     }
     213             : 
     214         225 :     retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
     215             :                                  to, rsa, RSA_PKCS1_PADDING);
     216         225 :     if (retsize <= 0) {
     217           0 :         ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
     218           0 :         hx509_set_error_string(context, 0, ret,
     219             :                                "RSA public decrypt failed: %d", retsize);
     220           0 :         free(to);
     221           0 :         goto out;
     222             :     }
     223         225 :     if (retsize > tosize)
     224           0 :         _hx509_abort("internal rsa decryption failure: ret > tosize");
     225             : 
     226         225 :     if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
     227             : 
     228         225 :         ret = decode_DigestInfo(to, retsize, &di, &size);
     229         225 :         free(to);
     230         225 :         if (ret) {
     231           0 :             goto out;
     232             :         }
     233             : 
     234             :         /* Check for extra data inside the sigature */
     235         225 :         if (size != (size_t)retsize) {
     236           0 :             ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
     237           0 :             hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
     238           0 :             goto out;
     239             :         }
     240             : 
     241         450 :         if (sig_alg->digest_alg &&
     242         225 :             der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
     243         225 :                              &sig_alg->digest_alg->algorithm) != 0)
     244             :         {
     245           0 :             ret = HX509_CRYPTO_OID_MISMATCH;
     246           0 :             hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
     247           0 :             goto out;
     248             :         }
     249             : 
     250             :         /* verify that the parameters are NULL or the NULL-type */
     251         225 :         if (di.digestAlgorithm.parameters != NULL &&
     252         225 :             (di.digestAlgorithm.parameters->length != 2 ||
     253         225 :              memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
     254             :         {
     255           0 :             ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
     256           0 :             hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
     257           0 :             goto out;
     258             :         }
     259             : 
     260         225 :         ret = _hx509_verify_signature(context,
     261             :                                       NULL,
     262             :                                       &di.digestAlgorithm,
     263             :                                       data,
     264             :                                       &di.digest);
     265         225 :         if (ret)
     266           0 :             goto out;
     267             : 
     268             :     } else {
     269           0 :         if ((size_t)retsize != data->length ||
     270           0 :             ct_memcmp(to, data->data, retsize) != 0)
     271             :         {
     272           0 :             ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
     273           0 :             hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
     274           0 :             goto out;
     275             :         }
     276           0 :         free(to);
     277           0 :         ret = 0;
     278             :     }
     279             : 
     280         225 :  out:
     281         225 :     free_DigestInfo(&di);
     282         225 :     if (rsa)
     283         225 :         RSA_free(rsa);
     284         225 :     return ret;
     285             : }
     286             : 
     287             : static int
     288          65 : rsa_create_signature(hx509_context context,
     289             :                      const struct signature_alg *sig_alg,
     290             :                      const hx509_private_key signer,
     291             :                      const AlgorithmIdentifier *alg,
     292             :                      const heim_octet_string *data,
     293             :                      AlgorithmIdentifier *signatureAlgorithm,
     294             :                      heim_octet_string *sig)
     295             : {
     296           0 :     const AlgorithmIdentifier *digest_alg;
     297           0 :     heim_octet_string indata;
     298           0 :     const heim_oid *sig_oid;
     299           0 :     size_t size;
     300           0 :     int ret;
     301             : 
     302          65 :     if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0)
     303           0 :         return HX509_ALG_NOT_SUPP;
     304             : 
     305          65 :     if (alg)
     306          65 :         sig_oid = &alg->algorithm;
     307             :     else
     308           0 :         sig_oid = signer->signature_alg;
     309             : 
     310          65 :     if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
     311          37 :         digest_alg = hx509_signature_sha512();
     312          28 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
     313           0 :         digest_alg = hx509_signature_sha384();
     314          28 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
     315          24 :         digest_alg = hx509_signature_sha256();
     316           4 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
     317           4 :         digest_alg = hx509_signature_sha1();
     318           0 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
     319           0 :         digest_alg = hx509_signature_md5();
     320           0 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
     321           0 :         digest_alg = hx509_signature_md5();
     322           0 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) {
     323           0 :         digest_alg = hx509_signature_sha1();
     324           0 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
     325           0 :         digest_alg = hx509_signature_sha1();
     326           0 :     } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) {
     327           0 :         digest_alg = NULL;
     328             :     } else
     329           0 :         return HX509_ALG_NOT_SUPP;
     330             : 
     331          65 :     if (signatureAlgorithm) {
     332          65 :         ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid,
     333             :                                     "\x05\x00", 2);
     334          65 :         if (ret) {
     335           0 :             hx509_clear_error_string(context);
     336           0 :             return ret;
     337             :         }
     338             :     }
     339             : 
     340          65 :     if (digest_alg) {
     341           0 :         DigestInfo di;
     342          65 :         memset(&di, 0, sizeof(di));
     343             : 
     344          65 :         ret = _hx509_create_signature(context,
     345             :                                       NULL,
     346             :                                       digest_alg,
     347             :                                       data,
     348             :                                       &di.digestAlgorithm,
     349             :                                       &di.digest);
     350          65 :         if (ret)
     351           0 :             return ret;
     352          65 :         ASN1_MALLOC_ENCODE(DigestInfo,
     353             :                            indata.data,
     354             :                            indata.length,
     355             :                            &di,
     356             :                            &size,
     357             :                            ret);
     358          65 :         free_DigestInfo(&di);
     359          65 :         if (ret) {
     360           0 :             hx509_set_error_string(context, 0, ret, "out of memory");
     361           0 :             return ret;
     362             :         }
     363          65 :         if (indata.length != size)
     364           0 :             _hx509_abort("internal ASN.1 encoder error");
     365             :     } else {
     366           0 :         indata = *data;
     367             :     }
     368             : 
     369          65 :     sig->length = RSA_size(signer->private_key.rsa);
     370          65 :     sig->data = malloc(sig->length);
     371          65 :     if (sig->data == NULL) {
     372           0 :         der_free_octet_string(&indata);
     373           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
     374           0 :         return ENOMEM;
     375             :     }
     376             : 
     377          65 :     ret = RSA_private_encrypt(indata.length, indata.data,
     378          65 :                               sig->data,
     379             :                               signer->private_key.rsa,
     380             :                               RSA_PKCS1_PADDING);
     381          65 :     if (indata.data != data->data)
     382          65 :         der_free_octet_string(&indata);
     383          65 :     if (ret <= 0) {
     384           0 :         ret = HX509_CMS_FAILED_CREATE_SIGATURE;
     385           0 :         hx509_set_error_string(context, 0, ret,
     386             :                                "RSA private encrypt failed: %d", ret);
     387           0 :         return ret;
     388             :     }
     389          65 :     if (sig->length > (size_t)ret) {
     390           0 :         size = sig->length - ret;
     391           0 :         memmove((uint8_t *)sig->data + size, sig->data, ret);
     392           0 :         memset(sig->data, 0, size);
     393          65 :     } else if (sig->length < (size_t)ret)
     394           0 :         _hx509_abort("RSA signature prelen longer than output len");
     395             : 
     396          65 :     return 0;
     397             : }
     398             : 
     399             : static int
     400          74 : rsa_private_key_import(hx509_context context,
     401             :                        const AlgorithmIdentifier *keyai,
     402             :                        const void *data,
     403             :                        size_t len,
     404             :                        hx509_key_format_t format,
     405             :                        hx509_private_key private_key)
     406             : {
     407          74 :     switch (format) {
     408          74 :     case HX509_KEY_FORMAT_DER: {
     409          74 :         const unsigned char *p = data;
     410             : 
     411          82 :         private_key->private_key.rsa =
     412          74 :             d2i_RSAPrivateKey(NULL, &p, len);
     413          74 :         if (private_key->private_key.rsa == NULL) {
     414           0 :             hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
     415             :                                    "Failed to parse RSA key");
     416           0 :             return HX509_PARSING_KEY_FAILED;
     417             :         }
     418          74 :         private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
     419          74 :         break;
     420             : 
     421             :     }
     422           0 :     default:
     423           0 :         return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
     424             :     }
     425             : 
     426          74 :     return 0;
     427             : }
     428             : 
     429             : static int
     430           0 : rsa_private_key2SPKI(hx509_context context,
     431             :                      hx509_private_key private_key,
     432             :                      SubjectPublicKeyInfo *spki)
     433             : {
     434           0 :     int len, ret;
     435             : 
     436           0 :     memset(spki, 0, sizeof(*spki));
     437             : 
     438           0 :     len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
     439           0 :     if (len < 0)
     440           0 :         return -1;
     441             : 
     442           0 :     spki->subjectPublicKey.data = malloc(len);
     443           0 :     if (spki->subjectPublicKey.data == NULL) {
     444           0 :         hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
     445           0 :         return ENOMEM;
     446             :     }
     447           0 :     spki->subjectPublicKey.length = len * 8;
     448             : 
     449           0 :     ret = _hx509_set_digest_alg(&spki->algorithm,
     450             :                                 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     451             :                                 "\x05\x00", 2);
     452           0 :     if (ret) {
     453           0 :         hx509_set_error_string(context, 0, ret, "malloc - out of memory");
     454           0 :         free(spki->subjectPublicKey.data);
     455           0 :         spki->subjectPublicKey.data = NULL;
     456           0 :         spki->subjectPublicKey.length = 0;
     457           0 :         return ret;
     458             :     }
     459             : 
     460             :     {
     461           0 :         unsigned char *pp = spki->subjectPublicKey.data;
     462           0 :         i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
     463             :     }
     464             : 
     465           0 :     return 0;
     466             : }
     467             : 
     468             : static int
     469           0 : rsa_generate_private_key(hx509_context context,
     470             :                          struct hx509_generate_private_context *ctx,
     471             :                          hx509_private_key private_key)
     472             : {
     473           0 :     BIGNUM *e;
     474           0 :     int ret;
     475           0 :     unsigned long bits;
     476             : 
     477           0 :     static const int default_rsa_e = 65537;
     478           0 :     static const int default_rsa_bits = 2048;
     479             : 
     480           0 :     private_key->private_key.rsa = RSA_new();
     481           0 :     if (private_key->private_key.rsa == NULL) {
     482           0 :         hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
     483             :                                "Failed to generate RSA key");
     484           0 :         return HX509_PARSING_KEY_FAILED;
     485             :     }
     486             : 
     487           0 :     e = BN_new();
     488           0 :     BN_set_word(e, default_rsa_e);
     489             : 
     490           0 :     bits = default_rsa_bits;
     491             : 
     492           0 :     if (ctx->num_bits)
     493           0 :         bits = ctx->num_bits;
     494             : 
     495           0 :     ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
     496           0 :     BN_free(e);
     497           0 :     if (ret != 1) {
     498           0 :         hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
     499             :                                "Failed to generate RSA key");
     500           0 :         return HX509_PARSING_KEY_FAILED;
     501             :     }
     502           0 :     private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
     503             : 
     504           0 :     return 0;
     505             : }
     506             : 
     507             : static int
     508           0 : rsa_private_key_export(hx509_context context,
     509             :                        const hx509_private_key key,
     510             :                        hx509_key_format_t format,
     511             :                        heim_octet_string *data)
     512             : {
     513           0 :     int ret;
     514             : 
     515           0 :     data->data = NULL;
     516           0 :     data->length = 0;
     517             : 
     518           0 :     switch (format) {
     519           0 :     case HX509_KEY_FORMAT_DER:
     520             : 
     521           0 :         ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
     522           0 :         if (ret <= 0) {
     523           0 :             ret = EINVAL;
     524           0 :             hx509_set_error_string(context, 0, ret,
     525             :                                "Private key is not exportable");
     526           0 :             return ret;
     527             :         }
     528             : 
     529           0 :         data->data = malloc(ret);
     530           0 :         if (data->data == NULL) {
     531           0 :             ret = ENOMEM;
     532           0 :             hx509_set_error_string(context, 0, ret, "malloc out of memory");
     533           0 :             return ret;
     534             :         }
     535           0 :         data->length = ret;
     536             : 
     537             :         {
     538           0 :             unsigned char *p = data->data;
     539           0 :             i2d_RSAPrivateKey(key->private_key.rsa, &p);
     540             :         }
     541           0 :         break;
     542           0 :     default:
     543           0 :         return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
     544             :     }
     545             : 
     546           0 :     return 0;
     547             : }
     548             : 
     549             : static BIGNUM *
     550           0 : rsa_get_internal(hx509_context context,
     551             :                  hx509_private_key key,
     552             :                  const char *type)
     553             : {
     554           0 :     if (strcasecmp(type, "rsa-modulus") == 0) {
     555           0 :         return BN_dup(key->private_key.rsa->n);
     556           0 :     } else if (strcasecmp(type, "rsa-exponent") == 0) {
     557           0 :         return BN_dup(key->private_key.rsa->e);
     558             :     } else
     559           0 :         return NULL;
     560             : }
     561             : 
     562             : 
     563             : 
     564             : static hx509_private_key_ops rsa_private_key_ops = {
     565             :     "RSA PRIVATE KEY",
     566             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     567             :     NULL,
     568             :     rsa_private_key2SPKI,
     569             :     rsa_private_key_export,
     570             :     rsa_private_key_import,
     571             :     rsa_generate_private_key,
     572             :     rsa_get_internal
     573             : };
     574             : 
     575             : /*
     576             :  *
     577             :  */
     578             : 
     579             : static int
     580           0 : dsa_verify_signature(hx509_context context,
     581             :                      const struct signature_alg *sig_alg,
     582             :                      const Certificate *signer,
     583             :                      const AlgorithmIdentifier *alg,
     584             :                      const heim_octet_string *data,
     585             :                      const heim_octet_string *sig)
     586             : {
     587           0 :     const SubjectPublicKeyInfo *spi;
     588           0 :     DSAPublicKey pk;
     589           0 :     DSAParams param;
     590           0 :     size_t size;
     591           0 :     DSA *dsa;
     592           0 :     int ret;
     593             : 
     594           0 :     spi = &signer->tbsCertificate.subjectPublicKeyInfo;
     595             : 
     596           0 :     dsa = DSA_new();
     597           0 :     if (dsa == NULL) {
     598           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
     599           0 :         return ENOMEM;
     600             :     }
     601             : 
     602           0 :     ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
     603           0 :                               spi->subjectPublicKey.length / 8,
     604             :                               &pk, &size);
     605           0 :     if (ret)
     606           0 :         goto out;
     607             : 
     608           0 :     dsa->pub_key = heim_int2BN(&pk);
     609             : 
     610           0 :     free_DSAPublicKey(&pk);
     611             : 
     612           0 :     if (dsa->pub_key == NULL) {
     613           0 :         ret = ENOMEM;
     614           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     615           0 :         goto out;
     616             :     }
     617             : 
     618           0 :     if (spi->algorithm.parameters == NULL) {
     619           0 :         ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
     620           0 :         hx509_set_error_string(context, 0, ret, "DSA parameters missing");
     621           0 :         goto out;
     622             :     }
     623             : 
     624           0 :     ret = decode_DSAParams(spi->algorithm.parameters->data,
     625           0 :                            spi->algorithm.parameters->length,
     626             :                            &param,
     627             :                            &size);
     628           0 :     if (ret) {
     629           0 :         hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
     630           0 :         goto out;
     631             :     }
     632             : 
     633           0 :     dsa->p = heim_int2BN(&param.p);
     634           0 :     dsa->q = heim_int2BN(&param.q);
     635           0 :     dsa->g = heim_int2BN(&param.g);
     636             : 
     637           0 :     free_DSAParams(&param);
     638             : 
     639           0 :     if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
     640           0 :         ret = ENOMEM;
     641           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     642           0 :         goto out;
     643             :     }
     644             : 
     645           0 :     ret = DSA_verify(-1, data->data, data->length,
     646           0 :                      (unsigned char*)sig->data, sig->length,
     647             :                      dsa);
     648           0 :     if (ret == 1)
     649           0 :         ret = 0;
     650           0 :     else if (ret == 0 || ret == -1) {
     651           0 :         ret = HX509_CRYPTO_BAD_SIGNATURE;
     652           0 :         hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
     653             :     } else {
     654           0 :         ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
     655           0 :         hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
     656             :     }
     657             : 
     658           0 :  out:
     659           0 :     DSA_free(dsa);
     660             : 
     661           0 :     return ret;
     662             : }
     663             : 
     664             : #if 0
     665             : static int
     666             : dsa_parse_private_key(hx509_context context,
     667             :                       const void *data,
     668             :                       size_t len,
     669             :                       hx509_private_key private_key)
     670             : {
     671             :     const unsigned char *p = data;
     672             : 
     673             :     private_key->private_key.dsa =
     674             :         d2i_DSAPrivateKey(NULL, &p, len);
     675             :     if (private_key->private_key.dsa == NULL)
     676             :         return EINVAL;
     677             :     private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1;
     678             : 
     679             :     return 0;
     680             : /* else */
     681             :     hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
     682             :                            "No support to parse DSA keys");
     683             :     return HX509_PARSING_KEY_FAILED;
     684             : }
     685             : #endif
     686             : 
     687             : static int
     688         126 : evp_md_create_signature(hx509_context context,
     689             :                         const struct signature_alg *sig_alg,
     690             :                         const hx509_private_key signer,
     691             :                         const AlgorithmIdentifier *alg,
     692             :                         const heim_octet_string *data,
     693             :                         AlgorithmIdentifier *signatureAlgorithm,
     694             :                         heim_octet_string *sig)
     695             : {
     696         126 :     size_t sigsize = EVP_MD_size(sig_alg->evp_md());
     697           0 :     EVP_MD_CTX *ctx;
     698             : 
     699         126 :     memset(sig, 0, sizeof(*sig));
     700             : 
     701         126 :     if (signatureAlgorithm) {
     702           0 :         int ret;
     703          65 :         ret = _hx509_set_digest_alg(signatureAlgorithm,
     704          65 :                                     sig_alg->sig_oid, "\x05\x00", 2);
     705          65 :         if (ret)
     706           0 :             return ret;
     707             :     }
     708             : 
     709             : 
     710         126 :     sig->data = malloc(sigsize);
     711         126 :     if (sig->data == NULL) {
     712           0 :         sig->length = 0;
     713           0 :         return ENOMEM;
     714             :     }
     715         126 :     sig->length = sigsize;
     716             : 
     717         126 :     ctx = EVP_MD_CTX_create();
     718         126 :     EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
     719         126 :     EVP_DigestUpdate(ctx, data->data, data->length);
     720         126 :     EVP_DigestFinal_ex(ctx, sig->data, NULL);
     721         126 :     EVP_MD_CTX_destroy(ctx);
     722             : 
     723             : 
     724         126 :     return 0;
     725             : }
     726             : 
     727             : static int
     728         253 : evp_md_verify_signature(hx509_context context,
     729             :                         const struct signature_alg *sig_alg,
     730             :                         const Certificate *signer,
     731             :                         const AlgorithmIdentifier *alg,
     732             :                         const heim_octet_string *data,
     733             :                         const heim_octet_string *sig)
     734             : {
     735           0 :     unsigned char digest[EVP_MAX_MD_SIZE];
     736           0 :     EVP_MD_CTX *ctx;
     737         253 :     size_t sigsize = EVP_MD_size(sig_alg->evp_md());
     738             : 
     739         253 :     if (sig->length != sigsize || sigsize > sizeof(digest)) {
     740           0 :         hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
     741             :                                "SHA256 sigature has wrong length");
     742           0 :         return HX509_CRYPTO_SIG_INVALID_FORMAT;
     743             :     }
     744             : 
     745         253 :     ctx = EVP_MD_CTX_create();
     746         253 :     EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
     747         253 :     EVP_DigestUpdate(ctx, data->data, data->length);
     748         253 :     EVP_DigestFinal_ex(ctx, digest, NULL);
     749         253 :     EVP_MD_CTX_destroy(ctx);
     750             : 
     751         253 :     if (ct_memcmp(digest, sig->data, sigsize) != 0) {
     752           0 :         hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
     753           0 :                                "Bad %s sigature", sig_alg->name);
     754           0 :         return HX509_CRYPTO_BAD_SIGNATURE;
     755             :     }
     756             : 
     757         253 :     return 0;
     758             : }
     759             : 
     760             : #ifdef HAVE_HCRYPTO_W_OPENSSL
     761             : extern const struct signature_alg ecdsa_with_sha512_alg;
     762             : extern const struct signature_alg ecdsa_with_sha384_alg;
     763             : extern const struct signature_alg ecdsa_with_sha256_alg;
     764             : extern const struct signature_alg ecdsa_with_sha1_alg;
     765             : #endif
     766             : 
     767             : static const struct signature_alg heim_rsa_pkcs1_x509 = {
     768             :     "rsa-pkcs1-x509",
     769             :     ASN1_OID_ID_HEIM_RSA_PKCS1_X509,
     770             :     &_hx509_signature_rsa_pkcs1_x509_data,
     771             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     772             :     NULL,
     773             :     PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
     774             :     0,
     775             :     NULL,
     776             :     rsa_verify_signature,
     777             :     rsa_create_signature,
     778             :     0
     779             : };
     780             : 
     781             : static const struct signature_alg pkcs1_rsa_sha1_alg = {
     782             :     "rsa",
     783             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     784             :     &_hx509_signature_rsa_with_sha1_data,
     785             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     786             :     NULL,
     787             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
     788             :     0,
     789             :     NULL,
     790             :     rsa_verify_signature,
     791             :     rsa_create_signature,
     792             :     0
     793             : };
     794             : 
     795             : static const struct signature_alg rsa_with_sha512_alg = {
     796             :     "rsa-with-sha512",
     797             :     ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION,
     798             :     &_hx509_signature_rsa_with_sha512_data,
     799             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     800             :     &_hx509_signature_sha512_data,
     801             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
     802             :     0,
     803             :     NULL,
     804             :     rsa_verify_signature,
     805             :     rsa_create_signature,
     806             :     0
     807             : };
     808             : 
     809             : static const struct signature_alg rsa_with_sha384_alg = {
     810             :     "rsa-with-sha384",
     811             :     ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION,
     812             :     &_hx509_signature_rsa_with_sha384_data,
     813             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     814             :     &_hx509_signature_sha384_data,
     815             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
     816             :     0,
     817             :     NULL,
     818             :     rsa_verify_signature,
     819             :     rsa_create_signature,
     820             :     0
     821             : };
     822             : 
     823             : static const struct signature_alg rsa_with_sha256_alg = {
     824             :     "rsa-with-sha256",
     825             :     ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
     826             :     &_hx509_signature_rsa_with_sha256_data,
     827             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     828             :     &_hx509_signature_sha256_data,
     829             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
     830             :     0,
     831             :     NULL,
     832             :     rsa_verify_signature,
     833             :     rsa_create_signature,
     834             :     0
     835             : };
     836             : 
     837             : static const struct signature_alg rsa_with_sha1_alg = {
     838             :     "rsa-with-sha1",
     839             :     ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION,
     840             :     &_hx509_signature_rsa_with_sha1_data,
     841             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     842             :     &_hx509_signature_sha1_data,
     843             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
     844             :     0,
     845             :     NULL,
     846             :     rsa_verify_signature,
     847             :     rsa_create_signature,
     848             :     0
     849             : };
     850             : 
     851             : static const struct signature_alg rsa_with_sha1_alg_secsig = {
     852             :     "rsa-with-sha1",
     853             :     ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION,
     854             :     &_hx509_signature_rsa_with_sha1_data,
     855             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     856             :     &_hx509_signature_sha1_data,
     857             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
     858             :     0,
     859             :     NULL,
     860             :     rsa_verify_signature,
     861             :     rsa_create_signature,
     862             :     0
     863             : };
     864             : 
     865             : static const struct signature_alg rsa_with_md5_alg = {
     866             :     "rsa-with-md5",
     867             :     ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION,
     868             :     &_hx509_signature_rsa_with_md5_data,
     869             :     ASN1_OID_ID_PKCS1_RSAENCRYPTION,
     870             :     &_hx509_signature_md5_data,
     871             :     PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|WEAK_SIG_ALG,
     872             :     1230739889,
     873             :     NULL,
     874             :     rsa_verify_signature,
     875             :     rsa_create_signature,
     876             :     0
     877             : };
     878             : 
     879             : static const struct signature_alg dsa_sha1_alg = {
     880             :     "dsa-with-sha1",
     881             :     ASN1_OID_ID_DSA_WITH_SHA1,
     882             :     NULL,
     883             :     ASN1_OID_ID_DSA,
     884             :     &_hx509_signature_sha1_data,
     885             :     PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
     886             :     0,
     887             :     NULL,
     888             :     dsa_verify_signature,
     889             :     /* create_signature */ NULL,
     890             :     0
     891             : };
     892             : 
     893             : static const struct signature_alg sha512_alg = {
     894             :     "sha-512",
     895             :     ASN1_OID_ID_SHA512,
     896             :     &_hx509_signature_sha512_data,
     897             :     NULL,
     898             :     NULL,
     899             :     SIG_DIGEST,
     900             :     0,
     901             :     EVP_sha512,
     902             :     evp_md_verify_signature,
     903             :     evp_md_create_signature,
     904             :     0
     905             : };
     906             : 
     907             : static const struct signature_alg sha384_alg = {
     908             :     "sha-384",
     909             :     ASN1_OID_ID_SHA384,
     910             :     &_hx509_signature_sha384_data,
     911             :     NULL,
     912             :     NULL,
     913             :     SIG_DIGEST,
     914             :     0,
     915             :     EVP_sha384,
     916             :     evp_md_verify_signature,
     917             :     evp_md_create_signature,
     918             :     0
     919             : };
     920             : 
     921             : static const struct signature_alg sha256_alg = {
     922             :     "sha-256",
     923             :     ASN1_OID_ID_SHA256,
     924             :     &_hx509_signature_sha256_data,
     925             :     NULL,
     926             :     NULL,
     927             :     SIG_DIGEST,
     928             :     0,
     929             :     EVP_sha256,
     930             :     evp_md_verify_signature,
     931             :     evp_md_create_signature,
     932             :     0
     933             : };
     934             : 
     935             : static const struct signature_alg sha1_alg = {
     936             :     "sha1",
     937             :     ASN1_OID_ID_SECSIG_SHA_1,
     938             :     &_hx509_signature_sha1_data,
     939             :     NULL,
     940             :     NULL,
     941             :     SIG_DIGEST,
     942             :     0,
     943             :     EVP_sha1,
     944             :     evp_md_verify_signature,
     945             :     evp_md_create_signature,
     946             :     0
     947             : };
     948             : 
     949             : static const struct signature_alg md5_alg = {
     950             :     "rsa-md5",
     951             :     ASN1_OID_ID_RSA_DIGEST_MD5,
     952             :     &_hx509_signature_md5_data,
     953             :     NULL,
     954             :     NULL,
     955             :     SIG_DIGEST|WEAK_SIG_ALG,
     956             :     0,
     957             :     EVP_md5,
     958             :     evp_md_verify_signature,
     959             :     NULL,
     960             :     0
     961             : };
     962             : 
     963             : /*
     964             :  * Order matter in this structure, "best" first for each "key
     965             :  * compatible" type (type is ECDSA, RSA, DSA, none, etc)
     966             :  */
     967             : 
     968             : static const struct signature_alg *sig_algs[] = {
     969             : #ifdef HAVE_HCRYPTO_W_OPENSSL
     970             :     &ecdsa_with_sha512_alg,
     971             :     &ecdsa_with_sha384_alg,
     972             :     &ecdsa_with_sha256_alg,
     973             :     &ecdsa_with_sha1_alg,
     974             : #endif
     975             :     &rsa_with_sha512_alg,
     976             :     &rsa_with_sha384_alg,
     977             :     &rsa_with_sha256_alg,
     978             :     &rsa_with_sha1_alg,
     979             :     &rsa_with_sha1_alg_secsig,
     980             :     &pkcs1_rsa_sha1_alg,
     981             :     &rsa_with_md5_alg,
     982             :     &heim_rsa_pkcs1_x509,
     983             :     &dsa_sha1_alg,
     984             :     &sha512_alg,
     985             :     &sha384_alg,
     986             :     &sha256_alg,
     987             :     &sha1_alg,
     988             :     &md5_alg,
     989             :     NULL
     990             : };
     991             : 
     992             : const struct signature_alg *
     993         989 : _hx509_find_sig_alg(const heim_oid *oid)
     994             : {
     995           0 :     unsigned int i;
     996        6148 :     for (i = 0; sig_algs[i]; i++)
     997        6148 :         if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
     998         989 :             return sig_algs[i];
     999           0 :     return NULL;
    1000             : }
    1001             : 
    1002             : static const AlgorithmIdentifier *
    1003         130 : alg_for_privatekey(const hx509_private_key pk, int type)
    1004             : {
    1005           0 :     const heim_oid *keytype;
    1006           0 :     unsigned int i;
    1007             : 
    1008         130 :     if (pk->ops == NULL)
    1009           0 :         return NULL;
    1010             : 
    1011         130 :     keytype = pk->ops->key_oid;
    1012             : 
    1013         130 :     for (i = 0; sig_algs[i]; i++) {
    1014         130 :         if (sig_algs[i]->key_oid == NULL)
    1015           0 :             continue;
    1016         130 :         if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
    1017           0 :             continue;
    1018         130 :         if (pk->ops->available &&
    1019           0 :             pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
    1020           0 :             continue;
    1021         130 :         if (type == HX509_SELECT_PUBLIC_SIG)
    1022          65 :             return sig_algs[i]->sig_alg;
    1023          65 :         if (type == HX509_SELECT_DIGEST)
    1024          65 :             return sig_algs[i]->digest_alg;
    1025             : 
    1026           0 :         return NULL;
    1027             :     }
    1028           0 :     return NULL;
    1029             : }
    1030             : 
    1031             : /*
    1032             :  *
    1033             :  */
    1034             : #ifdef HAVE_HCRYPTO_W_OPENSSL
    1035             : extern hx509_private_key_ops ecdsa_private_key_ops;
    1036             : #endif
    1037             : 
    1038             : static struct hx509_private_key_ops *private_algs[] = {
    1039             :     &rsa_private_key_ops,
    1040             : #ifdef HAVE_HCRYPTO_W_OPENSSL
    1041             :     &ecdsa_private_key_ops,
    1042             : #endif
    1043             :     NULL
    1044             : };
    1045             : 
    1046             : HX509_LIB_FUNCTION hx509_private_key_ops * HX509_LIB_CALL
    1047          74 : hx509_find_private_alg(const heim_oid *oid)
    1048             : {
    1049           8 :     int i;
    1050          74 :     for (i = 0; private_algs[i]; i++) {
    1051          74 :         if (private_algs[i]->key_oid == NULL)
    1052           0 :             continue;
    1053          74 :         if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
    1054          74 :             return private_algs[i];
    1055             :     }
    1056           0 :     return NULL;
    1057             : }
    1058             : 
    1059             : /*
    1060             :  * Check if the algorithm `alg' have a best before date, and if it
    1061             :  * des, make sure the its before the time `t'.
    1062             :  */
    1063             : 
    1064             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1065          72 : _hx509_signature_is_weak(hx509_context context, const AlgorithmIdentifier *alg)
    1066             : {
    1067           0 :     const struct signature_alg *md;
    1068             : 
    1069          72 :     md = _hx509_find_sig_alg(&alg->algorithm);
    1070          72 :     if (md == NULL) {
    1071           0 :         hx509_clear_error_string(context);
    1072           0 :         return HX509_SIG_ALG_NO_SUPPORTED;
    1073             :     }
    1074          72 :     if (md->flags & WEAK_SIG_ALG) {
    1075           0 :         hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
    1076           0 :                                "Algorithm %s is weak", md->name);
    1077           0 :         return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
    1078             :     }
    1079          72 :     return 0;
    1080             : }
    1081             : 
    1082             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1083         146 : _hx509_self_signed_valid(hx509_context context,
    1084             :                          const AlgorithmIdentifier *alg)
    1085             : {
    1086           0 :     const struct signature_alg *md;
    1087             : 
    1088         146 :     md = _hx509_find_sig_alg(&alg->algorithm);
    1089         146 :     if (md == NULL) {
    1090           0 :         hx509_clear_error_string(context);
    1091           0 :         return HX509_SIG_ALG_NO_SUPPORTED;
    1092             :     }
    1093         146 :     if ((md->flags & SELF_SIGNED_OK) == 0) {
    1094           0 :         hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
    1095             :                                "Algorithm %s not trusted for self signatures",
    1096           0 :                                md->name);
    1097           0 :         return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
    1098             :     }
    1099         146 :     return 0;
    1100             : }
    1101             : 
    1102             : 
    1103             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1104         478 : _hx509_verify_signature(hx509_context context,
    1105             :                         const hx509_cert cert,
    1106             :                         const AlgorithmIdentifier *alg,
    1107             :                         const heim_octet_string *data,
    1108             :                         const heim_octet_string *sig)
    1109             : {
    1110           0 :     const struct signature_alg *md;
    1111         478 :     const Certificate *signer = NULL;
    1112             : 
    1113         478 :     if (cert)
    1114         225 :         signer = _hx509_get_cert(cert);
    1115             : 
    1116         478 :     md = _hx509_find_sig_alg(&alg->algorithm);
    1117         478 :     if (md == NULL) {
    1118           0 :         hx509_clear_error_string(context);
    1119           0 :         return HX509_SIG_ALG_NO_SUPPORTED;
    1120             :     }
    1121         478 :     if (signer && (md->flags & PROVIDE_CONF) == 0) {
    1122           0 :         hx509_clear_error_string(context);
    1123           0 :         return HX509_CRYPTO_SIG_NO_CONF;
    1124             :     }
    1125         478 :     if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
    1126           0 :             hx509_clear_error_string(context);
    1127           0 :         return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
    1128             :     }
    1129         478 :     if (md->key_oid && signer) {
    1130           0 :         const SubjectPublicKeyInfo *spi;
    1131         225 :         spi = &signer->tbsCertificate.subjectPublicKeyInfo;
    1132             : 
    1133         225 :         if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
    1134           0 :             hx509_clear_error_string(context);
    1135           0 :             return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
    1136             :         }
    1137             :     }
    1138         478 :     return (*md->verify_signature)(context, md, signer, alg, data, sig);
    1139             : }
    1140             : 
    1141             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1142         191 : _hx509_create_signature(hx509_context context,
    1143             :                         const hx509_private_key signer,
    1144             :                         const AlgorithmIdentifier *alg,
    1145             :                         const heim_octet_string *data,
    1146             :                         AlgorithmIdentifier *signatureAlgorithm,
    1147             :                         heim_octet_string *sig)
    1148             : {
    1149           0 :     const struct signature_alg *md;
    1150             : 
    1151         191 :     md = _hx509_find_sig_alg(&alg->algorithm);
    1152         191 :     if (md == NULL) {
    1153           0 :         hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
    1154             :             "algorithm no supported");
    1155           0 :         return HX509_SIG_ALG_NO_SUPPORTED;
    1156             :     }
    1157             : 
    1158         191 :     if (signer && (md->flags & PROVIDE_CONF) == 0) {
    1159           0 :         hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
    1160             :             "algorithm provides no conf");
    1161           0 :         return HX509_CRYPTO_SIG_NO_CONF;
    1162             :     }
    1163             : 
    1164         191 :     return (*md->create_signature)(context, md, signer, alg, data,
    1165             :                                    signatureAlgorithm, sig);
    1166             : }
    1167             : 
    1168             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1169           0 : _hx509_create_signature_bitstring(hx509_context context,
    1170             :                                   const hx509_private_key signer,
    1171             :                                   const AlgorithmIdentifier *alg,
    1172             :                                   const heim_octet_string *data,
    1173             :                                   AlgorithmIdentifier *signatureAlgorithm,
    1174             :                                   heim_bit_string *sig)
    1175             : {
    1176           0 :     heim_octet_string os;
    1177           0 :     int ret;
    1178             : 
    1179           0 :     ret = _hx509_create_signature(context, signer, alg,
    1180             :                                   data, signatureAlgorithm, &os);
    1181           0 :     if (ret)
    1182           0 :         return ret;
    1183           0 :     sig->data = os.data;
    1184           0 :     sig->length = os.length * 8;
    1185           0 :     return 0;
    1186             : }
    1187             : 
    1188             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1189          21 : _hx509_public_encrypt(hx509_context context,
    1190             :                       const heim_octet_string *cleartext,
    1191             :                       const Certificate *cert,
    1192             :                       heim_oid *encryption_oid,
    1193             :                       heim_octet_string *ciphertext)
    1194             : {
    1195           0 :     const SubjectPublicKeyInfo *spi;
    1196           0 :     unsigned char *to;
    1197           0 :     int tosize;
    1198           0 :     int ret;
    1199           0 :     RSA *rsa;
    1200           0 :     size_t size;
    1201           0 :     const unsigned char *p;
    1202             : 
    1203          21 :     ciphertext->data = NULL;
    1204          21 :     ciphertext->length = 0;
    1205             : 
    1206          21 :     spi = &cert->tbsCertificate.subjectPublicKeyInfo;
    1207             : 
    1208          21 :     p = spi->subjectPublicKey.data;
    1209          21 :     size = spi->subjectPublicKey.length / 8;
    1210             : 
    1211          21 :     rsa = d2i_RSAPublicKey(NULL, &p, size);
    1212          21 :     if (rsa == NULL) {
    1213           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    1214           0 :         return ENOMEM;
    1215             :     }
    1216             : 
    1217          21 :     tosize = RSA_size(rsa);
    1218          21 :     to = malloc(tosize);
    1219          21 :     if (to == NULL) {
    1220           0 :         RSA_free(rsa);
    1221           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    1222           0 :         return ENOMEM;
    1223             :     }
    1224             : 
    1225          21 :     ret = RSA_public_encrypt(cleartext->length,
    1226          21 :                              (unsigned char *)cleartext->data,
    1227             :                              to, rsa, RSA_PKCS1_PADDING);
    1228          21 :     RSA_free(rsa);
    1229          21 :     if (ret <= 0) {
    1230           0 :         free(to);
    1231           0 :         hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
    1232             :                                "RSA public encrypt failed with %d", ret);
    1233           0 :         return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
    1234             :     }
    1235          21 :     if (ret > tosize)
    1236           0 :         _hx509_abort("internal rsa decryption failure: ret > tosize");
    1237             : 
    1238          21 :     ciphertext->length = ret;
    1239          21 :     ciphertext->data = to;
    1240             : 
    1241          21 :     ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
    1242          21 :     if (ret) {
    1243           0 :         der_free_octet_string(ciphertext);
    1244           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    1245           0 :         return ENOMEM;
    1246             :     }
    1247             : 
    1248          21 :     return 0;
    1249             : }
    1250             : 
    1251             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1252           0 : hx509_private_key_private_decrypt(hx509_context context,
    1253             :                                    const heim_octet_string *ciphertext,
    1254             :                                    const heim_oid *encryption_oid,
    1255             :                                    hx509_private_key p,
    1256             :                                    heim_octet_string *cleartext)
    1257             : {
    1258           0 :     int ret;
    1259             : 
    1260           0 :     cleartext->data = NULL;
    1261           0 :     cleartext->length = 0;
    1262             : 
    1263           0 :     if (p->private_key.rsa == NULL) {
    1264           0 :         hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
    1265             :                                "Private RSA key missing");
    1266           0 :         return HX509_PRIVATE_KEY_MISSING;
    1267             :     }
    1268             : 
    1269           0 :     cleartext->length = RSA_size(p->private_key.rsa);
    1270           0 :     cleartext->data = malloc(cleartext->length);
    1271           0 :     if (cleartext->data == NULL) {
    1272           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    1273           0 :         return ENOMEM;
    1274             :     }
    1275           0 :     ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
    1276           0 :                               cleartext->data,
    1277             :                               p->private_key.rsa,
    1278             :                               RSA_PKCS1_PADDING);
    1279           0 :     if (ret <= 0) {
    1280           0 :         der_free_octet_string(cleartext);
    1281           0 :         hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
    1282             :                                "Failed to decrypt using private key: %d", ret);
    1283           0 :         return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
    1284             :     }
    1285           0 :     if (cleartext->length < (size_t)ret)
    1286           0 :         _hx509_abort("internal rsa decryption failure: ret > tosize");
    1287             : 
    1288           0 :     cleartext->length = ret;
    1289             : 
    1290           0 :     return 0;
    1291             : }
    1292             : 
    1293             : 
    1294             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1295          74 : hx509_parse_private_key(hx509_context context,
    1296             :                          const AlgorithmIdentifier *keyai,
    1297             :                          const void *data,
    1298             :                          size_t len,
    1299             :                          hx509_key_format_t format,
    1300             :                          hx509_private_key *private_key)
    1301             : {
    1302           8 :     struct hx509_private_key_ops *ops;
    1303           8 :     int ret;
    1304             : 
    1305          74 :     *private_key = NULL;
    1306             : 
    1307          74 :     ops = hx509_find_private_alg(&keyai->algorithm);
    1308          74 :     if (ops == NULL) {
    1309           0 :         hx509_clear_error_string(context);
    1310           0 :         return HX509_SIG_ALG_NO_SUPPORTED;
    1311             :     }
    1312             : 
    1313          74 :     ret = hx509_private_key_init(private_key, ops, NULL);
    1314          74 :     if (ret) {
    1315           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
    1316           0 :         return ret;
    1317             :     }
    1318             : 
    1319          74 :     ret = (*ops->import)(context, keyai, data, len, format, *private_key);
    1320          74 :     if (ret)
    1321           0 :         hx509_private_key_free(private_key);
    1322             : 
    1323          74 :     if (ret && format == HX509_KEY_FORMAT_PKCS8) {
    1324           0 :         PKCS8PrivateKeyInfo ki;
    1325           0 :         hx509_private_key key;
    1326             : 
    1327             :         /* Re-enter to try parsing the DER-encoded key from PKCS#8 envelope */
    1328           0 :         ret = decode_PKCS8PrivateKeyInfo(data, len, &ki, NULL);
    1329           0 :         if (ret) {
    1330           0 :             hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
    1331             :                                    "Failed to parse PKCS#8-encoded private "
    1332             :                                    "key");
    1333           0 :             return HX509_PARSING_KEY_FAILED;
    1334             :         }
    1335           0 :         ret = hx509_parse_private_key(context, &ki.privateKeyAlgorithm,
    1336           0 :                                       ki.privateKey.data, ki.privateKey.length,
    1337             :                                       HX509_KEY_FORMAT_DER, &key);
    1338           0 :         free_PKCS8PrivateKeyInfo(&ki);
    1339           0 :         if (ret) {
    1340           0 :             hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
    1341             :                                    "Failed to parse RSA key from PKCS#8 "
    1342             :                                    "envelope");
    1343           0 :             return HX509_PARSING_KEY_FAILED;
    1344             :         }
    1345           0 :         *private_key = key;
    1346             :     }
    1347          66 :     return ret;
    1348             : }
    1349             : 
    1350             : /*
    1351             :  *
    1352             :  */
    1353             : 
    1354             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1355           0 : hx509_private_key2SPKI(hx509_context context,
    1356             :                         hx509_private_key private_key,
    1357             :                         SubjectPublicKeyInfo *spki)
    1358             : {
    1359           0 :     const struct hx509_private_key_ops *ops = private_key->ops;
    1360           0 :     if (ops == NULL || ops->get_spki == NULL) {
    1361           0 :         hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
    1362             :                                "Private key have no key2SPKI function");
    1363           0 :         return HX509_UNIMPLEMENTED_OPERATION;
    1364             :     }
    1365           0 :     return (*ops->get_spki)(context, private_key, spki);
    1366             : }
    1367             : 
    1368             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1369           0 : _hx509_generate_private_key_init(hx509_context context,
    1370             :                                  const heim_oid *oid,
    1371             :                                  struct hx509_generate_private_context **ctx)
    1372             : {
    1373           0 :     *ctx = NULL;
    1374             : 
    1375           0 :     if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
    1376           0 :         hx509_set_error_string(context, 0, EINVAL,
    1377             :                                "private key not an RSA key");
    1378           0 :         return EINVAL;
    1379             :     }
    1380             : 
    1381           0 :     *ctx = calloc(1, sizeof(**ctx));
    1382           0 :     if (*ctx == NULL) {
    1383           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    1384           0 :         return ENOMEM;
    1385             :     }
    1386           0 :     (*ctx)->key_oid = oid;
    1387             : 
    1388           0 :     return 0;
    1389             : }
    1390             : 
    1391             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1392           0 : _hx509_generate_private_key_is_ca(hx509_context context,
    1393             :                                   struct hx509_generate_private_context *ctx)
    1394             : {
    1395           0 :     ctx->isCA = 1;
    1396           0 :     return 0;
    1397             : }
    1398             : 
    1399             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1400           0 : _hx509_generate_private_key_bits(hx509_context context,
    1401             :                                  struct hx509_generate_private_context *ctx,
    1402             :                                  unsigned long bits)
    1403             : {
    1404           0 :     ctx->num_bits = bits;
    1405           0 :     return 0;
    1406             : }
    1407             : 
    1408             : 
    1409             : HX509_LIB_FUNCTION void HX509_LIB_CALL
    1410           0 : _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
    1411             : {
    1412           0 :     free(*ctx);
    1413           0 :     *ctx = NULL;
    1414           0 : }
    1415             : 
    1416             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1417           0 : _hx509_generate_private_key(hx509_context context,
    1418             :                             struct hx509_generate_private_context *ctx,
    1419             :                             hx509_private_key *private_key)
    1420             : {
    1421           0 :     struct hx509_private_key_ops *ops;
    1422           0 :     int ret;
    1423             : 
    1424           0 :     *private_key = NULL;
    1425             : 
    1426           0 :     ops = hx509_find_private_alg(ctx->key_oid);
    1427           0 :     if (ops == NULL) {
    1428           0 :         hx509_clear_error_string(context);
    1429           0 :         return HX509_SIG_ALG_NO_SUPPORTED;
    1430             :     }
    1431             : 
    1432           0 :     ret = hx509_private_key_init(private_key, ops, NULL);
    1433           0 :     if (ret) {
    1434           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
    1435           0 :         return ret;
    1436             :     }
    1437             : 
    1438           0 :     ret = (*ops->generate_private_key)(context, ctx, *private_key);
    1439           0 :     if (ret)
    1440           0 :         hx509_private_key_free(private_key);
    1441             : 
    1442           0 :     return ret;
    1443             : }
    1444             : 
    1445             : /*
    1446             :  *
    1447             :  */
    1448             : 
    1449             : const AlgorithmIdentifier *
    1450          37 : hx509_signature_sha512(void)
    1451          37 : { return &_hx509_signature_sha512_data; }
    1452             : 
    1453             : const AlgorithmIdentifier *
    1454           0 : hx509_signature_sha384(void)
    1455           0 : { return &_hx509_signature_sha384_data; }
    1456             : 
    1457             : const AlgorithmIdentifier *
    1458          24 : hx509_signature_sha256(void)
    1459          24 : { return &_hx509_signature_sha256_data; }
    1460             : 
    1461             : const AlgorithmIdentifier *
    1462           8 : hx509_signature_sha1(void)
    1463           8 : { return &_hx509_signature_sha1_data; }
    1464             : 
    1465             : const AlgorithmIdentifier *
    1466           0 : hx509_signature_md5(void)
    1467           0 : { return &_hx509_signature_md5_data; }
    1468             : 
    1469             : const AlgorithmIdentifier *
    1470           0 : hx509_signature_rsa_with_sha512(void)
    1471           0 : { return &_hx509_signature_rsa_with_sha512_data; }
    1472             : 
    1473             : const AlgorithmIdentifier *
    1474           0 : hx509_signature_rsa_with_sha384(void)
    1475           0 : { return &_hx509_signature_rsa_with_sha384_data; }
    1476             : 
    1477             : const AlgorithmIdentifier *
    1478           0 : hx509_signature_rsa_with_sha256(void)
    1479           0 : { return &_hx509_signature_rsa_with_sha256_data; }
    1480             : 
    1481             : const AlgorithmIdentifier *
    1482           4 : hx509_signature_rsa_with_sha1(void)
    1483           4 : { return &_hx509_signature_rsa_with_sha1_data; }
    1484             : 
    1485             : const AlgorithmIdentifier *
    1486           0 : hx509_signature_rsa_with_md5(void)
    1487           0 : { return &_hx509_signature_rsa_with_md5_data; }
    1488             : 
    1489             : const AlgorithmIdentifier *
    1490          74 : hx509_signature_rsa(void)
    1491          74 : { return &_hx509_signature_rsa_data; }
    1492             : 
    1493             : const AlgorithmIdentifier *
    1494           0 : hx509_signature_rsa_pkcs1_x509(void)
    1495           0 : { return &_hx509_signature_rsa_pkcs1_x509_data; }
    1496             : 
    1497             : const AlgorithmIdentifier *
    1498         128 : hx509_crypto_des_rsdi_ede3_cbc(void)
    1499         128 : { return &_hx509_des_rsdi_ede3_cbc_oid; }
    1500             : 
    1501             : const AlgorithmIdentifier *
    1502         124 : hx509_crypto_aes128_cbc(void)
    1503         124 : { return &_hx509_crypto_aes128_cbc_data; }
    1504             : 
    1505             : const AlgorithmIdentifier *
    1506         124 : hx509_crypto_aes256_cbc(void)
    1507         124 : { return &_hx509_crypto_aes256_cbc_data; }
    1508             : 
    1509             : /*
    1510             :  *
    1511             :  */
    1512             : 
    1513             : const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
    1514             :     &_hx509_signature_rsa_with_sha256_data;
    1515             : const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
    1516             :     &_hx509_signature_sha256_data;
    1517             : const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
    1518             :     &_hx509_crypto_aes128_cbc_data;
    1519             : 
    1520             : /*
    1521             :  *
    1522             :  */
    1523             : 
    1524             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1525          74 : hx509_private_key_init(hx509_private_key *key,
    1526             :                         hx509_private_key_ops *ops,
    1527             :                         void *keydata)
    1528             : {
    1529          74 :     *key = calloc(1, sizeof(**key));
    1530          74 :     if (*key == NULL)
    1531           0 :         return ENOMEM;
    1532          74 :     (*key)->ref = 1;
    1533          74 :     (*key)->ops = ops;
    1534          74 :     (*key)->private_key.keydata = keydata;
    1535          74 :     return 0;
    1536             : }
    1537             : 
    1538             : HX509_LIB_FUNCTION hx509_private_key HX509_LIB_CALL
    1539         148 : _hx509_private_key_ref(hx509_private_key key)
    1540             : {
    1541         148 :     if (key->ref == 0)
    1542           0 :         _hx509_abort("key refcount <= 0 on ref");
    1543         148 :     key->ref++;
    1544         148 :     if (key->ref == UINT_MAX)
    1545           0 :         _hx509_abort("key refcount == UINT_MAX on ref");
    1546         148 :     return key;
    1547             : }
    1548             : 
    1549             : HX509_LIB_FUNCTION const char * HX509_LIB_CALL
    1550           0 : _hx509_private_pem_name(hx509_private_key key)
    1551             : {
    1552           0 :     return key->ops->pemtype;
    1553             : }
    1554             : 
    1555             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1556         114 : hx509_private_key_free(hx509_private_key *key)
    1557             : {
    1558         114 :     if (key == NULL || *key == NULL)
    1559           0 :         return 0;
    1560             : 
    1561         114 :     if ((*key)->ref == 0)
    1562           0 :         _hx509_abort("key refcount == 0 on free");
    1563         114 :     if (--(*key)->ref > 0)
    1564          86 :         return 0;
    1565             : 
    1566          20 :     if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
    1567          20 :         if ((*key)->private_key.rsa)
    1568          20 :             RSA_free((*key)->private_key.rsa);
    1569           0 :     } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid,
    1570           0 :                                                ASN1_OID_ID_ECPUBLICKEY) == 0 &&
    1571           0 :                (*key)->private_key.ecdsa != NULL) {
    1572           0 :       _hx509_private_eckey_free((*key)->private_key.ecdsa);
    1573             :     }
    1574          20 :     (*key)->private_key.rsa = NULL;
    1575          20 :     free(*key);
    1576          20 :     *key = NULL;
    1577          20 :     return 0;
    1578             : }
    1579             : 
    1580             : HX509_LIB_FUNCTION void HX509_LIB_CALL
    1581           0 : hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
    1582             : {
    1583           0 :     if (key->private_key.rsa)
    1584           0 :         RSA_free(key->private_key.rsa);
    1585           0 :     key->private_key.rsa = ptr;
    1586           0 :     key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
    1587           0 :     key->md = &pkcs1_rsa_sha1_alg;
    1588           0 : }
    1589             : 
    1590             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1591           0 : _hx509_private_key_oid(hx509_context context,
    1592             :                        const hx509_private_key key,
    1593             :                        heim_oid *data)
    1594             : {
    1595           0 :     int ret;
    1596           0 :     ret = der_copy_oid(key->ops->key_oid, data);
    1597           0 :     if (ret)
    1598           0 :         hx509_set_error_string(context, 0, ret, "malloc out of memory");
    1599           0 :     return ret;
    1600             : }
    1601             : 
    1602             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1603           0 : _hx509_private_key_exportable(hx509_private_key key)
    1604             : {
    1605           0 :     if (key->ops->export == NULL)
    1606           0 :         return 0;
    1607           0 :     return 1;
    1608             : }
    1609             : 
    1610             : HX509_LIB_FUNCTION BIGNUM * HX509_LIB_CALL
    1611           0 : _hx509_private_key_get_internal(hx509_context context,
    1612             :                                 hx509_private_key key,
    1613             :                                 const char *type)
    1614             : {
    1615           0 :     if (key->ops->get_internal == NULL)
    1616           0 :         return NULL;
    1617           0 :     return (*key->ops->get_internal)(context, key, type);
    1618             : }
    1619             : 
    1620             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1621           0 : _hx509_private_key_export(hx509_context context,
    1622             :                           const hx509_private_key key,
    1623             :                           hx509_key_format_t format,
    1624             :                           heim_octet_string *data)
    1625             : {
    1626           0 :     data->length = 0;
    1627           0 :     data->data = NULL;
    1628           0 :     if (key->ops->export == NULL) {
    1629           0 :         hx509_clear_error_string(context);
    1630           0 :         return HX509_UNIMPLEMENTED_OPERATION;
    1631             :     }
    1632           0 :     if (format == HX509_KEY_FORMAT_PKCS8) {
    1633           0 :         PKCS8PrivateKeyInfo ki;
    1634           0 :         size_t size;
    1635           0 :         int ret;
    1636             : 
    1637           0 :         memset(&ki, 0, sizeof(ki));
    1638           0 :         ki.attributes = NULL; /* No localKeyId needed */
    1639           0 :         ki.privateKey.data = NULL;
    1640           0 :         ki.privateKeyAlgorithm.algorithm.components = NULL;
    1641           0 :         ret = der_parse_hex_heim_integer("00", &ki.version);
    1642           0 :         if (ret == 0)
    1643           0 :             ret = _hx509_private_key_oid(context, key,
    1644             :                                          &ki.privateKeyAlgorithm.algorithm);
    1645           0 :         if (ret == 0)
    1646             :             /* Re-enter */
    1647           0 :             ret = _hx509_private_key_export(context, key, HX509_KEY_FORMAT_DER,
    1648             :                                             &ki.privateKey);
    1649             : 
    1650             :         /*
    1651             :          * XXX To set ki.privateKeyAlgorithm.parameters we'll need to either
    1652             :          * move this code into the *key->ops->export() functions, or expand
    1653             :          * their signature to allow them to set it for us, or add a method to
    1654             :          * hx509_private_key_ops that allows us to get the parameters from the
    1655             :          * backend.
    1656             :          */
    1657           0 :         ki.privateKeyAlgorithm.parameters = NULL;
    1658             : 
    1659           0 :         if (ret == 0)
    1660           0 :             ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, data->data, data->length,
    1661             :                                &ki, &size, ret);
    1662           0 :         free_PKCS8PrivateKeyInfo(&ki);
    1663           0 :         if (ret == 0 && size != data->length)
    1664           0 :             ret = EINVAL;
    1665           0 :         if (ret)
    1666           0 :             hx509_set_error_string(context, 0, ret,
    1667             :                                    "Private key PKCS#8 encoding failed");
    1668           0 :         return ret;
    1669             :     }
    1670           0 :     return (*key->ops->export)(context, key, format, data);
    1671             : }
    1672             : 
    1673             : /*
    1674             :  *
    1675             :  */
    1676             : 
    1677             : struct hx509cipher {
    1678             :     const char *name;
    1679             :     int flags;
    1680             : #define CIPHER_WEAK 1
    1681             :     const heim_oid *oid;
    1682             :     const AlgorithmIdentifier *(*ai_func)(void);
    1683             :     const EVP_CIPHER *(*evp_func)(void);
    1684             :     int (*get_params)(hx509_context, const hx509_crypto,
    1685             :                       const heim_octet_string *, heim_octet_string *);
    1686             :     int (*set_params)(hx509_context, const heim_octet_string *,
    1687             :                       hx509_crypto, heim_octet_string *);
    1688             : };
    1689             : 
    1690             : struct hx509_crypto_data {
    1691             :     char *name;
    1692             :     int flags;
    1693             : #define ALLOW_WEAK      1
    1694             : 
    1695             : #define PADDING_NONE    2
    1696             : #define PADDING_PKCS7   4
    1697             : #define PADDING_FLAGS   (2|4)
    1698             :     const struct hx509cipher *cipher;
    1699             :     const EVP_CIPHER *c;
    1700             :     heim_octet_string key;
    1701             :     heim_oid oid;
    1702             :     void *param;
    1703             : };
    1704             : 
    1705             : /*
    1706             :  *
    1707             :  */
    1708             : 
    1709             : static unsigned private_rc2_40_oid_data[] = { 127, 1 };
    1710             : 
    1711             : static heim_oid asn1_oid_private_rc2_40 =
    1712             :     { 2, private_rc2_40_oid_data };
    1713             : 
    1714             : /*
    1715             :  *
    1716             :  */
    1717             : 
    1718             : static int
    1719          21 : CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
    1720             :                  const heim_octet_string *ivec, heim_octet_string *param)
    1721             : {
    1722           0 :     size_t size;
    1723           0 :     int ret;
    1724             : 
    1725          21 :     assert(crypto->param == NULL);
    1726          21 :     if (ivec == NULL)
    1727           0 :         return 0;
    1728             : 
    1729          21 :     ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
    1730             :                        ivec, &size, ret);
    1731          21 :     if (ret == 0 && size != param->length)
    1732           0 :         _hx509_abort("Internal asn1 encoder failure");
    1733          21 :     if (ret)
    1734           0 :         hx509_clear_error_string(context);
    1735          21 :     return ret;
    1736             : }
    1737             : 
    1738             : static int
    1739           0 : CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
    1740             :                 hx509_crypto crypto, heim_octet_string *ivec)
    1741             : {
    1742           0 :     int ret;
    1743           0 :     if (ivec == NULL)
    1744           0 :         return 0;
    1745             : 
    1746           0 :     ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
    1747           0 :     if (ret)
    1748           0 :         hx509_clear_error_string(context);
    1749             : 
    1750           0 :     return ret;
    1751             : }
    1752             : 
    1753             : struct _RC2_params {
    1754             :     int maximum_effective_key;
    1755             : };
    1756             : 
    1757             : static int
    1758           0 : CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
    1759             :                    const heim_octet_string *ivec, heim_octet_string *param)
    1760             : {
    1761           0 :     CMSRC2CBCParameter rc2params;
    1762           0 :     const struct _RC2_params *p = crypto->param;
    1763           0 :     int maximum_effective_key = 128;
    1764           0 :     size_t size;
    1765           0 :     int ret;
    1766             : 
    1767           0 :     memset(&rc2params, 0, sizeof(rc2params));
    1768             : 
    1769           0 :     if (p)
    1770           0 :         maximum_effective_key = p->maximum_effective_key;
    1771             : 
    1772           0 :     switch(maximum_effective_key) {
    1773           0 :     case 40:
    1774           0 :         rc2params.rc2ParameterVersion = 160;
    1775           0 :         break;
    1776           0 :     case 64:
    1777           0 :         rc2params.rc2ParameterVersion = 120;
    1778           0 :         break;
    1779           0 :     case 128:
    1780           0 :         rc2params.rc2ParameterVersion = 58;
    1781           0 :         break;
    1782             :     }
    1783           0 :     rc2params.iv = *ivec;
    1784             : 
    1785           0 :     ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
    1786             :                        &rc2params, &size, ret);
    1787           0 :     if (ret == 0 && size != param->length)
    1788           0 :         _hx509_abort("Internal asn1 encoder failure");
    1789             : 
    1790           0 :     return ret;
    1791             : }
    1792             : 
    1793             : static int
    1794           0 : CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
    1795             :                    hx509_crypto crypto, heim_octet_string *ivec)
    1796             : {
    1797           0 :     CMSRC2CBCParameter rc2param;
    1798           0 :     struct _RC2_params *p;
    1799           0 :     size_t size;
    1800           0 :     int ret;
    1801             : 
    1802           0 :     ret = decode_CMSRC2CBCParameter(param->data, param->length,
    1803             :                                     &rc2param, &size);
    1804           0 :     if (ret) {
    1805           0 :         hx509_clear_error_string(context);
    1806           0 :         return ret;
    1807             :     }
    1808             : 
    1809           0 :     p = calloc(1, sizeof(*p));
    1810           0 :     if (p == NULL) {
    1811           0 :         free_CMSRC2CBCParameter(&rc2param);
    1812           0 :         hx509_clear_error_string(context);
    1813           0 :         return ENOMEM;
    1814             :     }
    1815           0 :     switch(rc2param.rc2ParameterVersion) {
    1816           0 :     case 160:
    1817           0 :         crypto->c = EVP_rc2_40_cbc();
    1818           0 :         p->maximum_effective_key = 40;
    1819           0 :         break;
    1820           0 :     case 120:
    1821           0 :         crypto->c = EVP_rc2_64_cbc();
    1822           0 :         p->maximum_effective_key = 64;
    1823           0 :         break;
    1824           0 :     case 58:
    1825           0 :         crypto->c = EVP_rc2_cbc();
    1826           0 :         p->maximum_effective_key = 128;
    1827           0 :         break;
    1828           0 :     default:
    1829           0 :         free(p);
    1830           0 :         free_CMSRC2CBCParameter(&rc2param);
    1831           0 :         return HX509_CRYPTO_SIG_INVALID_FORMAT;
    1832             :     }
    1833           0 :     if (ivec)
    1834           0 :         ret = der_copy_octet_string(&rc2param.iv, ivec);
    1835           0 :     free_CMSRC2CBCParameter(&rc2param);
    1836           0 :     if (ret) {
    1837           0 :         free(p);
    1838           0 :         hx509_clear_error_string(context);
    1839             :     } else
    1840           0 :         crypto->param = p;
    1841             : 
    1842           0 :     return ret;
    1843             : }
    1844             : 
    1845             : /*
    1846             :  *
    1847             :  */
    1848             : 
    1849             : static const struct hx509cipher ciphers[] = {
    1850             :     {
    1851             :         "rc2-cbc",
    1852             :         CIPHER_WEAK,
    1853             :         ASN1_OID_ID_PKCS3_RC2_CBC,
    1854             :         NULL,
    1855             :         EVP_rc2_cbc,
    1856             :         CMSRC2CBCParam_get,
    1857             :         CMSRC2CBCParam_set
    1858             :     },
    1859             :     {
    1860             :         "rc2-cbc",
    1861             :         CIPHER_WEAK,
    1862             :         ASN1_OID_ID_RSADSI_RC2_CBC,
    1863             :         NULL,
    1864             :         EVP_rc2_cbc,
    1865             :         CMSRC2CBCParam_get,
    1866             :         CMSRC2CBCParam_set
    1867             :     },
    1868             :     {
    1869             :         "rc2-40-cbc",
    1870             :         CIPHER_WEAK,
    1871             :         &asn1_oid_private_rc2_40,
    1872             :         NULL,
    1873             :         EVP_rc2_40_cbc,
    1874             :         CMSRC2CBCParam_get,
    1875             :         CMSRC2CBCParam_set
    1876             :     },
    1877             :     {
    1878             :         "des-ede3-cbc",
    1879             :         0,
    1880             :         ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
    1881             :         NULL,
    1882             :         EVP_des_ede3_cbc,
    1883             :         CMSCBCParam_get,
    1884             :         CMSCBCParam_set
    1885             :     },
    1886             :     {
    1887             :         "des-ede3-cbc",
    1888             :         0,
    1889             :         ASN1_OID_ID_RSADSI_DES_EDE3_CBC,
    1890             :         hx509_crypto_des_rsdi_ede3_cbc,
    1891             :         EVP_des_ede3_cbc,
    1892             :         CMSCBCParam_get,
    1893             :         CMSCBCParam_set
    1894             :     },
    1895             :     {
    1896             :         "aes-128-cbc",
    1897             :         0,
    1898             :         ASN1_OID_ID_AES_128_CBC,
    1899             :         hx509_crypto_aes128_cbc,
    1900             :         EVP_aes_128_cbc,
    1901             :         CMSCBCParam_get,
    1902             :         CMSCBCParam_set
    1903             :     },
    1904             :     {
    1905             :         "aes-192-cbc",
    1906             :         0,
    1907             :         ASN1_OID_ID_AES_192_CBC,
    1908             :         NULL,
    1909             :         EVP_aes_192_cbc,
    1910             :         CMSCBCParam_get,
    1911             :         CMSCBCParam_set
    1912             :     },
    1913             :     {
    1914             :         "aes-256-cbc",
    1915             :         0,
    1916             :         ASN1_OID_ID_AES_256_CBC,
    1917             :         hx509_crypto_aes256_cbc,
    1918             :         EVP_aes_256_cbc,
    1919             :         CMSCBCParam_get,
    1920             :         CMSCBCParam_set
    1921             :     }
    1922             : };
    1923             : 
    1924             : static const struct hx509cipher *
    1925          21 : find_cipher_by_oid(const heim_oid *oid)
    1926             : {
    1927           0 :     size_t i;
    1928             : 
    1929         156 :     for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
    1930         156 :         if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
    1931          21 :             return &ciphers[i];
    1932             : 
    1933           0 :     return NULL;
    1934             : }
    1935             : 
    1936             : static const struct hx509cipher *
    1937           0 : find_cipher_by_name(const char *name)
    1938             : {
    1939           0 :     size_t i;
    1940             : 
    1941           0 :     for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
    1942           0 :         if (strcasecmp(name, ciphers[i].name) == 0)
    1943           0 :             return &ciphers[i];
    1944             : 
    1945           0 :     return NULL;
    1946             : }
    1947             : 
    1948             : 
    1949             : HX509_LIB_FUNCTION const heim_oid * HX509_LIB_CALL
    1950           0 : hx509_crypto_enctype_by_name(const char *name)
    1951             : {
    1952           0 :     const struct hx509cipher *cipher;
    1953             : 
    1954           0 :     cipher = find_cipher_by_name(name);
    1955           0 :     if (cipher == NULL)
    1956           0 :         return NULL;
    1957           0 :     return cipher->oid;
    1958             : }
    1959             : 
    1960             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    1961          21 : hx509_crypto_init(hx509_context context,
    1962             :                   const char *provider,
    1963             :                   const heim_oid *enctype,
    1964             :                   hx509_crypto *crypto)
    1965             : {
    1966           0 :     const struct hx509cipher *cipher;
    1967             : 
    1968          21 :     *crypto = NULL;
    1969             : 
    1970          21 :     cipher = find_cipher_by_oid(enctype);
    1971          21 :     if (cipher == NULL) {
    1972           0 :         hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
    1973             :                                "Algorithm not supported");
    1974           0 :         return HX509_ALG_NOT_SUPP;
    1975             :     }
    1976             : 
    1977          21 :     *crypto = calloc(1, sizeof(**crypto));
    1978          21 :     if (*crypto == NULL) {
    1979           0 :         hx509_clear_error_string(context);
    1980           0 :         return ENOMEM;
    1981             :     }
    1982             : 
    1983          21 :     (*crypto)->flags = PADDING_PKCS7;
    1984          21 :     (*crypto)->cipher = cipher;
    1985          21 :     (*crypto)->c = (*cipher->evp_func)();
    1986             : 
    1987          21 :     if (der_copy_oid(enctype, &(*crypto)->oid)) {
    1988           0 :         hx509_crypto_destroy(*crypto);
    1989           0 :         *crypto = NULL;
    1990           0 :         hx509_clear_error_string(context);
    1991           0 :         return ENOMEM;
    1992             :     }
    1993             : 
    1994          21 :     return 0;
    1995             : }
    1996             : 
    1997             : HX509_LIB_FUNCTION const char * HX509_LIB_CALL
    1998           0 : hx509_crypto_provider(hx509_crypto crypto)
    1999             : {
    2000           0 :     return "unknown";
    2001             : }
    2002             : 
    2003             : HX509_LIB_FUNCTION void HX509_LIB_CALL
    2004          21 : hx509_crypto_destroy(hx509_crypto crypto)
    2005             : {
    2006          21 :     if (crypto->name)
    2007           0 :         free(crypto->name);
    2008          21 :     if (crypto->key.data)
    2009          21 :         free(crypto->key.data);
    2010          21 :     if (crypto->param)
    2011           0 :         free(crypto->param);
    2012          21 :     der_free_oid(&crypto->oid);
    2013          21 :     memset(crypto, 0, sizeof(*crypto));
    2014          21 :     free(crypto);
    2015          21 : }
    2016             : 
    2017             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2018           0 : hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
    2019             : {
    2020           0 :     return 0;
    2021             : }
    2022             : 
    2023             : HX509_LIB_FUNCTION void HX509_LIB_CALL
    2024           0 : hx509_crypto_allow_weak(hx509_crypto crypto)
    2025             : {
    2026           0 :     crypto->flags |= ALLOW_WEAK;
    2027           0 : }
    2028             : 
    2029             : HX509_LIB_FUNCTION void HX509_LIB_CALL
    2030           0 : hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
    2031             : {
    2032           0 :     switch (padding_type) {
    2033           0 :     case HX509_CRYPTO_PADDING_PKCS7:
    2034           0 :         crypto->flags &= ~PADDING_FLAGS;
    2035           0 :         crypto->flags |= PADDING_PKCS7;
    2036           0 :         break;
    2037           0 :     case HX509_CRYPTO_PADDING_NONE:
    2038           0 :         crypto->flags &= ~PADDING_FLAGS;
    2039           0 :         crypto->flags |= PADDING_NONE;
    2040           0 :         break;
    2041           0 :     default:
    2042           0 :         _hx509_abort("Invalid padding");
    2043             :     }
    2044           0 : }
    2045             : 
    2046             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2047           0 : hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
    2048             : {
    2049           0 :     if (EVP_CIPHER_key_length(crypto->c) > (int)length)
    2050           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2051             : 
    2052           0 :     if (crypto->key.data) {
    2053           0 :         free(crypto->key.data);
    2054           0 :         crypto->key.data = NULL;
    2055           0 :         crypto->key.length = 0;
    2056             :     }
    2057           0 :     crypto->key.data = malloc(length);
    2058           0 :     if (crypto->key.data == NULL)
    2059           0 :         return ENOMEM;
    2060           0 :     memcpy(crypto->key.data, data, length);
    2061           0 :     crypto->key.length = length;
    2062             : 
    2063           0 :     return 0;
    2064             : }
    2065             : 
    2066             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2067          21 : hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
    2068             : {
    2069          21 :     if (crypto->key.data) {
    2070           0 :         free(crypto->key.data);
    2071           0 :         crypto->key.length = 0;
    2072             :     }
    2073             : 
    2074          21 :     crypto->key.length = EVP_CIPHER_key_length(crypto->c);
    2075          21 :     crypto->key.data = malloc(crypto->key.length);
    2076          21 :     if (crypto->key.data == NULL) {
    2077           0 :         crypto->key.length = 0;
    2078           0 :         return ENOMEM;
    2079             :     }
    2080          21 :     if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
    2081           0 :         free(crypto->key.data);
    2082           0 :         crypto->key.data = NULL;
    2083           0 :         crypto->key.length = 0;
    2084           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2085             :     }
    2086          21 :     if (key)
    2087          21 :         return der_copy_octet_string(&crypto->key, key);
    2088             :     else
    2089           0 :         return 0;
    2090             : }
    2091             : 
    2092             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2093           0 : hx509_crypto_set_params(hx509_context context,
    2094             :                         hx509_crypto crypto,
    2095             :                         const heim_octet_string *param,
    2096             :                         heim_octet_string *ivec)
    2097             : {
    2098           0 :     return (*crypto->cipher->set_params)(context, param, crypto, ivec);
    2099             : }
    2100             : 
    2101             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2102          21 : hx509_crypto_get_params(hx509_context context,
    2103             :                         hx509_crypto crypto,
    2104             :                         const heim_octet_string *ivec,
    2105             :                         heim_octet_string *param)
    2106             : {
    2107          21 :     return (*crypto->cipher->get_params)(context, crypto, ivec, param);
    2108             : }
    2109             : 
    2110             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2111          21 : hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
    2112             : {
    2113          21 :     ivec->length = EVP_CIPHER_iv_length(crypto->c);
    2114          21 :     ivec->data = malloc(ivec->length);
    2115          21 :     if (ivec->data == NULL) {
    2116           0 :         ivec->length = 0;
    2117           0 :         return ENOMEM;
    2118             :     }
    2119             : 
    2120          21 :     if (RAND_bytes(ivec->data, ivec->length) <= 0) {
    2121           0 :         free(ivec->data);
    2122           0 :         ivec->data = NULL;
    2123           0 :         ivec->length = 0;
    2124           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2125             :     }
    2126          21 :     return 0;
    2127             : }
    2128             : 
    2129             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2130          21 : hx509_crypto_encrypt(hx509_crypto crypto,
    2131             :                      const void *data,
    2132             :                      const size_t length,
    2133             :                      const heim_octet_string *ivec,
    2134             :                      heim_octet_string **ciphertext)
    2135             : {
    2136           0 :     EVP_CIPHER_CTX evp;
    2137           0 :     size_t padsize, bsize;
    2138           0 :     int ret;
    2139             : 
    2140          21 :     *ciphertext = NULL;
    2141             : 
    2142          21 :     if ((crypto->cipher->flags & CIPHER_WEAK) &&
    2143           0 :         (crypto->flags & ALLOW_WEAK) == 0)
    2144           0 :         return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
    2145             : 
    2146          21 :     assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
    2147             : 
    2148          21 :     EVP_CIPHER_CTX_init(&evp);
    2149             : 
    2150          21 :     ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
    2151          21 :                             crypto->key.data, ivec->data, 1);
    2152          21 :     if (ret != 1) {
    2153           0 :         EVP_CIPHER_CTX_cleanup(&evp);
    2154           0 :         ret = HX509_CRYPTO_INTERNAL_ERROR;
    2155           0 :         goto out;
    2156             :     }
    2157             : 
    2158          21 :     *ciphertext = calloc(1, sizeof(**ciphertext));
    2159          21 :     if (*ciphertext == NULL) {
    2160           0 :         ret = ENOMEM;
    2161           0 :         goto out;
    2162             :     }
    2163             : 
    2164          21 :     assert(crypto->flags & PADDING_FLAGS);
    2165             : 
    2166          21 :     bsize = EVP_CIPHER_block_size(crypto->c);
    2167          21 :     padsize = 0;
    2168             : 
    2169          21 :     if (crypto->flags & PADDING_NONE) {
    2170           0 :         if (bsize != 1 && (length % bsize) != 0)
    2171           0 :             return HX509_CMS_PADDING_ERROR;
    2172          21 :     } else if (crypto->flags & PADDING_PKCS7) {
    2173          21 :         if (bsize != 1)
    2174          21 :             padsize = bsize - (length % bsize);
    2175             :     }
    2176             : 
    2177          21 :     (*ciphertext)->length = length + padsize;
    2178          21 :     (*ciphertext)->data = malloc(length + padsize);
    2179          21 :     if ((*ciphertext)->data == NULL) {
    2180           0 :         ret = ENOMEM;
    2181           0 :         goto out;
    2182             :     }
    2183             : 
    2184          21 :     memcpy((*ciphertext)->data, data, length);
    2185          21 :     if (padsize) {
    2186           0 :         size_t i;
    2187          21 :         unsigned char *p = (*ciphertext)->data;
    2188          21 :         p += length;
    2189         137 :         for (i = 0; i < padsize; i++)
    2190         116 :             *p++ = padsize;
    2191             :     }
    2192             : 
    2193          21 :     ret = EVP_Cipher(&evp, (*ciphertext)->data,
    2194          21 :                      (*ciphertext)->data,
    2195             :                      length + padsize);
    2196          21 :     if (ret != 1) {
    2197           0 :         ret = HX509_CRYPTO_INTERNAL_ERROR;
    2198           0 :         goto out;
    2199             :     }
    2200          21 :     ret = 0;
    2201             : 
    2202          21 :  out:
    2203          21 :     if (ret) {
    2204           0 :         if (*ciphertext) {
    2205           0 :             if ((*ciphertext)->data) {
    2206           0 :                 free((*ciphertext)->data);
    2207             :             }
    2208           0 :             free(*ciphertext);
    2209           0 :             *ciphertext = NULL;
    2210             :         }
    2211             :     }
    2212          21 :     EVP_CIPHER_CTX_cleanup(&evp);
    2213             : 
    2214          21 :     return ret;
    2215             : }
    2216             : 
    2217             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2218           0 : hx509_crypto_decrypt(hx509_crypto crypto,
    2219             :                      const void *data,
    2220             :                      const size_t length,
    2221             :                      heim_octet_string *ivec,
    2222             :                      heim_octet_string *clear)
    2223             : {
    2224           0 :     EVP_CIPHER_CTX evp;
    2225           0 :     void *idata = NULL;
    2226           0 :     int ret;
    2227             : 
    2228           0 :     clear->data = NULL;
    2229           0 :     clear->length = 0;
    2230             : 
    2231           0 :     if ((crypto->cipher->flags & CIPHER_WEAK) &&
    2232           0 :         (crypto->flags & ALLOW_WEAK) == 0)
    2233           0 :         return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
    2234             : 
    2235           0 :     if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length)
    2236           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2237             : 
    2238           0 :     if (crypto->key.data == NULL)
    2239           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2240             : 
    2241           0 :     if (ivec)
    2242           0 :         idata = ivec->data;
    2243             : 
    2244           0 :     EVP_CIPHER_CTX_init(&evp);
    2245             : 
    2246           0 :     ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
    2247           0 :                             crypto->key.data, idata, 0);
    2248           0 :     if (ret != 1) {
    2249           0 :         EVP_CIPHER_CTX_cleanup(&evp);
    2250           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2251             :     }
    2252             : 
    2253           0 :     clear->length = length;
    2254           0 :     clear->data = malloc(length);
    2255           0 :     if (clear->data == NULL) {
    2256           0 :         EVP_CIPHER_CTX_cleanup(&evp);
    2257           0 :         clear->length = 0;
    2258           0 :         return ENOMEM;
    2259             :     }
    2260             : 
    2261           0 :     if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
    2262           0 :         return HX509_CRYPTO_INTERNAL_ERROR;
    2263             :     }
    2264           0 :     EVP_CIPHER_CTX_cleanup(&evp);
    2265             : 
    2266           0 :     if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
    2267           0 :         int padsize;
    2268           0 :         unsigned char *p;
    2269           0 :         int j, bsize = EVP_CIPHER_block_size(crypto->c);
    2270             : 
    2271           0 :         if ((int)clear->length < bsize) {
    2272           0 :             ret = HX509_CMS_PADDING_ERROR;
    2273           0 :             goto out;
    2274             :         }
    2275             : 
    2276           0 :         p = clear->data;
    2277           0 :         p += clear->length - 1;
    2278           0 :         padsize = *p;
    2279           0 :         if (padsize > bsize) {
    2280           0 :             ret = HX509_CMS_PADDING_ERROR;
    2281           0 :             goto out;
    2282             :         }
    2283           0 :         clear->length -= padsize;
    2284           0 :         for (j = 0; j < padsize; j++) {
    2285           0 :             if (*p-- != padsize) {
    2286           0 :                 ret = HX509_CMS_PADDING_ERROR;
    2287           0 :                 goto out;
    2288             :             }
    2289             :         }
    2290             :     }
    2291             : 
    2292           0 :     return 0;
    2293             : 
    2294           0 :  out:
    2295           0 :     if (clear->data)
    2296           0 :         free(clear->data);
    2297           0 :     clear->data = NULL;
    2298           0 :     clear->length = 0;
    2299           0 :     return ret;
    2300             : }
    2301             : 
    2302             : typedef int (*PBE_string2key_func)(hx509_context,
    2303             :                                    const char *,
    2304             :                                    const heim_octet_string *,
    2305             :                                    hx509_crypto *, heim_octet_string *,
    2306             :                                    heim_octet_string *,
    2307             :                                    const heim_oid *, const EVP_MD *);
    2308             : 
    2309             : static int
    2310           0 : PBE_string2key(hx509_context context,
    2311             :                const char *password,
    2312             :                const heim_octet_string *parameters,
    2313             :                hx509_crypto *crypto,
    2314             :                heim_octet_string *key, heim_octet_string *iv,
    2315             :                const heim_oid *enc_oid,
    2316             :                const EVP_MD *md)
    2317             : {
    2318           0 :     PKCS12_PBEParams p12params;
    2319           0 :     int passwordlen;
    2320           0 :     hx509_crypto c;
    2321           0 :     int iter, saltlen, ret;
    2322           0 :     unsigned char *salt;
    2323             : 
    2324           0 :     passwordlen = password ? strlen(password) : 0;
    2325             : 
    2326           0 :     if (parameters == NULL)
    2327           0 :         return HX509_ALG_NOT_SUPP;
    2328             : 
    2329           0 :     ret = decode_PKCS12_PBEParams(parameters->data,
    2330           0 :                                   parameters->length,
    2331             :                                   &p12params, NULL);
    2332           0 :     if (ret)
    2333           0 :         goto out;
    2334             : 
    2335           0 :     if (p12params.iterations)
    2336           0 :         iter = *p12params.iterations;
    2337             :     else
    2338           0 :         iter = 1;
    2339           0 :     salt = p12params.salt.data;
    2340           0 :     saltlen = p12params.salt.length;
    2341             : 
    2342           0 :     if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
    2343             :                          PKCS12_KEY_ID, iter, key->length, key->data, md)) {
    2344           0 :         ret = HX509_CRYPTO_INTERNAL_ERROR;
    2345           0 :         goto out;
    2346             :     }
    2347             : 
    2348           0 :     if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
    2349             :                          PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
    2350           0 :         ret = HX509_CRYPTO_INTERNAL_ERROR;
    2351           0 :         goto out;
    2352             :     }
    2353             : 
    2354           0 :     ret = hx509_crypto_init(context, NULL, enc_oid, &c);
    2355           0 :     if (ret)
    2356           0 :         goto out;
    2357             : 
    2358           0 :     hx509_crypto_allow_weak(c);
    2359             : 
    2360           0 :     ret = hx509_crypto_set_key_data(c, key->data, key->length);
    2361           0 :     if (ret) {
    2362           0 :         hx509_crypto_destroy(c);
    2363           0 :         goto out;
    2364             :     }
    2365             : 
    2366           0 :     *crypto = c;
    2367           0 : out:
    2368           0 :     free_PKCS12_PBEParams(&p12params);
    2369           0 :     return ret;
    2370             : }
    2371             : 
    2372             : static const heim_oid *
    2373           0 : find_string2key(const heim_oid *oid,
    2374             :                 const EVP_CIPHER **c,
    2375             :                 const EVP_MD **md,
    2376             :                 PBE_string2key_func *s2k)
    2377             : {
    2378           0 :     if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
    2379           0 :         *c = EVP_rc2_40_cbc();
    2380           0 :         if (*c == NULL)
    2381           0 :             return NULL;
    2382           0 :         *md = EVP_sha1();
    2383           0 :         if (*md == NULL)
    2384           0 :             return NULL;
    2385           0 :         *s2k = PBE_string2key;
    2386           0 :         return &asn1_oid_private_rc2_40;
    2387           0 :     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
    2388           0 :         *c = EVP_rc2_cbc();
    2389           0 :         if (*c == NULL)
    2390           0 :             return NULL;
    2391           0 :         *md = EVP_sha1();
    2392           0 :         if (*md == NULL)
    2393           0 :             return NULL;
    2394           0 :         *s2k = PBE_string2key;
    2395           0 :         return ASN1_OID_ID_PKCS3_RC2_CBC;
    2396             : #if 0
    2397             :     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
    2398             :         *c = EVP_rc4_40();
    2399             :         if (*c == NULL)
    2400             :             return NULL;
    2401             :         *md = EVP_sha1();
    2402             :         if (*md == NULL)
    2403             :             return NULL;
    2404             :         *s2k = PBE_string2key;
    2405             :         return NULL;
    2406             :     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
    2407             :         *c = EVP_rc4();
    2408             :         if (*c == NULL)
    2409             :             return NULL;
    2410             :         *md = EVP_sha1();
    2411             :         if (*md == NULL)
    2412             :             return NULL;
    2413             :         *s2k = PBE_string2key;
    2414             :         return ASN1_OID_ID_PKCS3_RC4;
    2415             : #endif
    2416           0 :     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
    2417           0 :         *c = EVP_des_ede3_cbc();
    2418           0 :         if (*c == NULL)
    2419           0 :             return NULL;
    2420           0 :         *md = EVP_sha1();
    2421           0 :         if (*md == NULL)
    2422           0 :             return NULL;
    2423           0 :         *s2k = PBE_string2key;
    2424           0 :         return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
    2425             :     }
    2426             : 
    2427           0 :     return NULL;
    2428             : }
    2429             : 
    2430             : /*
    2431             :  *
    2432             :  */
    2433             : 
    2434             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2435           0 : _hx509_pbe_encrypt(hx509_context context,
    2436             :                    hx509_lock lock,
    2437             :                    const AlgorithmIdentifier *ai,
    2438             :                    const heim_octet_string *content,
    2439             :                    heim_octet_string *econtent)
    2440             : {
    2441           0 :     hx509_clear_error_string(context);
    2442           0 :     return EINVAL;
    2443             : }
    2444             : 
    2445             : /*
    2446             :  *
    2447             :  */
    2448             : 
    2449             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2450           0 : _hx509_pbe_decrypt(hx509_context context,
    2451             :                    hx509_lock lock,
    2452             :                    const AlgorithmIdentifier *ai,
    2453             :                    const heim_octet_string *econtent,
    2454             :                    heim_octet_string *content)
    2455             : {
    2456           0 :     const struct _hx509_password *pw;
    2457           0 :     heim_octet_string key, iv;
    2458           0 :     const heim_oid *enc_oid;
    2459           0 :     const EVP_CIPHER *c;
    2460           0 :     const EVP_MD *md;
    2461           0 :     PBE_string2key_func s2k;
    2462           0 :     int ret = 0;
    2463           0 :     size_t i;
    2464             : 
    2465           0 :     memset(&key, 0, sizeof(key));
    2466           0 :     memset(&iv, 0, sizeof(iv));
    2467             : 
    2468           0 :     memset(content, 0, sizeof(*content));
    2469             : 
    2470           0 :     enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
    2471           0 :     if (enc_oid == NULL) {
    2472           0 :         hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
    2473             :                                "String to key algorithm not supported");
    2474           0 :         ret = HX509_ALG_NOT_SUPP;
    2475           0 :         goto out;
    2476             :     }
    2477             : 
    2478           0 :     key.length = EVP_CIPHER_key_length(c);
    2479           0 :     key.data = malloc(key.length);
    2480           0 :     if (key.data == NULL) {
    2481           0 :         ret = ENOMEM;
    2482           0 :         hx509_clear_error_string(context);
    2483           0 :         goto out;
    2484             :     }
    2485             : 
    2486           0 :     iv.length = EVP_CIPHER_iv_length(c);
    2487           0 :     iv.data = malloc(iv.length);
    2488           0 :     if (iv.data == NULL) {
    2489           0 :         ret = ENOMEM;
    2490           0 :         hx509_clear_error_string(context);
    2491           0 :         goto out;
    2492             :     }
    2493             : 
    2494           0 :     pw = _hx509_lock_get_passwords(lock);
    2495             : 
    2496           0 :     ret = HX509_CRYPTO_INTERNAL_ERROR;
    2497           0 :     for (i = 0; i < pw->len + 1; i++) {
    2498           0 :         hx509_crypto crypto;
    2499           0 :         const char *password;
    2500             : 
    2501           0 :         if (i < pw->len)
    2502           0 :             password = pw->val[i];
    2503           0 :         else if (i < pw->len + 1)
    2504           0 :             password = "";
    2505             :         else
    2506           0 :             password = NULL;
    2507             : 
    2508           0 :         ret = (*s2k)(context, password, ai->parameters, &crypto,
    2509             :                      &key, &iv, enc_oid, md);
    2510           0 :         if (ret)
    2511           0 :             goto out;
    2512             : 
    2513           0 :         ret = hx509_crypto_decrypt(crypto,
    2514           0 :                                    econtent->data,
    2515           0 :                                    econtent->length,
    2516             :                                    &iv,
    2517             :                                    content);
    2518           0 :         hx509_crypto_destroy(crypto);
    2519           0 :         if (ret == 0)
    2520           0 :             goto out;
    2521             : 
    2522             :     }
    2523           0 : out:
    2524           0 :     if (key.data)
    2525           0 :         der_free_octet_string(&key);
    2526           0 :     if (iv.data)
    2527           0 :         der_free_octet_string(&iv);
    2528           0 :     return ret;
    2529             : }
    2530             : 
    2531             : /*
    2532             :  *
    2533             :  */
    2534             : 
    2535             : 
    2536             : static int
    2537          74 : match_keys_rsa(hx509_cert c, hx509_private_key private_key)
    2538             : {
    2539           8 :     const Certificate *cert;
    2540           8 :     const SubjectPublicKeyInfo *spi;
    2541           8 :     RSAPublicKey pk;
    2542           8 :     RSA *rsa;
    2543           8 :     size_t size;
    2544           8 :     int ret;
    2545             : 
    2546          74 :     if (private_key->private_key.rsa == NULL)
    2547           0 :         return 0;
    2548             : 
    2549          74 :     rsa = private_key->private_key.rsa;
    2550          74 :     if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
    2551           0 :         return 0;
    2552             : 
    2553          74 :     cert = _hx509_get_cert(c);
    2554          74 :     spi = &cert->tbsCertificate.subjectPublicKeyInfo;
    2555             : 
    2556          74 :     rsa = RSA_new();
    2557          74 :     if (rsa == NULL)
    2558           0 :         return 0;
    2559             : 
    2560          82 :     ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
    2561          74 :                               spi->subjectPublicKey.length / 8,
    2562             :                               &pk, &size);
    2563          74 :     if (ret) {
    2564           0 :         RSA_free(rsa);
    2565           0 :         return 0;
    2566             :     }
    2567          74 :     rsa->n = heim_int2BN(&pk.modulus);
    2568          74 :     rsa->e = heim_int2BN(&pk.publicExponent);
    2569             : 
    2570          74 :     free_RSAPublicKey(&pk);
    2571             : 
    2572          74 :     rsa->d = BN_dup(private_key->private_key.rsa->d);
    2573          74 :     rsa->p = BN_dup(private_key->private_key.rsa->p);
    2574          74 :     rsa->q = BN_dup(private_key->private_key.rsa->q);
    2575          74 :     rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
    2576          74 :     rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
    2577          74 :     rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
    2578             : 
    2579          74 :     if (rsa->n == NULL || rsa->e == NULL ||
    2580          74 :         rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
    2581          74 :         rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
    2582           0 :         RSA_free(rsa);
    2583           0 :         return 0;
    2584             :     }
    2585             : 
    2586          74 :     ret = RSA_check_key(rsa);
    2587          74 :     RSA_free(rsa);
    2588             : 
    2589          74 :     return ret == 1;
    2590             : }
    2591             : 
    2592             : static int
    2593           0 : match_keys_ec(hx509_cert c, hx509_private_key private_key)
    2594             : {
    2595           0 :     return 1; /* XXX use EC_KEY_check_key */
    2596             : }
    2597             : 
    2598             : 
    2599             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2600          74 : _hx509_match_keys(hx509_cert c, hx509_private_key key)
    2601             : {
    2602          74 :     if (!key->ops)
    2603           0 :         return 0;
    2604          74 :     if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
    2605          74 :         return match_keys_rsa(c, key);
    2606           0 :     if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
    2607           0 :         return match_keys_ec(c, key);
    2608           0 :     return 0;
    2609             : 
    2610             : }
    2611             : 
    2612             : 
    2613             : static const heim_oid *
    2614         102 : find_keytype(const hx509_private_key key)
    2615             : {
    2616           0 :     const struct signature_alg *md;
    2617             : 
    2618         102 :     if (key == NULL)
    2619           0 :         return NULL;
    2620             : 
    2621         102 :     md = _hx509_find_sig_alg(key->signature_alg);
    2622         102 :     if (md == NULL)
    2623           0 :         return NULL;
    2624         102 :     return md->key_oid;
    2625             : }
    2626             : 
    2627             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2628         130 : hx509_crypto_select(const hx509_context context,
    2629             :                     int type,
    2630             :                     const hx509_private_key source,
    2631             :                     hx509_peer_info peer,
    2632             :                     AlgorithmIdentifier *selected)
    2633             : {
    2634         130 :     const AlgorithmIdentifier *def = NULL;
    2635           0 :     size_t i, j;
    2636           0 :     int ret, bits;
    2637             : 
    2638         130 :     memset(selected, 0, sizeof(*selected));
    2639             : 
    2640         130 :     if (type == HX509_SELECT_DIGEST) {
    2641          65 :         bits = SIG_DIGEST;
    2642          65 :         if (source)
    2643          65 :             def = alg_for_privatekey(source, type);
    2644          65 :         if (def == NULL)
    2645           0 :             def = _hx509_crypto_default_digest_alg;
    2646          65 :     } else if (type == HX509_SELECT_PUBLIC_SIG) {
    2647          65 :         bits = SIG_PUBLIC_SIG;
    2648             :         /* XXX depend on `source´ and `peer´ */
    2649          65 :         if (source)
    2650          65 :             def = alg_for_privatekey(source, type);
    2651          65 :         if (def == NULL)
    2652           0 :             def = _hx509_crypto_default_sig_alg;
    2653           0 :     } else if (type == HX509_SELECT_SECRET_ENC) {
    2654           0 :         bits = SIG_SECRET;
    2655           0 :         def = _hx509_crypto_default_secret_alg;
    2656             :     } else {
    2657           0 :         hx509_set_error_string(context, 0, EINVAL,
    2658             :                                "Unknown type %d of selection", type);
    2659           0 :         return EINVAL;
    2660             :     }
    2661             : 
    2662         130 :     if (peer) {
    2663          82 :         const heim_oid *keytype = NULL;
    2664             : 
    2665          82 :         keytype = find_keytype(source);
    2666             : 
    2667         222 :         for (i = 0; i < peer->len; i++) {
    2668        2383 :             for (j = 0; sig_algs[j]; j++) {
    2669        2243 :                 if ((sig_algs[j]->flags & bits) != bits)
    2670        1397 :                     continue;
    2671         846 :                 if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
    2672         846 :                                      &peer->val[i].algorithm) != 0)
    2673         788 :                     continue;
    2674          99 :                 if (keytype && sig_algs[j]->key_oid &&
    2675          41 :                     der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
    2676           0 :                     continue;
    2677             : 
    2678             :                 /* found one, use that */
    2679          58 :                 ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
    2680          58 :                 if (ret)
    2681           0 :                     hx509_clear_error_string(context);
    2682          58 :                 return ret;
    2683             :             }
    2684         140 :             if (bits & SIG_SECRET) {
    2685           0 :                 const struct hx509cipher *cipher;
    2686             : 
    2687           0 :                 cipher = find_cipher_by_oid(&peer->val[i].algorithm);
    2688           0 :                 if (cipher == NULL)
    2689           0 :                     continue;
    2690           0 :                 if (cipher->ai_func == NULL)
    2691           0 :                     continue;
    2692           0 :                 ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
    2693           0 :                 if (ret)
    2694           0 :                     hx509_clear_error_string(context);
    2695           0 :                 return ret;
    2696             :             }
    2697             :         }
    2698             :     }
    2699             : 
    2700             :     /* use default */
    2701          72 :     ret = copy_AlgorithmIdentifier(def, selected);
    2702          72 :     if (ret)
    2703           0 :         hx509_clear_error_string(context);
    2704          72 :     return ret;
    2705             : }
    2706             : 
    2707             : HX509_LIB_FUNCTION int HX509_LIB_CALL
    2708         124 : hx509_crypto_available(hx509_context context,
    2709             :                        int type,
    2710             :                        hx509_cert source,
    2711             :                        AlgorithmIdentifier **val,
    2712             :                        unsigned int *plen)
    2713             : {
    2714         124 :     const heim_oid *keytype = NULL;
    2715           0 :     unsigned int len, i;
    2716           0 :     void *ptr;
    2717           0 :     int bits, ret;
    2718             : 
    2719         124 :     *val = NULL;
    2720             : 
    2721         124 :     if (type == HX509_SELECT_ALL) {
    2722         124 :         bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
    2723           0 :     } else if (type == HX509_SELECT_DIGEST) {
    2724           0 :         bits = SIG_DIGEST;
    2725           0 :     } else if (type == HX509_SELECT_PUBLIC_SIG) {
    2726           0 :         bits = SIG_PUBLIC_SIG;
    2727             :     } else {
    2728           0 :         hx509_set_error_string(context, 0, EINVAL,
    2729             :                                "Unknown type %d of available", type);
    2730           0 :         return EINVAL;
    2731             :     }
    2732             : 
    2733         124 :     if (source)
    2734          20 :         keytype = find_keytype(_hx509_cert_private_key(source));
    2735             : 
    2736         124 :     len = 0;
    2737        1860 :     for (i = 0; sig_algs[i]; i++) {
    2738        1736 :         if ((sig_algs[i]->flags & bits) == 0)
    2739           0 :             continue;
    2740        1736 :         if (sig_algs[i]->sig_alg == NULL)
    2741         124 :             continue;
    2742        1772 :         if (keytype && sig_algs[i]->key_oid &&
    2743         160 :             der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
    2744           0 :             continue;
    2745             : 
    2746             :         /* found one, add that to the list */
    2747        1612 :         ptr = realloc(*val, sizeof(**val) * (len + 1));
    2748        1612 :         if (ptr == NULL)
    2749           0 :             goto out;
    2750        1612 :         *val = ptr;
    2751             : 
    2752        1612 :         ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
    2753        1612 :         if (ret)
    2754           0 :             goto out;
    2755        1612 :         len++;
    2756             :     }
    2757             : 
    2758             :     /* Add AES */
    2759         124 :     if (bits & SIG_SECRET) {
    2760             : 
    2761        1116 :         for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
    2762             : 
    2763         992 :             if (ciphers[i].flags & CIPHER_WEAK)
    2764         372 :                 continue;
    2765         620 :             if (ciphers[i].ai_func == NULL)
    2766         248 :                 continue;
    2767             : 
    2768         372 :             ptr = realloc(*val, sizeof(**val) * (len + 1));
    2769         372 :             if (ptr == NULL)
    2770           0 :                 goto out;
    2771         372 :             *val = ptr;
    2772             : 
    2773         372 :             ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
    2774         372 :             if (ret)
    2775           0 :                 goto out;
    2776         372 :             len++;
    2777             :         }
    2778             :     }
    2779             : 
    2780         124 :     *plen = len;
    2781         124 :     return 0;
    2782             : 
    2783           0 : out:
    2784           0 :     for (i = 0; i < len; i++)
    2785           0 :         free_AlgorithmIdentifier(&(*val)[i]);
    2786           0 :     free(*val);
    2787           0 :     *val = NULL;
    2788           0 :     hx509_set_error_string(context, 0, ENOMEM, "out of memory");
    2789           0 :     return ENOMEM;
    2790             : }
    2791             : 
    2792             : HX509_LIB_FUNCTION void HX509_LIB_CALL
    2793           0 : hx509_crypto_free_algs(AlgorithmIdentifier *val,
    2794             :                        unsigned int len)
    2795             : {
    2796           0 :     unsigned int i;
    2797           0 :     for (i = 0; i < len; i++)
    2798           0 :         free_AlgorithmIdentifier(&val[i]);
    2799           0 :     free(val);
    2800           0 : }

Generated by: LCOV version 1.14