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