remove unused type
[heimdal.git] / lib / hx509 / crypto.c
blobf4667c6e31596d3a61ba2de4b22fe47700a239b7
1 /*
2 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include "hx_locl.h"
36 struct hx509_crypto;
38 struct signature_alg;
40 struct hx509_generate_private_context {
41 const heim_oid *key_oid;
42 int isCA;
43 unsigned long num_bits;
46 struct hx509_private_key_ops {
47 const char *pemtype;
48 const heim_oid *key_oid;
49 int (*available)(const hx509_private_key,
50 const AlgorithmIdentifier *);
51 int (*get_spki)(hx509_context,
52 const hx509_private_key,
53 SubjectPublicKeyInfo *);
54 int (*export)(hx509_context context,
55 const hx509_private_key,
56 heim_octet_string *);
57 int (*import)(hx509_context, const AlgorithmIdentifier *,
58 const void *, size_t, hx509_private_key);
59 int (*generate_private_key)(hx509_context,
60 struct hx509_generate_private_context *,
61 hx509_private_key);
62 BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
65 struct hx509_private_key {
66 unsigned int ref;
67 const struct signature_alg *md;
68 const heim_oid *signature_alg;
69 union {
70 RSA *rsa;
71 void *keydata;
72 #ifdef HAVE_OPENSSL
73 EC_KEY *ecdsa;
74 #endif
75 } private_key;
76 hx509_private_key_ops *ops;
83 struct signature_alg {
84 const char *name;
85 const heim_oid *sig_oid;
86 const AlgorithmIdentifier *sig_alg;
87 const heim_oid *key_oid;
88 const AlgorithmIdentifier *digest_alg;
89 int flags;
90 #define PROVIDE_CONF 1
91 #define REQUIRE_SIGNER 2
93 #define SIG_DIGEST 0x100
94 #define SIG_PUBLIC_SIG 0x200
95 #define SIG_SECRET 0x400
97 #define RA_RSA_USES_DIGEST_INFO 0x1000000
99 time_t best_before; /* refuse signature made after best before date */
100 int (*verify_signature)(hx509_context context,
101 const struct signature_alg *,
102 const Certificate *,
103 const AlgorithmIdentifier *,
104 const heim_octet_string *,
105 const heim_octet_string *);
106 int (*create_signature)(hx509_context,
107 const struct signature_alg *,
108 const hx509_private_key,
109 const AlgorithmIdentifier *,
110 const heim_octet_string *,
111 AlgorithmIdentifier *,
112 heim_octet_string *);
113 int digest_size;
116 static const struct signature_alg *
117 find_sig_alg(const heim_oid *oid);
123 static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
125 static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
126 const AlgorithmIdentifier _hx509_signature_sha512_data = {
127 { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
130 static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
131 const AlgorithmIdentifier _hx509_signature_sha384_data = {
132 { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
135 static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
136 const AlgorithmIdentifier _hx509_signature_sha256_data = {
137 { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
140 static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
141 const AlgorithmIdentifier _hx509_signature_sha1_data = {
142 { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
145 static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
146 const AlgorithmIdentifier _hx509_signature_md5_data = {
147 { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
150 static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
151 const AlgorithmIdentifier _hx509_signature_md2_data = {
152 { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
155 static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
156 const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
157 { 6, rk_UNCONST(ecPublicKey) }, NULL
160 static const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 };
161 const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = {
162 { 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL
165 static const unsigned ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 };
166 const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = {
167 { 6, rk_UNCONST(ecdsa_with_sha1_oid) }, NULL
170 static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
171 const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
172 { 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL
175 static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
176 const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
177 { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
180 static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
181 const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
182 { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
185 static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
186 const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
187 { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
190 static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
191 const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
192 { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
195 static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
196 const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
197 { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
200 static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
201 const AlgorithmIdentifier _hx509_signature_rsa_data = {
202 { 7, rk_UNCONST(rsa_oid) }, NULL
205 static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
206 const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
207 { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
210 static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
211 const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
212 { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
215 static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
216 const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
217 { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
220 static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
221 const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
222 { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
229 static BIGNUM *
230 heim_int2BN(const heim_integer *i)
232 BIGNUM *bn;
234 bn = BN_bin2bn(i->data, i->length, NULL);
235 BN_set_negative(bn, i->negative);
236 return bn;
243 static int
244 set_digest_alg(DigestAlgorithmIdentifier *id,
245 const heim_oid *oid,
246 const void *param, size_t length)
248 int ret;
249 if (param) {
250 id->parameters = malloc(sizeof(*id->parameters));
251 if (id->parameters == NULL)
252 return ENOMEM;
253 id->parameters->data = malloc(length);
254 if (id->parameters->data == NULL) {
255 free(id->parameters);
256 id->parameters = NULL;
257 return ENOMEM;
259 memcpy(id->parameters->data, param, length);
260 id->parameters->length = length;
261 } else
262 id->parameters = NULL;
263 ret = der_copy_oid(oid, &id->algorithm);
264 if (ret) {
265 if (id->parameters) {
266 free(id->parameters->data);
267 free(id->parameters);
268 id->parameters = NULL;
270 return ret;
272 return 0;
275 #ifdef HAVE_OPENSSL
277 static int
278 heim_oid2ecnid(heim_oid *oid)
281 * Now map to openssl OID fun
284 if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp256r1) == 0)
285 return NID_X9_62_prime256v1;
286 else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r1) == 0)
287 return NID_secp160r1;
288 else if (der_heim_oid_cmp(oid, &asn1_oid_id_ec_group_secp160r2) == 0)
289 return NID_secp160r2;
291 return -1;
294 static int
295 parse_ECParameters(hx509_context context,
296 heim_octet_string *parameters, int *nid)
298 ECParameters ecparam;
299 size_t size;
300 int ret;
302 if (parameters == NULL) {
303 ret = HX509_PARSING_KEY_FAILED;
304 hx509_set_error_string(context, 0, ret,
305 "EC parameters missing");
306 return ret;
309 ret = decode_ECParameters(parameters->data, parameters->length,
310 &ecparam, &size);
311 if (ret) {
312 hx509_set_error_string(context, 0, ret,
313 "Failed to decode EC parameters");
314 return ret;
317 if (ecparam.element != choice_ECParameters_namedCurve) {
318 free_ECParameters(&ecparam);
319 hx509_set_error_string(context, 0, ret,
320 "EC parameters is not a named curve");
321 return HX509_CRYPTO_SIG_INVALID_FORMAT;
324 *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
325 free_ECParameters(&ecparam);
326 if (*nid == -1) {
327 hx509_set_error_string(context, 0, ret,
328 "Failed to find matcing NID for EC curve");
329 return HX509_CRYPTO_SIG_INVALID_FORMAT;
331 return 0;
339 static int
340 ecdsa_verify_signature(hx509_context context,
341 const struct signature_alg *sig_alg,
342 const Certificate *signer,
343 const AlgorithmIdentifier *alg,
344 const heim_octet_string *data,
345 const heim_octet_string *sig)
347 const AlgorithmIdentifier *digest_alg;
348 const SubjectPublicKeyInfo *spi;
349 heim_octet_string digest;
350 int ret;
351 EC_KEY *key = NULL;
352 int groupnid;
353 EC_GROUP *group;
354 const unsigned char *p;
355 long len;
357 digest_alg = sig_alg->digest_alg;
359 ret = _hx509_create_signature(context,
360 NULL,
361 digest_alg,
362 data,
363 NULL,
364 &digest);
365 if (ret)
366 return ret;
368 /* set up EC KEY */
369 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
371 if (der_heim_oid_cmp(&spi->algorithm.algorithm, &asn1_oid_id_ecPublicKey) != 0)
372 return HX509_CRYPTO_SIG_INVALID_FORMAT;
374 #ifdef HAVE_OPENSSL
376 * Find the group id
379 ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
380 if (ret) {
381 der_free_octet_string(&digest);
382 return ret;
386 * Create group, key, parse key
389 key = EC_KEY_new();
390 group = EC_GROUP_new_by_curve_name(groupnid);
391 EC_KEY_set_group(key, group);
392 EC_GROUP_free(group);
394 p = spi->subjectPublicKey.data;
395 len = spi->subjectPublicKey.length / 8;
397 if (o2i_ECPublicKey(&key, &p, len) == NULL) {
398 EC_KEY_free(key);
399 return HX509_CRYPTO_SIG_INVALID_FORMAT;
401 #else
402 key = SubjectPublicKeyInfo2EC_KEY(spi);
403 #endif
405 ret = ECDSA_verify(-1, digest.data, digest.length,
406 sig->data, sig->length, key);
407 der_free_octet_string(&digest);
408 EC_KEY_free(key);
409 if (ret != 1) {
410 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
411 return ret;
414 return 0;
417 static int
418 ecdsa_create_signature(hx509_context context,
419 const struct signature_alg *sig_alg,
420 const hx509_private_key signer,
421 const AlgorithmIdentifier *alg,
422 const heim_octet_string *data,
423 AlgorithmIdentifier *signatureAlgorithm,
424 heim_octet_string *sig)
426 const AlgorithmIdentifier *digest_alg;
427 heim_octet_string indata;
428 const heim_oid *sig_oid;
429 unsigned int siglen;
430 int ret;
432 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
433 _hx509_abort("internal error passing private key to wrong ops");
435 sig_oid = sig_alg->sig_oid;
436 digest_alg = sig_alg->digest_alg;
438 if (signatureAlgorithm) {
439 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
440 if (ret) {
441 hx509_clear_error_string(context);
442 goto error;
446 ret = _hx509_create_signature(context,
447 NULL,
448 digest_alg,
449 data,
450 NULL,
451 &indata);
452 if (ret) {
453 if (signatureAlgorithm)
454 free_AlgorithmIdentifier(signatureAlgorithm);
455 goto error;
458 sig->length = ECDSA_size(signer->private_key.ecdsa);
459 sig->data = malloc(sig->length);
460 if (sig->data == NULL) {
461 der_free_octet_string(&indata);
462 ret = ENOMEM;
463 hx509_set_error_string(context, 0, ret, "out of memory");
464 goto error;
467 siglen = sig->length;
469 ret = ECDSA_sign(-1, indata.data, indata.length,
470 sig->data, &siglen, signer->private_key.ecdsa);
471 der_free_octet_string(&indata);
472 if (ret != 1) {
473 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
474 hx509_set_error_string(context, 0, ret,
475 "ECDSA sign failed: %d", ret);
476 goto error;
478 if (siglen > sig->length)
479 _hx509_abort("ECDSA signature prelen longer the output len");
481 sig->length = siglen;
483 return 0;
484 error:
485 if (signatureAlgorithm)
486 free_AlgorithmIdentifier(signatureAlgorithm);
487 return ret;
490 static int
491 ecdsa_available(const hx509_private_key signer,
492 const AlgorithmIdentifier *sig_alg)
494 const struct signature_alg *sig;
495 const EC_GROUP *group;
496 BN_CTX *bnctx = NULL;
497 BIGNUM *order = NULL;
498 int ret = 0;
500 if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
501 _hx509_abort("internal error passing private key to wrong ops");
503 sig = find_sig_alg(&sig_alg->algorithm);
505 if (sig == NULL || sig->digest_size == 0)
506 return 0;
508 group = EC_KEY_get0_group(signer->private_key.ecdsa);
509 if (group == NULL)
510 return 0;
512 bnctx = BN_CTX_new();
513 order = BN_new();
514 if (order == NULL)
515 goto err;
517 if (EC_GROUP_get_order(group, order, bnctx) != 1)
518 goto err;
520 if (BN_num_bytes(order) > sig->digest_size)
521 ret = 1;
522 err:
523 if (bnctx)
524 BN_CTX_free(bnctx);
525 if (order)
526 BN_clear_free(order);
528 return ret;
532 #endif /* HAVE_OPENSSL */
538 static int
539 rsa_verify_signature(hx509_context context,
540 const struct signature_alg *sig_alg,
541 const Certificate *signer,
542 const AlgorithmIdentifier *alg,
543 const heim_octet_string *data,
544 const heim_octet_string *sig)
546 const SubjectPublicKeyInfo *spi;
547 DigestInfo di;
548 unsigned char *to;
549 int tosize, retsize;
550 int ret;
551 RSA *rsa;
552 RSAPublicKey pk;
553 size_t size;
555 memset(&di, 0, sizeof(di));
557 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
559 rsa = RSA_new();
560 if (rsa == NULL) {
561 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
562 return ENOMEM;
564 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
565 spi->subjectPublicKey.length / 8,
566 &pk, &size);
567 if (ret) {
568 hx509_set_error_string(context, 0, ret, "Failed to decode RSAPublicKey");
569 goto out;
572 rsa->n = heim_int2BN(&pk.modulus);
573 rsa->e = heim_int2BN(&pk.publicExponent);
575 free_RSAPublicKey(&pk);
577 if (rsa->n == NULL || rsa->e == NULL) {
578 ret = ENOMEM;
579 hx509_set_error_string(context, 0, ret, "out of memory");
580 goto out;
583 tosize = RSA_size(rsa);
584 to = malloc(tosize);
585 if (to == NULL) {
586 ret = ENOMEM;
587 hx509_set_error_string(context, 0, ret, "out of memory");
588 goto out;
591 retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
592 to, rsa, RSA_PKCS1_PADDING);
593 if (retsize <= 0) {
594 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
595 hx509_set_error_string(context, 0, ret,
596 "RSA public decrypt failed: %d", retsize);
597 free(to);
598 goto out;
600 if (retsize > tosize)
601 _hx509_abort("internal rsa decryption failure: ret > tosize");
603 if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
605 ret = decode_DigestInfo(to, retsize, &di, &size);
606 free(to);
607 if (ret) {
608 goto out;
611 /* Check for extra data inside the sigature */
612 if (size != retsize) {
613 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
614 hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
615 goto out;
618 if (sig_alg->digest_alg &&
619 der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
620 &sig_alg->digest_alg->algorithm) != 0)
622 ret = HX509_CRYPTO_OID_MISMATCH;
623 hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
624 goto out;
627 /* verify that the parameters are NULL or the NULL-type */
628 if (di.digestAlgorithm.parameters != NULL &&
629 (di.digestAlgorithm.parameters->length != 2 ||
630 memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
632 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
633 hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
634 goto out;
637 ret = _hx509_verify_signature(context,
638 NULL,
639 &di.digestAlgorithm,
640 data,
641 &di.digest);
642 } else {
643 if (retsize != data->length ||
644 memcmp(to, data->data, retsize) != 0)
646 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
647 hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
648 goto out;
650 free(to);
653 out:
654 free_DigestInfo(&di);
655 RSA_free(rsa);
656 return ret;
659 static int
660 rsa_create_signature(hx509_context context,
661 const struct signature_alg *sig_alg,
662 const hx509_private_key signer,
663 const AlgorithmIdentifier *alg,
664 const heim_octet_string *data,
665 AlgorithmIdentifier *signatureAlgorithm,
666 heim_octet_string *sig)
668 const AlgorithmIdentifier *digest_alg;
669 heim_octet_string indata;
670 const heim_oid *sig_oid;
671 size_t size;
672 int ret;
674 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0)
675 return HX509_ALG_NOT_SUPP;
677 if (alg)
678 sig_oid = &alg->algorithm;
679 else
680 sig_oid = signer->signature_alg;
682 if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha256WithRSAEncryption) == 0) {
683 digest_alg = hx509_signature_sha256();
684 } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_sha1WithRSAEncryption) == 0) {
685 digest_alg = hx509_signature_sha1();
686 } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
687 digest_alg = hx509_signature_md5();
688 } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_md5WithRSAEncryption) == 0) {
689 digest_alg = hx509_signature_md5();
690 } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_dsa_with_sha1) == 0) {
691 digest_alg = hx509_signature_sha1();
692 } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
693 digest_alg = hx509_signature_sha1();
694 } else if (der_heim_oid_cmp(sig_oid, &asn1_oid_id_heim_rsa_pkcs1_x509) == 0) {
695 digest_alg = NULL;
696 } else
697 return HX509_ALG_NOT_SUPP;
699 if (signatureAlgorithm) {
700 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
701 if (ret) {
702 hx509_clear_error_string(context);
703 return ret;
707 if (digest_alg) {
708 DigestInfo di;
709 memset(&di, 0, sizeof(di));
711 ret = _hx509_create_signature(context,
712 NULL,
713 digest_alg,
714 data,
715 &di.digestAlgorithm,
716 &di.digest);
717 if (ret)
718 return ret;
719 ASN1_MALLOC_ENCODE(DigestInfo,
720 indata.data,
721 indata.length,
722 &di,
723 &size,
724 ret);
725 free_DigestInfo(&di);
726 if (ret) {
727 hx509_set_error_string(context, 0, ret, "out of memory");
728 return ret;
730 if (indata.length != size)
731 _hx509_abort("internal ASN.1 encoder error");
732 } else {
733 indata = *data;
736 sig->length = RSA_size(signer->private_key.rsa);
737 sig->data = malloc(sig->length);
738 if (sig->data == NULL) {
739 der_free_octet_string(&indata);
740 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
741 return ENOMEM;
744 ret = RSA_private_encrypt(indata.length, indata.data,
745 sig->data,
746 signer->private_key.rsa,
747 RSA_PKCS1_PADDING);
748 if (indata.data != data->data)
749 der_free_octet_string(&indata);
750 if (ret <= 0) {
751 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
752 hx509_set_error_string(context, 0, ret,
753 "RSA private decrypt failed: %d", ret);
754 return ret;
756 if (ret > sig->length)
757 _hx509_abort("RSA signature prelen longer the output len");
759 sig->length = ret;
761 return 0;
764 static int
765 rsa_private_key_import(hx509_context context,
766 const AlgorithmIdentifier *keyai,
767 const void *data,
768 size_t len,
769 hx509_private_key private_key)
771 const unsigned char *p = data;
773 private_key->private_key.rsa =
774 d2i_RSAPrivateKey(NULL, &p, len);
775 if (private_key->private_key.rsa == NULL) {
776 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
777 "Failed to parse RSA key");
778 return HX509_PARSING_KEY_FAILED;
780 private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
782 return 0;
785 static int
786 rsa_private_key2SPKI(hx509_context context,
787 hx509_private_key private_key,
788 SubjectPublicKeyInfo *spki)
790 int len, ret;
792 memset(spki, 0, sizeof(*spki));
794 len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
796 spki->subjectPublicKey.data = malloc(len);
797 if (spki->subjectPublicKey.data == NULL) {
798 hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
799 return ENOMEM;
801 spki->subjectPublicKey.length = len * 8;
803 ret = set_digest_alg(&spki->algorithm, &asn1_oid_id_pkcs1_rsaEncryption,
804 "\x05\x00", 2);
805 if (ret) {
806 hx509_set_error_string(context, 0, ret, "malloc - out of memory");
807 free(spki->subjectPublicKey.data);
808 spki->subjectPublicKey.data = NULL;
809 spki->subjectPublicKey.length = 0;
810 return ret;
814 unsigned char *pp = spki->subjectPublicKey.data;
815 i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
818 return 0;
821 static int
822 rsa_generate_private_key(hx509_context context,
823 struct hx509_generate_private_context *ctx,
824 hx509_private_key private_key)
826 BIGNUM *e;
827 int ret;
828 unsigned long bits;
830 static const int default_rsa_e = 65537;
831 static const int default_rsa_bits = 1024;
833 private_key->private_key.rsa = RSA_new();
834 if (private_key->private_key.rsa == NULL) {
835 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
836 "Failed to generate RSA key");
837 return HX509_PARSING_KEY_FAILED;
840 e = BN_new();
841 BN_set_word(e, default_rsa_e);
843 bits = default_rsa_bits;
845 if (ctx->num_bits)
846 bits = ctx->num_bits;
847 else if (ctx->isCA)
848 bits *= 2;
850 ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
851 BN_free(e);
852 if (ret != 1) {
853 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
854 "Failed to generate RSA key");
855 return HX509_PARSING_KEY_FAILED;
857 private_key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
859 return 0;
862 static int
863 rsa_private_key_export(hx509_context context,
864 const hx509_private_key key,
865 heim_octet_string *data)
867 int ret;
869 data->data = NULL;
870 data->length = 0;
872 ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
873 if (ret <= 0) {
874 ret = EINVAL;
875 hx509_set_error_string(context, 0, ret,
876 "Private key is not exportable");
877 return ret;
880 data->data = malloc(ret);
881 if (data->data == NULL) {
882 ret = ENOMEM;
883 hx509_set_error_string(context, 0, ret, "malloc out of memory");
884 return ret;
886 data->length = ret;
889 unsigned char *p = data->data;
890 i2d_RSAPrivateKey(key->private_key.rsa, &p);
893 return 0;
896 static BIGNUM *
897 rsa_get_internal(hx509_context context,
898 hx509_private_key key,
899 const char *type)
901 if (strcasecmp(type, "rsa-modulus") == 0) {
902 return BN_dup(key->private_key.rsa->n);
903 } else if (strcasecmp(type, "rsa-exponent") == 0) {
904 return BN_dup(key->private_key.rsa->e);
905 } else
906 return NULL;
911 static hx509_private_key_ops rsa_private_key_ops = {
912 "RSA PRIVATE KEY",
913 &asn1_oid_id_pkcs1_rsaEncryption,
914 NULL,
915 rsa_private_key2SPKI,
916 rsa_private_key_export,
917 rsa_private_key_import,
918 rsa_generate_private_key,
919 rsa_get_internal
922 #ifdef HAVE_OPENSSL
924 static int
925 ecdsa_private_key2SPKI(hx509_context context,
926 hx509_private_key private_key,
927 SubjectPublicKeyInfo *spki)
929 memset(spki, 0, sizeof(*spki));
930 return ENOMEM;
933 static int
934 ecdsa_private_key_export(hx509_context context,
935 const hx509_private_key key,
936 heim_octet_string *data)
938 return ENOMEM;
941 static int
942 ecdsa_private_key_import(hx509_context context,
943 const AlgorithmIdentifier *keyai,
944 const void *data,
945 size_t len,
946 hx509_private_key private_key)
948 const unsigned char *p = data;
949 EC_KEY **pkey = NULL;
951 if (keyai->parameters) {
952 EC_GROUP *group;
953 int groupnid;
954 EC_KEY *key;
955 int ret;
957 ret = parse_ECParameters(context, keyai->parameters, &groupnid);
958 if (ret)
959 return ret;
961 key = EC_KEY_new();
962 if (key == NULL)
963 return ENOMEM;
965 group = EC_GROUP_new_by_curve_name(groupnid);
966 if (group == NULL) {
967 EC_KEY_free(key);
968 return ENOMEM;
970 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
971 if (EC_KEY_set_group(key, group) == 0) {
972 EC_KEY_free(key);
973 EC_GROUP_free(group);
974 return ENOMEM;
976 EC_GROUP_free(group);
977 pkey = &key;
980 private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
981 if (private_key->private_key.ecdsa == NULL) {
982 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
983 "Failed to parse EC private key");
984 return HX509_PARSING_KEY_FAILED;
986 private_key->signature_alg = &asn1_oid_id_ecdsa_with_SHA256;
988 return 0;
991 static int
992 ecdsa_generate_private_key(hx509_context context,
993 struct hx509_generate_private_context *ctx,
994 hx509_private_key private_key)
996 return ENOMEM;
999 static BIGNUM *
1000 ecdsa_get_internal(hx509_context context,
1001 hx509_private_key key,
1002 const char *type)
1004 return NULL;
1008 static hx509_private_key_ops ecdsa_private_key_ops = {
1009 "EC PRIVATE KEY",
1010 &asn1_oid_id_ecPublicKey,
1011 ecdsa_available,
1012 ecdsa_private_key2SPKI,
1013 ecdsa_private_key_export,
1014 ecdsa_private_key_import,
1015 ecdsa_generate_private_key,
1016 ecdsa_get_internal
1019 #endif /* HAVE_OPENSSL */
1025 static int
1026 dsa_verify_signature(hx509_context context,
1027 const struct signature_alg *sig_alg,
1028 const Certificate *signer,
1029 const AlgorithmIdentifier *alg,
1030 const heim_octet_string *data,
1031 const heim_octet_string *sig)
1033 const SubjectPublicKeyInfo *spi;
1034 DSAPublicKey pk;
1035 DSAParams param;
1036 size_t size;
1037 DSA *dsa;
1038 int ret;
1040 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1042 dsa = DSA_new();
1043 if (dsa == NULL) {
1044 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1045 return ENOMEM;
1048 ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
1049 spi->subjectPublicKey.length / 8,
1050 &pk, &size);
1051 if (ret)
1052 goto out;
1054 dsa->pub_key = heim_int2BN(&pk);
1056 free_DSAPublicKey(&pk);
1058 if (dsa->pub_key == NULL) {
1059 ret = ENOMEM;
1060 hx509_set_error_string(context, 0, ret, "out of memory");
1061 goto out;
1064 if (spi->algorithm.parameters == NULL) {
1065 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
1066 hx509_set_error_string(context, 0, ret, "DSA parameters missing");
1067 goto out;
1070 ret = decode_DSAParams(spi->algorithm.parameters->data,
1071 spi->algorithm.parameters->length,
1072 &param,
1073 &size);
1074 if (ret) {
1075 hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
1076 goto out;
1079 dsa->p = heim_int2BN(&param.p);
1080 dsa->q = heim_int2BN(&param.q);
1081 dsa->g = heim_int2BN(&param.g);
1083 free_DSAParams(&param);
1085 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
1086 ret = ENOMEM;
1087 hx509_set_error_string(context, 0, ret, "out of memory");
1088 goto out;
1091 ret = DSA_verify(-1, data->data, data->length,
1092 (unsigned char*)sig->data, sig->length,
1093 dsa);
1094 if (ret == 1)
1095 ret = 0;
1096 else if (ret == 0 || ret == -1) {
1097 ret = HX509_CRYPTO_BAD_SIGNATURE;
1098 hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
1099 } else {
1100 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
1101 hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
1104 out:
1105 DSA_free(dsa);
1107 return ret;
1110 #if 0
1111 static int
1112 dsa_parse_private_key(hx509_context context,
1113 const void *data,
1114 size_t len,
1115 hx509_private_key private_key)
1117 const unsigned char *p = data;
1119 private_key->private_key.dsa =
1120 d2i_DSAPrivateKey(NULL, &p, len);
1121 if (private_key->private_key.dsa == NULL)
1122 return EINVAL;
1123 private_key->signature_alg = &asn1_oid_id_dsa_with_sha1;
1125 return 0;
1126 /* else */
1127 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1128 "No support to parse DSA keys");
1129 return HX509_PARSING_KEY_FAILED;
1131 #endif
1134 static int
1135 sha1_verify_signature(hx509_context context,
1136 const struct signature_alg *sig_alg,
1137 const Certificate *signer,
1138 const AlgorithmIdentifier *alg,
1139 const heim_octet_string *data,
1140 const heim_octet_string *sig)
1142 unsigned char digest[SHA_DIGEST_LENGTH];
1143 SHA_CTX m;
1145 if (sig->length != SHA_DIGEST_LENGTH) {
1146 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1147 "SHA1 sigature have wrong length");
1148 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1151 SHA1_Init(&m);
1152 SHA1_Update(&m, data->data, data->length);
1153 SHA1_Final (digest, &m);
1155 if (memcmp(digest, sig->data, SHA_DIGEST_LENGTH) != 0) {
1156 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
1157 "Bad SHA1 sigature");
1158 return HX509_CRYPTO_BAD_SIGNATURE;
1161 return 0;
1164 static int
1165 sha256_create_signature(hx509_context context,
1166 const struct signature_alg *sig_alg,
1167 const hx509_private_key signer,
1168 const AlgorithmIdentifier *alg,
1169 const heim_octet_string *data,
1170 AlgorithmIdentifier *signatureAlgorithm,
1171 heim_octet_string *sig)
1173 SHA256_CTX m;
1175 memset(sig, 0, sizeof(*sig));
1177 if (signatureAlgorithm) {
1178 int ret;
1179 ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
1180 "\x05\x00", 2);
1181 if (ret)
1182 return ret;
1186 sig->data = malloc(SHA256_DIGEST_LENGTH);
1187 if (sig->data == NULL) {
1188 sig->length = 0;
1189 return ENOMEM;
1191 sig->length = SHA256_DIGEST_LENGTH;
1193 SHA256_Init(&m);
1194 SHA256_Update(&m, data->data, data->length);
1195 SHA256_Final (sig->data, &m);
1197 return 0;
1200 static int
1201 sha256_verify_signature(hx509_context context,
1202 const struct signature_alg *sig_alg,
1203 const Certificate *signer,
1204 const AlgorithmIdentifier *alg,
1205 const heim_octet_string *data,
1206 const heim_octet_string *sig)
1208 unsigned char digest[SHA256_DIGEST_LENGTH];
1209 SHA256_CTX m;
1211 if (sig->length != SHA256_DIGEST_LENGTH) {
1212 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1213 "SHA256 sigature have wrong length");
1214 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1217 SHA256_Init(&m);
1218 SHA256_Update(&m, data->data, data->length);
1219 SHA256_Final (digest, &m);
1221 if (memcmp(digest, sig->data, SHA256_DIGEST_LENGTH) != 0) {
1222 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
1223 "Bad SHA256 sigature");
1224 return HX509_CRYPTO_BAD_SIGNATURE;
1227 return 0;
1230 static int
1231 sha1_create_signature(hx509_context context,
1232 const struct signature_alg *sig_alg,
1233 const hx509_private_key signer,
1234 const AlgorithmIdentifier *alg,
1235 const heim_octet_string *data,
1236 AlgorithmIdentifier *signatureAlgorithm,
1237 heim_octet_string *sig)
1239 SHA_CTX m;
1241 memset(sig, 0, sizeof(*sig));
1243 if (signatureAlgorithm) {
1244 int ret;
1245 ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
1246 "\x05\x00", 2);
1247 if (ret)
1248 return ret;
1252 sig->data = malloc(SHA_DIGEST_LENGTH);
1253 if (sig->data == NULL) {
1254 sig->length = 0;
1255 return ENOMEM;
1257 sig->length = SHA_DIGEST_LENGTH;
1259 SHA1_Init(&m);
1260 SHA1_Update(&m, data->data, data->length);
1261 SHA1_Final (sig->data, &m);
1263 return 0;
1266 static int
1267 md5_verify_signature(hx509_context context,
1268 const struct signature_alg *sig_alg,
1269 const Certificate *signer,
1270 const AlgorithmIdentifier *alg,
1271 const heim_octet_string *data,
1272 const heim_octet_string *sig)
1274 unsigned char digest[MD5_DIGEST_LENGTH];
1275 MD5_CTX m;
1277 if (sig->length != MD5_DIGEST_LENGTH) {
1278 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1279 "MD5 sigature have wrong length");
1280 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1283 MD5_Init(&m);
1284 MD5_Update(&m, data->data, data->length);
1285 MD5_Final (digest, &m);
1287 if (memcmp(digest, sig->data, MD5_DIGEST_LENGTH) != 0) {
1288 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
1289 "Bad MD5 sigature");
1290 return HX509_CRYPTO_BAD_SIGNATURE;
1293 return 0;
1296 static int
1297 md2_verify_signature(hx509_context context,
1298 const struct signature_alg *sig_alg,
1299 const Certificate *signer,
1300 const AlgorithmIdentifier *alg,
1301 const heim_octet_string *data,
1302 const heim_octet_string *sig)
1304 unsigned char digest[MD2_DIGEST_LENGTH];
1305 MD2_CTX m;
1307 if (sig->length != MD2_DIGEST_LENGTH) {
1308 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1309 "MD2 sigature have wrong length");
1310 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1313 MD2_Init(&m);
1314 MD2_Update(&m, data->data, data->length);
1315 MD2_Final (digest, &m);
1317 if (memcmp(digest, sig->data, MD2_DIGEST_LENGTH) != 0) {
1318 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
1319 "Bad MD2 sigature");
1320 return HX509_CRYPTO_BAD_SIGNATURE;
1323 return 0;
1326 #ifdef HAVE_OPENSSL
1328 static const struct signature_alg ecdsa_with_sha256_alg = {
1329 "ecdsa-with-sha256",
1330 &asn1_oid_id_ecdsa_with_SHA256,
1331 &_hx509_signature_ecdsa_with_sha256_data,
1332 &asn1_oid_id_ecPublicKey,
1333 &_hx509_signature_sha256_data,
1334 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1336 ecdsa_verify_signature,
1337 ecdsa_create_signature,
1341 static const struct signature_alg ecdsa_with_sha1_alg = {
1342 "ecdsa-with-sha1",
1343 &asn1_oid_id_ecdsa_with_SHA1,
1344 &_hx509_signature_ecdsa_with_sha1_data,
1345 &asn1_oid_id_ecPublicKey,
1346 &_hx509_signature_sha1_data,
1347 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1349 ecdsa_verify_signature,
1350 ecdsa_create_signature,
1354 #endif
1356 static const struct signature_alg heim_rsa_pkcs1_x509 = {
1357 "rsa-pkcs1-x509",
1358 &asn1_oid_id_heim_rsa_pkcs1_x509,
1359 &_hx509_signature_rsa_pkcs1_x509_data,
1360 &asn1_oid_id_pkcs1_rsaEncryption,
1361 NULL,
1362 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
1364 rsa_verify_signature,
1365 rsa_create_signature
1368 static const struct signature_alg pkcs1_rsa_sha1_alg = {
1369 "rsa",
1370 &asn1_oid_id_pkcs1_rsaEncryption,
1371 &_hx509_signature_rsa_with_sha1_data,
1372 &asn1_oid_id_pkcs1_rsaEncryption,
1373 NULL,
1374 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1376 rsa_verify_signature,
1377 rsa_create_signature
1380 static const struct signature_alg rsa_with_sha256_alg = {
1381 "rsa-with-sha256",
1382 &asn1_oid_id_pkcs1_sha256WithRSAEncryption,
1383 &_hx509_signature_rsa_with_sha256_data,
1384 &asn1_oid_id_pkcs1_rsaEncryption,
1385 &_hx509_signature_sha256_data,
1386 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1388 rsa_verify_signature,
1389 rsa_create_signature
1392 static const struct signature_alg rsa_with_sha1_alg = {
1393 "rsa-with-sha1",
1394 &asn1_oid_id_pkcs1_sha1WithRSAEncryption,
1395 &_hx509_signature_rsa_with_sha1_data,
1396 &asn1_oid_id_pkcs1_rsaEncryption,
1397 &_hx509_signature_sha1_data,
1398 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1400 rsa_verify_signature,
1401 rsa_create_signature
1404 static const struct signature_alg rsa_with_md5_alg = {
1405 "rsa-with-md5",
1406 &asn1_oid_id_pkcs1_md5WithRSAEncryption,
1407 &_hx509_signature_rsa_with_md5_data,
1408 &asn1_oid_id_pkcs1_rsaEncryption,
1409 &_hx509_signature_md5_data,
1410 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1411 1230739889,
1412 rsa_verify_signature,
1413 rsa_create_signature
1416 static const struct signature_alg rsa_with_md2_alg = {
1417 "rsa-with-md2",
1418 &asn1_oid_id_pkcs1_md2WithRSAEncryption,
1419 &_hx509_signature_rsa_with_md2_data,
1420 &asn1_oid_id_pkcs1_rsaEncryption,
1421 &_hx509_signature_md2_data,
1422 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1423 1230739889,
1424 rsa_verify_signature,
1425 rsa_create_signature
1428 static const struct signature_alg dsa_sha1_alg = {
1429 "dsa-with-sha1",
1430 &asn1_oid_id_dsa_with_sha1,
1431 NULL,
1432 &asn1_oid_id_dsa,
1433 &_hx509_signature_sha1_data,
1434 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
1436 dsa_verify_signature,
1437 /* create_signature */ NULL,
1440 static const struct signature_alg sha256_alg = {
1441 "sha-256",
1442 &asn1_oid_id_sha256,
1443 &_hx509_signature_sha256_data,
1444 NULL,
1445 NULL,
1446 SIG_DIGEST,
1448 sha256_verify_signature,
1449 sha256_create_signature
1452 static const struct signature_alg sha1_alg = {
1453 "sha1",
1454 &asn1_oid_id_secsig_sha_1,
1455 &_hx509_signature_sha1_data,
1456 NULL,
1457 NULL,
1458 SIG_DIGEST,
1460 sha1_verify_signature,
1461 sha1_create_signature
1464 static const struct signature_alg md5_alg = {
1465 "rsa-md5",
1466 &asn1_oid_id_rsa_digest_md5,
1467 &_hx509_signature_md5_data,
1468 NULL,
1469 NULL,
1470 SIG_DIGEST,
1472 md5_verify_signature
1475 static const struct signature_alg md2_alg = {
1476 "rsa-md2",
1477 &asn1_oid_id_rsa_digest_md2,
1478 &_hx509_signature_md2_data,
1479 NULL,
1480 NULL,
1481 SIG_DIGEST,
1483 md2_verify_signature
1487 * Order matter in this structure, "best" first for each "key
1488 * compatible" type (type is ECDSA, RSA, DSA, none, etc)
1491 static const struct signature_alg *sig_algs[] = {
1492 #ifdef HAVE_OPENSSL
1493 &ecdsa_with_sha256_alg,
1494 &ecdsa_with_sha1_alg,
1495 #endif
1496 &rsa_with_sha256_alg,
1497 &rsa_with_sha1_alg,
1498 &pkcs1_rsa_sha1_alg,
1499 &rsa_with_md5_alg,
1500 &rsa_with_md2_alg,
1501 &heim_rsa_pkcs1_x509,
1502 &dsa_sha1_alg,
1503 &sha256_alg,
1504 &sha1_alg,
1505 &md5_alg,
1506 &md2_alg,
1507 NULL
1510 static const struct signature_alg *
1511 find_sig_alg(const heim_oid *oid)
1513 unsigned int i;
1514 for (i = 0; sig_algs[i]; i++)
1515 if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
1516 return sig_algs[i];
1517 return NULL;
1520 static const AlgorithmIdentifier *
1521 alg_for_privatekey(const hx509_private_key pk, int type)
1523 const heim_oid *keytype;
1524 unsigned int i;
1526 if (pk->ops == NULL)
1527 return NULL;
1529 keytype = pk->ops->key_oid;
1531 for (i = 0; sig_algs[i]; i++) {
1532 if (sig_algs[i]->key_oid == NULL)
1533 continue;
1534 if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
1535 continue;
1536 if (pk->ops->available &&
1537 pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
1538 continue;
1539 if (type == HX509_SELECT_PUBLIC_SIG)
1540 return sig_algs[i]->sig_alg;
1541 if (type == HX509_SELECT_DIGEST)
1542 return sig_algs[i]->digest_alg;
1544 return NULL;
1546 return NULL;
1553 static struct hx509_private_key_ops *private_algs[] = {
1554 &rsa_private_key_ops,
1555 #ifdef HAVE_OPENSSL
1556 &ecdsa_private_key_ops,
1557 #endif
1558 NULL
1561 static hx509_private_key_ops *
1562 find_private_alg(const heim_oid *oid)
1564 int i;
1565 for (i = 0; private_algs[i]; i++) {
1566 if (private_algs[i]->key_oid == NULL)
1567 continue;
1568 if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
1569 return private_algs[i];
1571 return NULL;
1575 * Check if the algorithm `alg' have a best before date, and if it
1576 * des, make sure the its before the time `t'.
1580 _hx509_signature_best_before(hx509_context context,
1581 const AlgorithmIdentifier *alg,
1582 time_t t)
1584 const struct signature_alg *md;
1586 md = find_sig_alg(&alg->algorithm);
1587 if (md == NULL) {
1588 hx509_clear_error_string(context);
1589 return HX509_SIG_ALG_NO_SUPPORTED;
1591 if (md->best_before && md->best_before < t) {
1592 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1593 "Algorithm %s has passed it best before date",
1594 md->name);
1595 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1597 return 0;
1601 _hx509_verify_signature(hx509_context context,
1602 const Certificate *signer,
1603 const AlgorithmIdentifier *alg,
1604 const heim_octet_string *data,
1605 const heim_octet_string *sig)
1607 const struct signature_alg *md;
1609 md = find_sig_alg(&alg->algorithm);
1610 if (md == NULL) {
1611 hx509_clear_error_string(context);
1612 return HX509_SIG_ALG_NO_SUPPORTED;
1614 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1615 hx509_clear_error_string(context);
1616 return HX509_CRYPTO_SIG_NO_CONF;
1618 if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1619 hx509_clear_error_string(context);
1620 return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1622 if (md->key_oid && signer) {
1623 const SubjectPublicKeyInfo *spi;
1624 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1626 if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
1627 hx509_clear_error_string(context);
1628 return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
1631 return (*md->verify_signature)(context, md, signer, alg, data, sig);
1635 _hx509_verify_signature_bitstring(hx509_context context,
1636 const Certificate *signer,
1637 const AlgorithmIdentifier *alg,
1638 const heim_octet_string *data,
1639 const heim_bit_string *sig)
1641 heim_octet_string os;
1643 if (sig->length & 7) {
1644 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1645 "signature not multiple of 8 bits");
1646 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1649 os.data = sig->data;
1650 os.length = sig->length / 8;
1652 return _hx509_verify_signature(context, signer, alg, data, &os);
1656 _hx509_create_signature(hx509_context context,
1657 const hx509_private_key signer,
1658 const AlgorithmIdentifier *alg,
1659 const heim_octet_string *data,
1660 AlgorithmIdentifier *signatureAlgorithm,
1661 heim_octet_string *sig)
1663 const struct signature_alg *md;
1665 md = find_sig_alg(&alg->algorithm);
1666 if (md == NULL) {
1667 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1668 "algorithm no supported");
1669 return HX509_SIG_ALG_NO_SUPPORTED;
1672 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1673 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1674 "algorithm provides no conf");
1675 return HX509_CRYPTO_SIG_NO_CONF;
1678 return (*md->create_signature)(context, md, signer, alg, data,
1679 signatureAlgorithm, sig);
1683 _hx509_create_signature_bitstring(hx509_context context,
1684 const hx509_private_key signer,
1685 const AlgorithmIdentifier *alg,
1686 const heim_octet_string *data,
1687 AlgorithmIdentifier *signatureAlgorithm,
1688 heim_bit_string *sig)
1690 heim_octet_string os;
1691 int ret;
1693 ret = _hx509_create_signature(context, signer, alg,
1694 data, signatureAlgorithm, &os);
1695 if (ret)
1696 return ret;
1697 sig->data = os.data;
1698 sig->length = os.length * 8;
1699 return 0;
1703 _hx509_public_encrypt(hx509_context context,
1704 const heim_octet_string *cleartext,
1705 const Certificate *cert,
1706 heim_oid *encryption_oid,
1707 heim_octet_string *ciphertext)
1709 const SubjectPublicKeyInfo *spi;
1710 unsigned char *to;
1711 int tosize;
1712 int ret;
1713 RSA *rsa;
1714 RSAPublicKey pk;
1715 size_t size;
1717 ciphertext->data = NULL;
1718 ciphertext->length = 0;
1720 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1722 rsa = RSA_new();
1723 if (rsa == NULL) {
1724 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1725 return ENOMEM;
1728 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
1729 spi->subjectPublicKey.length / 8,
1730 &pk, &size);
1731 if (ret) {
1732 RSA_free(rsa);
1733 hx509_set_error_string(context, 0, ret, "RSAPublicKey decode failure");
1734 return ret;
1736 rsa->n = heim_int2BN(&pk.modulus);
1737 rsa->e = heim_int2BN(&pk.publicExponent);
1739 free_RSAPublicKey(&pk);
1741 if (rsa->n == NULL || rsa->e == NULL) {
1742 RSA_free(rsa);
1743 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1744 return ENOMEM;
1747 tosize = RSA_size(rsa);
1748 to = malloc(tosize);
1749 if (to == NULL) {
1750 RSA_free(rsa);
1751 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1752 return ENOMEM;
1755 ret = RSA_public_encrypt(cleartext->length,
1756 (unsigned char *)cleartext->data,
1757 to, rsa, RSA_PKCS1_PADDING);
1758 RSA_free(rsa);
1759 if (ret <= 0) {
1760 free(to);
1761 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
1762 "RSA public encrypt failed with %d", ret);
1763 return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
1765 if (ret > tosize)
1766 _hx509_abort("internal rsa decryption failure: ret > tosize");
1768 ciphertext->length = ret;
1769 ciphertext->data = to;
1771 ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption, encryption_oid);
1772 if (ret) {
1773 der_free_octet_string(ciphertext);
1774 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1775 return ENOMEM;
1778 return 0;
1782 _hx509_private_key_private_decrypt(hx509_context context,
1783 const heim_octet_string *ciphertext,
1784 const heim_oid *encryption_oid,
1785 hx509_private_key p,
1786 heim_octet_string *cleartext)
1788 int ret;
1790 cleartext->data = NULL;
1791 cleartext->length = 0;
1793 if (p->private_key.rsa == NULL) {
1794 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1795 "Private RSA key missing");
1796 return HX509_PRIVATE_KEY_MISSING;
1799 cleartext->length = RSA_size(p->private_key.rsa);
1800 cleartext->data = malloc(cleartext->length);
1801 if (cleartext->data == NULL) {
1802 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1803 return ENOMEM;
1805 ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
1806 cleartext->data,
1807 p->private_key.rsa,
1808 RSA_PKCS1_PADDING);
1809 if (ret <= 0) {
1810 der_free_octet_string(cleartext);
1811 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
1812 "Failed to decrypt using private key: %d", ret);
1813 return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
1815 if (cleartext->length < ret)
1816 _hx509_abort("internal rsa decryption failure: ret > tosize");
1818 cleartext->length = ret;
1820 return 0;
1825 _hx509_parse_private_key(hx509_context context,
1826 const AlgorithmIdentifier *keyai,
1827 const void *data,
1828 size_t len,
1829 hx509_private_key *private_key)
1831 struct hx509_private_key_ops *ops;
1832 int ret;
1834 *private_key = NULL;
1836 ops = find_private_alg(&keyai->algorithm);
1837 if (ops == NULL) {
1838 hx509_clear_error_string(context);
1839 return HX509_SIG_ALG_NO_SUPPORTED;
1842 ret = _hx509_private_key_init(private_key, ops, NULL);
1843 if (ret) {
1844 hx509_set_error_string(context, 0, ret, "out of memory");
1845 return ret;
1848 ret = (*ops->import)(context, keyai, data, len, *private_key);
1849 if (ret)
1850 _hx509_private_key_free(private_key);
1852 return ret;
1860 _hx509_private_key2SPKI(hx509_context context,
1861 hx509_private_key private_key,
1862 SubjectPublicKeyInfo *spki)
1864 const struct hx509_private_key_ops *ops = private_key->ops;
1865 if (ops == NULL || ops->get_spki == NULL) {
1866 hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1867 "Private key have no key2SPKI function");
1868 return HX509_UNIMPLEMENTED_OPERATION;
1870 return (*ops->get_spki)(context, private_key, spki);
1874 _hx509_generate_private_key_init(hx509_context context,
1875 const heim_oid *oid,
1876 struct hx509_generate_private_context **ctx)
1878 *ctx = NULL;
1880 if (der_heim_oid_cmp(oid, &asn1_oid_id_pkcs1_rsaEncryption) != 0) {
1881 hx509_set_error_string(context, 0, EINVAL,
1882 "private key not an RSA key");
1883 return EINVAL;
1886 *ctx = calloc(1, sizeof(**ctx));
1887 if (*ctx == NULL) {
1888 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1889 return ENOMEM;
1891 (*ctx)->key_oid = oid;
1893 return 0;
1897 _hx509_generate_private_key_is_ca(hx509_context context,
1898 struct hx509_generate_private_context *ctx)
1900 ctx->isCA = 1;
1901 return 0;
1905 _hx509_generate_private_key_bits(hx509_context context,
1906 struct hx509_generate_private_context *ctx,
1907 unsigned long bits)
1909 ctx->num_bits = bits;
1910 return 0;
1914 void
1915 _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1917 free(*ctx);
1918 *ctx = NULL;
1922 _hx509_generate_private_key(hx509_context context,
1923 struct hx509_generate_private_context *ctx,
1924 hx509_private_key *private_key)
1926 struct hx509_private_key_ops *ops;
1927 int ret;
1929 *private_key = NULL;
1931 ops = find_private_alg(ctx->key_oid);
1932 if (ops == NULL) {
1933 hx509_clear_error_string(context);
1934 return HX509_SIG_ALG_NO_SUPPORTED;
1937 ret = _hx509_private_key_init(private_key, ops, NULL);
1938 if (ret) {
1939 hx509_set_error_string(context, 0, ret, "out of memory");
1940 return ret;
1943 ret = (*ops->generate_private_key)(context, ctx, *private_key);
1944 if (ret)
1945 _hx509_private_key_free(private_key);
1947 return ret;
1954 const AlgorithmIdentifier *
1955 hx509_signature_sha512(void)
1956 { return &_hx509_signature_sha512_data; }
1958 const AlgorithmIdentifier *
1959 hx509_signature_sha384(void)
1960 { return &_hx509_signature_sha384_data; }
1962 const AlgorithmIdentifier *
1963 hx509_signature_sha256(void)
1964 { return &_hx509_signature_sha256_data; }
1966 const AlgorithmIdentifier *
1967 hx509_signature_sha1(void)
1968 { return &_hx509_signature_sha1_data; }
1970 const AlgorithmIdentifier *
1971 hx509_signature_md5(void)
1972 { return &_hx509_signature_md5_data; }
1974 const AlgorithmIdentifier *
1975 hx509_signature_md2(void)
1976 { return &_hx509_signature_md2_data; }
1978 const AlgorithmIdentifier *
1979 hx509_signature_ecPublicKey(void)
1980 { return &_hx509_signature_ecPublicKey; }
1982 const AlgorithmIdentifier *
1983 hx509_signature_ecdsa_with_sha256(void)
1984 { return &_hx509_signature_ecdsa_with_sha256_data; }
1986 const AlgorithmIdentifier *
1987 hx509_signature_ecdsa_with_sha1(void)
1988 { return &_hx509_signature_ecdsa_with_sha1_data; }
1990 const AlgorithmIdentifier *
1991 hx509_signature_rsa_with_sha512(void)
1992 { return &_hx509_signature_rsa_with_sha512_data; }
1994 const AlgorithmIdentifier *
1995 hx509_signature_rsa_with_sha384(void)
1996 { return &_hx509_signature_rsa_with_sha384_data; }
1998 const AlgorithmIdentifier *
1999 hx509_signature_rsa_with_sha256(void)
2000 { return &_hx509_signature_rsa_with_sha256_data; }
2002 const AlgorithmIdentifier *
2003 hx509_signature_rsa_with_sha1(void)
2004 { return &_hx509_signature_rsa_with_sha1_data; }
2006 const AlgorithmIdentifier *
2007 hx509_signature_rsa_with_md5(void)
2008 { return &_hx509_signature_rsa_with_md5_data; }
2010 const AlgorithmIdentifier *
2011 hx509_signature_rsa_with_md2(void)
2012 { return &_hx509_signature_rsa_with_md2_data; }
2014 const AlgorithmIdentifier *
2015 hx509_signature_rsa(void)
2016 { return &_hx509_signature_rsa_data; }
2018 const AlgorithmIdentifier *
2019 hx509_signature_rsa_pkcs1_x509(void)
2020 { return &_hx509_signature_rsa_pkcs1_x509_data; }
2022 const AlgorithmIdentifier *
2023 hx509_crypto_des_rsdi_ede3_cbc(void)
2024 { return &_hx509_des_rsdi_ede3_cbc_oid; }
2026 const AlgorithmIdentifier *
2027 hx509_crypto_aes128_cbc(void)
2028 { return &_hx509_crypto_aes128_cbc_data; }
2030 const AlgorithmIdentifier *
2031 hx509_crypto_aes256_cbc(void)
2032 { return &_hx509_crypto_aes256_cbc_data; }
2038 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
2039 &_hx509_signature_rsa_with_sha256_data;
2040 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
2041 &_hx509_signature_sha256_data;
2042 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
2043 &_hx509_crypto_aes128_cbc_data;
2050 _hx509_private_key_init(hx509_private_key *key,
2051 hx509_private_key_ops *ops,
2052 void *keydata)
2054 *key = calloc(1, sizeof(**key));
2055 if (*key == NULL)
2056 return ENOMEM;
2057 (*key)->ref = 1;
2058 (*key)->ops = ops;
2059 (*key)->private_key.keydata = keydata;
2060 return 0;
2063 hx509_private_key
2064 _hx509_private_key_ref(hx509_private_key key)
2066 if (key->ref == 0)
2067 _hx509_abort("key refcount <= 0 on ref");
2068 key->ref++;
2069 if (key->ref == UINT_MAX)
2070 _hx509_abort("key refcount == UINT_MAX on ref");
2071 return key;
2074 const char *
2075 _hx509_private_pem_name(hx509_private_key key)
2077 return key->ops->pemtype;
2081 _hx509_private_key_free(hx509_private_key *key)
2083 if (key == NULL || *key == NULL)
2084 return 0;
2086 if ((*key)->ref == 0)
2087 _hx509_abort("key refcount == 0 on free");
2088 if (--(*key)->ref > 0)
2089 return 0;
2091 if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0) {
2092 if ((*key)->private_key.rsa)
2093 RSA_free((*key)->private_key.rsa);
2094 #ifdef HAVE_OPENSSL
2095 } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0) {
2096 if ((*key)->private_key.ecdsa)
2097 EC_KEY_free((*key)->private_key.ecdsa);
2098 #endif
2100 (*key)->private_key.rsa = NULL;
2101 free(*key);
2102 *key = NULL;
2103 return 0;
2106 void
2107 _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
2109 if (key->private_key.rsa)
2110 RSA_free(key->private_key.rsa);
2111 key->private_key.rsa = ptr;
2112 key->signature_alg = &asn1_oid_id_pkcs1_sha1WithRSAEncryption;
2113 key->md = &pkcs1_rsa_sha1_alg;
2117 _hx509_private_key_oid(hx509_context context,
2118 const hx509_private_key key,
2119 heim_oid *data)
2121 int ret;
2122 ret = der_copy_oid(key->ops->key_oid, data);
2123 if (ret)
2124 hx509_set_error_string(context, 0, ret, "malloc out of memory");
2125 return ret;
2129 _hx509_private_key_exportable(hx509_private_key key)
2131 if (key->ops->export == NULL)
2132 return 0;
2133 return 1;
2136 BIGNUM *
2137 _hx509_private_key_get_internal(hx509_context context,
2138 hx509_private_key key,
2139 const char *type)
2141 if (key->ops->get_internal == NULL)
2142 return NULL;
2143 return (*key->ops->get_internal)(context, key, type);
2147 _hx509_private_key_export(hx509_context context,
2148 const hx509_private_key key,
2149 heim_octet_string *data)
2151 if (key->ops->export == NULL) {
2152 hx509_clear_error_string(context);
2153 return HX509_UNIMPLEMENTED_OPERATION;
2155 return (*key->ops->export)(context, key, data);
2162 struct hx509cipher {
2163 const char *name;
2164 int flags;
2165 #define CIPHER_WEAK 1
2166 const heim_oid *oid;
2167 const AlgorithmIdentifier *(*ai_func)(void);
2168 const EVP_CIPHER *(*evp_func)(void);
2169 int (*get_params)(hx509_context, const hx509_crypto,
2170 const heim_octet_string *, heim_octet_string *);
2171 int (*set_params)(hx509_context, const heim_octet_string *,
2172 hx509_crypto, heim_octet_string *);
2175 struct hx509_crypto_data {
2176 char *name;
2177 int flags;
2178 #define ALLOW_WEAK 1
2179 const struct hx509cipher *cipher;
2180 const EVP_CIPHER *c;
2181 heim_octet_string key;
2182 heim_oid oid;
2183 void *param;
2190 static unsigned private_rc2_40_oid_data[] = { 127, 1 };
2192 static heim_oid asn1_oid_private_rc2_40 =
2193 { 2, private_rc2_40_oid_data };
2199 static int
2200 CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
2201 const heim_octet_string *ivec, heim_octet_string *param)
2203 size_t size;
2204 int ret;
2206 assert(crypto->param == NULL);
2207 if (ivec == NULL)
2208 return 0;
2210 ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
2211 ivec, &size, ret);
2212 if (ret == 0 && size != param->length)
2213 _hx509_abort("Internal asn1 encoder failure");
2214 if (ret)
2215 hx509_clear_error_string(context);
2216 return ret;
2219 static int
2220 CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
2221 hx509_crypto crypto, heim_octet_string *ivec)
2223 int ret;
2224 if (ivec == NULL)
2225 return 0;
2227 ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
2228 if (ret)
2229 hx509_clear_error_string(context);
2231 return ret;
2234 struct _RC2_params {
2235 int maximum_effective_key;
2238 static int
2239 CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
2240 const heim_octet_string *ivec, heim_octet_string *param)
2242 CMSRC2CBCParameter rc2params;
2243 const struct _RC2_params *p = crypto->param;
2244 int maximum_effective_key = 128;
2245 size_t size;
2246 int ret;
2248 memset(&rc2params, 0, sizeof(rc2params));
2250 if (p)
2251 maximum_effective_key = p->maximum_effective_key;
2253 switch(maximum_effective_key) {
2254 case 40:
2255 rc2params.rc2ParameterVersion = 160;
2256 break;
2257 case 64:
2258 rc2params.rc2ParameterVersion = 120;
2259 break;
2260 case 128:
2261 rc2params.rc2ParameterVersion = 58;
2262 break;
2264 rc2params.iv = *ivec;
2266 ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
2267 &rc2params, &size, ret);
2268 if (ret == 0 && size != param->length)
2269 _hx509_abort("Internal asn1 encoder failure");
2271 return ret;
2274 static int
2275 CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
2276 hx509_crypto crypto, heim_octet_string *ivec)
2278 CMSRC2CBCParameter rc2param;
2279 struct _RC2_params *p;
2280 size_t size;
2281 int ret;
2283 ret = decode_CMSRC2CBCParameter(param->data, param->length,
2284 &rc2param, &size);
2285 if (ret) {
2286 hx509_clear_error_string(context);
2287 return ret;
2290 p = calloc(1, sizeof(*p));
2291 if (p == NULL) {
2292 free_CMSRC2CBCParameter(&rc2param);
2293 hx509_clear_error_string(context);
2294 return ENOMEM;
2296 switch(rc2param.rc2ParameterVersion) {
2297 case 160:
2298 crypto->c = EVP_rc2_40_cbc();
2299 p->maximum_effective_key = 40;
2300 break;
2301 case 120:
2302 crypto->c = EVP_rc2_64_cbc();
2303 p->maximum_effective_key = 64;
2304 break;
2305 case 58:
2306 crypto->c = EVP_rc2_cbc();
2307 p->maximum_effective_key = 128;
2308 break;
2309 default:
2310 free(p);
2311 free_CMSRC2CBCParameter(&rc2param);
2312 return HX509_CRYPTO_SIG_INVALID_FORMAT;
2314 if (ivec)
2315 ret = der_copy_octet_string(&rc2param.iv, ivec);
2316 free_CMSRC2CBCParameter(&rc2param);
2317 if (ret) {
2318 free(p);
2319 hx509_clear_error_string(context);
2320 } else
2321 crypto->param = p;
2323 return ret;
2330 static const struct hx509cipher ciphers[] = {
2332 "rc2-cbc",
2333 CIPHER_WEAK,
2334 &asn1_oid_id_pkcs3_rc2_cbc,
2335 NULL,
2336 EVP_rc2_cbc,
2337 CMSRC2CBCParam_get,
2338 CMSRC2CBCParam_set
2341 "rc2-cbc",
2342 CIPHER_WEAK,
2343 &asn1_oid_id_rsadsi_rc2_cbc,
2344 NULL,
2345 EVP_rc2_cbc,
2346 CMSRC2CBCParam_get,
2347 CMSRC2CBCParam_set
2350 "rc2-40-cbc",
2351 CIPHER_WEAK,
2352 &asn1_oid_private_rc2_40,
2353 NULL,
2354 EVP_rc2_40_cbc,
2355 CMSRC2CBCParam_get,
2356 CMSRC2CBCParam_set
2359 "des-ede3-cbc",
2361 &asn1_oid_id_pkcs3_des_ede3_cbc,
2362 NULL,
2363 EVP_des_ede3_cbc,
2364 CMSCBCParam_get,
2365 CMSCBCParam_set
2368 "des-ede3-cbc",
2370 &asn1_oid_id_rsadsi_des_ede3_cbc,
2371 hx509_crypto_des_rsdi_ede3_cbc,
2372 EVP_des_ede3_cbc,
2373 CMSCBCParam_get,
2374 CMSCBCParam_set
2377 "aes-128-cbc",
2379 &asn1_oid_id_aes_128_cbc,
2380 hx509_crypto_aes128_cbc,
2381 EVP_aes_128_cbc,
2382 CMSCBCParam_get,
2383 CMSCBCParam_set
2386 "aes-192-cbc",
2388 &asn1_oid_id_aes_192_cbc,
2389 NULL,
2390 EVP_aes_192_cbc,
2391 CMSCBCParam_get,
2392 CMSCBCParam_set
2395 "aes-256-cbc",
2397 &asn1_oid_id_aes_256_cbc,
2398 hx509_crypto_aes256_cbc,
2399 EVP_aes_256_cbc,
2400 CMSCBCParam_get,
2401 CMSCBCParam_set
2405 static const struct hx509cipher *
2406 find_cipher_by_oid(const heim_oid *oid)
2408 int i;
2410 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
2411 if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
2412 return &ciphers[i];
2414 return NULL;
2417 static const struct hx509cipher *
2418 find_cipher_by_name(const char *name)
2420 int i;
2422 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
2423 if (strcasecmp(name, ciphers[i].name) == 0)
2424 return &ciphers[i];
2426 return NULL;
2430 const heim_oid *
2431 hx509_crypto_enctype_by_name(const char *name)
2433 const struct hx509cipher *cipher;
2435 cipher = find_cipher_by_name(name);
2436 if (cipher == NULL)
2437 return NULL;
2438 return cipher->oid;
2442 hx509_crypto_init(hx509_context context,
2443 const char *provider,
2444 const heim_oid *enctype,
2445 hx509_crypto *crypto)
2447 const struct hx509cipher *cipher;
2449 *crypto = NULL;
2451 cipher = find_cipher_by_oid(enctype);
2452 if (cipher == NULL) {
2453 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2454 "Algorithm not supported");
2455 return HX509_ALG_NOT_SUPP;
2458 *crypto = calloc(1, sizeof(**crypto));
2459 if (*crypto == NULL) {
2460 hx509_clear_error_string(context);
2461 return ENOMEM;
2464 (*crypto)->cipher = cipher;
2465 (*crypto)->c = (*cipher->evp_func)();
2467 if (der_copy_oid(enctype, &(*crypto)->oid)) {
2468 hx509_crypto_destroy(*crypto);
2469 *crypto = NULL;
2470 hx509_clear_error_string(context);
2471 return ENOMEM;
2474 return 0;
2477 const char *
2478 hx509_crypto_provider(hx509_crypto crypto)
2480 return "unknown";
2483 void
2484 hx509_crypto_destroy(hx509_crypto crypto)
2486 if (crypto->name)
2487 free(crypto->name);
2488 if (crypto->key.data)
2489 free(crypto->key.data);
2490 if (crypto->param)
2491 free(crypto->param);
2492 der_free_oid(&crypto->oid);
2493 memset(crypto, 0, sizeof(*crypto));
2494 free(crypto);
2498 hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2500 return 0;
2503 void
2504 hx509_crypto_allow_weak(hx509_crypto crypto)
2506 crypto->flags |= ALLOW_WEAK;
2510 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2512 if (EVP_CIPHER_key_length(crypto->c) > length)
2513 return HX509_CRYPTO_INTERNAL_ERROR;
2515 if (crypto->key.data) {
2516 free(crypto->key.data);
2517 crypto->key.data = NULL;
2518 crypto->key.length = 0;
2520 crypto->key.data = malloc(length);
2521 if (crypto->key.data == NULL)
2522 return ENOMEM;
2523 memcpy(crypto->key.data, data, length);
2524 crypto->key.length = length;
2526 return 0;
2530 hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2532 if (crypto->key.data) {
2533 free(crypto->key.data);
2534 crypto->key.length = 0;
2537 crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2538 crypto->key.data = malloc(crypto->key.length);
2539 if (crypto->key.data == NULL) {
2540 crypto->key.length = 0;
2541 return ENOMEM;
2543 if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2544 free(crypto->key.data);
2545 crypto->key.data = NULL;
2546 crypto->key.length = 0;
2547 return HX509_CRYPTO_INTERNAL_ERROR;
2549 if (key)
2550 return der_copy_octet_string(&crypto->key, key);
2551 else
2552 return 0;
2556 hx509_crypto_set_params(hx509_context context,
2557 hx509_crypto crypto,
2558 const heim_octet_string *param,
2559 heim_octet_string *ivec)
2561 return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2565 hx509_crypto_get_params(hx509_context context,
2566 hx509_crypto crypto,
2567 const heim_octet_string *ivec,
2568 heim_octet_string *param)
2570 return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2574 hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2576 ivec->length = EVP_CIPHER_iv_length(crypto->c);
2577 ivec->data = malloc(ivec->length);
2578 if (ivec->data == NULL) {
2579 ivec->length = 0;
2580 return ENOMEM;
2583 if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2584 free(ivec->data);
2585 ivec->data = NULL;
2586 ivec->length = 0;
2587 return HX509_CRYPTO_INTERNAL_ERROR;
2589 return 0;
2593 hx509_crypto_encrypt(hx509_crypto crypto,
2594 const void *data,
2595 const size_t length,
2596 const heim_octet_string *ivec,
2597 heim_octet_string **ciphertext)
2599 EVP_CIPHER_CTX evp;
2600 size_t padsize;
2601 int ret;
2603 *ciphertext = NULL;
2605 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2606 (crypto->flags & ALLOW_WEAK) == 0)
2607 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2609 assert(EVP_CIPHER_iv_length(crypto->c) == ivec->length);
2611 EVP_CIPHER_CTX_init(&evp);
2613 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2614 crypto->key.data, ivec->data, 1);
2615 if (ret != 1) {
2616 EVP_CIPHER_CTX_cleanup(&evp);
2617 ret = HX509_CRYPTO_INTERNAL_ERROR;
2618 goto out;
2621 *ciphertext = calloc(1, sizeof(**ciphertext));
2622 if (*ciphertext == NULL) {
2623 ret = ENOMEM;
2624 goto out;
2627 if (EVP_CIPHER_block_size(crypto->c) == 1) {
2628 padsize = 0;
2629 } else {
2630 int bsize = EVP_CIPHER_block_size(crypto->c);
2631 padsize = bsize - (length % bsize);
2633 (*ciphertext)->length = length + padsize;
2634 (*ciphertext)->data = malloc(length + padsize);
2635 if ((*ciphertext)->data == NULL) {
2636 ret = ENOMEM;
2637 goto out;
2640 memcpy((*ciphertext)->data, data, length);
2641 if (padsize) {
2642 int i;
2643 unsigned char *p = (*ciphertext)->data;
2644 p += length;
2645 for (i = 0; i < padsize; i++)
2646 *p++ = padsize;
2649 ret = EVP_Cipher(&evp, (*ciphertext)->data,
2650 (*ciphertext)->data,
2651 length + padsize);
2652 if (ret != 1) {
2653 ret = HX509_CRYPTO_INTERNAL_ERROR;
2654 goto out;
2656 ret = 0;
2658 out:
2659 if (ret) {
2660 if (*ciphertext) {
2661 if ((*ciphertext)->data) {
2662 free((*ciphertext)->data);
2664 free(*ciphertext);
2665 *ciphertext = NULL;
2668 EVP_CIPHER_CTX_cleanup(&evp);
2670 return ret;
2674 hx509_crypto_decrypt(hx509_crypto crypto,
2675 const void *data,
2676 const size_t length,
2677 heim_octet_string *ivec,
2678 heim_octet_string *clear)
2680 EVP_CIPHER_CTX evp;
2681 void *idata = NULL;
2682 int ret;
2684 clear->data = NULL;
2685 clear->length = 0;
2687 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2688 (crypto->flags & ALLOW_WEAK) == 0)
2689 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2691 if (ivec && EVP_CIPHER_iv_length(crypto->c) < ivec->length)
2692 return HX509_CRYPTO_INTERNAL_ERROR;
2694 if (crypto->key.data == NULL)
2695 return HX509_CRYPTO_INTERNAL_ERROR;
2697 if (ivec)
2698 idata = ivec->data;
2700 EVP_CIPHER_CTX_init(&evp);
2702 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2703 crypto->key.data, idata, 0);
2704 if (ret != 1) {
2705 EVP_CIPHER_CTX_cleanup(&evp);
2706 return HX509_CRYPTO_INTERNAL_ERROR;
2709 clear->length = length;
2710 clear->data = malloc(length);
2711 if (clear->data == NULL) {
2712 EVP_CIPHER_CTX_cleanup(&evp);
2713 clear->length = 0;
2714 return ENOMEM;
2717 if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2718 return HX509_CRYPTO_INTERNAL_ERROR;
2720 EVP_CIPHER_CTX_cleanup(&evp);
2722 if (EVP_CIPHER_block_size(crypto->c) > 1) {
2723 int padsize;
2724 unsigned char *p;
2725 int j, bsize = EVP_CIPHER_block_size(crypto->c);
2727 if (clear->length < bsize) {
2728 ret = HX509_CMS_PADDING_ERROR;
2729 goto out;
2732 p = clear->data;
2733 p += clear->length - 1;
2734 padsize = *p;
2735 if (padsize > bsize) {
2736 ret = HX509_CMS_PADDING_ERROR;
2737 goto out;
2739 clear->length -= padsize;
2740 for (j = 0; j < padsize; j++) {
2741 if (*p-- != padsize) {
2742 ret = HX509_CMS_PADDING_ERROR;
2743 goto out;
2748 return 0;
2750 out:
2751 if (clear->data)
2752 free(clear->data);
2753 clear->data = NULL;
2754 clear->length = 0;
2755 return ret;
2758 typedef int (*PBE_string2key_func)(hx509_context,
2759 const char *,
2760 const heim_octet_string *,
2761 hx509_crypto *, heim_octet_string *,
2762 heim_octet_string *,
2763 const heim_oid *, const EVP_MD *);
2765 static int
2766 PBE_string2key(hx509_context context,
2767 const char *password,
2768 const heim_octet_string *parameters,
2769 hx509_crypto *crypto,
2770 heim_octet_string *key, heim_octet_string *iv,
2771 const heim_oid *enc_oid,
2772 const EVP_MD *md)
2774 PKCS12_PBEParams p12params;
2775 int passwordlen;
2776 hx509_crypto c;
2777 int iter, saltlen, ret;
2778 unsigned char *salt;
2780 passwordlen = password ? strlen(password) : 0;
2782 if (parameters == NULL)
2783 return HX509_ALG_NOT_SUPP;
2785 ret = decode_PKCS12_PBEParams(parameters->data,
2786 parameters->length,
2787 &p12params, NULL);
2788 if (ret)
2789 goto out;
2791 if (p12params.iterations)
2792 iter = *p12params.iterations;
2793 else
2794 iter = 1;
2795 salt = p12params.salt.data;
2796 saltlen = p12params.salt.length;
2798 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2799 PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2800 ret = HX509_CRYPTO_INTERNAL_ERROR;
2801 goto out;
2804 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2805 PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2806 ret = HX509_CRYPTO_INTERNAL_ERROR;
2807 goto out;
2810 ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2811 if (ret)
2812 goto out;
2814 hx509_crypto_allow_weak(c);
2816 ret = hx509_crypto_set_key_data(c, key->data, key->length);
2817 if (ret) {
2818 hx509_crypto_destroy(c);
2819 goto out;
2822 *crypto = c;
2823 out:
2824 free_PKCS12_PBEParams(&p12params);
2825 return ret;
2828 static const heim_oid *
2829 find_string2key(const heim_oid *oid,
2830 const EVP_CIPHER **c,
2831 const EVP_MD **md,
2832 PBE_string2key_func *s2k)
2834 if (der_heim_oid_cmp(oid, &asn1_oid_id_pbewithSHAAnd40BitRC2_CBC) == 0) {
2835 *c = EVP_rc2_40_cbc();
2836 *md = EVP_sha1();
2837 *s2k = PBE_string2key;
2838 return &asn1_oid_private_rc2_40;
2839 } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC2_CBC) == 0) {
2840 *c = EVP_rc2_cbc();
2841 *md = EVP_sha1();
2842 *s2k = PBE_string2key;
2843 return &asn1_oid_id_pkcs3_rc2_cbc;
2844 #if 0
2845 } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd40BitRC4) == 0) {
2846 *c = EVP_rc4_40();
2847 *md = EVP_sha1();
2848 *s2k = PBE_string2key;
2849 return NULL;
2850 } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd128BitRC4) == 0) {
2851 *c = EVP_rc4();
2852 *md = EVP_sha1();
2853 *s2k = PBE_string2key;
2854 return &asn1_oid_id_pkcs3_rc4;
2855 #endif
2856 } else if (der_heim_oid_cmp(oid, &asn1_oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC) == 0) {
2857 *c = EVP_des_ede3_cbc();
2858 *md = EVP_sha1();
2859 *s2k = PBE_string2key;
2860 return &asn1_oid_id_pkcs3_des_ede3_cbc;
2863 return NULL;
2871 _hx509_pbe_encrypt(hx509_context context,
2872 hx509_lock lock,
2873 const AlgorithmIdentifier *ai,
2874 const heim_octet_string *content,
2875 heim_octet_string *econtent)
2877 hx509_clear_error_string(context);
2878 return EINVAL;
2886 _hx509_pbe_decrypt(hx509_context context,
2887 hx509_lock lock,
2888 const AlgorithmIdentifier *ai,
2889 const heim_octet_string *econtent,
2890 heim_octet_string *content)
2892 const struct _hx509_password *pw;
2893 heim_octet_string key, iv;
2894 const heim_oid *enc_oid;
2895 const EVP_CIPHER *c;
2896 const EVP_MD *md;
2897 PBE_string2key_func s2k;
2898 int i, ret = 0;
2900 memset(&key, 0, sizeof(key));
2901 memset(&iv, 0, sizeof(iv));
2903 memset(content, 0, sizeof(*content));
2905 enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2906 if (enc_oid == NULL) {
2907 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2908 "String to key algorithm not supported");
2909 ret = HX509_ALG_NOT_SUPP;
2910 goto out;
2913 key.length = EVP_CIPHER_key_length(c);
2914 key.data = malloc(key.length);
2915 if (key.data == NULL) {
2916 ret = ENOMEM;
2917 hx509_clear_error_string(context);
2918 goto out;
2921 iv.length = EVP_CIPHER_iv_length(c);
2922 iv.data = malloc(iv.length);
2923 if (iv.data == NULL) {
2924 ret = ENOMEM;
2925 hx509_clear_error_string(context);
2926 goto out;
2929 pw = _hx509_lock_get_passwords(lock);
2931 ret = HX509_CRYPTO_INTERNAL_ERROR;
2932 for (i = 0; i < pw->len + 1; i++) {
2933 hx509_crypto crypto;
2934 const char *password;
2936 if (i < pw->len)
2937 password = pw->val[i];
2938 else if (i < pw->len + 1)
2939 password = "";
2940 else
2941 password = NULL;
2943 ret = (*s2k)(context, password, ai->parameters, &crypto,
2944 &key, &iv, enc_oid, md);
2945 if (ret)
2946 goto out;
2948 ret = hx509_crypto_decrypt(crypto,
2949 econtent->data,
2950 econtent->length,
2951 &iv,
2952 content);
2953 hx509_crypto_destroy(crypto);
2954 if (ret == 0)
2955 goto out;
2958 out:
2959 if (key.data)
2960 der_free_octet_string(&key);
2961 if (iv.data)
2962 der_free_octet_string(&iv);
2963 return ret;
2971 static int
2972 match_keys_rsa(hx509_cert c, hx509_private_key private_key)
2974 const Certificate *cert;
2975 const SubjectPublicKeyInfo *spi;
2976 RSAPublicKey pk;
2977 RSA *rsa;
2978 size_t size;
2979 int ret;
2981 if (private_key->private_key.rsa == NULL)
2982 return 0;
2984 rsa = private_key->private_key.rsa;
2985 if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2986 return 0;
2988 cert = _hx509_get_cert(c);
2989 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2991 rsa = RSA_new();
2992 if (rsa == NULL)
2993 return 0;
2995 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2996 spi->subjectPublicKey.length / 8,
2997 &pk, &size);
2998 if (ret) {
2999 RSA_free(rsa);
3000 return 0;
3002 rsa->n = heim_int2BN(&pk.modulus);
3003 rsa->e = heim_int2BN(&pk.publicExponent);
3005 free_RSAPublicKey(&pk);
3007 rsa->d = BN_dup(private_key->private_key.rsa->d);
3008 rsa->p = BN_dup(private_key->private_key.rsa->p);
3009 rsa->q = BN_dup(private_key->private_key.rsa->q);
3010 rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
3011 rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
3012 rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
3014 if (rsa->n == NULL || rsa->e == NULL ||
3015 rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
3016 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
3017 RSA_free(rsa);
3018 return 0;
3021 ret = RSA_check_key(rsa);
3022 RSA_free(rsa);
3024 return ret == 1;
3027 static int
3028 match_keys_ec(hx509_cert c, hx509_private_key private_key)
3030 return 1; /* XXX use EC_KEY_check_key */
3035 _hx509_match_keys(hx509_cert c, hx509_private_key key)
3037 if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_pkcs1_rsaEncryption) == 0)
3038 return match_keys_rsa(c, key);
3039 if (der_heim_oid_cmp(key->ops->key_oid, &asn1_oid_id_ecPublicKey) == 0)
3040 return match_keys_ec(c, key);
3041 return 0;
3046 static const heim_oid *
3047 find_keytype(const hx509_private_key key)
3049 const struct signature_alg *md;
3051 if (key == NULL)
3052 return NULL;
3054 md = find_sig_alg(key->signature_alg);
3055 if (md == NULL)
3056 return NULL;
3057 return md->key_oid;
3061 hx509_crypto_select(const hx509_context context,
3062 int type,
3063 const hx509_private_key source,
3064 hx509_peer_info peer,
3065 AlgorithmIdentifier *selected)
3067 const AlgorithmIdentifier *def = NULL;
3068 size_t i, j;
3069 int ret, bits;
3071 memset(selected, 0, sizeof(*selected));
3073 if (type == HX509_SELECT_DIGEST) {
3074 bits = SIG_DIGEST;
3075 if (source)
3076 def = alg_for_privatekey(source, type);
3077 if (def == NULL)
3078 def = _hx509_crypto_default_digest_alg;
3079 } else if (type == HX509_SELECT_PUBLIC_SIG) {
3080 bits = SIG_PUBLIC_SIG;
3081 /* XXX depend on `source´ and `peer´ */
3082 if (source)
3083 def = alg_for_privatekey(source, type);
3084 if (def == NULL)
3085 def = _hx509_crypto_default_sig_alg;
3086 } else if (type == HX509_SELECT_SECRET_ENC) {
3087 bits = SIG_SECRET;
3088 def = _hx509_crypto_default_secret_alg;
3089 } else {
3090 hx509_set_error_string(context, 0, EINVAL,
3091 "Unknown type %d of selection", type);
3092 return EINVAL;
3095 if (peer) {
3096 const heim_oid *keytype = NULL;
3098 keytype = find_keytype(source);
3100 for (i = 0; i < peer->len; i++) {
3101 for (j = 0; sig_algs[j]; j++) {
3102 if ((sig_algs[j]->flags & bits) != bits)
3103 continue;
3104 if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
3105 &peer->val[i].algorithm) != 0)
3106 continue;
3107 if (keytype && sig_algs[j]->key_oid &&
3108 der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
3109 continue;
3111 /* found one, use that */
3112 ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
3113 if (ret)
3114 hx509_clear_error_string(context);
3115 return ret;
3117 if (bits & SIG_SECRET) {
3118 const struct hx509cipher *cipher;
3120 cipher = find_cipher_by_oid(&peer->val[i].algorithm);
3121 if (cipher == NULL)
3122 continue;
3123 if (cipher->ai_func == NULL)
3124 continue;
3125 ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
3126 if (ret)
3127 hx509_clear_error_string(context);
3128 return ret;
3133 /* use default */
3134 ret = copy_AlgorithmIdentifier(def, selected);
3135 if (ret)
3136 hx509_clear_error_string(context);
3137 return ret;
3141 hx509_crypto_available(hx509_context context,
3142 int type,
3143 hx509_cert source,
3144 AlgorithmIdentifier **val,
3145 unsigned int *plen)
3147 const heim_oid *keytype = NULL;
3148 unsigned int len, i;
3149 void *ptr;
3150 int bits, ret;
3152 *val = NULL;
3154 if (type == HX509_SELECT_ALL) {
3155 bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
3156 } else if (type == HX509_SELECT_DIGEST) {
3157 bits = SIG_DIGEST;
3158 } else if (type == HX509_SELECT_PUBLIC_SIG) {
3159 bits = SIG_PUBLIC_SIG;
3160 } else {
3161 hx509_set_error_string(context, 0, EINVAL,
3162 "Unknown type %d of available", type);
3163 return EINVAL;
3166 if (source)
3167 keytype = find_keytype(_hx509_cert_private_key(source));
3169 len = 0;
3170 for (i = 0; sig_algs[i]; i++) {
3171 if ((sig_algs[i]->flags & bits) == 0)
3172 continue;
3173 if (sig_algs[i]->sig_alg == NULL)
3174 continue;
3175 if (keytype && sig_algs[i]->key_oid &&
3176 der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
3177 continue;
3179 /* found one, add that to the list */
3180 ptr = realloc(*val, sizeof(**val) * (len + 1));
3181 if (ptr == NULL)
3182 goto out;
3183 *val = ptr;
3185 ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
3186 if (ret)
3187 goto out;
3188 len++;
3191 /* Add AES */
3192 if (bits & SIG_SECRET) {
3194 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
3196 if (ciphers[i].flags & CIPHER_WEAK)
3197 continue;
3198 if (ciphers[i].ai_func == NULL)
3199 continue;
3201 ptr = realloc(*val, sizeof(**val) * (len + 1));
3202 if (ptr == NULL)
3203 goto out;
3204 *val = ptr;
3206 ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
3207 if (ret)
3208 goto out;
3209 len++;
3213 *plen = len;
3214 return 0;
3216 out:
3217 for (i = 0; i < len; i++)
3218 free_AlgorithmIdentifier(&(*val)[i]);
3219 free(*val);
3220 *val = NULL;
3221 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
3222 return ENOMEM;
3225 void
3226 hx509_crypto_free_algs(AlgorithmIdentifier *val,
3227 unsigned int len)
3229 unsigned int i;
3230 for (i = 0; i < len; i++)
3231 free_AlgorithmIdentifier(&val[i]);
3232 free(val);