Coverage Report

Created: 2025-12-31 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/third_party/heimdal/lib/hcrypto/rsa.c
Line
Count
Source
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
RSA_new(void)
80
0
{
81
0
    return RSA_new_method(NULL);
82
0
}
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
RSA_new_method(ENGINE *engine)
98
0
{
99
0
    RSA *rsa;
100
101
0
    rsa = calloc(1, sizeof(*rsa));
102
0
    if (rsa == NULL)
103
0
  return NULL;
104
105
0
    rsa->references = 1;
106
107
0
    if (engine) {
108
0
  ENGINE_up_ref(engine);
109
0
  rsa->engine = engine;
110
0
    } else {
111
0
  rsa->engine = ENGINE_get_default_RSA();
112
0
    }
113
114
0
    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
0
  }
121
0
    }
122
123
0
    if (rsa->meth == NULL)
124
0
  rsa->meth = rk_UNCONST(RSA_get_default_method());
125
126
0
    (*rsa->meth->init)(rsa);
127
128
0
    return rsa;
129
0
}
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
RSA_free(RSA *rsa)
140
0
{
141
0
    if (rsa->references <= 0)
142
0
  abort();
143
144
0
    if (--rsa->references > 0)
145
0
  return;
146
147
0
    (*rsa->meth->finish)(rsa);
148
149
0
    if (rsa->engine)
150
0
  ENGINE_finish(rsa->engine);
151
152
0
#define free_if(f) if (f) { BN_free(f); }
153
0
    free_if(rsa->n);
154
0
    free_if(rsa->e);
155
0
    free_if(rsa->d);
156
0
    free_if(rsa->p);
157
0
    free_if(rsa->q);
158
0
    free_if(rsa->dmp1);
159
0
    free_if(rsa->dmq1);
160
0
    free_if(rsa->iqmp);
161
0
#undef free_if
162
163
0
    memset_s(rsa, sizeof(*rsa), 0, sizeof(*rsa));
164
0
    free(rsa);
165
0
}
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
RSA_up_ref(RSA *rsa)
181
0
{
182
0
    return ++rsa->references;
183
0
}
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
RSA_get_method(const RSA *rsa)
197
0
{
198
0
    return rsa->meth;
199
0
}
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
RSA_set_method(RSA *rsa, const RSA_METHOD *method)
214
0
{
215
0
    (*rsa->meth->finish)(rsa);
216
217
0
    if (rsa->engine) {
218
0
  ENGINE_finish(rsa->engine);
219
0
  rsa->engine = NULL;
220
0
    }
221
222
0
    rsa->meth = method;
223
0
    (*rsa->meth->init)(rsa);
224
0
    return 1;
225
0
}
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
RSA_set_app_data(RSA *rsa, void *arg)
240
0
{
241
0
    rsa->ex_data.sk = arg;
242
0
    return 1;
243
0
}
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
RSA_get_app_data(const RSA *rsa)
257
0
{
258
0
    return rsa->ex_data.sk;
259
0
}
260
261
int
262
RSA_check_key(const RSA *key)
263
0
{
264
0
    static const unsigned char inbuf[] = "hello, world!";
265
0
    RSA *rsa = rk_UNCONST(key);
266
0
    void *buffer;
267
0
    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
0
    if (rsa->n == NULL)
276
0
  return 0;
277
278
0
    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
0
    buffer = malloc(RSA_size(rsa));
283
0
    if (buffer == NULL)
284
0
  return 0;
285
286
0
    ret = RSA_private_encrypt(sizeof(inbuf), inbuf, buffer,
287
0
           rsa, RSA_PKCS1_PADDING);
288
0
    if (ret == -1) {
289
0
  free(buffer);
290
0
  return 0;
291
0
    }
292
293
0
    ret = RSA_public_decrypt(ret, buffer, buffer,
294
0
            rsa, RSA_PKCS1_PADDING);
295
0
    if (ret == -1) {
296
0
  free(buffer);
297
0
  return 0;
298
0
    }
299
300
0
    if (ret == sizeof(inbuf) && ct_memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
301
0
  free(buffer);
302
0
  return 1;
303
0
    }
304
0
    free(buffer);
305
0
    return 0;
306
0
}
307
308
int
309
RSA_size(const RSA *rsa)
310
0
{
311
0
    return BN_num_bytes(rsa->n);
312
0
}
313
314
#define RSAFUNC(name, body) \
315
int \
316
0
name(int flen,const unsigned char* f, unsigned char* t, RSA* r, int p){\
317
0
    return body; \
318
0
}
Unexecuted instantiation: hc_RSA_public_encrypt
Unexecuted instantiation: hc_RSA_public_decrypt
Unexecuted instantiation: hc_RSA_private_encrypt
Unexecuted instantiation: hc_RSA_private_decrypt
Unexecuted instantiation: rsa.c:null_rsa_public_encrypt
Unexecuted instantiation: rsa.c:null_rsa_public_decrypt
Unexecuted instantiation: rsa.c:null_rsa_private_encrypt
Unexecuted instantiation: rsa.c:null_rsa_private_decrypt
319
320
RSAFUNC(RSA_public_encrypt, (r)->meth->rsa_pub_enc(flen, f, t, r, p))
321
RSAFUNC(RSA_public_decrypt, (r)->meth->rsa_pub_dec(flen, f, t, r, p))
322
RSAFUNC(RSA_private_encrypt, (r)->meth->rsa_priv_enc(flen, f, t, r, p))
323
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
RSA_sign(int type, const unsigned char *from, unsigned int flen,
343
   unsigned char *to, unsigned int *tlen, RSA *rsa)
344
0
{
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
0
  } 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
0
         indata.data,
370
0
         indata.length,
371
0
         &di,
372
0
         &size,
