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