Line data Source code
1 : /*
2 : * Copyright (c) 2006 - 2008 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 <config.h>
35 : #include <roken.h>
36 : #include <krb5-types.h>
37 : #include <rfc2459_asn1.h>
38 :
39 : #include <der.h>
40 :
41 : #include <rsa.h>
42 :
43 : #include "common.h"
44 :
45 : /**
46 : * @page page_rsa RSA - public-key cryptography
47 : *
48 : * RSA is named by its inventors (Ron Rivest, Adi Shamir, and Leonard
49 : * Adleman) (published in 1977), patented expired in 21 September 2000.
50 : *
51 : *
52 : * Speed for RSA in seconds
53 : * no key blinding
54 : * 1000 iteration,
55 : * same rsa keys (1024 and 2048)
56 : * operation performed each eteration sign, verify, encrypt, decrypt on a random bit pattern
57 : *
58 : * name 1024 2048 4098
59 : * =================================
60 : * gmp: 0.73 6.60 44.80
61 : * tfm: 2.45 -- --
62 : * ltm: 3.79 20.74 105.41 (default in hcrypto)
63 : * openssl: 4.04 11.90 82.59
64 : * cdsa: 15.89 102.89 721.40
65 : * imath: 40.62 -- --
66 : *
67 : * See the library functions here: @ref hcrypto_rsa
68 : */
69 :
70 : /**
71 : * Same as RSA_new_method() using NULL as engine.
72 : *
73 : * @return a newly allocated RSA object. Free with RSA_free().
74 : *
75 : * @ingroup hcrypto_rsa
76 : */
77 :
78 : RSA *
79 394 : RSA_new(void)
80 : {
81 394 : return RSA_new_method(NULL);
82 : }
83 :
84 : /**
85 : * Allocate a new RSA object using the engine, if NULL is specified as
86 : * the engine, use the default RSA engine as returned by
87 : * ENGINE_get_default_RSA().
88 : *
89 : * @param engine Specific what ENGINE RSA provider should be used.
90 : *
91 : * @return a newly allocated RSA object. Free with RSA_free().
92 : *
93 : * @ingroup hcrypto_rsa
94 : */
95 :
96 : RSA *
97 394 : RSA_new_method(ENGINE *engine)
98 : {
99 16 : RSA *rsa;
100 :
101 394 : rsa = calloc(1, sizeof(*rsa));
102 394 : if (rsa == NULL)
103 0 : return NULL;
104 :
105 394 : rsa->references = 1;
106 :
107 394 : if (engine) {
108 0 : ENGINE_up_ref(engine);
109 0 : rsa->engine = engine;
110 : } else {
111 394 : rsa->engine = ENGINE_get_default_RSA();
112 : }
113 :
114 394 : if (rsa->engine) {
115 0 : rsa->meth = ENGINE_get_RSA(rsa->engine);
116 0 : if (rsa->meth == NULL) {
117 0 : ENGINE_finish(rsa->engine);
118 0 : free(rsa);
119 0 : return 0;
120 : }
121 : }
122 :
123 394 : if (rsa->meth == NULL)
124 394 : rsa->meth = rk_UNCONST(RSA_get_default_method());
125 :
126 394 : (*rsa->meth->init)(rsa);
127 :
128 394 : return rsa;
129 : }
130 :
131 : /**
132 : * Free an allocation RSA object.
133 : *
134 : * @param rsa the RSA object to free.
135 : * @ingroup hcrypto_rsa
136 : */
137 :
138 : void
139 340 : RSA_free(RSA *rsa)
140 : {
141 340 : if (rsa->references <= 0)
142 0 : abort();
143 :
144 340 : if (--rsa->references > 0)
145 0 : return;
146 :
147 340 : (*rsa->meth->finish)(rsa);
148 :
149 340 : if (rsa->engine)
150 0 : ENGINE_finish(rsa->engine);
151 :
152 : #define free_if(f) if (f) { BN_free(f); }
153 340 : free_if(rsa->n);
154 340 : free_if(rsa->e);
155 340 : free_if(rsa->d);
156 340 : free_if(rsa->p);
157 340 : free_if(rsa->q);
158 340 : free_if(rsa->dmp1);
159 340 : free_if(rsa->dmq1);
160 340 : free_if(rsa->iqmp);
161 : #undef free_if
162 :
163 340 : memset_s(rsa, sizeof(*rsa), 0, sizeof(*rsa));
164 340 : free(rsa);
165 : }
166 :
167 : /**
168 : * Add an extra reference to the RSA object. The object should be free
169 : * with RSA_free() to drop the reference.
170 : *
171 : * @param rsa the object to add reference counting too.
172 : *
173 : * @return the current reference count, can't safely be used except
174 : * for debug printing.
175 : *
176 : * @ingroup hcrypto_rsa
177 : */
178 :
179 : int
180 0 : RSA_up_ref(RSA *rsa)
181 : {
182 0 : return ++rsa->references;
183 : }
184 :
185 : /**
186 : * Return the RSA_METHOD used for this RSA object.
187 : *
188 : * @param rsa the object to get the method from.
189 : *
190 : * @return the method used for this RSA object.
191 : *
192 : * @ingroup hcrypto_rsa
193 : */
194 :
195 : const RSA_METHOD *
196 0 : RSA_get_method(const RSA *rsa)
197 : {
198 0 : return rsa->meth;
199 : }
200 :
201 : /**
202 : * Set a new method for the RSA keypair.
203 : *
204 : * @param rsa rsa parameter.
205 : * @param method the new method for the RSA parameter.
206 : *
207 : * @return 1 on success.
208 : *
209 : * @ingroup hcrypto_rsa
210 : */
211 :
212 : int
213 0 : RSA_set_method(RSA *rsa, const RSA_METHOD *method)
214 : {
215 0 : (*rsa->meth->finish)(rsa);
216 :
217 0 : if (rsa->engine) {
218 0 : ENGINE_finish(rsa->engine);
219 0 : rsa->engine = NULL;
220 : }
221 :
222 0 : rsa->meth = method;
223 0 : (*rsa->meth->init)(rsa);
224 0 : return 1;
225 : }
226 :
227 : /**
228 : * Set the application data for the RSA object.
229 : *
230 : * @param rsa the rsa object to set the parameter for
231 : * @param arg the data object to store
232 : *
233 : * @return 1 on success.
234 : *
235 : * @ingroup hcrypto_rsa
236 : */
237 :
238 : int
239 0 : RSA_set_app_data(RSA *rsa, void *arg)
240 : {
241 0 : rsa->ex_data.sk = arg;
242 0 : return 1;
243 : }
244 :
245 : /**
246 : * Get the application data for the RSA object.
247 : *
248 : * @param rsa the rsa object to get the parameter for
249 : *
250 : * @return the data object
251 : *
252 : * @ingroup hcrypto_rsa
253 : */
254 :
255 : void *
256 0 : RSA_get_app_data(const RSA *rsa)
257 : {
258 0 : return rsa->ex_data.sk;
259 : }
260 :
261 : int
262 74 : RSA_check_key(const RSA *key)
263 : {
264 8 : static const unsigned char inbuf[] = "hello, world!";
265 74 : RSA *rsa = rk_UNCONST(key);
266 8 : void *buffer;
267 8 : int ret;
268 :
269 : /*
270 : * XXX I have no clue how to implement this w/o a bignum library.
271 : * Well, when we have a RSA key pair, we can try to encrypt/sign
272 : * and then decrypt/verify.
273 : */
274 :
275 74 : if (rsa->n == NULL)
276 0 : return 0;
277 :
278 74 : if (rsa->d == NULL &&
279 0 : (rsa->p == NULL || rsa->q || rsa->dmp1 == NULL || rsa->dmq1 == NULL || rsa->iqmp == NULL))
280 0 : return 0;
281 :
282 74 : buffer = malloc(RSA_size(rsa));
283 74 : if (buffer == NULL)
284 0 : return 0;
285 :
286 74 : ret = RSA_private_encrypt(sizeof(inbuf), inbuf, buffer,
287 : rsa, RSA_PKCS1_PADDING);
288 74 : if (ret == -1) {
289 0 : free(buffer);
290 0 : return 0;
291 : }
292 :
293 74 : ret = RSA_public_decrypt(ret, buffer, buffer,
294 : rsa, RSA_PKCS1_PADDING);
295 74 : if (ret == -1) {
296 0 : free(buffer);
297 0 : return 0;
298 : }
299 :
300 74 : if (ret == sizeof(inbuf) && ct_memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
301 74 : free(buffer);
302 74 : return 1;
303 : }
304 0 : free(buffer);
305 0 : return 0;
306 : }
307 :
308 : int
309 1143 : RSA_size(const RSA *rsa)
310 : {
311 1143 : return BN_num_bytes(rsa->n);
312 : }
313 :
314 : #define RSAFUNC(name, body) \
315 : int \
316 : name(int flen,const unsigned char* f, unsigned char* t, RSA* r, int p){\
317 : return body; \
318 : }
319 :
320 21 : RSAFUNC(RSA_public_encrypt, (r)->meth->rsa_pub_enc(flen, f, t, r, p))
321 299 : RSAFUNC(RSA_public_decrypt, (r)->meth->rsa_pub_dec(flen, f, t, r, p))
322 139 : RSAFUNC(RSA_private_encrypt, (r)->meth->rsa_priv_enc(flen, f, t, r, p))
323 0 : RSAFUNC(RSA_private_decrypt, (r)->meth->rsa_priv_dec(flen, f, t, r, p))
324 :
325 : static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
326 :
327 : static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
328 : static const AlgorithmIdentifier _signature_sha1_data = {
329 : { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
330 : };
331 : static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
332 : static const AlgorithmIdentifier _signature_sha256_data = {
333 : { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
334 : };
335 : static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
336 : static const AlgorithmIdentifier _signature_md5_data = {
337 : { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
338 : };
339 :
340 :
341 : int
342 0 : RSA_sign(int type, const unsigned char *from, unsigned int flen,
343 : unsigned char *to, unsigned int *tlen, RSA *rsa)
344 : {
345 0 : if (rsa->meth->rsa_sign)
346 0 : return rsa->meth->rsa_sign(type, from, flen, to, tlen, rsa);
347 :
348 0 : if (rsa->meth->rsa_priv_enc) {
349 0 : heim_octet_string indata;
350 0 : DigestInfo di;
351 0 : size_t size;
352 0 : int ret;
353 :
354 0 : memset(&di, 0, sizeof(di));
355 :
356 0 : if (type == NID_sha1) {
357 0 : di.digestAlgorithm = _signature_sha1_data;
358 0 : } else if (type == NID_md5) {
359 0 : di.digestAlgorithm = _signature_md5_data;
360 0 : } else if (type == NID_sha256) {
361 0 : di.digestAlgorithm = _signature_sha256_data;
362 : } else
363 0 : return -1;
364 :
365 0 : di.digest.data = rk_UNCONST(from);
366 0 : di.digest.length = flen;
367 :
368 0 : ASN1_MALLOC_ENCODE(DigestInfo,
369 : indata.data,
370 : indata.length,
371 : &di,
372 : &size,
373 : ret);
374 0 : if (ret)
375 0 : return ret;
376 0 : if (indata.length != size)
377 0 : abort();
378 :
379 0 : ret = rsa->meth->rsa_priv_enc(indata.length, indata.data, to,
380 : rsa, RSA_PKCS1_PADDING);
381 0 : free(indata.data);
382 0 : if (ret > 0) {
383 0 : *tlen = ret;
384 0 : ret = 1;
385 : } else
386 0 : ret = 0;
387 :
388 0 : return ret;
389 : }
390 :
391 0 : return 0;
392 : }
393 :
394 : int
395 0 : RSA_verify(int type, const unsigned char *from, unsigned int flen,
396 : unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
397 : {
398 0 : if (rsa->meth->rsa_verify)
399 0 : return rsa->meth->rsa_verify(type, from, flen, sigbuf, siglen, rsa);
400 :
401 0 : if (rsa->meth->rsa_pub_dec) {
402 0 : const AlgorithmIdentifier *digest_alg;
403 0 : void *data;
404 0 : DigestInfo di;
405 0 : size_t size;
406 0 : int ret, ret2;
407 :
408 0 : data = malloc(RSA_size(rsa));
409 0 : if (data == NULL)
410 0 : return -1;
411 :
412 0 : memset(&di, 0, sizeof(di));
413 :
414 0 : ret = rsa->meth->rsa_pub_dec(siglen, sigbuf, data, rsa, RSA_PKCS1_PADDING);
415 0 : if (ret <= 0) {
416 0 : free(data);
417 0 : return -2;
418 : }
419 :
420 0 : ret2 = decode_DigestInfo(data, ret, &di, &size);
421 0 : free(data);
422 0 : if (ret2 != 0)
423 0 : return -3;
424 0 : if (ret != size) {
425 0 : free_DigestInfo(&di);
426 0 : return -4;
427 : }
428 :
429 0 : if (flen != di.digest.length || ct_memcmp(di.digest.data, from, flen) != 0) {
430 0 : free_DigestInfo(&di);
431 0 : return -5;
432 : }
433 :
434 0 : if (type == NID_sha1) {
435 0 : digest_alg = &_signature_sha1_data;
436 0 : } else if (type == NID_md5) {
437 0 : digest_alg = &_signature_md5_data;
438 0 : } else if (type == NID_sha256) {
439 0 : digest_alg = &_signature_sha256_data;
440 : } else {
441 0 : free_DigestInfo(&di);
442 0 : return -1;
443 : }
444 :
445 0 : ret = der_heim_oid_cmp(&digest_alg->algorithm,
446 : &di.digestAlgorithm.algorithm);
447 0 : free_DigestInfo(&di);
448 :
449 0 : if (ret != 0)
450 0 : return 0;
451 0 : return 1;
452 : }
453 :
454 0 : return 0;
455 : }
456 :
457 : /*
458 : * A NULL RSA_METHOD that returns failure for all operations. This is
459 : * used as the default RSA method if we don't have any native
460 : * support.
461 : */
462 :
463 0 : static RSAFUNC(null_rsa_public_encrypt, -1)
464 0 : static RSAFUNC(null_rsa_public_decrypt, -1)
465 0 : static RSAFUNC(null_rsa_private_encrypt, -1)
466 0 : static RSAFUNC(null_rsa_private_decrypt, -1)
467 :
468 : /*
469 : *
470 : */
471 :
472 : int
473 0 : RSA_generate_key_ex(RSA *r, int bits, BIGNUM *e, BN_GENCB *cb)
474 : {
475 0 : if (r->meth->rsa_keygen)
476 0 : return (*r->meth->rsa_keygen)(r, bits, e, cb);
477 0 : return 0;
478 : }
479 :
480 :
481 : /*
482 : *
483 : */
484 :
485 : static int
486 0 : null_rsa_init(RSA *rsa)
487 : {
488 0 : return 1;
489 : }
490 :
491 : static int
492 0 : null_rsa_finish(RSA *rsa)
493 : {
494 0 : return 1;
495 : }
496 :
497 : static const RSA_METHOD rsa_null_method = {
498 : "hcrypto null RSA",
499 : null_rsa_public_encrypt,
500 : null_rsa_public_decrypt,
501 : null_rsa_private_encrypt,
502 : null_rsa_private_decrypt,
503 : NULL,
504 : NULL,
505 : null_rsa_init,
506 : null_rsa_finish,
507 : 0,
508 : NULL,
509 : NULL,
510 : NULL,
511 : NULL
512 : };
513 :
514 : const RSA_METHOD *
515 0 : RSA_null_method(void)
516 : {
517 0 : return &rsa_null_method;
518 : }
519 :
520 : extern const RSA_METHOD hc_rsa_gmp_method;
521 : extern const RSA_METHOD hc_rsa_tfm_method;
522 : extern const RSA_METHOD hc_rsa_ltm_method;
523 : static const RSA_METHOD *default_rsa_method = &hc_rsa_ltm_method;
524 :
525 :
526 : const RSA_METHOD *
527 394 : RSA_get_default_method(void)
528 : {
529 394 : return default_rsa_method;
530 : }
531 :
532 : void
533 0 : RSA_set_default_method(const RSA_METHOD *meth)
534 : {
535 0 : default_rsa_method = meth;
536 0 : }
537 :
538 : /*
539 : *
540 : */
541 :
542 : RSA *
543 74 : d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
544 : {
545 8 : RSAPrivateKey data;
546 74 : RSA *k = rsa;
547 8 : size_t size;
548 8 : int ret;
549 :
550 74 : ret = decode_RSAPrivateKey(*pp, len, &data, &size);
551 74 : if (ret)
552 0 : return NULL;
553 :
554 74 : *pp += size;
555 :
556 74 : if (k == NULL) {
557 74 : k = RSA_new();
558 74 : if (k == NULL) {
559 0 : free_RSAPrivateKey(&data);
560 0 : return NULL;
561 : }
562 : }
563 :
564 74 : k->n = _hc_integer_to_BN(&data.modulus, NULL);
565 74 : k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
566 74 : k->d = _hc_integer_to_BN(&data.privateExponent, NULL);
567 74 : k->p = _hc_integer_to_BN(&data.prime1, NULL);
568 74 : k->q = _hc_integer_to_BN(&data.prime2, NULL);
569 74 : k->dmp1 = _hc_integer_to_BN(&data.exponent1, NULL);
570 74 : k->dmq1 = _hc_integer_to_BN(&data.exponent2, NULL);
571 74 : k->iqmp = _hc_integer_to_BN(&data.coefficient, NULL);
572 74 : free_RSAPrivateKey(&data);
573 :
574 74 : if (k->n == NULL || k->e == NULL || k->d == NULL || k->p == NULL ||
575 74 : k->q == NULL || k->dmp1 == NULL || k->dmq1 == NULL || k->iqmp == NULL)
576 : {
577 0 : RSA_free(k);
578 0 : return NULL;
579 : }
580 :
581 66 : return k;
582 : }
583 :
584 : int
585 0 : i2d_RSAPrivateKey(RSA *rsa, unsigned char **pp)
586 : {
587 0 : RSAPrivateKey data;
588 0 : size_t size;
589 0 : int ret;
590 :
591 0 : if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL || rsa->p == NULL ||
592 0 : rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 == NULL ||
593 0 : rsa->iqmp == NULL)
594 0 : return -1;
595 :
596 0 : memset(&data, 0, sizeof(data));
597 :
598 0 : ret = _hc_BN_to_integer(rsa->n, &data.modulus);
599 0 : ret |= _hc_BN_to_integer(rsa->e, &data.publicExponent);
600 0 : ret |= _hc_BN_to_integer(rsa->d, &data.privateExponent);
601 0 : ret |= _hc_BN_to_integer(rsa->p, &data.prime1);
602 0 : ret |= _hc_BN_to_integer(rsa->q, &data.prime2);
603 0 : ret |= _hc_BN_to_integer(rsa->dmp1, &data.exponent1);
604 0 : ret |= _hc_BN_to_integer(rsa->dmq1, &data.exponent2);
605 0 : ret |= _hc_BN_to_integer(rsa->iqmp, &data.coefficient);
606 0 : if (ret) {
607 0 : free_RSAPrivateKey(&data);
608 0 : return -1;
609 : }
610 :
611 0 : if (pp == NULL) {
612 0 : size = length_RSAPrivateKey(&data);
613 0 : free_RSAPrivateKey(&data);
614 : } else {
615 0 : void *p;
616 0 : size_t len;
617 :
618 0 : ASN1_MALLOC_ENCODE(RSAPrivateKey, p, len, &data, &size, ret);
619 0 : free_RSAPrivateKey(&data);
620 0 : if (ret)
621 0 : return -1;
622 0 : if (len != size)
623 0 : abort();
624 :
625 0 : memcpy(*pp, p, size);
626 0 : free(p);
627 :
628 0 : *pp += size;
629 :
630 : }
631 0 : return size;
632 : }
633 :
634 : int
635 0 : i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
636 : {
637 0 : RSAPublicKey data;
638 0 : size_t size;
639 0 : int ret;
640 :
641 0 : memset(&data, 0, sizeof(data));
642 :
643 0 : if (_hc_BN_to_integer(rsa->n, &data.modulus) ||
644 0 : _hc_BN_to_integer(rsa->e, &data.publicExponent))
645 : {
646 0 : free_RSAPublicKey(&data);
647 0 : return -1;
648 : }
649 :
650 0 : if (pp == NULL) {
651 0 : size = length_RSAPublicKey(&data);
652 0 : free_RSAPublicKey(&data);
653 : } else {
654 0 : void *p;
655 0 : size_t len;
656 :
657 0 : ASN1_MALLOC_ENCODE(RSAPublicKey, p, len, &data, &size, ret);
658 0 : free_RSAPublicKey(&data);
659 0 : if (ret)
660 0 : return -1;
661 0 : if (len != size)
662 0 : abort();
663 :
664 0 : memcpy(*pp, p, size);
665 0 : free(p);
666 :
667 0 : *pp += size;
668 : }
669 :
670 0 : return size;
671 : }
672 :
673 : RSA *
674 246 : d2i_RSAPublicKey(RSA *rsa, const unsigned char **pp, size_t len)
675 : {
676 0 : RSAPublicKey data;
677 246 : RSA *k = rsa;
678 0 : size_t size;
679 0 : int ret;
680 :
681 246 : ret = decode_RSAPublicKey(*pp, len, &data, &size);
682 246 : if (ret)
683 0 : return NULL;
684 :
685 246 : *pp += size;
686 :
687 246 : if (k == NULL) {
688 246 : k = RSA_new();
689 246 : if (k == NULL) {
690 0 : free_RSAPublicKey(&data);
691 0 : return NULL;
692 : }
693 : }
694 :
695 246 : k->n = _hc_integer_to_BN(&data.modulus, NULL);
696 246 : k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
697 :
698 246 : free_RSAPublicKey(&data);
699 :
700 246 : if (k->n == NULL || k->e == NULL) {
701 0 : RSA_free(k);
702 0 : return NULL;
703 : }
704 :
705 246 : return k;
706 : }
|