2 * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
35 __RCSID("$Heimdal: crypto.c 22435 2008-01-14 20:53:56Z lha $"
46 struct hx509_generate_private_context
{
47 const heim_oid
*key_oid
;
49 unsigned long num_bits
;
52 struct hx509_private_key_ops
{
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
,
61 int (*import
)(hx509_context
,
64 hx509_private_key private_key
);
65 int (*generate_private_key
)(hx509_context
,
66 struct hx509_generate_private_context
*,
68 BIGNUM
*(*get_internal
)(hx509_context
, hx509_private_key
, const char *);
69 int (*handle_alg
)(const hx509_private_key
,
70 const AlgorithmIdentifier
*,
72 int (*sign
)(hx509_context context
,
73 const hx509_private_key
,
74 const AlgorithmIdentifier
*,
75 const heim_octet_string
*,
76 AlgorithmIdentifier
*,
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
*,
90 struct hx509_private_key
{
92 const struct signature_alg
*md
;
93 const heim_oid
*signature_alg
;
98 /* new crypto layer */
99 hx509_private_key_ops
*ops
;
106 struct signature_alg
{
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);
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
*,
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
*);
143 heim_int2BN(const heim_integer
*i
)
147 bn
= BN_bin2bn(i
->data
, i
->length
, NULL
);
148 BN_set_negative(bn
, i
->negative
);
157 set_digest_alg(DigestAlgorithmIdentifier
*id
,
159 const void *param
, size_t length
)
163 id
->parameters
= malloc(sizeof(*id
->parameters
));
164 if (id
->parameters
== NULL
)
166 id
->parameters
->data
= malloc(length
);
167 if (id
->parameters
->data
== NULL
) {
168 free(id
->parameters
);
169 id
->parameters
= NULL
;
172 memcpy(id
->parameters
->data
, param
, length
);
173 id
->parameters
->length
= length
;
175 id
->parameters
= NULL
;
176 ret
= der_copy_oid(oid
, &id
->algorithm
);
178 if (id
->parameters
) {
179 free(id
->parameters
->data
);
180 free(id
->parameters
);
181 id
->parameters
= NULL
;
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
;
209 memset(&di
, 0, sizeof(di
));
211 spi
= &signer
->tbsCertificate
.subjectPublicKeyInfo
;
215 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
218 ret
= decode_RSAPublicKey(spi
->subjectPublicKey
.data
,
219 spi
->subjectPublicKey
.length
/ 8,
222 hx509_set_error_string(context
, 0, ret
, "Failed to decode RSAPublicKey");
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
) {
233 hx509_set_error_string(context
, 0, ret
, "out of memory");
237 tosize
= RSA_size(rsa
);
241 hx509_set_error_string(context
, 0, ret
, "out of memory");
245 retsize
= RSA_public_decrypt(sig
->length
, (unsigned char *)sig
->data
,
246 to
, rsa
, RSA_PKCS1_PADDING
);
248 ret
= HX509_CRYPTO_SIG_INVALID_FORMAT
;
249 hx509_set_error_string(context
, 0, ret
,
250 "RSA public decrypt failed: %d", retsize
);
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
);
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");
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");
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");
291 ret
= _hx509_verify_signature(context
,
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");
308 free_DigestInfo(&di
);
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
;
329 sig_oid
= &alg
->algorithm
;
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) {
348 return HX509_ALG_NOT_SUPP
;
350 if (signatureAlgorithm
) {
351 ret
= set_digest_alg(signatureAlgorithm
, sig_oid
, "\x05\x00", 2);
353 hx509_clear_error_string(context
);
360 memset(&di
, 0, sizeof(di
));
362 ret
= _hx509_create_signature(context
,
370 ASN1_MALLOC_ENCODE(DigestInfo
,
376 free_DigestInfo(&di
);
378 hx509_set_error_string(context
, 0, ret
, "out of memory");
381 if (indata
.length
!= size
)
382 _hx509_abort("internal ASN.1 encoder error");
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");
395 ret
= RSA_private_encrypt(indata
.length
, indata
.data
,
397 signer
->private_key
.rsa
,
399 if (indata
.data
!= data
->data
)
400 der_free_octet_string(&indata
);
402 ret
= HX509_CMS_FAILED_CREATE_SIGATURE
;
403 hx509_set_error_string(context
, 0, ret
,
404 "RSA private decrypt failed: %d", ret
);
407 if (ret
> sig
->length
)
408 _hx509_abort("RSA signature prelen longer the output len");
416 rsa_private_key_import(hx509_context context
,
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();
436 rsa_private_key2SPKI(hx509_context context
,
437 hx509_private_key private_key
,
438 SubjectPublicKeyInfo
*spki
)
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");
451 spki
->subjectPublicKey
.length
= len
* 8;
453 ret
= set_digest_alg(&spki
->algorithm
,oid_id_pkcs1_rsaEncryption(),
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;
464 unsigned char *pp
= spki
->subjectPublicKey
.data
;
465 i2d_RSAPublicKey(private_key
->private_key
.rsa
, &pp
);
472 rsa_generate_private_key(hx509_context context
,
473 struct hx509_generate_private_context
*ctx
,
474 hx509_private_key private_key
)
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
;
491 BN_set_word(e
, default_rsa_e
);
493 bits
= default_rsa_bits
;
496 bits
= ctx
->num_bits
;
500 ret
= RSA_generate_key_ex(private_key
->private_key
.rsa
, bits
, e
, NULL
);
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();
513 rsa_private_key_export(hx509_context context
,
514 const hx509_private_key key
,
515 heim_octet_string
*data
)
522 ret
= i2d_RSAPrivateKey(key
->private_key
.rsa
, NULL
);
525 hx509_set_error_string(context
, 0, ret
,
526 "Private key is not exportable");
530 data
->data
= malloc(ret
);
531 if (data
->data
== NULL
) {
533 hx509_set_error_string(context
, 0, ret
, "malloc out of memory");
539 unsigned char *p
= data
->data
;
540 i2d_RSAPrivateKey(key
->private_key
.rsa
, &p
);
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
);
559 static hx509_private_key_ops rsa_private_key_ops
= {
561 oid_id_pkcs1_rsaEncryption
,
562 rsa_private_key2SPKI
,
563 rsa_private_key_export
,
564 rsa_private_key_import
,
565 rsa_generate_private_key
,
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
;
589 spi
= &signer
->tbsCertificate
.subjectPublicKeyInfo
;
593 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
597 ret
= decode_DSAPublicKey(spi
->subjectPublicKey
.data
,
598 spi
->subjectPublicKey
.length
/ 8,
603 dsa
->pub_key
= heim_int2BN(&pk
);
605 free_DSAPublicKey(&pk
);
607 if (dsa
->pub_key
== NULL
) {
609 hx509_set_error_string(context
, 0, ret
, "out of memory");
613 if (spi
->algorithm
.parameters
== NULL
) {
614 ret
= HX509_CRYPTO_SIG_INVALID_FORMAT
;
615 hx509_set_error_string(context
, 0, ret
, "DSA parameters missing");
619 ret
= decode_DSAParams(spi
->algorithm
.parameters
->data
,
620 spi
->algorithm
.parameters
->length
,
624 hx509_set_error_string(context
, 0, ret
, "DSA parameters failed to decode");
628 dsa
->p
= heim_int2BN(¶m
.p
);
629 dsa
->q
= heim_int2BN(¶m
.q
);
630 dsa
->g
= heim_int2BN(¶m
.g
);
632 free_DSAParams(¶m
);
634 if (dsa
->p
== NULL
|| dsa
->q
== NULL
|| dsa
->g
== NULL
) {
636 hx509_set_error_string(context
, 0, ret
, "out of memory");
640 ret
= DSA_verify(-1, data
->data
, data
->length
,
641 (unsigned char*)sig
->data
, sig
->length
,
645 else if (ret
== 0 || ret
== -1) {
646 ret
= HX509_CRYPTO_BAD_SIGNATURE
;
647 hx509_set_error_string(context
, 0, ret
, "BAD DSA sigature");
649 ret
= HX509_CRYPTO_SIG_INVALID_FORMAT
;
650 hx509_set_error_string(context
, 0, ret
, "Invalid format of DSA sigature");
661 dsa_parse_private_key(hx509_context context
,
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
)
672 private_key
->signature_alg
= oid_id_dsa_with_sha1();
676 hx509_set_error_string(context
, 0, HX509_PARSING_KEY_FAILED
,
677 "No support to parse DSA keys");
678 return HX509_PARSING_KEY_FAILED
;
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
];
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
;
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
;
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
)
724 memset(sig
, 0, sizeof(*sig
));
726 if (signatureAlgorithm
) {
728 ret
= set_digest_alg(signatureAlgorithm
, (*sig_alg
->sig_oid
)(),
735 sig
->data
= malloc(SHA256_DIGEST_LENGTH
);
736 if (sig
->data
== NULL
) {
740 sig
->length
= SHA256_DIGEST_LENGTH
;
743 SHA256_Update(&m
, data
->data
, data
->length
);
744 SHA256_Final (sig
->data
, &m
);
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
];
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
;
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
;
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
)
790 memset(sig
, 0, sizeof(*sig
));
792 if (signatureAlgorithm
) {
794 ret
= set_digest_alg(signatureAlgorithm
, (*sig_alg
->sig_oid
)(),
801 sig
->data
= malloc(SHA_DIGEST_LENGTH
);
802 if (sig
->data
== NULL
) {
806 sig
->length
= SHA_DIGEST_LENGTH
;
809 SHA1_Update(&m
, data
->data
, data
->length
);
810 SHA1_Final (sig
->data
, &m
);
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
];
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
;
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
,
839 return HX509_CRYPTO_BAD_SIGNATURE
;
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
];
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
;
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
,
869 return HX509_CRYPTO_BAD_SIGNATURE
;
875 static const struct signature_alg heim_rsa_pkcs1_x509
= {
877 oid_id_heim_rsa_pkcs1_x509
,
878 hx509_signature_rsa_pkcs1_x509
,
879 oid_id_pkcs1_rsaEncryption
,
881 PROVIDE_CONF
|REQUIRE_SIGNER
|SIG_PUBLIC_SIG
,
882 rsa_verify_signature
,
886 static const struct signature_alg pkcs1_rsa_sha1_alg
= {
888 oid_id_pkcs1_rsaEncryption
,
889 hx509_signature_rsa_with_sha1
,
890 oid_id_pkcs1_rsaEncryption
,
892 PROVIDE_CONF
|REQUIRE_SIGNER
|RA_RSA_USES_DIGEST_INFO
|SIG_PUBLIC_SIG
,
893 rsa_verify_signature
,
897 static const struct signature_alg rsa_with_sha256_alg
= {
899 oid_id_pkcs1_sha256WithRSAEncryption
,
900 hx509_signature_rsa_with_sha256
,
901 oid_id_pkcs1_rsaEncryption
,
903 PROVIDE_CONF
|REQUIRE_SIGNER
|RA_RSA_USES_DIGEST_INFO
|SIG_PUBLIC_SIG
,
904 rsa_verify_signature
,
908 static const struct signature_alg rsa_with_sha1_alg
= {
910 oid_id_pkcs1_sha1WithRSAEncryption
,
911 hx509_signature_rsa_with_sha1
,
912 oid_id_pkcs1_rsaEncryption
,
914 PROVIDE_CONF
|REQUIRE_SIGNER
|RA_RSA_USES_DIGEST_INFO
|SIG_PUBLIC_SIG
,
915 rsa_verify_signature
,
919 static const struct signature_alg rsa_with_md5_alg
= {
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
,
930 static const struct signature_alg rsa_with_md2_alg
= {
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
,
941 static const struct signature_alg dsa_sha1_alg
= {
943 oid_id_dsa_with_sha1
,
947 PROVIDE_CONF
|REQUIRE_SIGNER
|SIG_PUBLIC_SIG
,
948 dsa_verify_signature
,
949 /* create_signature */ NULL
,
952 static const struct signature_alg sha256_alg
= {
955 hx509_signature_sha256
,
959 sha256_verify_signature
,
960 sha256_create_signature
963 static const struct signature_alg sha1_alg
= {
966 hx509_signature_sha1
,
970 sha1_verify_signature
,
971 sha1_create_signature
974 static const struct signature_alg md5_alg
= {
976 oid_id_rsa_digest_md5
,
984 static const struct signature_alg md2_alg
= {
986 oid_id_rsa_digest_md2
,
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
,
1002 &pkcs1_rsa_sha1_alg
,
1005 &heim_rsa_pkcs1_x509
,
1014 static const struct signature_alg
*
1015 find_sig_alg(const heim_oid
*oid
)
1018 for (i
= 0; sig_algs
[i
]; i
++)
1019 if (der_heim_oid_cmp((*sig_algs
[i
]->sig_oid
)(), oid
) == 0)
1028 static struct hx509_private_key_ops
*private_algs
[] = {
1029 &rsa_private_key_ops
,
1033 static hx509_private_key_ops
*
1034 find_private_alg(const heim_oid
*oid
)
1037 for (i
= 0; private_algs
[i
]; i
++) {
1038 if (private_algs
[i
]->key_oid
== NULL
)
1040 if (der_heim_oid_cmp((*private_algs
[i
]->key_oid
)(), oid
) == 0)
1041 return private_algs
[i
];
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
);
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
);
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
;
1147 ret
= _hx509_create_signature(context
, signer
, alg
,
1148 data
, signatureAlgorithm
, &os
);
1151 sig
->data
= os
.data
;
1152 sig
->length
= os
.length
* 8;
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
;
1171 ciphertext
->data
= NULL
;
1172 ciphertext
->length
= 0;
1174 spi
= &cert
->tbsCertificate
.subjectPublicKeyInfo
;
1178 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
1182 ret
= decode_RSAPublicKey(spi
->subjectPublicKey
.data
,
1183 spi
->subjectPublicKey
.length
/ 8,
1187 hx509_set_error_string(context
, 0, ret
, "RSAPublicKey decode failure");
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
) {
1197 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
1201 tosize
= RSA_size(rsa
);
1202 to
= malloc(tosize
);
1205 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
1209 ret
= RSA_public_encrypt(cleartext
->length
,
1210 (unsigned char *)cleartext
->data
,
1211 to
, rsa
, RSA_PKCS1_PADDING
);
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
;
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
);
1227 der_free_octet_string(ciphertext
);
1228 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
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
)
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");
1259 ret
= RSA_private_decrypt(ciphertext
->length
, ciphertext
->data
,
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
;
1279 _hx509_parse_private_key(hx509_context context
,
1280 const heim_oid
*key_oid
,
1283 hx509_private_key
*private_key
)
1285 struct hx509_private_key_ops
*ops
;
1288 *private_key
= NULL
;
1290 ops
= find_private_alg(key_oid
);
1292 hx509_clear_error_string(context
);
1293 return HX509_SIG_ALG_NO_SUPPORTED
;
1296 ret
= _hx509_private_key_init(private_key
, ops
, NULL
);
1298 hx509_set_error_string(context
, 0, ret
, "out of memory");
1302 ret
= (*ops
->import
)(context
, data
, len
, *private_key
);
1304 _hx509_private_key_free(private_key
);
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
)
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");
1340 *ctx
= calloc(1, sizeof(**ctx
));
1342 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
1345 (*ctx
)->key_oid
= oid
;
1351 _hx509_generate_private_key_is_ca(hx509_context context
,
1352 struct hx509_generate_private_context
*ctx
)
1359 _hx509_generate_private_key_bits(hx509_context context
,
1360 struct hx509_generate_private_context
*ctx
,
1363 ctx
->num_bits
= bits
;
1369 _hx509_generate_private_key_free(struct hx509_generate_private_context
**ctx
)
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
;
1383 *private_key
= NULL
;
1385 ops
= find_private_alg(ctx
->key_oid
);
1387 hx509_clear_error_string(context
);
1388 return HX509_SIG_ALG_NO_SUPPORTED
;
1391 ret
= _hx509_private_key_init(private_key
, ops
, NULL
);
1393 hx509_set_error_string(context
, 0, ret
, "out of memory");
1397 ret
= (*ops
->generate_private_key
)(context
, ctx
, *private_key
);
1399 _hx509_private_key_free(private_key
);
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
,
1584 *key
= calloc(1, sizeof(**key
));
1589 (*key
)->private_key
.keydata
= keydata
;
1594 _hx509_private_key_ref(hx509_private_key key
)
1597 _hx509_abort("refcount <= 0");
1600 _hx509_abort("refcount == 0");
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
)
1616 if ((*key
)->ref
<= 0)
1617 _hx509_abort("refcount <= 0");
1618 if (--(*key
)->ref
> 0)
1621 if ((*key
)->private_key
.rsa
)
1622 RSA_free((*key
)->private_key
.rsa
);
1623 (*key
)->private_key
.rsa
= NULL
;
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
;
1640 _hx509_private_key_oid(hx509_context context
,
1641 const hx509_private_key key
,
1645 ret
= der_copy_oid((*key
->ops
->key_oid
)(), data
);
1647 hx509_set_error_string(context
, 0, ret
, "malloc out of memory");
1652 _hx509_private_key_exportable(hx509_private_key key
)
1654 if (key
->ops
->export
== NULL
)
1660 _hx509_private_key_get_internal(hx509_context context
,
1661 hx509_private_key key
,
1664 if (key
->ops
->get_internal
== NULL
)
1666 return (*key
->ops
->get_internal
)(context
, key
, type
);
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
{
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
{
1698 const struct hx509cipher
*cipher
;
1699 const EVP_CIPHER
*c
;
1700 heim_octet_string key
;
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
};
1724 CMSCBCParam_get(hx509_context context
, const hx509_crypto crypto
,
1725 const heim_octet_string
*ivec
, heim_octet_string
*param
)
1730 assert(crypto
->param
== NULL
);
1734 ASN1_MALLOC_ENCODE(CMSCBCParameter
, param
->data
, param
->length
,
1736 if (ret
== 0 && size
!= param
->length
)
1737 _hx509_abort("Internal asn1 encoder failure");
1739 hx509_clear_error_string(context
);
1744 CMSCBCParam_set(hx509_context context
, const heim_octet_string
*param
,
1745 hx509_crypto crypto
, heim_octet_string
*ivec
)
1751 ret
= decode_CMSCBCParameter(param
->data
, param
->length
, ivec
, NULL
);
1753 hx509_clear_error_string(context
);
1758 struct _RC2_params
{
1759 int maximum_effective_key
;
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;
1772 memset(&rc2params
, 0, sizeof(rc2params
));
1775 maximum_effective_key
= p
->maximum_effective_key
;
1777 switch(maximum_effective_key
) {
1779 rc2params
.rc2ParameterVersion
= 160;
1782 rc2params
.rc2ParameterVersion
= 120;
1785 rc2params
.rc2ParameterVersion
= 58;
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");
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
;
1807 ret
= decode_CMSRC2CBCParameter(param
->data
, param
->length
,
1810 hx509_clear_error_string(context
);
1814 p
= calloc(1, sizeof(*p
));
1816 free_CMSRC2CBCParameter(&rc2param
);
1817 hx509_clear_error_string(context
);
1820 switch(rc2param
.rc2ParameterVersion
) {
1822 crypto
->c
= EVP_rc2_40_cbc();
1823 p
->maximum_effective_key
= 40;
1826 crypto
->c
= EVP_rc2_64_cbc();
1827 p
->maximum_effective_key
= 64;
1830 crypto
->c
= EVP_rc2_cbc();
1831 p
->maximum_effective_key
= 128;
1835 free_CMSRC2CBCParameter(&rc2param
);
1836 return HX509_CRYPTO_SIG_INVALID_FORMAT
;
1839 ret
= der_copy_octet_string(&rc2param
.iv
, ivec
);
1840 free_CMSRC2CBCParameter(&rc2param
);
1843 hx509_clear_error_string(context
);
1854 static const struct hx509cipher ciphers
[] = {
1857 oid_id_pkcs3_rc2_cbc
,
1865 oid_id_rsadsi_rc2_cbc
,
1881 oid_id_pkcs3_des_ede3_cbc
,
1889 oid_id_rsadsi_des_ede3_cbc
,
1890 hx509_crypto_des_rsdi_ede3_cbc
,
1898 hx509_crypto_aes128_cbc
,
1914 hx509_crypto_aes256_cbc
,
1921 static const struct hx509cipher
*
1922 find_cipher_by_oid(const heim_oid
*oid
)
1926 for (i
= 0; i
< sizeof(ciphers
)/sizeof(ciphers
[0]); i
++)
1927 if (der_heim_oid_cmp(oid
, (*ciphers
[i
].oid_func
)()) == 0)
1933 static const struct hx509cipher
*
1934 find_cipher_by_name(const char *name
)
1938 for (i
= 0; i
< sizeof(ciphers
)/sizeof(ciphers
[0]); i
++)
1939 if (strcasecmp(name
, ciphers
[i
].name
) == 0)
1947 hx509_crypto_enctype_by_name(const char *name
)
1949 const struct hx509cipher
*cipher
;
1951 cipher
= find_cipher_by_name(name
);
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
;
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
);
1980 (*crypto
)->cipher
= cipher
;
1981 (*crypto
)->c
= (*cipher
->evp_func
)();
1983 if (der_copy_oid(enctype
, &(*crypto
)->oid
)) {
1984 hx509_crypto_destroy(*crypto
);
1986 hx509_clear_error_string(context
);
1994 hx509_crypto_provider(hx509_crypto crypto
)
2000 hx509_crypto_destroy(hx509_crypto crypto
)
2004 if (crypto
->key
.data
)
2005 free(crypto
->key
.data
);
2007 free(crypto
->param
);
2008 der_free_oid(&crypto
->oid
);
2009 memset(crypto
, 0, sizeof(*crypto
));
2014 hx509_crypto_set_key_name(hx509_crypto crypto
, const char *name
)
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
)
2033 memcpy(crypto
->key
.data
, data
, length
);
2034 crypto
->key
.length
= length
;
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;
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
;
2060 return der_copy_octet_string(&crypto
->key
, key
);
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
) {
2093 if (RAND_bytes(ivec
->data
, ivec
->length
) <= 0) {
2097 return HX509_CRYPTO_INTERNAL_ERROR
;
2103 hx509_crypto_encrypt(hx509_crypto crypto
,
2105 const size_t length
,
2106 const heim_octet_string
*ivec
,
2107 heim_octet_string
**ciphertext
)
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);
2122 EVP_CIPHER_CTX_cleanup(&evp
);
2123 ret
= HX509_CRYPTO_INTERNAL_ERROR
;
2127 *ciphertext
= calloc(1, sizeof(**ciphertext
));
2128 if (*ciphertext
== NULL
) {
2133 if (EVP_CIPHER_block_size(crypto
->c
) == 1) {
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
) {
2146 memcpy((*ciphertext
)->data
, data
, length
);
2149 unsigned char *p
= (*ciphertext
)->data
;
2151 for (i
= 0; i
< padsize
; i
++)
2155 ret
= EVP_Cipher(&evp
, (*ciphertext
)->data
,
2156 (*ciphertext
)->data
,
2159 ret
= HX509_CRYPTO_INTERNAL_ERROR
;
2167 if ((*ciphertext
)->data
) {
2168 free((*ciphertext
)->data
);
2174 EVP_CIPHER_CTX_cleanup(&evp
);
2180 hx509_crypto_decrypt(hx509_crypto crypto
,
2182 const size_t length
,
2183 heim_octet_string
*ivec
,
2184 heim_octet_string
*clear
)
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
;
2202 EVP_CIPHER_CTX_init(&evp
);
2204 ret
= EVP_CipherInit_ex(&evp
, crypto
->c
, NULL
,
2205 crypto
->key
.data
, idata
, 0);
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
);
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) {
2227 int j
, bsize
= EVP_CIPHER_block_size(crypto
->c
);
2229 if (clear
->length
< bsize
) {
2230 ret
= HX509_CMS_PADDING_ERROR
;
2235 p
+= clear
->length
- 1;
2237 if (padsize
> bsize
) {
2238 ret
= HX509_CMS_PADDING_ERROR
;
2241 clear
->length
-= padsize
;
2242 for (j
= 0; j
< padsize
; j
++) {
2243 if (*p
-- != padsize
) {
2244 ret
= HX509_CMS_PADDING_ERROR
;
2260 typedef int (*PBE_string2key_func
)(hx509_context
,
2262 const heim_octet_string
*,
2263 hx509_crypto
*, heim_octet_string
*,
2264 heim_octet_string
*,
2265 const heim_oid
*, const EVP_MD
*);
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
,
2276 PKCS12_PBEParams p12params
;
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
,
2293 if (p12params
.iterations
)
2294 iter
= *p12params
.iterations
;
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
;
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
;
2312 ret
= hx509_crypto_init(context
, NULL
, enc_oid
, &c
);
2316 ret
= hx509_crypto_set_key_data(c
, key
->data
, key
->length
);
2318 hx509_crypto_destroy(c
);
2324 free_PKCS12_PBEParams(&p12params
);
2328 static const heim_oid
*
2329 find_string2key(const heim_oid
*oid
,
2330 const EVP_CIPHER
**c
,
2332 PBE_string2key_func
*s2k
)
2334 if (der_heim_oid_cmp(oid
, oid_id_pbewithSHAAnd40BitRC2_CBC()) == 0) {
2335 *c
= EVP_rc2_40_cbc();
2337 *s2k
= PBE_string2key
;
2338 return oid_private_rc2_40();
2339 } else if (der_heim_oid_cmp(oid
, oid_id_pbeWithSHAAnd128BitRC2_CBC()) == 0) {
2342 *s2k
= PBE_string2key
;
2343 return oid_id_pkcs3_rc2_cbc();
2345 } else if (der_heim_oid_cmp(oid
, oid_id_pbeWithSHAAnd40BitRC4()) == 0) {
2348 *s2k
= PBE_string2key
;
2350 } else if (der_heim_oid_cmp(oid
, oid_id_pbeWithSHAAnd128BitRC4()) == 0) {
2353 *s2k
= PBE_string2key
;
2354 return oid_id_pkcs3_rc4();
2356 } else if (der_heim_oid_cmp(oid
, oid_id_pbeWithSHAAnd3_KeyTripleDES_CBC()) == 0) {
2357 *c
= EVP_des_ede3_cbc();
2359 *s2k
= PBE_string2key
;
2360 return oid_id_pkcs3_des_ede3_cbc();
2371 _hx509_pbe_encrypt(hx509_context context
,
2373 const AlgorithmIdentifier
*ai
,
2374 const heim_octet_string
*content
,
2375 heim_octet_string
*econtent
)
2377 hx509_clear_error_string(context
);
2386 _hx509_pbe_decrypt(hx509_context context
,
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
;
2397 PBE_string2key_func s2k
;
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
;
2413 key
.length
= EVP_CIPHER_key_length(c
);
2414 key
.data
= malloc(key
.length
);
2415 if (key
.data
== NULL
) {
2417 hx509_clear_error_string(context
);
2421 iv
.length
= EVP_CIPHER_iv_length(c
);
2422 iv
.data
= malloc(iv
.length
);
2423 if (iv
.data
== NULL
) {
2425 hx509_clear_error_string(context
);
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
;
2437 password
= pw
->val
[i
];
2438 else if (i
< pw
->len
+ 1)
2443 ret
= (*s2k
)(context
, password
, ai
->parameters
, &crypto
,
2444 &key
, &iv
, enc_oid
, md
);
2448 ret
= hx509_crypto_decrypt(crypto
,
2453 hx509_crypto_destroy(crypto
);
2460 der_free_octet_string(&key
);
2462 der_free_octet_string(&iv
);
2472 _hx509_match_keys(hx509_cert c
, hx509_private_key private_key
)
2474 const Certificate
*cert
;
2475 const SubjectPublicKeyInfo
*spi
;
2481 if (private_key
->private_key
.rsa
== NULL
)
2484 rsa
= private_key
->private_key
.rsa
;
2485 if (rsa
->d
== NULL
|| rsa
->p
== NULL
|| rsa
->q
== NULL
)
2488 cert
= _hx509_get_cert(c
);
2489 spi
= &cert
->tbsCertificate
.subjectPublicKeyInfo
;
2495 ret
= decode_RSAPublicKey(spi
->subjectPublicKey
.data
,
2496 spi
->subjectPublicKey
.length
/ 8,
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
) {
2521 ret
= RSA_check_key(rsa
);
2527 static const heim_oid
*
2528 find_keytype(const hx509_private_key key
)
2530 const struct signature_alg
*md
;
2535 md
= find_sig_alg(key
->signature_alg
);
2538 return (*md
->key_oid
)();
2543 hx509_crypto_select(const hx509_context context
,
2545 const hx509_private_key source
,
2546 hx509_peer_info peer
,
2547 AlgorithmIdentifier
*selected
)
2549 const AlgorithmIdentifier
*def
;
2553 memset(selected
, 0, sizeof(*selected
));
2555 if (type
== HX509_SELECT_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
) {
2564 def
= _hx509_crypto_default_secret_alg
;
2566 hx509_set_error_string(context
, 0, EINVAL
,
2567 "Unknown type %d of selection", type
);
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
)
2580 if (der_heim_oid_cmp((*sig_algs
[j
]->sig_oid
)(),
2581 &peer
->val
[i
].algorithm
) != 0)
2583 if (keytype
&& sig_algs
[j
]->key_oid
&&
2584 der_heim_oid_cmp(keytype
, (*sig_algs
[j
]->key_oid
)()))
2587 /* found one, use that */
2588 ret
= copy_AlgorithmIdentifier(&peer
->val
[i
], selected
);
2590 hx509_clear_error_string(context
);
2593 if (bits
& SIG_SECRET
) {
2594 const struct hx509cipher
*cipher
;
2596 cipher
= find_cipher_by_oid(&peer
->val
[i
].algorithm
);
2599 if (cipher
->ai_func
== NULL
)
2601 ret
= copy_AlgorithmIdentifier(cipher
->ai_func(), selected
);
2603 hx509_clear_error_string(context
);
2610 ret
= copy_AlgorithmIdentifier(def
, selected
);
2612 hx509_clear_error_string(context
);
2617 hx509_crypto_available(hx509_context context
,
2620 AlgorithmIdentifier
**val
,
2623 const heim_oid
*keytype
= NULL
;
2624 unsigned int len
, i
;
2630 if (type
== HX509_SELECT_ALL
) {
2631 bits
= SIG_DIGEST
| SIG_PUBLIC_SIG
| SIG_SECRET
;
2632 } else if (type
== HX509_SELECT_DIGEST
) {
2634 } else if (type
== HX509_SELECT_PUBLIC_SIG
) {
2635 bits
= SIG_PUBLIC_SIG
;
2637 hx509_set_error_string(context
, 0, EINVAL
,
2638 "Unknown type %d of available", type
);
2643 keytype
= find_keytype(_hx509_cert_private_key(source
));
2646 for (i
= 0; sig_algs
[i
]; i
++) {
2647 if ((sig_algs
[i
]->flags
& bits
) == 0)
2649 if (sig_algs
[i
]->sig_alg
== NULL
)
2651 if (keytype
&& sig_algs
[i
]->key_oid
&&
2652 der_heim_oid_cmp((*sig_algs
[i
]->key_oid
)(), keytype
))
2655 /* found one, add that to the list */
2656 ptr
= realloc(*val
, sizeof(**val
) * (len
+ 1));
2661 ret
= copy_AlgorithmIdentifier((*sig_algs
[i
]->sig_alg
)(), &(*val
)[len
]);
2668 if (bits
& SIG_SECRET
) {
2670 for (i
= 0; i
< sizeof(ciphers
)/sizeof(ciphers
[0]); i
++) {
2672 if (ciphers
[i
].ai_func
== NULL
)
2675 ptr
= realloc(*val
, sizeof(**val
) * (len
+ 1));
2680 ret
= copy_AlgorithmIdentifier((ciphers
[i
].ai_func
)(), &(*val
)[len
]);
2691 for (i
= 0; i
< len
; i
++)
2692 free_AlgorithmIdentifier(&(*val
)[i
]);
2695 hx509_set_error_string(context
, 0, ENOMEM
, "out of memory");
2700 hx509_crypto_free_algs(AlgorithmIdentifier
*val
,
2704 for (i
= 0; i
< len
; i
++)
2705 free_AlgorithmIdentifier(&val
[i
]);