tor  0.4.2.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-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
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 
37 {
38  SECKEYPrivateKey *seckey;
39  SECKEYPublicKey *pubkey;
40 };
41 
44 int
46 {
47  return key && key->seckey;
48 }
49 
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 
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 
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 
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 
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 
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 
164 MOCK_IMPL(crypto_pk_t *,
165 crypto_pk_new,(void))
166 {
167  crypto_pk_t *result = tor_malloc_zero(sizeof(crypto_pk_t));
168  return result;
169 }
170 
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 
185 void
187 {
188  if (!key)
189  return;
190 
191  crypto_pk_clear(key);
192 
193  tor_free(key);
194 }
195 
199 MOCK_IMPL(int,
200 crypto_pk_generate_key_with_bits,(crypto_pk_t *key, int bits))
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 
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 
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 
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 
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 
330 size_t
332 {
333  tor_assert(key);
334  tor_assert(key->pubkey);
335  return SECKEY_PublicKeyStrength(key->pubkey);
336 }
337 
339 int
341 {
342  tor_assert(key);
343  tor_assert(key->pubkey);
344  return SECKEY_PublicKeyStrengthInBits(key->pubkey);
345 }
346 
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 
363 void
365 {
366  crypto_pk_clear(dest);
367  if (src->pubkey)
368  dest->pubkey = SECKEY_CopyPublicKey(src->pubkey);
369 }
370 
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 
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 
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 
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 
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 
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 
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 
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 
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(unused-parameter)
649 
650 
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 
683 crypto_pk_t *
684 crypto_pk_asn1_decode_private(const char *str, size_t len)
685 {
686  tor_assert(str);
687  tor_assert(len < INT_MAX);
688  PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS, NULL);
689  if (!slot)
690  return NULL;
691 
692  SECKEYPrivateKeyInfo info = {
693  .algorithm = {
694  .algorithm = {
695  .type = siBuffer,
696  .data = (unsigned char *)RSA_OID,
697  .len = sizeof(RSA_OID)
698  }
699  },
700  .privateKey = {
701  .type = siBuffer,
702  .data = (unsigned char *)str,
703  .len = (int)len,
704  }
705  };
706 
707  SECStatus s;
708  SECKEYPrivateKey *seckey = NULL;
709 
710  s = PK11_ImportPrivateKeyInfoAndReturnKey(slot, &info,
711  NULL /* nickname */,
712  NULL /* publicValue */,
713  PR_FALSE /* isPerm */,
714  PR_FALSE /* isPrivate */,
715  KU_ALL /* keyUsage */,
716  &seckey, NULL);
717 
718  crypto_pk_t *output = NULL;
719 
720  if (s == SECSuccess && seckey) {
721  output = crypto_pk_new();
722  output->seckey = seckey;
723  output->pubkey = SECKEY_ConvertToPublicKey(seckey);
724  tor_assert(output->pubkey);
725  } else {
726  crypto_nss_log_errors(LOG_WARN, "decoding an RSA private key");
727  }
728 
729  if (! crypto_pk_is_valid_private_key(output)) {
730  crypto_pk_free(output);
731  output = NULL;
732  }
733 
734  if (slot)
735  PK11_FreeSlot(slot);
736 
737  return output;
738 }
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
Headers for di_ops.c.
Macro definitions for MIN, MAX, and CLAMP.
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
#define LOG_INFO
Definition: log.h:42
Headers for crypto_rsa.c.
void crypto_pk_free_(crypto_pk_t *env)
#define tor_free(p)
Definition: malloc.h:52
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
crypto_pk_t * crypto_pk_asn1_decode_private(const char *str, size_t len)
Common functions for cryptographic routines.
crypto_pk_t * crypto_pk_asn1_decode(const char *str, size_t len)
void crypto_pk_assign_public(crypto_pk_t *dest, const crypto_pk_t *src)
tor_assert(buffer)
int tor_memcmp(const void *a, const void *b, size_t len)
Definition: di_ops.c:31
int crypto_pk_key_is_private(const crypto_pk_t *key)
#define PK_PKCS1_OAEP_PADDING
Definition: crypto_rsa.h:27
Header for binascii.c.
#define TOR_RSA_EXPONENT
Definition: crypto_rsa.h:37
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_private(crypto_pk_t *dest, const crypto_pk_t *src)
#define LOG_WARN
Definition: log.h:50
int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure)
crypto_pk_t * crypto_pk_dup_key(crypto_pk_t *orig)
int crypto_pk_public_exponent_ok(const crypto_pk_t *env)
Header for muldiv.c.
int crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest, size_t dest_len)
size_t crypto_pk_keysize(const crypto_pk_t *env)
#define fast_memcmp(a, b, c)
Definition: di_ops.h:26
Wrappers for reading and writing data to files on disk.
crypto_pk_t * crypto_pk_copy_full(crypto_pk_t *orig)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
Headers for log.c.
int crypto_pk_num_bits(crypto_pk_t *env)
int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
Macros to manage assertions, fatal and non-fatal.
Headers for crypto_nss_mgt.c.