No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / hx509 / crypto.c
blob8cb850f6c98729c880a33fe6d92d364ca731578f
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"
35 __RCSID("$Heimdal: crypto.c 22435 2008-01-14 20:53:56Z lha $"
36 "$NetBSD$");
38 struct hx509_crypto;
40 struct signature_alg;
42 enum crypto_op_type {
43 COT_SIGN
46 struct hx509_generate_private_context {
47 const heim_oid *key_oid;
48 int isCA;
49 unsigned long num_bits;
52 struct hx509_private_key_ops {
53 const char *pemtype;
54 const heim_oid *(*key_oid)(void);
55 int (*get_spki)(hx509_context,
56 const hx509_private_key,
57 SubjectPublicKeyInfo *);
58 int (*export)(hx509_context context,
59 const hx509_private_key,
60 heim_octet_string *);
61 int (*import)(hx509_context,
62 const void *data,
63 size_t len,
64 hx509_private_key private_key);
65 int (*generate_private_key)(hx509_context,
66 struct hx509_generate_private_context *,
67 hx509_private_key);
68 BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
69 int (*handle_alg)(const hx509_private_key,
70 const AlgorithmIdentifier *,
71 enum crypto_op_type);
72 int (*sign)(hx509_context context,
73 const hx509_private_key,
74 const AlgorithmIdentifier *,
75 const heim_octet_string *,
76 AlgorithmIdentifier *,
77 heim_octet_string *);
78 #if 0
79 const AlgorithmIdentifier *(*preferred_sig_alg)
80 (const hx509_private_key,
81 const hx509_peer_info);
82 int (*unwrap)(hx509_context context,
83 const hx509_private_key,
84 const AlgorithmIdentifier *,
85 const heim_octet_string *,
86 heim_octet_string *);
87 #endif
90 struct hx509_private_key {
91 unsigned int ref;
92 const struct signature_alg *md;
93 const heim_oid *signature_alg;
94 union {
95 RSA *rsa;
96 void *keydata;
97 } private_key;
98 /* new crypto layer */
99 hx509_private_key_ops *ops;
106 struct signature_alg {
107 const char *name;
108 const heim_oid *(*sig_oid)(void);
109 const AlgorithmIdentifier *(*sig_alg)(void);
110 const heim_oid *(*key_oid)(void);
111 const heim_oid *(*digest_oid)(void);
112 int flags;
113 #define PROVIDE_CONF 1
114 #define REQUIRE_SIGNER 2
116 #define SIG_DIGEST 0x100
117 #define SIG_PUBLIC_SIG 0x200
118 #define SIG_SECRET 0x400
120 #define RA_RSA_USES_DIGEST_INFO 0x1000000
123 int (*verify_signature)(hx509_context context,
124 const struct signature_alg *,
125 const Certificate *,
126 const AlgorithmIdentifier *,
127 const heim_octet_string *,
128 const heim_octet_string *);
129 int (*create_signature)(hx509_context,
130 const struct signature_alg *,
131 const hx509_private_key,
132 const AlgorithmIdentifier *,
133 const heim_octet_string *,
134 AlgorithmIdentifier *,
135 heim_octet_string *);
142 static BIGNUM *
143 heim_int2BN(const heim_integer *i)
145 BIGNUM *bn;
147 bn = BN_bin2bn(i->data, i->length, NULL);
148 BN_set_negative(bn, i->negative);
149 return bn;
156 static int
157 set_digest_alg(DigestAlgorithmIdentifier *id,
158 const heim_oid *oid,
159 const void *param, size_t length)
161 int ret;
162 if (param) {
163 id->parameters = malloc(sizeof(*id->parameters));
164 if (id->parameters == NULL)
165 return ENOMEM;
166 id->parameters->data = malloc(length);
167 if (id->parameters->data == NULL) {
168 free(id->parameters);
169 id->parameters = NULL;
170 return ENOMEM;
172 memcpy(id->parameters->data, param, length);
173 id->parameters->length = length;
174 } else
175 id->parameters = NULL;
176 ret = der_copy_oid(oid, &id->algorithm);
177 if (ret) {
178 if (id->parameters) {
179 free(id->parameters->data);
180 free(id->parameters);
181 id->parameters = NULL;
183 return ret;
185 return 0;
192 static int
193 rsa_verify_signature(hx509_context context,
194 const struct signature_alg *sig_alg,
195 const Certificate *signer,
196 const AlgorithmIdentifier *alg,
197 const heim_octet_string *data,
198 const heim_octet_string *sig)
200 const SubjectPublicKeyInfo *spi;
201 DigestInfo di;
202 unsigned char *to;
203 int tosize, retsize;
204 int ret;
205 RSA *rsa;
206 RSAPublicKey pk;
207 size_t size;
209 memset(&di, 0, sizeof(di));
211 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
213 rsa = RSA_new();
214 if (rsa == NULL) {
215 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
216 return ENOMEM;
218 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
219 spi->subjectPublicKey.length / 8,
220 &pk, &size);
221 if (ret) {
222 hx509_set_error_string(context, 0, ret, "Failed to decode RSAPublicKey");
223 goto out;
226 rsa->n = heim_int2BN(&pk.modulus);
227 rsa->e = heim_int2BN(&pk.publicExponent);
229 free_RSAPublicKey(&pk);
231 if (rsa->n == NULL || rsa->e == NULL) {
232 ret = ENOMEM;
233 hx509_set_error_string(context, 0, ret, "out of memory");
234 goto out;
237 tosize = RSA_size(rsa);
238 to = malloc(tosize);
239 if (to == NULL) {
240 ret = ENOMEM;
241 hx509_set_error_string(context, 0, ret, "out of memory");
242 goto out;
245 retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
246 to, rsa, RSA_PKCS1_PADDING);
247 if (retsize <= 0) {
248 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
249 hx509_set_error_string(context, 0, ret,
250 "RSA public decrypt failed: %d", retsize);
251 free(to);
252 goto out;
254 if (retsize > tosize)
255 _hx509_abort("internal rsa decryption failure: ret > tosize");
257 if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
259 ret = decode_DigestInfo(to, retsize, &di, &size);
260 free(to);
261 if (ret) {
262 goto out;
265 /* Check for extra data inside the sigature */
266 if (size != retsize) {
267 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
268 hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
269 goto out;
272 if (sig_alg->digest_oid &&
273 der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
274 (*sig_alg->digest_oid)()) != 0)
276 ret = HX509_CRYPTO_OID_MISMATCH;
277 hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
278 goto out;
281 /* verify that the parameters are NULL or the NULL-type */
282 if (di.digestAlgorithm.parameters != NULL &&
283 (di.digestAlgorithm.parameters->length != 2 ||
284 memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
286 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
287 hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
288 goto out;
291 ret = _hx509_verify_signature(context,
292 NULL,
293 &di.digestAlgorithm,
294 data,
295 &di.digest);
296 } else {
297 if (retsize != data->length ||
298 memcmp(to, data->data, retsize) != 0)
300 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
301 hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
302 goto out;
304 free(to);
307 out:
308 free_DigestInfo(&di);
309 RSA_free(rsa);
310 return ret;
313 static int
314 rsa_create_signature(hx509_context context,
315 const struct signature_alg *sig_alg,
316 const hx509_private_key signer,
317 const AlgorithmIdentifier *alg,
318 const heim_octet_string *data,
319 AlgorithmIdentifier *signatureAlgorithm,
320 heim_octet_string *sig)
322 const AlgorithmIdentifier *digest_alg;
323 heim_octet_string indata;
324 const heim_oid *sig_oid;
325 size_t size;
326 int ret;
328 if (alg)
329 sig_oid = &alg->algorithm;
330 else
331 sig_oid = signer->signature_alg;
333 if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha256WithRSAEncryption()) == 0) {
334 digest_alg = hx509_signature_sha256();
335 } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_sha1WithRSAEncryption()) == 0) {
336 digest_alg = hx509_signature_sha1();
337 } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {
338 digest_alg = hx509_signature_md5();
339 } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_md5WithRSAEncryption()) == 0) {
340 digest_alg = hx509_signature_md5();
341 } else if (der_heim_oid_cmp(sig_oid, oid_id_dsa_with_sha1()) == 0) {
342 digest_alg = hx509_signature_sha1();
343 } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {
344 digest_alg = hx509_signature_sha1();
345 } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {
346 digest_alg = NULL;
347 } else
348 return HX509_ALG_NOT_SUPP;
350 if (signatureAlgorithm) {
351 ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
352 if (ret) {
353 hx509_clear_error_string(context);
354 return ret;
358 if (digest_alg) {
359 DigestInfo di;
360 memset(&di, 0, sizeof(di));
362 ret = _hx509_create_signature(context,
363 NULL,
364 digest_alg,
365 data,
366 &di.digestAlgorithm,
367 &di.digest);
368 if (ret)
369 return ret;
370 ASN1_MALLOC_ENCODE(DigestInfo,
371 indata.data,
372 indata.length,
373 &di,
374 &size,
375 ret);
376 free_DigestInfo(&di);
377 if (ret) {
378 hx509_set_error_string(context, 0, ret, "out of memory");
379 return ret;
381 if (indata.length != size)
382 _hx509_abort("internal ASN.1 encoder error");
383 } else {
384 indata = *data;
387 sig->length = RSA_size(signer->private_key.rsa);
388 sig->data = malloc(sig->length);
389 if (sig->data == NULL) {
390 der_free_octet_string(&indata);
391 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
392 return ENOMEM;
395 ret = RSA_private_encrypt(indata.length, indata.data,
396 sig->data,
397 signer->private_key.rsa,
398 RSA_PKCS1_PADDING);
399 if (indata.data != data->data)
400 der_free_octet_string(&indata);
401 if (ret <= 0) {
402 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
403 hx509_set_error_string(context, 0, ret,
404 "RSA private decrypt failed: %d", ret);
405 return ret;
407 if (ret > sig->length)
408 _hx509_abort("RSA signature prelen longer the output len");
410 sig->length = ret;
412 return 0;
415 static int
416 rsa_private_key_import(hx509_context context,
417 const void *data,
418 size_t len,
419 hx509_private_key private_key)
421 const unsigned char *p = data;
423 private_key->private_key.rsa =
424 d2i_RSAPrivateKey(NULL, &p, len);
425 if (private_key->private_key.rsa == NULL) {
426 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
427 "Failed to parse RSA key");
428 return HX509_PARSING_KEY_FAILED;
430 private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
432 return 0;
435 static int
436 rsa_private_key2SPKI(hx509_context context,
437 hx509_private_key private_key,
438 SubjectPublicKeyInfo *spki)
440 int len, ret;
442 memset(spki, 0, sizeof(*spki));
444 len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
446 spki->subjectPublicKey.data = malloc(len);
447 if (spki->subjectPublicKey.data == NULL) {
448 hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
449 return ENOMEM;
451 spki->subjectPublicKey.length = len * 8;
453 ret = set_digest_alg(&spki->algorithm,oid_id_pkcs1_rsaEncryption(),
454 "\x05\x00", 2);
455 if (ret) {
456 hx509_set_error_string(context, 0, ret, "malloc - out of memory");
457 free(spki->subjectPublicKey.data);
458 spki->subjectPublicKey.data = NULL;
459 spki->subjectPublicKey.length = 0;
460 return ret;
464 unsigned char *pp = spki->subjectPublicKey.data;
465 i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
468 return 0;
471 static int
472 rsa_generate_private_key(hx509_context context,
473 struct hx509_generate_private_context *ctx,
474 hx509_private_key private_key)
476 BIGNUM *e;
477 int ret;
478 unsigned long bits;
480 static const int default_rsa_e = 65537;
481 static const int default_rsa_bits = 1024;
483 private_key->private_key.rsa = RSA_new();
484 if (private_key->private_key.rsa == NULL) {
485 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
486 "Failed to generate RSA key");
487 return HX509_PARSING_KEY_FAILED;
490 e = BN_new();
491 BN_set_word(e, default_rsa_e);
493 bits = default_rsa_bits;
495 if (ctx->num_bits)
496 bits = ctx->num_bits;
497 else if (ctx->isCA)
498 bits *= 2;
500 ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
501 BN_free(e);
502 if (ret != 1) {
503 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
504 "Failed to generate RSA key");
505 return HX509_PARSING_KEY_FAILED;
507 private_key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
509 return 0;
512 static int
513 rsa_private_key_export(hx509_context context,
514 const hx509_private_key key,
515 heim_octet_string *data)
517 int ret;
519 data->data = NULL;
520 data->length = 0;
522 ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
523 if (ret <= 0) {
524 ret = EINVAL;
525 hx509_set_error_string(context, 0, ret,
526 "Private key is not exportable");
527 return ret;
530 data->data = malloc(ret);
531 if (data->data == NULL) {
532 ret = ENOMEM;
533 hx509_set_error_string(context, 0, ret, "malloc out of memory");
534 return ret;
536 data->length = ret;
539 unsigned char *p = data->data;
540 i2d_RSAPrivateKey(key->private_key.rsa, &p);
543 return 0;
546 static BIGNUM *
547 rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
549 if (strcasecmp(type, "rsa-modulus") == 0) {
550 return BN_dup(key->private_key.rsa->n);
551 } else if (strcasecmp(type, "rsa-exponent") == 0) {
552 return BN_dup(key->private_key.rsa->e);
553 } else
554 return NULL;
559 static hx509_private_key_ops rsa_private_key_ops = {
560 "RSA PRIVATE KEY",
561 oid_id_pkcs1_rsaEncryption,
562 rsa_private_key2SPKI,
563 rsa_private_key_export,
564 rsa_private_key_import,
565 rsa_generate_private_key,
566 rsa_get_internal
574 static int
575 dsa_verify_signature(hx509_context context,
576 const struct signature_alg *sig_alg,
577 const Certificate *signer,
578 const AlgorithmIdentifier *alg,
579 const heim_octet_string *data,
580 const heim_octet_string *sig)
582 const SubjectPublicKeyInfo *spi;
583 DSAPublicKey pk;
584 DSAParams param;
585 size_t size;
586 DSA *dsa;
587 int ret;
589 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
591 dsa = DSA_new();
592 if (dsa == NULL) {
593 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
594 return ENOMEM;
597 ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
598 spi->subjectPublicKey.length / 8,
599 &pk, &size);
600 if (ret)
601 goto out;
603 dsa->pub_key = heim_int2BN(&pk);
605 free_DSAPublicKey(&pk);
607 if (dsa->pub_key == NULL) {
608 ret = ENOMEM;
609 hx509_set_error_string(context, 0, ret, "out of memory");
610 goto out;
613 if (spi->algorithm.parameters == NULL) {
614 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
615 hx509_set_error_string(context, 0, ret, "DSA parameters missing");
616 goto out;
619 ret = decode_DSAParams(spi->algorithm.parameters->data,
620 spi->algorithm.parameters->length,
621 &param,
622 &size);
623 if (ret) {
624 hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
625 goto out;
628 dsa->p = heim_int2BN(&param.p);
629 dsa->q = heim_int2BN(&param.q);
630 dsa->g = heim_int2BN(&param.g);
632 free_DSAParams(&param);
634 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
635 ret = ENOMEM;
636 hx509_set_error_string(context, 0, ret, "out of memory");
637 goto out;
640 ret = DSA_verify(-1, data->data, data->length,
641 (unsigned char*)sig->data, sig->length,
642 dsa);
643 if (ret == 1)
644 ret = 0;
645 else if (ret == 0 || ret == -1) {
646 ret = HX509_CRYPTO_BAD_SIGNATURE;
647 hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
648 } else {
649 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
650 hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
653 out:
654 DSA_free(dsa);
656 return ret;
659 #if 0
660 static int
661 dsa_parse_private_key(hx509_context context,
662 const void *data,
663 size_t len,
664 hx509_private_key private_key)
666 const unsigned char *p = data;
668 private_key->private_key.dsa =
669 d2i_DSAPrivateKey(NULL, &p, len);
670 if (private_key->private_key.dsa == NULL)
671 return EINVAL;
672 private_key->signature_alg = oid_id_dsa_with_sha1();
674 return 0;
675 /* else */
676 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
677 "No support to parse DSA keys");
678 return HX509_PARSING_KEY_FAILED;
680 #endif
683 static int
684 sha1_verify_signature(hx509_context context,
685 const struct signature_alg *sig_alg,
686 const Certificate *signer,
687 const AlgorithmIdentifier *alg,
688 const heim_octet_string *data,
689 const heim_octet_string *sig)
691 unsigned char digest[SHA_DIGEST_LENGTH];
692 SHA_CTX m;
694 if (sig->length != SHA_DIGEST_LENGTH) {
695 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
696 "SHA1 sigature have wrong length");
697 return HX509_CRYPTO_SIG_INVALID_FORMAT;
700 SHA1_Init(&m);
701 SHA1_Update(&m, data->data, data->length);
702 SHA1_Final (digest, &m);
704 if (memcmp(digest, sig->data, SHA_DIGEST_LENGTH) != 0) {
705 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
706 "Bad SHA1 sigature");
707 return HX509_CRYPTO_BAD_SIGNATURE;
710 return 0;
713 static int
714 sha256_create_signature(hx509_context context,
715 const struct signature_alg *sig_alg,
716 const hx509_private_key signer,
717 const AlgorithmIdentifier *alg,
718 const heim_octet_string *data,
719 AlgorithmIdentifier *signatureAlgorithm,
720 heim_octet_string *sig)
722 SHA256_CTX m;
724 memset(sig, 0, sizeof(*sig));
726 if (signatureAlgorithm) {
727 int ret;
728 ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(),
729 "\x05\x00", 2);
730 if (ret)
731 return ret;
735 sig->data = malloc(SHA256_DIGEST_LENGTH);
736 if (sig->data == NULL) {
737 sig->length = 0;
738 return ENOMEM;
740 sig->length = SHA256_DIGEST_LENGTH;
742 SHA256_Init(&m);
743 SHA256_Update(&m, data->data, data->length);
744 SHA256_Final (sig->data, &m);
746 return 0;
749 static int
750 sha256_verify_signature(hx509_context context,
751 const struct signature_alg *sig_alg,
752 const Certificate *signer,
753 const AlgorithmIdentifier *alg,
754 const heim_octet_string *data,
755 const heim_octet_string *sig)
757 unsigned char digest[SHA256_DIGEST_LENGTH];
758 SHA256_CTX m;
760 if (sig->length != SHA256_DIGEST_LENGTH) {
761 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
762 "SHA256 sigature have wrong length");
763 return HX509_CRYPTO_SIG_INVALID_FORMAT;
766 SHA256_Init(&m);
767 SHA256_Update(&m, data->data, data->length);
768 SHA256_Final (digest, &m);
770 if (memcmp(digest, sig->data, SHA256_DIGEST_LENGTH) != 0) {
771 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
772 "Bad SHA256 sigature");
773 return HX509_CRYPTO_BAD_SIGNATURE;
776 return 0;
779 static int
780 sha1_create_signature(hx509_context context,
781 const struct signature_alg *sig_alg,
782 const hx509_private_key signer,
783 const AlgorithmIdentifier *alg,
784 const heim_octet_string *data,
785 AlgorithmIdentifier *signatureAlgorithm,
786 heim_octet_string *sig)
788 SHA_CTX m;
790 memset(sig, 0, sizeof(*sig));
792 if (signatureAlgorithm) {
793 int ret;
794 ret = set_digest_alg(signatureAlgorithm, (*sig_alg->sig_oid)(),
795 "\x05\x00", 2);
796 if (ret)
797 return ret;
801 sig->data = malloc(SHA_DIGEST_LENGTH);
802 if (sig->data == NULL) {
803 sig->length = 0;
804 return ENOMEM;
806 sig->length = SHA_DIGEST_LENGTH;
808 SHA1_Init(&m);
809 SHA1_Update(&m, data->data, data->length);
810 SHA1_Final (sig->data, &m);
812 return 0;
815 static int
816 md5_verify_signature(hx509_context context,
817 const struct signature_alg *sig_alg,
818 const Certificate *signer,
819 const AlgorithmIdentifier *alg,
820 const heim_octet_string *data,
821 const heim_octet_string *sig)
823 unsigned char digest[MD5_DIGEST_LENGTH];
824 MD5_CTX m;
826 if (sig->length != MD5_DIGEST_LENGTH) {
827 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
828 "MD5 sigature have wrong length");
829 return HX509_CRYPTO_SIG_INVALID_FORMAT;
832 MD5_Init(&m);
833 MD5_Update(&m, data->data, data->length);
834 MD5_Final (digest, &m);
836 if (memcmp(digest, sig->data, MD5_DIGEST_LENGTH) != 0) {
837 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
838 "Bad MD5 sigature");
839 return HX509_CRYPTO_BAD_SIGNATURE;
842 return 0;
845 static int
846 md2_verify_signature(hx509_context context,
847 const struct signature_alg *sig_alg,
848 const Certificate *signer,
849 const AlgorithmIdentifier *alg,
850 const heim_octet_string *data,
851 const heim_octet_string *sig)
853 unsigned char digest[MD2_DIGEST_LENGTH];
854 MD2_CTX m;
856 if (sig->length != MD2_DIGEST_LENGTH) {
857 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
858 "MD2 sigature have wrong length");
859 return HX509_CRYPTO_SIG_INVALID_FORMAT;
862 MD2_Init(&m);
863 MD2_Update(&m, data->data, data->length);
864 MD2_Final (digest, &m);
866 if (memcmp(digest, sig->data, MD2_DIGEST_LENGTH) != 0) {
867 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
868 "Bad MD2 sigature");
869 return HX509_CRYPTO_BAD_SIGNATURE;
872 return 0;
875 static const struct signature_alg heim_rsa_pkcs1_x509 = {
876 "rsa-pkcs1-x509",
877 oid_id_heim_rsa_pkcs1_x509,
878 hx509_signature_rsa_pkcs1_x509,
879 oid_id_pkcs1_rsaEncryption,
880 NULL,
881 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
882 rsa_verify_signature,
883 rsa_create_signature
886 static const struct signature_alg pkcs1_rsa_sha1_alg = {
887 "rsa",
888 oid_id_pkcs1_rsaEncryption,
889 hx509_signature_rsa_with_sha1,
890 oid_id_pkcs1_rsaEncryption,
891 NULL,
892 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
893 rsa_verify_signature,
894 rsa_create_signature
897 static const struct signature_alg rsa_with_sha256_alg = {
898 "rsa-with-sha256",
899 oid_id_pkcs1_sha256WithRSAEncryption,
900 hx509_signature_rsa_with_sha256,
901 oid_id_pkcs1_rsaEncryption,
902 oid_id_sha256,
903 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
904 rsa_verify_signature,
905 rsa_create_signature
908 static const struct signature_alg rsa_with_sha1_alg = {
909 "rsa-with-sha1",
910 oid_id_pkcs1_sha1WithRSAEncryption,
911 hx509_signature_rsa_with_sha1,
912 oid_id_pkcs1_rsaEncryption,
913 oid_id_secsig_sha_1,
914 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
915 rsa_verify_signature,
916 rsa_create_signature
919 static const struct signature_alg rsa_with_md5_alg = {
920 "rsa-with-md5",
921 oid_id_pkcs1_md5WithRSAEncryption,
922 hx509_signature_rsa_with_md5,
923 oid_id_pkcs1_rsaEncryption,
924 oid_id_rsa_digest_md5,
925 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
926 rsa_verify_signature,
927 rsa_create_signature
930 static const struct signature_alg rsa_with_md2_alg = {
931 "rsa-with-md2",
932 oid_id_pkcs1_md2WithRSAEncryption,
933 hx509_signature_rsa_with_md2,
934 oid_id_pkcs1_rsaEncryption,
935 oid_id_rsa_digest_md2,
936 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
937 rsa_verify_signature,
938 rsa_create_signature
941 static const struct signature_alg dsa_sha1_alg = {
942 "dsa-with-sha1",
943 oid_id_dsa_with_sha1,
944 NULL,
945 oid_id_dsa,
946 oid_id_secsig_sha_1,
947 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
948 dsa_verify_signature,
949 /* create_signature */ NULL,
952 static const struct signature_alg sha256_alg = {
953 "sha-256",
954 oid_id_sha256,
955 hx509_signature_sha256,
956 NULL,
957 NULL,
958 SIG_DIGEST,
959 sha256_verify_signature,
960 sha256_create_signature
963 static const struct signature_alg sha1_alg = {
964 "sha1",
965 oid_id_secsig_sha_1,
966 hx509_signature_sha1,
967 NULL,
968 NULL,
969 SIG_DIGEST,
970 sha1_verify_signature,
971 sha1_create_signature
974 static const struct signature_alg md5_alg = {
975 "rsa-md5",
976 oid_id_rsa_digest_md5,
977 hx509_signature_md5,
978 NULL,
979 NULL,
980 SIG_DIGEST,
981 md5_verify_signature
984 static const struct signature_alg md2_alg = {
985 "rsa-md2",
986 oid_id_rsa_digest_md2,
987 hx509_signature_md2,
988 NULL,
989 NULL,
990 SIG_DIGEST,
991 md2_verify_signature
995 * Order matter in this structure, "best" first for each "key
996 * compatible" type (type is RSA, DSA, none, etc)
999 static const struct signature_alg *sig_algs[] = {
1000 &rsa_with_sha256_alg,
1001 &rsa_with_sha1_alg,
1002 &pkcs1_rsa_sha1_alg,
1003 &rsa_with_md5_alg,
1004 &rsa_with_md2_alg,
1005 &heim_rsa_pkcs1_x509,
1006 &dsa_sha1_alg,
1007 &sha256_alg,
1008 &sha1_alg,
1009 &md5_alg,
1010 &md2_alg,
1011 NULL
1014 static const struct signature_alg *
1015 find_sig_alg(const heim_oid *oid)
1017 int i;
1018 for (i = 0; sig_algs[i]; i++)
1019 if (der_heim_oid_cmp((*sig_algs[i]->sig_oid)(), oid) == 0)
1020 return sig_algs[i];
1021 return NULL;
1028 static struct hx509_private_key_ops *private_algs[] = {
1029 &rsa_private_key_ops,
1030 NULL
1033 static hx509_private_key_ops *
1034 find_private_alg(const heim_oid *oid)
1036 int i;
1037 for (i = 0; private_algs[i]; i++) {
1038 if (private_algs[i]->key_oid == NULL)
1039 continue;
1040 if (der_heim_oid_cmp((*private_algs[i]->key_oid)(), oid) == 0)
1041 return private_algs[i];
1043 return NULL;
1048 _hx509_verify_signature(hx509_context context,
1049 const Certificate *signer,
1050 const AlgorithmIdentifier *alg,
1051 const heim_octet_string *data,
1052 const heim_octet_string *sig)
1054 const struct signature_alg *md;
1056 md = find_sig_alg(&alg->algorithm);
1057 if (md == NULL) {
1058 hx509_clear_error_string(context);
1059 return HX509_SIG_ALG_NO_SUPPORTED;
1061 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1062 hx509_clear_error_string(context);
1063 return HX509_CRYPTO_SIG_NO_CONF;
1065 if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1066 hx509_clear_error_string(context);
1067 return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1069 if (md->key_oid && signer) {
1070 const SubjectPublicKeyInfo *spi;
1071 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1073 if (der_heim_oid_cmp(&spi->algorithm.algorithm, (*md->key_oid)()) != 0) {
1074 hx509_clear_error_string(context);
1075 return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
1078 return (*md->verify_signature)(context, md, signer, alg, data, sig);
1082 _hx509_verify_signature_bitstring(hx509_context context,
1083 const Certificate *signer,
1084 const AlgorithmIdentifier *alg,
1085 const heim_octet_string *data,
1086 const heim_bit_string *sig)
1088 heim_octet_string os;
1090 if (sig->length & 7) {
1091 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
1092 "signature not multiple of 8 bits");
1093 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1096 os.data = sig->data;
1097 os.length = sig->length / 8;
1099 return _hx509_verify_signature(context, signer, alg, data, &os);
1103 _hx509_create_signature(hx509_context context,
1104 const hx509_private_key signer,
1105 const AlgorithmIdentifier *alg,
1106 const heim_octet_string *data,
1107 AlgorithmIdentifier *signatureAlgorithm,
1108 heim_octet_string *sig)
1110 const struct signature_alg *md;
1112 if (signer && signer->ops && signer->ops->handle_alg &&
1113 (*signer->ops->handle_alg)(signer, alg, COT_SIGN))
1115 return (*signer->ops->sign)(context, signer, alg, data,
1116 signatureAlgorithm, sig);
1119 md = find_sig_alg(&alg->algorithm);
1120 if (md == NULL) {
1121 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1122 "algorithm no supported");
1123 return HX509_SIG_ALG_NO_SUPPORTED;
1126 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1127 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1128 "algorithm provides no conf");
1129 return HX509_CRYPTO_SIG_NO_CONF;
1132 return (*md->create_signature)(context, md, signer, alg, data,
1133 signatureAlgorithm, sig);
1137 _hx509_create_signature_bitstring(hx509_context context,
1138 const hx509_private_key signer,
1139 const AlgorithmIdentifier *alg,
1140 const heim_octet_string *data,
1141 AlgorithmIdentifier *signatureAlgorithm,
1142 heim_bit_string *sig)
1144 heim_octet_string os;
1145 int ret;
1147 ret = _hx509_create_signature(context, signer, alg,
1148 data, signatureAlgorithm, &os);
1149 if (ret)
1150 return ret;
1151 sig->data = os.data;
1152 sig->length = os.length * 8;
1153 return 0;
1157 _hx509_public_encrypt(hx509_context context,
1158 const heim_octet_string *cleartext,
1159 const Certificate *cert,
1160 heim_oid *encryption_oid,
1161 heim_octet_string *ciphertext)
1163 const SubjectPublicKeyInfo *spi;
1164 unsigned char *to;
1165 int tosize;
1166 int ret;
1167 RSA *rsa;
1168 RSAPublicKey pk;
1169 size_t size;
1171 ciphertext->data = NULL;
1172 ciphertext->length = 0;
1174 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1176 rsa = RSA_new();
1177 if (rsa == NULL) {
1178 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1179 return ENOMEM;
1182 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
1183 spi->subjectPublicKey.length / 8,
1184 &pk, &size);
1185 if (ret) {
1186 RSA_free(rsa);
1187 hx509_set_error_string(context, 0, ret, "RSAPublicKey decode failure");
1188 return ret;
1190 rsa->n = heim_int2BN(&pk.modulus);
1191 rsa->e = heim_int2BN(&pk.publicExponent);
1193 free_RSAPublicKey(&pk);
1195 if (rsa->n == NULL || rsa->e == NULL) {
1196 RSA_free(rsa);
1197 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1198 return ENOMEM;
1201 tosize = RSA_size(rsa);
1202 to = malloc(tosize);
1203 if (to == NULL) {
1204 RSA_free(rsa);
1205 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1206 return ENOMEM;
1209 ret = RSA_public_encrypt(cleartext->length,
1210 (unsigned char *)cleartext->data,
1211 to, rsa, RSA_PKCS1_PADDING);
1212 RSA_free(rsa);
1213 if (ret <= 0) {
1214 free(to);
1215 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
1216 "RSA public encrypt failed with %d", ret);
1217 return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
1219 if (ret > tosize)
1220 _hx509_abort("internal rsa decryption failure: ret > tosize");
1222 ciphertext->length = ret;
1223 ciphertext->data = to;
1225 ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(), encryption_oid);
1226 if (ret) {
1227 der_free_octet_string(ciphertext);
1228 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1229 return ENOMEM;
1232 return 0;
1236 _hx509_private_key_private_decrypt(hx509_context context,
1237 const heim_octet_string *ciphertext,
1238 const heim_oid *encryption_oid,
1239 hx509_private_key p,
1240 heim_octet_string *cleartext)
1242 int ret;
1244 cleartext->data = NULL;
1245 cleartext->length = 0;
1247 if (p->private_key.rsa == NULL) {
1248 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1249 "Private RSA key missing");
1250 return HX509_PRIVATE_KEY_MISSING;
1253 cleartext->length = RSA_size(p->private_key.rsa);
1254 cleartext->data = malloc(cleartext->length);
1255 if (cleartext->data == NULL) {
1256 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1257 return ENOMEM;
1259 ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
1260 cleartext->data,
1261 p->private_key.rsa,
1262 RSA_PKCS1_PADDING);
1263 if (ret <= 0) {
1264 der_free_octet_string(cleartext);
1265 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
1266 "Failed to decrypt using private key: %d", ret);
1267 return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
1269 if (cleartext->length < ret)
1270 _hx509_abort("internal rsa decryption failure: ret > tosize");
1272 cleartext->length = ret;
1274 return 0;
1279 _hx509_parse_private_key(hx509_context context,
1280 const heim_oid *key_oid,
1281 const void *data,
1282 size_t len,
1283 hx509_private_key *private_key)
1285 struct hx509_private_key_ops *ops;
1286 int ret;
1288 *private_key = NULL;
1290 ops = find_private_alg(key_oid);
1291 if (ops == NULL) {
1292 hx509_clear_error_string(context);
1293 return HX509_SIG_ALG_NO_SUPPORTED;
1296 ret = _hx509_private_key_init(private_key, ops, NULL);
1297 if (ret) {
1298 hx509_set_error_string(context, 0, ret, "out of memory");
1299 return ret;
1302 ret = (*ops->import)(context, data, len, *private_key);
1303 if (ret)
1304 _hx509_private_key_free(private_key);
1306 return ret;
1314 _hx509_private_key2SPKI(hx509_context context,
1315 hx509_private_key private_key,
1316 SubjectPublicKeyInfo *spki)
1318 const struct hx509_private_key_ops *ops = private_key->ops;
1319 if (ops == NULL || ops->get_spki == NULL) {
1320 hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1321 "Private key have no key2SPKI function");
1322 return HX509_UNIMPLEMENTED_OPERATION;
1324 return (*ops->get_spki)(context, private_key, spki);
1328 _hx509_generate_private_key_init(hx509_context context,
1329 const heim_oid *oid,
1330 struct hx509_generate_private_context **ctx)
1332 *ctx = NULL;
1334 if (der_heim_oid_cmp(oid, oid_id_pkcs1_rsaEncryption()) != 0) {
1335 hx509_set_error_string(context, 0, EINVAL,
1336 "private key not an RSA key");
1337 return EINVAL;
1340 *ctx = calloc(1, sizeof(**ctx));
1341 if (*ctx == NULL) {
1342 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1343 return ENOMEM;
1345 (*ctx)->key_oid = oid;
1347 return 0;
1351 _hx509_generate_private_key_is_ca(hx509_context context,
1352 struct hx509_generate_private_context *ctx)
1354 ctx->isCA = 1;
1355 return 0;
1359 _hx509_generate_private_key_bits(hx509_context context,
1360 struct hx509_generate_private_context *ctx,
1361 unsigned long bits)
1363 ctx->num_bits = bits;
1364 return 0;
1368 void
1369 _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1371 free(*ctx);
1372 *ctx = NULL;
1376 _hx509_generate_private_key(hx509_context context,
1377 struct hx509_generate_private_context *ctx,
1378 hx509_private_key *private_key)
1380 struct hx509_private_key_ops *ops;
1381 int ret;
1383 *private_key = NULL;
1385 ops = find_private_alg(ctx->key_oid);
1386 if (ops == NULL) {
1387 hx509_clear_error_string(context);
1388 return HX509_SIG_ALG_NO_SUPPORTED;
1391 ret = _hx509_private_key_init(private_key, ops, NULL);
1392 if (ret) {
1393 hx509_set_error_string(context, 0, ret, "out of memory");
1394 return ret;
1397 ret = (*ops->generate_private_key)(context, ctx, *private_key);
1398 if (ret)
1399 _hx509_private_key_free(private_key);
1401 return ret;
1409 static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
1411 static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
1412 const AlgorithmIdentifier _hx509_signature_sha512_data = {
1413 { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
1416 static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
1417 const AlgorithmIdentifier _hx509_signature_sha384_data = {
1418 { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
1421 static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
1422 const AlgorithmIdentifier _hx509_signature_sha256_data = {
1423 { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
1426 static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
1427 const AlgorithmIdentifier _hx509_signature_sha1_data = {
1428 { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
1431 static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
1432 const AlgorithmIdentifier _hx509_signature_md5_data = {
1433 { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
1436 static const unsigned md2_oid_tree[] = { 1, 2, 840, 113549, 2, 2 };
1437 const AlgorithmIdentifier _hx509_signature_md2_data = {
1438 { 6, rk_UNCONST(md2_oid_tree) }, rk_UNCONST(&null_entry_oid)
1441 static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
1442 const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
1443 { 7, rk_UNCONST(rsa_with_sha512_oid) }, NULL
1446 static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
1447 const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
1448 { 7, rk_UNCONST(rsa_with_sha384_oid) }, NULL
1451 static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
1452 const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
1453 { 7, rk_UNCONST(rsa_with_sha256_oid) }, NULL
1456 static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
1457 const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
1458 { 7, rk_UNCONST(rsa_with_sha1_oid) }, NULL
1461 static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
1462 const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
1463 { 7, rk_UNCONST(rsa_with_md5_oid) }, NULL
1466 static const unsigned rsa_with_md2_oid[] ={ 1, 2, 840, 113549, 1, 1, 2 };
1467 const AlgorithmIdentifier _hx509_signature_rsa_with_md2_data = {
1468 { 7, rk_UNCONST(rsa_with_md2_oid) }, NULL
1471 static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
1472 const AlgorithmIdentifier _hx509_signature_rsa_data = {
1473 { 7, rk_UNCONST(rsa_oid) }, NULL
1476 static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
1477 const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
1478 { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
1481 static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
1482 const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
1483 { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
1486 static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
1487 const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
1488 { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
1491 static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
1492 const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
1493 { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
1496 const AlgorithmIdentifier *
1497 hx509_signature_sha512(void)
1498 { return &_hx509_signature_sha512_data; }
1500 const AlgorithmIdentifier *
1501 hx509_signature_sha384(void)
1502 { return &_hx509_signature_sha384_data; }
1504 const AlgorithmIdentifier *
1505 hx509_signature_sha256(void)
1506 { return &_hx509_signature_sha256_data; }
1508 const AlgorithmIdentifier *
1509 hx509_signature_sha1(void)
1510 { return &_hx509_signature_sha1_data; }
1512 const AlgorithmIdentifier *
1513 hx509_signature_md5(void)
1514 { return &_hx509_signature_md5_data; }
1516 const AlgorithmIdentifier *
1517 hx509_signature_md2(void)
1518 { return &_hx509_signature_md2_data; }
1520 const AlgorithmIdentifier *
1521 hx509_signature_rsa_with_sha512(void)
1522 { return &_hx509_signature_rsa_with_sha512_data; }
1524 const AlgorithmIdentifier *
1525 hx509_signature_rsa_with_sha384(void)
1526 { return &_hx509_signature_rsa_with_sha384_data; }
1528 const AlgorithmIdentifier *
1529 hx509_signature_rsa_with_sha256(void)
1530 { return &_hx509_signature_rsa_with_sha256_data; }
1532 const AlgorithmIdentifier *
1533 hx509_signature_rsa_with_sha1(void)
1534 { return &_hx509_signature_rsa_with_sha1_data; }
1536 const AlgorithmIdentifier *
1537 hx509_signature_rsa_with_md5(void)
1538 { return &_hx509_signature_rsa_with_md5_data; }
1540 const AlgorithmIdentifier *
1541 hx509_signature_rsa_with_md2(void)
1542 { return &_hx509_signature_rsa_with_md2_data; }
1544 const AlgorithmIdentifier *
1545 hx509_signature_rsa(void)
1546 { return &_hx509_signature_rsa_data; }
1548 const AlgorithmIdentifier *
1549 hx509_signature_rsa_pkcs1_x509(void)
1550 { return &_hx509_signature_rsa_pkcs1_x509_data; }
1552 const AlgorithmIdentifier *
1553 hx509_crypto_des_rsdi_ede3_cbc(void)
1554 { return &_hx509_des_rsdi_ede3_cbc_oid; }
1556 const AlgorithmIdentifier *
1557 hx509_crypto_aes128_cbc(void)
1558 { return &_hx509_crypto_aes128_cbc_data; }
1560 const AlgorithmIdentifier *
1561 hx509_crypto_aes256_cbc(void)
1562 { return &_hx509_crypto_aes256_cbc_data; }
1568 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
1569 &_hx509_signature_rsa_with_sha1_data;
1570 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
1571 &_hx509_signature_sha1_data;
1572 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
1573 &_hx509_crypto_aes128_cbc_data;
1580 _hx509_private_key_init(hx509_private_key *key,
1581 hx509_private_key_ops *ops,
1582 void *keydata)
1584 *key = calloc(1, sizeof(**key));
1585 if (*key == NULL)
1586 return ENOMEM;
1587 (*key)->ref = 1;
1588 (*key)->ops = ops;
1589 (*key)->private_key.keydata = keydata;
1590 return 0;
1593 hx509_private_key
1594 _hx509_private_key_ref(hx509_private_key key)
1596 if (key->ref <= 0)
1597 _hx509_abort("refcount <= 0");
1598 key->ref++;
1599 if (key->ref == 0)
1600 _hx509_abort("refcount == 0");
1601 return key;
1604 const char *
1605 _hx509_private_pem_name(hx509_private_key key)
1607 return key->ops->pemtype;
1611 _hx509_private_key_free(hx509_private_key *key)
1613 if (key == NULL || *key == NULL)
1614 return 0;
1616 if ((*key)->ref <= 0)
1617 _hx509_abort("refcount <= 0");
1618 if (--(*key)->ref > 0)
1619 return 0;
1621 if ((*key)->private_key.rsa)
1622 RSA_free((*key)->private_key.rsa);
1623 (*key)->private_key.rsa = NULL;
1624 free(*key);
1625 *key = NULL;
1626 return 0;
1629 void
1630 _hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
1632 if (key->private_key.rsa)
1633 RSA_free(key->private_key.rsa);
1634 key->private_key.rsa = ptr;
1635 key->signature_alg = oid_id_pkcs1_sha1WithRSAEncryption();
1636 key->md = &pkcs1_rsa_sha1_alg;
1639 int
1640 _hx509_private_key_oid(hx509_context context,
1641 const hx509_private_key key,
1642 heim_oid *data)
1644 int ret;
1645 ret = der_copy_oid((*key->ops->key_oid)(), data);
1646 if (ret)
1647 hx509_set_error_string(context, 0, ret, "malloc out of memory");
1648 return ret;
1652 _hx509_private_key_exportable(hx509_private_key key)
1654 if (key->ops->export == NULL)
1655 return 0;
1656 return 1;
1659 BIGNUM *
1660 _hx509_private_key_get_internal(hx509_context context,
1661 hx509_private_key key,
1662 const char *type)
1664 if (key->ops->get_internal == NULL)
1665 return NULL;
1666 return (*key->ops->get_internal)(context, key, type);
1669 int
1670 _hx509_private_key_export(hx509_context context,
1671 const hx509_private_key key,
1672 heim_octet_string *data)
1674 if (key->ops->export == NULL) {
1675 hx509_clear_error_string(context);
1676 return HX509_UNIMPLEMENTED_OPERATION;
1678 return (*key->ops->export)(context, key, data);
1685 struct hx509cipher {
1686 const char *name;
1687 const heim_oid *(*oid_func)(void);
1688 const AlgorithmIdentifier *(*ai_func)(void);
1689 const EVP_CIPHER *(*evp_func)(void);
1690 int (*get_params)(hx509_context, const hx509_crypto,
1691 const heim_octet_string *, heim_octet_string *);
1692 int (*set_params)(hx509_context, const heim_octet_string *,
1693 hx509_crypto, heim_octet_string *);
1696 struct hx509_crypto_data {
1697 char *name;
1698 const struct hx509cipher *cipher;
1699 const EVP_CIPHER *c;
1700 heim_octet_string key;
1701 heim_oid oid;
1702 void *param;
1709 static const heim_oid *
1710 oid_private_rc2_40(void)
1712 static unsigned oid_data[] = { 127, 1 };
1713 static const heim_oid oid = { 2, oid_data };
1715 return &oid;
1723 static int
1724 CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
1725 const heim_octet_string *ivec, heim_octet_string *param)
1727 size_t size;
1728 int ret;
1730 assert(crypto->param == NULL);
1731 if (ivec == NULL)
1732 return 0;
1734 ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
1735 ivec, &size, ret);
1736 if (ret == 0 && size != param->length)
1737 _hx509_abort("Internal asn1 encoder failure");
1738 if (ret)
1739 hx509_clear_error_string(context);
1740 return ret;
1743 static int
1744 CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
1745 hx509_crypto crypto, heim_octet_string *ivec)
1747 int ret;
1748 if (ivec == NULL)
1749 return 0;
1751 ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
1752 if (ret)
1753 hx509_clear_error_string(context);
1755 return ret;
1758 struct _RC2_params {
1759 int maximum_effective_key;
1762 static int
1763 CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
1764 const heim_octet_string *ivec, heim_octet_string *param)
1766 CMSRC2CBCParameter rc2params;
1767 const struct _RC2_params *p = crypto->param;
1768 int maximum_effective_key = 128;
1769 size_t size;
1770 int ret;
1772 memset(&rc2params, 0, sizeof(rc2params));
1774 if (p)
1775 maximum_effective_key = p->maximum_effective_key;
1777 switch(maximum_effective_key) {
1778 case 40:
1779 rc2params.rc2ParameterVersion = 160;
1780 break;
1781 case 64:
1782 rc2params.rc2ParameterVersion = 120;
1783 break;
1784 case 128:
1785 rc2params.rc2ParameterVersion = 58;
1786 break;
1788 rc2params.iv = *ivec;
1790 ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
1791 &rc2params, &size, ret);
1792 if (ret == 0 && size != param->length)
1793 _hx509_abort("Internal asn1 encoder failure");
1795 return ret;
1798 static int
1799 CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
1800 hx509_crypto crypto, heim_octet_string *ivec)
1802 CMSRC2CBCParameter rc2param;
1803 struct _RC2_params *p;
1804 size_t size;
1805 int ret;
1807 ret = decode_CMSRC2CBCParameter(param->data, param->length,
1808 &rc2param, &size);
1809 if (ret) {
1810 hx509_clear_error_string(context);
1811 return ret;
1814 p = calloc(1, sizeof(*p));
1815 if (p == NULL) {
1816 free_CMSRC2CBCParameter(&rc2param);
1817 hx509_clear_error_string(context);
1818 return ENOMEM;
1820 switch(rc2param.rc2ParameterVersion) {
1821 case 160:
1822 crypto->c = EVP_rc2_40_cbc();
1823 p->maximum_effective_key = 40;
1824 break;
1825 case 120:
1826 crypto->c = EVP_rc2_64_cbc();
1827 p->maximum_effective_key = 64;
1828 break;
1829 case 58:
1830 crypto->c = EVP_rc2_cbc();
1831 p->maximum_effective_key = 128;
1832 break;
1833 default:
1834 free(p);
1835 free_CMSRC2CBCParameter(&rc2param);
1836 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1838 if (ivec)
1839 ret = der_copy_octet_string(&rc2param.iv, ivec);
1840 free_CMSRC2CBCParameter(&rc2param);
1841 if (ret) {
1842 free(p);
1843 hx509_clear_error_string(context);
1844 } else
1845 crypto->param = p;
1847 return ret;
1854 static const struct hx509cipher ciphers[] = {
1856 "rc2-cbc",
1857 oid_id_pkcs3_rc2_cbc,
1858 NULL,
1859 EVP_rc2_cbc,
1860 CMSRC2CBCParam_get,
1861 CMSRC2CBCParam_set
1864 "rc2-cbc",
1865 oid_id_rsadsi_rc2_cbc,
1866 NULL,
1867 EVP_rc2_cbc,
1868 CMSRC2CBCParam_get,
1869 CMSRC2CBCParam_set
1872 "rc2-40-cbc",
1873 oid_private_rc2_40,
1874 NULL,
1875 EVP_rc2_40_cbc,
1876 CMSRC2CBCParam_get,
1877 CMSRC2CBCParam_set
1880 "des-ede3-cbc",
1881 oid_id_pkcs3_des_ede3_cbc,
1882 NULL,
1883 EVP_des_ede3_cbc,
1884 CMSCBCParam_get,
1885 CMSCBCParam_set
1888 "des-ede3-cbc",
1889 oid_id_rsadsi_des_ede3_cbc,
1890 hx509_crypto_des_rsdi_ede3_cbc,
1891 EVP_des_ede3_cbc,
1892 CMSCBCParam_get,
1893 CMSCBCParam_set
1896 "aes-128-cbc",
1897 oid_id_aes_128_cbc,
1898 hx509_crypto_aes128_cbc,
1899 EVP_aes_128_cbc,
1900 CMSCBCParam_get,
1901 CMSCBCParam_set
1904 "aes-192-cbc",
1905 oid_id_aes_192_cbc,
1906 NULL,
1907 EVP_aes_192_cbc,
1908 CMSCBCParam_get,
1909 CMSCBCParam_set
1912 "aes-256-cbc",
1913 oid_id_aes_256_cbc,
1914 hx509_crypto_aes256_cbc,
1915 EVP_aes_256_cbc,
1916 CMSCBCParam_get,
1917 CMSCBCParam_set
1921 static const struct hx509cipher *
1922 find_cipher_by_oid(const heim_oid *oid)
1924 int i;
1926 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1927 if (der_heim_oid_cmp(oid, (*ciphers[i].oid_func)()) == 0)
1928 return &ciphers[i];
1930 return NULL;
1933 static const struct hx509cipher *
1934 find_cipher_by_name(const char *name)
1936 int i;
1938 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1939 if (strcasecmp(name, ciphers[i].name) == 0)
1940 return &ciphers[i];
1942 return NULL;
1946 const heim_oid *
1947 hx509_crypto_enctype_by_name(const char *name)
1949 const struct hx509cipher *cipher;
1951 cipher = find_cipher_by_name(name);
1952 if (cipher == NULL)
1953 return NULL;
1954 return (*cipher->oid_func)();
1958 hx509_crypto_init(hx509_context context,
1959 const char *provider,
1960 const heim_oid *enctype,
1961 hx509_crypto *crypto)
1963 const struct hx509cipher *cipher;
1965 *crypto = NULL;
1967 cipher = find_cipher_by_oid(enctype);
1968 if (cipher == NULL) {
1969 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
1970 "Algorithm not supported");
1971 return HX509_ALG_NOT_SUPP;
1974 *crypto = calloc(1, sizeof(**crypto));
1975 if (*crypto == NULL) {
1976 hx509_clear_error_string(context);
1977 return ENOMEM;
1980 (*crypto)->cipher = cipher;
1981 (*crypto)->c = (*cipher->evp_func)();
1983 if (der_copy_oid(enctype, &(*crypto)->oid)) {
1984 hx509_crypto_destroy(*crypto);
1985 *crypto = NULL;
1986 hx509_clear_error_string(context);
1987 return ENOMEM;
1990 return 0;
1993 const char *
1994 hx509_crypto_provider(hx509_crypto crypto)
1996 return "unknown";
1999 void
2000 hx509_crypto_destroy(hx509_crypto crypto)
2002 if (crypto->name)
2003 free(crypto->name);
2004 if (crypto->key.data)
2005 free(crypto->key.data);
2006 if (crypto->param)
2007 free(crypto->param);
2008 der_free_oid(&crypto->oid);
2009 memset(crypto, 0, sizeof(*crypto));
2010 free(crypto);
2014 hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2016 return 0;
2020 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2022 if (EVP_CIPHER_key_length(crypto->c) > length)
2023 return HX509_CRYPTO_INTERNAL_ERROR;
2025 if (crypto->key.data) {
2026 free(crypto->key.data);
2027 crypto->key.data = NULL;
2028 crypto->key.length = 0;
2030 crypto->key.data = malloc(length);
2031 if (crypto->key.data == NULL)
2032 return ENOMEM;
2033 memcpy(crypto->key.data, data, length);
2034 crypto->key.length = length;
2036 return 0;
2040 hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2042 if (crypto->key.data) {
2043 free(crypto->key.data);
2044 crypto->key.length = 0;
2047 crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2048 crypto->key.data = malloc(crypto->key.length);
2049 if (crypto->key.data == NULL) {
2050 crypto->key.length = 0;
2051 return ENOMEM;
2053 if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2054 free(crypto->key.data);
2055 crypto->key.data = NULL;
2056 crypto->key.length = 0;
2057 return HX509_CRYPTO_INTERNAL_ERROR;
2059 if (key)
2060 return der_copy_octet_string(&crypto->key, key);
2061 else
2062 return 0;
2066 hx509_crypto_set_params(hx509_context context,
2067 hx509_crypto crypto,
2068 const heim_octet_string *param,
2069 heim_octet_string *ivec)
2071 return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2075 hx509_crypto_get_params(hx509_context context,
2076 hx509_crypto crypto,
2077 const heim_octet_string *ivec,
2078 heim_octet_string *param)
2080 return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2084 hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2086 ivec->length = EVP_CIPHER_iv_length(crypto->c);
2087 ivec->data = malloc(ivec->length);
2088 if (ivec->data == NULL) {
2089 ivec->length = 0;
2090 return ENOMEM;
2093 if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2094 free(ivec->data);
2095 ivec->data = NULL;
2096 ivec->length = 0;
2097 return HX509_CRYPTO_INTERNAL_ERROR;
2099 return 0;
2103 hx509_crypto_encrypt(hx509_crypto crypto,
2104 const void *data,
2105 const size_t length,
2106 const heim_octet_string *ivec,
2107 heim_octet_string **ciphertext)
2109 EVP_CIPHER_CTX evp;
2110 size_t padsize;
2111 int ret;
2113 *ciphertext = NULL;
2115 assert(EVP_CIPHER_iv_length(crypto->c) == ivec->length);
2117 EVP_CIPHER_CTX_init(&evp);
2119 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2120 crypto->key.data, ivec->data, 1);
2121 if (ret != 1) {
2122 EVP_CIPHER_CTX_cleanup(&evp);
2123 ret = HX509_CRYPTO_INTERNAL_ERROR;
2124 goto out;
2127 *ciphertext = calloc(1, sizeof(**ciphertext));
2128 if (*ciphertext == NULL) {
2129 ret = ENOMEM;
2130 goto out;
2133 if (EVP_CIPHER_block_size(crypto->c) == 1) {
2134 padsize = 0;
2135 } else {
2136 int bsize = EVP_CIPHER_block_size(crypto->c);
2137 padsize = bsize - (length % bsize);
2139 (*ciphertext)->length = length + padsize;
2140 (*ciphertext)->data = malloc(length + padsize);
2141 if ((*ciphertext)->data == NULL) {
2142 ret = ENOMEM;
2143 goto out;
2146 memcpy((*ciphertext)->data, data, length);
2147 if (padsize) {
2148 int i;
2149 unsigned char *p = (*ciphertext)->data;
2150 p += length;
2151 for (i = 0; i < padsize; i++)
2152 *p++ = padsize;
2155 ret = EVP_Cipher(&evp, (*ciphertext)->data,
2156 (*ciphertext)->data,
2157 length + padsize);
2158 if (ret != 1) {
2159 ret = HX509_CRYPTO_INTERNAL_ERROR;
2160 goto out;
2162 ret = 0;
2164 out:
2165 if (ret) {
2166 if (*ciphertext) {
2167 if ((*ciphertext)->data) {
2168 free((*ciphertext)->data);
2170 free(*ciphertext);
2171 *ciphertext = NULL;
2174 EVP_CIPHER_CTX_cleanup(&evp);
2176 return ret;
2180 hx509_crypto_decrypt(hx509_crypto crypto,
2181 const void *data,
2182 const size_t length,
2183 heim_octet_string *ivec,
2184 heim_octet_string *clear)
2186 EVP_CIPHER_CTX evp;
2187 void *idata = NULL;
2188 int ret;
2190 clear->data = NULL;
2191 clear->length = 0;
2193 if (ivec && EVP_CIPHER_iv_length(crypto->c) < ivec->length)
2194 return HX509_CRYPTO_INTERNAL_ERROR;
2196 if (crypto->key.data == NULL)
2197 return HX509_CRYPTO_INTERNAL_ERROR;
2199 if (ivec)
2200 idata = ivec->data;
2202 EVP_CIPHER_CTX_init(&evp);
2204 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2205 crypto->key.data, idata, 0);
2206 if (ret != 1) {
2207 EVP_CIPHER_CTX_cleanup(&evp);
2208 return HX509_CRYPTO_INTERNAL_ERROR;
2211 clear->length = length;
2212 clear->data = malloc(length);
2213 if (clear->data == NULL) {
2214 EVP_CIPHER_CTX_cleanup(&evp);
2215 clear->length = 0;
2216 return ENOMEM;
2219 if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2220 return HX509_CRYPTO_INTERNAL_ERROR;
2222 EVP_CIPHER_CTX_cleanup(&evp);
2224 if (EVP_CIPHER_block_size(crypto->c) > 1) {
2225 int padsize;
2226 unsigned char *p;
2227 int j, bsize = EVP_CIPHER_block_size(crypto->c);
2229 if (clear->length < bsize) {
2230 ret = HX509_CMS_PADDING_ERROR;
2231 goto out;
2234 p = clear->data;
2235 p += clear->length - 1;
2236 padsize = *p;
2237 if (padsize > bsize) {
2238 ret = HX509_CMS_PADDING_ERROR;
2239 goto out;
2241 clear->length -= padsize;
2242 for (j = 0; j < padsize; j++) {
2243 if (*p-- != padsize) {
2244 ret = HX509_CMS_PADDING_ERROR;
2245 goto out;
2250 return 0;
2252 out:
2253 if (clear->data)
2254 free(clear->data);
2255 clear->data = NULL;
2256 clear->length = 0;
2257 return ret;
2260 typedef int (*PBE_string2key_func)(hx509_context,
2261 const char *,
2262 const heim_octet_string *,
2263 hx509_crypto *, heim_octet_string *,
2264 heim_octet_string *,
2265 const heim_oid *, const EVP_MD *);
2267 static int
2268 PBE_string2key(hx509_context context,
2269 const char *password,
2270 const heim_octet_string *parameters,
2271 hx509_crypto *crypto,
2272 heim_octet_string *key, heim_octet_string *iv,
2273 const heim_oid *enc_oid,
2274 const EVP_MD *md)
2276 PKCS12_PBEParams p12params;
2277 int passwordlen;
2278 hx509_crypto c;
2279 int iter, saltlen, ret;
2280 unsigned char *salt;
2282 passwordlen = password ? strlen(password) : 0;
2284 if (parameters == NULL)
2285 return HX509_ALG_NOT_SUPP;
2287 ret = decode_PKCS12_PBEParams(parameters->data,
2288 parameters->length,
2289 &p12params, NULL);
2290 if (ret)
2291 goto out;
2293 if (p12params.iterations)
2294 iter = *p12params.iterations;
2295 else
2296 iter = 1;
2297 salt = p12params.salt.data;
2298 saltlen = p12params.salt.length;
2300 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2301 PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2302 ret = HX509_CRYPTO_INTERNAL_ERROR;
2303 goto out;
2306 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2307 PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2308 ret = HX509_CRYPTO_INTERNAL_ERROR;
2309 goto out;
2312 ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2313 if (ret)
2314 goto out;
2316 ret = hx509_crypto_set_key_data(c, key->data, key->length);
2317 if (ret) {
2318 hx509_crypto_destroy(c);
2319 goto out;
2322 *crypto = c;
2323 out:
2324 free_PKCS12_PBEParams(&p12params);
2325 return ret;
2328 static const heim_oid *
2329 find_string2key(const heim_oid *oid,
2330 const EVP_CIPHER **c,
2331 const EVP_MD **md,
2332 PBE_string2key_func *s2k)
2334 if (der_heim_oid_cmp(oid, oid_id_pbewithSHAAnd40BitRC2_CBC()) == 0) {
2335 *c = EVP_rc2_40_cbc();
2336 *md = EVP_sha1();
2337 *s2k = PBE_string2key;
2338 return oid_private_rc2_40();
2339 } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC2_CBC()) == 0) {
2340 *c = EVP_rc2_cbc();
2341 *md = EVP_sha1();
2342 *s2k = PBE_string2key;
2343 return oid_id_pkcs3_rc2_cbc();
2344 #if 0
2345 } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd40BitRC4()) == 0) {
2346 *c = EVP_rc4_40();
2347 *md = EVP_sha1();
2348 *s2k = PBE_string2key;
2349 return NULL;
2350 } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd128BitRC4()) == 0) {
2351 *c = EVP_rc4();
2352 *md = EVP_sha1();
2353 *s2k = PBE_string2key;
2354 return oid_id_pkcs3_rc4();
2355 #endif
2356 } else if (der_heim_oid_cmp(oid, oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC()) == 0) {
2357 *c = EVP_des_ede3_cbc();
2358 *md = EVP_sha1();
2359 *s2k = PBE_string2key;
2360 return oid_id_pkcs3_des_ede3_cbc();
2363 return NULL;
2371 _hx509_pbe_encrypt(hx509_context context,
2372 hx509_lock lock,
2373 const AlgorithmIdentifier *ai,
2374 const heim_octet_string *content,
2375 heim_octet_string *econtent)
2377 hx509_clear_error_string(context);
2378 return EINVAL;
2386 _hx509_pbe_decrypt(hx509_context context,
2387 hx509_lock lock,
2388 const AlgorithmIdentifier *ai,
2389 const heim_octet_string *econtent,
2390 heim_octet_string *content)
2392 const struct _hx509_password *pw;
2393 heim_octet_string key, iv;
2394 const heim_oid *enc_oid;
2395 const EVP_CIPHER *c;
2396 const EVP_MD *md;
2397 PBE_string2key_func s2k;
2398 int i, ret = 0;
2400 memset(&key, 0, sizeof(key));
2401 memset(&iv, 0, sizeof(iv));
2403 memset(content, 0, sizeof(*content));
2405 enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2406 if (enc_oid == NULL) {
2407 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2408 "String to key algorithm not supported");
2409 ret = HX509_ALG_NOT_SUPP;
2410 goto out;
2413 key.length = EVP_CIPHER_key_length(c);
2414 key.data = malloc(key.length);
2415 if (key.data == NULL) {
2416 ret = ENOMEM;
2417 hx509_clear_error_string(context);
2418 goto out;
2421 iv.length = EVP_CIPHER_iv_length(c);
2422 iv.data = malloc(iv.length);
2423 if (iv.data == NULL) {
2424 ret = ENOMEM;
2425 hx509_clear_error_string(context);
2426 goto out;
2429 pw = _hx509_lock_get_passwords(lock);
2431 ret = HX509_CRYPTO_INTERNAL_ERROR;
2432 for (i = 0; i < pw->len + 1; i++) {
2433 hx509_crypto crypto;
2434 const char *password;
2436 if (i < pw->len)
2437 password = pw->val[i];
2438 else if (i < pw->len + 1)
2439 password = "";
2440 else
2441 password = NULL;
2443 ret = (*s2k)(context, password, ai->parameters, &crypto,
2444 &key, &iv, enc_oid, md);
2445 if (ret)
2446 goto out;
2448 ret = hx509_crypto_decrypt(crypto,
2449 econtent->data,
2450 econtent->length,
2451 &iv,
2452 content);
2453 hx509_crypto_destroy(crypto);
2454 if (ret == 0)
2455 goto out;
2458 out:
2459 if (key.data)
2460 der_free_octet_string(&key);
2461 if (iv.data)
2462 der_free_octet_string(&iv);
2463 return ret;
2472 _hx509_match_keys(hx509_cert c, hx509_private_key private_key)
2474 const Certificate *cert;
2475 const SubjectPublicKeyInfo *spi;
2476 RSAPublicKey pk;
2477 RSA *rsa;
2478 size_t size;
2479 int ret;
2481 if (private_key->private_key.rsa == NULL)
2482 return 0;
2484 rsa = private_key->private_key.rsa;
2485 if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2486 return 0;
2488 cert = _hx509_get_cert(c);
2489 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2491 rsa = RSA_new();
2492 if (rsa == NULL)
2493 return 0;
2495 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2496 spi->subjectPublicKey.length / 8,
2497 &pk, &size);
2498 if (ret) {
2499 RSA_free(rsa);
2500 return 0;
2502 rsa->n = heim_int2BN(&pk.modulus);
2503 rsa->e = heim_int2BN(&pk.publicExponent);
2505 free_RSAPublicKey(&pk);
2507 rsa->d = BN_dup(private_key->private_key.rsa->d);
2508 rsa->p = BN_dup(private_key->private_key.rsa->p);
2509 rsa->q = BN_dup(private_key->private_key.rsa->q);
2510 rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
2511 rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
2512 rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
2514 if (rsa->n == NULL || rsa->e == NULL ||
2515 rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
2516 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
2517 RSA_free(rsa);
2518 return 0;
2521 ret = RSA_check_key(rsa);
2522 RSA_free(rsa);
2524 return ret == 1;
2527 static const heim_oid *
2528 find_keytype(const hx509_private_key key)
2530 const struct signature_alg *md;
2532 if (key == NULL)
2533 return NULL;
2535 md = find_sig_alg(key->signature_alg);
2536 if (md == NULL)
2537 return NULL;
2538 return (*md->key_oid)();
2543 hx509_crypto_select(const hx509_context context,
2544 int type,
2545 const hx509_private_key source,
2546 hx509_peer_info peer,
2547 AlgorithmIdentifier *selected)
2549 const AlgorithmIdentifier *def;
2550 size_t i, j;
2551 int ret, bits;
2553 memset(selected, 0, sizeof(*selected));
2555 if (type == HX509_SELECT_DIGEST) {
2556 bits = SIG_DIGEST;
2557 def = _hx509_crypto_default_digest_alg;
2558 } else if (type == HX509_SELECT_PUBLIC_SIG) {
2559 bits = SIG_PUBLIC_SIG;
2560 /* XXX depend on `source´ and `peer´ */
2561 def = _hx509_crypto_default_sig_alg;
2562 } else if (type == HX509_SELECT_SECRET_ENC) {
2563 bits = SIG_SECRET;
2564 def = _hx509_crypto_default_secret_alg;
2565 } else {
2566 hx509_set_error_string(context, 0, EINVAL,
2567 "Unknown type %d of selection", type);
2568 return EINVAL;
2571 if (peer) {
2572 const heim_oid *keytype = NULL;
2574 keytype = find_keytype(source);
2576 for (i = 0; i < peer->len; i++) {
2577 for (j = 0; sig_algs[j]; j++) {
2578 if ((sig_algs[j]->flags & bits) != bits)
2579 continue;
2580 if (der_heim_oid_cmp((*sig_algs[j]->sig_oid)(),
2581 &peer->val[i].algorithm) != 0)
2582 continue;
2583 if (keytype && sig_algs[j]->key_oid &&
2584 der_heim_oid_cmp(keytype, (*sig_algs[j]->key_oid)()))
2585 continue;
2587 /* found one, use that */
2588 ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
2589 if (ret)
2590 hx509_clear_error_string(context);
2591 return ret;
2593 if (bits & SIG_SECRET) {
2594 const struct hx509cipher *cipher;
2596 cipher = find_cipher_by_oid(&peer->val[i].algorithm);
2597 if (cipher == NULL)
2598 continue;
2599 if (cipher->ai_func == NULL)
2600 continue;
2601 ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
2602 if (ret)
2603 hx509_clear_error_string(context);
2604 return ret;
2609 /* use default */
2610 ret = copy_AlgorithmIdentifier(def, selected);
2611 if (ret)
2612 hx509_clear_error_string(context);
2613 return ret;
2617 hx509_crypto_available(hx509_context context,
2618 int type,
2619 hx509_cert source,
2620 AlgorithmIdentifier **val,
2621 unsigned int *plen)
2623 const heim_oid *keytype = NULL;
2624 unsigned int len, i;
2625 void *ptr;
2626 int bits, ret;
2628 *val = NULL;
2630 if (type == HX509_SELECT_ALL) {
2631 bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
2632 } else if (type == HX509_SELECT_DIGEST) {
2633 bits = SIG_DIGEST;
2634 } else if (type == HX509_SELECT_PUBLIC_SIG) {
2635 bits = SIG_PUBLIC_SIG;
2636 } else {
2637 hx509_set_error_string(context, 0, EINVAL,
2638 "Unknown type %d of available", type);
2639 return EINVAL;
2642 if (source)
2643 keytype = find_keytype(_hx509_cert_private_key(source));
2645 len = 0;
2646 for (i = 0; sig_algs[i]; i++) {
2647 if ((sig_algs[i]->flags & bits) == 0)
2648 continue;
2649 if (sig_algs[i]->sig_alg == NULL)
2650 continue;
2651 if (keytype && sig_algs[i]->key_oid &&
2652 der_heim_oid_cmp((*sig_algs[i]->key_oid)(), keytype))
2653 continue;
2655 /* found one, add that to the list */
2656 ptr = realloc(*val, sizeof(**val) * (len + 1));
2657 if (ptr == NULL)
2658 goto out;
2659 *val = ptr;
2661 ret = copy_AlgorithmIdentifier((*sig_algs[i]->sig_alg)(), &(*val)[len]);
2662 if (ret)
2663 goto out;
2664 len++;
2667 /* Add AES */
2668 if (bits & SIG_SECRET) {
2670 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
2672 if (ciphers[i].ai_func == NULL)
2673 continue;
2675 ptr = realloc(*val, sizeof(**val) * (len + 1));
2676 if (ptr == NULL)
2677 goto out;
2678 *val = ptr;
2680 ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
2681 if (ret)
2682 goto out;
2683 len++;
2687 *plen = len;
2688 return 0;
2690 out:
2691 for (i = 0; i < len; i++)
2692 free_AlgorithmIdentifier(&(*val)[i]);
2693 free(*val);
2694 *val = NULL;
2695 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
2696 return ENOMEM;
2699 void
2700 hx509_crypto_free_algs(AlgorithmIdentifier *val,
2701 unsigned int len)
2703 unsigned int i;
2704 for (i = 0; i < len; i++)
2705 free_AlgorithmIdentifier(&val[i]);
2706 free(val);