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