Use anon realm for anonymous PKINIT
[heimdal.git] / lib / hx509 / crypto.c
blobb308ee2e6c161970eb64611088535b5676f2e5ca
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 hx509_key_format_t,
57 heim_octet_string *);
58 int (*import)(hx509_context, const AlgorithmIdentifier *,
59 const void *, size_t, hx509_key_format_t,
60 hx509_private_key);
61 int (*generate_private_key)(hx509_context,
62 struct hx509_generate_private_context *,
63 hx509_private_key);
64 BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
67 struct hx509_private_key {
68 unsigned int ref;
69 const struct signature_alg *md;
70 const heim_oid *signature_alg;
71 union {
72 RSA *rsa;
73 void *keydata;
74 #ifdef HAVE_OPENSSL
75 EC_KEY *ecdsa;
76 #endif
77 } private_key;
78 hx509_private_key_ops *ops;
85 struct signature_alg {
86 const char *name;
87 const heim_oid *sig_oid;
88 const AlgorithmIdentifier *sig_alg;
89 const heim_oid *key_oid;
90 const AlgorithmIdentifier *digest_alg;
91 int flags;
92 #define PROVIDE_CONF 0x1
93 #define REQUIRE_SIGNER 0x2
94 #define SELF_SIGNED_OK 0x4
95 #define WEAK_SIG_ALG 0x8
97 #define SIG_DIGEST 0x100
98 #define SIG_PUBLIC_SIG 0x200
99 #define SIG_SECRET 0x400
101 #define RA_RSA_USES_DIGEST_INFO 0x1000000
103 time_t best_before; /* refuse signature made after best before date */
104 const EVP_MD *(*evp_md)(void);
105 int (*verify_signature)(hx509_context context,
106 const struct signature_alg *,
107 const Certificate *,
108 const AlgorithmIdentifier *,
109 const heim_octet_string *,
110 const heim_octet_string *);
111 int (*create_signature)(hx509_context,
112 const struct signature_alg *,
113 const hx509_private_key,
114 const AlgorithmIdentifier *,
115 const heim_octet_string *,
116 AlgorithmIdentifier *,
117 heim_octet_string *);
118 int digest_size;
121 static const struct signature_alg *
122 find_sig_alg(const heim_oid *oid);
128 static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
130 static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
131 const AlgorithmIdentifier _hx509_signature_sha512_data = {
132 { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
135 static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
136 const AlgorithmIdentifier _hx509_signature_sha384_data = {
137 { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
140 static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
141 const AlgorithmIdentifier _hx509_signature_sha256_data = {
142 { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
145 static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
146 const AlgorithmIdentifier _hx509_signature_sha1_data = {
147 { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
150 static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
151 const AlgorithmIdentifier _hx509_signature_md5_data = {
152 { 6, rk_UNCONST(md5_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_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
196 const AlgorithmIdentifier _hx509_signature_rsa_data = {
197 { 7, rk_UNCONST(rsa_oid) }, NULL
200 static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
201 const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
202 { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
205 static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
206 const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
207 { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
210 static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
211 const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
212 { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
215 static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
216 const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
217 { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
224 static BIGNUM *
225 heim_int2BN(const heim_integer *i)
227 BIGNUM *bn;
229 bn = BN_bin2bn(i->data, i->length, NULL);
230 BN_set_negative(bn, i->negative);
231 return bn;
238 static int
239 set_digest_alg(DigestAlgorithmIdentifier *id,
240 const heim_oid *oid,
241 const void *param, size_t length)
243 int ret;
244 if (param) {
245 id->parameters = malloc(sizeof(*id->parameters));
246 if (id->parameters == NULL)
247 return ENOMEM;
248 id->parameters->data = malloc(length);
249 if (id->parameters->data == NULL) {
250 free(id->parameters);
251 id->parameters = NULL;
252 return ENOMEM;
254 memcpy(id->parameters->data, param, length);
255 id->parameters->length = length;
256 } else
257 id->parameters = NULL;
258 ret = der_copy_oid(oid, &id->algorithm);
259 if (ret) {
260 if (id->parameters) {
261 free(id->parameters->data);
262 free(id->parameters);
263 id->parameters = NULL;
265 return ret;
267 return 0;
270 #ifdef HAVE_OPENSSL
272 static int
273 heim_oid2ecnid(heim_oid *oid)
276 * Now map to openssl OID fun
279 if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0)
280 return NID_X9_62_prime256v1;
281 else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0)
282 return NID_secp160r1;
283 else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0)
284 return NID_secp160r2;
286 return -1;
289 static int
290 parse_ECParameters(hx509_context context,
291 heim_octet_string *parameters, int *nid)
293 ECParameters ecparam;
294 size_t size;
295 int ret;
297 if (parameters == NULL) {
298 ret = HX509_PARSING_KEY_FAILED;
299 hx509_set_error_string(context, 0, ret,
300 "EC parameters missing");
301 return ret;
304 ret = decode_ECParameters(parameters->data, parameters->length,
305 &ecparam, &size);
306 if (ret) {
307 hx509_set_error_string(context, 0, ret,
308 "Failed to decode EC parameters");
309 return ret;
312 if (ecparam.element != choice_ECParameters_namedCurve) {
313 free_ECParameters(&ecparam);
314 hx509_set_error_string(context, 0, ret,
315 "EC parameters is not a named curve");
316 return HX509_CRYPTO_SIG_INVALID_FORMAT;
319 *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
320 free_ECParameters(&ecparam);
321 if (*nid == -1) {
322 hx509_set_error_string(context, 0, ret,
323 "Failed to find matcing NID for EC curve");
324 return HX509_CRYPTO_SIG_INVALID_FORMAT;
326 return 0;
334 static int
335 ecdsa_verify_signature(hx509_context context,
336 const struct signature_alg *sig_alg,
337 const Certificate *signer,
338 const AlgorithmIdentifier *alg,
339 const heim_octet_string *data,
340 const heim_octet_string *sig)
342 const AlgorithmIdentifier *digest_alg;
343 const SubjectPublicKeyInfo *spi;
344 heim_octet_string digest;
345 int ret;
346 EC_KEY *key = NULL;
347 int groupnid;
348 EC_GROUP *group;
349 const unsigned char *p;
350 long len;
352 digest_alg = sig_alg->digest_alg;
354 ret = _hx509_create_signature(context,
355 NULL,
356 digest_alg,
357 data,
358 NULL,
359 &digest);
360 if (ret)
361 return ret;
363 /* set up EC KEY */
364 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
366 if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0)
367 return HX509_CRYPTO_SIG_INVALID_FORMAT;
369 #ifdef HAVE_OPENSSL
371 * Find the group id
374 ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
375 if (ret) {
376 der_free_octet_string(&digest);
377 return ret;
381 * Create group, key, parse key
384 key = EC_KEY_new();
385 group = EC_GROUP_new_by_curve_name(groupnid);
386 EC_KEY_set_group(key, group);
387 EC_GROUP_free(group);
389 p = spi->subjectPublicKey.data;
390 len = spi->subjectPublicKey.length / 8;
392 if (o2i_ECPublicKey(&key, &p, len) == NULL) {
393 EC_KEY_free(key);
394 return HX509_CRYPTO_SIG_INVALID_FORMAT;
396 #else
397 key = SubjectPublicKeyInfo2EC_KEY(spi);
398 #endif
400 ret = ECDSA_verify(-1, digest.data, digest.length,
401 sig->data, sig->length, key);
402 der_free_octet_string(&digest);
403 EC_KEY_free(key);
404 if (ret != 1) {
405 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
406 return ret;
409 return 0;
412 static int
413 ecdsa_create_signature(hx509_context context,
414 const struct signature_alg *sig_alg,
415 const hx509_private_key signer,
416 const AlgorithmIdentifier *alg,
417 const heim_octet_string *data,
418 AlgorithmIdentifier *signatureAlgorithm,
419 heim_octet_string *sig)
421 const AlgorithmIdentifier *digest_alg;
422 heim_octet_string indata;
423 const heim_oid *sig_oid;
424 unsigned int siglen;
425 int ret;
427 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0)
428 _hx509_abort("internal error passing private key to wrong ops");
430 sig_oid = sig_alg->sig_oid;
431 digest_alg = sig_alg->digest_alg;
433 if (signatureAlgorithm) {
434 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
435 if (ret) {
436 hx509_clear_error_string(context);
437 goto error;
441 ret = _hx509_create_signature(context,
442 NULL,
443 digest_alg,
444 data,
445 NULL,
446 &indata);
447 if (ret) {
448 if (signatureAlgorithm)
449 free_AlgorithmIdentifier(signatureAlgorithm);
450 goto error;
453 sig->length = ECDSA_size(signer->private_key.ecdsa);
454 sig->data = malloc(sig->length);
455 if (sig->data == NULL) {
456 der_free_octet_string(&indata);
457 ret = ENOMEM;
458 hx509_set_error_string(context, 0, ret, "out of memory");
459 goto error;
462 siglen = sig->length;
464 ret = ECDSA_sign(-1, indata.data, indata.length,
465 sig->data, &siglen, signer->private_key.ecdsa);
466 der_free_octet_string(&indata);
467 if (ret != 1) {
468 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
469 hx509_set_error_string(context, 0, ret,
470 "ECDSA sign failed: %d", ret);
471 goto error;
473 if (siglen > sig->length)
474 _hx509_abort("ECDSA signature prelen longer the output len");
476 sig->length = siglen;
478 return 0;
479 error:
480 if (signatureAlgorithm)
481 free_AlgorithmIdentifier(signatureAlgorithm);
482 return ret;
485 static int
486 ecdsa_available(const hx509_private_key signer,
487 const AlgorithmIdentifier *sig_alg)
489 const struct signature_alg *sig;
490 const EC_GROUP *group;
491 BN_CTX *bnctx = NULL;
492 BIGNUM *order = NULL;
493 int ret = 0;
495 if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
496 _hx509_abort("internal error passing private key to wrong ops");
498 sig = find_sig_alg(&sig_alg->algorithm);
500 if (sig == NULL || sig->digest_size == 0)
501 return 0;
503 group = EC_KEY_get0_group(signer->private_key.ecdsa);
504 if (group == NULL)
505 return 0;
507 bnctx = BN_CTX_new();
508 order = BN_new();
509 if (order == NULL)
510 goto err;
512 if (EC_GROUP_get_order(group, order, bnctx) != 1)
513 goto err;
515 if (BN_num_bytes(order) > sig->digest_size)
516 ret = 1;
517 err:
518 if (bnctx)
519 BN_CTX_free(bnctx);
520 if (order)
521 BN_clear_free(order);
523 return ret;
527 #endif /* HAVE_OPENSSL */
533 static int
534 rsa_verify_signature(hx509_context context,
535 const struct signature_alg *sig_alg,
536 const Certificate *signer,
537 const AlgorithmIdentifier *alg,
538 const heim_octet_string *data,
539 const heim_octet_string *sig)
541 const SubjectPublicKeyInfo *spi;
542 DigestInfo di;
543 unsigned char *to;
544 int tosize, retsize;
545 int ret;
546 RSA *rsa;
547 size_t size;
548 const unsigned char *p;
550 memset(&di, 0, sizeof(di));
552 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
554 p = spi->subjectPublicKey.data;
555 size = spi->subjectPublicKey.length / 8;
557 rsa = d2i_RSAPublicKey(NULL, &p, size);
558 if (rsa == NULL) {
559 ret = ENOMEM;
560 hx509_set_error_string(context, 0, ret, "out of memory");
561 goto out;
564 tosize = RSA_size(rsa);
565 to = malloc(tosize);
566 if (to == NULL) {
567 ret = ENOMEM;
568 hx509_set_error_string(context, 0, ret, "out of memory");
569 goto out;
572 retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
573 to, rsa, RSA_PKCS1_PADDING);
574 if (retsize <= 0) {
575 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
576 hx509_set_error_string(context, 0, ret,
577 "RSA public decrypt failed: %d", retsize);
578 free(to);
579 goto out;
581 if (retsize > tosize)
582 _hx509_abort("internal rsa decryption failure: ret > tosize");
584 if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
586 ret = decode_DigestInfo(to, retsize, &di, &size);
587 free(to);
588 if (ret) {
589 goto out;
592 /* Check for extra data inside the sigature */
593 if (size != (size_t)retsize) {
594 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
595 hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
596 goto out;
599 if (sig_alg->digest_alg &&
600 der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
601 &sig_alg->digest_alg->algorithm) != 0)
603 ret = HX509_CRYPTO_OID_MISMATCH;
604 hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
605 goto out;
608 /* verify that the parameters are NULL or the NULL-type */
609 if (di.digestAlgorithm.parameters != NULL &&
610 (di.digestAlgorithm.parameters->length != 2 ||
611 memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
613 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
614 hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
615 goto out;
618 ret = _hx509_verify_signature(context,
619 NULL,
620 &di.digestAlgorithm,
621 data,
622 &di.digest);
623 if (ret)
624 goto out;
626 } else {
627 if ((size_t)retsize != data->length ||
628 ct_memcmp(to, data->data, retsize) != 0)
630 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
631 hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
632 goto out;
634 free(to);
635 ret = 0;
638 out:
639 free_DigestInfo(&di);
640 if (rsa)
641 RSA_free(rsa);
642 return ret;
645 static int
646 rsa_create_signature(hx509_context context,
647 const struct signature_alg *sig_alg,
648 const hx509_private_key signer,
649 const AlgorithmIdentifier *alg,
650 const heim_octet_string *data,
651 AlgorithmIdentifier *signatureAlgorithm,
652 heim_octet_string *sig)
654 const AlgorithmIdentifier *digest_alg;
655 heim_octet_string indata;
656 const heim_oid *sig_oid;
657 size_t size;
658 int ret;
660 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0)
661 return HX509_ALG_NOT_SUPP;
663 if (alg)
664 sig_oid = &alg->algorithm;
665 else
666 sig_oid = signer->signature_alg;
668 if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
669 digest_alg = hx509_signature_sha512();
670 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
671 digest_alg = hx509_signature_sha384();
672 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
673 digest_alg = hx509_signature_sha256();
674 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
675 digest_alg = hx509_signature_sha1();
676 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
677 digest_alg = hx509_signature_md5();
678 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
679 digest_alg = hx509_signature_md5();
680 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) {
681 digest_alg = hx509_signature_sha1();
682 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
683 digest_alg = hx509_signature_sha1();
684 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) {
685 digest_alg = NULL;
686 } else
687 return HX509_ALG_NOT_SUPP;
689 if (signatureAlgorithm) {
690 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
691 if (ret) {
692 hx509_clear_error_string(context);
693 return ret;
697 if (digest_alg) {
698 DigestInfo di;
699 memset(&di, 0, sizeof(di));
701 ret = _hx509_create_signature(context,
702 NULL,
703 digest_alg,
704 data,
705 &di.digestAlgorithm,
706 &di.digest);
707 if (ret)
708 return ret;
709 ASN1_MALLOC_ENCODE(DigestInfo,
710 indata.data,
711 indata.length,
712 &di,
713 &size,
714 ret);
715 free_DigestInfo(&di);
716 if (ret) {
717 hx509_set_error_string(context, 0, ret, "out of memory");
718 return ret;
720 if (indata.length != size)
721 _hx509_abort("internal ASN.1 encoder error");
722 } else {
723 indata = *data;
726 sig->length = RSA_size(signer->private_key.rsa);
727 sig->data = malloc(sig->length);
728 if (sig->data == NULL) {
729 der_free_octet_string(&indata);
730 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
731 return ENOMEM;
734 ret = RSA_private_encrypt(indata.length, indata.data,
735 sig->data,
736 signer->private_key.rsa,
737 RSA_PKCS1_PADDING);
738 if (indata.data != data->data)
739 der_free_octet_string(&indata);
740 if (ret <= 0) {
741 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
742 hx509_set_error_string(context, 0, ret,
743 "RSA private encrypt failed: %d", ret);
744 return ret;
746 if (sig->length > (size_t)ret) {
747 size = sig->length - ret;
748 memmove((uint8_t *)sig->data + size, sig->data, ret);
749 memset(sig->data, 0, size);
750 } else if (sig->length < (size_t)ret)
751 _hx509_abort("RSA signature prelen longer the output len");
753 return 0;
756 static int
757 rsa_private_key_import(hx509_context context,
758 const AlgorithmIdentifier *keyai,
759 const void *data,
760 size_t len,
761 hx509_key_format_t format,
762 hx509_private_key private_key)
764 switch (format) {
765 case HX509_KEY_FORMAT_DER: {
766 const unsigned char *p = data;
768 private_key->private_key.rsa =
769 d2i_RSAPrivateKey(NULL, &p, len);
770 if (private_key->private_key.rsa == NULL) {
771 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
772 "Failed to parse RSA key");
773 return HX509_PARSING_KEY_FAILED;
775 private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
776 break;
779 default:
780 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
783 return 0;
786 static int
787 rsa_private_key2SPKI(hx509_context context,
788 hx509_private_key private_key,
789 SubjectPublicKeyInfo *spki)
791 int len, ret;
793 memset(spki, 0, sizeof(*spki));
795 len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
797 spki->subjectPublicKey.data = malloc(len);
798 if (spki->subjectPublicKey.data == NULL) {
799 hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
800 return ENOMEM;
802 spki->subjectPublicKey.length = len * 8;
804 ret = set_digest_alg(&spki->algorithm, ASN1_OID_ID_PKCS1_RSAENCRYPTION,
805 "\x05\x00", 2);
806 if (ret) {
807 hx509_set_error_string(context, 0, ret, "malloc - out of memory");
808 free(spki->subjectPublicKey.data);
809 spki->subjectPublicKey.data = NULL;
810 spki->subjectPublicKey.length = 0;
811 return ret;
815 unsigned char *pp = spki->subjectPublicKey.data;
816 i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
819 return 0;
822 static int
823 rsa_generate_private_key(hx509_context context,
824 struct hx509_generate_private_context *ctx,
825 hx509_private_key private_key)
827 BIGNUM *e;
828 int ret;
829 unsigned long bits;
831 static const int default_rsa_e = 65537;
832 static const int default_rsa_bits = 2048;
834 private_key->private_key.rsa = RSA_new();
835 if (private_key->private_key.rsa == NULL) {
836 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
837 "Failed to generate RSA key");
838 return HX509_PARSING_KEY_FAILED;
841 e = BN_new();
842 BN_set_word(e, default_rsa_e);
844 bits = default_rsa_bits;
846 if (ctx->num_bits)
847 bits = ctx->num_bits;
849 ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
850 BN_free(e);
851 if (ret != 1) {
852 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
853 "Failed to generate RSA key");
854 return HX509_PARSING_KEY_FAILED;
856 private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
858 return 0;
861 static int
862 rsa_private_key_export(hx509_context context,
863 const hx509_private_key key,
864 hx509_key_format_t format,
865 heim_octet_string *data)
867 int ret;
869 data->data = NULL;
870 data->length = 0;
872 switch (format) {
873 case HX509_KEY_FORMAT_DER:
875 ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
876 if (ret <= 0) {
877 ret = EINVAL;
878 hx509_set_error_string(context, 0, ret,
879 "Private key is not exportable");
880 return ret;
883 data->data = malloc(ret);
884 if (data->data == NULL) {
885 ret = ENOMEM;
886 hx509_set_error_string(context, 0, ret, "malloc out of memory");
887 return ret;
889 data->length = ret;
892 unsigned char *p = data->data;
893 i2d_RSAPrivateKey(key->private_key.rsa, &p);
895 break;
896 default:
897 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
900 return 0;
903 static BIGNUM *
904 rsa_get_internal(hx509_context context,
905 hx509_private_key key,
906 const char *type)
908 if (strcasecmp(type, "rsa-modulus") == 0) {
909 return BN_dup(key->private_key.rsa->n);
910 } else if (strcasecmp(type, "rsa-exponent") == 0) {
911 return BN_dup(key->private_key.rsa->e);
912 } else
913 return NULL;
918 static hx509_private_key_ops rsa_private_key_ops = {
919 "RSA PRIVATE KEY",
920 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
921 NULL,
922 rsa_private_key2SPKI,
923 rsa_private_key_export,
924 rsa_private_key_import,
925 rsa_generate_private_key,
926 rsa_get_internal
929 #ifdef HAVE_OPENSSL
931 static int
932 ecdsa_private_key2SPKI(hx509_context context,
933 hx509_private_key private_key,
934 SubjectPublicKeyInfo *spki)
936 memset(spki, 0, sizeof(*spki));
937 return ENOMEM;
940 static int
941 ecdsa_private_key_export(hx509_context context,
942 const hx509_private_key key,
943 hx509_key_format_t format,
944 heim_octet_string *data)
946 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
949 static int
950 ecdsa_private_key_import(hx509_context context,
951 const AlgorithmIdentifier *keyai,
952 const void *data,
953 size_t len,
954 hx509_key_format_t format,
955 hx509_private_key private_key)
957 const unsigned char *p = data;
958 EC_KEY **pkey = NULL;
960 if (keyai->parameters) {
961 EC_GROUP *group;
962 int groupnid;
963 EC_KEY *key;
964 int ret;
966 ret = parse_ECParameters(context, keyai->parameters, &groupnid);
967 if (ret)
968 return ret;
970 key = EC_KEY_new();
971 if (key == NULL)
972 return ENOMEM;
974 group = EC_GROUP_new_by_curve_name(groupnid);
975 if (group == NULL) {
976 EC_KEY_free(key);
977 return ENOMEM;
979 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
980 if (EC_KEY_set_group(key, group) == 0) {
981 EC_KEY_free(key);
982 EC_GROUP_free(group);
983 return ENOMEM;
985 EC_GROUP_free(group);
986 pkey = &key;
989 switch (format) {
990 case HX509_KEY_FORMAT_DER:
992 private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
993 if (private_key->private_key.ecdsa == NULL) {
994 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
995 "Failed to parse EC private key");
996 return HX509_PARSING_KEY_FAILED;
998 private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256;
999 break;
1001 default:
1002 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
1005 return 0;
1008 static int
1009 ecdsa_generate_private_key(hx509_context context,
1010 struct hx509_generate_private_context *ctx,
1011 hx509_private_key private_key)
1013 return ENOMEM;
1016 static BIGNUM *
1017 ecdsa_get_internal(hx509_context context,
1018 hx509_private_key key,
1019 const char *type)
1021 return NULL;
1025 static hx509_private_key_ops ecdsa_private_key_ops = {
1026 "EC PRIVATE KEY",
1027 ASN1_OID_ID_ECPUBLICKEY,
1028 ecdsa_available,
1029 ecdsa_private_key2SPKI,
1030 ecdsa_private_key_export,
1031 ecdsa_private_key_import,
1032 ecdsa_generate_private_key,
1033 ecdsa_get_internal
1036 #endif /* HAVE_OPENSSL */
1042 static int
1043 dsa_verify_signature(hx509_context context,
1044 const struct signature_alg *sig_alg,
1045 const Certificate *signer,
1046 const AlgorithmIdentifier *alg,
1047 const heim_octet_string *data,
1048 const heim_octet_string *sig)
1050 const SubjectPublicKeyInfo *spi;
1051 DSAPublicKey pk;
1052 DSAParams param;
1053 size_t size;
1054 DSA *dsa;
1055 int ret;
1057 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1059 dsa = DSA_new();
1060 if (dsa == NULL) {
1061 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1062 return ENOMEM;
1065 ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
1066 spi->subjectPublicKey.length / 8,
1067 &pk, &size);
1068 if (ret)
1069 goto out;
1071 dsa->pub_key = heim_int2BN(&pk);
1073 free_DSAPublicKey(&pk);
1075 if (dsa->pub_key == NULL) {
1076 ret = ENOMEM;
1077 hx509_set_error_string(context, 0, ret, "out of memory");
1078 goto out;
1081 if (spi->algorithm.parameters == NULL) {
1082 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
1083 hx509_set_error_string(context, 0, ret, "DSA parameters missing");
1084 goto out;
1087 ret = decode_DSAParams(spi->algorithm.parameters->data,
1088 spi->algorithm.parameters->length,
1089 &param,
1090 &size);
1091 if (ret) {
1092 hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
1093 goto out;
1096 dsa->p = heim_int2BN(&param.p);
1097 dsa->q = heim_int2BN(&param.q);
1098 dsa->g = heim_int2BN(&param.g);
1100 free_DSAParams(&param);
1102 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
1103 ret = ENOMEM;
1104 hx509_set_error_string(context, 0, ret, "out of memory");
1105 goto out;
1108 ret = DSA_verify(-1, data->data, data->length,
1109 (unsigned char*)sig->data, sig->length,
1110 dsa);
1111 if (ret == 1)
1112 ret = 0;
1113 else if (ret == 0 || ret == -1) {
1114 ret = HX509_CRYPTO_BAD_SIGNATURE;
1115 hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
1116 } else {
1117 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
1118 hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
1121 out:
1122 DSA_free(dsa);
1124 return ret;
1127 #if 0
1128 static int
1129 dsa_parse_private_key(hx509_context context,
1130 const void *data,
1131 size_t len,
1132 hx509_private_key private_key)
1134 const unsigned char *p = data;
1136 private_key->private_key.dsa =
1137 d2i_DSAPrivateKey(NULL, &p, len);
1138 if (private_key->private_key.dsa == NULL)
1139 return EINVAL;
1140 private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1;
1142 return 0;
1143 /* else */
1144 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1145 "No support to parse DSA keys");
1146 return HX509_PARSING_KEY_FAILED;
1148 #endif
1150 static int
1151 evp_md_create_signature(hx509_context context,
1152 const struct signature_alg *sig_alg,
1153 const hx509_private_key signer,
1154 const AlgorithmIdentifier *alg,
1155 const heim_octet_string *data,
1156 AlgorithmIdentifier *signatureAlgorithm,
1157 heim_octet_string *sig)
1159 size_t sigsize = EVP_MD_size(sig_alg->evp_md());
1160 EVP_MD_CTX *ctx;
1162 memset(sig, 0, sizeof(*sig));
1164 if (signatureAlgorithm) {
1165 int ret;
1166 ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
1167 "\x05\x00", 2);
1168 if (ret)
1169 return ret;
1173 sig->data = malloc(sigsize);
1174 if (sig->data == NULL) {
1175 sig->length = 0;
1176 return ENOMEM;
1178 sig->length = sigsize;
1180 ctx = EVP_MD_CTX_create();
1181 EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
1182 EVP_DigestUpdate(ctx, data->data, data->length);
1183 EVP_DigestFinal_ex(ctx, sig->data, NULL);
1184 EVP_MD_CTX_destroy(ctx);
1187 return 0;
1190 static int
1191 evp_md_verify_signature(hx509_context context,
1192 const struct signature_alg *sig_alg,
1193 const Certificate *signer,
1194 const AlgorithmIdentifier *alg,
1195 const heim_octet_string *data,
1196 const heim_octet_string *sig)
1198 unsigned char digest[EVP_MAX_MD_SIZE];
1199 EVP_MD_CTX *ctx;
1200 size_t sigsize = EVP_MD_size(sig_alg->evp_md());
1202 if (sig->length != sigsize || sigsize > sizeof(digest)) {
1203 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1204 "SHA256 sigature have wrong length");
1205 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1208 ctx = EVP_MD_CTX_create();
1209 EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
1210 EVP_DigestUpdate(ctx, data->data, data->length);
1211 EVP_DigestFinal_ex(ctx, digest, NULL);
1212 EVP_MD_CTX_destroy(ctx);
1214 if (ct_memcmp(digest, sig->data, sigsize) != 0) {
1215 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
1216 "Bad %s sigature", sig_alg->name);
1217 return HX509_CRYPTO_BAD_SIGNATURE;
1220 return 0;
1223 #ifdef HAVE_OPENSSL
1225 static const struct signature_alg ecdsa_with_sha256_alg = {
1226 "ecdsa-with-sha256",
1227 ASN1_OID_ID_ECDSA_WITH_SHA256,
1228 &_hx509_signature_ecdsa_with_sha256_data,
1229 ASN1_OID_ID_ECPUBLICKEY,
1230 &_hx509_signature_sha256_data,
1231 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1233 NULL,
1234 ecdsa_verify_signature,
1235 ecdsa_create_signature,
1239 static const struct signature_alg ecdsa_with_sha1_alg = {
1240 "ecdsa-with-sha1",
1241 ASN1_OID_ID_ECDSA_WITH_SHA1,
1242 &_hx509_signature_ecdsa_with_sha1_data,
1243 ASN1_OID_ID_ECPUBLICKEY,
1244 &_hx509_signature_sha1_data,
1245 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1247 NULL,
1248 ecdsa_verify_signature,
1249 ecdsa_create_signature,
1253 #endif
1255 static const struct signature_alg heim_rsa_pkcs1_x509 = {
1256 "rsa-pkcs1-x509",
1257 ASN1_OID_ID_HEIM_RSA_PKCS1_X509,
1258 &_hx509_signature_rsa_pkcs1_x509_data,
1259 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1260 NULL,
1261 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
1263 NULL,
1264 rsa_verify_signature,
1265 rsa_create_signature,
1269 static const struct signature_alg pkcs1_rsa_sha1_alg = {
1270 "rsa",
1271 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1272 &_hx509_signature_rsa_with_sha1_data,
1273 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1274 NULL,
1275 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1277 NULL,
1278 rsa_verify_signature,
1279 rsa_create_signature,
1283 static const struct signature_alg rsa_with_sha512_alg = {
1284 "rsa-with-sha512",
1285 ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION,
1286 &_hx509_signature_rsa_with_sha512_data,
1287 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1288 &_hx509_signature_sha512_data,
1289 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1291 NULL,
1292 rsa_verify_signature,
1293 rsa_create_signature,
1297 static const struct signature_alg rsa_with_sha384_alg = {
1298 "rsa-with-sha384",
1299 ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION,
1300 &_hx509_signature_rsa_with_sha384_data,
1301 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1302 &_hx509_signature_sha384_data,
1303 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1305 NULL,
1306 rsa_verify_signature,
1307 rsa_create_signature,
1311 static const struct signature_alg rsa_with_sha256_alg = {
1312 "rsa-with-sha256",
1313 ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
1314 &_hx509_signature_rsa_with_sha256_data,
1315 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1316 &_hx509_signature_sha256_data,
1317 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1319 NULL,
1320 rsa_verify_signature,
1321 rsa_create_signature,
1325 static const struct signature_alg rsa_with_sha1_alg = {
1326 "rsa-with-sha1",
1327 ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION,
1328 &_hx509_signature_rsa_with_sha1_data,
1329 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1330 &_hx509_signature_sha1_data,
1331 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1333 NULL,
1334 rsa_verify_signature,
1335 rsa_create_signature,
1339 static const struct signature_alg rsa_with_sha1_alg_secsig = {
1340 "rsa-with-sha1",
1341 ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION,
1342 &_hx509_signature_rsa_with_sha1_data,
1343 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1344 &_hx509_signature_sha1_data,
1345 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1347 NULL,
1348 rsa_verify_signature,
1349 rsa_create_signature,
1353 static const struct signature_alg rsa_with_md5_alg = {
1354 "rsa-with-md5",
1355 ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION,
1356 &_hx509_signature_rsa_with_md5_data,
1357 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1358 &_hx509_signature_md5_data,
1359 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|WEAK_SIG_ALG,
1360 1230739889,
1361 NULL,
1362 rsa_verify_signature,
1363 rsa_create_signature,
1367 static const struct signature_alg dsa_sha1_alg = {
1368 "dsa-with-sha1",
1369 ASN1_OID_ID_DSA_WITH_SHA1,
1370 NULL,
1371 ASN1_OID_ID_DSA,
1372 &_hx509_signature_sha1_data,
1373 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
1375 NULL,
1376 dsa_verify_signature,
1377 /* create_signature */ NULL,
1381 static const struct signature_alg sha512_alg = {
1382 "sha-512",
1383 ASN1_OID_ID_SHA512,
1384 &_hx509_signature_sha512_data,
1385 NULL,
1386 NULL,
1387 SIG_DIGEST,
1389 EVP_sha512,
1390 evp_md_verify_signature,
1391 evp_md_create_signature,
1395 static const struct signature_alg sha384_alg = {
1396 "sha-384",
1397 ASN1_OID_ID_SHA512,
1398 &_hx509_signature_sha384_data,
1399 NULL,
1400 NULL,
1401 SIG_DIGEST,
1403 EVP_sha384,
1404 evp_md_verify_signature,
1405 evp_md_create_signature,
1409 static const struct signature_alg sha256_alg = {
1410 "sha-256",
1411 ASN1_OID_ID_SHA256,
1412 &_hx509_signature_sha256_data,
1413 NULL,
1414 NULL,
1415 SIG_DIGEST,
1417 EVP_sha256,
1418 evp_md_verify_signature,
1419 evp_md_create_signature,
1423 static const struct signature_alg sha1_alg = {
1424 "sha1",
1425 ASN1_OID_ID_SECSIG_SHA_1,
1426 &_hx509_signature_sha1_data,
1427 NULL,
1428 NULL,
1429 SIG_DIGEST,
1431 EVP_sha1,
1432 evp_md_verify_signature,
1433 evp_md_create_signature,
1437 static const struct signature_alg md5_alg = {
1438 "rsa-md5",
1439 ASN1_OID_ID_RSA_DIGEST_MD5,
1440 &_hx509_signature_md5_data,
1441 NULL,
1442 NULL,
1443 SIG_DIGEST|WEAK_SIG_ALG,
1445 EVP_md5,
1446 evp_md_verify_signature,
1447 NULL,
1452 * Order matter in this structure, "best" first for each "key
1453 * compatible" type (type is ECDSA, RSA, DSA, none, etc)
1456 static const struct signature_alg *sig_algs[] = {
1457 #ifdef HAVE_OPENSSL
1458 &ecdsa_with_sha256_alg,
1459 &ecdsa_with_sha1_alg,
1460 #endif
1461 &rsa_with_sha512_alg,
1462 &rsa_with_sha384_alg,
1463 &rsa_with_sha256_alg,
1464 &rsa_with_sha1_alg,
1465 &rsa_with_sha1_alg_secsig,
1466 &pkcs1_rsa_sha1_alg,
1467 &rsa_with_md5_alg,
1468 &heim_rsa_pkcs1_x509,
1469 &dsa_sha1_alg,
1470 &sha512_alg,
1471 &sha384_alg,
1472 &sha256_alg,
1473 &sha1_alg,
1474 &md5_alg,
1475 NULL
1478 static const struct signature_alg *
1479 find_sig_alg(const heim_oid *oid)
1481 unsigned int i;
1482 for (i = 0; sig_algs[i]; i++)
1483 if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
1484 return sig_algs[i];
1485 return NULL;
1488 static const AlgorithmIdentifier *
1489 alg_for_privatekey(const hx509_private_key pk, int type)
1491 const heim_oid *keytype;
1492 unsigned int i;
1494 if (pk->ops == NULL)
1495 return NULL;
1497 keytype = pk->ops->key_oid;
1499 for (i = 0; sig_algs[i]; i++) {
1500 if (sig_algs[i]->key_oid == NULL)
1501 continue;
1502 if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
1503 continue;
1504 if (pk->ops->available &&
1505 pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
1506 continue;
1507 if (type == HX509_SELECT_PUBLIC_SIG)
1508 return sig_algs[i]->sig_alg;
1509 if (type == HX509_SELECT_DIGEST)
1510 return sig_algs[i]->digest_alg;
1512 return NULL;
1514 return NULL;
1521 static struct hx509_private_key_ops *private_algs[] = {
1522 &rsa_private_key_ops,
1523 #ifdef HAVE_OPENSSL
1524 &ecdsa_private_key_ops,
1525 #endif
1526 NULL
1529 hx509_private_key_ops *
1530 hx509_find_private_alg(const heim_oid *oid)
1532 int i;
1533 for (i = 0; private_algs[i]; i++) {
1534 if (private_algs[i]->key_oid == NULL)
1535 continue;
1536 if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
1537 return private_algs[i];
1539 return NULL;
1543 * Check if the algorithm `alg' have a best before date, and if it
1544 * des, make sure the its before the time `t'.
1548 _hx509_signature_is_weak(hx509_context context, const AlgorithmIdentifier *alg)
1550 const struct signature_alg *md;
1552 md = find_sig_alg(&alg->algorithm);
1553 if (md == NULL) {
1554 hx509_clear_error_string(context);
1555 return HX509_SIG_ALG_NO_SUPPORTED;
1557 if (md->flags & WEAK_SIG_ALG) {
1558 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1559 "Algorithm %s is weak", md->name);
1560 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1562 return 0;
1566 _hx509_self_signed_valid(hx509_context context,
1567 const AlgorithmIdentifier *alg)
1569 const struct signature_alg *md;
1571 md = find_sig_alg(&alg->algorithm);
1572 if (md == NULL) {
1573 hx509_clear_error_string(context);
1574 return HX509_SIG_ALG_NO_SUPPORTED;
1576 if ((md->flags & SELF_SIGNED_OK) == 0) {
1577 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1578 "Algorithm %s not trusted for self signatures",
1579 md->name);
1580 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1582 return 0;
1587 _hx509_verify_signature(hx509_context context,
1588 const hx509_cert cert,
1589 const AlgorithmIdentifier *alg,
1590 const heim_octet_string *data,
1591 const heim_octet_string *sig)
1593 const struct signature_alg *md;
1594 const Certificate *signer = NULL;
1596 if (cert)
1597 signer = _hx509_get_cert(cert);
1599 md = find_sig_alg(&alg->algorithm);
1600 if (md == NULL) {
1601 hx509_clear_error_string(context);
1602 return HX509_SIG_ALG_NO_SUPPORTED;
1604 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1605 hx509_clear_error_string(context);
1606 return HX509_CRYPTO_SIG_NO_CONF;
1608 if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1609 hx509_clear_error_string(context);
1610 return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1612 if (md->key_oid && signer) {
1613 const SubjectPublicKeyInfo *spi;
1614 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1616 if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
1617 hx509_clear_error_string(context);
1618 return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
1621 return (*md->verify_signature)(context, md, signer, alg, data, sig);
1625 _hx509_create_signature(hx509_context context,
1626 const hx509_private_key signer,
1627 const AlgorithmIdentifier *alg,
1628 const heim_octet_string *data,
1629 AlgorithmIdentifier *signatureAlgorithm,
1630 heim_octet_string *sig)
1632 const struct signature_alg *md;
1634 md = find_sig_alg(&alg->algorithm);
1635 if (md == NULL) {
1636 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1637 "algorithm no supported");
1638 return HX509_SIG_ALG_NO_SUPPORTED;
1641 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1642 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1643 "algorithm provides no conf");
1644 return HX509_CRYPTO_SIG_NO_CONF;
1647 return (*md->create_signature)(context, md, signer, alg, data,
1648 signatureAlgorithm, sig);
1652 _hx509_create_signature_bitstring(hx509_context context,
1653 const hx509_private_key signer,
1654 const AlgorithmIdentifier *alg,
1655 const heim_octet_string *data,
1656 AlgorithmIdentifier *signatureAlgorithm,
1657 heim_bit_string *sig)
1659 heim_octet_string os;
1660 int ret;
1662 ret = _hx509_create_signature(context, signer, alg,
1663 data, signatureAlgorithm, &os);
1664 if (ret)
1665 return ret;
1666 sig->data = os.data;
1667 sig->length = os.length * 8;
1668 return 0;
1672 _hx509_public_encrypt(hx509_context context,
1673 const heim_octet_string *cleartext,
1674 const Certificate *cert,
1675 heim_oid *encryption_oid,
1676 heim_octet_string *ciphertext)
1678 const SubjectPublicKeyInfo *spi;
1679 unsigned char *to;
1680 int tosize;
1681 int ret;
1682 RSA *rsa;
1683 size_t size;
1684 const unsigned char *p;
1686 ciphertext->data = NULL;
1687 ciphertext->length = 0;
1689 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1691 p = spi->subjectPublicKey.data;
1692 size = spi->subjectPublicKey.length / 8;
1694 rsa = d2i_RSAPublicKey(NULL, &p, size);
1695 if (rsa == NULL) {
1696 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1697 return ENOMEM;
1700 tosize = RSA_size(rsa);
1701 to = malloc(tosize);
1702 if (to == NULL) {
1703 RSA_free(rsa);
1704 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1705 return ENOMEM;
1708 ret = RSA_public_encrypt(cleartext->length,
1709 (unsigned char *)cleartext->data,
1710 to, rsa, RSA_PKCS1_PADDING);
1711 RSA_free(rsa);
1712 if (ret <= 0) {
1713 free(to);
1714 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
1715 "RSA public encrypt failed with %d", ret);
1716 return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
1718 if (ret > tosize)
1719 _hx509_abort("internal rsa decryption failure: ret > tosize");
1721 ciphertext->length = ret;
1722 ciphertext->data = to;
1724 ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
1725 if (ret) {
1726 der_free_octet_string(ciphertext);
1727 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1728 return ENOMEM;
1731 return 0;
1735 hx509_private_key_private_decrypt(hx509_context context,
1736 const heim_octet_string *ciphertext,
1737 const heim_oid *encryption_oid,
1738 hx509_private_key p,
1739 heim_octet_string *cleartext)
1741 int ret;
1743 cleartext->data = NULL;
1744 cleartext->length = 0;
1746 if (p->private_key.rsa == NULL) {
1747 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1748 "Private RSA key missing");
1749 return HX509_PRIVATE_KEY_MISSING;
1752 cleartext->length = RSA_size(p->private_key.rsa);
1753 cleartext->data = malloc(cleartext->length);
1754 if (cleartext->data == NULL) {
1755 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1756 return ENOMEM;
1758 ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
1759 cleartext->data,
1760 p->private_key.rsa,
1761 RSA_PKCS1_PADDING);
1762 if (ret <= 0) {
1763 der_free_octet_string(cleartext);
1764 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
1765 "Failed to decrypt using private key: %d", ret);
1766 return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
1768 if (cleartext->length < (size_t)ret)
1769 _hx509_abort("internal rsa decryption failure: ret > tosize");
1771 cleartext->length = ret;
1773 return 0;
1778 hx509_parse_private_key(hx509_context context,
1779 const AlgorithmIdentifier *keyai,
1780 const void *data,
1781 size_t len,
1782 hx509_key_format_t format,
1783 hx509_private_key *private_key)
1785 struct hx509_private_key_ops *ops;
1786 int ret;
1788 *private_key = NULL;
1790 ops = hx509_find_private_alg(&keyai->algorithm);
1791 if (ops == NULL) {
1792 hx509_clear_error_string(context);
1793 return HX509_SIG_ALG_NO_SUPPORTED;
1796 ret = hx509_private_key_init(private_key, ops, NULL);
1797 if (ret) {
1798 hx509_set_error_string(context, 0, ret, "out of memory");
1799 return ret;
1802 ret = (*ops->import)(context, keyai, data, len, format, *private_key);
1803 if (ret)
1804 hx509_private_key_free(private_key);
1806 return ret;
1814 hx509_private_key2SPKI(hx509_context context,
1815 hx509_private_key private_key,
1816 SubjectPublicKeyInfo *spki)
1818 const struct hx509_private_key_ops *ops = private_key->ops;
1819 if (ops == NULL || ops->get_spki == NULL) {
1820 hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1821 "Private key have no key2SPKI function");
1822 return HX509_UNIMPLEMENTED_OPERATION;
1824 return (*ops->get_spki)(context, private_key, spki);
1828 _hx509_generate_private_key_init(hx509_context context,
1829 const heim_oid *oid,
1830 struct hx509_generate_private_context **ctx)
1832 *ctx = NULL;
1834 if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
1835 hx509_set_error_string(context, 0, EINVAL,
1836 "private key not an RSA key");
1837 return EINVAL;
1840 *ctx = calloc(1, sizeof(**ctx));
1841 if (*ctx == NULL) {
1842 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1843 return ENOMEM;
1845 (*ctx)->key_oid = oid;
1847 return 0;
1851 _hx509_generate_private_key_is_ca(hx509_context context,
1852 struct hx509_generate_private_context *ctx)
1854 ctx->isCA = 1;
1855 return 0;
1859 _hx509_generate_private_key_bits(hx509_context context,
1860 struct hx509_generate_private_context *ctx,
1861 unsigned long bits)
1863 ctx->num_bits = bits;
1864 return 0;
1868 void
1869 _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1871 free(*ctx);
1872 *ctx = NULL;
1876 _hx509_generate_private_key(hx509_context context,
1877 struct hx509_generate_private_context *ctx,
1878 hx509_private_key *private_key)
1880 struct hx509_private_key_ops *ops;
1881 int ret;
1883 *private_key = NULL;
1885 ops = hx509_find_private_alg(ctx->key_oid);
1886 if (ops == NULL) {
1887 hx509_clear_error_string(context);
1888 return HX509_SIG_ALG_NO_SUPPORTED;
1891 ret = hx509_private_key_init(private_key, ops, NULL);
1892 if (ret) {
1893 hx509_set_error_string(context, 0, ret, "out of memory");
1894 return ret;
1897 ret = (*ops->generate_private_key)(context, ctx, *private_key);
1898 if (ret)
1899 hx509_private_key_free(private_key);
1901 return ret;
1908 const AlgorithmIdentifier *
1909 hx509_signature_sha512(void)
1910 { return &_hx509_signature_sha512_data; }
1912 const AlgorithmIdentifier *
1913 hx509_signature_sha384(void)
1914 { return &_hx509_signature_sha384_data; }
1916 const AlgorithmIdentifier *
1917 hx509_signature_sha256(void)
1918 { return &_hx509_signature_sha256_data; }
1920 const AlgorithmIdentifier *
1921 hx509_signature_sha1(void)
1922 { return &_hx509_signature_sha1_data; }
1924 const AlgorithmIdentifier *
1925 hx509_signature_md5(void)
1926 { return &_hx509_signature_md5_data; }
1928 const AlgorithmIdentifier *
1929 hx509_signature_ecPublicKey(void)
1930 { return &_hx509_signature_ecPublicKey; }
1932 const AlgorithmIdentifier *
1933 hx509_signature_ecdsa_with_sha256(void)
1934 { return &_hx509_signature_ecdsa_with_sha256_data; }
1936 const AlgorithmIdentifier *
1937 hx509_signature_ecdsa_with_sha1(void)
1938 { return &_hx509_signature_ecdsa_with_sha1_data; }
1940 const AlgorithmIdentifier *
1941 hx509_signature_rsa_with_sha512(void)
1942 { return &_hx509_signature_rsa_with_sha512_data; }
1944 const AlgorithmIdentifier *
1945 hx509_signature_rsa_with_sha384(void)
1946 { return &_hx509_signature_rsa_with_sha384_data; }
1948 const AlgorithmIdentifier *
1949 hx509_signature_rsa_with_sha256(void)
1950 { return &_hx509_signature_rsa_with_sha256_data; }
1952 const AlgorithmIdentifier *
1953 hx509_signature_rsa_with_sha1(void)
1954 { return &_hx509_signature_rsa_with_sha1_data; }
1956 const AlgorithmIdentifier *
1957 hx509_signature_rsa_with_md5(void)
1958 { return &_hx509_signature_rsa_with_md5_data; }
1960 const AlgorithmIdentifier *
1961 hx509_signature_rsa(void)
1962 { return &_hx509_signature_rsa_data; }
1964 const AlgorithmIdentifier *
1965 hx509_signature_rsa_pkcs1_x509(void)
1966 { return &_hx509_signature_rsa_pkcs1_x509_data; }
1968 const AlgorithmIdentifier *
1969 hx509_crypto_des_rsdi_ede3_cbc(void)
1970 { return &_hx509_des_rsdi_ede3_cbc_oid; }
1972 const AlgorithmIdentifier *
1973 hx509_crypto_aes128_cbc(void)
1974 { return &_hx509_crypto_aes128_cbc_data; }
1976 const AlgorithmIdentifier *
1977 hx509_crypto_aes256_cbc(void)
1978 { return &_hx509_crypto_aes256_cbc_data; }
1984 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
1985 &_hx509_signature_rsa_with_sha256_data;
1986 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
1987 &_hx509_signature_sha256_data;
1988 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
1989 &_hx509_crypto_aes128_cbc_data;
1996 hx509_private_key_init(hx509_private_key *key,
1997 hx509_private_key_ops *ops,
1998 void *keydata)
2000 *key = calloc(1, sizeof(**key));
2001 if (*key == NULL)
2002 return ENOMEM;
2003 (*key)->ref = 1;
2004 (*key)->ops = ops;
2005 (*key)->private_key.keydata = keydata;
2006 return 0;
2009 hx509_private_key
2010 _hx509_private_key_ref(hx509_private_key key)
2012 if (key->ref == 0)
2013 _hx509_abort("key refcount <= 0 on ref");
2014 key->ref++;
2015 if (key->ref == UINT_MAX)
2016 _hx509_abort("key refcount == UINT_MAX on ref");
2017 return key;
2020 const char *
2021 _hx509_private_pem_name(hx509_private_key key)
2023 return key->ops->pemtype;
2027 hx509_private_key_free(hx509_private_key *key)
2029 if (key == NULL || *key == NULL)
2030 return 0;
2032 if ((*key)->ref == 0)
2033 _hx509_abort("key refcount == 0 on free");
2034 if (--(*key)->ref > 0)
2035 return 0;
2037 if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
2038 if ((*key)->private_key.rsa)
2039 RSA_free((*key)->private_key.rsa);
2040 #ifdef HAVE_OPENSSL
2041 } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) {
2042 if ((*key)->private_key.ecdsa)
2043 EC_KEY_free((*key)->private_key.ecdsa);
2044 #endif
2046 (*key)->private_key.rsa = NULL;
2047 free(*key);
2048 *key = NULL;
2049 return 0;
2052 void
2053 hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
2055 if (key->private_key.rsa)
2056 RSA_free(key->private_key.rsa);
2057 key->private_key.rsa = ptr;
2058 key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
2059 key->md = &pkcs1_rsa_sha1_alg;
2063 _hx509_private_key_oid(hx509_context context,
2064 const hx509_private_key key,
2065 heim_oid *data)
2067 int ret;
2068 ret = der_copy_oid(key->ops->key_oid, data);
2069 if (ret)
2070 hx509_set_error_string(context, 0, ret, "malloc out of memory");
2071 return ret;
2075 _hx509_private_key_exportable(hx509_private_key key)
2077 if (key->ops->export == NULL)
2078 return 0;
2079 return 1;
2082 BIGNUM *
2083 _hx509_private_key_get_internal(hx509_context context,
2084 hx509_private_key key,
2085 const char *type)
2087 if (key->ops->get_internal == NULL)
2088 return NULL;
2089 return (*key->ops->get_internal)(context, key, type);
2093 _hx509_private_key_export(hx509_context context,
2094 const hx509_private_key key,
2095 hx509_key_format_t format,
2096 heim_octet_string *data)
2098 if (key->ops->export == NULL) {
2099 hx509_clear_error_string(context);
2100 return HX509_UNIMPLEMENTED_OPERATION;
2102 return (*key->ops->export)(context, key, format, data);
2109 struct hx509cipher {
2110 const char *name;
2111 int flags;
2112 #define CIPHER_WEAK 1
2113 const heim_oid *oid;
2114 const AlgorithmIdentifier *(*ai_func)(void);
2115 const EVP_CIPHER *(*evp_func)(void);
2116 int (*get_params)(hx509_context, const hx509_crypto,
2117 const heim_octet_string *, heim_octet_string *);
2118 int (*set_params)(hx509_context, const heim_octet_string *,
2119 hx509_crypto, heim_octet_string *);
2122 struct hx509_crypto_data {
2123 char *name;
2124 int flags;
2125 #define ALLOW_WEAK 1
2127 #define PADDING_NONE 2
2128 #define PADDING_PKCS7 4
2129 #define PADDING_FLAGS (2|4)
2130 const struct hx509cipher *cipher;
2131 const EVP_CIPHER *c;
2132 heim_octet_string key;
2133 heim_oid oid;
2134 void *param;
2141 static unsigned private_rc2_40_oid_data[] = { 127, 1 };
2143 static heim_oid asn1_oid_private_rc2_40 =
2144 { 2, private_rc2_40_oid_data };
2150 static int
2151 CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
2152 const heim_octet_string *ivec, heim_octet_string *param)
2154 size_t size;
2155 int ret;
2157 assert(crypto->param == NULL);
2158 if (ivec == NULL)
2159 return 0;
2161 ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
2162 ivec, &size, ret);
2163 if (ret == 0 && size != param->length)
2164 _hx509_abort("Internal asn1 encoder failure");
2165 if (ret)
2166 hx509_clear_error_string(context);
2167 return ret;
2170 static int
2171 CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
2172 hx509_crypto crypto, heim_octet_string *ivec)
2174 int ret;
2175 if (ivec == NULL)
2176 return 0;
2178 ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
2179 if (ret)
2180 hx509_clear_error_string(context);
2182 return ret;
2185 struct _RC2_params {
2186 int maximum_effective_key;
2189 static int
2190 CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
2191 const heim_octet_string *ivec, heim_octet_string *param)
2193 CMSRC2CBCParameter rc2params;
2194 const struct _RC2_params *p = crypto->param;
2195 int maximum_effective_key = 128;
2196 size_t size;
2197 int ret;
2199 memset(&rc2params, 0, sizeof(rc2params));
2201 if (p)
2202 maximum_effective_key = p->maximum_effective_key;
2204 switch(maximum_effective_key) {
2205 case 40:
2206 rc2params.rc2ParameterVersion = 160;
2207 break;
2208 case 64:
2209 rc2params.rc2ParameterVersion = 120;
2210 break;
2211 case 128:
2212 rc2params.rc2ParameterVersion = 58;
2213 break;
2215 rc2params.iv = *ivec;
2217 ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
2218 &rc2params, &size, ret);
2219 if (ret == 0 && size != param->length)
2220 _hx509_abort("Internal asn1 encoder failure");
2222 return ret;
2225 static int
2226 CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
2227 hx509_crypto crypto, heim_octet_string *ivec)
2229 CMSRC2CBCParameter rc2param;
2230 struct _RC2_params *p;
2231 size_t size;
2232 int ret;
2234 ret = decode_CMSRC2CBCParameter(param->data, param->length,
2235 &rc2param, &size);
2236 if (ret) {
2237 hx509_clear_error_string(context);
2238 return ret;
2241 p = calloc(1, sizeof(*p));
2242 if (p == NULL) {
2243 free_CMSRC2CBCParameter(&rc2param);
2244 hx509_clear_error_string(context);
2245 return ENOMEM;
2247 switch(rc2param.rc2ParameterVersion) {
2248 case 160:
2249 crypto->c = EVP_rc2_40_cbc();
2250 p->maximum_effective_key = 40;
2251 break;
2252 case 120:
2253 crypto->c = EVP_rc2_64_cbc();
2254 p->maximum_effective_key = 64;
2255 break;
2256 case 58:
2257 crypto->c = EVP_rc2_cbc();
2258 p->maximum_effective_key = 128;
2259 break;
2260 default:
2261 free(p);
2262 free_CMSRC2CBCParameter(&rc2param);
2263 return HX509_CRYPTO_SIG_INVALID_FORMAT;
2265 if (ivec)
2266 ret = der_copy_octet_string(&rc2param.iv, ivec);
2267 free_CMSRC2CBCParameter(&rc2param);
2268 if (ret) {
2269 free(p);
2270 hx509_clear_error_string(context);
2271 } else
2272 crypto->param = p;
2274 return ret;
2281 static const struct hx509cipher ciphers[] = {
2283 "rc2-cbc",
2284 CIPHER_WEAK,
2285 ASN1_OID_ID_PKCS3_RC2_CBC,
2286 NULL,
2287 EVP_rc2_cbc,
2288 CMSRC2CBCParam_get,
2289 CMSRC2CBCParam_set
2292 "rc2-cbc",
2293 CIPHER_WEAK,
2294 ASN1_OID_ID_RSADSI_RC2_CBC,
2295 NULL,
2296 EVP_rc2_cbc,
2297 CMSRC2CBCParam_get,
2298 CMSRC2CBCParam_set
2301 "rc2-40-cbc",
2302 CIPHER_WEAK,
2303 &asn1_oid_private_rc2_40,
2304 NULL,
2305 EVP_rc2_40_cbc,
2306 CMSRC2CBCParam_get,
2307 CMSRC2CBCParam_set
2310 "des-ede3-cbc",
2312 ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
2313 NULL,
2314 EVP_des_ede3_cbc,
2315 CMSCBCParam_get,
2316 CMSCBCParam_set
2319 "des-ede3-cbc",
2321 ASN1_OID_ID_RSADSI_DES_EDE3_CBC,
2322 hx509_crypto_des_rsdi_ede3_cbc,
2323 EVP_des_ede3_cbc,
2324 CMSCBCParam_get,
2325 CMSCBCParam_set
2328 "aes-128-cbc",
2330 ASN1_OID_ID_AES_128_CBC,
2331 hx509_crypto_aes128_cbc,
2332 EVP_aes_128_cbc,
2333 CMSCBCParam_get,
2334 CMSCBCParam_set
2337 "aes-192-cbc",
2339 ASN1_OID_ID_AES_192_CBC,
2340 NULL,
2341 EVP_aes_192_cbc,
2342 CMSCBCParam_get,
2343 CMSCBCParam_set
2346 "aes-256-cbc",
2348 ASN1_OID_ID_AES_256_CBC,
2349 hx509_crypto_aes256_cbc,
2350 EVP_aes_256_cbc,
2351 CMSCBCParam_get,
2352 CMSCBCParam_set
2356 static const struct hx509cipher *
2357 find_cipher_by_oid(const heim_oid *oid)
2359 size_t i;
2361 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
2362 if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
2363 return &ciphers[i];
2365 return NULL;
2368 static const struct hx509cipher *
2369 find_cipher_by_name(const char *name)
2371 size_t i;
2373 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
2374 if (strcasecmp(name, ciphers[i].name) == 0)
2375 return &ciphers[i];
2377 return NULL;
2381 const heim_oid *
2382 hx509_crypto_enctype_by_name(const char *name)
2384 const struct hx509cipher *cipher;
2386 cipher = find_cipher_by_name(name);
2387 if (cipher == NULL)
2388 return NULL;
2389 return cipher->oid;
2393 hx509_crypto_init(hx509_context context,
2394 const char *provider,
2395 const heim_oid *enctype,
2396 hx509_crypto *crypto)
2398 const struct hx509cipher *cipher;
2400 *crypto = NULL;
2402 cipher = find_cipher_by_oid(enctype);
2403 if (cipher == NULL) {
2404 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2405 "Algorithm not supported");
2406 return HX509_ALG_NOT_SUPP;
2409 *crypto = calloc(1, sizeof(**crypto));
2410 if (*crypto == NULL) {
2411 hx509_clear_error_string(context);
2412 return ENOMEM;
2415 (*crypto)->flags = PADDING_PKCS7;
2416 (*crypto)->cipher = cipher;
2417 (*crypto)->c = (*cipher->evp_func)();
2419 if (der_copy_oid(enctype, &(*crypto)->oid)) {
2420 hx509_crypto_destroy(*crypto);
2421 *crypto = NULL;
2422 hx509_clear_error_string(context);
2423 return ENOMEM;
2426 return 0;
2429 const char *
2430 hx509_crypto_provider(hx509_crypto crypto)
2432 return "unknown";
2435 void
2436 hx509_crypto_destroy(hx509_crypto crypto)
2438 if (crypto->name)
2439 free(crypto->name);
2440 if (crypto->key.data)
2441 free(crypto->key.data);
2442 if (crypto->param)
2443 free(crypto->param);
2444 der_free_oid(&crypto->oid);
2445 memset(crypto, 0, sizeof(*crypto));
2446 free(crypto);
2450 hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2452 return 0;
2455 void
2456 hx509_crypto_allow_weak(hx509_crypto crypto)
2458 crypto->flags |= ALLOW_WEAK;
2461 void
2462 hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
2464 switch (padding_type) {
2465 case HX509_CRYPTO_PADDING_PKCS7:
2466 crypto->flags &= ~PADDING_FLAGS;
2467 crypto->flags |= PADDING_PKCS7;
2468 break;
2469 case HX509_CRYPTO_PADDING_NONE:
2470 crypto->flags &= ~PADDING_FLAGS;
2471 crypto->flags |= PADDING_NONE;
2472 break;
2473 default:
2474 _hx509_abort("Invalid padding");
2479 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2481 if (EVP_CIPHER_key_length(crypto->c) > (int)length)
2482 return HX509_CRYPTO_INTERNAL_ERROR;
2484 if (crypto->key.data) {
2485 free(crypto->key.data);
2486 crypto->key.data = NULL;
2487 crypto->key.length = 0;
2489 crypto->key.data = malloc(length);
2490 if (crypto->key.data == NULL)
2491 return ENOMEM;
2492 memcpy(crypto->key.data, data, length);
2493 crypto->key.length = length;
2495 return 0;
2499 hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2501 if (crypto->key.data) {
2502 free(crypto->key.data);
2503 crypto->key.length = 0;
2506 crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2507 crypto->key.data = malloc(crypto->key.length);
2508 if (crypto->key.data == NULL) {
2509 crypto->key.length = 0;
2510 return ENOMEM;
2512 if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2513 free(crypto->key.data);
2514 crypto->key.data = NULL;
2515 crypto->key.length = 0;
2516 return HX509_CRYPTO_INTERNAL_ERROR;
2518 if (key)
2519 return der_copy_octet_string(&crypto->key, key);
2520 else
2521 return 0;
2525 hx509_crypto_set_params(hx509_context context,
2526 hx509_crypto crypto,
2527 const heim_octet_string *param,
2528 heim_octet_string *ivec)
2530 return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2534 hx509_crypto_get_params(hx509_context context,
2535 hx509_crypto crypto,
2536 const heim_octet_string *ivec,
2537 heim_octet_string *param)
2539 return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2543 hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2545 ivec->length = EVP_CIPHER_iv_length(crypto->c);
2546 ivec->data = malloc(ivec->length);
2547 if (ivec->data == NULL) {
2548 ivec->length = 0;
2549 return ENOMEM;
2552 if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2553 free(ivec->data);
2554 ivec->data = NULL;
2555 ivec->length = 0;
2556 return HX509_CRYPTO_INTERNAL_ERROR;
2558 return 0;
2562 hx509_crypto_encrypt(hx509_crypto crypto,
2563 const void *data,
2564 const size_t length,
2565 const heim_octet_string *ivec,
2566 heim_octet_string **ciphertext)
2568 EVP_CIPHER_CTX evp;
2569 size_t padsize, bsize;
2570 int ret;
2572 *ciphertext = NULL;
2574 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2575 (crypto->flags & ALLOW_WEAK) == 0)
2576 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2578 assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
2580 EVP_CIPHER_CTX_init(&evp);
2582 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2583 crypto->key.data, ivec->data, 1);
2584 if (ret != 1) {
2585 EVP_CIPHER_CTX_cleanup(&evp);
2586 ret = HX509_CRYPTO_INTERNAL_ERROR;
2587 goto out;
2590 *ciphertext = calloc(1, sizeof(**ciphertext));
2591 if (*ciphertext == NULL) {
2592 ret = ENOMEM;
2593 goto out;
2596 assert(crypto->flags & PADDING_FLAGS);
2598 bsize = EVP_CIPHER_block_size(crypto->c);
2599 padsize = 0;
2601 if (crypto->flags & PADDING_NONE) {
2602 if (bsize != 1 && (length % bsize) != 0)
2603 return HX509_CMS_PADDING_ERROR;
2604 } else if (crypto->flags & PADDING_PKCS7) {
2605 if (bsize != 1)
2606 padsize = bsize - (length % bsize);
2609 (*ciphertext)->length = length + padsize;
2610 (*ciphertext)->data = malloc(length + padsize);
2611 if ((*ciphertext)->data == NULL) {
2612 ret = ENOMEM;
2613 goto out;
2616 memcpy((*ciphertext)->data, data, length);
2617 if (padsize) {
2618 size_t i;
2619 unsigned char *p = (*ciphertext)->data;
2620 p += length;
2621 for (i = 0; i < padsize; i++)
2622 *p++ = padsize;
2625 ret = EVP_Cipher(&evp, (*ciphertext)->data,
2626 (*ciphertext)->data,
2627 length + padsize);
2628 if (ret != 1) {
2629 ret = HX509_CRYPTO_INTERNAL_ERROR;
2630 goto out;
2632 ret = 0;
2634 out:
2635 if (ret) {
2636 if (*ciphertext) {
2637 if ((*ciphertext)->data) {
2638 free((*ciphertext)->data);
2640 free(*ciphertext);
2641 *ciphertext = NULL;
2644 EVP_CIPHER_CTX_cleanup(&evp);
2646 return ret;
2650 hx509_crypto_decrypt(hx509_crypto crypto,
2651 const void *data,
2652 const size_t length,
2653 heim_octet_string *ivec,
2654 heim_octet_string *clear)
2656 EVP_CIPHER_CTX evp;
2657 void *idata = NULL;
2658 int ret;
2660 clear->data = NULL;
2661 clear->length = 0;
2663 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2664 (crypto->flags & ALLOW_WEAK) == 0)
2665 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2667 if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length)
2668 return HX509_CRYPTO_INTERNAL_ERROR;
2670 if (crypto->key.data == NULL)
2671 return HX509_CRYPTO_INTERNAL_ERROR;
2673 if (ivec)
2674 idata = ivec->data;
2676 EVP_CIPHER_CTX_init(&evp);
2678 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2679 crypto->key.data, idata, 0);
2680 if (ret != 1) {
2681 EVP_CIPHER_CTX_cleanup(&evp);
2682 return HX509_CRYPTO_INTERNAL_ERROR;
2685 clear->length = length;
2686 clear->data = malloc(length);
2687 if (clear->data == NULL) {
2688 EVP_CIPHER_CTX_cleanup(&evp);
2689 clear->length = 0;
2690 return ENOMEM;
2693 if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2694 return HX509_CRYPTO_INTERNAL_ERROR;
2696 EVP_CIPHER_CTX_cleanup(&evp);
2698 if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
2699 int padsize;
2700 unsigned char *p;
2701 int j, bsize = EVP_CIPHER_block_size(crypto->c);
2703 if ((int)clear->length < bsize) {
2704 ret = HX509_CMS_PADDING_ERROR;
2705 goto out;
2708 p = clear->data;
2709 p += clear->length - 1;
2710 padsize = *p;
2711 if (padsize > bsize) {
2712 ret = HX509_CMS_PADDING_ERROR;
2713 goto out;
2715 clear->length -= padsize;
2716 for (j = 0; j < padsize; j++) {
2717 if (*p-- != padsize) {
2718 ret = HX509_CMS_PADDING_ERROR;
2719 goto out;
2724 return 0;
2726 out:
2727 if (clear->data)
2728 free(clear->data);
2729 clear->data = NULL;
2730 clear->length = 0;
2731 return ret;
2734 typedef int (*PBE_string2key_func)(hx509_context,
2735 const char *,
2736 const heim_octet_string *,
2737 hx509_crypto *, heim_octet_string *,
2738 heim_octet_string *,
2739 const heim_oid *, const EVP_MD *);
2741 static int
2742 PBE_string2key(hx509_context context,
2743 const char *password,
2744 const heim_octet_string *parameters,
2745 hx509_crypto *crypto,
2746 heim_octet_string *key, heim_octet_string *iv,
2747 const heim_oid *enc_oid,
2748 const EVP_MD *md)
2750 PKCS12_PBEParams p12params;
2751 int passwordlen;
2752 hx509_crypto c;
2753 int iter, saltlen, ret;
2754 unsigned char *salt;
2756 passwordlen = password ? strlen(password) : 0;
2758 if (parameters == NULL)
2759 return HX509_ALG_NOT_SUPP;
2761 ret = decode_PKCS12_PBEParams(parameters->data,
2762 parameters->length,
2763 &p12params, NULL);
2764 if (ret)
2765 goto out;
2767 if (p12params.iterations)
2768 iter = *p12params.iterations;
2769 else
2770 iter = 1;
2771 salt = p12params.salt.data;
2772 saltlen = p12params.salt.length;
2774 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2775 PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2776 ret = HX509_CRYPTO_INTERNAL_ERROR;
2777 goto out;
2780 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2781 PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2782 ret = HX509_CRYPTO_INTERNAL_ERROR;
2783 goto out;
2786 ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2787 if (ret)
2788 goto out;
2790 hx509_crypto_allow_weak(c);
2792 ret = hx509_crypto_set_key_data(c, key->data, key->length);
2793 if (ret) {
2794 hx509_crypto_destroy(c);
2795 goto out;
2798 *crypto = c;
2799 out:
2800 free_PKCS12_PBEParams(&p12params);
2801 return ret;
2804 static const heim_oid *
2805 find_string2key(const heim_oid *oid,
2806 const EVP_CIPHER **c,
2807 const EVP_MD **md,
2808 PBE_string2key_func *s2k)
2810 if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
2811 *c = EVP_rc2_40_cbc();
2812 *md = EVP_sha1();
2813 *s2k = PBE_string2key;
2814 return &asn1_oid_private_rc2_40;
2815 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
2816 *c = EVP_rc2_cbc();
2817 *md = EVP_sha1();
2818 *s2k = PBE_string2key;
2819 return ASN1_OID_ID_PKCS3_RC2_CBC;
2820 #if 0
2821 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
2822 *c = EVP_rc4_40();
2823 *md = EVP_sha1();
2824 *s2k = PBE_string2key;
2825 return NULL;
2826 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
2827 *c = EVP_rc4();
2828 *md = EVP_sha1();
2829 *s2k = PBE_string2key;
2830 return ASN1_OID_ID_PKCS3_RC4;
2831 #endif
2832 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
2833 *c = EVP_des_ede3_cbc();
2834 *md = EVP_sha1();
2835 *s2k = PBE_string2key;
2836 return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
2839 return NULL;
2847 _hx509_pbe_encrypt(hx509_context context,
2848 hx509_lock lock,
2849 const AlgorithmIdentifier *ai,
2850 const heim_octet_string *content,
2851 heim_octet_string *econtent)
2853 hx509_clear_error_string(context);
2854 return EINVAL;
2862 _hx509_pbe_decrypt(hx509_context context,
2863 hx509_lock lock,
2864 const AlgorithmIdentifier *ai,
2865 const heim_octet_string *econtent,
2866 heim_octet_string *content)
2868 const struct _hx509_password *pw;
2869 heim_octet_string key, iv;
2870 const heim_oid *enc_oid;
2871 const EVP_CIPHER *c;
2872 const EVP_MD *md;
2873 PBE_string2key_func s2k;
2874 int ret = 0;
2875 size_t i;
2877 memset(&key, 0, sizeof(key));
2878 memset(&iv, 0, sizeof(iv));
2880 memset(content, 0, sizeof(*content));
2882 enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2883 if (enc_oid == NULL) {
2884 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2885 "String to key algorithm not supported");
2886 ret = HX509_ALG_NOT_SUPP;
2887 goto out;
2890 key.length = EVP_CIPHER_key_length(c);
2891 key.data = malloc(key.length);
2892 if (key.data == NULL) {
2893 ret = ENOMEM;
2894 hx509_clear_error_string(context);
2895 goto out;
2898 iv.length = EVP_CIPHER_iv_length(c);
2899 iv.data = malloc(iv.length);
2900 if (iv.data == NULL) {
2901 ret = ENOMEM;
2902 hx509_clear_error_string(context);
2903 goto out;
2906 pw = _hx509_lock_get_passwords(lock);
2908 ret = HX509_CRYPTO_INTERNAL_ERROR;
2909 for (i = 0; i < pw->len + 1; i++) {
2910 hx509_crypto crypto;
2911 const char *password;
2913 if (i < pw->len)
2914 password = pw->val[i];
2915 else if (i < pw->len + 1)
2916 password = "";
2917 else
2918 password = NULL;
2920 ret = (*s2k)(context, password, ai->parameters, &crypto,
2921 &key, &iv, enc_oid, md);
2922 if (ret)
2923 goto out;
2925 ret = hx509_crypto_decrypt(crypto,
2926 econtent->data,
2927 econtent->length,
2928 &iv,
2929 content);
2930 hx509_crypto_destroy(crypto);
2931 if (ret == 0)
2932 goto out;
2935 out:
2936 if (key.data)
2937 der_free_octet_string(&key);
2938 if (iv.data)
2939 der_free_octet_string(&iv);
2940 return ret;
2948 static int
2949 match_keys_rsa(hx509_cert c, hx509_private_key private_key)
2951 const Certificate *cert;
2952 const SubjectPublicKeyInfo *spi;
2953 RSAPublicKey pk;
2954 RSA *rsa;
2955 size_t size;
2956 int ret;
2958 if (private_key->private_key.rsa == NULL)
2959 return 0;
2961 rsa = private_key->private_key.rsa;
2962 if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2963 return 0;
2965 cert = _hx509_get_cert(c);
2966 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2968 rsa = RSA_new();
2969 if (rsa == NULL)
2970 return 0;
2972 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2973 spi->subjectPublicKey.length / 8,
2974 &pk, &size);
2975 if (ret) {
2976 RSA_free(rsa);
2977 return 0;
2979 rsa->n = heim_int2BN(&pk.modulus);
2980 rsa->e = heim_int2BN(&pk.publicExponent);
2982 free_RSAPublicKey(&pk);
2984 rsa->d = BN_dup(private_key->private_key.rsa->d);
2985 rsa->p = BN_dup(private_key->private_key.rsa->p);
2986 rsa->q = BN_dup(private_key->private_key.rsa->q);
2987 rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
2988 rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
2989 rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
2991 if (rsa->n == NULL || rsa->e == NULL ||
2992 rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
2993 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
2994 RSA_free(rsa);
2995 return 0;
2998 ret = RSA_check_key(rsa);
2999 RSA_free(rsa);
3001 return ret == 1;
3004 static int
3005 match_keys_ec(hx509_cert c, hx509_private_key private_key)
3007 return 1; /* XXX use EC_KEY_check_key */
3012 _hx509_match_keys(hx509_cert c, hx509_private_key key)
3014 if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
3015 return match_keys_rsa(c, key);
3016 if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
3017 return match_keys_ec(c, key);
3018 return 0;
3023 static const heim_oid *
3024 find_keytype(const hx509_private_key key)
3026 const struct signature_alg *md;
3028 if (key == NULL)
3029 return NULL;
3031 md = find_sig_alg(key->signature_alg);
3032 if (md == NULL)
3033 return NULL;
3034 return md->key_oid;
3038 hx509_crypto_select(const hx509_context context,
3039 int type,
3040 const hx509_private_key source,
3041 hx509_peer_info peer,
3042 AlgorithmIdentifier *selected)
3044 const AlgorithmIdentifier *def = NULL;
3045 size_t i, j;
3046 int ret, bits;
3048 memset(selected, 0, sizeof(*selected));
3050 if (type == HX509_SELECT_DIGEST) {
3051 bits = SIG_DIGEST;
3052 if (source)
3053 def = alg_for_privatekey(source, type);
3054 if (def == NULL)
3055 def = _hx509_crypto_default_digest_alg;
3056 } else if (type == HX509_SELECT_PUBLIC_SIG) {
3057 bits = SIG_PUBLIC_SIG;
3058 /* XXX depend on `source´ and `peer´ */
3059 if (source)
3060 def = alg_for_privatekey(source, type);
3061 if (def == NULL)
3062 def = _hx509_crypto_default_sig_alg;
3063 } else if (type == HX509_SELECT_SECRET_ENC) {
3064 bits = SIG_SECRET;
3065 def = _hx509_crypto_default_secret_alg;
3066 } else {
3067 hx509_set_error_string(context, 0, EINVAL,
3068 "Unknown type %d of selection", type);
3069 return EINVAL;
3072 if (peer) {
3073 const heim_oid *keytype = NULL;
3075 keytype = find_keytype(source);
3077 for (i = 0; i < peer->len; i++) {
3078 for (j = 0; sig_algs[j]; j++) {
3079 if ((sig_algs[j]->flags & bits) != bits)
3080 continue;
3081 if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
3082 &peer->val[i].algorithm) != 0)
3083 continue;
3084 if (keytype && sig_algs[j]->key_oid &&
3085 der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
3086 continue;
3088 /* found one, use that */
3089 ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
3090 if (ret)
3091 hx509_clear_error_string(context);
3092 return ret;
3094 if (bits & SIG_SECRET) {
3095 const struct hx509cipher *cipher;
3097 cipher = find_cipher_by_oid(&peer->val[i].algorithm);
3098 if (cipher == NULL)
3099 continue;
3100 if (cipher->ai_func == NULL)
3101 continue;
3102 ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
3103 if (ret)
3104 hx509_clear_error_string(context);
3105 return ret;
3110 /* use default */
3111 ret = copy_AlgorithmIdentifier(def, selected);
3112 if (ret)
3113 hx509_clear_error_string(context);
3114 return ret;
3118 hx509_crypto_available(hx509_context context,
3119 int type,
3120 hx509_cert source,
3121 AlgorithmIdentifier **val,
3122 unsigned int *plen)
3124 const heim_oid *keytype = NULL;
3125 unsigned int len, i;
3126 void *ptr;
3127 int bits, ret;
3129 *val = NULL;
3131 if (type == HX509_SELECT_ALL) {
3132 bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
3133 } else if (type == HX509_SELECT_DIGEST) {
3134 bits = SIG_DIGEST;
3135 } else if (type == HX509_SELECT_PUBLIC_SIG) {
3136 bits = SIG_PUBLIC_SIG;
3137 } else {
3138 hx509_set_error_string(context, 0, EINVAL,
3139 "Unknown type %d of available", type);
3140 return EINVAL;
3143 if (source)
3144 keytype = find_keytype(_hx509_cert_private_key(source));
3146 len = 0;
3147 for (i = 0; sig_algs[i]; i++) {
3148 if ((sig_algs[i]->flags & bits) == 0)
3149 continue;
3150 if (sig_algs[i]->sig_alg == NULL)
3151 continue;
3152 if (keytype && sig_algs[i]->key_oid &&
3153 der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
3154 continue;
3156 /* found one, add that to the list */
3157 ptr = realloc(*val, sizeof(**val) * (len + 1));
3158 if (ptr == NULL)
3159 goto out;
3160 *val = ptr;
3162 ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
3163 if (ret)
3164 goto out;
3165 len++;
3168 /* Add AES */
3169 if (bits & SIG_SECRET) {
3171 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
3173 if (ciphers[i].flags & CIPHER_WEAK)
3174 continue;
3175 if (ciphers[i].ai_func == NULL)
3176 continue;
3178 ptr = realloc(*val, sizeof(**val) * (len + 1));
3179 if (ptr == NULL)
3180 goto out;
3181 *val = ptr;
3183 ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
3184 if (ret)
3185 goto out;
3186 len++;
3190 *plen = len;
3191 return 0;
3193 out:
3194 for (i = 0; i < len; i++)
3195 free_AlgorithmIdentifier(&(*val)[i]);
3196 free(*val);
3197 *val = NULL;
3198 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
3199 return ENOMEM;
3202 void
3203 hx509_crypto_free_algs(AlgorithmIdentifier *val,
3204 unsigned int len)
3206 unsigned int i;
3207 for (i = 0; i < len; i++)
3208 free_AlgorithmIdentifier(&val[i]);
3209 free(val);