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