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