Tor  0.4.8.0-alpha-dev
crypto_rsa_nss.c
1 /* Copyright (c) 2001, Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
7 /**
8  * \file crypto_rsa.c
9  * \brief NSS implementations of our RSA code.
10  **/
11 
13 
16 #include "lib/ctime/di_ops.h"
17 #include "lib/encoding/binascii.h"
18 #include "lib/fs/files.h"
19 #include "lib/intmath/cmp.h"
20 #include "lib/intmath/muldiv.h"
21 #include "lib/log/log.h"
22 #include "lib/log/util_bug.h"
23 
24 #include <string.h>
25 
26 DISABLE_GCC_WARNING("-Wstrict-prototypes")
27 #include <keyhi.h>
28 #include <pk11pub.h>
29 #include <secder.h>
30 ENABLE_GCC_WARNING("-Wstrict-prototypes")
31 
32 #ifdef ENABLE_OPENSSL
33 #include <openssl/rsa.h>
34 #include <openssl/evp.h>
35 #endif
36 
37 /** Declaration for crypto_pk_t structure. */
39 {
40  SECKEYPrivateKey *seckey;
41  SECKEYPublicKey *pubkey;
42 };
43 
44 /** Return true iff <b>key</b> contains the private-key portion of the RSA
45  * key. */
46 int
48 {
49  return key && key->seckey;
50 }
51 
52 /** used by tortls.c: wrap a SecKEYPublicKey in a crypto_pk_t. Take ownership
53  * of the RSA object. */
55 crypto_pk_new_from_nss_pubkey(struct SECKEYPublicKeyStr *pub)
56 {
57  crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
58  result->pubkey = pub;
59  return result;
60 }
61 
62 /** Return the SECKEYPublicKey for the provided crypto_pk_t. */
63 const SECKEYPublicKey *
64 crypto_pk_get_nss_pubkey(const crypto_pk_t *key)
65 {
66  tor_assert(key);
67  return key->pubkey;
68 }
69 
70 /** Return the SECKEYPrivateKey for the provided crypto_pk_t, or NULL if it
71  * does not exist. */
72 const SECKEYPrivateKey *
73 crypto_pk_get_nss_privkey(const crypto_pk_t *key)
74 {
75  tor_assert(key);
76  return key->seckey;
77 }
78 
79 #ifdef ENABLE_OPENSSL
80 /** used by tortls.c: wrap an RSA* in a crypto_pk_t. Take ownership of the
81  * RSA object. */
83 crypto_new_pk_from_openssl_rsa_(RSA *rsa)
84 {
85  crypto_pk_t *pk = NULL;
86  unsigned char *buf = NULL;
87  int len = i2d_RSAPublicKey(rsa, &buf);
88  RSA_free(rsa);
89 
90  if (len < 0 || buf == NULL)
91  goto end;
92 
93  pk = crypto_pk_asn1_decode((const char *)buf, len);
94 
95  end:
96  if (buf)
97  OPENSSL_free(buf);
98  return pk;
99 }
100 
101 /** Helper, used by tor-gencert.c. Return the RSA from a
102  * crypto_pk_t. */
103 struct rsa_st *
104 crypto_pk_get_openssl_rsa_(crypto_pk_t *pk)
105 {
106  size_t buflen = crypto_pk_keysize(pk)*16;
107  unsigned char *buf = tor_malloc_zero(buflen);
108  const unsigned char *cp = buf;
109  RSA *rsa = NULL;
110 
111  int used = crypto_pk_asn1_encode_private(pk, (char*)buf, buflen);
112  if (used < 0)
113  goto end;
114  rsa = d2i_RSAPrivateKey(NULL, &cp, used);
115 
116  end:
117  memwipe(buf, 0, buflen);
118  tor_free(buf);
119  return rsa;
120 }
121 
122 /** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_t. Iff
123  * private is set, include the private-key portion of the key. Return a valid
124  * pointer on success, and NULL on failure. */
125 MOCK_IMPL(struct evp_pkey_st *,
126 crypto_pk_get_openssl_evp_pkey_,(crypto_pk_t *pk, int private))
127 {
128  size_t buflen = crypto_pk_keysize(pk)*16;
129  unsigned char *buf = tor_malloc_zero(buflen);
130  const unsigned char *cp = buf;
131  RSA *rsa = NULL;
132  EVP_PKEY *result = NULL;
133 
134  if (private) {
135  int len = crypto_pk_asn1_encode_private(pk, (char*)buf, buflen);
136  if (len < 0)
137  goto end;
138  rsa = d2i_RSAPrivateKey(NULL, &cp, len);
139  } else {
140  int len = crypto_pk_asn1_encode(pk, (char*)buf, buflen);
141  if (len < 0)
142  goto end;
143  rsa = d2i_RSAPublicKey(NULL, &cp, len);
144  }
145  if (!rsa)
146  goto end;
147 
148  if (!(result = EVP_PKEY_new()))
149  goto end;
150  if (!(EVP_PKEY_assign_RSA(result, rsa))) {
151  EVP_PKEY_free(result);
152  RSA_free(rsa);
153  result = NULL;
154  }
155 
156  end:
157  memwipe(buf, 0, buflen);
158  tor_free(buf);
159  return result;
160 }
161 #endif /* defined(ENABLE_OPENSSL) */
162 
163 /** Allocate and return storage for a public key. The key itself will not yet
164  * be set.
165  */
168 {
169  crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
170  return result;
171 }
172 
173 /** Release the NSS objects held in <b>key</b> */
174 static void
175 crypto_pk_clear(crypto_pk_t *key)
176 {
177  if (key->pubkey)
178  SECKEY_DestroyPublicKey(key->pubkey);
179  if (key->seckey)
180  SECKEY_DestroyPrivateKey(key->seckey);
181  memset(key, 0, sizeof(crypto_pk_t));
182 }
183 
184 /** Release a reference to an asymmetric key; when all the references
185  * are released, free the key.
186  */
187 void
189 {
190  if (!key)
191  return;
192 
193  crypto_pk_clear(key);
194 
195  tor_free(key);
196 }
197 
198 /** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
199  * Return 0 on success, -1 on failure.
200  */
201 MOCK_IMPL(int,
203 {
204  tor_assert(key);
205 
206  PK11RSAGenParams params = {
207  .keySizeInBits = bits,
208  .pe = TOR_RSA_EXPONENT
209  };
210 
211  int result = -1;
212  PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, NULL);
213  SECKEYPrivateKey *seckey = NULL;
214  SECKEYPublicKey *pubkey = NULL;
215 
216  if (!slot) {
217  crypto_nss_log_errors(LOG_WARN, "getting slot for RSA keygen");
218  goto done;
219  }
220 
221  seckey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &params,
222  &pubkey,
223  PR_FALSE /*isPerm */,
224  PR_FALSE /*isSensitive*/,
225  NULL);
226  if (seckey == NULL || pubkey == NULL) {
227  crypto_nss_log_errors(LOG_WARN, "generating an RSA key");
228  goto done;
229  }
230 
231  crypto_pk_clear(key);
232  key->seckey = seckey;
233  key->pubkey = pubkey;
234  seckey = NULL;
235  pubkey = NULL;
236 
237  result = 0;
238  done:
239  if (slot)
240  PK11_FreeSlot(slot);
241  if (pubkey)
242  SECKEY_DestroyPublicKey(pubkey);
243  if (seckey)
244  SECKEY_DestroyPrivateKey(seckey);
245 
246  return result;
247 }
248 
249 /** Return true iff <b>env</b> is a valid private key.
250  */
251 int
253 {
254  /* We don't need to do validation here, since unlike OpenSSL, NSS won't let
255  * us load private keys without validating them. */
256  return key && key->seckey;
257 }
258 
259 /** Return true iff <b>env</b> contains a public key whose public exponent
260  * equals 65537.
261  */
262 int
264 {
265  return key &&
266  key->pubkey &&
267  key->pubkey->keyType == rsaKey &&
268  DER_GetUInteger(&key->pubkey->u.rsa.publicExponent) == TOR_RSA_EXPONENT;
269 }
270 
271 /** Compare two big-endian integers stored in a and b; return a tristate.
272  */
273 STATIC int
274 secitem_uint_cmp(const SECItem *a, const SECItem *b)
275 {
276  const unsigned abits = SECKEY_BigIntegerBitLength(a);
277  const unsigned bbits = SECKEY_BigIntegerBitLength(b);
278 
279  if (abits < bbits)
280  return -1;
281  else if (abits > bbits)
282  return 1;
283 
284  /* okay, they have the same number of bits set. Get a pair of aligned
285  * pointers to their bytes that are set... */
286  const unsigned nbytes = CEIL_DIV(abits, 8);
287  tor_assert(nbytes <= a->len);
288  tor_assert(nbytes <= b->len);
289 
290  const unsigned char *aptr = a->data + (a->len - nbytes);
291  const unsigned char *bptr = b->data + (b->len - nbytes);
292 
293  /* And compare them. */
294  return fast_memcmp(aptr, bptr, nbytes);
295 }
296 
297 /** Compare the public-key components of a and b. Return less than 0
298  * if a<b, 0 if a==b, and greater than 0 if a>b. A NULL key is
299  * considered to be less than all non-NULL keys, and equal to itself.
300  *
301  * Note that this may leak information about the keys through timing.
302  */
303 int
305 {
306  int result;
307  char a_is_non_null = (a != NULL) && (a->pubkey != NULL);
308  char b_is_non_null = (b != NULL) && (b->pubkey != NULL);
309  char an_argument_is_null = !a_is_non_null | !b_is_non_null;
310 
311  result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
312  if (an_argument_is_null)
313  return result;
314 
315  // This is all Tor uses with this structure.
316  tor_assert(a->pubkey->keyType == rsaKey);
317  tor_assert(b->pubkey->keyType == rsaKey);
318 
319  const SECItem *a_n, *a_e, *b_n, *b_e;
320  a_n = &a->pubkey->u.rsa.modulus;
321  b_n = &b->pubkey->u.rsa.modulus;
322  a_e = &a->pubkey->u.rsa.publicExponent;
323  b_e = &b->pubkey->u.rsa.publicExponent;
324 
325  result = secitem_uint_cmp(a_n, b_n);
326  if (result)
327  return result;
328  return secitem_uint_cmp(a_e, b_e);
329 }
330 
331 /** Return the size of the public key modulus in <b>env</b>, in bytes. */
332 size_t
334 {
335  tor_assert(key);
336  tor_assert(key->pubkey);
337  return SECKEY_PublicKeyStrength(key->pubkey);
338 }
339 
340 /** Return the size of the public key modulus of <b>env</b>, in bits. */
341 int
343 {
344  tor_assert(key);
345  tor_assert(key->pubkey);
346  return SECKEY_PublicKeyStrengthInBits(key->pubkey);
347 }
348 
349 /**
350  * Make a copy of <b>key</b> and return it.
351  */
352 crypto_pk_t *
354 {
355  crypto_pk_t *result = crypto_pk_new();
356  if (key->pubkey)
357  result->pubkey = SECKEY_CopyPublicKey(key->pubkey);
358  if (key->seckey)
359  result->seckey = SECKEY_CopyPrivateKey(key->seckey);
360  return result;
361 }
362 
363 /** For testing: replace dest with src. (Dest must have a refcount
364  * of 1) */
365 void
367 {
368  crypto_pk_clear(dest);
369  if (src->pubkey)
370  dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
371 }
372 
373 /** For testing: replace dest with src. (Dest must have a refcount
374  * of 1) */
375 void
377 {
378  crypto_pk_clear(dest);
379  if (src->pubkey)
380  dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
381  if (src->seckey)
382  dest->seckey = SECKEY_CopyPrivateKey(src->seckey);
383 }
384 
385 /** Make a real honest-to-goodness copy of <b>env</b>, and return it.
386  * Returns NULL on failure. */
387 crypto_pk_t *
389 {
390  // These aren't reference-counted is nss, so it's fine to just
391  // use the same function.
392  return crypto_pk_dup_key(key);
393 }
394 
395 static const CK_RSA_PKCS_OAEP_PARAMS oaep_params = {
396  .hashAlg = CKM_SHA_1,
397  .mgf = CKG_MGF1_SHA1,
398  .source = CKZ_DATA_SPECIFIED,
399  .pSourceData = NULL,
400  .ulSourceDataLen = 0
401 };
402 static const SECItem oaep_item = {
403  .type = siBuffer,
404  .data = (unsigned char *) &oaep_params,
405  .len = sizeof(oaep_params)
406 };
407 
408 /** Return the mechanism code and parameters for a given padding method when
409  * used with RSA */
410 static CK_MECHANISM_TYPE
411 padding_to_mechanism(int padding, SECItem **item_out)
412 {
413  switch (padding) {
415  *item_out = (SECItem *)&oaep_item;
416  return CKM_RSA_PKCS_OAEP;
417  default:
418  tor_assert_unreached();
419  *item_out = NULL;
420  return CKM_INVALID_MECHANISM;
421  }
422 }
423 
424 /** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
425  * in <b>env</b>, using the padding method <b>padding</b>. On success,
426  * write the result to <b>to</b>, and return the number of bytes
427  * written. On failure, return -1.
428  *
429  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
430  * at least the length of the modulus of <b>env</b>.
431  */
432 int
433 crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
434  const char *from, size_t fromlen, int padding)
435 {
436  tor_assert(env);
437  tor_assert(to);
438  tor_assert(from);
439  tor_assert(tolen < INT_MAX);
440  tor_assert(fromlen < INT_MAX);
441 
442  if (BUG(! env->pubkey))
443  return -1;
444 
445  unsigned int result_len = 0;
446  SECItem *item = NULL;
447  CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
448 
449  SECStatus s = PK11_PubEncrypt(env->pubkey, m, item,
450  (unsigned char *)to, &result_len,
451  (unsigned int)tolen,
452  (const unsigned char *)from,
453  (unsigned int)fromlen,
454  NULL);
455  if (s != SECSuccess) {
456  crypto_nss_log_errors(LOG_WARN, "encrypting to an RSA key");
457  return -1;
458  }
459 
460  return (int)result_len;
461 }
462 
463 /** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
464  * in <b>env</b>, using the padding method <b>padding</b>. On success,
465  * write the result to <b>to</b>, and return the number of bytes
466  * written. On failure, return -1.
467  *
468  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
469  * at least the length of the modulus of <b>key</b>.
470  */
471 int
473  size_t tolen,
474  const char *from, size_t fromlen,
475  int padding, int warnOnFailure)
476 {
477  tor_assert(key);
478  tor_assert(to);
479  tor_assert(from);
480  tor_assert(tolen < INT_MAX);
481  tor_assert(fromlen < INT_MAX);
482 
483  if (!crypto_pk_key_is_private(key))
484  return -1; /* Not a private key. */
485 
486  unsigned int result_len = 0;
487  SECItem *item = NULL;
488  CK_MECHANISM_TYPE m = padding_to_mechanism(padding, &item);
489  SECStatus s = PK11_PrivDecrypt(key->seckey, m, item,
490  (unsigned char *)to, &result_len,
491  (unsigned int)tolen,
492  (const unsigned char *)from,
493  (unsigned int)fromlen);
494 
495  if (s != SECSuccess) {
496  const int severity = warnOnFailure ? LOG_WARN : LOG_INFO;
497  crypto_nss_log_errors(severity, "decrypting with an RSA key");
498  return -1;
499  }
500 
501  return (int)result_len;
502 }
503 
504 /** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
505  * public key in <b>key</b>, using PKCS1 padding. On success, write the
506  * signed data to <b>to</b>, and return the number of bytes written.
507  * On failure, return -1.
508  *
509  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
510  * at least the length of the modulus of <b>key</b>.
511  */
512 MOCK_IMPL(int,
513 crypto_pk_public_checksig,(const crypto_pk_t *key, char *to,
514  size_t tolen,
515  const char *from, size_t fromlen))
516 {
517  tor_assert(key);
518  tor_assert(to);
519  tor_assert(from);
520  tor_assert(tolen < INT_MAX);
521  tor_assert(fromlen < INT_MAX);
522  tor_assert(key->pubkey);
523 
524  SECItem sig = {
525  .type = siBuffer,
526  .data = (unsigned char *) from,
527  .len = (unsigned int) fromlen,
528  };
529  SECItem dsig = {
530  .type = siBuffer,
531  .data = (unsigned char *) to,
532  .len = (unsigned int) tolen
533  };
534  SECStatus s;
535  s = PK11_VerifyRecover(key->pubkey, &sig, &dsig, NULL);
536  if (s != SECSuccess)
537  return -1;
538 
539  return (int)dsig.len;
540 }
541 
542 /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
543  * <b>env</b>, using PKCS1 padding. On success, write the signature to
544  * <b>to</b>, and return the number of bytes written. On failure, return
545  * -1.
546  *
547  * <b>tolen</b> is the number of writable bytes in <b>to</b>, and must be
548  * at least the length of the modulus of <b>env</b>.
549  */
550 int
551 crypto_pk_private_sign(const crypto_pk_t *key, char *to, size_t tolen,
552  const char *from, size_t fromlen)
553 {
554  tor_assert(key);
555  tor_assert(to);
556  tor_assert(from);
557  tor_assert(tolen < INT_MAX);
558  tor_assert(fromlen < INT_MAX);
559 
560  if (BUG(!crypto_pk_key_is_private(key)))
561  return -1;
562 
563  SECItem sig = {
564  .type = siBuffer,
565  .data = (unsigned char *)to,
566  .len = (unsigned int) tolen
567  };
568  SECItem hash = {
569  .type = siBuffer,
570  .data = (unsigned char *)from,
571  .len = (unsigned int) fromlen
572  };
573  CK_MECHANISM_TYPE m = CKM_RSA_PKCS;
574  SECStatus s = PK11_SignWithMechanism(key->seckey, m, NULL,
575  &sig, &hash);
576 
577  if (s != SECSuccess) {
578  crypto_nss_log_errors(LOG_WARN, "signing with an RSA key");
579  return -1;
580  }
581 
582  return (int)sig.len;
583 }
584 
585 /* "This has lead to people trading hard-to-find object identifiers and ASN.1
586  * definitions like baseball cards" - Peter Gutmann, "X.509 Style Guide". */
587 static const unsigned char RSA_OID[] = {
588  /* RSADSI */ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
589  /* PKCS1 */ 0x01, 0x01,
590  /* RSA */ 0x01
591 };
592 
593 /** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
594  * Return -1 on error, or the number of characters used on success.
595  */
596 int
597 crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
598 {
599  tor_assert(pk);
600  if (pk->pubkey == NULL)
601  return -1;
602 
603  CERTSubjectPublicKeyInfo *info;
604  info = SECKEY_CreateSubjectPublicKeyInfo(pk->pubkey);
605  if (! info)
606  return -1;
607 
608  const SECItem *item = &info->subjectPublicKey;
609  size_t actual_len = (item->len) >> 3; /* bits to bytes */
610  size_t n_used = MIN(actual_len, dest_len);
611  memcpy(dest, item->data, n_used);
612 
613  SECKEY_DestroySubjectPublicKeyInfo(info);
614  return (int) n_used;
615 }
616 
617 /** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
618  * success and NULL on failure.
619  */
620 crypto_pk_t *
621 crypto_pk_asn1_decode(const char *str, size_t len)
622 {
623  tor_assert(str);
624  if (len >= INT_MAX)
625  return NULL;
626  CERTSubjectPublicKeyInfo info = {
627  .algorithm = {
628  .algorithm = {
629  .type = siDEROID,
630  .data = (unsigned char *)RSA_OID,
631  .len = sizeof(RSA_OID)
632  }
633  },
634  .subjectPublicKey = {
635  .type = siBuffer,
636  .data = (unsigned char *)str,
637  .len = (unsigned int)(len << 3) /* bytes to bits */
638  }
639  };
640 
641  SECKEYPublicKey *pub = SECKEY_ExtractPublicKey(&info);
642  if (pub == NULL)
643  return NULL;
644 
645  crypto_pk_t *result = crypto_pk_new();
646  result->pubkey = pub;
647  return result;
648 }
649 
650 DISABLE_GCC_WARNING("-Wunused-parameter")
651 
652 /** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the Base64
653  * encoding of the DER representation of the private key into the
654  * <b>dest_len</b>-byte buffer in <b>dest</b>.
655  * Return the number of bytes written on success, -1 on failure.
656  */
657 int
659  char *dest, size_t destlen)
660 {
661  tor_assert(destlen <= INT_MAX);
662  if (!crypto_pk_key_is_private(pk))
663  return -1;
664 
665  SECKEYPrivateKeyInfo *info = PK11_ExportPrivKeyInfo(pk->seckey, NULL);
666  if (!info)
667  return -1;
668  SECItem *item = &info->privateKey;
669 
670  if (destlen < item->len) {
671  SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
672  return -1;
673  }
674  int result = (int)item->len;
675  memcpy(dest, item->data, item->len);
676  SECKEY_DestroyPrivateKeyInfo(info, PR_TRUE);
677 
678  return result;
679 }
680 
681 /** Given a buffer containing the DER representation of the
682  * private key <b>str</b>, decode and return the result on success, or NULL
683  * on failure.
684  *
685  * If <b>max_bits</b> is nonnegative, reject any key longer than max_bits
686  * without performing any expensive validation on it.
687  */
688 crypto_pk_t *
689 crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
690 {
691  tor_assert(str);
692  tor_assert(len < INT_MAX);
693  PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
694  if (!slot)
695  return NULL;
696 
697  SECKEYPrivateKeyInfo info = {
698  .algorithm = {
699  .algorithm = {
700  .type = siBuffer,
701  .data = (unsigned char *)RSA_OID,
702  .len = sizeof(RSA_OID)
703  }
704  },
705  .privateKey = {
706  .type = siBuffer,
707  .data = (unsigned char *)str,
708  .len = (int)len,
709  }
710  };
711 
712  SECStatus s;
713  SECKEYPrivateKey *seckey = NULL;
714 
715  s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
716  NULL /* nickname */,
717  NULL /* publicValue */,
718  PR_FALSE /* isPerm */,
719  PR_FALSE /* isPrivate */,
720  KU_ALL /* keyUsage */,
721  &seckey, NULL);
722 
723  crypto_pk_t *output = NULL;
724 
725  if (s == SECSuccess && seckey) {
726  output = crypto_pk_new();
727  output->seckey = seckey;
728  output->pubkey = SECKEY_ConvertToPublicKey(seckey);
729  tor_assert(output->pubkey);
730  } else {
731  crypto_nss_log_errors(LOG_WARN, "decoding an RSA private key");
732  }
733 
734  if (! crypto_pk_is_valid_private_key(output)) {
735  crypto_pk_free(output);
736  output = NULL;
737  }
738 
739  if (output) {
740  const int bits = SECKEY_PublicKeyStrengthInBits(output->pubkey);
741  if (max_bits >= 0 && bits > max_bits) {
742  log_info(LD_CRYPTO, "Private key longer than expected.");
743  crypto_pk_free(output);
744  output = NULL;
745  }
746  }
747 
748  if (slot)
749  PK11_FreeSlot(slot);
750 
751  return output;
752 }
Header for binascii.c.
Macro definitions for MIN, MAX, and CLAMP.
Headers for crypto_nss_mgt.c.
Headers for crypto_rsa.c.
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
#define TOR_RSA_EXPONENT
Definition: crypto_rsa.h:37
void crypto_pk_assign_private(crypto_pk_t *dest, const crypto_pk_t *src)
crypto_pk_t * crypto_pk_asn1_decode_private(const char *str, size_t len, int max_bits)
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
int crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
size_t crypto_pk_keysize(const crypto_pk_t *env)
crypto_pk_t * crypto_pk_new(void)
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
crypto_pk_t * crypto_pk_asn1_decode(const char *str, size_t len)
int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
#define PK_PKCS1_OAEP_PADDING
Definition: crypto_rsa.h:27
int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding)
void crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
int crypto_pk_num_bits(crypto_pk_t *env)
int crypto_pk_key_is_private(const crypto_pk_t *key)
int crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, size_t dest_len)
crypto_pk_t * crypto_pk_copy_full(crypto_pk_t *orig)
int crypto_pk_public_checksig(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_public_exponent_ok(const crypto_pk_t *env)
void crypto_pk_free_(crypto_pk_t *env)
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
int tor_memcmp(const void *a, const void *b, size_t len)
Definition: di_ops.c:31
Headers for di_ops.c.
#define fast_memcmp(a, b, c)
Definition: di_ops.h:28
Wrappers for reading and writing data to files on disk.
Headers for log.c.
#define LD_CRYPTO
Definition: log.h:64
#define LOG_WARN
Definition: log.h:53
#define LOG_INFO
Definition: log.h:45
#define tor_free(p)
Definition: malloc.h:56
Header for muldiv.c.
#define STATIC
Definition: testsupport.h:32
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102