Remove building with NOCRYPTO option
[minix.git] / crypto / external / bsd / heimdal / dist / lib / hx509 / crypto.c
blob3482dd22db8d10853cb6977ecd8991b18fc9167a
1 /* $NetBSD: crypto.c,v 1.1.1.2 2014/04/24 12:45:41 pettai Exp $ */
3 /*
4 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
36 #include "hx_locl.h"
38 struct hx509_crypto;
40 struct signature_alg;
42 struct hx509_generate_private_context {
43 const heim_oid *key_oid;
44 int isCA;
45 unsigned long num_bits;
48 struct hx509_private_key_ops {
49 const char *pemtype;
50 const heim_oid *key_oid;
51 int (*available)(const hx509_private_key,
52 const AlgorithmIdentifier *);
53 int (*get_spki)(hx509_context,
54 const hx509_private_key,
55 SubjectPublicKeyInfo *);
56 int (*export)(hx509_context context,
57 const hx509_private_key,
58 hx509_key_format_t,
59 heim_octet_string *);
60 int (*import)(hx509_context, const AlgorithmIdentifier *,
61 const void *, size_t, hx509_key_format_t,
62 hx509_private_key);
63 int (*generate_private_key)(hx509_context,
64 struct hx509_generate_private_context *,
65 hx509_private_key);
66 BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
69 struct hx509_private_key {
70 unsigned int ref;
71 const struct signature_alg *md;
72 const heim_oid *signature_alg;
73 union {
74 RSA *rsa;
75 void *keydata;
76 #ifdef HAVE_OPENSSL
77 EC_KEY *ecdsa;
78 #endif
79 } private_key;
80 hx509_private_key_ops *ops;
87 struct signature_alg {
88 const char *name;
89 const heim_oid *sig_oid;
90 const AlgorithmIdentifier *sig_alg;
91 const heim_oid *key_oid;
92 const AlgorithmIdentifier *digest_alg;
93 int flags;
94 #define PROVIDE_CONF 0x1
95 #define REQUIRE_SIGNER 0x2
96 #define SELF_SIGNED_OK 0x4
98 #define SIG_DIGEST 0x100
99 #define SIG_PUBLIC_SIG 0x200
100 #define SIG_SECRET 0x400
102 #define RA_RSA_USES_DIGEST_INFO 0x1000000
104 time_t best_before; /* refuse signature made after best before date */
105 const EVP_MD *(*evp_md)(void);
106 int (*verify_signature)(hx509_context context,
107 const struct signature_alg *,
108 const Certificate *,
109 const AlgorithmIdentifier *,
110 const heim_octet_string *,
111 const heim_octet_string *);
112 int (*create_signature)(hx509_context,
113 const struct signature_alg *,
114 const hx509_private_key,
115 const AlgorithmIdentifier *,
116 const heim_octet_string *,
117 AlgorithmIdentifier *,
118 heim_octet_string *);
119 int digest_size;
122 static const struct signature_alg *
123 find_sig_alg(const heim_oid *oid);
129 static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
131 static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
132 const AlgorithmIdentifier _hx509_signature_sha512_data = {
133 { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
136 static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
137 const AlgorithmIdentifier _hx509_signature_sha384_data = {
138 { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
141 static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
142 const AlgorithmIdentifier _hx509_signature_sha256_data = {
143 { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
146 static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
147 const AlgorithmIdentifier _hx509_signature_sha1_data = {
148 { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
151 static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
152 const AlgorithmIdentifier _hx509_signature_md5_data = {
153 { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
156 static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
157 const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
158 { 6, rk_UNCONST(ecPublicKey) }, NULL
161 static const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 };
162 const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = {
163 { 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL
166 static const unsigned ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 };
167 const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = {
168 { 6, rk_UNCONST(ecdsa_with_sha1_oid) }, NULL
171 static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
172 const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
173 { 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL
176 static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
177 const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
178 { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
181 static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
182 const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
183 { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
186 static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
187 const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
188 { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
191 static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
192 const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
193 { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
196 static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
197 const AlgorithmIdentifier _hx509_signature_rsa_data = {
198 { 7, rk_UNCONST(rsa_oid) }, NULL
201 static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
202 const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
203 { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
206 static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
207 const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
208 { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
211 static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
212 const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
213 { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
216 static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
217 const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
218 { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
225 static BIGNUM *
226 heim_int2BN(const heim_integer *i)
228 BIGNUM *bn;
230 bn = BN_bin2bn(i->data, i->length, NULL);
231 BN_set_negative(bn, i->negative);
232 return bn;
239 static int
240 set_digest_alg(DigestAlgorithmIdentifier *id,
241 const heim_oid *oid,
242 const void *param, size_t length)
244 int ret;
245 if (param) {
246 id->parameters = malloc(sizeof(*id->parameters));
247 if (id->parameters == NULL)
248 return ENOMEM;
249 id->parameters->data = malloc(length);
250 if (id->parameters->data == NULL) {
251 free(id->parameters);
252 id->parameters = NULL;
253 return ENOMEM;
255 memcpy(id->parameters->data, param, length);
256 id->parameters->length = length;
257 } else
258 id->parameters = NULL;
259 ret = der_copy_oid(oid, &id->algorithm);
260 if (ret) {
261 if (id->parameters) {
262 free(id->parameters->data);
263 free(id->parameters);
264 id->parameters = NULL;
266 return ret;
268 return 0;
271 #ifdef HAVE_OPENSSL
273 static int
274 heim_oid2ecnid(heim_oid *oid)
277 * Now map to openssl OID fun
280 if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0)
281 return NID_X9_62_prime256v1;
282 else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0)
283 return NID_secp160r1;
284 else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0)
285 return NID_secp160r2;
287 return -1;
290 static int
291 parse_ECParameters(hx509_context context,
292 heim_octet_string *parameters, int *nid)
294 ECParameters ecparam;
295 size_t size;
296 int ret;
298 if (parameters == NULL) {
299 ret = HX509_PARSING_KEY_FAILED;
300 hx509_set_error_string(context, 0, ret,
301 "EC parameters missing");
302 return ret;
305 ret = decode_ECParameters(parameters->data, parameters->length,
306 &ecparam, &size);
307 if (ret) {
308 hx509_set_error_string(context, 0, ret,
309 "Failed to decode EC parameters");
310 return ret;
313 if (ecparam.element != choice_ECParameters_namedCurve) {
314 free_ECParameters(&ecparam);
315 hx509_set_error_string(context, 0, ret,
316 "EC parameters is not a named curve");
317 return HX509_CRYPTO_SIG_INVALID_FORMAT;
320 *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
321 free_ECParameters(&ecparam);
322 if (*nid == -1) {
323 hx509_set_error_string(context, 0, ret,
324 "Failed to find matcing NID for EC curve");
325 return HX509_CRYPTO_SIG_INVALID_FORMAT;
327 return 0;
335 static int
336 ecdsa_verify_signature(hx509_context context,
337 const struct signature_alg *sig_alg,
338 const Certificate *signer,
339 const AlgorithmIdentifier *alg,
340 const heim_octet_string *data,
341 const heim_octet_string *sig)
343 const AlgorithmIdentifier *digest_alg;
344 const SubjectPublicKeyInfo *spi;
345 heim_octet_string digest;
346 int ret;
347 EC_KEY *key = NULL;
348 int groupnid;
349 EC_GROUP *group;
350 const unsigned char *p;
351 long len;
353 digest_alg = sig_alg->digest_alg;
355 ret = _hx509_create_signature(context,
356 NULL,
357 digest_alg,
358 data,
359 NULL,
360 &digest);
361 if (ret)
362 return ret;
364 /* set up EC KEY */
365 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
367 if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0)
368 return HX509_CRYPTO_SIG_INVALID_FORMAT;
370 #ifdef HAVE_OPENSSL
372 * Find the group id
375 ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
376 if (ret) {
377 der_free_octet_string(&digest);
378 return ret;
382 * Create group, key, parse key
385 key = EC_KEY_new();
386 group = EC_GROUP_new_by_curve_name(groupnid);
387 EC_KEY_set_group(key, group);
388 EC_GROUP_free(group);
390 p = spi->subjectPublicKey.data;
391 len = spi->subjectPublicKey.length / 8;
393 if (o2i_ECPublicKey(&key, &p, len) == NULL) {
394 EC_KEY_free(key);
395 return HX509_CRYPTO_SIG_INVALID_FORMAT;
397 #else
398 key = SubjectPublicKeyInfo2EC_KEY(spi);
399 #endif
401 ret = ECDSA_verify(-1, digest.data, digest.length,
402 sig->data, sig->length, key);
403 der_free_octet_string(&digest);
404 EC_KEY_free(key);
405 if (ret != 1) {
406 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
407 return ret;
410 return 0;
413 static int
414 ecdsa_create_signature(hx509_context context,
415 const struct signature_alg *sig_alg,
416 const hx509_private_key signer,
417 const AlgorithmIdentifier *alg,
418 const heim_octet_string *data,
419 AlgorithmIdentifier *signatureAlgorithm,
420 heim_octet_string *sig)
422 const AlgorithmIdentifier *digest_alg;
423 heim_octet_string indata;
424 const heim_oid *sig_oid;
425 unsigned int siglen;
426 int ret;
428 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0)
429 _hx509_abort("internal error passing private key to wrong ops");
431 sig_oid = sig_alg->sig_oid;
432 digest_alg = sig_alg->digest_alg;
434 if (signatureAlgorithm) {
435 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
436 if (ret) {
437 hx509_clear_error_string(context);
438 goto error;
442 ret = _hx509_create_signature(context,
443 NULL,
444 digest_alg,
445 data,
446 NULL,
447 &indata);
448 if (ret) {
449 if (signatureAlgorithm)
450 free_AlgorithmIdentifier(signatureAlgorithm);
451 goto error;
454 sig->length = ECDSA_size(signer->private_key.ecdsa);
455 sig->data = malloc(sig->length);
456 if (sig->data == NULL) {
457 der_free_octet_string(&indata);
458 ret = ENOMEM;
459 hx509_set_error_string(context, 0, ret, "out of memory");
460 goto error;
463 siglen = sig->length;
465 ret = ECDSA_sign(-1, indata.data, indata.length,
466 sig->data, &siglen, signer->private_key.ecdsa);
467 der_free_octet_string(&indata);
468 if (ret != 1) {
469 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
470 hx509_set_error_string(context, 0, ret,
471 "ECDSA sign failed: %d", ret);
472 goto error;
474 if (siglen > sig->length)
475 _hx509_abort("ECDSA signature prelen longer the output len");
477 sig->length = siglen;
479 return 0;
480 error:
481 if (signatureAlgorithm)
482 free_AlgorithmIdentifier(signatureAlgorithm);
483 return ret;
486 static int
487 ecdsa_available(const hx509_private_key signer,
488 const AlgorithmIdentifier *sig_alg)
490 const struct signature_alg *sig;
491 const EC_GROUP *group;
492 BN_CTX *bnctx = NULL;
493 BIGNUM *order = NULL;
494 int ret = 0;
496 if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
497 _hx509_abort("internal error passing private key to wrong ops");
499 sig = find_sig_alg(&sig_alg->algorithm);
501 if (sig == NULL || sig->digest_size == 0)
502 return 0;
504 group = EC_KEY_get0_group(signer->private_key.ecdsa);
505 if (group == NULL)
506 return 0;
508 bnctx = BN_CTX_new();
509 order = BN_new();
510 if (order == NULL)
511 goto err;
513 if (EC_GROUP_get_order(group, order, bnctx) != 1)
514 goto err;
516 if (BN_num_bytes(order) > sig->digest_size)
517 ret = 1;
518 err:
519 if (bnctx)
520 BN_CTX_free(bnctx);
521 if (order)
522 BN_clear_free(order);
524 return ret;
528 #endif /* HAVE_OPENSSL */
534 static int
535 rsa_verify_signature(hx509_context context,
536 const struct signature_alg *sig_alg,
537 const Certificate *signer,
538 const AlgorithmIdentifier *alg,
539 const heim_octet_string *data,
540 const heim_octet_string *sig)
542 const SubjectPublicKeyInfo *spi;
543 DigestInfo di;
544 unsigned char *to;
545 int tosize, retsize;
546 int ret;
547 RSA *rsa;
548 size_t size;
549 const unsigned char *p;
551 memset(&di, 0, sizeof(di));
553 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
555 p = spi->subjectPublicKey.data;
556 size = spi->subjectPublicKey.length / 8;
558 rsa = d2i_RSAPublicKey(NULL, &p, size);
559 if (rsa == NULL) {
560 ret = ENOMEM;
561 hx509_set_error_string(context, 0, ret, "out of memory");
562 goto out;
565 tosize = RSA_size(rsa);
566 to = malloc(tosize);
567 if (to == NULL) {
568 ret = ENOMEM;
569 hx509_set_error_string(context, 0, ret, "out of memory");
570 goto out;
573 retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
574 to, rsa, RSA_PKCS1_PADDING);
575 if (retsize <= 0) {
576 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
577 hx509_set_error_string(context, 0, ret,
578 "RSA public decrypt failed: %d", retsize);
579 free(to);
580 goto out;
582 if (retsize > tosize)
583 _hx509_abort("internal rsa decryption failure: ret > tosize");
585 if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
587 ret = decode_DigestInfo(to, retsize, &di, &size);
588 free(to);
589 if (ret) {
590 goto out;
593 /* Check for extra data inside the sigature */
594 if (size != (size_t)retsize) {
595 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
596 hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
597 goto out;
600 if (sig_alg->digest_alg &&
601 der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
602 &sig_alg->digest_alg->algorithm) != 0)
604 ret = HX509_CRYPTO_OID_MISMATCH;
605 hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
606 goto out;
609 /* verify that the parameters are NULL or the NULL-type */
610 if (di.digestAlgorithm.parameters != NULL &&
611 (di.digestAlgorithm.parameters->length != 2 ||
612 memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
614 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
615 hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
616 goto out;
619 ret = _hx509_verify_signature(context,
620 NULL,
621 &di.digestAlgorithm,
622 data,
623 &di.digest);
624 } else {
625 if ((size_t)retsize != data->length ||
626 ct_memcmp(to, data->data, retsize) != 0)
628 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
629 hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
630 goto out;
632 free(to);
634 ret = 0;
636 out:
637 free_DigestInfo(&di);
638 if (rsa)
639 RSA_free(rsa);
640 return ret;
643 static int
644 rsa_create_signature(hx509_context context,
645 const struct signature_alg *sig_alg,
646 const hx509_private_key signer,
647 const AlgorithmIdentifier *alg,
648 const heim_octet_string *data,
649 AlgorithmIdentifier *signatureAlgorithm,
650 heim_octet_string *sig)
652 const AlgorithmIdentifier *digest_alg;
653 heim_octet_string indata;
654 const heim_oid *sig_oid;
655 size_t size;
656 int ret;
658 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0)
659 return HX509_ALG_NOT_SUPP;
661 if (alg)
662 sig_oid = &alg->algorithm;
663 else
664 sig_oid = signer->signature_alg;
666 if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
667 digest_alg = hx509_signature_sha512();
668 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
669 digest_alg = hx509_signature_sha384();
670 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
671 digest_alg = hx509_signature_sha256();
672 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
673 digest_alg = hx509_signature_sha1();
674 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
675 digest_alg = hx509_signature_md5();
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_DSA_WITH_SHA1) == 0) {
679 digest_alg = hx509_signature_sha1();
680 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
681 digest_alg = hx509_signature_sha1();
682 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) {
683 digest_alg = NULL;
684 } else
685 return HX509_ALG_NOT_SUPP;
687 if (signatureAlgorithm) {
688 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
689 if (ret) {
690 hx509_clear_error_string(context);
691 return ret;
695 if (digest_alg) {
696 DigestInfo di;
697 memset(&di, 0, sizeof(di));
699 ret = _hx509_create_signature(context,
700 NULL,
701 digest_alg,
702 data,
703 &di.digestAlgorithm,
704 &di.digest);
705 if (ret)
706 return ret;
707 ASN1_MALLOC_ENCODE(DigestInfo,
708 indata.data,
709 indata.length,
710 &di,
711 &size,
712 ret);
713 free_DigestInfo(&di);
714 if (ret) {
715 hx509_set_error_string(context, 0, ret, "out of memory");
716 return ret;
718 if (indata.length != size)
719 _hx509_abort("internal ASN.1 encoder error");
720 } else {
721 indata = *data;
724 sig->length = RSA_size(signer->private_key.rsa);
725 sig->data = malloc(sig->length);
726 if (sig->data == NULL) {
727 der_free_octet_string(&indata);
728 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
729 return ENOMEM;
732 ret = RSA_private_encrypt(indata.length, indata.data,
733 sig->data,
734 signer->private_key.rsa,
735 RSA_PKCS1_PADDING);
736 if (indata.data != data->data)
737 der_free_octet_string(&indata);
738 if (ret <= 0) {
739 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
740 hx509_set_error_string(context, 0, ret,
741 "RSA private encrypt failed: %d", ret);
742 return ret;
744 if ((size_t)ret > sig->length)
745 _hx509_abort("RSA signature prelen longer the output len");
747 sig->length = ret;
749 return 0;
752 static int
753 rsa_private_key_import(hx509_context context,
754 const AlgorithmIdentifier *keyai,
755 const void *data,
756 size_t len,
757 hx509_key_format_t format,
758 hx509_private_key private_key)
760 switch (format) {
761 case HX509_KEY_FORMAT_DER: {
762 const unsigned char *p = data;
764 private_key->private_key.rsa =
765 d2i_RSAPrivateKey(NULL, &p, len);
766 if (private_key->private_key.rsa == NULL) {
767 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
768 "Failed to parse RSA key");
769 return HX509_PARSING_KEY_FAILED;
771 private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
772 break;
775 default:
776 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
779 return 0;
782 static int
783 rsa_private_key2SPKI(hx509_context context,
784 hx509_private_key private_key,
785 SubjectPublicKeyInfo *spki)
787 int len, ret;
789 memset(spki, 0, sizeof(*spki));
791 len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
793 spki->subjectPublicKey.data = malloc(len);
794 if (spki->subjectPublicKey.data == NULL) {
795 hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
796 return ENOMEM;
798 spki->subjectPublicKey.length = len * 8;
800 ret = set_digest_alg(&spki->algorithm, ASN1_OID_ID_PKCS1_RSAENCRYPTION,
801 "\x05\x00", 2);
802 if (ret) {
803 hx509_set_error_string(context, 0, ret, "malloc - out of memory");
804 free(spki->subjectPublicKey.data);
805 spki->subjectPublicKey.data = NULL;
806 spki->subjectPublicKey.length = 0;
807 return ret;
811 unsigned char *pp = spki->subjectPublicKey.data;
812 i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
815 return 0;
818 static int
819 rsa_generate_private_key(hx509_context context,
820 struct hx509_generate_private_context *ctx,
821 hx509_private_key private_key)
823 BIGNUM *e;
824 int ret;
825 unsigned long bits;
827 static const int default_rsa_e = 65537;
828 static const int default_rsa_bits = 2048;
830 private_key->private_key.rsa = RSA_new();
831 if (private_key->private_key.rsa == NULL) {
832 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
833 "Failed to generate RSA key");
834 return HX509_PARSING_KEY_FAILED;
837 e = BN_new();
838 BN_set_word(e, default_rsa_e);
840 bits = default_rsa_bits;
842 if (ctx->num_bits)
843 bits = ctx->num_bits;
845 ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
846 BN_free(e);
847 if (ret != 1) {
848 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
849 "Failed to generate RSA key");
850 return HX509_PARSING_KEY_FAILED;
852 private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
854 return 0;
857 static int
858 rsa_private_key_export(hx509_context context,
859 const hx509_private_key key,
860 hx509_key_format_t format,
861 heim_octet_string *data)
863 int ret;
865 data->data = NULL;
866 data->length = 0;
868 switch (format) {
869 case HX509_KEY_FORMAT_DER:
871 ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
872 if (ret <= 0) {
873 ret = EINVAL;
874 hx509_set_error_string(context, 0, ret,
875 "Private key is not exportable");
876 return ret;
879 data->data = malloc(ret);
880 if (data->data == NULL) {
881 ret = ENOMEM;
882 hx509_set_error_string(context, 0, ret, "malloc out of memory");
883 return ret;
885 data->length = ret;
888 unsigned char *p = data->data;
889 i2d_RSAPrivateKey(key->private_key.rsa, &p);
891 break;
892 default:
893 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
896 return 0;
899 static BIGNUM *
900 rsa_get_internal(hx509_context context,
901 hx509_private_key key,
902 const char *type)
904 if (strcasecmp(type, "rsa-modulus") == 0) {
905 return BN_dup(key->private_key.rsa->n);
906 } else if (strcasecmp(type, "rsa-exponent") == 0) {
907 return BN_dup(key->private_key.rsa->e);
908 } else
909 return NULL;
914 static hx509_private_key_ops rsa_private_key_ops = {
915 "RSA PRIVATE KEY",
916 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
917 NULL,
918 rsa_private_key2SPKI,
919 rsa_private_key_export,
920 rsa_private_key_import,
921 rsa_generate_private_key,
922 rsa_get_internal
925 #ifdef HAVE_OPENSSL
927 static int
928 ecdsa_private_key2SPKI(hx509_context context,
929 hx509_private_key private_key,
930 SubjectPublicKeyInfo *spki)
932 memset(spki, 0, sizeof(*spki));
933 return ENOMEM;
936 static int
937 ecdsa_private_key_export(hx509_context context,
938 const hx509_private_key key,
939 hx509_key_format_t format,
940 heim_octet_string *data)
942 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
945 static int
946 ecdsa_private_key_import(hx509_context context,
947 const AlgorithmIdentifier *keyai,
948 const void *data,
949 size_t len,
950 hx509_key_format_t format,
951 hx509_private_key private_key)
953 const unsigned char *p = data;
954 EC_KEY **pkey = NULL;
956 if (keyai->parameters) {
957 EC_GROUP *group;
958 int groupnid;
959 EC_KEY *key;
960 int ret;
962 ret = parse_ECParameters(context, keyai->parameters, &groupnid);
963 if (ret)
964 return ret;
966 key = EC_KEY_new();
967 if (key == NULL)
968 return ENOMEM;
970 group = EC_GROUP_new_by_curve_name(groupnid);
971 if (group == NULL) {
972 EC_KEY_free(key);
973 return ENOMEM;
975 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
976 if (EC_KEY_set_group(key, group) == 0) {
977 EC_KEY_free(key);
978 EC_GROUP_free(group);
979 return ENOMEM;
981 EC_GROUP_free(group);
982 pkey = &key;
985 switch (format) {
986 case HX509_KEY_FORMAT_DER:
988 private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
989 if (private_key->private_key.ecdsa == NULL) {
990 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
991 "Failed to parse EC private key");
992 return HX509_PARSING_KEY_FAILED;
994 private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256;
995 break;
997 default:
998 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
1001 return 0;
1004 static int
1005 ecdsa_generate_private_key(hx509_context context,
1006 struct hx509_generate_private_context *ctx,
1007 hx509_private_key private_key)
1009 return ENOMEM;
1012 static BIGNUM *
1013 ecdsa_get_internal(hx509_context context,
1014 hx509_private_key key,
1015 const char *type)
1017 return NULL;
1021 static hx509_private_key_ops ecdsa_private_key_ops = {
1022 "EC PRIVATE KEY",
1023 ASN1_OID_ID_ECPUBLICKEY,
1024 ecdsa_available,
1025 ecdsa_private_key2SPKI,
1026 ecdsa_private_key_export,
1027 ecdsa_private_key_import,
1028 ecdsa_generate_private_key,
1029 ecdsa_get_internal
1032 #endif /* HAVE_OPENSSL */
1038 static int
1039 dsa_verify_signature(hx509_context context,
1040 const struct signature_alg *sig_alg,
1041 const Certificate *signer,
1042 const AlgorithmIdentifier *alg,
1043 const heim_octet_string *data,
1044 const heim_octet_string *sig)
1046 const SubjectPublicKeyInfo *spi;
1047 DSAPublicKey pk;
1048 DSAParams param;
1049 size_t size;
1050 DSA *dsa;
1051 int ret;
1053 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1055 dsa = DSA_new();
1056 if (dsa == NULL) {
1057 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1058 return ENOMEM;
1061 ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
1062 spi->subjectPublicKey.length / 8,
1063 &pk, &size);
1064 if (ret)
1065 goto out;
1067 dsa->pub_key = heim_int2BN(&pk);
1069 free_DSAPublicKey(&pk);
1071 if (dsa->pub_key == NULL) {
1072 ret = ENOMEM;
1073 hx509_set_error_string(context, 0, ret, "out of memory");
1074 goto out;
1077 if (spi->algorithm.parameters == NULL) {
1078 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
1079 hx509_set_error_string(context, 0, ret, "DSA parameters missing");
1080 goto out;
1083 ret = decode_DSAParams(spi->algorithm.parameters->data,
1084 spi->algorithm.parameters->length,
1085 &param,
1086 &size);
1087 if (ret) {
1088 hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
1089 goto out;
1092 dsa->p = heim_int2BN(&param.p);
1093 dsa->q = heim_int2BN(&param.q);
1094 dsa->g = heim_int2BN(&param.g);
1096 free_DSAParams(&param);
1098 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
1099 ret = ENOMEM;
1100 hx509_set_error_string(context, 0, ret, "out of memory");
1101 goto out;
1104 ret = DSA_verify(-1, data->data, data->length,
1105 (unsigned char*)sig->data, sig->length,
1106 dsa);
1107 if (ret == 1)
1108 ret = 0;
1109 else if (ret == 0 || ret == -1) {
1110 ret = HX509_CRYPTO_BAD_SIGNATURE;
1111 hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
1112 } else {
1113 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
1114 hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
1117 out:
1118 DSA_free(dsa);
1120 return ret;
1123 #if 0
1124 static int
1125 dsa_parse_private_key(hx509_context context,
1126 const void *data,
1127 size_t len,
1128 hx509_private_key private_key)
1130 const unsigned char *p = data;
1132 private_key->private_key.dsa =
1133 d2i_DSAPrivateKey(NULL, &p, len);
1134 if (private_key->private_key.dsa == NULL)
1135 return EINVAL;
1136 private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1;
1138 return 0;
1139 /* else */
1140 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1141 "No support to parse DSA keys");
1142 return HX509_PARSING_KEY_FAILED;
1144 #endif
1146 static int
1147 evp_md_create_signature(hx509_context context,
1148 const struct signature_alg *sig_alg,
1149 const hx509_private_key signer,
1150 const AlgorithmIdentifier *alg,
1151 const heim_octet_string *data,
1152 AlgorithmIdentifier *signatureAlgorithm,
1153 heim_octet_string *sig)
1155 size_t sigsize = EVP_MD_size(sig_alg->evp_md());
1156 EVP_MD_CTX *ctx;
1158 memset(sig, 0, sizeof(*sig));
1160 if (signatureAlgorithm) {
1161 int ret;
1162 ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
1163 "\x05\x00", 2);
1164 if (ret)
1165 return ret;
1169 sig->data = malloc(sigsize);
1170 if (sig->data == NULL) {
1171 sig->length = 0;
1172 return ENOMEM;
1174 sig->length = sigsize;
1176 ctx = EVP_MD_CTX_create();
1177 EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
1178 EVP_DigestUpdate(ctx, data->data, data->length);
1179 EVP_DigestFinal_ex(ctx, sig->data, NULL);
1180 EVP_MD_CTX_destroy(ctx);
1183 return 0;
1186 static int
1187 evp_md_verify_signature(hx509_context context,
1188 const struct signature_alg *sig_alg,
1189 const Certificate *signer,
1190 const AlgorithmIdentifier *alg,
1191 const heim_octet_string *data,
1192 const heim_octet_string *sig)
1194 unsigned char digest[EVP_MAX_MD_SIZE];
1195 EVP_MD_CTX *ctx;
1196 size_t sigsize = EVP_MD_size(sig_alg->evp_md());
1198 if (sig->length != sigsize || sigsize > sizeof(digest)) {
1199 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1200 "SHA256 sigature have wrong length");
1201 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1204 ctx = EVP_MD_CTX_create();
1205 EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
1206 EVP_DigestUpdate(ctx, data->data, data->length);
1207 EVP_DigestFinal_ex(ctx, digest, NULL);
1208 EVP_MD_CTX_destroy(ctx);
1210 if (ct_memcmp(digest, sig->data, sigsize) != 0) {
1211 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
1212 "Bad %s sigature", sig_alg->name);
1213 return HX509_CRYPTO_BAD_SIGNATURE;
1216 return 0;
1219 #ifdef HAVE_OPENSSL
1221 static const struct signature_alg ecdsa_with_sha256_alg = {
1222 "ecdsa-with-sha256",
1223 ASN1_OID_ID_ECDSA_WITH_SHA256,
1224 &_hx509_signature_ecdsa_with_sha256_data,
1225 ASN1_OID_ID_ECPUBLICKEY,
1226 &_hx509_signature_sha256_data,
1227 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1229 NULL,
1230 ecdsa_verify_signature,
1231 ecdsa_create_signature,
1235 static const struct signature_alg ecdsa_with_sha1_alg = {
1236 "ecdsa-with-sha1",
1237 ASN1_OID_ID_ECDSA_WITH_SHA1,
1238 &_hx509_signature_ecdsa_with_sha1_data,
1239 ASN1_OID_ID_ECPUBLICKEY,
1240 &_hx509_signature_sha1_data,
1241 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1243 NULL,
1244 ecdsa_verify_signature,
1245 ecdsa_create_signature,
1249 #endif
1251 static const struct signature_alg heim_rsa_pkcs1_x509 = {
1252 "rsa-pkcs1-x509",
1253 ASN1_OID_ID_HEIM_RSA_PKCS1_X509,
1254 &_hx509_signature_rsa_pkcs1_x509_data,
1255 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1256 NULL,
1257 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
1259 NULL,
1260 rsa_verify_signature,
1261 rsa_create_signature,
1265 static const struct signature_alg pkcs1_rsa_sha1_alg = {
1266 "rsa",
1267 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1268 &_hx509_signature_rsa_with_sha1_data,
1269 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1270 NULL,
1271 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1273 NULL,
1274 rsa_verify_signature,
1275 rsa_create_signature,
1279 static const struct signature_alg rsa_with_sha512_alg = {
1280 "rsa-with-sha512",
1281 ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION,
1282 &_hx509_signature_rsa_with_sha512_data,
1283 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1284 &_hx509_signature_sha512_data,
1285 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1287 NULL,
1288 rsa_verify_signature,
1289 rsa_create_signature,
1293 static const struct signature_alg rsa_with_sha384_alg = {
1294 "rsa-with-sha384",
1295 ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION,
1296 &_hx509_signature_rsa_with_sha384_data,
1297 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1298 &_hx509_signature_sha384_data,
1299 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1301 NULL,
1302 rsa_verify_signature,
1303 rsa_create_signature,
1307 static const struct signature_alg rsa_with_sha256_alg = {
1308 "rsa-with-sha256",
1309 ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
1310 &_hx509_signature_rsa_with_sha256_data,
1311 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1312 &_hx509_signature_sha256_data,
1313 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1315 NULL,
1316 rsa_verify_signature,
1317 rsa_create_signature,
1321 static const struct signature_alg rsa_with_sha1_alg = {
1322 "rsa-with-sha1",
1323 ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION,
1324 &_hx509_signature_rsa_with_sha1_data,
1325 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1326 &_hx509_signature_sha1_data,
1327 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1329 NULL,
1330 rsa_verify_signature,
1331 rsa_create_signature,
1335 static const struct signature_alg rsa_with_sha1_alg_secsig = {
1336 "rsa-with-sha1",
1337 ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION,
1338 &_hx509_signature_rsa_with_sha1_data,
1339 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1340 &_hx509_signature_sha1_data,
1341 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
1343 NULL,
1344 rsa_verify_signature,
1345 rsa_create_signature,
1349 static const struct signature_alg rsa_with_md5_alg = {
1350 "rsa-with-md5",
1351 ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION,
1352 &_hx509_signature_rsa_with_md5_data,
1353 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
1354 &_hx509_signature_md5_data,
1355 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
1356 1230739889,
1357 NULL,
1358 rsa_verify_signature,
1359 rsa_create_signature,
1363 static const struct signature_alg dsa_sha1_alg = {
1364 "dsa-with-sha1",
1365 ASN1_OID_ID_DSA_WITH_SHA1,
1366 NULL,
1367 ASN1_OID_ID_DSA,
1368 &_hx509_signature_sha1_data,
1369 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
1371 NULL,
1372 dsa_verify_signature,
1373 /* create_signature */ NULL,
1377 static const struct signature_alg sha512_alg = {
1378 "sha-512",
1379 ASN1_OID_ID_SHA512,
1380 &_hx509_signature_sha512_data,
1381 NULL,
1382 NULL,
1383 SIG_DIGEST,
1385 EVP_sha512,
1386 evp_md_verify_signature,
1387 evp_md_create_signature,
1391 static const struct signature_alg sha384_alg = {
1392 "sha-384",
1393 ASN1_OID_ID_SHA512,
1394 &_hx509_signature_sha384_data,
1395 NULL,
1396 NULL,
1397 SIG_DIGEST,
1399 EVP_sha384,
1400 evp_md_verify_signature,
1401 evp_md_create_signature,
1405 static const struct signature_alg sha256_alg = {
1406 "sha-256",
1407 ASN1_OID_ID_SHA256,
1408 &_hx509_signature_sha256_data,
1409 NULL,
1410 NULL,
1411 SIG_DIGEST,
1413 EVP_sha256,
1414 evp_md_verify_signature,
1415 evp_md_create_signature,
1419 static const struct signature_alg sha1_alg = {
1420 "sha1",
1421 ASN1_OID_ID_SECSIG_SHA_1,
1422 &_hx509_signature_sha1_data,
1423 NULL,
1424 NULL,
1425 SIG_DIGEST,
1427 EVP_sha1,
1428 evp_md_verify_signature,
1429 evp_md_create_signature,
1433 static const struct signature_alg md5_alg = {
1434 "rsa-md5",
1435 ASN1_OID_ID_RSA_DIGEST_MD5,
1436 &_hx509_signature_md5_data,
1437 NULL,
1438 NULL,
1439 SIG_DIGEST,
1441 EVP_md5,
1442 evp_md_verify_signature,
1443 NULL,
1448 * Order matter in this structure, "best" first for each "key
1449 * compatible" type (type is ECDSA, RSA, DSA, none, etc)
1452 static const struct signature_alg *sig_algs[] = {
1453 #ifdef HAVE_OPENSSL
1454 &ecdsa_with_sha256_alg,
1455 &ecdsa_with_sha1_alg,
1456 #endif
1457 &rsa_with_sha512_alg,
1458 &rsa_with_sha384_alg,
1459 &rsa_with_sha256_alg,
1460 &rsa_with_sha1_alg,
1461 &rsa_with_sha1_alg_secsig,
1462 &pkcs1_rsa_sha1_alg,
1463 &rsa_with_md5_alg,
1464 &heim_rsa_pkcs1_x509,
1465 &dsa_sha1_alg,
1466 &sha512_alg,
1467 &sha384_alg,
1468 &sha256_alg,
1469 &sha1_alg,
1470 &md5_alg,
1471 NULL
1474 static const struct signature_alg *
1475 find_sig_alg(const heim_oid *oid)
1477 unsigned int i;
1478 for (i = 0; sig_algs[i]; i++)
1479 if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
1480 return sig_algs[i];
1481 return NULL;
1484 static const AlgorithmIdentifier *
1485 alg_for_privatekey(const hx509_private_key pk, int type)
1487 const heim_oid *keytype;
1488 unsigned int i;
1490 if (pk->ops == NULL)
1491 return NULL;
1493 keytype = pk->ops->key_oid;
1495 for (i = 0; sig_algs[i]; i++) {
1496 if (sig_algs[i]->key_oid == NULL)
1497 continue;
1498 if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
1499 continue;
1500 if (pk->ops->available &&
1501 pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
1502 continue;
1503 if (type == HX509_SELECT_PUBLIC_SIG)
1504 return sig_algs[i]->sig_alg;
1505 if (type == HX509_SELECT_DIGEST)
1506 return sig_algs[i]->digest_alg;
1508 return NULL;
1510 return NULL;
1517 static struct hx509_private_key_ops *private_algs[] = {
1518 &rsa_private_key_ops,
1519 #ifdef HAVE_OPENSSL
1520 &ecdsa_private_key_ops,
1521 #endif
1522 NULL
1525 hx509_private_key_ops *
1526 hx509_find_private_alg(const heim_oid *oid)
1528 int i;
1529 for (i = 0; private_algs[i]; i++) {
1530 if (private_algs[i]->key_oid == NULL)
1531 continue;
1532 if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
1533 return private_algs[i];
1535 return NULL;
1539 * Check if the algorithm `alg' have a best before date, and if it
1540 * des, make sure the its before the time `t'.
1544 _hx509_signature_best_before(hx509_context context,
1545 const AlgorithmIdentifier *alg,
1546 time_t t)
1548 const struct signature_alg *md;
1550 md = find_sig_alg(&alg->algorithm);
1551 if (md == NULL) {
1552 hx509_clear_error_string(context);
1553 return HX509_SIG_ALG_NO_SUPPORTED;
1555 if (md->best_before && md->best_before < t) {
1556 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1557 "Algorithm %s has passed it best before date",
1558 md->name);
1559 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1561 return 0;
1565 _hx509_self_signed_valid(hx509_context context,
1566 const AlgorithmIdentifier *alg)
1568 const struct signature_alg *md;
1570 md = find_sig_alg(&alg->algorithm);
1571 if (md == NULL) {
1572 hx509_clear_error_string(context);
1573 return HX509_SIG_ALG_NO_SUPPORTED;
1575 if ((md->flags & SELF_SIGNED_OK) == 0) {
1576 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1577 "Algorithm %s not trusted for self signatures",
1578 md->name);
1579 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1581 return 0;
1586 _hx509_verify_signature(hx509_context context,
1587 const hx509_cert cert,
1588 const AlgorithmIdentifier *alg,
1589 const heim_octet_string *data,
1590 const heim_octet_string *sig)
1592 const struct signature_alg *md;
1593 const Certificate *signer = NULL;
1595 if (cert)
1596 signer = _hx509_get_cert(cert);
1598 md = find_sig_alg(&alg->algorithm);
1599 if (md == NULL) {
1600 hx509_clear_error_string(context);
1601 return HX509_SIG_ALG_NO_SUPPORTED;
1603 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1604 hx509_clear_error_string(context);
1605 return HX509_CRYPTO_SIG_NO_CONF;
1607 if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1608 hx509_clear_error_string(context);
1609 return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1611 if (md->key_oid && signer) {
1612 const SubjectPublicKeyInfo *spi;
1613 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1615 if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
1616 hx509_clear_error_string(context);
1617 return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
1620 return (*md->verify_signature)(context, md, signer, alg, data, sig);
1624 _hx509_create_signature(hx509_context context,
1625 const hx509_private_key signer,
1626 const AlgorithmIdentifier *alg,
1627 const heim_octet_string *data,
1628 AlgorithmIdentifier *signatureAlgorithm,
1629 heim_octet_string *sig)
1631 const struct signature_alg *md;
1633 md = find_sig_alg(&alg->algorithm);
1634 if (md == NULL) {
1635 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1636 "algorithm no supported");
1637 return HX509_SIG_ALG_NO_SUPPORTED;
1640 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1641 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1642 "algorithm provides no conf");
1643 return HX509_CRYPTO_SIG_NO_CONF;
1646 return (*md->create_signature)(context, md, signer, alg, data,
1647 signatureAlgorithm, sig);
1651 _hx509_create_signature_bitstring(hx509_context context,
1652 const hx509_private_key signer,
1653 const AlgorithmIdentifier *alg,
1654 const heim_octet_string *data,
1655 AlgorithmIdentifier *signatureAlgorithm,
1656 heim_bit_string *sig)
1658 heim_octet_string os;
1659 int ret;
1661 ret = _hx509_create_signature(context, signer, alg,
1662 data, signatureAlgorithm, &os);
1663 if (ret)
1664 return ret;
1665 sig->data = os.data;
1666 sig->length = os.length * 8;
1667 return 0;
1671 _hx509_public_encrypt(hx509_context context,
1672 const heim_octet_string *cleartext,
1673 const Certificate *cert,
1674 heim_oid *encryption_oid,
1675 heim_octet_string *ciphertext)
1677 const SubjectPublicKeyInfo *spi;
1678 unsigned char *to;
1679 int tosize;
1680 int ret;
1681 RSA *rsa;
1682 size_t size;
1683 const unsigned char *p;
1685 ciphertext->data = NULL;
1686 ciphertext->length = 0;
1688 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1690 p = spi->subjectPublicKey.data;
1691 size = spi->subjectPublicKey.length / 8;
1693 rsa = d2i_RSAPublicKey(NULL, &p, size);
1694 if (rsa == NULL) {
1695 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1696 return ENOMEM;
1699 tosize = RSA_size(rsa);
1700 to = malloc(tosize);
1701 if (to == NULL) {
1702 RSA_free(rsa);
1703 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1704 return ENOMEM;
1707 ret = RSA_public_encrypt(cleartext->length,
1708 (unsigned char *)cleartext->data,
1709 to, rsa, RSA_PKCS1_PADDING);
1710 RSA_free(rsa);
1711 if (ret <= 0) {
1712 free(to);
1713 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
1714 "RSA public encrypt failed with %d", ret);
1715 return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
1717 if (ret > tosize)
1718 _hx509_abort("internal rsa decryption failure: ret > tosize");
1720 ciphertext->length = ret;
1721 ciphertext->data = to;
1723 ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
1724 if (ret) {
1725 der_free_octet_string(ciphertext);
1726 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1727 return ENOMEM;
1730 return 0;
1734 hx509_private_key_private_decrypt(hx509_context context,
1735 const heim_octet_string *ciphertext,
1736 const heim_oid *encryption_oid,
1737 hx509_private_key p,
1738 heim_octet_string *cleartext)
1740 int ret;
1742 cleartext->data = NULL;
1743 cleartext->length = 0;
1745 if (p->private_key.rsa == NULL) {
1746 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1747 "Private RSA key missing");
1748 return HX509_PRIVATE_KEY_MISSING;
1751 cleartext->length = RSA_size(p->private_key.rsa);
1752 cleartext->data = malloc(cleartext->length);
1753 if (cleartext->data == NULL) {
1754 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1755 return ENOMEM;
1757 ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
1758 cleartext->data,
1759 p->private_key.rsa,
1760 RSA_PKCS1_PADDING);
1761 if (ret <= 0) {
1762 der_free_octet_string(cleartext);
1763 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
1764 "Failed to decrypt using private key: %d", ret);
1765 return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
1767 if (cleartext->length < (size_t)ret)
1768 _hx509_abort("internal rsa decryption failure: ret > tosize");
1770 cleartext->length = ret;
1772 return 0;
1777 hx509_parse_private_key(hx509_context context,
1778 const AlgorithmIdentifier *keyai,
1779 const void *data,
1780 size_t len,
1781 hx509_key_format_t format,
1782 hx509_private_key *private_key)
1784 struct hx509_private_key_ops *ops;
1785 int ret;
1787 *private_key = NULL;
1789 ops = hx509_find_private_alg(&keyai->algorithm);
1790 if (ops == NULL) {
1791 hx509_clear_error_string(context);
1792 return HX509_SIG_ALG_NO_SUPPORTED;
1795 ret = hx509_private_key_init(private_key, ops, NULL);
1796 if (ret) {
1797 hx509_set_error_string(context, 0, ret, "out of memory");
1798 return ret;
1801 ret = (*ops->import)(context, keyai, data, len, format, *private_key);
1802 if (ret)
1803 hx509_private_key_free(private_key);
1805 return ret;
1813 hx509_private_key2SPKI(hx509_context context,
1814 hx509_private_key private_key,
1815 SubjectPublicKeyInfo *spki)
1817 const struct hx509_private_key_ops *ops = private_key->ops;
1818 if (ops == NULL || ops->get_spki == NULL) {
1819 hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1820 "Private key have no key2SPKI function");
1821 return HX509_UNIMPLEMENTED_OPERATION;
1823 return (*ops->get_spki)(context, private_key, spki);
1827 _hx509_generate_private_key_init(hx509_context context,
1828 const heim_oid *oid,
1829 struct hx509_generate_private_context **ctx)
1831 *ctx = NULL;
1833 if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
1834 hx509_set_error_string(context, 0, EINVAL,
1835 "private key not an RSA key");
1836 return EINVAL;
1839 *ctx = calloc(1, sizeof(**ctx));
1840 if (*ctx == NULL) {
1841 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1842 return ENOMEM;
1844 (*ctx)->key_oid = oid;
1846 return 0;
1850 _hx509_generate_private_key_is_ca(hx509_context context,
1851 struct hx509_generate_private_context *ctx)
1853 ctx->isCA = 1;
1854 return 0;
1858 _hx509_generate_private_key_bits(hx509_context context,
1859 struct hx509_generate_private_context *ctx,
1860 unsigned long bits)
1862 ctx->num_bits = bits;
1863 return 0;
1867 void
1868 _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1870 free(*ctx);
1871 *ctx = NULL;
1875 _hx509_generate_private_key(hx509_context context,
1876 struct hx509_generate_private_context *ctx,
1877 hx509_private_key *private_key)
1879 struct hx509_private_key_ops *ops;
1880 int ret;
1882 *private_key = NULL;
1884 ops = hx509_find_private_alg(ctx->key_oid);
1885 if (ops == NULL) {
1886 hx509_clear_error_string(context);
1887 return HX509_SIG_ALG_NO_SUPPORTED;
1890 ret = hx509_private_key_init(private_key, ops, NULL);
1891 if (ret) {
1892 hx509_set_error_string(context, 0, ret, "out of memory");
1893 return ret;
1896 ret = (*ops->generate_private_key)(context, ctx, *private_key);
1897 if (ret)
1898 hx509_private_key_free(private_key);
1900 return ret;
1907 const AlgorithmIdentifier *
1908 hx509_signature_sha512(void)
1909 { return &_hx509_signature_sha512_data; }
1911 const AlgorithmIdentifier *
1912 hx509_signature_sha384(void)
1913 { return &_hx509_signature_sha384_data; }
1915 const AlgorithmIdentifier *
1916 hx509_signature_sha256(void)
1917 { return &_hx509_signature_sha256_data; }
1919 const AlgorithmIdentifier *
1920 hx509_signature_sha1(void)
1921 { return &_hx509_signature_sha1_data; }
1923 const AlgorithmIdentifier *
1924 hx509_signature_md5(void)
1925 { return &_hx509_signature_md5_data; }
1927 const AlgorithmIdentifier *
1928 hx509_signature_ecPublicKey(void)
1929 { return &_hx509_signature_ecPublicKey; }
1931 const AlgorithmIdentifier *
1932 hx509_signature_ecdsa_with_sha256(void)
1933 { return &_hx509_signature_ecdsa_with_sha256_data; }
1935 const AlgorithmIdentifier *
1936 hx509_signature_ecdsa_with_sha1(void)
1937 { return &_hx509_signature_ecdsa_with_sha1_data; }
1939 const AlgorithmIdentifier *
1940 hx509_signature_rsa_with_sha512(void)
1941 { return &_hx509_signature_rsa_with_sha512_data; }
1943 const AlgorithmIdentifier *
1944 hx509_signature_rsa_with_sha384(void)
1945 { return &_hx509_signature_rsa_with_sha384_data; }
1947 const AlgorithmIdentifier *
1948 hx509_signature_rsa_with_sha256(void)
1949 { return &_hx509_signature_rsa_with_sha256_data; }
1951 const AlgorithmIdentifier *
1952 hx509_signature_rsa_with_sha1(void)
1953 { return &_hx509_signature_rsa_with_sha1_data; }
1955 const AlgorithmIdentifier *
1956 hx509_signature_rsa_with_md5(void)
1957 { return &_hx509_signature_rsa_with_md5_data; }
1959 const AlgorithmIdentifier *
1960 hx509_signature_rsa(void)
1961 { return &_hx509_signature_rsa_data; }
1963 const AlgorithmIdentifier *
1964 hx509_signature_rsa_pkcs1_x509(void)
1965 { return &_hx509_signature_rsa_pkcs1_x509_data; }
1967 const AlgorithmIdentifier *
1968 hx509_crypto_des_rsdi_ede3_cbc(void)
1969 { return &_hx509_des_rsdi_ede3_cbc_oid; }
1971 const AlgorithmIdentifier *
1972 hx509_crypto_aes128_cbc(void)
1973 { return &_hx509_crypto_aes128_cbc_data; }
1975 const AlgorithmIdentifier *
1976 hx509_crypto_aes256_cbc(void)
1977 { return &_hx509_crypto_aes256_cbc_data; }
1983 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
1984 &_hx509_signature_rsa_with_sha256_data;
1985 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
1986 &_hx509_signature_sha256_data;
1987 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
1988 &_hx509_crypto_aes128_cbc_data;
1995 hx509_private_key_init(hx509_private_key *key,
1996 hx509_private_key_ops *ops,
1997 void *keydata)
1999 *key = calloc(1, sizeof(**key));
2000 if (*key == NULL)
2001 return ENOMEM;
2002 (*key)->ref = 1;
2003 (*key)->ops = ops;
2004 (*key)->private_key.keydata = keydata;
2005 return 0;
2008 hx509_private_key
2009 _hx509_private_key_ref(hx509_private_key key)
2011 if (key->ref == 0)
2012 _hx509_abort("key refcount <= 0 on ref");
2013 key->ref++;
2014 if (key->ref == UINT_MAX)
2015 _hx509_abort("key refcount == UINT_MAX on ref");
2016 return key;
2019 const char *
2020 _hx509_private_pem_name(hx509_private_key key)
2022 return key->ops->pemtype;
2026 hx509_private_key_free(hx509_private_key *key)
2028 if (key == NULL || *key == NULL)
2029 return 0;
2031 if ((*key)->ref == 0)
2032 _hx509_abort("key refcount == 0 on free");
2033 if (--(*key)->ref > 0)
2034 return 0;
2036 if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
2037 if ((*key)->private_key.rsa)
2038 RSA_free((*key)->private_key.rsa);
2039 #ifdef HAVE_OPENSSL
2040 } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) {
2041 if ((*key)->private_key.ecdsa)
2042 EC_KEY_free((*key)->private_key.ecdsa);
2043 #endif
2045 (*key)->private_key.rsa = NULL;
2046 free(*key);
2047 *key = NULL;
2048 return 0;
2051 void
2052 hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
2054 if (key->private_key.rsa)
2055 RSA_free(key->private_key.rsa);
2056 key->private_key.rsa = ptr;
2057 key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
2058 key->md = &pkcs1_rsa_sha1_alg;
2062 _hx509_private_key_oid(hx509_context context,
2063 const hx509_private_key key,
2064 heim_oid *data)
2066 int ret;
2067 ret = der_copy_oid(key->ops->key_oid, data);
2068 if (ret)
2069 hx509_set_error_string(context, 0, ret, "malloc out of memory");
2070 return ret;
2074 _hx509_private_key_exportable(hx509_private_key key)
2076 if (key->ops->export == NULL)
2077 return 0;
2078 return 1;
2081 BIGNUM *
2082 _hx509_private_key_get_internal(hx509_context context,
2083 hx509_private_key key,
2084 const char *type)
2086 if (key->ops->get_internal == NULL)
2087 return NULL;
2088 return (*key->ops->get_internal)(context, key, type);
2092 _hx509_private_key_export(hx509_context context,
2093 const hx509_private_key key,
2094 hx509_key_format_t format,
2095 heim_octet_string *data)
2097 if (key->ops->export == NULL) {
2098 hx509_clear_error_string(context);
2099 return HX509_UNIMPLEMENTED_OPERATION;
2101 return (*key->ops->export)(context, key, format, data);
2108 struct hx509cipher {
2109 const char *name;
2110 int flags;
2111 #define CIPHER_WEAK 1
2112 const heim_oid *oid;
2113 const AlgorithmIdentifier *(*ai_func)(void);
2114 const EVP_CIPHER *(*evp_func)(void);
2115 int (*get_params)(hx509_context, const hx509_crypto,
2116 const heim_octet_string *, heim_octet_string *);
2117 int (*set_params)(hx509_context, const heim_octet_string *,
2118 hx509_crypto, heim_octet_string *);
2121 struct hx509_crypto_data {
2122 char *name;
2123 int flags;
2124 #define ALLOW_WEAK 1
2126 #define PADDING_NONE 2
2127 #define PADDING_PKCS7 4
2128 #define PADDING_FLAGS (2|4)
2129 const struct hx509cipher *cipher;
2130 const EVP_CIPHER *c;
2131 heim_octet_string key;
2132 heim_oid oid;
2133 void *param;
2140 static unsigned private_rc2_40_oid_data[] = { 127, 1 };
2142 static heim_oid asn1_oid_private_rc2_40 =
2143 { 2, private_rc2_40_oid_data };
2149 static int
2150 CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
2151 const heim_octet_string *ivec, heim_octet_string *param)
2153 size_t size;
2154 int ret;
2156 assert(crypto->param == NULL);
2157 if (ivec == NULL)
2158 return 0;
2160 ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
2161 ivec, &size, ret);
2162 if (ret == 0 && size != param->length)
2163 _hx509_abort("Internal asn1 encoder failure");
2164 if (ret)
2165 hx509_clear_error_string(context);
2166 return ret;
2169 static int
2170 CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
2171 hx509_crypto crypto, heim_octet_string *ivec)
2173 int ret;
2174 if (ivec == NULL)
2175 return 0;
2177 ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
2178 if (ret)
2179 hx509_clear_error_string(context);
2181 return ret;
2184 struct _RC2_params {
2185 int maximum_effective_key;
2188 static int
2189 CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
2190 const heim_octet_string *ivec, heim_octet_string *param)
2192 CMSRC2CBCParameter rc2params;
2193 const struct _RC2_params *p = crypto->param;
2194 int maximum_effective_key = 128;
2195 size_t size;
2196 int ret;
2198 memset(&rc2params, 0, sizeof(rc2params));
2200 if (p)
2201 maximum_effective_key = p->maximum_effective_key;
2203 switch(maximum_effective_key) {
2204 case 40:
2205 rc2params.rc2ParameterVersion = 160;
2206 break;
2207 case 64:
2208 rc2params.rc2ParameterVersion = 120;
2209 break;
2210 case 128:
2211 rc2params.rc2ParameterVersion = 58;
2212 break;
2214 rc2params.iv = *ivec;
2216 ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
2217 &rc2params, &size, ret);
2218 if (ret == 0 && size != param->length)
2219 _hx509_abort("Internal asn1 encoder failure");
2221 return ret;
2224 static int
2225 CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
2226 hx509_crypto crypto, heim_octet_string *ivec)
2228 CMSRC2CBCParameter rc2param;
2229 struct _RC2_params *p;
2230 size_t size;
2231 int ret;
2233 ret = decode_CMSRC2CBCParameter(param->data, param->length,
2234 &rc2param, &size);
2235 if (ret) {
2236 hx509_clear_error_string(context);
2237 return ret;
2240 p = calloc(1, sizeof(*p));
2241 if (p == NULL) {
2242 free_CMSRC2CBCParameter(&rc2param);
2243 hx509_clear_error_string(context);
2244 return ENOMEM;
2246 switch(rc2param.rc2ParameterVersion) {
2247 case 160:
2248 crypto->c = EVP_rc2_40_cbc();
2249 p->maximum_effective_key = 40;
2250 break;
2251 case 120:
2252 crypto->c = EVP_rc2_64_cbc();
2253 p->maximum_effective_key = 64;
2254 break;
2255 case 58:
2256 crypto->c = EVP_rc2_cbc();
2257 p->maximum_effective_key = 128;
2258 break;
2259 default:
2260 free(p);
2261 free_CMSRC2CBCParameter(&rc2param);
2262 return HX509_CRYPTO_SIG_INVALID_FORMAT;
2264 if (ivec)
2265 ret = der_copy_octet_string(&rc2param.iv, ivec);
2266 free_CMSRC2CBCParameter(&rc2param);
2267 if (ret) {
2268 free(p);
2269 hx509_clear_error_string(context);
2270 } else
2271 crypto->param = p;
2273 return ret;
2280 static const struct hx509cipher ciphers[] = {
2282 "rc2-cbc",
2283 CIPHER_WEAK,
2284 ASN1_OID_ID_PKCS3_RC2_CBC,
2285 NULL,
2286 EVP_rc2_cbc,
2287 CMSRC2CBCParam_get,
2288 CMSRC2CBCParam_set
2291 "rc2-cbc",
2292 CIPHER_WEAK,
2293 ASN1_OID_ID_RSADSI_RC2_CBC,
2294 NULL,
2295 EVP_rc2_cbc,
2296 CMSRC2CBCParam_get,
2297 CMSRC2CBCParam_set
2300 "rc2-40-cbc",
2301 CIPHER_WEAK,
2302 &asn1_oid_private_rc2_40,
2303 NULL,
2304 EVP_rc2_40_cbc,
2305 CMSRC2CBCParam_get,
2306 CMSRC2CBCParam_set
2309 "des-ede3-cbc",
2311 ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
2312 NULL,
2313 EVP_des_ede3_cbc,
2314 CMSCBCParam_get,
2315 CMSCBCParam_set
2318 "des-ede3-cbc",
2320 ASN1_OID_ID_RSADSI_DES_EDE3_CBC,
2321 hx509_crypto_des_rsdi_ede3_cbc,
2322 EVP_des_ede3_cbc,
2323 CMSCBCParam_get,
2324 CMSCBCParam_set
2327 "aes-128-cbc",
2329 ASN1_OID_ID_AES_128_CBC,
2330 hx509_crypto_aes128_cbc,
2331 EVP_aes_128_cbc,
2332 CMSCBCParam_get,
2333 CMSCBCParam_set
2336 "aes-192-cbc",
2338 ASN1_OID_ID_AES_192_CBC,
2339 NULL,
2340 EVP_aes_192_cbc,
2341 CMSCBCParam_get,
2342 CMSCBCParam_set
2345 "aes-256-cbc",
2347 ASN1_OID_ID_AES_256_CBC,
2348 hx509_crypto_aes256_cbc,
2349 EVP_aes_256_cbc,
2350 CMSCBCParam_get,
2351 CMSCBCParam_set
2355 static const struct hx509cipher *
2356 find_cipher_by_oid(const heim_oid *oid)
2358 size_t i;
2360 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
2361 if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
2362 return &ciphers[i];
2364 return NULL;
2367 static const struct hx509cipher *
2368 find_cipher_by_name(const char *name)
2370 size_t i;
2372 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
2373 if (strcasecmp(name, ciphers[i].name) == 0)
2374 return &ciphers[i];
2376 return NULL;
2380 const heim_oid *
2381 hx509_crypto_enctype_by_name(const char *name)
2383 const struct hx509cipher *cipher;
2385 cipher = find_cipher_by_name(name);
2386 if (cipher == NULL)
2387 return NULL;
2388 return cipher->oid;
2392 hx509_crypto_init(hx509_context context,
2393 const char *provider,
2394 const heim_oid *enctype,
2395 hx509_crypto *crypto)
2397 const struct hx509cipher *cipher;
2399 *crypto = NULL;
2401 cipher = find_cipher_by_oid(enctype);
2402 if (cipher == NULL) {
2403 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2404 "Algorithm not supported");
2405 return HX509_ALG_NOT_SUPP;
2408 *crypto = calloc(1, sizeof(**crypto));
2409 if (*crypto == NULL) {
2410 hx509_clear_error_string(context);
2411 return ENOMEM;
2414 (*crypto)->flags = PADDING_PKCS7;
2415 (*crypto)->cipher = cipher;
2416 (*crypto)->c = (*cipher->evp_func)();
2418 if (der_copy_oid(enctype, &(*crypto)->oid)) {
2419 hx509_crypto_destroy(*crypto);
2420 *crypto = NULL;
2421 hx509_clear_error_string(context);
2422 return ENOMEM;
2425 return 0;
2428 const char *
2429 hx509_crypto_provider(hx509_crypto crypto)
2431 return "unknown";
2434 void
2435 hx509_crypto_destroy(hx509_crypto crypto)
2437 if (crypto->name)
2438 free(crypto->name);
2439 if (crypto->key.data)
2440 free(crypto->key.data);
2441 if (crypto->param)
2442 free(crypto->param);
2443 der_free_oid(&crypto->oid);
2444 memset(crypto, 0, sizeof(*crypto));
2445 free(crypto);
2449 hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2451 return 0;
2454 void
2455 hx509_crypto_allow_weak(hx509_crypto crypto)
2457 crypto->flags |= ALLOW_WEAK;
2460 void
2461 hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
2463 switch (padding_type) {
2464 case HX509_CRYPTO_PADDING_PKCS7:
2465 crypto->flags &= ~PADDING_FLAGS;
2466 crypto->flags |= PADDING_PKCS7;
2467 break;
2468 case HX509_CRYPTO_PADDING_NONE:
2469 crypto->flags &= ~PADDING_FLAGS;
2470 crypto->flags |= PADDING_NONE;
2471 break;
2472 default:
2473 _hx509_abort("Invalid padding");
2478 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2480 if (EVP_CIPHER_key_length(crypto->c) > (int)length)
2481 return HX509_CRYPTO_INTERNAL_ERROR;
2483 if (crypto->key.data) {
2484 free(crypto->key.data);
2485 crypto->key.data = NULL;
2486 crypto->key.length = 0;
2488 crypto->key.data = malloc(length);
2489 if (crypto->key.data == NULL)
2490 return ENOMEM;
2491 memcpy(crypto->key.data, data, length);
2492 crypto->key.length = length;
2494 return 0;
2498 hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2500 if (crypto->key.data) {
2501 free(crypto->key.data);
2502 crypto->key.length = 0;
2505 crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2506 crypto->key.data = malloc(crypto->key.length);
2507 if (crypto->key.data == NULL) {
2508 crypto->key.length = 0;
2509 return ENOMEM;
2511 if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2512 free(crypto->key.data);
2513 crypto->key.data = NULL;
2514 crypto->key.length = 0;
2515 return HX509_CRYPTO_INTERNAL_ERROR;
2517 if (key)
2518 return der_copy_octet_string(&crypto->key, key);
2519 else
2520 return 0;
2524 hx509_crypto_set_params(hx509_context context,
2525 hx509_crypto crypto,
2526 const heim_octet_string *param,
2527 heim_octet_string *ivec)
2529 return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2533 hx509_crypto_get_params(hx509_context context,
2534 hx509_crypto crypto,
2535 const heim_octet_string *ivec,
2536 heim_octet_string *param)
2538 return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2542 hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2544 ivec->length = EVP_CIPHER_iv_length(crypto->c);
2545 ivec->data = malloc(ivec->length);
2546 if (ivec->data == NULL) {
2547 ivec->length = 0;
2548 return ENOMEM;
2551 if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2552 free(ivec->data);
2553 ivec->data = NULL;
2554 ivec->length = 0;
2555 return HX509_CRYPTO_INTERNAL_ERROR;
2557 return 0;
2561 hx509_crypto_encrypt(hx509_crypto crypto,
2562 const void *data,
2563 const size_t length,
2564 const heim_octet_string *ivec,
2565 heim_octet_string **ciphertext)
2567 EVP_CIPHER_CTX evp;
2568 size_t padsize, bsize;
2569 int ret;
2571 *ciphertext = NULL;
2573 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2574 (crypto->flags & ALLOW_WEAK) == 0)
2575 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2577 assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
2579 EVP_CIPHER_CTX_init(&evp);
2581 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2582 crypto->key.data, ivec->data, 1);
2583 if (ret != 1) {
2584 EVP_CIPHER_CTX_cleanup(&evp);
2585 ret = HX509_CRYPTO_INTERNAL_ERROR;
2586 goto out;
2589 *ciphertext = calloc(1, sizeof(**ciphertext));
2590 if (*ciphertext == NULL) {
2591 ret = ENOMEM;
2592 goto out;
2595 assert(crypto->flags & PADDING_FLAGS);
2597 bsize = EVP_CIPHER_block_size(crypto->c);
2598 padsize = 0;
2600 if (crypto->flags & PADDING_NONE) {
2601 if (bsize != 1 && (length % bsize) != 0)
2602 return HX509_CMS_PADDING_ERROR;
2603 } else if (crypto->flags & PADDING_PKCS7) {
2604 if (bsize != 1)
2605 padsize = bsize - (length % bsize);
2608 (*ciphertext)->length = length + padsize;
2609 (*ciphertext)->data = malloc(length + padsize);
2610 if ((*ciphertext)->data == NULL) {
2611 ret = ENOMEM;
2612 goto out;
2615 memcpy((*ciphertext)->data, data, length);
2616 if (padsize) {
2617 size_t i;
2618 unsigned char *p = (*ciphertext)->data;
2619 p += length;
2620 for (i = 0; i < padsize; i++)
2621 *p++ = padsize;
2624 ret = EVP_Cipher(&evp, (*ciphertext)->data,
2625 (*ciphertext)->data,
2626 length + padsize);
2627 if (ret != 1) {
2628 ret = HX509_CRYPTO_INTERNAL_ERROR;
2629 goto out;
2631 ret = 0;
2633 out:
2634 if (ret) {
2635 if (*ciphertext) {
2636 if ((*ciphertext)->data) {
2637 free((*ciphertext)->data);
2639 free(*ciphertext);
2640 *ciphertext = NULL;
2643 EVP_CIPHER_CTX_cleanup(&evp);
2645 return ret;
2649 hx509_crypto_decrypt(hx509_crypto crypto,
2650 const void *data,
2651 const size_t length,
2652 heim_octet_string *ivec,
2653 heim_octet_string *clear)
2655 EVP_CIPHER_CTX evp;
2656 void *idata = NULL;
2657 int ret;
2659 clear->data = NULL;
2660 clear->length = 0;
2662 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2663 (crypto->flags & ALLOW_WEAK) == 0)
2664 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2666 if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length)
2667 return HX509_CRYPTO_INTERNAL_ERROR;
2669 if (crypto->key.data == NULL)
2670 return HX509_CRYPTO_INTERNAL_ERROR;
2672 if (ivec)
2673 idata = ivec->data;
2675 EVP_CIPHER_CTX_init(&evp);
2677 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2678 crypto->key.data, idata, 0);
2679 if (ret != 1) {
2680 EVP_CIPHER_CTX_cleanup(&evp);
2681 return HX509_CRYPTO_INTERNAL_ERROR;
2684 clear->length = length;
2685 clear->data = malloc(length);
2686 if (clear->data == NULL) {
2687 EVP_CIPHER_CTX_cleanup(&evp);
2688 clear->length = 0;
2689 return ENOMEM;
2692 if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2693 return HX509_CRYPTO_INTERNAL_ERROR;
2695 EVP_CIPHER_CTX_cleanup(&evp);
2697 if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
2698 int padsize;
2699 unsigned char *p;
2700 int j, bsize = EVP_CIPHER_block_size(crypto->c);
2702 if ((int)clear->length < bsize) {
2703 ret = HX509_CMS_PADDING_ERROR;
2704 goto out;
2707 p = clear->data;
2708 p += clear->length - 1;
2709 padsize = *p;
2710 if (padsize > bsize) {
2711 ret = HX509_CMS_PADDING_ERROR;
2712 goto out;
2714 clear->length -= padsize;
2715 for (j = 0; j < padsize; j++) {
2716 if (*p-- != padsize) {
2717 ret = HX509_CMS_PADDING_ERROR;
2718 goto out;
2723 return 0;
2725 out:
2726 if (clear->data)
2727 free(clear->data);
2728 clear->data = NULL;
2729 clear->length = 0;
2730 return ret;
2733 typedef int (*PBE_string2key_func)(hx509_context,
2734 const char *,
2735 const heim_octet_string *,
2736 hx509_crypto *, heim_octet_string *,
2737 heim_octet_string *,
2738 const heim_oid *, const EVP_MD *);
2740 static int
2741 PBE_string2key(hx509_context context,
2742 const char *password,
2743 const heim_octet_string *parameters,
2744 hx509_crypto *crypto,
2745 heim_octet_string *key, heim_octet_string *iv,
2746 const heim_oid *enc_oid,
2747 const EVP_MD *md)
2749 PKCS12_PBEParams p12params;
2750 int passwordlen;
2751 hx509_crypto c;
2752 int iter, saltlen, ret;
2753 unsigned char *salt;
2755 passwordlen = password ? strlen(password) : 0;
2757 if (parameters == NULL)
2758 return HX509_ALG_NOT_SUPP;
2760 ret = decode_PKCS12_PBEParams(parameters->data,
2761 parameters->length,
2762 &p12params, NULL);
2763 if (ret)
2764 goto out;
2766 if (p12params.iterations)
2767 iter = *p12params.iterations;
2768 else
2769 iter = 1;
2770 salt = p12params.salt.data;
2771 saltlen = p12params.salt.length;
2773 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2774 PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2775 ret = HX509_CRYPTO_INTERNAL_ERROR;
2776 goto out;
2779 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2780 PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2781 ret = HX509_CRYPTO_INTERNAL_ERROR;
2782 goto out;
2785 ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2786 if (ret)
2787 goto out;
2789 hx509_crypto_allow_weak(c);
2791 ret = hx509_crypto_set_key_data(c, key->data, key->length);
2792 if (ret) {
2793 hx509_crypto_destroy(c);
2794 goto out;
2797 *crypto = c;
2798 out:
2799 free_PKCS12_PBEParams(&p12params);
2800 return ret;
2803 static const heim_oid *
2804 find_string2key(const heim_oid *oid,
2805 const EVP_CIPHER **c,
2806 const EVP_MD **md,
2807 PBE_string2key_func *s2k)
2809 if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
2810 *c = EVP_rc2_40_cbc();
2811 *md = EVP_sha1();
2812 *s2k = PBE_string2key;
2813 return &asn1_oid_private_rc2_40;
2814 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
2815 *c = EVP_rc2_cbc();
2816 *md = EVP_sha1();
2817 *s2k = PBE_string2key;
2818 return ASN1_OID_ID_PKCS3_RC2_CBC;
2819 #if 0
2820 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
2821 *c = EVP_rc4_40();
2822 *md = EVP_sha1();
2823 *s2k = PBE_string2key;
2824 return NULL;
2825 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
2826 *c = EVP_rc4();
2827 *md = EVP_sha1();
2828 *s2k = PBE_string2key;
2829 return ASN1_OID_ID_PKCS3_RC4;
2830 #endif
2831 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
2832 *c = EVP_des_ede3_cbc();
2833 *md = EVP_sha1();
2834 *s2k = PBE_string2key;
2835 return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
2838 return NULL;
2846 _hx509_pbe_encrypt(hx509_context context,
2847 hx509_lock lock,
2848 const AlgorithmIdentifier *ai,
2849 const heim_octet_string *content,
2850 heim_octet_string *econtent)
2852 hx509_clear_error_string(context);
2853 return EINVAL;
2861 _hx509_pbe_decrypt(hx509_context context,
2862 hx509_lock lock,
2863 const AlgorithmIdentifier *ai,
2864 const heim_octet_string *econtent,
2865 heim_octet_string *content)
2867 const struct _hx509_password *pw;
2868 heim_octet_string key, iv;
2869 const heim_oid *enc_oid;
2870 const EVP_CIPHER *c;
2871 const EVP_MD *md;
2872 PBE_string2key_func s2k;
2873 int ret = 0;
2874 size_t i;
2876 memset(&key, 0, sizeof(key));
2877 memset(&iv, 0, sizeof(iv));
2879 memset(content, 0, sizeof(*content));
2881 enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2882 if (enc_oid == NULL) {
2883 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2884 "String to key algorithm not supported");
2885 ret = HX509_ALG_NOT_SUPP;
2886 goto out;
2889 key.length = EVP_CIPHER_key_length(c);
2890 key.data = malloc(key.length);
2891 if (key.data == NULL) {
2892 ret = ENOMEM;
2893 hx509_clear_error_string(context);
2894 goto out;
2897 iv.length = EVP_CIPHER_iv_length(c);
2898 iv.data = malloc(iv.length);
2899 if (iv.data == NULL) {
2900 ret = ENOMEM;
2901 hx509_clear_error_string(context);
2902 goto out;
2905 pw = _hx509_lock_get_passwords(lock);
2907 ret = HX509_CRYPTO_INTERNAL_ERROR;
2908 for (i = 0; i < pw->len + 1; i++) {
2909 hx509_crypto crypto;
2910 const char *password;
2912 if (i < pw->len)
2913 password = pw->val[i];
2914 else if (i < pw->len + 1)
2915 password = "";
2916 else
2917 password = NULL;
2919 ret = (*s2k)(context, password, ai->parameters, &crypto,
2920 &key, &iv, enc_oid, md);
2921 if (ret)
2922 goto out;
2924 ret = hx509_crypto_decrypt(crypto,
2925 econtent->data,
2926 econtent->length,
2927 &iv,
2928 content);
2929 hx509_crypto_destroy(crypto);
2930 if (ret == 0)
2931 goto out;
2934 out:
2935 if (key.data)
2936 der_free_octet_string(&key);
2937 if (iv.data)
2938 der_free_octet_string(&iv);
2939 return ret;
2947 static int
2948 match_keys_rsa(hx509_cert c, hx509_private_key private_key)
2950 const Certificate *cert;
2951 const SubjectPublicKeyInfo *spi;
2952 RSAPublicKey pk;
2953 RSA *rsa;
2954 size_t size;
2955 int ret;
2957 if (private_key->private_key.rsa == NULL)
2958 return 0;
2960 rsa = private_key->private_key.rsa;
2961 if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2962 return 0;
2964 cert = _hx509_get_cert(c);
2965 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2967 rsa = RSA_new();
2968 if (rsa == NULL)
2969 return 0;
2971 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2972 spi->subjectPublicKey.length / 8,
2973 &pk, &size);
2974 if (ret) {
2975 RSA_free(rsa);
2976 return 0;
2978 rsa->n = heim_int2BN(&pk.modulus);
2979 rsa->e = heim_int2BN(&pk.publicExponent);
2981 free_RSAPublicKey(&pk);
2983 rsa->d = BN_dup(private_key->private_key.rsa->d);
2984 rsa->p = BN_dup(private_key->private_key.rsa->p);
2985 rsa->q = BN_dup(private_key->private_key.rsa->q);
2986 rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
2987 rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
2988 rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
2990 if (rsa->n == NULL || rsa->e == NULL ||
2991 rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
2992 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
2993 RSA_free(rsa);
2994 return 0;
2997 ret = RSA_check_key(rsa);
2998 RSA_free(rsa);
3000 return ret == 1;
3003 static int
3004 match_keys_ec(hx509_cert c, hx509_private_key private_key)
3006 return 1; /* XXX use EC_KEY_check_key */
3011 _hx509_match_keys(hx509_cert c, hx509_private_key key)
3013 if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
3014 return match_keys_rsa(c, key);
3015 if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
3016 return match_keys_ec(c, key);
3017 return 0;
3022 static const heim_oid *
3023 find_keytype(const hx509_private_key key)
3025 const struct signature_alg *md;
3027 if (key == NULL)
3028 return NULL;
3030 md = find_sig_alg(key->signature_alg);
3031 if (md == NULL)
3032 return NULL;
3033 return md->key_oid;
3037 hx509_crypto_select(const hx509_context context,
3038 int type,
3039 const hx509_private_key source,
3040 hx509_peer_info peer,
3041 AlgorithmIdentifier *selected)
3043 const AlgorithmIdentifier *def = NULL;
3044 size_t i, j;
3045 int ret, bits;
3047 memset(selected, 0, sizeof(*selected));
3049 if (type == HX509_SELECT_DIGEST) {
3050 bits = SIG_DIGEST;
3051 if (source)
3052 def = alg_for_privatekey(source, type);
3053 if (def == NULL)
3054 def = _hx509_crypto_default_digest_alg;
3055 } else if (type == HX509_SELECT_PUBLIC_SIG) {
3056 bits = SIG_PUBLIC_SIG;
3057 /* XXX depend on `source´ and `peer´ */
3058 if (source)
3059 def = alg_for_privatekey(source, type);
3060 if (def == NULL)
3061 def = _hx509_crypto_default_sig_alg;
3062 } else if (type == HX509_SELECT_SECRET_ENC) {
3063 bits = SIG_SECRET;
3064 def = _hx509_crypto_default_secret_alg;
3065 } else {
3066 hx509_set_error_string(context, 0, EINVAL,
3067 "Unknown type %d of selection", type);
3068 return EINVAL;
3071 if (peer) {
3072 const heim_oid *keytype = NULL;
3074 keytype = find_keytype(source);
3076 for (i = 0; i < peer->len; i++) {
3077 for (j = 0; sig_algs[j]; j++) {
3078 if ((sig_algs[j]->flags & bits) != bits)
3079 continue;
3080 if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
3081 &peer->val[i].algorithm) != 0)
3082 continue;
3083 if (keytype && sig_algs[j]->key_oid &&
3084 der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
3085 continue;
3087 /* found one, use that */
3088 ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
3089 if (ret)
3090 hx509_clear_error_string(context);
3091 return ret;
3093 if (bits & SIG_SECRET) {
3094 const struct hx509cipher *cipher;
3096 cipher = find_cipher_by_oid(&peer->val[i].algorithm);
3097 if (cipher == NULL)
3098 continue;
3099 if (cipher->ai_func == NULL)
3100 continue;
3101 ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
3102 if (ret)
3103 hx509_clear_error_string(context);
3104 return ret;
3109 /* use default */
3110 ret = copy_AlgorithmIdentifier(def, selected);
3111 if (ret)
3112 hx509_clear_error_string(context);
3113 return ret;
3117 hx509_crypto_available(hx509_context context,
3118 int type,
3119 hx509_cert source,
3120 AlgorithmIdentifier **val,
3121 unsigned int *plen)
3123 const heim_oid *keytype = NULL;
3124 unsigned int len, i;
3125 void *ptr;
3126 int bits, ret;
3128 *val = NULL;
3130 if (type == HX509_SELECT_ALL) {
3131 bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
3132 } else if (type == HX509_SELECT_DIGEST) {
3133 bits = SIG_DIGEST;
3134 } else if (type == HX509_SELECT_PUBLIC_SIG) {
3135 bits = SIG_PUBLIC_SIG;
3136 } else {
3137 hx509_set_error_string(context, 0, EINVAL,
3138 "Unknown type %d of available", type);
3139 return EINVAL;
3142 if (source)
3143 keytype = find_keytype(_hx509_cert_private_key(source));
3145 len = 0;
3146 for (i = 0; sig_algs[i]; i++) {
3147 if ((sig_algs[i]->flags & bits) == 0)
3148 continue;
3149 if (sig_algs[i]->sig_alg == NULL)
3150 continue;
3151 if (keytype && sig_algs[i]->key_oid &&
3152 der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
3153 continue;
3155 /* found one, add that to the list */
3156 ptr = realloc(*val, sizeof(**val) * (len + 1));
3157 if (ptr == NULL)
3158 goto out;
3159 *val = ptr;
3161 ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
3162 if (ret)
3163 goto out;
3164 len++;
3167 /* Add AES */
3168 if (bits & SIG_SECRET) {
3170 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
3172 if (ciphers[i].flags & CIPHER_WEAK)
3173 continue;
3174 if (ciphers[i].ai_func == NULL)
3175 continue;
3177 ptr = realloc(*val, sizeof(**val) * (len + 1));
3178 if (ptr == NULL)
3179 goto out;
3180 *val = ptr;
3182 ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
3183 if (ret)
3184 goto out;
3185 len++;
3189 *plen = len;
3190 return 0;
3192 out:
3193 for (i = 0; i < len; i++)
3194 free_AlgorithmIdentifier(&(*val)[i]);
3195 free(*val);
3196 *val = NULL;
3197 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
3198 return ENOMEM;
3201 void
3202 hx509_crypto_free_algs(AlgorithmIdentifier *val,
3203 unsigned int len)
3205 unsigned int i;
3206 for (i = 0; i < len; i++)
3207 free_AlgorithmIdentifier(&val[i]);
3208 free(val);