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 76 : heim_int2BN(const heim_integer *i)
127 : {
128 : BIGNUM *bn;
129 :
130 76 : bn = BN_bin2bn(i->data, i->length, NULL);
131 76 : BN_set_negative(bn, i->negative);
132 76 : return bn;
133 : }
134 :
135 : /*
136 : *
137 : */
138 :
139 : HX509_LIB_FUNCTION int HX509_LIB_CALL
140 0 : _hx509_set_digest_alg(DigestAlgorithmIdentifier *id,
141 : const heim_oid *oid,
142 : const void *param, size_t length)
143 : {
144 : int ret;
145 0 : if (param) {
146 0 : id->parameters = malloc(sizeof(*id->parameters));
147 0 : if (id->parameters == NULL)
148 0 : return ENOMEM;
149 0 : id->parameters->data = malloc(length);
150 0 : if (id->parameters->data == NULL) {
151 0 : free(id->parameters);
152 0 : id->parameters = NULL;
153 0 : return ENOMEM;
154 : }
155 0 : memcpy(id->parameters->data, param, length);
156 0 : id->parameters->length = length;
157 : } else
158 0 : id->parameters = NULL;
159 0 : ret = der_copy_oid(oid, &id->algorithm);
160 0 : 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 0 : return 0;
169 : }
170 :
171 : /*
172 : *
173 : */
174 :
175 : static int
176 0 : 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 : const SubjectPublicKeyInfo *spi;
184 : DigestInfo di;
185 : unsigned char *to;
186 : int tosize, retsize;
187 : int ret;
188 : RSA *rsa;
189 : size_t size;
190 : const unsigned char *p;
191 :
192 0 : memset(&di, 0, sizeof(di));
193 :
194 0 : spi = &signer->tbsCertificate.subjectPublicKeyInfo;
195 :
196 0 : p = spi->subjectPublicKey.data;
197 0 : size = spi->subjectPublicKey.length / 8;
198 :
199 0 : rsa = d2i_RSAPublicKey(NULL, &p, size);
200 0 : 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 0 : tosize = RSA_size(rsa);
207 0 : to = malloc(tosize);
208 0 : 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 0 : retsize = RSA_public_decrypt(sig->length, (unsigned char *)sig->data,
215 : to, rsa, RSA_PKCS1_PADDING);
216 0 : 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 0 : if (retsize > tosize)
224 0 : _hx509_abort("internal rsa decryption failure: ret > tosize");
225 :
226 0 : if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
227 :
228 0 : ret = decode_DigestInfo(to, retsize, &di, &size);
229 0 : free(to);
230 0 : if (ret) {
231 0 : goto out;
232 : }
233 :
234 : /* Check for extra data inside the sigature */
235 0 : 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 0 : if (sig_alg->digest_alg &&
242 0 : der_heim_oid_cmp(&di.digestAlgorithm.algorithm,
243 0 : &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 0 : if (di.digestAlgorithm.parameters != NULL &&
252 0 : (di.digestAlgorithm.parameters->length != 2 ||
253 0 : 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 0 : ret = _hx509_verify_signature(context,
261 : NULL,
262 : &di.digestAlgorithm,
263 : data,
264 : &di.digest);
265 0 : 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 0 : out:
281 0 : free_DigestInfo(&di);
282 0 : if (rsa)
283 0 : RSA_free(rsa);
284 0 : return ret;
285 : }
286 :
287 : static int
288 0 : 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 : const AlgorithmIdentifier *digest_alg;
297 : heim_octet_string indata;
298 : const heim_oid *sig_oid;
299 : size_t size;
300 : int ret;
301 :
302 0 : 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 0 : if (alg)
306 0 : sig_oid = &alg->algorithm;
307 : else
308 0 : sig_oid = signer->signature_alg;
309 :
310 0 : if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA512WITHRSAENCRYPTION) == 0) {
311 0 : digest_alg = hx509_signature_sha512();
312 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA384WITHRSAENCRYPTION) == 0) {
313 0 : digest_alg = hx509_signature_sha384();
314 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA256WITHRSAENCRYPTION) == 0) {
315 0 : digest_alg = hx509_signature_sha256();
316 0 : } else if (der_heim_oid_cmp(sig_oid, ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION) == 0) {
317 0 : 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 0 : if (signatureAlgorithm) {
332 0 : ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid,
333 : "\x05\x00", 2);
334 0 : if (ret) {
335 0 : hx509_clear_error_string(context);
336 0 : return ret;
337 : }
338 : }
339 :
340 0 : if (digest_alg) {
341 : DigestInfo di;
342 0 : memset(&di, 0, sizeof(di));
343 :
344 0 : ret = _hx509_create_signature(context,
345 : NULL,
346 : digest_alg,
347 : data,
348 : &di.digestAlgorithm,
349 : &di.digest);
350 0 : if (ret)
351 0 : return ret;
352 0 : ASN1_MALLOC_ENCODE(DigestInfo,
353 : indata.data,
354 : indata.length,
355 : &di,
356 : &size,
357 : ret);
358 0 : free_DigestInfo(&di);
359 0 : if (ret) {
360 0 : hx509_set_error_string(context, 0, ret, "out of memory");
361 0 : return ret;
362 : }
363 0 : if (indata.length != size)
364 0 : _hx509_abort("internal ASN.1 encoder error");
365 : } else {
366 0 : indata = *data;
367 : }
368 :
369 0 : sig->length = RSA_size(signer->private_key.rsa);
370 0 : sig->data = malloc(sig->length);
371 0 : 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 0 : ret = RSA_private_encrypt(indata.length, indata.data,
378 0 : sig->data,
379 : signer->private_key.rsa,
380 : RSA_PKCS1_PADDING);
381 0 : if (indata.data != data->data)
382 0 : der_free_octet_string(&indata);
383 0 : 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 0 : 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 0 : } else if (sig->length < (size_t)ret)
394 0 : _hx509_abort("RSA signature prelen longer the output len");
395 :
396 0 : return 0;
397 : }
398 :
399 : static int
400 38 : 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 38 : switch (format) {
408 38 : case HX509_KEY_FORMAT_DER: {
409 38 : const unsigned char *p = data;
410 :
411 38 : private_key->private_key.rsa =
412 38 : d2i_RSAPrivateKey(NULL, &p, len);
413 38 : 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 38 : private_key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
419 38 : break;
420 :
421 : }
422 0 : default:
423 0 : return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
424 : }
425 :
426 38 : 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 : 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 : BIGNUM *e;
474 : int ret;
475 : unsigned long bits;
476 :
477 : static const int default_rsa_e = 65537;
478 : 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 : 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 : const SubjectPublicKeyInfo *spi;
588 : DSAPublicKey pk;
589 : DSAParams param;
590 : size_t size;
591 : DSA *dsa;
592 : 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 0 : 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 0 : size_t sigsize = EVP_MD_size(sig_alg->evp_md());
697 : EVP_MD_CTX *ctx;
698 :
699 0 : memset(sig, 0, sizeof(*sig));
700 :
701 0 : if (signatureAlgorithm) {
702 : int ret;
703 0 : ret = _hx509_set_digest_alg(signatureAlgorithm,
704 0 : sig_alg->sig_oid, "\x05\x00", 2);
705 0 : if (ret)
706 0 : return ret;
707 : }
708 :
709 :
710 0 : sig->data = malloc(sigsize);
711 0 : if (sig->data == NULL) {
712 0 : sig->length = 0;
713 0 : return ENOMEM;
714 : }
715 0 : sig->length = sigsize;
716 :
717 0 : ctx = EVP_MD_CTX_create();
718 0 : EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
719 0 : EVP_DigestUpdate(ctx, data->data, data->length);
720 0 : EVP_DigestFinal_ex(ctx, sig->data, NULL);
721 0 : EVP_MD_CTX_destroy(ctx);
722 :
723 :
724 0 : return 0;
725 : }
726 :
727 : static int
728 0 : 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 : unsigned char digest[EVP_MAX_MD_SIZE];
736 : EVP_MD_CTX *ctx;
737 0 : size_t sigsize = EVP_MD_size(sig_alg->evp_md());
738 :
739 0 : if (sig->length != sigsize || sigsize > sizeof(digest)) {
740 0 : hx509_set_error_string(context, 0, HX509_CRYPTO_SIG_INVALID_FORMAT,
741 : "SHA256 sigature have wrong length");
742 0 : return HX509_CRYPTO_SIG_INVALID_FORMAT;
743 : }
744 :
745 0 : ctx = EVP_MD_CTX_create();
746 0 : EVP_DigestInit_ex(ctx, sig_alg->evp_md(), NULL);
747 0 : EVP_DigestUpdate(ctx, data->data, data->length);
748 0 : EVP_DigestFinal_ex(ctx, digest, NULL);
749 0 : EVP_MD_CTX_destroy(ctx);
750 :
751 0 : 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 0 : 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 0 : _hx509_find_sig_alg(const heim_oid *oid)
994 : {
995 : unsigned int i;
996 0 : for (i = 0; sig_algs[i]; i++)
997 0 : if (der_heim_oid_cmp(sig_algs[i]->sig_oid, oid) == 0)
998 0 : return sig_algs[i];
999 0 : return NULL;
1000 : }
1001 :
1002 : static const AlgorithmIdentifier *
1003 0 : alg_for_privatekey(const hx509_private_key pk, int type)
1004 : {
1005 : const heim_oid *keytype;
1006 : unsigned int i;
1007 :
1008 0 : if (pk->ops == NULL)
1009 0 : return NULL;
1010 :
1011 0 : keytype = pk->ops->key_oid;
1012 :
1013 0 : for (i = 0; sig_algs[i]; i++) {
1014 0 : if (sig_algs[i]->key_oid == NULL)
1015 0 : continue;
1016 0 : if (der_heim_oid_cmp(sig_algs[i]->key_oid, keytype) != 0)
1017 0 : continue;
1018 0 : if (pk->ops->available &&
1019 0 : pk->ops->available(pk, sig_algs[i]->sig_alg) == 0)
1020 0 : continue;
1021 0 : if (type == HX509_SELECT_PUBLIC_SIG)
1022 0 : return sig_algs[i]->sig_alg;
1023 0 : if (type == HX509_SELECT_DIGEST)
1024 0 : 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 38 : hx509_find_private_alg(const heim_oid *oid)
1048 : {
1049 : int i;
1050 38 : for (i = 0; private_algs[i]; i++) {
1051 38 : if (private_algs[i]->key_oid == NULL)
1052 0 : continue;
1053 38 : if (der_heim_oid_cmp(private_algs[i]->key_oid, oid) == 0)
1054 38 : 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 0 : _hx509_signature_is_weak(hx509_context context, const AlgorithmIdentifier *alg)
1066 : {
1067 : const struct signature_alg *md;
1068 :
1069 0 : md = _hx509_find_sig_alg(&alg->algorithm);
1070 0 : if (md == NULL) {
1071 0 : hx509_clear_error_string(context);
1072 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1073 : }
1074 0 : 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 0 : return 0;
1080 : }
1081 :
1082 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1083 0 : _hx509_self_signed_valid(hx509_context context,
1084 : const AlgorithmIdentifier *alg)
1085 : {
1086 : const struct signature_alg *md;
1087 :
1088 0 : md = _hx509_find_sig_alg(&alg->algorithm);
1089 0 : if (md == NULL) {
1090 0 : hx509_clear_error_string(context);
1091 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1092 : }
1093 0 : 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 0 : return 0;
1100 : }
1101 :
1102 :
1103 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1104 0 : _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 : const struct signature_alg *md;
1111 0 : const Certificate *signer = NULL;
1112 :
1113 0 : if (cert)
1114 0 : signer = _hx509_get_cert(cert);
1115 :
1116 0 : md = _hx509_find_sig_alg(&alg->algorithm);
1117 0 : if (md == NULL) {
1118 0 : hx509_clear_error_string(context);
1119 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1120 : }
1121 0 : if (signer && (md->flags & PROVIDE_CONF) == 0) {
1122 0 : hx509_clear_error_string(context);
1123 0 : return HX509_CRYPTO_SIG_NO_CONF;
1124 : }
1125 0 : if (signer == NULL && (md->flags & REQUIRE_SIGNER)) {
1126 0 : hx509_clear_error_string(context);
1127 0 : return HX509_CRYPTO_SIGNATURE_WITHOUT_SIGNER;
1128 : }
1129 0 : if (md->key_oid && signer) {
1130 : const SubjectPublicKeyInfo *spi;
1131 0 : spi = &signer->tbsCertificate.subjectPublicKeyInfo;
1132 :
1133 0 : 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 0 : return (*md->verify_signature)(context, md, signer, alg, data, sig);
1139 : }
1140 :
1141 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1142 0 : _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 : const struct signature_alg *md;
1150 :
1151 0 : md = _hx509_find_sig_alg(&alg->algorithm);
1152 0 : 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 0 : 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 0 : 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 : heim_octet_string os;
1177 : 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 0 : _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 : const SubjectPublicKeyInfo *spi;
1196 : unsigned char *to;
1197 : int tosize;
1198 : int ret;
1199 : RSA *rsa;
1200 : size_t size;
1201 : const unsigned char *p;
1202 :
1203 0 : ciphertext->data = NULL;
1204 0 : ciphertext->length = 0;
1205 :
1206 0 : spi = &cert->tbsCertificate.subjectPublicKeyInfo;
1207 :
1208 0 : p = spi->subjectPublicKey.data;
1209 0 : size = spi->subjectPublicKey.length / 8;
1210 :
1211 0 : rsa = d2i_RSAPublicKey(NULL, &p, size);
1212 0 : if (rsa == NULL) {
1213 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1214 0 : return ENOMEM;
1215 : }
1216 :
1217 0 : tosize = RSA_size(rsa);
1218 0 : to = malloc(tosize);
1219 0 : 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 0 : ret = RSA_public_encrypt(cleartext->length,
1226 0 : (unsigned char *)cleartext->data,
1227 : to, rsa, RSA_PKCS1_PADDING);
1228 0 : RSA_free(rsa);
1229 0 : 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 0 : if (ret > tosize)
1236 0 : _hx509_abort("internal rsa decryption failure: ret > tosize");
1237 :
1238 0 : ciphertext->length = ret;
1239 0 : ciphertext->data = to;
1240 :
1241 0 : ret = der_copy_oid(ASN1_OID_ID_PKCS1_RSAENCRYPTION, encryption_oid);
1242 0 : 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 0 : 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 : 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 38 : 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 : struct hx509_private_key_ops *ops;
1303 : int ret;
1304 :
1305 38 : *private_key = NULL;
1306 :
1307 38 : if (format == HX509_KEY_FORMAT_PKCS8) {
1308 : PKCS8PrivateKeyInfo ki;
1309 : hx509_private_key key;
1310 :
1311 0 : ret = decode_PKCS8PrivateKeyInfo(data, len, &ki, NULL);
1312 0 : if (ret) {
1313 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1314 : "Failed to parse PKCS#8-encoded private "
1315 : "key");
1316 0 : return HX509_PARSING_KEY_FAILED;
1317 : }
1318 :
1319 : /* Re-enter to parse DER-encoded key from PKCS#8 envelope */
1320 0 : ret = hx509_parse_private_key(context, &ki.privateKeyAlgorithm,
1321 0 : ki.privateKey.data, ki.privateKey.length,
1322 : HX509_KEY_FORMAT_DER, &key);
1323 0 : free_PKCS8PrivateKeyInfo(&ki);
1324 0 : if (ret) {
1325 0 : hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
1326 : "Failed to parse RSA key from PKCS#8 "
1327 : "envelope");
1328 0 : return HX509_PARSING_KEY_FAILED;
1329 : }
1330 :
1331 0 : *private_key = key;
1332 0 : return ret;
1333 : }
1334 :
1335 38 : ops = hx509_find_private_alg(&keyai->algorithm);
1336 38 : if (ops == NULL) {
1337 0 : hx509_clear_error_string(context);
1338 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1339 : }
1340 :
1341 38 : ret = hx509_private_key_init(private_key, ops, NULL);
1342 38 : if (ret) {
1343 0 : hx509_set_error_string(context, 0, ret, "out of memory");
1344 0 : return ret;
1345 : }
1346 :
1347 38 : ret = (*ops->import)(context, keyai, data, len, format, *private_key);
1348 38 : if (ret)
1349 0 : hx509_private_key_free(private_key);
1350 :
1351 38 : return ret;
1352 : }
1353 :
1354 : /*
1355 : *
1356 : */
1357 :
1358 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1359 0 : hx509_private_key2SPKI(hx509_context context,
1360 : hx509_private_key private_key,
1361 : SubjectPublicKeyInfo *spki)
1362 : {
1363 0 : const struct hx509_private_key_ops *ops = private_key->ops;
1364 0 : if (ops == NULL || ops->get_spki == NULL) {
1365 0 : hx509_set_error_string(context, 0, HX509_UNIMPLEMENTED_OPERATION,
1366 : "Private key have no key2SPKI function");
1367 0 : return HX509_UNIMPLEMENTED_OPERATION;
1368 : }
1369 0 : return (*ops->get_spki)(context, private_key, spki);
1370 : }
1371 :
1372 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1373 0 : _hx509_generate_private_key_init(hx509_context context,
1374 : const heim_oid *oid,
1375 : struct hx509_generate_private_context **ctx)
1376 : {
1377 0 : *ctx = NULL;
1378 :
1379 0 : if (der_heim_oid_cmp(oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) != 0) {
1380 0 : hx509_set_error_string(context, 0, EINVAL,
1381 : "private key not an RSA key");
1382 0 : return EINVAL;
1383 : }
1384 :
1385 0 : *ctx = calloc(1, sizeof(**ctx));
1386 0 : if (*ctx == NULL) {
1387 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
1388 0 : return ENOMEM;
1389 : }
1390 0 : (*ctx)->key_oid = oid;
1391 :
1392 0 : return 0;
1393 : }
1394 :
1395 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1396 0 : _hx509_generate_private_key_is_ca(hx509_context context,
1397 : struct hx509_generate_private_context *ctx)
1398 : {
1399 0 : ctx->isCA = 1;
1400 0 : return 0;
1401 : }
1402 :
1403 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1404 0 : _hx509_generate_private_key_bits(hx509_context context,
1405 : struct hx509_generate_private_context *ctx,
1406 : unsigned long bits)
1407 : {
1408 0 : ctx->num_bits = bits;
1409 0 : return 0;
1410 : }
1411 :
1412 :
1413 : HX509_LIB_FUNCTION void HX509_LIB_CALL
1414 0 : _hx509_generate_private_key_free(struct hx509_generate_private_context **ctx)
1415 : {
1416 0 : free(*ctx);
1417 0 : *ctx = NULL;
1418 0 : }
1419 :
1420 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1421 0 : _hx509_generate_private_key(hx509_context context,
1422 : struct hx509_generate_private_context *ctx,
1423 : hx509_private_key *private_key)
1424 : {
1425 : struct hx509_private_key_ops *ops;
1426 : int ret;
1427 :
1428 0 : *private_key = NULL;
1429 :
1430 0 : ops = hx509_find_private_alg(ctx->key_oid);
1431 0 : if (ops == NULL) {
1432 0 : hx509_clear_error_string(context);
1433 0 : return HX509_SIG_ALG_NO_SUPPORTED;
1434 : }
1435 :
1436 0 : ret = hx509_private_key_init(private_key, ops, NULL);
1437 0 : if (ret) {
1438 0 : hx509_set_error_string(context, 0, ret, "out of memory");
1439 0 : return ret;
1440 : }
1441 :
1442 0 : ret = (*ops->generate_private_key)(context, ctx, *private_key);
1443 0 : if (ret)
1444 0 : hx509_private_key_free(private_key);
1445 :
1446 0 : return ret;
1447 : }
1448 :
1449 : /*
1450 : *
1451 : */
1452 :
1453 : const AlgorithmIdentifier *
1454 0 : hx509_signature_sha512(void)
1455 0 : { return &_hx509_signature_sha512_data; }
1456 :
1457 : const AlgorithmIdentifier *
1458 0 : hx509_signature_sha384(void)
1459 0 : { return &_hx509_signature_sha384_data; }
1460 :
1461 : const AlgorithmIdentifier *
1462 0 : hx509_signature_sha256(void)
1463 0 : { return &_hx509_signature_sha256_data; }
1464 :
1465 : const AlgorithmIdentifier *
1466 0 : hx509_signature_sha1(void)
1467 0 : { return &_hx509_signature_sha1_data; }
1468 :
1469 : const AlgorithmIdentifier *
1470 0 : hx509_signature_md5(void)
1471 0 : { return &_hx509_signature_md5_data; }
1472 :
1473 : const AlgorithmIdentifier *
1474 0 : hx509_signature_rsa_with_sha512(void)
1475 0 : { return &_hx509_signature_rsa_with_sha512_data; }
1476 :
1477 : const AlgorithmIdentifier *
1478 0 : hx509_signature_rsa_with_sha384(void)
1479 0 : { return &_hx509_signature_rsa_with_sha384_data; }
1480 :
1481 : const AlgorithmIdentifier *
1482 0 : hx509_signature_rsa_with_sha256(void)
1483 0 : { return &_hx509_signature_rsa_with_sha256_data; }
1484 :
1485 : const AlgorithmIdentifier *
1486 0 : hx509_signature_rsa_with_sha1(void)
1487 0 : { return &_hx509_signature_rsa_with_sha1_data; }
1488 :
1489 : const AlgorithmIdentifier *
1490 0 : hx509_signature_rsa_with_md5(void)
1491 0 : { return &_hx509_signature_rsa_with_md5_data; }
1492 :
1493 : const AlgorithmIdentifier *
1494 38 : hx509_signature_rsa(void)
1495 38 : { return &_hx509_signature_rsa_data; }
1496 :
1497 : const AlgorithmIdentifier *
1498 0 : hx509_signature_rsa_pkcs1_x509(void)
1499 0 : { return &_hx509_signature_rsa_pkcs1_x509_data; }
1500 :
1501 : const AlgorithmIdentifier *
1502 77 : hx509_crypto_des_rsdi_ede3_cbc(void)
1503 77 : { return &_hx509_des_rsdi_ede3_cbc_oid; }
1504 :
1505 : const AlgorithmIdentifier *
1506 77 : hx509_crypto_aes128_cbc(void)
1507 77 : { return &_hx509_crypto_aes128_cbc_data; }
1508 :
1509 : const AlgorithmIdentifier *
1510 77 : hx509_crypto_aes256_cbc(void)
1511 77 : { return &_hx509_crypto_aes256_cbc_data; }
1512 :
1513 : /*
1514 : *
1515 : */
1516 :
1517 : const AlgorithmIdentifier * _hx509_crypto_default_sig_alg =
1518 : &_hx509_signature_rsa_with_sha256_data;
1519 : const AlgorithmIdentifier * _hx509_crypto_default_digest_alg =
1520 : &_hx509_signature_sha256_data;
1521 : const AlgorithmIdentifier * _hx509_crypto_default_secret_alg =
1522 : &_hx509_crypto_aes128_cbc_data;
1523 :
1524 : /*
1525 : *
1526 : */
1527 :
1528 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1529 38 : hx509_private_key_init(hx509_private_key *key,
1530 : hx509_private_key_ops *ops,
1531 : void *keydata)
1532 : {
1533 38 : *key = calloc(1, sizeof(**key));
1534 38 : if (*key == NULL)
1535 0 : return ENOMEM;
1536 38 : (*key)->ref = 1;
1537 38 : (*key)->ops = ops;
1538 38 : (*key)->private_key.keydata = keydata;
1539 38 : return 0;
1540 : }
1541 :
1542 : HX509_LIB_FUNCTION hx509_private_key HX509_LIB_CALL
1543 76 : _hx509_private_key_ref(hx509_private_key key)
1544 : {
1545 76 : if (key->ref == 0)
1546 0 : _hx509_abort("key refcount <= 0 on ref");
1547 76 : key->ref++;
1548 76 : if (key->ref == UINT_MAX)
1549 0 : _hx509_abort("key refcount == UINT_MAX on ref");
1550 76 : return key;
1551 : }
1552 :
1553 : HX509_LIB_FUNCTION const char * HX509_LIB_CALL
1554 0 : _hx509_private_pem_name(hx509_private_key key)
1555 : {
1556 0 : return key->ops->pemtype;
1557 : }
1558 :
1559 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1560 38 : hx509_private_key_free(hx509_private_key *key)
1561 : {
1562 38 : if (key == NULL || *key == NULL)
1563 0 : return 0;
1564 :
1565 38 : if ((*key)->ref == 0)
1566 0 : _hx509_abort("key refcount == 0 on free");
1567 38 : if (--(*key)->ref > 0)
1568 38 : return 0;
1569 :
1570 0 : if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
1571 0 : if ((*key)->private_key.rsa)
1572 0 : RSA_free((*key)->private_key.rsa);
1573 0 : } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid,
1574 0 : ASN1_OID_ID_ECPUBLICKEY) == 0 &&
1575 0 : (*key)->private_key.ecdsa != NULL) {
1576 0 : _hx509_private_eckey_free((*key)->private_key.ecdsa);
1577 : }
1578 0 : (*key)->private_key.rsa = NULL;
1579 0 : free(*key);
1580 0 : *key = NULL;
1581 0 : return 0;
1582 : }
1583 :
1584 : HX509_LIB_FUNCTION void HX509_LIB_CALL
1585 0 : hx509_private_key_assign_rsa(hx509_private_key key, void *ptr)
1586 : {
1587 0 : if (key->private_key.rsa)
1588 0 : RSA_free(key->private_key.rsa);
1589 0 : key->private_key.rsa = ptr;
1590 0 : key->signature_alg = ASN1_OID_ID_PKCS1_SHA1WITHRSAENCRYPTION;
1591 0 : key->md = &pkcs1_rsa_sha1_alg;
1592 0 : }
1593 :
1594 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1595 0 : _hx509_private_key_oid(hx509_context context,
1596 : const hx509_private_key key,
1597 : heim_oid *data)
1598 : {
1599 : int ret;
1600 0 : ret = der_copy_oid(key->ops->key_oid, data);
1601 0 : if (ret)
1602 0 : hx509_set_error_string(context, 0, ret, "malloc out of memory");
1603 0 : return ret;
1604 : }
1605 :
1606 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1607 0 : _hx509_private_key_exportable(hx509_private_key key)
1608 : {
1609 0 : if (key->ops->export == NULL)
1610 0 : return 0;
1611 0 : return 1;
1612 : }
1613 :
1614 : HX509_LIB_FUNCTION BIGNUM * HX509_LIB_CALL
1615 0 : _hx509_private_key_get_internal(hx509_context context,
1616 : hx509_private_key key,
1617 : const char *type)
1618 : {
1619 0 : if (key->ops->get_internal == NULL)
1620 0 : return NULL;
1621 0 : return (*key->ops->get_internal)(context, key, type);
1622 : }
1623 :
1624 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1625 0 : _hx509_private_key_export(hx509_context context,
1626 : const hx509_private_key key,
1627 : hx509_key_format_t format,
1628 : heim_octet_string *data)
1629 : {
1630 0 : data->length = 0;
1631 0 : data->data = NULL;
1632 0 : if (key->ops->export == NULL) {
1633 0 : hx509_clear_error_string(context);
1634 0 : return HX509_UNIMPLEMENTED_OPERATION;
1635 : }
1636 0 : if (format == HX509_KEY_FORMAT_PKCS8) {
1637 : PKCS8PrivateKeyInfo ki;
1638 : size_t size;
1639 : int ret;
1640 :
1641 0 : memset(&ki, 0, sizeof(ki));
1642 0 : ki.attributes = NULL; /* No localKeyId needed */
1643 0 : ki.privateKey.data = NULL;
1644 0 : ki.privateKeyAlgorithm.algorithm.components = NULL;
1645 0 : ret = der_parse_hex_heim_integer("00", &ki.version);
1646 0 : if (ret == 0)
1647 0 : ret = _hx509_private_key_oid(context, key,
1648 : &ki.privateKeyAlgorithm.algorithm);
1649 0 : if (ret == 0)
1650 : /* Re-enter */
1651 0 : ret = _hx509_private_key_export(context, key, HX509_KEY_FORMAT_DER,
1652 : &ki.privateKey);
1653 :
1654 : /*
1655 : * XXX To set ki.privateKeyAlgorithm.parameters we'll need to either
1656 : * move this code into the *key->ops->export() functions, or expand
1657 : * their signature to allow them to set it for us, or add a method to
1658 : * hx509_private_key_ops that allows us to get the parameters from the
1659 : * backend.
1660 : */
1661 0 : ki.privateKeyAlgorithm.parameters = NULL;
1662 :
1663 0 : if (ret == 0)
1664 0 : ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, data->data, data->length,
1665 : &ki, &size, ret);
1666 0 : free_PKCS8PrivateKeyInfo(&ki);
1667 0 : if (ret == 0 && size != data->length)
1668 0 : ret = EINVAL;
1669 0 : if (ret)
1670 0 : hx509_set_error_string(context, 0, ret,
1671 : "Private key PKCS#8 encoding failed");
1672 0 : return ret;
1673 : }
1674 0 : return (*key->ops->export)(context, key, format, data);
1675 : }
1676 :
1677 : /*
1678 : *
1679 : */
1680 :
1681 : struct hx509cipher {
1682 : const char *name;
1683 : int flags;
1684 : #define CIPHER_WEAK 1
1685 : const heim_oid *oid;
1686 : const AlgorithmIdentifier *(*ai_func)(void);
1687 : const EVP_CIPHER *(*evp_func)(void);
1688 : int (*get_params)(hx509_context, const hx509_crypto,
1689 : const heim_octet_string *, heim_octet_string *);
1690 : int (*set_params)(hx509_context, const heim_octet_string *,
1691 : hx509_crypto, heim_octet_string *);
1692 : };
1693 :
1694 : struct hx509_crypto_data {
1695 : char *name;
1696 : int flags;
1697 : #define ALLOW_WEAK 1
1698 :
1699 : #define PADDING_NONE 2
1700 : #define PADDING_PKCS7 4
1701 : #define PADDING_FLAGS (2|4)
1702 : const struct hx509cipher *cipher;
1703 : const EVP_CIPHER *c;
1704 : heim_octet_string key;
1705 : heim_oid oid;
1706 : void *param;
1707 : };
1708 :
1709 : /*
1710 : *
1711 : */
1712 :
1713 : static unsigned private_rc2_40_oid_data[] = { 127, 1 };
1714 :
1715 : static heim_oid asn1_oid_private_rc2_40 =
1716 : { 2, private_rc2_40_oid_data };
1717 :
1718 : /*
1719 : *
1720 : */
1721 :
1722 : static int
1723 0 : CMSCBCParam_get(hx509_context context, const hx509_crypto crypto,
1724 : const heim_octet_string *ivec, heim_octet_string *param)
1725 : {
1726 : size_t size;
1727 : int ret;
1728 :
1729 0 : assert(crypto->param == NULL);
1730 0 : if (ivec == NULL)
1731 0 : return 0;
1732 :
1733 0 : ASN1_MALLOC_ENCODE(CMSCBCParameter, param->data, param->length,
1734 : ivec, &size, ret);
1735 0 : if (ret == 0 && size != param->length)
1736 0 : _hx509_abort("Internal asn1 encoder failure");
1737 0 : if (ret)
1738 0 : hx509_clear_error_string(context);
1739 0 : return ret;
1740 : }
1741 :
1742 : static int
1743 0 : CMSCBCParam_set(hx509_context context, const heim_octet_string *param,
1744 : hx509_crypto crypto, heim_octet_string *ivec)
1745 : {
1746 : int ret;
1747 0 : if (ivec == NULL)
1748 0 : return 0;
1749 :
1750 0 : ret = decode_CMSCBCParameter(param->data, param->length, ivec, NULL);
1751 0 : if (ret)
1752 0 : hx509_clear_error_string(context);
1753 :
1754 0 : return ret;
1755 : }
1756 :
1757 : struct _RC2_params {
1758 : int maximum_effective_key;
1759 : };
1760 :
1761 : static int
1762 0 : CMSRC2CBCParam_get(hx509_context context, const hx509_crypto crypto,
1763 : const heim_octet_string *ivec, heim_octet_string *param)
1764 : {
1765 : CMSRC2CBCParameter rc2params;
1766 0 : const struct _RC2_params *p = crypto->param;
1767 0 : int maximum_effective_key = 128;
1768 : size_t size;
1769 : int ret;
1770 :
1771 0 : memset(&rc2params, 0, sizeof(rc2params));
1772 :
1773 0 : if (p)
1774 0 : maximum_effective_key = p->maximum_effective_key;
1775 :
1776 0 : switch(maximum_effective_key) {
1777 0 : case 40:
1778 0 : rc2params.rc2ParameterVersion = 160;
1779 0 : break;
1780 0 : case 64:
1781 0 : rc2params.rc2ParameterVersion = 120;
1782 0 : break;
1783 0 : case 128:
1784 0 : rc2params.rc2ParameterVersion = 58;
1785 0 : break;
1786 : }
1787 0 : rc2params.iv = *ivec;
1788 :
1789 0 : ASN1_MALLOC_ENCODE(CMSRC2CBCParameter, param->data, param->length,
1790 : &rc2params, &size, ret);
1791 0 : if (ret == 0 && size != param->length)
1792 0 : _hx509_abort("Internal asn1 encoder failure");
1793 :
1794 0 : return ret;
1795 : }
1796 :
1797 : static int
1798 0 : CMSRC2CBCParam_set(hx509_context context, const heim_octet_string *param,
1799 : hx509_crypto crypto, heim_octet_string *ivec)
1800 : {
1801 : CMSRC2CBCParameter rc2param;
1802 : struct _RC2_params *p;
1803 : size_t size;
1804 : int ret;
1805 :
1806 0 : ret = decode_CMSRC2CBCParameter(param->data, param->length,
1807 : &rc2param, &size);
1808 0 : if (ret) {
1809 0 : hx509_clear_error_string(context);
1810 0 : return ret;
1811 : }
1812 :
1813 0 : p = calloc(1, sizeof(*p));
1814 0 : if (p == NULL) {
1815 0 : free_CMSRC2CBCParameter(&rc2param);
1816 0 : hx509_clear_error_string(context);
1817 0 : return ENOMEM;
1818 : }
1819 0 : switch(rc2param.rc2ParameterVersion) {
1820 0 : case 160:
1821 0 : crypto->c = EVP_rc2_40_cbc();
1822 0 : p->maximum_effective_key = 40;
1823 0 : break;
1824 0 : case 120:
1825 0 : crypto->c = EVP_rc2_64_cbc();
1826 0 : p->maximum_effective_key = 64;
1827 0 : break;
1828 0 : case 58:
1829 0 : crypto->c = EVP_rc2_cbc();
1830 0 : p->maximum_effective_key = 128;
1831 0 : break;
1832 0 : default:
1833 0 : free(p);
1834 0 : free_CMSRC2CBCParameter(&rc2param);
1835 0 : return HX509_CRYPTO_SIG_INVALID_FORMAT;
1836 : }
1837 0 : if (ivec)
1838 0 : ret = der_copy_octet_string(&rc2param.iv, ivec);
1839 0 : free_CMSRC2CBCParameter(&rc2param);
1840 0 : if (ret) {
1841 0 : free(p);
1842 0 : hx509_clear_error_string(context);
1843 : } else
1844 0 : crypto->param = p;
1845 :
1846 0 : return ret;
1847 : }
1848 :
1849 : /*
1850 : *
1851 : */
1852 :
1853 : static const struct hx509cipher ciphers[] = {
1854 : {
1855 : "rc2-cbc",
1856 : CIPHER_WEAK,
1857 : ASN1_OID_ID_PKCS3_RC2_CBC,
1858 : NULL,
1859 : EVP_rc2_cbc,
1860 : CMSRC2CBCParam_get,
1861 : CMSRC2CBCParam_set
1862 : },
1863 : {
1864 : "rc2-cbc",
1865 : CIPHER_WEAK,
1866 : ASN1_OID_ID_RSADSI_RC2_CBC,
1867 : NULL,
1868 : EVP_rc2_cbc,
1869 : CMSRC2CBCParam_get,
1870 : CMSRC2CBCParam_set
1871 : },
1872 : {
1873 : "rc2-40-cbc",
1874 : CIPHER_WEAK,
1875 : &asn1_oid_private_rc2_40,
1876 : NULL,
1877 : EVP_rc2_40_cbc,
1878 : CMSRC2CBCParam_get,
1879 : CMSRC2CBCParam_set
1880 : },
1881 : {
1882 : "des-ede3-cbc",
1883 : 0,
1884 : ASN1_OID_ID_PKCS3_DES_EDE3_CBC,
1885 : NULL,
1886 : EVP_des_ede3_cbc,
1887 : CMSCBCParam_get,
1888 : CMSCBCParam_set
1889 : },
1890 : {
1891 : "des-ede3-cbc",
1892 : 0,
1893 : ASN1_OID_ID_RSADSI_DES_EDE3_CBC,
1894 : hx509_crypto_des_rsdi_ede3_cbc,
1895 : EVP_des_ede3_cbc,
1896 : CMSCBCParam_get,
1897 : CMSCBCParam_set
1898 : },
1899 : {
1900 : "aes-128-cbc",
1901 : 0,
1902 : ASN1_OID_ID_AES_128_CBC,
1903 : hx509_crypto_aes128_cbc,
1904 : EVP_aes_128_cbc,
1905 : CMSCBCParam_get,
1906 : CMSCBCParam_set
1907 : },
1908 : {
1909 : "aes-192-cbc",
1910 : 0,
1911 : ASN1_OID_ID_AES_192_CBC,
1912 : NULL,
1913 : EVP_aes_192_cbc,
1914 : CMSCBCParam_get,
1915 : CMSCBCParam_set
1916 : },
1917 : {
1918 : "aes-256-cbc",
1919 : 0,
1920 : ASN1_OID_ID_AES_256_CBC,
1921 : hx509_crypto_aes256_cbc,
1922 : EVP_aes_256_cbc,
1923 : CMSCBCParam_get,
1924 : CMSCBCParam_set
1925 : }
1926 : };
1927 :
1928 : static const struct hx509cipher *
1929 0 : find_cipher_by_oid(const heim_oid *oid)
1930 : {
1931 : size_t i;
1932 :
1933 0 : for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1934 0 : if (der_heim_oid_cmp(oid, ciphers[i].oid) == 0)
1935 0 : return &ciphers[i];
1936 :
1937 0 : return NULL;
1938 : }
1939 :
1940 : static const struct hx509cipher *
1941 0 : find_cipher_by_name(const char *name)
1942 : {
1943 : size_t i;
1944 :
1945 0 : for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++)
1946 0 : if (strcasecmp(name, ciphers[i].name) == 0)
1947 0 : return &ciphers[i];
1948 :
1949 0 : return NULL;
1950 : }
1951 :
1952 :
1953 : HX509_LIB_FUNCTION const heim_oid * HX509_LIB_CALL
1954 0 : hx509_crypto_enctype_by_name(const char *name)
1955 : {
1956 : const struct hx509cipher *cipher;
1957 :
1958 0 : cipher = find_cipher_by_name(name);
1959 0 : if (cipher == NULL)
1960 0 : return NULL;
1961 0 : return cipher->oid;
1962 : }
1963 :
1964 : HX509_LIB_FUNCTION int HX509_LIB_CALL
1965 0 : hx509_crypto_init(hx509_context context,
1966 : const char *provider,
1967 : const heim_oid *enctype,
1968 : hx509_crypto *crypto)
1969 : {
1970 : const struct hx509cipher *cipher;
1971 :
1972 0 : *crypto = NULL;
1973 :
1974 0 : cipher = find_cipher_by_oid(enctype);
1975 0 : if (cipher == NULL) {
1976 0 : hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
1977 : "Algorithm not supported");
1978 0 : return HX509_ALG_NOT_SUPP;
1979 : }
1980 :
1981 0 : *crypto = calloc(1, sizeof(**crypto));
1982 0 : if (*crypto == NULL) {
1983 0 : hx509_clear_error_string(context);
1984 0 : return ENOMEM;
1985 : }
1986 :
1987 0 : (*crypto)->flags = PADDING_PKCS7;
1988 0 : (*crypto)->cipher = cipher;
1989 0 : (*crypto)->c = (*cipher->evp_func)();
1990 :
1991 0 : if (der_copy_oid(enctype, &(*crypto)->oid)) {
1992 0 : hx509_crypto_destroy(*crypto);
1993 0 : *crypto = NULL;
1994 0 : hx509_clear_error_string(context);
1995 0 : return ENOMEM;
1996 : }
1997 :
1998 0 : return 0;
1999 : }
2000 :
2001 : HX509_LIB_FUNCTION const char * HX509_LIB_CALL
2002 0 : hx509_crypto_provider(hx509_crypto crypto)
2003 : {
2004 0 : return "unknown";
2005 : }
2006 :
2007 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2008 0 : hx509_crypto_destroy(hx509_crypto crypto)
2009 : {
2010 0 : if (crypto->name)
2011 0 : free(crypto->name);
2012 0 : if (crypto->key.data)
2013 0 : free(crypto->key.data);
2014 0 : if (crypto->param)
2015 0 : free(crypto->param);
2016 0 : der_free_oid(&crypto->oid);
2017 0 : memset(crypto, 0, sizeof(*crypto));
2018 0 : free(crypto);
2019 0 : }
2020 :
2021 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2022 0 : hx509_crypto_set_key_name(hx509_crypto crypto, const char *name)
2023 : {
2024 0 : return 0;
2025 : }
2026 :
2027 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2028 0 : hx509_crypto_allow_weak(hx509_crypto crypto)
2029 : {
2030 0 : crypto->flags |= ALLOW_WEAK;
2031 0 : }
2032 :
2033 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2034 0 : hx509_crypto_set_padding(hx509_crypto crypto, int padding_type)
2035 : {
2036 0 : switch (padding_type) {
2037 0 : case HX509_CRYPTO_PADDING_PKCS7:
2038 0 : crypto->flags &= ~PADDING_FLAGS;
2039 0 : crypto->flags |= PADDING_PKCS7;
2040 0 : break;
2041 0 : case HX509_CRYPTO_PADDING_NONE:
2042 0 : crypto->flags &= ~PADDING_FLAGS;
2043 0 : crypto->flags |= PADDING_NONE;
2044 0 : break;
2045 0 : default:
2046 0 : _hx509_abort("Invalid padding");
2047 : }
2048 0 : }
2049 :
2050 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2051 0 : hx509_crypto_set_key_data(hx509_crypto crypto, const void *data, size_t length)
2052 : {
2053 0 : if (EVP_CIPHER_key_length(crypto->c) > (int)length)
2054 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2055 :
2056 0 : if (crypto->key.data) {
2057 0 : free(crypto->key.data);
2058 0 : crypto->key.data = NULL;
2059 0 : crypto->key.length = 0;
2060 : }
2061 0 : crypto->key.data = malloc(length);
2062 0 : if (crypto->key.data == NULL)
2063 0 : return ENOMEM;
2064 0 : memcpy(crypto->key.data, data, length);
2065 0 : crypto->key.length = length;
2066 :
2067 0 : return 0;
2068 : }
2069 :
2070 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2071 0 : hx509_crypto_set_random_key(hx509_crypto crypto, heim_octet_string *key)
2072 : {
2073 0 : if (crypto->key.data) {
2074 0 : free(crypto->key.data);
2075 0 : crypto->key.length = 0;
2076 : }
2077 :
2078 0 : crypto->key.length = EVP_CIPHER_key_length(crypto->c);
2079 0 : crypto->key.data = malloc(crypto->key.length);
2080 0 : if (crypto->key.data == NULL) {
2081 0 : crypto->key.length = 0;
2082 0 : return ENOMEM;
2083 : }
2084 0 : if (RAND_bytes(crypto->key.data, crypto->key.length) <= 0) {
2085 0 : free(crypto->key.data);
2086 0 : crypto->key.data = NULL;
2087 0 : crypto->key.length = 0;
2088 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2089 : }
2090 0 : if (key)
2091 0 : return der_copy_octet_string(&crypto->key, key);
2092 : else
2093 0 : return 0;
2094 : }
2095 :
2096 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2097 0 : hx509_crypto_set_params(hx509_context context,
2098 : hx509_crypto crypto,
2099 : const heim_octet_string *param,
2100 : heim_octet_string *ivec)
2101 : {
2102 0 : return (*crypto->cipher->set_params)(context, param, crypto, ivec);
2103 : }
2104 :
2105 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2106 0 : hx509_crypto_get_params(hx509_context context,
2107 : hx509_crypto crypto,
2108 : const heim_octet_string *ivec,
2109 : heim_octet_string *param)
2110 : {
2111 0 : return (*crypto->cipher->get_params)(context, crypto, ivec, param);
2112 : }
2113 :
2114 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2115 0 : hx509_crypto_random_iv(hx509_crypto crypto, heim_octet_string *ivec)
2116 : {
2117 0 : ivec->length = EVP_CIPHER_iv_length(crypto->c);
2118 0 : ivec->data = malloc(ivec->length);
2119 0 : if (ivec->data == NULL) {
2120 0 : ivec->length = 0;
2121 0 : return ENOMEM;
2122 : }
2123 :
2124 0 : if (RAND_bytes(ivec->data, ivec->length) <= 0) {
2125 0 : free(ivec->data);
2126 0 : ivec->data = NULL;
2127 0 : ivec->length = 0;
2128 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2129 : }
2130 0 : return 0;
2131 : }
2132 :
2133 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2134 0 : hx509_crypto_encrypt(hx509_crypto crypto,
2135 : const void *data,
2136 : const size_t length,
2137 : const heim_octet_string *ivec,
2138 : heim_octet_string **ciphertext)
2139 : {
2140 : EVP_CIPHER_CTX evp;
2141 : size_t padsize, bsize;
2142 : int ret;
2143 :
2144 0 : *ciphertext = NULL;
2145 :
2146 0 : if ((crypto->cipher->flags & CIPHER_WEAK) &&
2147 0 : (crypto->flags & ALLOW_WEAK) == 0)
2148 0 : return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2149 :
2150 0 : assert(EVP_CIPHER_iv_length(crypto->c) == (int)ivec->length);
2151 :
2152 0 : EVP_CIPHER_CTX_init(&evp);
2153 :
2154 0 : ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2155 0 : crypto->key.data, ivec->data, 1);
2156 0 : if (ret != 1) {
2157 0 : EVP_CIPHER_CTX_cleanup(&evp);
2158 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2159 0 : goto out;
2160 : }
2161 :
2162 0 : *ciphertext = calloc(1, sizeof(**ciphertext));
2163 0 : if (*ciphertext == NULL) {
2164 0 : ret = ENOMEM;
2165 0 : goto out;
2166 : }
2167 :
2168 0 : assert(crypto->flags & PADDING_FLAGS);
2169 :
2170 0 : bsize = EVP_CIPHER_block_size(crypto->c);
2171 0 : padsize = 0;
2172 :
2173 0 : if (crypto->flags & PADDING_NONE) {
2174 0 : if (bsize != 1 && (length % bsize) != 0)
2175 0 : return HX509_CMS_PADDING_ERROR;
2176 0 : } else if (crypto->flags & PADDING_PKCS7) {
2177 0 : if (bsize != 1)
2178 0 : padsize = bsize - (length % bsize);
2179 : }
2180 :
2181 0 : (*ciphertext)->length = length + padsize;
2182 0 : (*ciphertext)->data = malloc(length + padsize);
2183 0 : if ((*ciphertext)->data == NULL) {
2184 0 : ret = ENOMEM;
2185 0 : goto out;
2186 : }
2187 :
2188 0 : memcpy((*ciphertext)->data, data, length);
2189 0 : if (padsize) {
2190 : size_t i;
2191 0 : unsigned char *p = (*ciphertext)->data;
2192 0 : p += length;
2193 0 : for (i = 0; i < padsize; i++)
2194 0 : *p++ = padsize;
2195 : }
2196 :
2197 0 : ret = EVP_Cipher(&evp, (*ciphertext)->data,
2198 0 : (*ciphertext)->data,
2199 : length + padsize);
2200 0 : if (ret != 1) {
2201 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2202 0 : goto out;
2203 : }
2204 0 : ret = 0;
2205 :
2206 0 : out:
2207 0 : if (ret) {
2208 0 : if (*ciphertext) {
2209 0 : if ((*ciphertext)->data) {
2210 0 : free((*ciphertext)->data);
2211 : }
2212 0 : free(*ciphertext);
2213 0 : *ciphertext = NULL;
2214 : }
2215 : }
2216 0 : EVP_CIPHER_CTX_cleanup(&evp);
2217 :
2218 0 : return ret;
2219 : }
2220 :
2221 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2222 0 : hx509_crypto_decrypt(hx509_crypto crypto,
2223 : const void *data,
2224 : const size_t length,
2225 : heim_octet_string *ivec,
2226 : heim_octet_string *clear)
2227 : {
2228 : EVP_CIPHER_CTX evp;
2229 0 : void *idata = NULL;
2230 : int ret;
2231 :
2232 0 : clear->data = NULL;
2233 0 : clear->length = 0;
2234 :
2235 0 : if ((crypto->cipher->flags & CIPHER_WEAK) &&
2236 0 : (crypto->flags & ALLOW_WEAK) == 0)
2237 0 : return HX509_CRYPTO_ALGORITHM_BEST_BEFORE;
2238 :
2239 0 : if (ivec && EVP_CIPHER_iv_length(crypto->c) < (int)ivec->length)
2240 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2241 :
2242 0 : if (crypto->key.data == NULL)
2243 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2244 :
2245 0 : if (ivec)
2246 0 : idata = ivec->data;
2247 :
2248 0 : EVP_CIPHER_CTX_init(&evp);
2249 :
2250 0 : ret = EVP_CipherInit_ex(&evp, crypto->c, NULL,
2251 0 : crypto->key.data, idata, 0);
2252 0 : if (ret != 1) {
2253 0 : EVP_CIPHER_CTX_cleanup(&evp);
2254 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2255 : }
2256 :
2257 0 : clear->length = length;
2258 0 : clear->data = malloc(length);
2259 0 : if (clear->data == NULL) {
2260 0 : EVP_CIPHER_CTX_cleanup(&evp);
2261 0 : clear->length = 0;
2262 0 : return ENOMEM;
2263 : }
2264 :
2265 0 : if (EVP_Cipher(&evp, clear->data, data, length) != 1) {
2266 0 : return HX509_CRYPTO_INTERNAL_ERROR;
2267 : }
2268 0 : EVP_CIPHER_CTX_cleanup(&evp);
2269 :
2270 0 : if ((crypto->flags & PADDING_PKCS7) && EVP_CIPHER_block_size(crypto->c) > 1) {
2271 : int padsize;
2272 : unsigned char *p;
2273 0 : int j, bsize = EVP_CIPHER_block_size(crypto->c);
2274 :
2275 0 : if ((int)clear->length < bsize) {
2276 0 : ret = HX509_CMS_PADDING_ERROR;
2277 0 : goto out;
2278 : }
2279 :
2280 0 : p = clear->data;
2281 0 : p += clear->length - 1;
2282 0 : padsize = *p;
2283 0 : if (padsize > bsize) {
2284 0 : ret = HX509_CMS_PADDING_ERROR;
2285 0 : goto out;
2286 : }
2287 0 : clear->length -= padsize;
2288 0 : for (j = 0; j < padsize; j++) {
2289 0 : if (*p-- != padsize) {
2290 0 : ret = HX509_CMS_PADDING_ERROR;
2291 0 : goto out;
2292 : }
2293 : }
2294 : }
2295 :
2296 0 : return 0;
2297 :
2298 0 : out:
2299 0 : if (clear->data)
2300 0 : free(clear->data);
2301 0 : clear->data = NULL;
2302 0 : clear->length = 0;
2303 0 : return ret;
2304 : }
2305 :
2306 : typedef int (*PBE_string2key_func)(hx509_context,
2307 : const char *,
2308 : const heim_octet_string *,
2309 : hx509_crypto *, heim_octet_string *,
2310 : heim_octet_string *,
2311 : const heim_oid *, const EVP_MD *);
2312 :
2313 : static int
2314 0 : PBE_string2key(hx509_context context,
2315 : const char *password,
2316 : const heim_octet_string *parameters,
2317 : hx509_crypto *crypto,
2318 : heim_octet_string *key, heim_octet_string *iv,
2319 : const heim_oid *enc_oid,
2320 : const EVP_MD *md)
2321 : {
2322 : PKCS12_PBEParams p12params;
2323 : int passwordlen;
2324 : hx509_crypto c;
2325 : int iter, saltlen, ret;
2326 : unsigned char *salt;
2327 :
2328 0 : passwordlen = password ? strlen(password) : 0;
2329 :
2330 0 : if (parameters == NULL)
2331 0 : return HX509_ALG_NOT_SUPP;
2332 :
2333 0 : ret = decode_PKCS12_PBEParams(parameters->data,
2334 0 : parameters->length,
2335 : &p12params, NULL);
2336 0 : if (ret)
2337 0 : goto out;
2338 :
2339 0 : if (p12params.iterations)
2340 0 : iter = *p12params.iterations;
2341 : else
2342 0 : iter = 1;
2343 0 : salt = p12params.salt.data;
2344 0 : saltlen = p12params.salt.length;
2345 :
2346 0 : if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2347 : PKCS12_KEY_ID, iter, key->length, key->data, md)) {
2348 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2349 0 : goto out;
2350 : }
2351 :
2352 0 : if (!PKCS12_key_gen (password, passwordlen, salt, saltlen,
2353 : PKCS12_IV_ID, iter, iv->length, iv->data, md)) {
2354 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2355 0 : goto out;
2356 : }
2357 :
2358 0 : ret = hx509_crypto_init(context, NULL, enc_oid, &c);
2359 0 : if (ret)
2360 0 : goto out;
2361 :
2362 0 : hx509_crypto_allow_weak(c);
2363 :
2364 0 : ret = hx509_crypto_set_key_data(c, key->data, key->length);
2365 0 : if (ret) {
2366 0 : hx509_crypto_destroy(c);
2367 0 : goto out;
2368 : }
2369 :
2370 0 : *crypto = c;
2371 0 : out:
2372 0 : free_PKCS12_PBEParams(&p12params);
2373 0 : return ret;
2374 : }
2375 :
2376 : static const heim_oid *
2377 0 : find_string2key(const heim_oid *oid,
2378 : const EVP_CIPHER **c,
2379 : const EVP_MD **md,
2380 : PBE_string2key_func *s2k)
2381 : {
2382 0 : if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
2383 0 : *c = EVP_rc2_40_cbc();
2384 0 : if (*c == NULL)
2385 0 : return NULL;
2386 0 : *md = EVP_sha1();
2387 0 : if (*md == NULL)
2388 0 : return NULL;
2389 0 : *s2k = PBE_string2key;
2390 0 : return &asn1_oid_private_rc2_40;
2391 0 : } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
2392 0 : *c = EVP_rc2_cbc();
2393 0 : if (*c == NULL)
2394 0 : return NULL;
2395 0 : *md = EVP_sha1();
2396 0 : if (*md == NULL)
2397 0 : return NULL;
2398 0 : *s2k = PBE_string2key;
2399 0 : return ASN1_OID_ID_PKCS3_RC2_CBC;
2400 : #if 0
2401 : } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
2402 : *c = EVP_rc4_40();
2403 : if (*c == NULL)
2404 : return NULL;
2405 : *md = EVP_sha1();
2406 : if (*md == NULL)
2407 : return NULL;
2408 : *s2k = PBE_string2key;
2409 : return NULL;
2410 : } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
2411 : *c = EVP_rc4();
2412 : if (*c == NULL)
2413 : return NULL;
2414 : *md = EVP_sha1();
2415 : if (*md == NULL)
2416 : return NULL;
2417 : *s2k = PBE_string2key;
2418 : return ASN1_OID_ID_PKCS3_RC4;
2419 : #endif
2420 0 : } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
2421 0 : *c = EVP_des_ede3_cbc();
2422 0 : if (*c == NULL)
2423 0 : return NULL;
2424 0 : *md = EVP_sha1();
2425 0 : if (*md == NULL)
2426 0 : return NULL;
2427 0 : *s2k = PBE_string2key;
2428 0 : return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
2429 : }
2430 :
2431 0 : return NULL;
2432 : }
2433 :
2434 : /*
2435 : *
2436 : */
2437 :
2438 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2439 0 : _hx509_pbe_encrypt(hx509_context context,
2440 : hx509_lock lock,
2441 : const AlgorithmIdentifier *ai,
2442 : const heim_octet_string *content,
2443 : heim_octet_string *econtent)
2444 : {
2445 0 : hx509_clear_error_string(context);
2446 0 : return EINVAL;
2447 : }
2448 :
2449 : /*
2450 : *
2451 : */
2452 :
2453 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2454 0 : _hx509_pbe_decrypt(hx509_context context,
2455 : hx509_lock lock,
2456 : const AlgorithmIdentifier *ai,
2457 : const heim_octet_string *econtent,
2458 : heim_octet_string *content)
2459 : {
2460 : const struct _hx509_password *pw;
2461 : heim_octet_string key, iv;
2462 : const heim_oid *enc_oid;
2463 : const EVP_CIPHER *c;
2464 : const EVP_MD *md;
2465 : PBE_string2key_func s2k;
2466 0 : int ret = 0;
2467 : size_t i;
2468 :
2469 0 : memset(&key, 0, sizeof(key));
2470 0 : memset(&iv, 0, sizeof(iv));
2471 :
2472 0 : memset(content, 0, sizeof(*content));
2473 :
2474 0 : enc_oid = find_string2key(&ai->algorithm, &c, &md, &s2k);
2475 0 : if (enc_oid == NULL) {
2476 0 : hx509_set_error_string(context, 0, HX509_ALG_NOT_SUPP,
2477 : "String to key algorithm not supported");
2478 0 : ret = HX509_ALG_NOT_SUPP;
2479 0 : goto out;
2480 : }
2481 :
2482 0 : key.length = EVP_CIPHER_key_length(c);
2483 0 : key.data = malloc(key.length);
2484 0 : if (key.data == NULL) {
2485 0 : ret = ENOMEM;
2486 0 : hx509_clear_error_string(context);
2487 0 : goto out;
2488 : }
2489 :
2490 0 : iv.length = EVP_CIPHER_iv_length(c);
2491 0 : iv.data = malloc(iv.length);
2492 0 : if (iv.data == NULL) {
2493 0 : ret = ENOMEM;
2494 0 : hx509_clear_error_string(context);
2495 0 : goto out;
2496 : }
2497 :
2498 0 : pw = _hx509_lock_get_passwords(lock);
2499 :
2500 0 : ret = HX509_CRYPTO_INTERNAL_ERROR;
2501 0 : for (i = 0; i < pw->len + 1; i++) {
2502 : hx509_crypto crypto;
2503 : const char *password;
2504 :
2505 0 : if (i < pw->len)
2506 0 : password = pw->val[i];
2507 0 : else if (i < pw->len + 1)
2508 0 : password = "";
2509 : else
2510 0 : password = NULL;
2511 :
2512 0 : ret = (*s2k)(context, password, ai->parameters, &crypto,
2513 : &key, &iv, enc_oid, md);
2514 0 : if (ret)
2515 0 : goto out;
2516 :
2517 0 : ret = hx509_crypto_decrypt(crypto,
2518 0 : econtent->data,
2519 0 : econtent->length,
2520 : &iv,
2521 : content);
2522 0 : hx509_crypto_destroy(crypto);
2523 0 : if (ret == 0)
2524 0 : goto out;
2525 :
2526 : }
2527 0 : out:
2528 0 : if (key.data)
2529 0 : der_free_octet_string(&key);
2530 0 : if (iv.data)
2531 0 : der_free_octet_string(&iv);
2532 0 : return ret;
2533 : }
2534 :
2535 : /*
2536 : *
2537 : */
2538 :
2539 :
2540 : static int
2541 38 : match_keys_rsa(hx509_cert c, hx509_private_key private_key)
2542 : {
2543 : const Certificate *cert;
2544 : const SubjectPublicKeyInfo *spi;
2545 : RSAPublicKey pk;
2546 : RSA *rsa;
2547 : size_t size;
2548 : int ret;
2549 :
2550 38 : if (private_key->private_key.rsa == NULL)
2551 0 : return 0;
2552 :
2553 38 : rsa = private_key->private_key.rsa;
2554 38 : if (rsa->d == NULL || rsa->p == NULL || rsa->q == NULL)
2555 0 : return 0;
2556 :
2557 38 : cert = _hx509_get_cert(c);
2558 38 : spi = &cert->tbsCertificate.subjectPublicKeyInfo;
2559 :
2560 38 : rsa = RSA_new();
2561 38 : if (rsa == NULL)
2562 0 : return 0;
2563 :
2564 38 : ret = decode_RSAPublicKey(spi->subjectPublicKey.data,
2565 38 : spi->subjectPublicKey.length / 8,
2566 : &pk, &size);
2567 38 : if (ret) {
2568 0 : RSA_free(rsa);
2569 0 : return 0;
2570 : }
2571 38 : rsa->n = heim_int2BN(&pk.modulus);
2572 38 : rsa->e = heim_int2BN(&pk.publicExponent);
2573 :
2574 38 : free_RSAPublicKey(&pk);
2575 :
2576 38 : rsa->d = BN_dup(private_key->private_key.rsa->d);
2577 38 : rsa->p = BN_dup(private_key->private_key.rsa->p);
2578 38 : rsa->q = BN_dup(private_key->private_key.rsa->q);
2579 38 : rsa->dmp1 = BN_dup(private_key->private_key.rsa->dmp1);
2580 38 : rsa->dmq1 = BN_dup(private_key->private_key.rsa->dmq1);
2581 38 : rsa->iqmp = BN_dup(private_key->private_key.rsa->iqmp);
2582 :
2583 38 : if (rsa->n == NULL || rsa->e == NULL ||
2584 38 : rsa->d == NULL || rsa->p == NULL|| rsa->q == NULL ||
2585 38 : rsa->dmp1 == NULL || rsa->dmq1 == NULL) {
2586 0 : RSA_free(rsa);
2587 0 : return 0;
2588 : }
2589 :
2590 38 : ret = RSA_check_key(rsa);
2591 38 : RSA_free(rsa);
2592 :
2593 38 : return ret == 1;
2594 : }
2595 :
2596 : static int
2597 0 : match_keys_ec(hx509_cert c, hx509_private_key private_key)
2598 : {
2599 0 : return 1; /* XXX use EC_KEY_check_key */
2600 : }
2601 :
2602 :
2603 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2604 38 : _hx509_match_keys(hx509_cert c, hx509_private_key key)
2605 : {
2606 38 : if (!key->ops)
2607 0 : return 0;
2608 38 : if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0)
2609 38 : return match_keys_rsa(c, key);
2610 0 : if (der_heim_oid_cmp(key->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0)
2611 0 : return match_keys_ec(c, key);
2612 0 : return 0;
2613 :
2614 : }
2615 :
2616 :
2617 : static const heim_oid *
2618 0 : find_keytype(const hx509_private_key key)
2619 : {
2620 : const struct signature_alg *md;
2621 :
2622 0 : if (key == NULL)
2623 0 : return NULL;
2624 :
2625 0 : md = _hx509_find_sig_alg(key->signature_alg);
2626 0 : if (md == NULL)
2627 0 : return NULL;
2628 0 : return md->key_oid;
2629 : }
2630 :
2631 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2632 0 : hx509_crypto_select(const hx509_context context,
2633 : int type,
2634 : const hx509_private_key source,
2635 : hx509_peer_info peer,
2636 : AlgorithmIdentifier *selected)
2637 : {
2638 0 : const AlgorithmIdentifier *def = NULL;
2639 : size_t i, j;
2640 : int ret, bits;
2641 :
2642 0 : memset(selected, 0, sizeof(*selected));
2643 :
2644 0 : if (type == HX509_SELECT_DIGEST) {
2645 0 : bits = SIG_DIGEST;
2646 0 : if (source)
2647 0 : def = alg_for_privatekey(source, type);
2648 0 : if (def == NULL)
2649 0 : def = _hx509_crypto_default_digest_alg;
2650 0 : } else if (type == HX509_SELECT_PUBLIC_SIG) {
2651 0 : bits = SIG_PUBLIC_SIG;
2652 : /* XXX depend on `source´ and `peer´ */
2653 0 : if (source)
2654 0 : def = alg_for_privatekey(source, type);
2655 0 : if (def == NULL)
2656 0 : def = _hx509_crypto_default_sig_alg;
2657 0 : } else if (type == HX509_SELECT_SECRET_ENC) {
2658 0 : bits = SIG_SECRET;
2659 0 : def = _hx509_crypto_default_secret_alg;
2660 : } else {
2661 0 : hx509_set_error_string(context, 0, EINVAL,
2662 : "Unknown type %d of selection", type);
2663 0 : return EINVAL;
2664 : }
2665 :
2666 0 : if (peer) {
2667 0 : const heim_oid *keytype = NULL;
2668 :
2669 0 : keytype = find_keytype(source);
2670 :
2671 0 : for (i = 0; i < peer->len; i++) {
2672 0 : for (j = 0; sig_algs[j]; j++) {
2673 0 : if ((sig_algs[j]->flags & bits) != bits)
2674 0 : continue;
2675 0 : if (der_heim_oid_cmp(sig_algs[j]->sig_oid,
2676 0 : &peer->val[i].algorithm) != 0)
2677 0 : continue;
2678 0 : if (keytype && sig_algs[j]->key_oid &&
2679 0 : der_heim_oid_cmp(keytype, sig_algs[j]->key_oid))
2680 0 : continue;
2681 :
2682 : /* found one, use that */
2683 0 : ret = copy_AlgorithmIdentifier(&peer->val[i], selected);
2684 0 : if (ret)
2685 0 : hx509_clear_error_string(context);
2686 0 : return ret;
2687 : }
2688 0 : if (bits & SIG_SECRET) {
2689 : const struct hx509cipher *cipher;
2690 :
2691 0 : cipher = find_cipher_by_oid(&peer->val[i].algorithm);
2692 0 : if (cipher == NULL)
2693 0 : continue;
2694 0 : if (cipher->ai_func == NULL)
2695 0 : continue;
2696 0 : ret = copy_AlgorithmIdentifier(cipher->ai_func(), selected);
2697 0 : if (ret)
2698 0 : hx509_clear_error_string(context);
2699 0 : return ret;
2700 : }
2701 : }
2702 : }
2703 :
2704 : /* use default */
2705 0 : ret = copy_AlgorithmIdentifier(def, selected);
2706 0 : if (ret)
2707 0 : hx509_clear_error_string(context);
2708 0 : return ret;
2709 : }
2710 :
2711 : HX509_LIB_FUNCTION int HX509_LIB_CALL
2712 77 : hx509_crypto_available(hx509_context context,
2713 : int type,
2714 : hx509_cert source,
2715 : AlgorithmIdentifier **val,
2716 : unsigned int *plen)
2717 : {
2718 77 : const heim_oid *keytype = NULL;
2719 : unsigned int len, i;
2720 : void *ptr;
2721 : int bits, ret;
2722 :
2723 77 : *val = NULL;
2724 :
2725 77 : if (type == HX509_SELECT_ALL) {
2726 77 : bits = SIG_DIGEST | SIG_PUBLIC_SIG | SIG_SECRET;
2727 0 : } else if (type == HX509_SELECT_DIGEST) {
2728 0 : bits = SIG_DIGEST;
2729 0 : } else if (type == HX509_SELECT_PUBLIC_SIG) {
2730 0 : bits = SIG_PUBLIC_SIG;
2731 : } else {
2732 0 : hx509_set_error_string(context, 0, EINVAL,
2733 : "Unknown type %d of available", type);
2734 0 : return EINVAL;
2735 : }
2736 :
2737 77 : if (source)
2738 0 : keytype = find_keytype(_hx509_cert_private_key(source));
2739 :
2740 77 : len = 0;
2741 1155 : for (i = 0; sig_algs[i]; i++) {
2742 1078 : if ((sig_algs[i]->flags & bits) == 0)
2743 0 : continue;
2744 1078 : if (sig_algs[i]->sig_alg == NULL)
2745 77 : continue;
2746 1001 : if (keytype && sig_algs[i]->key_oid &&
2747 0 : der_heim_oid_cmp(sig_algs[i]->key_oid, keytype))
2748 0 : continue;
2749 :
2750 : /* found one, add that to the list */
2751 1001 : ptr = realloc(*val, sizeof(**val) * (len + 1));
2752 1001 : if (ptr == NULL)
2753 0 : goto out;
2754 1001 : *val = ptr;
2755 :
2756 1001 : ret = copy_AlgorithmIdentifier(sig_algs[i]->sig_alg, &(*val)[len]);
2757 1001 : if (ret)
2758 0 : goto out;
2759 1001 : len++;
2760 : }
2761 :
2762 : /* Add AES */
2763 77 : if (bits & SIG_SECRET) {
2764 :
2765 693 : for (i = 0; i < sizeof(ciphers)/sizeof(ciphers[0]); i++) {
2766 :
2767 616 : if (ciphers[i].flags & CIPHER_WEAK)
2768 231 : continue;
2769 385 : if (ciphers[i].ai_func == NULL)
2770 154 : continue;
2771 :
2772 231 : ptr = realloc(*val, sizeof(**val) * (len + 1));
2773 231 : if (ptr == NULL)
2774 0 : goto out;
2775 231 : *val = ptr;
2776 :
2777 231 : ret = copy_AlgorithmIdentifier((ciphers[i].ai_func)(), &(*val)[len]);
2778 231 : if (ret)
2779 0 : goto out;
2780 231 : len++;
2781 : }
2782 : }
2783 :
2784 77 : *plen = len;
2785 77 : return 0;
2786 :
2787 0 : out:
2788 0 : for (i = 0; i < len; i++)
2789 0 : free_AlgorithmIdentifier(&(*val)[i]);
2790 0 : free(*val);
2791 0 : *val = NULL;
2792 0 : hx509_set_error_string(context, 0, ENOMEM, "out of memory");
2793 0 : return ENOMEM;
2794 : }
2795 :
2796 : HX509_LIB_FUNCTION void HX509_LIB_CALL
2797 0 : hx509_crypto_free_algs(AlgorithmIdentifier *val,
2798 : unsigned int len)
2799 : {
2800 : unsigned int i;
2801 0 : for (i = 0; i < len; i++)
2802 0 : free_AlgorithmIdentifier(&val[i]);
2803 0 : free(val);
2804 0 : }
|