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