Line data Source code
1 : /*
2 : * Copyright (c) 2004 - 2016 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
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.
16 : *
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.
20 : *
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.
32 : */
33 :
34 : #include "hx_locl.h"
35 :
36 : /*-
37 : * RFC5758 specifies no parameters for ecdsa-with-SHA<N> signatures
38 : * RFC5754 specifies NULL parameters for sha<N>WithRSAEncryption signatures
39 : *
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.
42 : */
43 :
44 : static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
45 :
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)
49 : };
50 :
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)
54 : };
55 :
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)
59 : };
60 :
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)
64 : };
65 :
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)
69 : };
70 :
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)
74 : };
75 :
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)
79 : };
80 :
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)
84 : };
85 :
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)
89 : };
90 :
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)
94 : };
95 :
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
99 : };
100 :
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
104 : };
105 :
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
109 : };
110 :
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
114 : };
115 :
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
119 : };
120 :
121 : /*
122 : *
123 : */
124 :
125 : static BIGNUM *
126 148 : heim_int2BN(const heim_integer *i)
127 : {
128 16 : BIGNUM *bn;
129 :
130 148 : bn = BN_bin2bn(i->data, i->length, NULL);
131 148 : BN_set_negative(bn, i->negative);
132 148 : return bn;
133 : }
134 :
135 : /*
136 : *
137 : */
138 :
139 : HX509_LIB_FUNCTION int HX509_LIB_CALL
140 130 : _hx509_set_digest_alg(DigestAlgorithmIdentifier *id,
141 : const heim_oid *oid,
142 : const void *param, size_t length)
143 : {
144 0 : int ret;
145 130 : if (param) {
146 130 : id->parameters = malloc(sizeof(*id->parameters));
147 130 : if (id->parameters == NULL)
148 0 : return ENOMEM;
149 130 : id->parameters->data = malloc(length);
150 130 : if (id->parameters->data == NULL) {
151 0 : free(id->parameters);
152 0 : id->parameters = NULL;
153 0 : return ENOMEM;
154 : }
155 130 : memcpy(id->parameters->data, param, length);
156 130 : id->parameters->length = length;
157 : } else
158 0 : id->parameters = NULL;
159 130 : ret = der_copy_oid(oid, &id->algorithm);
160 130 : if (ret) {
161 0 : if (id->parameters) {
162 0 : free(id->parameters->data);
163 0 : free(id->parameters);
164 0 : id->parameters = NULL;
165 : }
166 0 : return ret;
167 : }
168 130 : return 0;
169 : }
170 :
171 : /*
172 : *
173 : */
174 :
175 : static int
176 225 : 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)
182 : {
183 0 : const SubjectPublicKeyInfo *spi;
184 0 : DigestInfo di;
185 0 : unsigned char *to;
186 0 : int tosize, retsize;
187 0 : int ret;
188 0 : RSA *rsa;
189 0 : size_t size;
190 0 : const unsigned char *p;
191 :
192 225 : memset(&di, 0, sizeof(di));
193 :
194 225 : spi = &signer->tbsCertificate.subjectPublicKeyInfo;
195 :
196 225 : p = spi->subjectPublicKey.data;
197 225 : size = spi->subjectPublicKey.length / 8;
198 :
199 225 : rsa = d2i_RSAPublicKey(NULL, &p, size);
200 225 : if (rsa == NULL) {
201 0 : ret = ENOMEM;
202 0 : hx509_set_error_string(context, 0, ret, "out of memory");
203 0 : goto out;
204 : }
205 :
206 225 : tosize = RSA_size(rsa);
207 225 : to = malloc(tosize);
208 225 : if (to == NULL) {
209 0 : ret = ENOMEM;
210 0 : hx509_set_error_string(context, 0, ret, "out of memory");
211 0 : goto out;
212 : }
213 :
214 225 : retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
215 : to, rsa, RSA_PKCS1_PADDING);
216 225 : if (retsize <= 0) {
217 0 : ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
218 0 : hx509_set_error_string(context, 0, ret,
219 : "RSA public decrypt failed: %d", retsize);
220 0 : free(to);
221 0 : goto out;
222 : }
223 225 : if (retsize > tosize)
224 0 : _hx509_abort("internal rsa decryption failure: ret > tosize");
225 :
226 225 : if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
227 :
228 225 : ret = decode_DigestInfo(to, retsize, &di, &size);
229 225 : free(to);
230 225 : if (ret) {
231 0 : goto out;
232 : }
233 :
234 : /* Check for extra data inside the sigature */
235 225 : if (size != (size_t)retsize) {
236 0 : ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
237 0 : hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
238 0 : goto out;
239 : }
240 :
241 450 : if (sig_alg->digest_alg &&
242 225 : der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
243 225 : &sig_alg->digest_alg->algorithm) != 0)
244 : {
245 0 : ret = HX509_CRYPTO_OID_MISMATCH;
246 0 : hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
247 0 : goto out;
248 : }
249 :
250 : /* verify that the parameters are NULL or the NULL-type */
251 225 : if (di.digestAlgorithm.parameters != NULL &&
252 225 : (di.digestAlgorithm.parameters->length != 2 ||
253 225 : memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
254 : {
255 0 : ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
256 0 : hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
257 0 : goto out;
258 : }
259 :
260 225 : ret = _hx509_verify_signature(context,
261 : NULL,
262 : &di.digestAlgorithm,
263 : data,
264 : &di.digest);
265 225 : if (ret)
266 0 : goto out;
267 :
268 : } else {
269 0 : if ((size_t)retsize != data->length ||
270 0 : ct_memcmp(to, data->data, retsize) != 0)
271 : {
272 0 : ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
273 0 : hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
274 0 : goto out;
275 : }
276 0 : free(to);
277 0 : ret = 0;
278 : }
279 :
280 225 : out:
281 225 : free_DigestInfo(&di);
282 225 : if (rsa)
283 225 : RSA_free(rsa);
284 225 : return ret;
285 : }
286 :
287 : static int
288 65 : 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)
295 : {
296 0 : const AlgorithmIdentifier *digest_alg;
297 0 : heim_octet_string indata;
298 0 : const heim_oid *sig_oid;
299 0 : size_t size;
300 0 : int ret;
301 :
302 65 : if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0)
303 0 : return HX509_ALG_NOT_SUPP;
304 :
305 65 : if (alg)
306 65 : sig_oid = &alg->algorithm;
307 : else
308 0 : sig_oid = signer->signature_alg;
309 :
310 65 : if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
311 37 : digest_alg = hx509_signature_sha512();
312 28 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
313 0 : digest_alg = hx509_signature_sha384();
314 28 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
315 24 : digest_alg = hx509_signature_sha256();
316 4 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
317 4 : digest_alg = hx509_signature_sha1();
318 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
319 0 : digest_alg = hx509_signature_md5();
320 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION) == 0) {
321 0 : digest_alg = hx509_signature_md5();
322 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_DSA_WITH_SHA1) == 0) {
323 0 : digest_alg = hx509_signature_sha1();
324 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
325 0 : digest_alg = hx509_signature_sha1();
326 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_HEIM_RSA_PKCS1_X509) == 0) {
327 0 : digest_alg = NULL;
328 : } else
329 0 : return HX509_ALG_NOT_SUPP;
330 :
331 65 : if (signatureAlgorithm) {
332 65 : ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid,
333 : "\x05\x00", 2);
334 65 : if (ret) {
335 0 : hx509_clear_error_string(context);
336 0 : return ret;
337 : }
338 : }
339 :
340 65 : if (digest_alg) {
341 0 : DigestInfo di;
342 65 : memset(&di, 0, sizeof(di));
343 :
344 65 : ret = _hx509_create_signature(context,
345 : NULL,
346 : digest_alg,
347 : data,
348 : &di.digestAlgorithm,
349 : &di.digest);
350 65 : if (ret)
351 0 : return ret;
352 65 : ASN1_MALLOC_ENCODE(DigestInfo,
353 : indata.data,
354 : indata.length,
355 : &di,
356 : &size,
357 : ret);
358 65 : free_DigestInfo(&di);
359 65 : if (ret) {
360 0 : hx509_set_error_string(context, 0, ret, "out of memory");
361 0 : return ret;
362 : }
363 65 : if (indata.length != size)
364 0 : _hx509_abort("internal ASN.1 encoder error");
365 : } else {
366 0 : indata = *data;
367 : }
368 :
369 65 : sig->length = RSA_size(signer->private_key.rsa);
370 65 : sig->data = malloc(sig->length);
371 65 : if (sig->data == NULL) {
372 0 : der_free_octet_string(&indata);
373 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
374 0 : return ENOMEM;
375 : }
376 :
377 65 : ret = RSA_private_encrypt(indata.length, indata.data,
378 65 : sig->data,
379 : signer->private_key.rsa,
380 : RSA_PKCS1_PADDING);
381 65 : if (indata.data != data->data)
382 65 : der_free_octet_string(&indata);
383 65 : if (ret <= 0) {
384 0 : ret = HX509_CMS_FAILED_CREATE_SIGATURE;
385 0 : hx509_set_error_string(context, 0, ret,
386 : "RSA private encrypt failed: %d", ret);
387 0 : return ret;
388 : }
389 65 : if (sig->length > (size_t)ret) {
390 0 : size = sig->length - ret;
391 0 : memmove((uint8_t *)sig->data + size, sig->data, ret);
392 0 : memset(sig->data, 0, size);
393 65 : } else if (sig->length < (size_t)ret)
394 0 : _hx509_abort("RSA signature prelen longer than output len");
395 :
396 65 : return 0;
397 : }
398 :
399 : static int
400 74 : 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)
406 : {
407 74 : switch (format) {
408 74 : case HX509_KEY_FORMAT_DER: {
409 74 : const unsigned char *p = data;
410 :
411 82 : private_key->private_key.rsa =
412 74 : d2i_RSAPrivateKey(NULL, &p, len);
413 74 : if (private_key->private_key.rsa == NULL) {
414 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
415 : "Failed to parse RSA key");
416 0 : return HX509_PARSING_KEY_FAILED;
417 : }
418 74 : private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
419 74 : break;
420 :
421 : }
422 0 : default:
423 0 : return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
424 : }
425 :
426 74 : return 0;
427 : }
428 :
429 : static int
430 0 : rsa_private_key2SPKI(hx509_context context,
431 : hx509_private_key private_key,
432 : SubjectPublicKeyInfo *spki)
433 : {
434 0 : int len, ret;
435 :
436 0 : memset(spki, 0, sizeof(*spki));
437 :
438 0 : len = i2d_RSAPublicKey(private_key->private_key.rsa, NULL);
439 0 : if (len < 0)
440 0 : return -1;
441 :
442 0 : spki->subjectPublicKey.data = malloc(len);
443 0 : if (spki->subjectPublicKey.data == NULL) {
444 0 : hx509_set_error_string(context, 0, ENOMEM, "malloc - out of memory");
445 0 : return ENOMEM;
446 : }
447 0 : spki->subjectPublicKey.length = len * 8;
448 :
449 0 : ret = _hx509_set_digest_alg(&spki->algorithm,
450 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
451 : "\x05\x00", 2);
452 0 : if (ret) {
453 0 : hx509_set_error_string(context, 0, ret, "malloc - out of memory");
454 0 : free(spki->subjectPublicKey.data);
455 0 : spki->subjectPublicKey.data = NULL;
456 0 : spki->subjectPublicKey.length = 0;
457 0 : return ret;
458 : }
459 :
460 : {
461 0 : unsigned char *pp = spki->subjectPublicKey.data;
462 0 : i2d_RSAPublicKey(private_key->private_key.rsa, &pp);
463 : }
464 :
465 0 : return 0;
466 : }
467 :
468 : static int
469 0 : rsa_generate_private_key(hx509_context context,
470 : struct hx509_generate_private_context *ctx,
471 : hx509_private_key private_key)
472 : {
473 0 : BIGNUM *e;
474 0 : int ret;
475 0 : unsigned long bits;
476 :
477 0 : static const int default_rsa_e = 65537;
478 0 : static const int default_rsa_bits = 2048;
479 :
480 0 : private_key->private_key.rsa = RSA_new();
481 0 : if (private_key->private_key.rsa == NULL) {
482 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
483 : "Failed to generate RSA key");
484 0 : return HX509_PARSING_KEY_FAILED;
485 : }
486 :
487 0 : e = BN_new();
488 0 : BN_set_word(e, default_rsa_e);
489 :
490 0 : bits = default_rsa_bits;
491 :
492 0 : if (ctx->num_bits)
493 0 : bits = ctx->num_bits;
494 :
495 0 : ret = RSA_generate_key_ex(private_key->private_key.rsa, bits, e, NULL);
496 0 : BN_free(e);
497 0 : if (ret != 1) {
498 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
499 : "Failed to generate RSA key");
500 0 : return HX509_PARSING_KEY_FAILED;
501 : }
502 0 : private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
503 :
504 0 : return 0;
505 : }
506 :
507 : static int
508 0 : rsa_private_key_export(hx509_context context,
509 : const hx509_private_key key,
510 : hx509_key_format_t format,
511 : heim_octet_string *data)
512 : {
513 0 : int ret;
514 :
515 0 : data->data = NULL;
516 0 : data->length = 0;
517 :
518 0 : switch (format) {
519 0 : case HX509_KEY_FORMAT_DER:
520 :
521 0 : ret = i2d_RSAPrivateKey(key->private_key.rsa, NULL);
522 0 : if (ret <= 0) {
523 0 : ret = EINVAL;
524 0 : hx509_set_error_string(context, 0, ret,
525 : "Private key is not exportable");
526 0 : return ret;
527 : }
528 :
529 0 : data->data = malloc(ret);
530 0 : if (data->data == NULL) {
531 0 : ret = ENOMEM;
532 0 : hx509_set_error_string(context, 0, ret, "malloc out of memory");
533 0 : return ret;
534 : }
535 0 : data->length = ret;
536 :
537 : {
538 0 : unsigned char *p = data->data;
539 0 : i2d_RSAPrivateKey(key->private_key.rsa, &p);
540 : }
541 0 : break;
542 0 : default:
543 0 : return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
544 : }
545 :
546 0 : return 0;
547 : }
548 :
549 : static BIGNUM *
550 0 : rsa_get_internal(hx509_context context,
551 : hx509_private_key key,
552 : const char *type)
553 : {
554 0 : if (strcasecmp(type, "rsa-modulus") == 0) {
555 0 : return BN_dup(key->private_key.rsa->n);
556 0 : } else if (strcasecmp(type, "rsa-exponent") == 0) {
557 0 : return BN_dup(key->private_key.rsa->e);
558 : } else
559 0 : return NULL;
560 : }
561 :
562 :
563 :
564 : static hx509_private_key_ops rsa_private_key_ops = {
565 : "RSA PRIVATE KEY",
566 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
567 : NULL,
568 : rsa_private_key2SPKI,
569 : rsa_private_key_export,
570 : rsa_private_key_import,
571 : rsa_generate_private_key,
572 : rsa_get_internal
573 : };
574 :
575 : /*
576 : *
577 : */
578 :
579 : static int
580 0 : dsa_verify_signature(hx509_context context,
581 : const struct signature_alg *sig_alg,
582 : const Certificate *signer,
583 : const AlgorithmIdentifier *alg,
584 : const heim_octet_string *data,
585 : const heim_octet_string *sig)
586 : {
587 0 : const SubjectPublicKeyInfo *spi;
588 0 : DSAPublicKey pk;
589 0 : DSAParams param;
590 0 : size_t size;
591 0 : DSA *dsa;
592 0 : int ret;
593 :
594 0 : spi = &signer->tbsCertificate.subjectPublicKeyInfo;
595 :
596 0 : dsa = DSA_new();
597 0 : if (dsa == NULL) {
598 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
599 0 : return ENOMEM;
600 : }
601 :
602 0 : ret = decode_DSAPublicKey(spi->subjectPublicKey.data,
603 0 : spi->subjectPublicKey.length / 8,
604 : &pk, &size);
605 0 : if (ret)
606 0 : goto out;
607 :
608 0 : dsa->pub_key = heim_int2BN(&pk);
609 :
610 0 : free_DSAPublicKey(&pk);
611 :
612 0 : if (dsa->pub_key == NULL) {
613 0 : ret = ENOMEM;
614 0 : hx509_set_error_string(context, 0, ret, "out of memory");
615 0 : goto out;
616 : }
617 :
618 0 : if (spi->algorithm.parameters == NULL) {
619 0 : ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
620 0 : hx509_set_error_string(context, 0, ret, "DSA parameters missing");
621 0 : goto out;
622 : }
623 :
624 0 : ret = decode_DSAParams(spi->algorithm.parameters->data,
625 0 : spi->algorithm.parameters->length,
626 : ¶m,
627 : &size);
628 0 : if (ret) {
629 0 : hx509_set_error_string(context, 0, ret, "DSA parameters failed to decode");
630 0 : goto out;
631 : }
632 :
633 0 : dsa->p = heim_int2BN(¶m.p);
634 0 : dsa->q = heim_int2BN(¶m.q);
635 0 : dsa->g = heim_int2BN(¶m.g);
636 :
637 0 : free_DSAParams(¶m);
638 :
639 0 : if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
640 0 : ret = ENOMEM;
641 0 : hx509_set_error_string(context, 0, ret, "out of memory");
642 0 : goto out;
643 : }
644 :
645 0 : ret = DSA_verify(-1, data->data, data->length,
646 0 : (unsigned char*)sig->data, sig->length,
647 : dsa);
648 0 : if (ret == 1)
649 0 : ret = 0;
650 0 : else if (ret == 0 || ret == -1) {
651 0 : ret = HX509_CRYPTO_BAD_SIGNATURE;
652 0 : hx509_set_error_string(context, 0, ret, "BAD DSA sigature");
653 : } else {
654 0 : ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
655 0 : hx509_set_error_string(context, 0, ret, "Invalid format of DSA sigature");
656 : }
657 :
658 0 : out:
659 0 : DSA_free(dsa);
660 :
661 0 : return ret;
662 : }
663 :
664 : #if 0
665 : static int
666 : dsa_parse_private_key(hx509_context context,
667 : const void *data,
668 : size_t len,
669 : hx509_private_key private_key)
670 : {
671 : const unsigned char *p = data;
672 :
673 : private_key->private_key.dsa =
674 : d2i_DSAPrivateKey(NULL, &p, len);
675 : if (private_key->private_key.dsa == NULL)
676 : return EINVAL;
677 : private_key->signature_alg = ASN1_OID_ID_DSA_WITH_SHA1;
678 :
679 : return 0;
680 : /* else */
681 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
682 : "No support to parse DSA keys");
683 : return HX509_PARSING_KEY_FAILED;
684 : }
685 : #endif
686 :
687 : static int
688 126 : evp_md_create_signature(hx509_context context,
689 : const struct signature_alg *sig_alg,
690 : const hx509_private_key signer,
691 : const AlgorithmIdentifier *alg,
692 : const heim_octet_string *data,
693 : AlgorithmIdentifier *signatureAlgorithm,
694 : heim_octet_string *sig)
695 : {
696 126 : size_t sigsize = EVP_MD_size(sig_alg->evp_md());
697 0 : EVP_MD_CTX *ctx;
698 :
699 126 : memset(sig, 0, sizeof(*sig));
700 :
701 126 : if (signatureAlgorithm) {
702 0 : int ret;
703 65 : ret = _hx509_set_digest_alg(signatureAlgorithm,
704 65 : sig_alg->sig_oid, "\x05\x00", 2);
705 65 : if (ret)
706 0 : return ret;
707 : }
708 :
709 :
710 126 : sig->data = malloc(sigsize);
711 126 : if (sig->data == NULL) {
712 0 : sig->length = 0;
713 0 : return ENOMEM;
714 : }
715 126 : sig->length = sigsize;
716 :
717 126 : ctx = EVP_MD_CTX_create();
718 126 : EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
719 126 : EVP_DigestUpdate(ctx, data->data, data->length);
720 126 : EVP_DigestFinal_ex(ctx, sig->data, NULL);
721 126 : EVP_MD_CTX_destroy(ctx);
722 :
723 :
724 126 : return 0;
725 : }
726 :
727 : static int
728 253 : evp_md_verify_signature(hx509_context context,
729 : const struct signature_alg *sig_alg,
730 : const Certificate *signer,
731 : const AlgorithmIdentifier *alg,
732 : const heim_octet_string *data,
733 : const heim_octet_string *sig)
734 : {
735 0 : unsigned char digest[EVP_MAX_MD_SIZE];
736 0 : EVP_MD_CTX *ctx;
737 253 : size_t sigsize = EVP_MD_size(sig_alg->evp_md());
738 :
739 253 : if (sig->length != sigsize || sigsize > sizeof(digest)) {
740 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
741 : "SHA256 sigature has wrong length");
742 0 : return HX509_CRYPTO_SIG_INVALID_FORMAT;
743 : }
744 :
745 253 : ctx = EVP_MD_CTX_create();
746 253 : EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
747 253 : EVP_DigestUpdate(ctx, data->data, data->length);
748 253 : EVP_DigestFinal_ex(ctx, digest, NULL);
749 253 : EVP_MD_CTX_destroy(ctx);
750 :
751 253 : if (ct_memcmp(digest, sig->data, sigsize) != 0) {
752 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_BAD_SIGNATURE,
753 0 : "Bad %s sigature", sig_alg->name);
754 0 : return HX509_CRYPTO_BAD_SIGNATURE;
755 : }
756 :
757 253 : return 0;
758 : }
759 :
760 : #ifdef HAVE_HCRYPTO_W_OPENSSL
761 : extern const struct signature_alg ecdsa_with_sha512_alg;
762 : extern const struct signature_alg ecdsa_with_sha384_alg;
763 : extern const struct signature_alg ecdsa_with_sha256_alg;
764 : extern const struct signature_alg ecdsa_with_sha1_alg;
765 : #endif
766 :
767 : static const struct signature_alg heim_rsa_pkcs1_x509 = {
768 : "rsa-pkcs1-x509",
769 : ASN1_OID_ID_HEIM_RSA_PKCS1_X509,
770 : &_hx509_signature_rsa_pkcs1_x509_data,
771 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
772 : NULL,
773 : PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
774 : 0,
775 : NULL,
776 : rsa_verify_signature,
777 : rsa_create_signature,
778 : 0
779 : };
780 :
781 : static const struct signature_alg pkcs1_rsa_sha1_alg = {
782 : "rsa",
783 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
784 : &_hx509_signature_rsa_with_sha1_data,
785 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
786 : NULL,
787 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
788 : 0,
789 : NULL,
790 : rsa_verify_signature,
791 : rsa_create_signature,
792 : 0
793 : };
794 :
795 : static const struct signature_alg rsa_with_sha512_alg = {
796 : "rsa-with-sha512",
797 : ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION,
798 : &_hx509_signature_rsa_with_sha512_data,
799 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
800 : &_hx509_signature_sha512_data,
801 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
802 : 0,
803 : NULL,
804 : rsa_verify_signature,
805 : rsa_create_signature,
806 : 0
807 : };
808 :
809 : static const struct signature_alg rsa_with_sha384_alg = {
810 : "rsa-with-sha384",
811 : ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION,
812 : &_hx509_signature_rsa_with_sha384_data,
813 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
814 : &_hx509_signature_sha384_data,
815 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
816 : 0,
817 : NULL,
818 : rsa_verify_signature,
819 : rsa_create_signature,
820 : 0
821 : };
822 :
823 : static const struct signature_alg rsa_with_sha256_alg = {
824 : "rsa-with-sha256",
825 : ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION,
826 : &_hx509_signature_rsa_with_sha256_data,
827 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
828 : &_hx509_signature_sha256_data,
829 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
830 : 0,
831 : NULL,
832 : rsa_verify_signature,
833 : rsa_create_signature,
834 : 0
835 : };
836 :
837 : static const struct signature_alg rsa_with_sha1_alg = {
838 : "rsa-with-sha1",
839 : ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION,
840 : &_hx509_signature_rsa_with_sha1_data,
841 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
842 : &_hx509_signature_sha1_data,
843 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
844 : 0,
845 : NULL,
846 : rsa_verify_signature,
847 : rsa_create_signature,
848 : 0
849 : };
850 :
851 : static const struct signature_alg rsa_with_sha1_alg_secsig = {
852 : "rsa-with-sha1",
853 : ASN1_OID_ID_SECSIG_SHA_1WITHRSAENCRYPTION,
854 : &_hx509_signature_rsa_with_sha1_data,
855 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
856 : &_hx509_signature_sha1_data,
857 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
858 : 0,
859 : NULL,
860 : rsa_verify_signature,
861 : rsa_create_signature,
862 : 0
863 : };
864 :
865 : static const struct signature_alg rsa_with_md5_alg = {
866 : "rsa-with-md5",
867 : ASN1_OID_ID_PKCS1_MD5WITHRSAENCRYPTION,
868 : &_hx509_signature_rsa_with_md5_data,
869 : ASN1_OID_ID_PKCS1_RSAENCRYPTION,
870 : &_hx509_signature_md5_data,
871 : PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|WEAK_SIG_ALG,
872 : 1230739889,
873 : NULL,
874 : rsa_verify_signature,
875 : rsa_create_signature,
876 : 0
877 : };
878 :
879 : static const struct signature_alg dsa_sha1_alg = {
880 : "dsa-with-sha1",
881 : ASN1_OID_ID_DSA_WITH_SHA1,
882 : NULL,
883 : ASN1_OID_ID_DSA,
884 : &_hx509_signature_sha1_data,
885 : PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
886 : 0,
887 : NULL,
888 : dsa_verify_signature,
889 : /* create_signature */ NULL,
890 : 0
891 : };
892 :
893 : static const struct signature_alg sha512_alg = {
894 : "sha-512",
895 : ASN1_OID_ID_SHA512,
896 : &_hx509_signature_sha512_data,
897 : NULL,
898 : NULL,
899 : SIG_DIGEST,
900 : 0,
901 : EVP_sha512,
902 : evp_md_verify_signature,
903 : evp_md_create_signature,
904 : 0
905 : };
906 :
907 : static const struct signature_alg sha384_alg = {
908 : "sha-384",
909 : ASN1_OID_ID_SHA384,
910 : &_hx509_signature_sha384_data,
911 : NULL,
912 : NULL,
913 : SIG_DIGEST,
914 : 0,
915 : EVP_sha384,
916 : evp_md_verify_signature,
917 : evp_md_create_signature,
918 : 0
919 : };
920 :
921 : static const struct signature_alg sha256_alg = {
922 : "sha-256",
923 : ASN1_OID_ID_SHA256,
924 : &_hx509_signature_sha256_data,
925 : NULL,
926 : NULL,
927 : SIG_DIGEST,
928 : 0,
929 : EVP_sha256,
930 : evp_md_verify_signature,
931 : evp_md_create_signature,
932 : 0
933 : };
934 :
935 : static const struct signature_alg sha1_alg = {
936 : "sha1",
937 : ASN1_OID_ID_SECSIG_SHA_1,
938 : &_hx509_signature_sha1_data,
939 : NULL,
940 : NULL,
941 : SIG_DIGEST,
942 : 0,
943 : EVP_sha1,
944 : evp_md_verify_signature,
945 : evp_md_create_signature,
946 : 0
947 : };
948 :
949 : static const struct signature_alg md5_alg = {
950 : "rsa-md5",
951 : ASN1_OID_ID_RSA_DIGEST_MD5,
952 : &_hx509_signature_md5_data,
953 : NULL,
954 : NULL,
955 : SIG_DIGEST|WEAK_SIG_ALG,
956 : 0,
957 : EVP_md5,
958 : evp_md_verify_signature,
959 : NULL,
960 : 0
961 : };
962 :
963 : /*
964 : * Order matter in this structure, "best" first for each "key
965 : * compatible" type (type is ECDSA, RSA, DSA, none, etc)
966 : */
967 :
968 : static const struct signature_alg *sig_algs[] = {
969 : #ifdef HAVE_HCRYPTO_W_OPENSSL
970 : &ecdsa_with_sha512_alg,
971 : &ecdsa_with_sha384_alg,
972 : &ecdsa_with_sha256_alg,
973 : &ecdsa_with_sha1_alg,
974 : #endif
975 : &rsa_with_sha512_alg,
976 : &rsa_with_sha384_alg,
977 : &rsa_with_sha256_alg,
978 : &rsa_with_sha1_alg,
979 : &rsa_with_sha1_alg_secsig,
980 : &pkcs1_rsa_sha1_alg,
981 : &rsa_with_md5_alg,
982 : &heim_rsa_pkcs1_x509,
983 : &dsa_sha1_alg,
984 : &sha512_alg,
985 : &sha384_alg,
986 : &sha256_alg,
987 : &sha1_alg,
988 : &md5_alg,
989 : NULL
990 : };
991 :
992 : const struct signature_alg *
993 989 : _hx509_find_sig_alg(const heim_oid *oid)
994 : {
995 0 : unsigned int i;
996 6148 : for (i = 0; sig_algs[i]; i++)
997 6148 : if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
998 989 : return sig_algs[i];
999 0 : return NULL;
1000 : }
1001 :
1002 : static const AlgorithmIdentifier *
1003 130 : alg_for_privatekey(const hx509_private_key pk, int type)
1004 : {
1005 0 : const heim_oid *keytype;
1006 0 : unsigned int i;
1007 :
1008 130 : if (pk->ops == NULL)
1009 0 : return NULL;
1010 :
1011 130 : keytype = pk->ops->key_oid;
1012 :
1013 130 : for (i = 0; sig_algs[i]; i++) {
1014 130 : if (sig_algs[i]->key_oid == NULL)
1015 0 : continue;
1016 130 : if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
1017 0 : continue;
1018 130 : if (pk->ops->available &&
1019 0 : pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
1020 0 : continue;
1021 130 : if (type == HX509_SELECT_PUBLIC_SIG)
1022 65 : return sig_algs[i]->sig_alg;
1023 65 : if (type == HX509_SELECT_DIGEST)
1024 65 : return sig_algs[i]->digest_alg;
1025 :
1026 0 : return NULL;
1027 : }
1028 0 : return NULL;
1029 : }
1030 :
1031 : /*
1032 : *
1033 : */
1034 : #ifdef HAVE_HCRYPTO_W_OPENSSL
1035 : extern hx509_private_key_ops ecdsa_private_key_ops;
1036 : #endif
1037 :
1038 : static struct hx509_private_key_ops *private_algs[] = {
1039 : &rsa_private_key_ops,
1040 : #ifdef HAVE_HCRYPTO_W_OPENSSL
1041 : &ecdsa_private_key_ops,
1042 : #endif
1043 : NULL
1044 : };
1045 :
1046 : HX509_LIB_FUNCTION hx509_private_key_ops * HX509_LIB_CALL
1047 74 : hx509_find_private_alg(const heim_oid *oid)
1048 : {
1049 8 : int i;
1050 74 : for (i = 0; private_algs[i]; i++) {
1051 74 : if (private_algs[i]->key_oid == NULL)
1052 0 : continue;
1053 74 : if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
1054 74 : return private_algs[i];
1055 : }
1056 0 : return NULL;
1057 : }
1058 :
1059 : /*
1060 : * Check if the algorithm `alg' have a best before date, and if it
1061 : * des, make sure the its before the time `t'.
1062 : */
1063 :
1064 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1065 72 : _hx509_signature_is_weak(hx509_context context, const AlgorithmIdentifier *alg)
1066 : {
1067 0 : const struct signature_alg *md;
1068 :
1069 72 : md = _hx509_find_sig_alg(&alg->algorithm);
1070 72 : if (md == NULL) {
1071 0 : hx509_clear_error_string(context);
1072 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1073 : }
1074 72 : if (md->flags & WEAK_SIG_ALG) {
1075 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1076 0 : "Algorithm %s is weak", md->name);
1077 0 : return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1078 : }
1079 72 : return 0;
1080 : }
1081 :
1082 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1083 146 : _hx509_self_signed_valid(hx509_context context,
1084 : const AlgorithmIdentifier *alg)
1085 : {
1086 0 : const struct signature_alg *md;
1087 :
1088 146 : md = _hx509_find_sig_alg(&alg->algorithm);
1089 146 : if (md == NULL) {
1090 0 : hx509_clear_error_string(context);
1091 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1092 : }
1093 146 : if ((md->flags & SELF_SIGNED_OK) == 0) {
1094 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_ALGORITHM_BEST_BEFORE,
1095 : "Algorithm %s not trusted for self signatures",
1096 0 : md->name);
1097 0 : return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
1098 : }
1099 146 : return 0;
1100 : }
1101 :
1102 :
1103 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1104 478 : _hx509_verify_signature(hx509_context context,
1105 : const hx509_cert cert,
1106 : const AlgorithmIdentifier *alg,
1107 : const heim_octet_string *data,
1108 : const heim_octet_string *sig)
1109 : {
1110 0 : const struct signature_alg *md;
1111 478 : const Certificate *signer = NULL;
1112 :
1113 478 : if (cert)
1114 225 : signer = _hx509_get_cert(cert);
1115 :
1116 478 : md = _hx509_find_sig_alg(&alg->algorithm);
1117 478 : if (md == NULL) {
1118 0 : hx509_clear_error_string(context);
1119 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1120 : }
1121 478 : if (signer && (md->flags & PROVIDE_CONF) == 0) {
1122 0 : hx509_clear_error_string(context);
1123 0 : return HX509_CRYPTO_SIG_NO_CONF;
1124 : }
1125 478 : if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1126 0 : hx509_clear_error_string(context);
1127 0 : return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1128 : }
1129 478 : if (md->key_oid && signer) {
1130 0 : const SubjectPublicKeyInfo *spi;
1131 225 : spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1132 :
1133 225 : if (der_heim_oid_cmp(&spi->algorithm.algorithm, md->key_oid) != 0) {
1134 0 : hx509_clear_error_string(context);
1135 0 : return HX509_SIG_ALG_DONT_MATCH_KEY_ALG;
1136 : }
1137 : }
1138 478 : return (*md->verify_signature)(context, md, signer, alg, data, sig);
1139 : }
1140 :
1141 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1142 191 : _hx509_create_signature(hx509_context context,
1143 : const hx509_private_key signer,
1144 : const AlgorithmIdentifier *alg,
1145 : const heim_octet_string *data,
1146 : AlgorithmIdentifier *signatureAlgorithm,
1147 : heim_octet_string *sig)
1148 : {
1149 0 : const struct signature_alg *md;
1150 :
1151 191 : md = _hx509_find_sig_alg(&alg->algorithm);
1152 191 : if (md == NULL) {
1153 0 : hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1154 : "algorithm no supported");
1155 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1156 : }
1157 :
1158 191 : if (signer && (md->flags & PROVIDE_CONF) == 0) {
1159 0 : hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
1160 : "algorithm provides no conf");
1161 0 : return HX509_CRYPTO_SIG_NO_CONF;
1162 : }
1163 :
1164 191 : return (*md->create_signature)(context, md, signer, alg, data,
1165 : signatureAlgorithm, sig);
1166 : }
1167 :
1168 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1169 0 : _hx509_create_signature_bitstring(hx509_context context,
1170 : const hx509_private_key signer,
1171 : const AlgorithmIdentifier *alg,
1172 : const heim_octet_string *data,
1173 : AlgorithmIdentifier *signatureAlgorithm,
1174 : heim_bit_string *sig)
1175 : {
1176 0 : heim_octet_string os;
1177 0 : int ret;
1178 :
1179 0 : ret = _hx509_create_signature(context, signer, alg,
1180 : data, signatureAlgorithm, &os);
1181 0 : if (ret)
1182 0 : return ret;
1183 0 : sig->data = os.data;
1184 0 : sig->length = os.length * 8;
1185 0 : return 0;
1186 : }
1187 :
1188 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1189 21 : _hx509_public_encrypt(hx509_context context,
1190 : const heim_octet_string *cleartext,
1191 : const Certificate *cert,
1192 : heim_oid *encryption_oid,
1193 : heim_octet_string *ciphertext)
1194 : {
1195 0 : const SubjectPublicKeyInfo *spi;
1196 0 : unsigned char *to;
1197 0 : int tosize;
1198 0 : int ret;
1199 0 : RSA *rsa;
1200 0 : size_t size;
1201 0 : const unsigned char *p;
1202 :
1203 21 : ciphertext->data = NULL;
1204 21 : ciphertext->length = 0;
1205 :
1206 21 : spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1207 :
1208 21 : p = spi->subjectPublicKey.data;
1209 21 : size = spi->subjectPublicKey.length / 8;
1210 :
1211 21 : rsa = d2i_RSAPublicKey(NULL, &p, size);
1212 21 : if (rsa == NULL) {
1213 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1214 0 : return ENOMEM;
1215 : }
1216 :
1217 21 : tosize = RSA_size(rsa);
1218 21 : to = malloc(tosize);
1219 21 : if (to == NULL) {
1220 0 : RSA_free(rsa);
1221 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1222 0 : return ENOMEM;
1223 : }
1224 :
1225 21 : ret = RSA_public_encrypt(cleartext->length,
1226 21 : (unsigned char *)cleartext->data,
1227 : to, rsa, RSA_PKCS1_PADDING);
1228 21 : RSA_free(rsa);
1229 21 : if (ret <= 0) {
1230 0 : free(to);
1231 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PUBLIC_ENCRYPT,
1232 : "RSA public encrypt failed with %d", ret);
1233 0 : return HX509_CRYPTO_RSA_PUBLIC_ENCRYPT;
1234 : }
1235 21 : if (ret > tosize)
1236 0 : _hx509_abort("internal rsa decryption failure: ret > tosize");
1237 :
1238 21 : ciphertext->length = ret;
1239 21 : ciphertext->data = to;
1240 :
1241 21 : ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
1242 21 : if (ret) {
1243 0 : der_free_octet_string(ciphertext);
1244 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1245 0 : return ENOMEM;
1246 : }
1247 :
1248 21 : return 0;
1249 : }
1250 :
1251 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1252 0 : hx509_private_key_private_decrypt(hx509_context context,
1253 : const heim_octet_string *ciphertext,
1254 : const heim_oid *encryption_oid,
1255 : hx509_private_key p,
1256 : heim_octet_string *cleartext)
1257 : {
1258 0 : int ret;
1259 :
1260 0 : cleartext->data = NULL;
1261 0 : cleartext->length = 0;
1262 :
1263 0 : if (p->private_key.rsa == NULL) {
1264 0 : hx509_set_error_string(context, 0, HX509_PRIVATE_KEY_MISSING,
1265 : "Private RSA key missing");
1266 0 : return HX509_PRIVATE_KEY_MISSING;
1267 : }
1268 :
1269 0 : cleartext->length = RSA_size(p->private_key.rsa);
1270 0 : cleartext->data = malloc(cleartext->length);
1271 0 : if (cleartext->data == NULL) {
1272 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1273 0 : return ENOMEM;
1274 : }
1275 0 : ret = RSA_private_decrypt(ciphertext->length, ciphertext->data,
1276 0 : cleartext->data,
1277 : p->private_key.rsa,
1278 : RSA_PKCS1_PADDING);
1279 0 : if (ret <= 0) {
1280 0 : der_free_octet_string(cleartext);
1281 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_RSA_PRIVATE_DECRYPT,
1282 : "Failed to decrypt using private key: %d", ret);
1283 0 : return HX509_CRYPTO_RSA_PRIVATE_DECRYPT;
1284 : }
1285 0 : if (cleartext->length < (size_t)ret)
1286 0 : _hx509_abort("internal rsa decryption failure: ret > tosize");
1287 :
1288 0 : cleartext->length = ret;
1289 :
1290 0 : return 0;
1291 : }
1292 :
1293 :
1294 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1295 74 : hx509_parse_private_key(hx509_context context,
1296 : const AlgorithmIdentifier *keyai,
1297 : const void *data,
1298 : size_t len,
1299 : hx509_key_format_t format,
1300 : hx509_private_key *private_key)
1301 : {
1302 8 : struct hx509_private_key_ops *ops;
1303 8 : int ret;
1304 :
1305 74 : *private_key = NULL;
1306 :
1307 74 : ops = hx509_find_private_alg(&keyai->algorithm);
1308 74 : if (ops == NULL) {
1309 0 : hx509_clear_error_string(context);
1310 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1311 : }
1312 :
1313 74 : ret = hx509_private_key_init(private_key, ops, NULL);
1314 74 : if (ret) {
1315 0 : hx509_set_error_string(context, 0, ret, "out of memory");
1316 0 : return ret;
1317 : }
1318 :
1319 74 : ret = (*ops->import)(context, keyai, data, len, format, *private_key);
1320 74 : if (ret)
1321 0 : hx509_private_key_free(private_key);
1322 :
1323 74 : if (ret && format == HX509_KEY_FORMAT_PKCS8) {
1324 0 : PKCS8PrivateKeyInfo ki;
1325 0 : hx509_private_key key;
1326 :
1327 : /* Re-enter to try parsing the DER-encoded key from PKCS#8 envelope */
1328 0 : ret = decode_PKCS8PrivateKeyInfo(data, len, &ki, NULL);
1329 0 : if (ret) {
1330 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1331 : "Failed to parse PKCS#8-encoded private "
1332 : "key");
1333 0 : return HX509_PARSING_KEY_FAILED;
1334 : }
1335 0 : ret = hx509_parse_private_key(context, &ki.privateKeyAlgorithm,
1336 0 : ki.privateKey.data, ki.privateKey.length,
1337 : HX509_KEY_FORMAT_DER, &key);
1338 0 : free_PKCS8PrivateKeyInfo(&ki);
1339 0 : if (ret) {
1340 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1341 : "Failed to parse RSA key from PKCS#8 "
1342 : "envelope");
1343 0 : return HX509_PARSING_KEY_FAILED;
1344 : }
1345 0 : *private_key = key;
1346 : }
1347 66 : return ret;
1348 : }
1349 :
1350 : /*
1351 : *
1352 : */
1353 :
1354 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1355 0 : hx509_private_key2SPKI(hx509_context context,
1356 : hx509_private_key private_key,
1357 : SubjectPublicKeyInfo *spki)
1358 : {
1359 0 : const struct hx509_private_key_ops *ops = private_key->ops;
1360 0 : if (ops == NULL || ops->get_spki == NULL) {
1361 0 : hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1362 : "Private key have no key2SPKI function");
1363 0 : return HX509_UNIMPLEMENTED_OPERATION;
1364 : }
1365 0 : return (*ops->get_spki)(context, private_key, spki);
1366 : }
1367 :
1368 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1369 0 : _hx509_generate_private_key_init(hx509_context context,
1370 : const heim_oid *oid,
1371 : struct hx509_generate_private_context **ctx)
1372 : {
1373 0 : *ctx = NULL;
1374 :
1375 0 : if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
1376 0 : hx509_set_error_string(context, 0, EINVAL,
1377 : "private key not an RSA key");
1378 0 : return EINVAL;
1379 : }
1380 :
1381 0 : *ctx = calloc(1, sizeof(**ctx));
1382 0 : if (*ctx == NULL) {
1383 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1384 0 : return ENOMEM;
1385 : }
1386 0 : (*ctx)->key_oid = oid;
1387 :
1388 0 : return 0;
1389 : }
1390 :
1391 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1392 0 : _hx509_generate_private_key_is_ca(hx509_context context,
1393 : struct hx509_generate_private_context *ctx)
1394 : {
1395 0 : ctx->isCA = 1;
1396 0 : return 0;
1397 : }
1398 :
1399 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1400 0 : _hx509_generate_private_key_bits(hx509_context context,
1401 : struct hx509_generate_private_context *ctx,
1402 : unsigned long bits)
1403 : {
1404 0 : ctx->num_bits = bits;
1405 0 : return 0;
1406 : }
1407 :
1408 :
1409 : HX509_LIB_FUNCTION void HX509_LIB_CALL
1410 0 : _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1411 : {
1412 0 : free(*ctx);
1413 0 : *ctx = NULL;
1414 0 : }
1415 :
1416 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1417 0 : _hx509_generate_private_key(hx509_context context,
1418 : struct hx509_generate_private_context *ctx,
1419 : hx509_private_key *private_key)
1420 : {
1421 0 : struct hx509_private_key_ops *ops;
1422 0 : int ret;
1423 :
1424 0 : *private_key = NULL;
1425 :
1426 0 : ops = hx509_find_private_alg(ctx->key_oid);
1427 0 : if (ops == NULL) {
1428 0 : hx509_clear_error_string(context);
1429 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1430 : }
1431 :
1432 0 : ret = hx509_private_key_init(private_key, ops, NULL);
1433 0 : if (ret) {
1434 0 : hx509_set_error_string(context, 0, ret, "out of memory");
1435 0 : return ret;
1436 : }
1437 :
1438 0 : ret = (*ops->generate_private_key)(context, ctx, *private_key);
1439 0 : if (ret)
1440 0 : hx509_private_key_free(private_key);
1441 :
1442 0 : return ret;
1443 : }
1444 :
1445 : /*
1446 : *
1447 : */
1448 :
1449 : const AlgorithmIdentifier *
1450 37 : hx509_signature_sha512(void)
1451 37 : { return &_hx509_signature_sha512_data; }
1452 :
1453 : const AlgorithmIdentifier *
1454 0 : hx509_signature_sha384(void)
1455 0 : { return &_hx509_signature_sha384_data; }
1456 :
1457 : const AlgorithmIdentifier *
1458 24 : hx509_signature_sha256(void)
1459 24 : { return &_hx509_signature_sha256_data; }
1460 :
1461 : const AlgorithmIdentifier *
1462 8 : hx509_signature_sha1(void)
1463 8 : { return &_hx509_signature_sha1_data; }
1464 :
1465 : const AlgorithmIdentifier *
1466 0 : hx509_signature_md5(void)
1467 0 : { return &_hx509_signature_md5_data; }
1468 :
1469 : const AlgorithmIdentifier *
1470 0 : hx509_signature_rsa_with_sha512(void)
1471 0 : { return &_hx509_signature_rsa_with_sha512_data; }
1472 :
1473 : const AlgorithmIdentifier *
1474 0 : hx509_signature_rsa_with_sha384(void)
1475 0 : { return &_hx509_signature_rsa_with_sha384_data; }
1476 :
1477 : const AlgorithmIdentifier *
1478 0 : hx509_signature_rsa_with_sha256(void)
1479 0 : { return &_hx509_signature_rsa_with_sha256_data; }
1480 :
1481 : const AlgorithmIdentifier *
1482 4 : hx509_signature_rsa_with_sha1(void)
1483 4 : { return &_hx509_signature_rsa_with_sha1_data; }
1484 :
1485 : const AlgorithmIdentifier *
1486 0 : hx509_signature_rsa_with_md5(void)
1487 0 : { return &_hx509_signature_rsa_with_md5_data; }
1488 :
1489 : const AlgorithmIdentifier *
1490 74 : hx509_signature_rsa(void)
1491 74 : { return &_hx509_signature_rsa_data; }
1492 :
1493 : const AlgorithmIdentifier *
1494 0 : hx509_signature_rsa_pkcs1_x509(void)
1495 0 : { return &_hx509_signature_rsa_pkcs1_x509_data; }
1496 :
1497 : const AlgorithmIdentifier *
1498 128 : hx509_crypto_des_rsdi_ede3_cbc(void)
1499 128 : { return &_hx509_des_rsdi_ede3_cbc_oid; }
1500 :
1501 : const AlgorithmIdentifier *
1502 124 : hx509_crypto_aes128_cbc(void)
1503 124 : { return &_hx509_crypto_aes128_cbc_data; }
1504 :
1505 : const AlgorithmIdentifier *
1506 124 : hx509_crypto_aes256_cbc(void)
1507 124 : { return &_hx509_crypto_aes256_cbc_data; }
1508 :
1509 : /*
1510 : *
1511 : */
1512 :
1513 : const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
1514 : &_hx509_signature_rsa_with_sha256_data;
1515 : const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
1516 : &_hx509_signature_sha256_data;
1517 : const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
1518 : &_hx509_crypto_aes128_cbc_data;
1519 :
1520 : /*
1521 : *
1522 : */
1523 :
1524 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1525 74 : hx509_private_key_init(hx509_private_key *key,
1526 : hx509_private_key_ops *ops,
1527 : void *keydata)
1528 : {
1529 74 : *key = calloc(1, sizeof(**key));
1530 74 : if (*key == NULL)
1531 0 : return ENOMEM;
1532 74 : (*key)->ref = 1;
1533 74 : (*key)->ops = ops;
1534 74 : (*key)->private_key.keydata = keydata;
1535 74 : return 0;
1536 : }
1537 :
1538 : HX509_LIB_FUNCTION hx509_private_key HX509_LIB_CALL
1539 148 : _hx509_private_key_ref(hx509_private_key key)
1540 : {
1541 148 : if (key->ref == 0)
1542 0 : _hx509_abort("key refcount <= 0 on ref");
1543 148 : key->ref++;
1544 148 : if (key->ref == UINT_MAX)
1545 0 : _hx509_abort("key refcount == UINT_MAX on ref");
1546 148 : return key;
1547 : }
1548 :
1549 : HX509_LIB_FUNCTION const char * HX509_LIB_CALL
1550 0 : _hx509_private_pem_name(hx509_private_key key)
1551 : {
1552 0 : return key->ops->pemtype;
1553 : }
1554 :
1555 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1556 114 : hx509_private_key_free(hx509_private_key *key)
1557 : {
1558 114 : if (key == NULL || *key == NULL)
1559 0 : return 0;
1560 :
1561 114 : if ((*key)->ref == 0)
1562 0 : _hx509_abort("key refcount == 0 on free");
1563 114 : if (--(*key)->ref > 0)
1564 86 : return 0;
1565 :
1566 20 : if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
1567 20 : if ((*key)->private_key.rsa)
1568 20 : RSA_free((*key)->private_key.rsa);
1569 0 : } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid,
1570 0 : ASN1_OID_ID_ECPUBLICKEY) == 0 &&
1571 0 : (*key)->private_key.ecdsa != NULL) {
1572 0 : _hx509_private_eckey_free((*key)->private_key.ecdsa);
1573 : }
1574 20 : (*key)->private_key.rsa = NULL;
1575 20 : free(*key);
1576 20 : *key = NULL;
1577 20 : return 0;
1578 : }
1579 :
1580 : HX509_LIB_FUNCTION void HX509_LIB_CALL
1581 0 : hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
1582 : {
1583 0 : if (key->private_key.rsa)
1584 0 : RSA_free(key->private_key.rsa);
1585 0 : key->private_key.rsa = ptr;
1586 0 : key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
1587 0 : key->md = &pkcs1_rsa_sha1_alg;
1588 0 : }
1589 :
1590 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1591 0 : _hx509_private_key_oid(hx509_context context,
1592 : const hx509_private_key key,
1593 : heim_oid *data)
1594 : {
1595 0 : int ret;
1596 0 : ret = der_copy_oid(key->ops->key_oid, data);
1597 0 : if (ret)
1598 0 : hx509_set_error_string(context, 0, ret, "malloc out of memory");
1599 0 : return ret;
1600 : }
1601 :
1602 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1603 0 : _hx509_private_key_exportable(hx509_private_key key)
1604 : {
1605 0 : if (key->ops->export == NULL)
1606 0 : return 0;
1607 0 : return 1;
1608 : }
1609 :
1610 : HX509_LIB_FUNCTION BIGNUM * HX509_LIB_CALL
1611 0 : _hx509_private_key_get_internal(hx509_context context,
1612 : hx509_private_key key,
1613 : const char *type)
1614 : {
1615 0 : if (key->ops->get_internal == NULL)
1616 0 : return NULL;
1617 0 : return (*key->ops->get_internal)(context, key, type);
1618 : }
1619 :
1620 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1621 0 : _hx509_private_key_export(hx509_context context,
1622 : const hx509_private_key key,
1623 : hx509_key_format_t format,
1624 : heim_octet_string *data)
1625 : {
1626 0 : data->length = 0;
1627 0 : data->data = NULL;
1628 0 : if (key->ops->export == NULL) {
1629 0 : hx509_clear_error_string(context);
1630 0 : return HX509_UNIMPLEMENTED_OPERATION;
1631 : }
1632 0 : if (format == HX509_KEY_FORMAT_PKCS8) {
1633 0 : PKCS8PrivateKeyInfo ki;
1634 0 : size_t size;
1635 0 : int ret;
1636 :
1637 0 : memset(&ki, 0, sizeof(ki));
1638 0 : ki.attributes = NULL; /* No localKeyId needed */
1639 0 : ki.privateKey.data = NULL;
1640 0 : ki.privateKeyAlgorithm.algorithm.components = NULL;
1641 0 : ret = der_parse_hex_heim_integer("00", &ki.version);
1642 0 : if (ret == 0)
1643 0 : ret = _hx509_private_key_oid(context, key,
1644 : &ki.privateKeyAlgorithm.algorithm);
1645 0 : if (ret == 0)
1646 : /* Re-enter */
1647 0 : ret = _hx509_private_key_export(context, key, HX509_KEY_FORMAT_DER,
1648 : &ki.privateKey);
1649 :
1650 : /*
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.
1656 : */
1657 0 : ki.privateKeyAlgorithm.parameters = NULL;
1658 :
1659 0 : if (ret == 0)
1660 0 : ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, data->data, data->length,
1661 : &ki, &size, ret);
1662 0 : free_PKCS8PrivateKeyInfo(&ki);
1663 0 : if (ret == 0 && size != data->length)
1664 0 : ret = EINVAL;
1665 0 : if (ret)
1666 0 : hx509_set_error_string(context, 0, ret,
1667 : "Private key PKCS#8 encoding failed");
1668 0 : return ret;
1669 : }
1670 0 : return (*key->ops->export)(context, key, format, data);
1671 : }
1672 :
1673 : /*
1674 : *
1675 : */
1676 :
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 *);
1688 : };
1689 :
1690 : struct hx509_crypto_data {
1691 : char *name;
1692 : int flags;
1693 : #define ALLOW_WEAK 1
1694 :
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;
1703 : };
1704 :
1705 : /*
1706 : *
1707 : */
1708 :
1709 : static unsigned private_rc2_40_oid_data[] = { 127, 1 };
1710 :
1711 : static heim_oid asn1_oid_private_rc2_40 =
1712 : { 2, private_rc2_40_oid_data };
1713 :
1714 : /*
1715 : *
1716 : */
1717 :
1718 : static int
1719 21 : CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
1720 : const heim_octet_string *ivec, heim_octet_string *param)
1721 : {
1722 0 : size_t size;
1723 0 : int ret;
1724 :
1725 21 : assert(crypto->param == NULL);
1726 21 : if (ivec == NULL)
1727 0 : return 0;
1728 :
1729 21 : ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
1730 : ivec, &size, ret);
1731 21 : if (ret == 0 && size != param->length)
1732 0 : _hx509_abort("Internal asn1 encoder failure");
1733 21 : if (ret)
1734 0 : hx509_clear_error_string(context);
1735 21 : return ret;
1736 : }
1737 :
1738 : static int
1739 0 : CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
1740 : hx509_crypto crypto, heim_octet_string *ivec)
1741 : {
1742 0 : int ret;
1743 0 : if (ivec == NULL)
1744 0 : return 0;
1745 :
1746 0 : ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
1747 0 : if (ret)
1748 0 : hx509_clear_error_string(context);
1749 :
1750 0 : return ret;
1751 : }
1752 :
1753 : struct _RC2_params {
1754 : int maximum_effective_key;
1755 : };
1756 :
1757 : static int
1758 0 : CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
1759 : const heim_octet_string *ivec, heim_octet_string *param)
1760 : {
1761 0 : CMSRC2CBCParameter rc2params;
1762 0 : const struct _RC2_params *p = crypto->param;
1763 0 : int maximum_effective_key = 128;
1764 0 : size_t size;
1765 0 : int ret;
1766 :
1767 0 : memset(&rc2params, 0, sizeof(rc2params));
1768 :
1769 0 : if (p)
1770 0 : maximum_effective_key = p->maximum_effective_key;
1771 :
1772 0 : switch(maximum_effective_key) {
1773 0 : case 40:
1774 0 : rc2params.rc2ParameterVersion = 160;
1775 0 : break;
1776 0 : case 64:
1777 0 : rc2params.rc2ParameterVersion = 120;
1778 0 : break;
1779 0 : case 128:
1780 0 : rc2params.rc2ParameterVersion = 58;
1781 0 : break;
1782 : }
1783 0 : rc2params.iv = *ivec;
1784 :
1785 0 : ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
1786 : &rc2params, &size, ret);
1787 0 : if (ret == 0 && size != param->length)
1788 0 : _hx509_abort("Internal asn1 encoder failure");
1789 :
1790 0 : return ret;
1791 : }
1792 :
1793 : static int
1794 0 : CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
1795 : hx509_crypto crypto, heim_octet_string *ivec)
1796 : {
1797 0 : CMSRC2CBCParameter rc2param;
1798 0 : struct _RC2_params *p;
1799 0 : size_t size;
1800 0 : int ret;
1801 :
1802 0 : ret = decode_CMSRC2CBCParameter(param->data, param->length,
1803 : &rc2param, &size);
1804 0 : if (ret) {
1805 0 : hx509_clear_error_string(context);
1806 0 : return ret;
1807 : }
1808 :
1809 0 : p = calloc(1, sizeof(*p));
1810 0 : if (p == NULL) {
1811 0 : free_CMSRC2CBCParameter(&rc2param);
1812 0 : hx509_clear_error_string(context);
1813 0 : return ENOMEM;
1814 : }
1815 0 : switch(rc2param.rc2ParameterVersion) {
1816 0 : case 160:
1817 0 : crypto->c = EVP_rc2_40_cbc();
1818 0 : p->maximum_effective_key = 40;
1819 0 : break;
1820 0 : case 120:
1821 0 : crypto->c = EVP_rc2_64_cbc();
1822 0 : p->maximum_effective_key = 64;
1823 0 : break;
1824 0 : case 58:
1825 0 : crypto->c = EVP_rc2_cbc();
1826 0 : p->maximum_effective_key = 128;
1827 0 : break;
1828 0 : default:
1829 0 : free(p);
1830 0 : free_CMSRC2CBCParameter(&rc2param);
1831 0 : return HX509_CRYPTO_SIG_INVALID_FORMAT;
1832 : }
1833 0 : if (ivec)
1834 0 : ret = der_copy_octet_string(&rc2param.iv, ivec);
1835 0 : free_CMSRC2CBCParameter(&rc2param);
1836 0 : if (ret) {
1837 0 : free(p);
1838 0 : hx509_clear_error_string(context);
1839 : } else
1840 0 : crypto->param = p;
1841 :
1842 0 : return ret;
1843 : }
1844 :
1845 : /*
1846 : *
1847 : */
1848 :
1849 : static const struct hx509cipher ciphers[] = {
1850 : {
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
1858 : },
1859 : {
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
1867 : },
1868 : {
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
1876 : },
1877 : {
1878 : "des-ede3-cbc",
1879 : 0,
1880 : ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
1881 : NULL,
1882 : EVP_des_ede3_cbc,
1883 : CMSCBCParam_get,
1884 : CMSCBCParam_set
1885 : },
1886 : {
1887 : "des-ede3-cbc",
1888 : 0,
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
1894 : },
1895 : {
1896 : "aes-128-cbc",
1897 : 0,
1898 : ASN1_OID_ID_AES_128_CBC,
1899 : hx509_crypto_aes128_cbc,
1900 : EVP_aes_128_cbc,
1901 : CMSCBCParam_get,
1902 : CMSCBCParam_set
1903 : },
1904 : {
1905 : "aes-192-cbc",
1906 : 0,
1907 : ASN1_OID_ID_AES_192_CBC,
1908 : NULL,
1909 : EVP_aes_192_cbc,
1910 : CMSCBCParam_get,
1911 : CMSCBCParam_set
1912 : },
1913 : {
1914 : "aes-256-cbc",
1915 : 0,
1916 : ASN1_OID_ID_AES_256_CBC,
1917 : hx509_crypto_aes256_cbc,
1918 : EVP_aes_256_cbc,
1919 : CMSCBCParam_get,
1920 : CMSCBCParam_set
1921 : }
1922 : };
1923 :
1924 : static const struct hx509cipher *
1925 21 : find_cipher_by_oid(const heim_oid *oid)
1926 : {
1927 0 : size_t i;
1928 :
1929 156 : for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1930 156 : if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
1931 21 : return &ciphers[i];
1932 :
1933 0 : return NULL;
1934 : }
1935 :
1936 : static const struct hx509cipher *
1937 0 : find_cipher_by_name(const char *name)
1938 : {
1939 0 : size_t i;
1940 :
1941 0 : for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1942 0 : if (strcasecmp(name, ciphers[i].name) == 0)
1943 0 : return &ciphers[i];
1944 :
1945 0 : return NULL;
1946 : }
1947 :
1948 :
1949 : HX509_LIB_FUNCTION const heim_oid * HX509_LIB_CALL
1950 0 : hx509_crypto_enctype_by_name(const char *name)
1951 : {
1952 0 : const struct hx509cipher *cipher;
1953 :
1954 0 : cipher = find_cipher_by_name(name);
1955 0 : if (cipher == NULL)
1956 0 : return NULL;
1957 0 : return cipher->oid;
1958 : }
1959 :
1960 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1961 21 : hx509_crypto_init(hx509_context context,
1962 : const char *provider,
1963 : const heim_oid *enctype,
1964 : hx509_crypto *crypto)
1965 : {
1966 0 : const struct hx509cipher *cipher;
1967 :
1968 21 : *crypto = NULL;
1969 :
1970 21 : cipher = find_cipher_by_oid(enctype);
1971 21 : if (cipher == NULL) {
1972 0 : hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
1973 : "Algorithm not supported");
1974 0 : return HX509_ALG_NOT_SUPP;
1975 : }
1976 :
1977 21 : *crypto = calloc(1, sizeof(**crypto));
1978 21 : if (*crypto == NULL) {
1979 0 : hx509_clear_error_string(context);
1980 0 : return ENOMEM;
1981 : }
1982 :
1983 21 : (*crypto)->flags = PADDING_PKCS7;
1984 21 : (*crypto)->cipher = cipher;
1985 21 : (*crypto)->c = (*cipher->evp_func)();
1986 :
1987 21 : if (der_copy_oid(enctype, &(*crypto)->oid)) {
1988 0 : hx509_crypto_destroy(*crypto);
1989 0 : *crypto = NULL;
1990 0 : hx509_clear_error_string(context);
1991 0 : return ENOMEM;
1992 : }
1993 :
1994 21 : return 0;
1995 : }
1996 :
1997 : HX509_LIB_FUNCTION const char * HX509_LIB_CALL
1998 0 : hx509_crypto_provider(hx509_crypto crypto)
1999 : {
2000 0 : return "unknown";
2001 : }
2002 :
2003 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2004 21 : hx509_crypto_destroy(hx509_crypto crypto)
2005 : {
2006 21 : if (crypto->name)
2007 0 : free(crypto->name);
2008 21 : if (crypto->key.data)
2009 21 : free(crypto->key.data);
2010 21 : if (crypto->param)
2011 0 : free(crypto->param);
2012 21 : der_free_oid(&crypto->oid);
2013 21 : memset(crypto, 0, sizeof(*crypto));
2014 21 : free(crypto);
2015 21 : }
2016 :
2017 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2018 0 : hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2019 : {
2020 0 : return 0;
2021 : }
2022 :
2023 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2024 0 : hx509_crypto_allow_weak(hx509_crypto crypto)
2025 : {
2026 0 : crypto->flags |= ALLOW_WEAK;
2027 0 : }
2028 :
2029 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2030 0 : hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
2031 : {
2032 0 : switch (padding_type) {
2033 0 : case HX509_CRYPTO_PADDING_PKCS7:
2034 0 : crypto->flags &= ~PADDING_FLAGS;
2035 0 : crypto->flags |= PADDING_PKCS7;
2036 0 : break;
2037 0 : case HX509_CRYPTO_PADDING_NONE:
2038 0 : crypto->flags &= ~PADDING_FLAGS;
2039 0 : crypto->flags |= PADDING_NONE;
2040 0 : break;
2041 0 : default:
2042 0 : _hx509_abort("Invalid padding");
2043 : }
2044 0 : }
2045 :
2046 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2047 0 : hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2048 : {
2049 0 : if (EVP_CIPHER_key_length(crypto->c) > (int)length)
2050 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2051 :
2052 0 : if (crypto->key.data) {
2053 0 : free(crypto->key.data);
2054 0 : crypto->key.data = NULL;
2055 0 : crypto->key.length = 0;
2056 : }
2057 0 : crypto->key.data = malloc(length);
2058 0 : if (crypto->key.data == NULL)
2059 0 : return ENOMEM;
2060 0 : memcpy(crypto->key.data, data, length);
2061 0 : crypto->key.length = length;
2062 :
2063 0 : return 0;
2064 : }
2065 :
2066 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2067 21 : hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2068 : {
2069 21 : if (crypto->key.data) {
2070 0 : free(crypto->key.data);
2071 0 : crypto->key.length = 0;
2072 : }
2073 :
2074 21 : crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2075 21 : crypto->key.data = malloc(crypto->key.length);
2076 21 : if (crypto->key.data == NULL) {
2077 0 : crypto->key.length = 0;
2078 0 : return ENOMEM;
2079 : }
2080 21 : if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2081 0 : free(crypto->key.data);
2082 0 : crypto->key.data = NULL;
2083 0 : crypto->key.length = 0;
2084 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2085 : }
2086 21 : if (key)
2087 21 : return der_copy_octet_string(&crypto->key, key);
2088 : else
2089 0 : return 0;
2090 : }
2091 :
2092 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2093 0 : hx509_crypto_set_params(hx509_context context,
2094 : hx509_crypto crypto,
2095 : const heim_octet_string *param,
2096 : heim_octet_string *ivec)
2097 : {
2098 0 : return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2099 : }
2100 :
2101 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2102 21 : hx509_crypto_get_params(hx509_context context,
2103 : hx509_crypto crypto,
2104 : const heim_octet_string *ivec,
2105 : heim_octet_string *param)
2106 : {
2107 21 : return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2108 : }
2109 :
2110 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2111 21 : hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2112 : {
2113 21 : ivec->length = EVP_CIPHER_iv_length(crypto->c);
2114 21 : ivec->data = malloc(ivec->length);
2115 21 : if (ivec->data == NULL) {
2116 0 : ivec->length = 0;
2117 0 : return ENOMEM;
2118 : }
2119 :
2120 21 : if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2121 0 : free(ivec->data);
2122 0 : ivec->data = NULL;
2123 0 : ivec->length = 0;
2124 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2125 : }
2126 21 : return 0;
2127 : }
2128 :
2129 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2130 21 : 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)
2135 : {
2136 0 : EVP_CIPHER_CTX evp;
2137 0 : size_t padsize, bsize;
2138 0 : int ret;
2139 :
2140 21 : *ciphertext = NULL;
2141 :
2142 21 : if ((crypto->cipher->flags & CIPHER_WEAK) &&
2143 0 : (crypto->flags & ALLOW_WEAK) == 0)
2144 0 : return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2145 :
2146 21 : assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
2147 :
2148 21 : EVP_CIPHER_CTX_init(&evp);
2149 :
2150 21 : ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2151 21 : crypto->key.data, ivec->data, 1);
2152 21 : if (ret != 1) {
2153 0 : EVP_CIPHER_CTX_cleanup(&evp);
2154 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2155 0 : goto out;
2156 : }
2157 :
2158 21 : *ciphertext = calloc(1, sizeof(**ciphertext));
2159 21 : if (*ciphertext == NULL) {
2160 0 : ret = ENOMEM;
2161 0 : goto out;
2162 : }
2163 :
2164 21 : assert(crypto->flags & PADDING_FLAGS);
2165 :
2166 21 : bsize = EVP_CIPHER_block_size(crypto->c);
2167 21 : padsize = 0;
2168 :
2169 21 : if (crypto->flags & PADDING_NONE) {
2170 0 : if (bsize != 1 && (length % bsize) != 0)
2171 0 : return HX509_CMS_PADDING_ERROR;
2172 21 : } else if (crypto->flags & PADDING_PKCS7) {
2173 21 : if (bsize != 1)
2174 21 : padsize = bsize - (length % bsize);
2175 : }
2176 :
2177 21 : (*ciphertext)->length = length + padsize;
2178 21 : (*ciphertext)->data = malloc(length + padsize);
2179 21 : if ((*ciphertext)->data == NULL) {
2180 0 : ret = ENOMEM;
2181 0 : goto out;
2182 : }
2183 :
2184 21 : memcpy((*ciphertext)->data, data, length);
2185 21 : if (padsize) {
2186 0 : size_t i;
2187 21 : unsigned char *p = (*ciphertext)->data;
2188 21 : p += length;
2189 137 : for (i = 0; i < padsize; i++)
2190 116 : *p++ = padsize;
2191 : }
2192 :
2193 21 : ret = EVP_Cipher(&evp, (*ciphertext)->data,
2194 21 : (*ciphertext)->data,
2195 : length + padsize);
2196 21 : if (ret != 1) {
2197 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2198 0 : goto out;
2199 : }
2200 21 : ret = 0;
2201 :
2202 21 : out:
2203 21 : if (ret) {
2204 0 : if (*ciphertext) {
2205 0 : if ((*ciphertext)->data) {
2206 0 : free((*ciphertext)->data);
2207 : }
2208 0 : free(*ciphertext);
2209 0 : *ciphertext = NULL;
2210 : }
2211 : }
2212 21 : EVP_CIPHER_CTX_cleanup(&evp);
2213 :
2214 21 : return ret;
2215 : }
2216 :
2217 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2218 0 : 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)
2223 : {
2224 0 : EVP_CIPHER_CTX evp;
2225 0 : void *idata = NULL;
2226 0 : int ret;
2227 :
2228 0 : clear->data = NULL;
2229 0 : clear->length = 0;
2230 :
2231 0 : if ((crypto->cipher->flags & CIPHER_WEAK) &&
2232 0 : (crypto->flags & ALLOW_WEAK) == 0)
2233 0 : return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2234 :
2235 0 : if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length)
2236 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2237 :
2238 0 : if (crypto->key.data == NULL)
2239 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2240 :
2241 0 : if (ivec)
2242 0 : idata = ivec->data;
2243 :
2244 0 : EVP_CIPHER_CTX_init(&evp);
2245 :
2246 0 : ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2247 0 : crypto->key.data, idata, 0);
2248 0 : if (ret != 1) {
2249 0 : EVP_CIPHER_CTX_cleanup(&evp);
2250 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2251 : }
2252 :
2253 0 : clear->length = length;
2254 0 : clear->data = malloc(length);
2255 0 : if (clear->data == NULL) {
2256 0 : EVP_CIPHER_CTX_cleanup(&evp);
2257 0 : clear->length = 0;
2258 0 : return ENOMEM;
2259 : }
2260 :
2261 0 : if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2262 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2263 : }
2264 0 : EVP_CIPHER_CTX_cleanup(&evp);
2265 :
2266 0 : if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
2267 0 : int padsize;
2268 0 : unsigned char *p;
2269 0 : int j, bsize = EVP_CIPHER_block_size(crypto->c);
2270 :
2271 0 : if ((int)clear->length < bsize) {
2272 0 : ret = HX509_CMS_PADDING_ERROR;
2273 0 : goto out;
2274 : }
2275 :
2276 0 : p = clear->data;
2277 0 : p += clear->length - 1;
2278 0 : padsize = *p;
2279 0 : if (padsize > bsize) {
2280 0 : ret = HX509_CMS_PADDING_ERROR;
2281 0 : goto out;
2282 : }
2283 0 : clear->length -= padsize;
2284 0 : for (j = 0; j < padsize; j++) {
2285 0 : if (*p-- != padsize) {
2286 0 : ret = HX509_CMS_PADDING_ERROR;
2287 0 : goto out;
2288 : }
2289 : }
2290 : }
2291 :
2292 0 : return 0;
2293 :
2294 0 : out:
2295 0 : if (clear->data)
2296 0 : free(clear->data);
2297 0 : clear->data = NULL;
2298 0 : clear->length = 0;
2299 0 : return ret;
2300 : }
2301 :
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 *);
2308 :
2309 : static int
2310 0 : 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)
2317 : {
2318 0 : PKCS12_PBEParams p12params;
2319 0 : int passwordlen;
2320 0 : hx509_crypto c;
2321 0 : int iter, saltlen, ret;
2322 0 : unsigned char *salt;
2323 :
2324 0 : passwordlen = password ? strlen(password) : 0;
2325 :
2326 0 : if (parameters == NULL)
2327 0 : return HX509_ALG_NOT_SUPP;
2328 :
2329 0 : ret = decode_PKCS12_PBEParams(parameters->data,
2330 0 : parameters->length,
2331 : &p12params, NULL);
2332 0 : if (ret)
2333 0 : goto out;
2334 :
2335 0 : if (p12params.iterations)
2336 0 : iter = *p12params.iterations;
2337 : else
2338 0 : iter = 1;
2339 0 : salt = p12params.salt.data;
2340 0 : saltlen = p12params.salt.length;
2341 :
2342 0 : if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2343 : PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2344 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2345 0 : goto out;
2346 : }
2347 :
2348 0 : if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2349 : PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2350 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2351 0 : goto out;
2352 : }
2353 :
2354 0 : ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2355 0 : if (ret)
2356 0 : goto out;
2357 :
2358 0 : hx509_crypto_allow_weak(c);
2359 :
2360 0 : ret = hx509_crypto_set_key_data(c, key->data, key->length);
2361 0 : if (ret) {
2362 0 : hx509_crypto_destroy(c);
2363 0 : goto out;
2364 : }
2365 :
2366 0 : *crypto = c;
2367 0 : out:
2368 0 : free_PKCS12_PBEParams(&p12params);
2369 0 : return ret;
2370 : }
2371 :
2372 : static const heim_oid *
2373 0 : find_string2key(const heim_oid *oid,
2374 : const EVP_CIPHER **c,
2375 : const EVP_MD **md,
2376 : PBE_string2key_func *s2k)
2377 : {
2378 0 : if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
2379 0 : *c = EVP_rc2_40_cbc();
2380 0 : if (*c == NULL)
2381 0 : return NULL;
2382 0 : *md = EVP_sha1();
2383 0 : if (*md == NULL)
2384 0 : return NULL;
2385 0 : *s2k = PBE_string2key;
2386 0 : return &asn1_oid_private_rc2_40;
2387 0 : } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
2388 0 : *c = EVP_rc2_cbc();
2389 0 : if (*c == NULL)
2390 0 : return NULL;
2391 0 : *md = EVP_sha1();
2392 0 : if (*md == NULL)
2393 0 : return NULL;
2394 0 : *s2k = PBE_string2key;
2395 0 : 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 0 : } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
2417 0 : *c = EVP_des_ede3_cbc();
2418 0 : if (*c == NULL)
2419 0 : return NULL;
2420 0 : *md = EVP_sha1();
2421 0 : if (*md == NULL)
2422 0 : return NULL;
2423 0 : *s2k = PBE_string2key;
2424 0 : return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
2425 : }
2426 :
2427 0 : return NULL;
2428 : }
2429 :
2430 : /*
2431 : *
2432 : */
2433 :
2434 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2435 0 : _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)
2440 : {
2441 0 : hx509_clear_error_string(context);
2442 0 : return EINVAL;
2443 : }
2444 :
2445 : /*
2446 : *
2447 : */
2448 :
2449 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2450 0 : _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)
2455 : {
2456 0 : const struct _hx509_password *pw;
2457 0 : heim_octet_string key, iv;
2458 0 : const heim_oid *enc_oid;
2459 0 : const EVP_CIPHER *c;
2460 0 : const EVP_MD *md;
2461 0 : PBE_string2key_func s2k;
2462 0 : int ret = 0;
2463 0 : size_t i;
2464 :
2465 0 : memset(&key, 0, sizeof(key));
2466 0 : memset(&iv, 0, sizeof(iv));
2467 :
2468 0 : memset(content, 0, sizeof(*content));
2469 :
2470 0 : enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2471 0 : if (enc_oid == NULL) {
2472 0 : hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2473 : "String to key algorithm not supported");
2474 0 : ret = HX509_ALG_NOT_SUPP;
2475 0 : goto out;
2476 : }
2477 :
2478 0 : key.length = EVP_CIPHER_key_length(c);
2479 0 : key.data = malloc(key.length);
2480 0 : if (key.data == NULL) {
2481 0 : ret = ENOMEM;
2482 0 : hx509_clear_error_string(context);
2483 0 : goto out;
2484 : }
2485 :
2486 0 : iv.length = EVP_CIPHER_iv_length(c);
2487 0 : iv.data = malloc(iv.length);
2488 0 : if (iv.data == NULL) {
2489 0 : ret = ENOMEM;
2490 0 : hx509_clear_error_string(context);
2491 0 : goto out;
2492 : }
2493 :
2494 0 : pw = _hx509_lock_get_passwords(lock);
2495 :
2496 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2497 0 : for (i = 0; i < pw->len + 1; i++) {
2498 0 : hx509_crypto crypto;
2499 0 : const char *password;
2500 :
2501 0 : if (i < pw->len)
2502 0 : password = pw->val[i];
2503 0 : else if (i < pw->len + 1)
2504 0 : password = "";
2505 : else
2506 0 : password = NULL;
2507 :
2508 0 : ret = (*s2k)(context, password, ai->parameters, &crypto,
2509 : &key, &iv, enc_oid, md);
2510 0 : if (ret)
2511 0 : goto out;
2512 :
2513 0 : ret = hx509_crypto_decrypt(crypto,
2514 0 : econtent->data,
2515 0 : econtent->length,
2516 : &iv,
2517 : content);
2518 0 : hx509_crypto_destroy(crypto);
2519 0 : if (ret == 0)
2520 0 : goto out;
2521 :
2522 : }
2523 0 : out:
2524 0 : if (key.data)
2525 0 : der_free_octet_string(&key);
2526 0 : if (iv.data)
2527 0 : der_free_octet_string(&iv);
2528 0 : return ret;
2529 : }
2530 :
2531 : /*
2532 : *
2533 : */
2534 :
2535 :
2536 : static int
2537 74 : match_keys_rsa(hx509_cert c, hx509_private_key private_key)
2538 : {
2539 8 : const Certificate *cert;
2540 8 : const SubjectPublicKeyInfo *spi;
2541 8 : RSAPublicKey pk;
2542 8 : RSA *rsa;
2543 8 : size_t size;
2544 8 : int ret;
2545 :
2546 74 : if (private_key->private_key.rsa == NULL)
2547 0 : return 0;
2548 :
2549 74 : rsa = private_key->private_key.rsa;
2550 74 : if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2551 0 : return 0;
2552 :
2553 74 : cert = _hx509_get_cert(c);
2554 74 : spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2555 :
2556 74 : rsa = RSA_new();
2557 74 : if (rsa == NULL)
2558 0 : return 0;
2559 :
2560 82 : ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2561 74 : spi->subjectPublicKey.length / 8,
2562 : &pk, &size);
2563 74 : if (ret) {
2564 0 : RSA_free(rsa);
2565 0 : return 0;
2566 : }
2567 74 : rsa->n = heim_int2BN(&pk.modulus);
2568 74 : rsa->e = heim_int2BN(&pk.publicExponent);
2569 :
2570 74 : free_RSAPublicKey(&pk);
2571 :
2572 74 : rsa->d = BN_dup(private_key->private_key.rsa->d);
2573 74 : rsa->p = BN_dup(private_key->private_key.rsa->p);
2574 74 : rsa->q = BN_dup(private_key->private_key.rsa->q);
2575 74 : rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
2576 74 : rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
2577 74 : rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
2578 :
2579 74 : if (rsa->n == NULL || rsa->e == NULL ||
2580 74 : rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
2581 74 : rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
2582 0 : RSA_free(rsa);
2583 0 : return 0;
2584 : }
2585 :
2586 74 : ret = RSA_check_key(rsa);
2587 74 : RSA_free(rsa);
2588 :
2589 74 : return ret == 1;
2590 : }
2591 :
2592 : static int
2593 0 : match_keys_ec(hx509_cert c, hx509_private_key private_key)
2594 : {
2595 0 : return 1; /* XXX use EC_KEY_check_key */
2596 : }
2597 :
2598 :
2599 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2600 74 : _hx509_match_keys(hx509_cert c, hx509_private_key key)
2601 : {
2602 74 : if (!key->ops)
2603 0 : return 0;
2604 74 : if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
2605 74 : return match_keys_rsa(c, key);
2606 0 : if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
2607 0 : return match_keys_ec(c, key);
2608 0 : return 0;
2609 :
2610 : }
2611 :
2612 :
2613 : static const heim_oid *
2614 102 : find_keytype(const hx509_private_key key)
2615 : {
2616 0 : const struct signature_alg *md;
2617 :
2618 102 : if (key == NULL)
2619 0 : return NULL;
2620 :
2621 102 : md = _hx509_find_sig_alg(key->signature_alg);
2622 102 : if (md == NULL)
2623 0 : return NULL;
2624 102 : return md->key_oid;
2625 : }
2626 :
2627 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2628 130 : hx509_crypto_select(const hx509_context context,
2629 : int type,
2630 : const hx509_private_key source,
2631 : hx509_peer_info peer,
2632 : AlgorithmIdentifier *selected)
2633 : {
2634 130 : const AlgorithmIdentifier *def = NULL;
2635 0 : size_t i, j;
2636 0 : int ret, bits;
2637 :
2638 130 : memset(selected, 0, sizeof(*selected));
2639 :
2640 130 : if (type == HX509_SELECT_DIGEST) {
2641 65 : bits = SIG_DIGEST;
2642 65 : if (source)
2643 65 : def = alg_for_privatekey(source, type);
2644 65 : if (def == NULL)
2645 0 : def = _hx509_crypto_default_digest_alg;
2646 65 : } else if (type == HX509_SELECT_PUBLIC_SIG) {
2647 65 : bits = SIG_PUBLIC_SIG;
2648 : /* XXX depend on `source´ and `peer´ */
2649 65 : if (source)
2650 65 : def = alg_for_privatekey(source, type);
2651 65 : if (def == NULL)
2652 0 : def = _hx509_crypto_default_sig_alg;
2653 0 : } else if (type == HX509_SELECT_SECRET_ENC) {
2654 0 : bits = SIG_SECRET;
2655 0 : def = _hx509_crypto_default_secret_alg;
2656 : } else {
2657 0 : hx509_set_error_string(context, 0, EINVAL,
2658 : "Unknown type %d of selection", type);
2659 0 : return EINVAL;
2660 : }
2661 :
2662 130 : if (peer) {
2663 82 : const heim_oid *keytype = NULL;
2664 :
2665 82 : keytype = find_keytype(source);
2666 :
2667 222 : for (i = 0; i < peer->len; i++) {
2668 2383 : for (j = 0; sig_algs[j]; j++) {
2669 2243 : if ((sig_algs[j]->flags & bits) != bits)
2670 1397 : continue;
2671 846 : if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
2672 846 : &peer->val[i].algorithm) != 0)
2673 788 : continue;
2674 99 : if (keytype && sig_algs[j]->key_oid &&
2675 41 : der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
2676 0 : continue;
2677 :
2678 : /* found one, use that */
2679 58 : ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
2680 58 : if (ret)
2681 0 : hx509_clear_error_string(context);
2682 58 : return ret;
2683 : }
2684 140 : if (bits & SIG_SECRET) {
2685 0 : const struct hx509cipher *cipher;
2686 :
2687 0 : cipher = find_cipher_by_oid(&peer->val[i].algorithm);
2688 0 : if (cipher == NULL)
2689 0 : continue;
2690 0 : if (cipher->ai_func == NULL)
2691 0 : continue;
2692 0 : ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
2693 0 : if (ret)
2694 0 : hx509_clear_error_string(context);
2695 0 : return ret;
2696 : }
2697 : }
2698 : }
2699 :
2700 : /* use default */
2701 72 : ret = copy_AlgorithmIdentifier(def, selected);
2702 72 : if (ret)
2703 0 : hx509_clear_error_string(context);
2704 72 : return ret;
2705 : }
2706 :
2707 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2708 124 : hx509_crypto_available(hx509_context context,
2709 : int type,
2710 : hx509_cert source,
2711 : AlgorithmIdentifier **val,
2712 : unsigned int *plen)
2713 : {
2714 124 : const heim_oid *keytype = NULL;
2715 0 : unsigned int len, i;
2716 0 : void *ptr;
2717 0 : int bits, ret;
2718 :
2719 124 : *val = NULL;
2720 :
2721 124 : if (type == HX509_SELECT_ALL) {
2722 124 : bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
2723 0 : } else if (type == HX509_SELECT_DIGEST) {
2724 0 : bits = SIG_DIGEST;
2725 0 : } else if (type == HX509_SELECT_PUBLIC_SIG) {
2726 0 : bits = SIG_PUBLIC_SIG;
2727 : } else {
2728 0 : hx509_set_error_string(context, 0, EINVAL,
2729 : "Unknown type %d of available", type);
2730 0 : return EINVAL;
2731 : }
2732 :
2733 124 : if (source)
2734 20 : keytype = find_keytype(_hx509_cert_private_key(source));
2735 :
2736 124 : len = 0;
2737 1860 : for (i = 0; sig_algs[i]; i++) {
2738 1736 : if ((sig_algs[i]->flags & bits) == 0)
2739 0 : continue;
2740 1736 : if (sig_algs[i]->sig_alg == NULL)
2741 124 : continue;
2742 1772 : if (keytype && sig_algs[i]->key_oid &&
2743 160 : der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
2744 0 : continue;
2745 :
2746 : /* found one, add that to the list */
2747 1612 : ptr = realloc(*val, sizeof(**val) * (len + 1));
2748 1612 : if (ptr == NULL)
2749 0 : goto out;
2750 1612 : *val = ptr;
2751 :
2752 1612 : ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
2753 1612 : if (ret)
2754 0 : goto out;
2755 1612 : len++;
2756 : }
2757 :
2758 : /* Add AES */
2759 124 : if (bits & SIG_SECRET) {
2760 :
2761 1116 : for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
2762 :
2763 992 : if (ciphers[i].flags & CIPHER_WEAK)
2764 372 : continue;
2765 620 : if (ciphers[i].ai_func == NULL)
2766 248 : continue;
2767 :
2768 372 : ptr = realloc(*val, sizeof(**val) * (len + 1));
2769 372 : if (ptr == NULL)
2770 0 : goto out;
2771 372 : *val = ptr;
2772 :
2773 372 : ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
2774 372 : if (ret)
2775 0 : goto out;
2776 372 : len++;
2777 : }
2778 : }
2779 :
2780 124 : *plen = len;
2781 124 : return 0;
2782 :
2783 0 : out:
2784 0 : for (i = 0; i < len; i++)
2785 0 : free_AlgorithmIdentifier(&(*val)[i]);
2786 0 : free(*val);
2787 0 : *val = NULL;
2788 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
2789 0 : return ENOMEM;
2790 : }
2791 :
2792 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2793 0 : hx509_crypto_free_algs(AlgorithmIdentifier *val,
2794 : unsigned int len)
2795 : {
2796 0 : unsigned int i;
2797 0 : for (i = 0; i < len; i++)
2798 0 : free_AlgorithmIdentifier(&val[i]);
2799 0 : free(val);
2800 0 : }
|