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