HEIMDAL: move code from source4/heimdal* to third_party/heimdal*
[Samba.git] / third_party / heimdal / lib / hx509 / crypto.c
blob77e721064ef11e158ae033e93cc43146967222a1
1 /*
2 * Copyright (c) 2004 - 2016 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "hx_locl.h"
36 /*-
37 * RFC5758 specifies no parameters for ecdsa-with-SHA<N> signatures
38 * RFC5754 specifies NULL parameters for sha<N>WithRSAEncryption signatures
40 * XXX: Make sure that the parameters are either NULL in both the tbs and the
41 * signature, or absent from both the tbs and the signature.
44 static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
46 static const unsigned sha512_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 3 };
47 const AlgorithmIdentifier _hx509_signature_sha512_data = {
48 { 9, rk_UNCONST(sha512_oid_tree) }, rk_UNCONST(&null_entry_oid)
51 static const unsigned sha384_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 2 };
52 const AlgorithmIdentifier _hx509_signature_sha384_data = {
53 { 9, rk_UNCONST(sha384_oid_tree) }, rk_UNCONST(&null_entry_oid)
56 static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
57 const AlgorithmIdentifier _hx509_signature_sha256_data = {
58 { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
61 static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
62 const AlgorithmIdentifier _hx509_signature_sha1_data = {
63 { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
66 static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
67 const AlgorithmIdentifier _hx509_signature_md5_data = {
68 { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
71 static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
72 const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
73 { 7, rk_UNCONST(rsa_with_sha512_oid) }, rk_UNCONST(&null_entry_oid)
76 static const unsigned rsa_with_sha384_oid[] ={ 1, 2, 840, 113549, 1, 1, 12 };
77 const AlgorithmIdentifier _hx509_signature_rsa_with_sha384_data = {
78 { 7, rk_UNCONST(rsa_with_sha384_oid) }, rk_UNCONST(&null_entry_oid)
81 static const unsigned rsa_with_sha256_oid[] ={ 1, 2, 840, 113549, 1, 1, 11 };
82 const AlgorithmIdentifier _hx509_signature_rsa_with_sha256_data = {
83 { 7, rk_UNCONST(rsa_with_sha256_oid) }, rk_UNCONST(&null_entry_oid)
86 static const unsigned rsa_with_sha1_oid[] ={ 1, 2, 840, 113549, 1, 1, 5 };
87 const AlgorithmIdentifier _hx509_signature_rsa_with_sha1_data = {
88 { 7, rk_UNCONST(rsa_with_sha1_oid) }, rk_UNCONST(&null_entry_oid)
91 static const unsigned rsa_with_md5_oid[] ={ 1, 2, 840, 113549, 1, 1, 4 };
92 const AlgorithmIdentifier _hx509_signature_rsa_with_md5_data = {
93 { 7, rk_UNCONST(rsa_with_md5_oid) }, rk_UNCONST(&null_entry_oid)
96 static const unsigned rsa_oid[] ={ 1, 2, 840, 113549, 1, 1, 1 };
97 const AlgorithmIdentifier _hx509_signature_rsa_data = {
98 { 7, rk_UNCONST(rsa_oid) }, NULL
101 static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
102 const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = {
103 { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
106 static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
107 const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
108 { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
111 static const unsigned aes128_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 2 };
112 const AlgorithmIdentifier _hx509_crypto_aes128_cbc_data = {
113 { 9, rk_UNCONST(aes128_cbc_oid) }, NULL
116 static const unsigned aes256_cbc_oid[] ={ 2, 16, 840, 1, 101, 3, 4, 1, 42 };
117 const AlgorithmIdentifier _hx509_crypto_aes256_cbc_data = {
118 { 9, rk_UNCONST(aes256_cbc_oid) }, NULL
125 static BIGNUM *
126 heim_int2BN(const heim_integer *i)
128 BIGNUM *bn;
130 bn = BN_bin2bn(i->data, i->length, NULL);
131 BN_set_negative(bn, i->negative);
132 return bn;
139 HX509_LIB_FUNCTION int HX509_LIB_CALL
140 _hx509_set_digest_alg(DigestAlgorithmIdentifier *id,
141 const heim_oid *oid,
142 const void *param, size_t length)
144 int ret;
145 if (param) {
146 id->parameters = malloc(sizeof(*id->parameters));
147 if (id->parameters == NULL)
148 return ENOMEM;
149 id->parameters->data = malloc(length);
150 if (id->parameters->data == NULL) {
151 free(id->parameters);
152 id->parameters = NULL;
153 return ENOMEM;
155 memcpy(id->parameters->data, param, length);
156 id->parameters->length = length;
157 } else
158 id->parameters = NULL;
159 ret = der_copy_oid(oid, &id->algorithm);
160 if (ret) {
161 if (id->parameters) {
162 free(id->parameters->data);
163 free(id->parameters);
164 id->parameters = NULL;
166 return ret;
168 return 0;
175 static int
176 rsa_verify_signature(hx509_context context,
177 const struct signature_alg *sig_alg,
178 const Certificate *signer,
179 const AlgorithmIdentifier *alg,
180 const heim_octet_string *data,
181 const heim_octet_string *sig)
183 const SubjectPublicKeyInfo *spi;
184 DigestInfo di;
185 unsigned char *to;
186 int tosize, retsize;
187 int ret;
188 RSA *rsa;
189 size_t size;
190 const unsigned char *p;
192 memset(&di, 0, sizeof(di));
194 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
196 p = spi->subjectPublicKey.data;
197 size = spi->subjectPublicKey.length / 8;
199 rsa = d2i_RSAPublicKey(NULL, &p, size);
200 if (rsa == NULL) {
201 ret = ENOMEM;
202 hx509_set_error_string(context, 0, ret, "out of memory");
203 goto out;
206 tosize = RSA_size(rsa);
207 to = malloc(tosize);
208 if (to == NULL) {
209 ret = ENOMEM;
210 hx509_set_error_string(context, 0, ret, "out of memory");
211 goto out;
214 retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
215 to, rsa, RSA_PKCS1_PADDING);
216 if (retsize <= 0) {
217 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
218 hx509_set_error_string(context, 0, ret,
219 "RSA public decrypt failed: %d", retsize);
220 free(to);
221 goto out;
223 if (retsize > tosize)
224 _hx509_abort("internal rsa decryption failure: ret > tosize");
226 if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
228 ret = decode_DigestInfo(to, retsize, &di, &size);
229 free(to);
230 if (ret) {
231 goto out;
234 /* Check for extra data inside the sigature */
235 if (size != (size_t)retsize) {
236 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
237 hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
238 goto out;
241 if (sig_alg->digest_alg &&
242 der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
243 &sig_alg->digest_alg->algorithm) != 0)
245 ret = HX509_CRYPTO_OID_MISMATCH;
246 hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
247 goto out;
250 /* verify that the parameters are NULL or the NULL-type */
251 if (di.digestAlgorithm.parameters != NULL &&
252 (di.digestAlgorithm.parameters->length != 2 ||
253 memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
255 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
256 hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
257 goto out;
260 ret = _hx509_verify_signature(context,
261 NULL,
262 &di.digestAlgorithm,
263 data,
264 &di.digest);
265 if (ret)
266 goto out;
268 } else {
269 if ((size_t)retsize != data->length ||
270 ct_memcmp(to, data->data, retsize) != 0)
272 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
273 hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
274 goto out;
276 free(to);
277 ret = 0;
280 out:
281 free_DigestInfo(&di);
282 if (rsa)
283 RSA_free(rsa);
284 return ret;
287 static int
288 rsa_create_signature(hx509_context context,
289 const struct signature_alg *sig_alg,
290 const hx509_private_key signer,
291 const AlgorithmIdentifier *alg,
292 const heim_octet_string *data,
293 AlgorithmIdentifier *signatureAlgorithm,
294 heim_octet_string *sig)
296 const AlgorithmIdentifier *digest_alg;
297 heim_octet_string indata;
298 const heim_oid *sig_oid;
299 size_t size;
300 int ret;
302 if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0)
303 return HX509_ALG_NOT_SUPP;
305 if (alg)
306 sig_oid = &alg->algorithm;
307 else
308 sig_oid = signer->signature_alg;
310 if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
311 digest_alg = hx509_signature_sha512();
312 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
313 digest_alg = hx509_signature_sha384();
314 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
315 digest_alg = hx509_signature_sha256();
316 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
317 digest_alg = hx509_signature_sha1();
318 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
319 digest_alg = hx509_signature_md5();
320 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
321 digest_alg = hx509_signature_md5();
322 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) {
323 digest_alg = hx509_signature_sha1();
324 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
325 digest_alg = hx509_signature_sha1();
326 } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) {
327 digest_alg = NULL;
328 } else
329 return HX509_ALG_NOT_SUPP;
331 if (signatureAlgorithm) {
332 ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid,
333 "\x05\x00", 2);
334 if (ret) {
335 hx509_clear_error_string(context);
336 return ret;
340 if (digest_alg) {
341 DigestInfo di;
342 memset(&di, 0, sizeof(di));
344 ret = _hx509_create_signature(context,
345 NULL,
346 digest_alg,
347 data,
348 &di.digestAlgorithm,
349 &di.digest);
350 if (ret)
351 return ret;
352 ASN1_MALLOC_ENCODE(DigestInfo,
353 indata.data,
354 indata.length,
355 &di,
356 &size,
357 ret);
358 free_DigestInfo(&di);
359 if (ret) {
360 hx509_set_error_string(context, 0, ret, "out of memory");
361 return ret;
363 if (indata.length != size)
364 _hx509_abort("internal ASN.1 encoder error");
365 } else {
366 indata = *data;
369 sig->length = RSA_size(signer->private_key.rsa);
370 sig->data = malloc(sig->length);
371 if (sig->data == NULL) {
372 der_free_octet_string(&indata);
373 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
374 return ENOMEM;
377 ret = RSA_private_encrypt(indata.length, indata.data,
378 sig->data,
379 signer->private_key.rsa,
380 RSA_PKCS1_PADDING);
381 if (indata.data != data->data)
382 der_free_octet_string(&indata);
383 if (ret <= 0) {
384 ret = HX509_CMS_FAILED_CREATE_SIGATURE;
385 hx509_set_error_string(context, 0, ret,
386 "RSA private encrypt failed: %d", ret);
387 return ret;
389 if (sig->length > (size_t)ret) {
390 size = sig->length - ret;
391 memmove((uint8_t *)sig->data + size, sig->data, ret);
392 memset(sig->data, 0, size);
393 } else if (sig->length < (size_t)ret)
394 _hx509_abort("RSA signature prelen longer the output len");
396 return 0;
399 static int
400 rsa_private_key_import(hx509_context context,
401 const AlgorithmIdentifier *keyai,
402 const void *data,
403 size_t len,
404 hx509_key_format_t format,
405 hx509_private_key private_key)
407 switch (format) {
408 case HX509_KEY_FORMAT_DER: {
409 const unsigned char *p = data;
411 private_key->private_key.rsa =
412 d2i_RSAPrivateKey(NULL, &p, len);
413 if (private_key->private_key.rsa == NULL) {
414 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
415 "Failed to parse RSA key");
416 return HX509_PARSING_KEY_FAILED;
418 private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
419 break;
422 default:
423 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
426 return 0;
429 static int
430 rsa_private_key2SPKI(hx509_context context,
431 hx509_private_key private_key,
432 SubjectPublicKeyInfo *spki)
434 int len, ret;
436 memset(spki, 0, sizeof(*spki));
438 len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
440 spki->subjectPublicKey.data = malloc(len);
441 if (spki->subjectPublicKey.data == NULL) {
442 hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
443 return ENOMEM;
445 spki->subjectPublicKey.length = len * 8;
447 ret = _hx509_set_digest_alg(&spki->algorithm,
448 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
449 "\x05\x00", 2);
450 if (ret) {
451 hx509_set_error_string(context, 0, ret, "malloc - out of memory");
452 free(spki->subjectPublicKey.data);
453 spki->subjectPublicKey.data = NULL;
454 spki->subjectPublicKey.length = 0;
455 return ret;
459 unsigned char *pp = spki->subjectPublicKey.data;
460 i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
463 return 0;
466 static int
467 rsa_generate_private_key(hx509_context context,
468 struct hx509_generate_private_context *ctx,
469 hx509_private_key private_key)
471 BIGNUM *e;
472 int ret;
473 unsigned long bits;
475 static const int default_rsa_e = 65537;
476 static const int default_rsa_bits = 2048;
478 private_key->private_key.rsa = RSA_new();
479 if (private_key->private_key.rsa == NULL) {
480 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
481 "Failed to generate RSA key");
482 return HX509_PARSING_KEY_FAILED;
485 e = BN_new();
486 BN_set_word(e, default_rsa_e);
488 bits = default_rsa_bits;
490 if (ctx->num_bits)
491 bits = ctx->num_bits;
493 ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
494 BN_free(e);
495 if (ret != 1) {
496 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
497 "Failed to generate RSA key");
498 return HX509_PARSING_KEY_FAILED;
500 private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
502 return 0;
505 static int
506 rsa_private_key_export(hx509_context context,
507 const hx509_private_key key,
508 hx509_key_format_t format,
509 heim_octet_string *data)
511 int ret;
513 data->data = NULL;
514 data->length = 0;
516 switch (format) {
517 case HX509_KEY_FORMAT_DER:
519 ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
520 if (ret <= 0) {
521 ret = EINVAL;
522 hx509_set_error_string(context, 0, ret,
523 "Private key is not exportable");
524 return ret;
527 data->data = malloc(ret);
528 if (data->data == NULL) {
529 ret = ENOMEM;
530 hx509_set_error_string(context, 0, ret, "malloc out of memory");
531 return ret;
533 data->length = ret;
536 unsigned char *p = data->data;
537 i2d_RSAPrivateKey(key->private_key.rsa, &p);
539 break;
540 default:
541 return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
544 return 0;
547 static BIGNUM *
548 rsa_get_internal(hx509_context context,
549 hx509_private_key key,
550 const char *type)
552 if (strcasecmp(type, "rsa-modulus") == 0) {
553 return BN_dup(key->private_key.rsa->n);
554 } else if (strcasecmp(type, "rsa-exponent") == 0) {
555 return BN_dup(key->private_key.rsa->e);
556 } else
557 return NULL;
562 static hx509_private_key_ops rsa_private_key_ops = {
563 "RSA PRIVATE KEY",
564 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
565 NULL,
566 rsa_private_key2SPKI,
567 rsa_private_key_export,
568 rsa_private_key_import,
569 rsa_generate_private_key,
570 rsa_get_internal
577 static int
578 dsa_verify_signature(hx509_context context,
579 const struct signature_alg *sig_alg,
580 const Certificate *signer,
581 const AlgorithmIdentifier *alg,
582 const heim_octet_string *data,
583 const heim_octet_string *sig)
585 const SubjectPublicKeyInfo *spi;
586 DSAPublicKey pk;
587 DSAParams param;
588 size_t size;
589 DSA *dsa;
590 int ret;
592 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
594 dsa = DSA_new();
595 if (dsa == NULL) {
596 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
597 return ENOMEM;
600 ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
601 spi->subjectPublicKey.length / 8,
602 &pk, &size);
603 if (ret)
604 goto out;
606 dsa->pub_key = heim_int2BN(&pk);
608 free_DSAPublicKey(&pk);
610 if (dsa->pub_key == NULL) {
611 ret = ENOMEM;
612 hx509_set_error_string(context, 0, ret, "out of memory");
613 goto out;
616 if (spi->algorithm.parameters == NULL) {
617 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
618 hx509_set_error_string(context, 0, ret, "DSA parameters missing");
619 goto out;
622 ret = decode_DSAParams(spi->algorithm.parameters->data,
623 spi->algorithm.parameters->length,
624 &param,
625 &size);
626 if (ret) {
627 hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
628 goto out;
631 dsa->p = heim_int2BN(&param.p);
632 dsa->q = heim_int2BN(&param.q);
633 dsa->g = heim_int2BN(&param.g);
635 free_DSAParams(&param);
637 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
638 ret = ENOMEM;
639 hx509_set_error_string(context, 0, ret, "out of memory");
640 goto out;
643 ret = DSA_verify(-1, data->data, data->length,
644 (unsigned char*)sig->data, sig->length,
645 dsa);
646 if (ret == 1)
647 ret = 0;
648 else if (ret == 0 || ret == -1) {
649 ret = HX509_CRYPTO_BAD_SIGNATURE;
650 hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
651 } else {
652 ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
653 hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
656 out:
657 DSA_free(dsa);
659 return ret;
662 #if 0
663 static int
664 dsa_parse_private_key(hx509_context context,
665 const void *data,
666 size_t len,
667 hx509_private_key private_key)
669 const unsigned char *p = data;
671 private_key->private_key.dsa =
672 d2i_DSAPrivateKey(NULL, &p, len);
673 if (private_key->private_key.dsa == NULL)
674 return EINVAL;
675 private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1;
677 return 0;
678 /* else */
679 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
680 "No support to parse DSA keys");
681 return HX509_PARSING_KEY_FAILED;
683 #endif
685 static int
686 evp_md_create_signature(hx509_context context,
687 const struct signature_alg *sig_alg,
688 const hx509_private_key signer,
689 const AlgorithmIdentifier *alg,
690 const heim_octet_string *data,
691 AlgorithmIdentifier *signatureAlgorithm,
692 heim_octet_string *sig)
694 size_t sigsize = EVP_MD_size(sig_alg->evp_md());
695 EVP_MD_CTX *ctx;
697 memset(sig, 0, sizeof(*sig));
699 if (signatureAlgorithm) {
700 int ret;
701 ret = _hx509_set_digest_alg(signatureAlgorithm,
702 sig_alg->sig_oid, "\x05\x00", 2);
703 if (ret)
704 return ret;
708 sig->data = malloc(sigsize);
709 if (sig->data == NULL) {
710 sig->length = 0;
711 return ENOMEM;
713 sig->length = sigsize;
715 ctx = EVP_MD_CTX_create();
716 EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
717 EVP_DigestUpdate(ctx, data->data, data->length);
718 EVP_DigestFinal_ex(ctx, sig->data, NULL);
719 EVP_MD_CTX_destroy(ctx);
722 return 0;
725 static int
726 evp_md_verify_signature(hx509_context context,
727 const struct signature_alg *sig_alg,
728 const Certificate *signer,
729 const AlgorithmIdentifier *alg,
730 const heim_octet_string *data,
731 const heim_octet_string *sig)
733 unsigned char digest[EVP_MAX_MD_SIZE];
734 EVP_MD_CTX *ctx;
735 size_t sigsize = EVP_MD_size(sig_alg->evp_md());
737 if (sig->length != sigsize || sigsize > sizeof(digest)) {
738 hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
739 "SHA256 sigature have wrong length");
740 return HX509_CRYPTO_SIG_INVALID_FORMAT;
743 ctx = EVP_MD_CTX_create();
744 EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
745 EVP_DigestUpdate(ctx, data->data, data->length);
746 EVP_DigestFinal_ex(ctx, digest, NULL);
747 EVP_MD_CTX_destroy(ctx);
749 if (ct_memcmp(digest, sig->data, sigsize) != 0) {
750 hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
751 "Bad %s sigature", sig_alg->name);
752 return HX509_CRYPTO_BAD_SIGNATURE;
755 return 0;
758 #ifdef HAVE_HCRYPTO_W_OPENSSL
759 extern const struct signature_alg ecdsa_with_sha512_alg;
760 extern const struct signature_alg ecdsa_with_sha384_alg;
761 extern const struct signature_alg ecdsa_with_sha256_alg;
762 extern const struct signature_alg ecdsa_with_sha1_alg;
763 #endif
765 static const struct signature_alg heim_rsa_pkcs1_x509 = {
766 "rsa-pkcs1-x509",
767 ASN1_OID_ID_HEIM_RSA_PKCS1_X509,
768 &_hx509_signature_rsa_pkcs1_x509_data,
769 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
770 NULL,
771 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
773 NULL,
774 rsa_verify_signature,
775 rsa_create_signature,
779 static const struct signature_alg pkcs1_rsa_sha1_alg = {
780 "rsa",
781 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
782 &_hx509_signature_rsa_with_sha1_data,
783 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
784 NULL,
785 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
787 NULL,
788 rsa_verify_signature,
789 rsa_create_signature,
793 static const struct signature_alg rsa_with_sha512_alg = {
794 "rsa-with-sha512",
795 ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION,
796 &_hx509_signature_rsa_with_sha512_data,
797 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
798 &_hx509_signature_sha512_data,
799 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
801 NULL,
802 rsa_verify_signature,
803 rsa_create_signature,
807 static const struct signature_alg rsa_with_sha384_alg = {
808 "rsa-with-sha384",
809 ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION,
810 &_hx509_signature_rsa_with_sha384_data,
811 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
812 &_hx509_signature_sha384_data,
813 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
815 NULL,
816 rsa_verify_signature,
817 rsa_create_signature,
821 static const struct signature_alg rsa_with_sha256_alg = {
822 "rsa-with-sha256",
823 ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
824 &_hx509_signature_rsa_with_sha256_data,
825 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
826 &_hx509_signature_sha256_data,
827 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
829 NULL,
830 rsa_verify_signature,
831 rsa_create_signature,
835 static const struct signature_alg rsa_with_sha1_alg = {
836 "rsa-with-sha1",
837 ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION,
838 &_hx509_signature_rsa_with_sha1_data,
839 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
840 &_hx509_signature_sha1_data,
841 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
843 NULL,
844 rsa_verify_signature,
845 rsa_create_signature,
849 static const struct signature_alg rsa_with_sha1_alg_secsig = {
850 "rsa-with-sha1",
851 ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION,
852 &_hx509_signature_rsa_with_sha1_data,
853 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
854 &_hx509_signature_sha1_data,
855 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
857 NULL,
858 rsa_verify_signature,
859 rsa_create_signature,
863 static const struct signature_alg rsa_with_md5_alg = {
864 "rsa-with-md5",
865 ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION,
866 &_hx509_signature_rsa_with_md5_data,
867 ASN1_OID_ID_PKCS1_RSAENCRYPTION,
868 &_hx509_signature_md5_data,
869 PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|WEAK_SIG_ALG,
870 1230739889,
871 NULL,
872 rsa_verify_signature,
873 rsa_create_signature,
877 static const struct signature_alg dsa_sha1_alg = {
878 "dsa-with-sha1",
879 ASN1_OID_ID_DSA_WITH_SHA1,
880 NULL,
881 ASN1_OID_ID_DSA,
882 &_hx509_signature_sha1_data,
883 PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
885 NULL,
886 dsa_verify_signature,
887 /* create_signature */ NULL,
891 static const struct signature_alg sha512_alg = {
892 "sha-512",
893 ASN1_OID_ID_SHA512,
894 &_hx509_signature_sha512_data,
895 NULL,
896 NULL,
897 SIG_DIGEST,
899 EVP_sha512,
900 evp_md_verify_signature,
901 evp_md_create_signature,
905 static const struct signature_alg sha384_alg = {
906 "sha-384",
907 ASN1_OID_ID_SHA384,
908 &_hx509_signature_sha384_data,
909 NULL,
910 NULL,
911 SIG_DIGEST,
913 EVP_sha384,
914 evp_md_verify_signature,
915 evp_md_create_signature,
919 static const struct signature_alg sha256_alg = {
920 "sha-256",
921 ASN1_OID_ID_SHA256,
922 &_hx509_signature_sha256_data,
923 NULL,
924 NULL,
925 SIG_DIGEST,
927 EVP_sha256,
928 evp_md_verify_signature,
929 evp_md_create_signature,
933 static const struct signature_alg sha1_alg = {
934 "sha1",
935 ASN1_OID_ID_SECSIG_SHA_1,
936 &_hx509_signature_sha1_data,
937 NULL,
938 NULL,
939 SIG_DIGEST,
941 EVP_sha1,
942 evp_md_verify_signature,
943 evp_md_create_signature,
947 static const struct signature_alg md5_alg = {
948 "rsa-md5",
949 ASN1_OID_ID_RSA_DIGEST_MD5,
950 &_hx509_signature_md5_data,
951 NULL,
952 NULL,
953 SIG_DIGEST|WEAK_SIG_ALG,
955 EVP_md5,
956 evp_md_verify_signature,
957 NULL,
962 * Order matter in this structure, "best" first for each "key
963 * compatible" type (type is ECDSA, RSA, DSA, none, etc)
966 static const struct signature_alg *sig_algs[] = {
967 #ifdef HAVE_HCRYPTO_W_OPENSSL
968 &ecdsa_with_sha512_alg,
969 &ecdsa_with_sha384_alg,
970 &ecdsa_with_sha256_alg,
971 &ecdsa_with_sha1_alg,
972 #endif
973 &rsa_with_sha512_alg,
974 &rsa_with_sha384_alg,
975 &rsa_with_sha256_alg,
976 &rsa_with_sha1_alg,
977 &rsa_with_sha1_alg_secsig,
978 &pkcs1_rsa_sha1_alg,
979 &rsa_with_md5_alg,
980 &heim_rsa_pkcs1_x509,
981 &dsa_sha1_alg,
982 &sha512_alg,
983 &sha384_alg,
984 &sha256_alg,
985 &sha1_alg,
986 &md5_alg,
987 NULL
990 const struct signature_alg *
991 _hx509_find_sig_alg(const heim_oid *oid)
993 unsigned int i;
994 for (i = 0; sig_algs[i]; i++)
995 if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
996 return sig_algs[i];
997 return NULL;
1000 static const AlgorithmIdentifier *
1001 alg_for_privatekey(const hx509_private_key pk, int type)
1003 const heim_oid *keytype;
1004 unsigned int i;
1006 if (pk->ops == NULL)
1007 return NULL;
1009 keytype = pk->ops->key_oid;
1011 for (i = 0; sig_algs[i]; i++) {
1012 if (sig_algs[i]->key_oid == NULL)
1013 continue;
1014 if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
1015 continue;
1016 if (pk->ops->available &&
1017 pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
1018 continue;
1019 if (type == HX509_SELECT_PUBLIC_SIG)
1020 return sig_algs[i]->sig_alg;
1021 if (type == HX509_SELECT_DIGEST)
1022 return sig_algs[i]->digest_alg;
1024 return NULL;
1026 return NULL;
1032 #ifdef HAVE_HCRYPTO_W_OPENSSL
1033 extern hx509_private_key_ops ecdsa_private_key_ops;
1034 #endif
1036 static struct hx509_private_key_ops *private_algs[] = {
1037 &rsa_private_key_ops,
1038 #ifdef HAVE_HCRYPTO_W_OPENSSL
1039 &ecdsa_private_key_ops,
1040 #endif
1041 NULL
1044 HX509_LIB_FUNCTION hx509_private_key_ops * HX509_LIB_CALL
1045 hx509_find_private_alg(const heim_oid *oid)
1047 int i;
1048 for (i = 0; private_algs[i]; i++) {
1049 if (private_algs[i]->key_oid == NULL)
1050 continue;
1051 if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
1052 return private_algs[i];
1054 return NULL;
1058 * Check if the algorithm `alg' have a best before date, and if it
1059 * des, make sure the its before the time `t'.
1062 HX509_LIB_FUNCTION int HX509_LIB_CALL
1063 _hx509_signature_is_weak(hx509_context context, const AlgorithmIdentifier *alg)
1065 const struct signature_alg *md;
1067 md = _hx509_find_sig_alg(&alg->algorithm);
1068 if (md == NULL) {
1069 hx509_clear_error_string(context);
1070 return HX509_SIG_ALG_NO_SUPPORTED;
1072 if (md->flags & WEAK_SIG_ALG) {
1073 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1074 "Algorithm %s is weak", md->name);
1075 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1077 return 0;
1080 HX509_LIB_FUNCTION int HX509_LIB_CALL
1081 _hx509_self_signed_valid(hx509_context context,
1082 const AlgorithmIdentifier *alg)
1084 const struct signature_alg *md;
1086 md = _hx509_find_sig_alg(&alg->algorithm);
1087 if (md == NULL) {
1088 hx509_clear_error_string(context);
1089 return HX509_SIG_ALG_NO_SUPPORTED;
1091 if ((md->flags & SELF_SIGNED_OK) == 0) {
1092 hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1093 "Algorithm %s not trusted for self signatures",
1094 md->name);
1095 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1097 return 0;
1101 HX509_LIB_FUNCTION int HX509_LIB_CALL
1102 _hx509_verify_signature(hx509_context context,
1103 const hx509_cert cert,
1104 const AlgorithmIdentifier *alg,
1105 const heim_octet_string *data,
1106 const heim_octet_string *sig)
1108 const struct signature_alg *md;
1109 const Certificate *signer = NULL;
1111 if (cert)
1112 signer = _hx509_get_cert(cert);
1114 md = _hx509_find_sig_alg(&alg->algorithm);
1115 if (md == NULL) {
1116 hx509_clear_error_string(context);
1117 return HX509_SIG_ALG_NO_SUPPORTED;
1119 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1120 hx509_clear_error_string(context);
1121 return HX509_CRYPTO_SIG_NO_CONF;
1123 if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1124 hx509_clear_error_string(context);
1125 return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1127 if (md->key_oid && signer) {
1128 const SubjectPublicKeyInfo *spi;
1129 spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1131 if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
1132 hx509_clear_error_string(context);
1133 return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
1136 return (*md->verify_signature)(context, md, signer, alg, data, sig);
1139 HX509_LIB_FUNCTION int HX509_LIB_CALL
1140 _hx509_create_signature(hx509_context context,
1141 const hx509_private_key signer,
1142 const AlgorithmIdentifier *alg,
1143 const heim_octet_string *data,
1144 AlgorithmIdentifier *signatureAlgorithm,
1145 heim_octet_string *sig)
1147 const struct signature_alg *md;
1149 md = _hx509_find_sig_alg(&alg->algorithm);
1150 if (md == NULL) {
1151 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1152 "algorithm no supported");
1153 return HX509_SIG_ALG_NO_SUPPORTED;
1156 if (signer && (md->flags & PROVIDE_CONF) == 0) {
1157 hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1158 "algorithm provides no conf");
1159 return HX509_CRYPTO_SIG_NO_CONF;
1162 return (*md->create_signature)(context, md, signer, alg, data,
1163 signatureAlgorithm, sig);
1166 HX509_LIB_FUNCTION int HX509_LIB_CALL
1167 _hx509_create_signature_bitstring(hx509_context context,
1168 const hx509_private_key signer,
1169 const AlgorithmIdentifier *alg,
1170 const heim_octet_string *data,
1171 AlgorithmIdentifier *signatureAlgorithm,
1172 heim_bit_string *sig)
1174 heim_octet_string os;
1175 int ret;
1177 ret = _hx509_create_signature(context, signer, alg,
1178 data, signatureAlgorithm, &os);
1179 if (ret)
1180 return ret;
1181 sig->data = os.data;
1182 sig->length = os.length * 8;
1183 return 0;
1186 HX509_LIB_FUNCTION int HX509_LIB_CALL
1187 _hx509_public_encrypt(hx509_context context,
1188 const heim_octet_string *cleartext,
1189 const Certificate *cert,
1190 heim_oid *encryption_oid,
1191 heim_octet_string *ciphertext)
1193 const SubjectPublicKeyInfo *spi;
1194 unsigned char *to;
1195 int tosize;
1196 int ret;
1197 RSA *rsa;
1198 size_t size;
1199 const unsigned char *p;
1201 ciphertext->data = NULL;
1202 ciphertext->length = 0;
1204 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1206 p = spi->subjectPublicKey.data;
1207 size = spi->subjectPublicKey.length / 8;
1209 rsa = d2i_RSAPublicKey(NULL, &p, size);
1210 if (rsa == NULL) {
1211 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1212 return ENOMEM;
1215 tosize = RSA_size(rsa);
1216 to = malloc(tosize);
1217 if (to == NULL) {
1218 RSA_free(rsa);
1219 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1220 return ENOMEM;
1223 ret = RSA_public_encrypt(cleartext->length,
1224 (unsigned char *)cleartext->data,
1225 to, rsa, RSA_PKCS1_PADDING);
1226 RSA_free(rsa);
1227 if (ret <= 0) {
1228 free(to);
1229 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
1230 "RSA public encrypt failed with %d", ret);
1231 return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
1233 if (ret > tosize)
1234 _hx509_abort("internal rsa decryption failure: ret > tosize");
1236 ciphertext->length = ret;
1237 ciphertext->data = to;
1239 ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
1240 if (ret) {
1241 der_free_octet_string(ciphertext);
1242 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1243 return ENOMEM;
1246 return 0;
1249 HX509_LIB_FUNCTION int HX509_LIB_CALL
1250 hx509_private_key_private_decrypt(hx509_context context,
1251 const heim_octet_string *ciphertext,
1252 const heim_oid *encryption_oid,
1253 hx509_private_key p,
1254 heim_octet_string *cleartext)
1256 int ret;
1258 cleartext->data = NULL;
1259 cleartext->length = 0;
1261 if (p->private_key.rsa == NULL) {
1262 hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1263 "Private RSA key missing");
1264 return HX509_PRIVATE_KEY_MISSING;
1267 cleartext->length = RSA_size(p->private_key.rsa);
1268 cleartext->data = malloc(cleartext->length);
1269 if (cleartext->data == NULL) {
1270 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1271 return ENOMEM;
1273 ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
1274 cleartext->data,
1275 p->private_key.rsa,
1276 RSA_PKCS1_PADDING);
1277 if (ret <= 0) {
1278 der_free_octet_string(cleartext);
1279 hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
1280 "Failed to decrypt using private key: %d", ret);
1281 return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
1283 if (cleartext->length < (size_t)ret)
1284 _hx509_abort("internal rsa decryption failure: ret > tosize");
1286 cleartext->length = ret;
1288 return 0;
1292 HX509_LIB_FUNCTION int HX509_LIB_CALL
1293 hx509_parse_private_key(hx509_context context,
1294 const AlgorithmIdentifier *keyai,
1295 const void *data,
1296 size_t len,
1297 hx509_key_format_t format,
1298 hx509_private_key *private_key)
1300 struct hx509_private_key_ops *ops;
1301 int ret;
1303 *private_key = NULL;
1305 if (format == HX509_KEY_FORMAT_PKCS8) {
1306 PKCS8PrivateKeyInfo ki;
1307 hx509_private_key key;
1309 ret = decode_PKCS8PrivateKeyInfo(data, len, &ki, NULL);
1310 if (ret) {
1311 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1312 "Failed to parse PKCS#8-encoded private "
1313 "key");
1314 return HX509_PARSING_KEY_FAILED;
1317 /* Re-enter to parse DER-encoded key from PKCS#8 envelope */
1318 ret = hx509_parse_private_key(context, &ki.privateKeyAlgorithm,
1319 ki.privateKey.data, ki.privateKey.length,
1320 HX509_KEY_FORMAT_DER, &key);
1321 free_PKCS8PrivateKeyInfo(&ki);
1322 if (ret) {
1323 hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1324 "Failed to parse RSA key from PKCS#8 "
1325 "envelope");
1326 return HX509_PARSING_KEY_FAILED;
1329 *private_key = key;
1330 return ret;
1333 ops = hx509_find_private_alg(&keyai->algorithm);
1334 if (ops == NULL) {
1335 hx509_clear_error_string(context);
1336 return HX509_SIG_ALG_NO_SUPPORTED;
1339 ret = hx509_private_key_init(private_key, ops, NULL);
1340 if (ret) {
1341 hx509_set_error_string(context, 0, ret, "out of memory");
1342 return ret;
1345 ret = (*ops->import)(context, keyai, data, len, format, *private_key);
1346 if (ret)
1347 hx509_private_key_free(private_key);
1349 return ret;
1356 HX509_LIB_FUNCTION int HX509_LIB_CALL
1357 hx509_private_key2SPKI(hx509_context context,
1358 hx509_private_key private_key,
1359 SubjectPublicKeyInfo *spki)
1361 const struct hx509_private_key_ops *ops = private_key->ops;
1362 if (ops == NULL || ops->get_spki == NULL) {
1363 hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1364 "Private key have no key2SPKI function");
1365 return HX509_UNIMPLEMENTED_OPERATION;
1367 return (*ops->get_spki)(context, private_key, spki);
1370 HX509_LIB_FUNCTION int HX509_LIB_CALL
1371 _hx509_generate_private_key_init(hx509_context context,
1372 const heim_oid *oid,
1373 struct hx509_generate_private_context **ctx)
1375 *ctx = NULL;
1377 if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
1378 hx509_set_error_string(context, 0, EINVAL,
1379 "private key not an RSA key");
1380 return EINVAL;
1383 *ctx = calloc(1, sizeof(**ctx));
1384 if (*ctx == NULL) {
1385 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1386 return ENOMEM;
1388 (*ctx)->key_oid = oid;
1390 return 0;
1393 HX509_LIB_FUNCTION int HX509_LIB_CALL
1394 _hx509_generate_private_key_is_ca(hx509_context context,
1395 struct hx509_generate_private_context *ctx)
1397 ctx->isCA = 1;
1398 return 0;
1401 HX509_LIB_FUNCTION int HX509_LIB_CALL
1402 _hx509_generate_private_key_bits(hx509_context context,
1403 struct hx509_generate_private_context *ctx,
1404 unsigned long bits)
1406 ctx->num_bits = bits;
1407 return 0;
1411 HX509_LIB_FUNCTION void HX509_LIB_CALL
1412 _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1414 free(*ctx);
1415 *ctx = NULL;
1418 HX509_LIB_FUNCTION int HX509_LIB_CALL
1419 _hx509_generate_private_key(hx509_context context,
1420 struct hx509_generate_private_context *ctx,
1421 hx509_private_key *private_key)
1423 struct hx509_private_key_ops *ops;
1424 int ret;
1426 *private_key = NULL;
1428 ops = hx509_find_private_alg(ctx->key_oid);
1429 if (ops == NULL) {
1430 hx509_clear_error_string(context);
1431 return HX509_SIG_ALG_NO_SUPPORTED;
1434 ret = hx509_private_key_init(private_key, ops, NULL);
1435 if (ret) {
1436 hx509_set_error_string(context, 0, ret, "out of memory");
1437 return ret;
1440 ret = (*ops->generate_private_key)(context, ctx, *private_key);
1441 if (ret)
1442 hx509_private_key_free(private_key);
1444 return ret;
1451 const AlgorithmIdentifier *
1452 hx509_signature_sha512(void)
1453 { return &_hx509_signature_sha512_data; }
1455 const AlgorithmIdentifier *
1456 hx509_signature_sha384(void)
1457 { return &_hx509_signature_sha384_data; }
1459 const AlgorithmIdentifier *
1460 hx509_signature_sha256(void)
1461 { return &_hx509_signature_sha256_data; }
1463 const AlgorithmIdentifier *
1464 hx509_signature_sha1(void)
1465 { return &_hx509_signature_sha1_data; }
1467 const AlgorithmIdentifier *
1468 hx509_signature_md5(void)
1469 { return &_hx509_signature_md5_data; }
1471 const AlgorithmIdentifier *
1472 hx509_signature_rsa_with_sha512(void)
1473 { return &_hx509_signature_rsa_with_sha512_data; }
1475 const AlgorithmIdentifier *
1476 hx509_signature_rsa_with_sha384(void)
1477 { return &_hx509_signature_rsa_with_sha384_data; }
1479 const AlgorithmIdentifier *
1480 hx509_signature_rsa_with_sha256(void)
1481 { return &_hx509_signature_rsa_with_sha256_data; }
1483 const AlgorithmIdentifier *
1484 hx509_signature_rsa_with_sha1(void)
1485 { return &_hx509_signature_rsa_with_sha1_data; }
1487 const AlgorithmIdentifier *
1488 hx509_signature_rsa_with_md5(void)
1489 { return &_hx509_signature_rsa_with_md5_data; }
1491 const AlgorithmIdentifier *
1492 hx509_signature_rsa(void)
1493 { return &_hx509_signature_rsa_data; }
1495 const AlgorithmIdentifier *
1496 hx509_signature_rsa_pkcs1_x509(void)
1497 { return &_hx509_signature_rsa_pkcs1_x509_data; }
1499 const AlgorithmIdentifier *
1500 hx509_crypto_des_rsdi_ede3_cbc(void)
1501 { return &_hx509_des_rsdi_ede3_cbc_oid; }
1503 const AlgorithmIdentifier *
1504 hx509_crypto_aes128_cbc(void)
1505 { return &_hx509_crypto_aes128_cbc_data; }
1507 const AlgorithmIdentifier *
1508 hx509_crypto_aes256_cbc(void)
1509 { return &_hx509_crypto_aes256_cbc_data; }
1515 const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
1516 &_hx509_signature_rsa_with_sha256_data;
1517 const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
1518 &_hx509_signature_sha256_data;
1519 const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
1520 &_hx509_crypto_aes128_cbc_data;
1526 HX509_LIB_FUNCTION int HX509_LIB_CALL
1527 hx509_private_key_init(hx509_private_key *key,
1528 hx509_private_key_ops *ops,
1529 void *keydata)
1531 *key = calloc(1, sizeof(**key));
1532 if (*key == NULL)
1533 return ENOMEM;
1534 (*key)->ref = 1;
1535 (*key)->ops = ops;
1536 (*key)->private_key.keydata = keydata;
1537 return 0;
1540 HX509_LIB_FUNCTION hx509_private_key HX509_LIB_CALL
1541 _hx509_private_key_ref(hx509_private_key key)
1543 if (key->ref == 0)
1544 _hx509_abort("key refcount <= 0 on ref");
1545 key->ref++;
1546 if (key->ref == UINT_MAX)
1547 _hx509_abort("key refcount == UINT_MAX on ref");
1548 return key;
1551 HX509_LIB_FUNCTION const char * HX509_LIB_CALL
1552 _hx509_private_pem_name(hx509_private_key key)
1554 return key->ops->pemtype;
1557 HX509_LIB_FUNCTION int HX509_LIB_CALL
1558 hx509_private_key_free(hx509_private_key *key)
1560 if (key == NULL || *key == NULL)
1561 return 0;
1563 if ((*key)->ref == 0)
1564 _hx509_abort("key refcount == 0 on free");
1565 if (--(*key)->ref > 0)
1566 return 0;
1568 if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
1569 if ((*key)->private_key.rsa)
1570 RSA_free((*key)->private_key.rsa);
1571 } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid,
1572 ASN1_OID_ID_ECPUBLICKEY) == 0 &&
1573 (*key)->private_key.ecdsa != NULL) {
1574 _hx509_private_eckey_free((*key)->private_key.ecdsa);
1576 (*key)->private_key.rsa = NULL;
1577 free(*key);
1578 *key = NULL;
1579 return 0;
1582 HX509_LIB_FUNCTION void HX509_LIB_CALL
1583 hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
1585 if (key->private_key.rsa)
1586 RSA_free(key->private_key.rsa);
1587 key->private_key.rsa = ptr;
1588 key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
1589 key->md = &pkcs1_rsa_sha1_alg;
1592 HX509_LIB_FUNCTION int HX509_LIB_CALL
1593 _hx509_private_key_oid(hx509_context context,
1594 const hx509_private_key key,
1595 heim_oid *data)
1597 int ret;
1598 ret = der_copy_oid(key->ops->key_oid, data);
1599 if (ret)
1600 hx509_set_error_string(context, 0, ret, "malloc out of memory");
1601 return ret;
1604 HX509_LIB_FUNCTION int HX509_LIB_CALL
1605 _hx509_private_key_exportable(hx509_private_key key)
1607 if (key->ops->export == NULL)
1608 return 0;
1609 return 1;
1612 HX509_LIB_FUNCTION BIGNUM * HX509_LIB_CALL
1613 _hx509_private_key_get_internal(hx509_context context,
1614 hx509_private_key key,
1615 const char *type)
1617 if (key->ops->get_internal == NULL)
1618 return NULL;
1619 return (*key->ops->get_internal)(context, key, type);
1622 HX509_LIB_FUNCTION int HX509_LIB_CALL
1623 _hx509_private_key_export(hx509_context context,
1624 const hx509_private_key key,
1625 hx509_key_format_t format,
1626 heim_octet_string *data)
1628 if (key->ops->export == NULL) {
1629 hx509_clear_error_string(context);
1630 return HX509_UNIMPLEMENTED_OPERATION;
1632 if (format == HX509_KEY_FORMAT_PKCS8) {
1633 PKCS8PrivateKeyInfo ki;
1634 size_t size;
1635 int ret;
1637 memset(&ki, 0, sizeof(ki));
1638 ki.attributes = NULL; /* No localKeyId needed */
1639 ki.privateKey.data = NULL;
1640 ki.privateKeyAlgorithm.algorithm.components = NULL;
1641 ret = der_parse_hex_heim_integer("00", &ki.version);
1642 if (ret == 0)
1643 ret = _hx509_private_key_oid(context, key,
1644 &ki.privateKeyAlgorithm.algorithm);
1645 if (ret == 0)
1646 /* Re-enter */
1647 ret = _hx509_private_key_export(context, key, HX509_KEY_FORMAT_DER,
1648 &ki.privateKey);
1651 * XXX To set ki.privateKeyAlgorithm.parameters we'll need to either
1652 * move this code into the *key->ops->export() functions, or expand
1653 * their signature to allow them to set it for us, or add a method to
1654 * hx509_private_key_ops that allows us to get the parameters from the
1655 * backend.
1657 ki.privateKeyAlgorithm.parameters = NULL;
1659 if (ret == 0)
1660 ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, data->data, data->length,
1661 &ki, &size, ret);
1662 free_PKCS8PrivateKeyInfo(&ki);
1663 if (ret == 0 && size != data->length)
1664 ret = EINVAL;
1665 if (ret)
1666 hx509_set_error_string(context, 0, ret,
1667 "Private key PKCS#8 encoding failed");
1668 return ret;
1670 return (*key->ops->export)(context, key, format, data);
1677 struct hx509cipher {
1678 const char *name;
1679 int flags;
1680 #define CIPHER_WEAK 1
1681 const heim_oid *oid;
1682 const AlgorithmIdentifier *(*ai_func)(void);
1683 const EVP_CIPHER *(*evp_func)(void);
1684 int (*get_params)(hx509_context, const hx509_crypto,
1685 const heim_octet_string *, heim_octet_string *);
1686 int (*set_params)(hx509_context, const heim_octet_string *,
1687 hx509_crypto, heim_octet_string *);
1690 struct hx509_crypto_data {
1691 char *name;
1692 int flags;
1693 #define ALLOW_WEAK 1
1695 #define PADDING_NONE 2
1696 #define PADDING_PKCS7 4
1697 #define PADDING_FLAGS (2|4)
1698 const struct hx509cipher *cipher;
1699 const EVP_CIPHER *c;
1700 heim_octet_string key;
1701 heim_oid oid;
1702 void *param;
1709 static unsigned private_rc2_40_oid_data[] = { 127, 1 };
1711 static heim_oid asn1_oid_private_rc2_40 =
1712 { 2, private_rc2_40_oid_data };
1718 static int
1719 CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
1720 const heim_octet_string *ivec, heim_octet_string *param)
1722 size_t size;
1723 int ret;
1725 assert(crypto->param == NULL);
1726 if (ivec == NULL)
1727 return 0;
1729 ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
1730 ivec, &size, ret);
1731 if (ret == 0 && size != param->length)
1732 _hx509_abort("Internal asn1 encoder failure");
1733 if (ret)
1734 hx509_clear_error_string(context);
1735 return ret;
1738 static int
1739 CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
1740 hx509_crypto crypto, heim_octet_string *ivec)
1742 int ret;
1743 if (ivec == NULL)
1744 return 0;
1746 ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
1747 if (ret)
1748 hx509_clear_error_string(context);
1750 return ret;
1753 struct _RC2_params {
1754 int maximum_effective_key;
1757 static int
1758 CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
1759 const heim_octet_string *ivec, heim_octet_string *param)
1761 CMSRC2CBCParameter rc2params;
1762 const struct _RC2_params *p = crypto->param;
1763 int maximum_effective_key = 128;
1764 size_t size;
1765 int ret;
1767 memset(&rc2params, 0, sizeof(rc2params));
1769 if (p)
1770 maximum_effective_key = p->maximum_effective_key;
1772 switch(maximum_effective_key) {
1773 case 40:
1774 rc2params.rc2ParameterVersion = 160;
1775 break;
1776 case 64:
1777 rc2params.rc2ParameterVersion = 120;
1778 break;
1779 case 128:
1780 rc2params.rc2ParameterVersion = 58;
1781 break;
1783 rc2params.iv = *ivec;
1785 ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
1786 &rc2params, &size, ret);
1787 if (ret == 0 && size != param->length)
1788 _hx509_abort("Internal asn1 encoder failure");
1790 return ret;
1793 static int
1794 CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
1795 hx509_crypto crypto, heim_octet_string *ivec)
1797 CMSRC2CBCParameter rc2param;
1798 struct _RC2_params *p;
1799 size_t size;
1800 int ret;
1802 ret = decode_CMSRC2CBCParameter(param->data, param->length,
1803 &rc2param, &size);
1804 if (ret) {
1805 hx509_clear_error_string(context);
1806 return ret;
1809 p = calloc(1, sizeof(*p));
1810 if (p == NULL) {
1811 free_CMSRC2CBCParameter(&rc2param);
1812 hx509_clear_error_string(context);
1813 return ENOMEM;
1815 switch(rc2param.rc2ParameterVersion) {
1816 case 160:
1817 crypto->c = EVP_rc2_40_cbc();
1818 p->maximum_effective_key = 40;
1819 break;
1820 case 120:
1821 crypto->c = EVP_rc2_64_cbc();
1822 p->maximum_effective_key = 64;
1823 break;
1824 case 58:
1825 crypto->c = EVP_rc2_cbc();
1826 p->maximum_effective_key = 128;
1827 break;
1828 default:
1829 free(p);
1830 free_CMSRC2CBCParameter(&rc2param);
1831 return HX509_CRYPTO_SIG_INVALID_FORMAT;
1833 if (ivec)
1834 ret = der_copy_octet_string(&rc2param.iv, ivec);
1835 free_CMSRC2CBCParameter(&rc2param);
1836 if (ret) {
1837 free(p);
1838 hx509_clear_error_string(context);
1839 } else
1840 crypto->param = p;
1842 return ret;
1849 static const struct hx509cipher ciphers[] = {
1851 "rc2-cbc",
1852 CIPHER_WEAK,
1853 ASN1_OID_ID_PKCS3_RC2_CBC,
1854 NULL,
1855 EVP_rc2_cbc,
1856 CMSRC2CBCParam_get,
1857 CMSRC2CBCParam_set
1860 "rc2-cbc",
1861 CIPHER_WEAK,
1862 ASN1_OID_ID_RSADSI_RC2_CBC,
1863 NULL,
1864 EVP_rc2_cbc,
1865 CMSRC2CBCParam_get,
1866 CMSRC2CBCParam_set
1869 "rc2-40-cbc",
1870 CIPHER_WEAK,
1871 &asn1_oid_private_rc2_40,
1872 NULL,
1873 EVP_rc2_40_cbc,
1874 CMSRC2CBCParam_get,
1875 CMSRC2CBCParam_set
1878 "des-ede3-cbc",
1880 ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
1881 NULL,
1882 EVP_des_ede3_cbc,
1883 CMSCBCParam_get,
1884 CMSCBCParam_set
1887 "des-ede3-cbc",
1889 ASN1_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",
1898 ASN1_OID_ID_AES_128_CBC,
1899 hx509_crypto_aes128_cbc,
1900 EVP_aes_128_cbc,
1901 CMSCBCParam_get,
1902 CMSCBCParam_set
1905 "aes-192-cbc",
1907 ASN1_OID_ID_AES_192_CBC,
1908 NULL,
1909 EVP_aes_192_cbc,
1910 CMSCBCParam_get,
1911 CMSCBCParam_set
1914 "aes-256-cbc",
1916 ASN1_OID_ID_AES_256_CBC,
1917 hx509_crypto_aes256_cbc,
1918 EVP_aes_256_cbc,
1919 CMSCBCParam_get,
1920 CMSCBCParam_set
1924 static const struct hx509cipher *
1925 find_cipher_by_oid(const heim_oid *oid)
1927 size_t i;
1929 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1930 if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
1931 return &ciphers[i];
1933 return NULL;
1936 static const struct hx509cipher *
1937 find_cipher_by_name(const char *name)
1939 size_t i;
1941 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1942 if (strcasecmp(name, ciphers[i].name) == 0)
1943 return &ciphers[i];
1945 return NULL;
1949 HX509_LIB_FUNCTION const heim_oid * HX509_LIB_CALL
1950 hx509_crypto_enctype_by_name(const char *name)
1952 const struct hx509cipher *cipher;
1954 cipher = find_cipher_by_name(name);
1955 if (cipher == NULL)
1956 return NULL;
1957 return cipher->oid;
1960 HX509_LIB_FUNCTION int HX509_LIB_CALL
1961 hx509_crypto_init(hx509_context context,
1962 const char *provider,
1963 const heim_oid *enctype,
1964 hx509_crypto *crypto)
1966 const struct hx509cipher *cipher;
1968 *crypto = NULL;
1970 cipher = find_cipher_by_oid(enctype);
1971 if (cipher == NULL) {
1972 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
1973 "Algorithm not supported");
1974 return HX509_ALG_NOT_SUPP;
1977 *crypto = calloc(1, sizeof(**crypto));
1978 if (*crypto == NULL) {
1979 hx509_clear_error_string(context);
1980 return ENOMEM;
1983 (*crypto)->flags = PADDING_PKCS7;
1984 (*crypto)->cipher = cipher;
1985 (*crypto)->c = (*cipher->evp_func)();
1987 if (der_copy_oid(enctype, &(*crypto)->oid)) {
1988 hx509_crypto_destroy(*crypto);
1989 *crypto = NULL;
1990 hx509_clear_error_string(context);
1991 return ENOMEM;
1994 return 0;
1997 HX509_LIB_FUNCTION const char * HX509_LIB_CALL
1998 hx509_crypto_provider(hx509_crypto crypto)
2000 return "unknown";
2003 HX509_LIB_FUNCTION void HX509_LIB_CALL
2004 hx509_crypto_destroy(hx509_crypto crypto)
2006 if (crypto->name)
2007 free(crypto->name);
2008 if (crypto->key.data)
2009 free(crypto->key.data);
2010 if (crypto->param)
2011 free(crypto->param);
2012 der_free_oid(&crypto->oid);
2013 memset(crypto, 0, sizeof(*crypto));
2014 free(crypto);
2017 HX509_LIB_FUNCTION int HX509_LIB_CALL
2018 hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2020 return 0;
2023 HX509_LIB_FUNCTION void HX509_LIB_CALL
2024 hx509_crypto_allow_weak(hx509_crypto crypto)
2026 crypto->flags |= ALLOW_WEAK;
2029 HX509_LIB_FUNCTION void HX509_LIB_CALL
2030 hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
2032 switch (padding_type) {
2033 case HX509_CRYPTO_PADDING_PKCS7:
2034 crypto->flags &= ~PADDING_FLAGS;
2035 crypto->flags |= PADDING_PKCS7;
2036 break;
2037 case HX509_CRYPTO_PADDING_NONE:
2038 crypto->flags &= ~PADDING_FLAGS;
2039 crypto->flags |= PADDING_NONE;
2040 break;
2041 default:
2042 _hx509_abort("Invalid padding");
2046 HX509_LIB_FUNCTION int HX509_LIB_CALL
2047 hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2049 if (EVP_CIPHER_key_length(crypto->c) > (int)length)
2050 return HX509_CRYPTO_INTERNAL_ERROR;
2052 if (crypto->key.data) {
2053 free(crypto->key.data);
2054 crypto->key.data = NULL;
2055 crypto->key.length = 0;
2057 crypto->key.data = malloc(length);
2058 if (crypto->key.data == NULL)
2059 return ENOMEM;
2060 memcpy(crypto->key.data, data, length);
2061 crypto->key.length = length;
2063 return 0;
2066 HX509_LIB_FUNCTION int HX509_LIB_CALL
2067 hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2069 if (crypto->key.data) {
2070 free(crypto->key.data);
2071 crypto->key.length = 0;
2074 crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2075 crypto->key.data = malloc(crypto->key.length);
2076 if (crypto->key.data == NULL) {
2077 crypto->key.length = 0;
2078 return ENOMEM;
2080 if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2081 free(crypto->key.data);
2082 crypto->key.data = NULL;
2083 crypto->key.length = 0;
2084 return HX509_CRYPTO_INTERNAL_ERROR;
2086 if (key)
2087 return der_copy_octet_string(&crypto->key, key);
2088 else
2089 return 0;
2092 HX509_LIB_FUNCTION int HX509_LIB_CALL
2093 hx509_crypto_set_params(hx509_context context,
2094 hx509_crypto crypto,
2095 const heim_octet_string *param,
2096 heim_octet_string *ivec)
2098 return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2101 HX509_LIB_FUNCTION int HX509_LIB_CALL
2102 hx509_crypto_get_params(hx509_context context,
2103 hx509_crypto crypto,
2104 const heim_octet_string *ivec,
2105 heim_octet_string *param)
2107 return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2110 HX509_LIB_FUNCTION int HX509_LIB_CALL
2111 hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2113 ivec->length = EVP_CIPHER_iv_length(crypto->c);
2114 ivec->data = malloc(ivec->length);
2115 if (ivec->data == NULL) {
2116 ivec->length = 0;
2117 return ENOMEM;
2120 if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2121 free(ivec->data);
2122 ivec->data = NULL;
2123 ivec->length = 0;
2124 return HX509_CRYPTO_INTERNAL_ERROR;
2126 return 0;
2129 HX509_LIB_FUNCTION int HX509_LIB_CALL
2130 hx509_crypto_encrypt(hx509_crypto crypto,
2131 const void *data,
2132 const size_t length,
2133 const heim_octet_string *ivec,
2134 heim_octet_string **ciphertext)
2136 EVP_CIPHER_CTX evp;
2137 size_t padsize, bsize;
2138 int ret;
2140 *ciphertext = NULL;
2142 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2143 (crypto->flags & ALLOW_WEAK) == 0)
2144 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2146 assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
2148 EVP_CIPHER_CTX_init(&evp);
2150 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2151 crypto->key.data, ivec->data, 1);
2152 if (ret != 1) {
2153 EVP_CIPHER_CTX_cleanup(&evp);
2154 ret = HX509_CRYPTO_INTERNAL_ERROR;
2155 goto out;
2158 *ciphertext = calloc(1, sizeof(**ciphertext));
2159 if (*ciphertext == NULL) {
2160 ret = ENOMEM;
2161 goto out;
2164 assert(crypto->flags & PADDING_FLAGS);
2166 bsize = EVP_CIPHER_block_size(crypto->c);
2167 padsize = 0;
2169 if (crypto->flags & PADDING_NONE) {
2170 if (bsize != 1 && (length % bsize) != 0)
2171 return HX509_CMS_PADDING_ERROR;
2172 } else if (crypto->flags & PADDING_PKCS7) {
2173 if (bsize != 1)
2174 padsize = bsize - (length % bsize);
2177 (*ciphertext)->length = length + padsize;
2178 (*ciphertext)->data = malloc(length + padsize);
2179 if ((*ciphertext)->data == NULL) {
2180 ret = ENOMEM;
2181 goto out;
2184 memcpy((*ciphertext)->data, data, length);
2185 if (padsize) {
2186 size_t i;
2187 unsigned char *p = (*ciphertext)->data;
2188 p += length;
2189 for (i = 0; i < padsize; i++)
2190 *p++ = padsize;
2193 ret = EVP_Cipher(&evp, (*ciphertext)->data,
2194 (*ciphertext)->data,
2195 length + padsize);
2196 if (ret != 1) {
2197 ret = HX509_CRYPTO_INTERNAL_ERROR;
2198 goto out;
2200 ret = 0;
2202 out:
2203 if (ret) {
2204 if (*ciphertext) {
2205 if ((*ciphertext)->data) {
2206 free((*ciphertext)->data);
2208 free(*ciphertext);
2209 *ciphertext = NULL;
2212 EVP_CIPHER_CTX_cleanup(&evp);
2214 return ret;
2217 HX509_LIB_FUNCTION int HX509_LIB_CALL
2218 hx509_crypto_decrypt(hx509_crypto crypto,
2219 const void *data,
2220 const size_t length,
2221 heim_octet_string *ivec,
2222 heim_octet_string *clear)
2224 EVP_CIPHER_CTX evp;
2225 void *idata = NULL;
2226 int ret;
2228 clear->data = NULL;
2229 clear->length = 0;
2231 if ((crypto->cipher->flags & CIPHER_WEAK) &&
2232 (crypto->flags & ALLOW_WEAK) == 0)
2233 return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2235 if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length)
2236 return HX509_CRYPTO_INTERNAL_ERROR;
2238 if (crypto->key.data == NULL)
2239 return HX509_CRYPTO_INTERNAL_ERROR;
2241 if (ivec)
2242 idata = ivec->data;
2244 EVP_CIPHER_CTX_init(&evp);
2246 ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2247 crypto->key.data, idata, 0);
2248 if (ret != 1) {
2249 EVP_CIPHER_CTX_cleanup(&evp);
2250 return HX509_CRYPTO_INTERNAL_ERROR;
2253 clear->length = length;
2254 clear->data = malloc(length);
2255 if (clear->data == NULL) {
2256 EVP_CIPHER_CTX_cleanup(&evp);
2257 clear->length = 0;
2258 return ENOMEM;
2261 if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2262 return HX509_CRYPTO_INTERNAL_ERROR;
2264 EVP_CIPHER_CTX_cleanup(&evp);
2266 if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
2267 int padsize;
2268 unsigned char *p;
2269 int j, bsize = EVP_CIPHER_block_size(crypto->c);
2271 if ((int)clear->length < bsize) {
2272 ret = HX509_CMS_PADDING_ERROR;
2273 goto out;
2276 p = clear->data;
2277 p += clear->length - 1;
2278 padsize = *p;
2279 if (padsize > bsize) {
2280 ret = HX509_CMS_PADDING_ERROR;
2281 goto out;
2283 clear->length -= padsize;
2284 for (j = 0; j < padsize; j++) {
2285 if (*p-- != padsize) {
2286 ret = HX509_CMS_PADDING_ERROR;
2287 goto out;
2292 return 0;
2294 out:
2295 if (clear->data)
2296 free(clear->data);
2297 clear->data = NULL;
2298 clear->length = 0;
2299 return ret;
2302 typedef int (*PBE_string2key_func)(hx509_context,
2303 const char *,
2304 const heim_octet_string *,
2305 hx509_crypto *, heim_octet_string *,
2306 heim_octet_string *,
2307 const heim_oid *, const EVP_MD *);
2309 static int
2310 PBE_string2key(hx509_context context,
2311 const char *password,
2312 const heim_octet_string *parameters,
2313 hx509_crypto *crypto,
2314 heim_octet_string *key, heim_octet_string *iv,
2315 const heim_oid *enc_oid,
2316 const EVP_MD *md)
2318 PKCS12_PBEParams p12params;
2319 int passwordlen;
2320 hx509_crypto c;
2321 int iter, saltlen, ret;
2322 unsigned char *salt;
2324 passwordlen = password ? strlen(password) : 0;
2326 if (parameters == NULL)
2327 return HX509_ALG_NOT_SUPP;
2329 ret = decode_PKCS12_PBEParams(parameters->data,
2330 parameters->length,
2331 &p12params, NULL);
2332 if (ret)
2333 goto out;
2335 if (p12params.iterations)
2336 iter = *p12params.iterations;
2337 else
2338 iter = 1;
2339 salt = p12params.salt.data;
2340 saltlen = p12params.salt.length;
2342 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2343 PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2344 ret = HX509_CRYPTO_INTERNAL_ERROR;
2345 goto out;
2348 if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2349 PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2350 ret = HX509_CRYPTO_INTERNAL_ERROR;
2351 goto out;
2354 ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2355 if (ret)
2356 goto out;
2358 hx509_crypto_allow_weak(c);
2360 ret = hx509_crypto_set_key_data(c, key->data, key->length);
2361 if (ret) {
2362 hx509_crypto_destroy(c);
2363 goto out;
2366 *crypto = c;
2367 out:
2368 free_PKCS12_PBEParams(&p12params);
2369 return ret;
2372 static const heim_oid *
2373 find_string2key(const heim_oid *oid,
2374 const EVP_CIPHER **c,
2375 const EVP_MD **md,
2376 PBE_string2key_func *s2k)
2378 if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
2379 *c = EVP_rc2_40_cbc();
2380 if (*c == NULL)
2381 return NULL;
2382 *md = EVP_sha1();
2383 if (*md == NULL)
2384 return NULL;
2385 *s2k = PBE_string2key;
2386 return &asn1_oid_private_rc2_40;
2387 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
2388 *c = EVP_rc2_cbc();
2389 if (*c == NULL)
2390 return NULL;
2391 *md = EVP_sha1();
2392 if (*md == NULL)
2393 return NULL;
2394 *s2k = PBE_string2key;
2395 return ASN1_OID_ID_PKCS3_RC2_CBC;
2396 #if 0
2397 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
2398 *c = EVP_rc4_40();
2399 if (*c == NULL)
2400 return NULL;
2401 *md = EVP_sha1();
2402 if (*md == NULL)
2403 return NULL;
2404 *s2k = PBE_string2key;
2405 return NULL;
2406 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
2407 *c = EVP_rc4();
2408 if (*c == NULL)
2409 return NULL;
2410 *md = EVP_sha1();
2411 if (*md == NULL)
2412 return NULL;
2413 *s2k = PBE_string2key;
2414 return ASN1_OID_ID_PKCS3_RC4;
2415 #endif
2416 } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
2417 *c = EVP_des_ede3_cbc();
2418 if (*c == NULL)
2419 return NULL;
2420 *md = EVP_sha1();
2421 if (*md == NULL)
2422 return NULL;
2423 *s2k = PBE_string2key;
2424 return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
2427 return NULL;
2434 HX509_LIB_FUNCTION int HX509_LIB_CALL
2435 _hx509_pbe_encrypt(hx509_context context,
2436 hx509_lock lock,
2437 const AlgorithmIdentifier *ai,
2438 const heim_octet_string *content,
2439 heim_octet_string *econtent)
2441 hx509_clear_error_string(context);
2442 return EINVAL;
2449 HX509_LIB_FUNCTION int HX509_LIB_CALL
2450 _hx509_pbe_decrypt(hx509_context context,
2451 hx509_lock lock,
2452 const AlgorithmIdentifier *ai,
2453 const heim_octet_string *econtent,
2454 heim_octet_string *content)
2456 const struct _hx509_password *pw;
2457 heim_octet_string key, iv;
2458 const heim_oid *enc_oid;
2459 const EVP_CIPHER *c;
2460 const EVP_MD *md;
2461 PBE_string2key_func s2k;
2462 int ret = 0;
2463 size_t i;
2465 memset(&key, 0, sizeof(key));
2466 memset(&iv, 0, sizeof(iv));
2468 memset(content, 0, sizeof(*content));
2470 enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2471 if (enc_oid == NULL) {
2472 hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2473 "String to key algorithm not supported");
2474 ret = HX509_ALG_NOT_SUPP;
2475 goto out;
2478 key.length = EVP_CIPHER_key_length(c);
2479 key.data = malloc(key.length);
2480 if (key.data == NULL) {
2481 ret = ENOMEM;
2482 hx509_clear_error_string(context);
2483 goto out;
2486 iv.length = EVP_CIPHER_iv_length(c);
2487 iv.data = malloc(iv.length);
2488 if (iv.data == NULL) {
2489 ret = ENOMEM;
2490 hx509_clear_error_string(context);
2491 goto out;
2494 pw = _hx509_lock_get_passwords(lock);
2496 ret = HX509_CRYPTO_INTERNAL_ERROR;
2497 for (i = 0; i < pw->len + 1; i++) {
2498 hx509_crypto crypto;
2499 const char *password;
2501 if (i < pw->len)
2502 password = pw->val[i];
2503 else if (i < pw->len + 1)
2504 password = "";
2505 else
2506 password = NULL;
2508 ret = (*s2k)(context, password, ai->parameters, &crypto,
2509 &key, &iv, enc_oid, md);
2510 if (ret)
2511 goto out;
2513 ret = hx509_crypto_decrypt(crypto,
2514 econtent->data,
2515 econtent->length,
2516 &iv,
2517 content);
2518 hx509_crypto_destroy(crypto);
2519 if (ret == 0)
2520 goto out;
2523 out:
2524 if (key.data)
2525 der_free_octet_string(&key);
2526 if (iv.data)
2527 der_free_octet_string(&iv);
2528 return ret;
2536 static int
2537 match_keys_rsa(hx509_cert c, hx509_private_key private_key)
2539 const Certificate *cert;
2540 const SubjectPublicKeyInfo *spi;
2541 RSAPublicKey pk;
2542 RSA *rsa;
2543 size_t size;
2544 int ret;
2546 if (private_key->private_key.rsa == NULL)
2547 return 0;
2549 rsa = private_key->private_key.rsa;
2550 if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2551 return 0;
2553 cert = _hx509_get_cert(c);
2554 spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2556 rsa = RSA_new();
2557 if (rsa == NULL)
2558 return 0;
2560 ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2561 spi->subjectPublicKey.length / 8,
2562 &pk, &size);
2563 if (ret) {
2564 RSA_free(rsa);
2565 return 0;
2567 rsa->n = heim_int2BN(&pk.modulus);
2568 rsa->e = heim_int2BN(&pk.publicExponent);
2570 free_RSAPublicKey(&pk);
2572 rsa->d = BN_dup(private_key->private_key.rsa->d);
2573 rsa->p = BN_dup(private_key->private_key.rsa->p);
2574 rsa->q = BN_dup(private_key->private_key.rsa->q);
2575 rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
2576 rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
2577 rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
2579 if (rsa->n == NULL || rsa->e == NULL ||
2580 rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
2581 rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
2582 RSA_free(rsa);
2583 return 0;
2586 ret = RSA_check_key(rsa);
2587 RSA_free(rsa);
2589 return ret == 1;
2592 static int
2593 match_keys_ec(hx509_cert c, hx509_private_key private_key)
2595 return 1; /* XXX use EC_KEY_check_key */
2599 HX509_LIB_FUNCTION int HX509_LIB_CALL
2600 _hx509_match_keys(hx509_cert c, hx509_private_key key)
2602 if (!key->ops)
2603 return 0;
2604 if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
2605 return match_keys_rsa(c, key);
2606 if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
2607 return match_keys_ec(c, key);
2608 return 0;
2613 static const heim_oid *
2614 find_keytype(const hx509_private_key key)
2616 const struct signature_alg *md;
2618 if (key == NULL)
2619 return NULL;
2621 md = _hx509_find_sig_alg(key->signature_alg);
2622 if (md == NULL)
2623 return NULL;
2624 return md->key_oid;
2627 HX509_LIB_FUNCTION int HX509_LIB_CALL
2628 hx509_crypto_select(const hx509_context context,
2629 int type,
2630 const hx509_private_key source,
2631 hx509_peer_info peer,
2632 AlgorithmIdentifier *selected)
2634 const AlgorithmIdentifier *def = NULL;
2635 size_t i, j;
2636 int ret, bits;
2638 memset(selected, 0, sizeof(*selected));
2640 if (type == HX509_SELECT_DIGEST) {
2641 bits = SIG_DIGEST;
2642 if (source)
2643 def = alg_for_privatekey(source, type);
2644 if (def == NULL)
2645 def = _hx509_crypto_default_digest_alg;
2646 } else if (type == HX509_SELECT_PUBLIC_SIG) {
2647 bits = SIG_PUBLIC_SIG;
2648 /* XXX depend on `source´ and `peer´ */
2649 if (source)
2650 def = alg_for_privatekey(source, type);
2651 if (def == NULL)
2652 def = _hx509_crypto_default_sig_alg;
2653 } else if (type == HX509_SELECT_SECRET_ENC) {
2654 bits = SIG_SECRET;
2655 def = _hx509_crypto_default_secret_alg;
2656 } else {
2657 hx509_set_error_string(context, 0, EINVAL,
2658 "Unknown type %d of selection", type);
2659 return EINVAL;
2662 if (peer) {
2663 const heim_oid *keytype = NULL;
2665 keytype = find_keytype(source);
2667 for (i = 0; i < peer->len; i++) {
2668 for (j = 0; sig_algs[j]; j++) {
2669 if ((sig_algs[j]->flags & bits) != bits)
2670 continue;
2671 if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
2672 &peer->val[i].algorithm) != 0)
2673 continue;
2674 if (keytype && sig_algs[j]->key_oid &&
2675 der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
2676 continue;
2678 /* found one, use that */
2679 ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
2680 if (ret)
2681 hx509_clear_error_string(context);
2682 return ret;
2684 if (bits & SIG_SECRET) {
2685 const struct hx509cipher *cipher;
2687 cipher = find_cipher_by_oid(&peer->val[i].algorithm);
2688 if (cipher == NULL)
2689 continue;
2690 if (cipher->ai_func == NULL)
2691 continue;
2692 ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
2693 if (ret)
2694 hx509_clear_error_string(context);
2695 return ret;
2700 /* use default */
2701 ret = copy_AlgorithmIdentifier(def, selected);
2702 if (ret)
2703 hx509_clear_error_string(context);
2704 return ret;
2707 HX509_LIB_FUNCTION int HX509_LIB_CALL
2708 hx509_crypto_available(hx509_context context,
2709 int type,
2710 hx509_cert source,
2711 AlgorithmIdentifier **val,
2712 unsigned int *plen)
2714 const heim_oid *keytype = NULL;
2715 unsigned int len, i;
2716 void *ptr;
2717 int bits, ret;
2719 *val = NULL;
2721 if (type == HX509_SELECT_ALL) {
2722 bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
2723 } else if (type == HX509_SELECT_DIGEST) {
2724 bits = SIG_DIGEST;
2725 } else if (type == HX509_SELECT_PUBLIC_SIG) {
2726 bits = SIG_PUBLIC_SIG;
2727 } else {
2728 hx509_set_error_string(context, 0, EINVAL,
2729 "Unknown type %d of available", type);
2730 return EINVAL;
2733 if (source)
2734 keytype = find_keytype(_hx509_cert_private_key(source));
2736 len = 0;
2737 for (i = 0; sig_algs[i]; i++) {
2738 if ((sig_algs[i]->flags & bits) == 0)
2739 continue;
2740 if (sig_algs[i]->sig_alg == NULL)
2741 continue;
2742 if (keytype && sig_algs[i]->key_oid &&
2743 der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
2744 continue;
2746 /* found one, add that to the list */
2747 ptr = realloc(*val, sizeof(**val) * (len + 1));
2748 if (ptr == NULL)
2749 goto out;
2750 *val = ptr;
2752 ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
2753 if (ret)
2754 goto out;
2755 len++;
2758 /* Add AES */
2759 if (bits & SIG_SECRET) {
2761 for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
2763 if (ciphers[i].flags & CIPHER_WEAK)
2764 continue;
2765 if (ciphers[i].ai_func == NULL)
2766 continue;
2768 ptr = realloc(*val, sizeof(**val) * (len + 1));
2769 if (ptr == NULL)
2770 goto out;
2771 *val = ptr;
2773 ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
2774 if (ret)
2775 goto out;
2776 len++;
2780 *plen = len;
2781 return 0;
2783 out:
2784 for (i = 0; i < len; i++)
2785 free_AlgorithmIdentifier(&(*val)[i]);
2786 free(*val);
2787 *val = NULL;
2788 hx509_set_error_string(context, 0, ENOMEM, "out of memory");
2789 return ENOMEM;
2792 HX509_LIB_FUNCTION void HX509_LIB_CALL
2793 hx509_crypto_free_algs(AlgorithmIdentifier *val,
2794 unsigned int len)
2796 unsigned int i;
2797 for (i = 0; i < len; i++)
2798 free_AlgorithmIdentifier(&val[i]);
2799 free(val);