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