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