373
0
         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
0
              rsa, RSA_PKCS1_PADDING);
381
0
  free(indata.data);
382
0
  if (ret > 0) {
383
0
      *tlen = ret;
384
0
      ret = 1;
385
0
  } else
386
0
      ret = 0;
387
388
0
  return ret;
389
0
    }
390
391
0
    return 0;
392
0
}
393
394
int
395
RSA_verify(int type, const unsigned char *from, unsigned int flen,
396
     unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
397
0
{
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
0
  }
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
0
  }
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
0
  }
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
0
  } else {
441
0
      free_DigestInfo(&di);
442
0
      return -1;
443
0
  }
444
445
0
  ret = der_heim_oid_cmp(&digest_alg->algorithm,
446
0
             &di.digestAlgorithm.algorithm);
447
0
  free_DigestInfo(&di);
448
449
0
  if (ret != 0)
450
0
      return 0;
451
0
  return 1;
452
0
    }
453
454
0
    return 0;
455
0
}
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
static RSAFUNC(null_rsa_public_encrypt, -1)
464
static RSAFUNC(null_rsa_public_decrypt, -1)
465
static RSAFUNC(null_rsa_private_encrypt, -1)
466
static RSAFUNC(null_rsa_private_decrypt, -1)
467
468
/*
469
 *
470
 */
471
472
int
473
RSA_generate_key_ex(RSA *r, int bits, BIGNUM *e, BN_GENCB *cb)
474
0
{
475
0
    if (r->meth->rsa_keygen)
476
0
  return (*r->meth->rsa_keygen)(r, bits, e, cb);
477
0
    return 0;
478
0
}
479
480
481
/*
482
 *
483
 */
484
485
static int
486
null_rsa_init(RSA *rsa)
487
0
{
488
0
    return 1;
489
0
}
490
491
static int
492
null_rsa_finish(RSA *rsa)
493
0
{
494
0
    return 1;
495
0
}
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
RSA_null_method(void)
516
0
{
517
0
    return &rsa_null_method;
518
0
}
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
RSA_get_default_method(void)
528
0
{
529
0
    return default_rsa_method;
530
0
}
531
532
void
533
RSA_set_default_method(const RSA_METHOD *meth)
534
0
{
535
0
    default_rsa_method = meth;
536
0
}
537
538
/*
539
 *
540
 */
541
542
RSA *
543
d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
544
0
{
545
0
    RSAPrivateKey data;
546
0
    RSA *k = rsa;
547
0
    size_t size;
548
0
    int ret;
549
550
0
    ret = decode_RSAPrivateKey(*pp, len, &data, &size);
551
0
    if (ret)
552
0
  return NULL;
553
554
0
    *pp += size;
555
556
0
    if (k == NULL) {
557
0
  k = RSA_new();
558
0
  if (k == NULL) {
559
0
      free_RSAPrivateKey(&data);
560
0
      return NULL;
561
0
  }
562
0
    }
563
564
0
    k->n = _hc_integer_to_BN(&data.modulus, NULL);
565
0
    k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
566
0
    k->d = _hc_integer_to_BN(&data.privateExponent, NULL);
567
0
    k->p = _hc_integer_to_BN(&data.prime1, NULL);
568
0
    k->q = _hc_integer_to_BN(&data.prime2, NULL);
569
0
    k->dmp1 = _hc_integer_to_BN(&data.exponent1, NULL);
570
0
    k->dmq1 = _hc_integer_to_BN(&data.exponent2, NULL);
571
0
    k->iqmp = _hc_integer_to_BN(&data.coefficient, NULL);
572
0
    free_RSAPrivateKey(&data);
573
574
0
    if (k->n == NULL || k->e == NULL || k->d == NULL || k->p == NULL ||
575
0
  k->q == NULL || k->dmp1 == NULL || k->dmq1 == NULL || k->iqmp == NULL)
576
0
    {
577
0
  RSA_free(k);
578
0
  return NULL;
579
0
    }
580
581
0
    return k;
582
0
}
583
584
int
585
i2d_RSAPrivateKey(RSA *rsa, unsigned char **pp)
586
0
{
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
0
    }
610
611
0
    if (pp == NULL) {
612
0
  size = length_RSAPrivateKey(&data);
613
0
  free_RSAPrivateKey(&data);
614
0
    } 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
0
    }
631
0
    return size;
632
0
}
633
634
int
635
i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
636
0
{
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
0
    {
646
0
  free_RSAPublicKey(&data);
647
0
  return -1;
648
0
    }
649
650
0
    if (pp == NULL) {
651
0
  size = length_RSAPublicKey(&data);
652
0
  free_RSAPublicKey(&data);
653
0
    } 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
0
    }
669
670
0
    return size;
671
0
}
672
673
RSA *
674
d2i_RSAPublicKey(RSA *rsa, const unsigned char **pp, size_t len)
675
0
{
676
0
    RSAPublicKey data;
677
0
    RSA *k = rsa;
678
0
    size_t size;
679
0
    int ret;
680
681
0
    ret = decode_RSAPublicKey(*pp, len, &data, &size);
682
0
    if (ret)
683
0
  return NULL;
684
685
0
    *pp += size;
686
687
0
    if (k == NULL) {
688
0
  k = RSA_new();
689
0
  if (k == NULL) {
690
0
      free_RSAPublicKey(&data);
691
0
      return NULL;
692
0
  }
693
0
    }
694
695
0
    k->n = _hc_integer_to_BN(&data.modulus, NULL);
696
0
    k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
697
698
0
    free_RSAPublicKey(&data);
699
700
0
    if (k->n == NULL || k->e == NULL) {
701
0
  RSA_free(k);
702
0
  return NULL;
703
0
    }
704
705
0
    return k;
706
0
}