tor  0.4.0.1-alpha
crypto_rsa_openssl.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 
12 #include "lib/crypt_ops/compat_openssl.h"
15 #include "lib/ctime/di_ops.h"
16 #include "lib/log/util_bug.h"
17 #include "lib/fs/files.h"
18 
19 DISABLE_GCC_WARNING(redundant-decls)
20 
21 #include <openssl/err.h>
22 #include <openssl/rsa.h>
23 #include <openssl/pem.h>
24 #include <openssl/evp.h>
25 #include <openssl/engine.h>
26 #include <openssl/rand.h>
27 #include <openssl/bn.h>
28 #include <openssl/conf.h>
29 
30 ENABLE_GCC_WARNING(redundant-decls)
31 
32 #include "lib/log/log.h"
33 #include "lib/encoding/binascii.h"
34 
35 #include <string.h>
36 
38 struct crypto_pk_t
39 {
40  int refs;
41  RSA *key;
42 };
43 
46 int
48 {
49 #ifdef OPENSSL_1_1_API
50  if (!k || !k->key)
51  return 0;
52 
53  const BIGNUM *p, *q;
54  RSA_get0_factors(k->key, &p, &q);
55  return p != NULL; /* XXX/yawning: Should we check q? */
56 #else /* !(defined(OPENSSL_1_1_API)) */
57  return k && k->key && k->key->p;
58 #endif /* defined(OPENSSL_1_1_API) */
59 }
60 
64 crypto_new_pk_from_openssl_rsa_(RSA *rsa)
65 {
66  crypto_pk_t *env;
67  tor_assert(rsa);
68  env = tor_malloc(sizeof(crypto_pk_t));
69  env->refs = 1;
70  env->key = rsa;
71  return env;
72 }
73 
76 RSA *
77 crypto_pk_get_openssl_rsa_(crypto_pk_t *env)
78 {
79  return RSAPrivateKey_dup(env->key);
80 }
81 
85 MOCK_IMPL(EVP_PKEY *,
86 crypto_pk_get_openssl_evp_pkey_,(crypto_pk_t *env, int private))
87 {
88  RSA *key = NULL;
89  EVP_PKEY *pkey = NULL;
90  tor_assert(env->key);
91  if (private) {
92  if (!(key = RSAPrivateKey_dup(env->key)))
93  goto error;
94  } else {
95  if (!(key = RSAPublicKey_dup(env->key)))
96  goto error;
97  }
98  if (!(pkey = EVP_PKEY_new()))
99  goto error;
100  if (!(EVP_PKEY_assign_RSA(pkey, key)))
101  goto error;
102  return pkey;
103  error:
104  if (pkey)
105  EVP_PKEY_free(pkey);
106  if (key)
107  RSA_free(key);
108  return NULL;
109 }
110 
114 MOCK_IMPL(crypto_pk_t *,
115 crypto_pk_new,(void))
116 {
117  RSA *rsa;
118 
119  rsa = RSA_new();
120  tor_assert(rsa);
121  return crypto_new_pk_from_openssl_rsa_(rsa);
122 }
123 
127 void
129 {
130  if (!env)
131  return;
132 
133  if (--env->refs > 0)
134  return;
135  tor_assert(env->refs == 0);
136 
137  if (env->key)
138  RSA_free(env->key);
139 
140  tor_free(env);
141 }
142 
146 MOCK_IMPL(int,
147 crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits))
148 {
149  tor_assert(env);
150 
151  if (env->key) {
152  RSA_free(env->key);
153  env->key = NULL;
154  }
155 
156  {
157  BIGNUM *e = BN_new();
158  RSA *r = NULL;
159  if (!e)
160  goto done;
161  if (! BN_set_word(e, TOR_RSA_EXPONENT))
162  goto done;
163  r = RSA_new();
164  if (!r)
165  goto done;
166  if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
167  goto done;
168 
169  env->key = r;
170  r = NULL;
171  done:
172  if (e)
173  BN_clear_free(e);
174  if (r)
175  RSA_free(r);
176  }
177 
178  if (!env->key) {
179  crypto_openssl_log_errors(LOG_WARN, "generating RSA key");
180  return -1;
181  }
182 
183  return 0;
184 }
185 
188 int
190 {
191  int r;
192  tor_assert(env);
193 
194  r = RSA_check_key(env->key);
195  if (r <= 0) {
196  crypto_openssl_log_errors(LOG_WARN,"checking RSA key");
197  return 0;
198  } else {
199  return 1;
200  }
201 }
202 
206 int
208 {
209  tor_assert(env);
210  tor_assert(env->key);
211 
212  const BIGNUM *e;
213 
214 #ifdef OPENSSL_1_1_API
215  const BIGNUM *n, *d;
216  RSA_get0_key(env->key, &n, &e, &d);
217 #else
218  e = env->key->e;
219 #endif /* defined(OPENSSL_1_1_API) */
220  return BN_is_word(e, TOR_RSA_EXPONENT);
221 }
222 
229 int
230 crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
231 {
232  int result;
233  char a_is_non_null = (a != NULL) && (a->key != NULL);
234  char b_is_non_null = (b != NULL) && (b->key != NULL);
235  char an_argument_is_null = !a_is_non_null | !b_is_non_null;
236 
237  result = tor_memcmp(&a_is_non_null, &b_is_non_null, sizeof(a_is_non_null));
238  if (an_argument_is_null)
239  return result;
240 
241  const BIGNUM *a_n, *a_e;
242  const BIGNUM *b_n, *b_e;
243 
244 #ifdef OPENSSL_1_1_API
245  const BIGNUM *a_d, *b_d;
246  RSA_get0_key(a->key, &a_n, &a_e, &a_d);
247  RSA_get0_key(b->key, &b_n, &b_e, &b_d);
248 #else
249  a_n = a->key->n;
250  a_e = a->key->e;
251  b_n = b->key->n;
252  b_e = b->key->e;
253 #endif /* defined(OPENSSL_1_1_API) */
254 
255  tor_assert(a_n != NULL && a_e != NULL);
256  tor_assert(b_n != NULL && b_e != NULL);
257 
258  result = BN_cmp(a_n, b_n);
259  if (result)
260  return result;
261  return BN_cmp(a_e, b_e);
262 }
263 
265 size_t
266 crypto_pk_keysize(const crypto_pk_t *env)
267 {
268  tor_assert(env);
269  tor_assert(env->key);
270 
271  return (size_t) RSA_size((RSA*)env->key);
272 }
273 
275 int
277 {
278  tor_assert(env);
279  tor_assert(env->key);
280 
281 #ifdef OPENSSL_1_1_API
282  /* It's so stupid that there's no other way to check that n is valid
283  * before calling RSA_bits().
284  */
285  const BIGNUM *n, *e, *d;
286  RSA_get0_key(env->key, &n, &e, &d);
287  tor_assert(n != NULL);
288 
289  return RSA_bits(env->key);
290 #else /* !(defined(OPENSSL_1_1_API)) */
291  tor_assert(env->key->n);
292  return BN_num_bits(env->key->n);
293 #endif /* defined(OPENSSL_1_1_API) */
294 }
295 
298 crypto_pk_t *
300 {
301  tor_assert(env);
302  tor_assert(env->key);
303 
304  env->refs++;
305  return env;
306 }
307 
311 void
313 {
314  tor_assert(dest);
315  tor_assert(dest->refs == 1);
316  tor_assert(src);
317  RSA_free(dest->key);
318  dest->key = RSAPrivateKey_dup(src->key);
319 }
320 
324 void
326 {
327  tor_assert(dest);
328  tor_assert(dest->refs == 1);
329  tor_assert(src);
330  RSA_free(dest->key);
331  dest->key = RSAPublicKey_dup(src->key);
332 }
333 
336 crypto_pk_t *
338 {
339  RSA *new_key;
340  int privatekey = 0;
341  tor_assert(env);
342  tor_assert(env->key);
343 
344  if (crypto_pk_key_is_private(env)) {
345  new_key = RSAPrivateKey_dup(env->key);
346  privatekey = 1;
347  } else {
348  new_key = RSAPublicKey_dup(env->key);
349  }
350  if (!new_key) {
351  /* LCOV_EXCL_START
352  *
353  * We can't cause RSA*Key_dup() to fail, so we can't really test this.
354  */
355  log_err(LD_CRYPTO, "Unable to duplicate a %s key: openssl failed.",
356  privatekey?"private":"public");
358  privatekey ? "Duplicating a private key" :
359  "Duplicating a public key");
361  return NULL;
362  /* LCOV_EXCL_STOP */
363  }
364 
365  return crypto_new_pk_from_openssl_rsa_(new_key);
366 }
367 
376 int
377 crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
378  const char *from, size_t fromlen, int padding)
379 {
380  int r;
381  tor_assert(env);
382  tor_assert(from);
383  tor_assert(to);
384  tor_assert(fromlen<INT_MAX);
385  tor_assert(tolen >= crypto_pk_keysize(env));
386 
387  r = RSA_public_encrypt((int)fromlen,
388  (unsigned char*)from, (unsigned char*)to,
389  env->key, crypto_get_rsa_padding(padding));
390  if (r<0) {
391  crypto_openssl_log_errors(LOG_WARN, "performing RSA encryption");
392  return -1;
393  }
394  return r;
395 }
396 
405 int
407  size_t tolen,
408  const char *from, size_t fromlen,
409  int padding, int warnOnFailure)
410 {
411  int r;
412  tor_assert(env);
413  tor_assert(from);
414  tor_assert(to);
415  tor_assert(env->key);
416  tor_assert(fromlen<INT_MAX);
417  tor_assert(tolen >= crypto_pk_keysize(env));
418  if (!crypto_pk_key_is_private(env))
419  /* Not a private key */
420  return -1;
421 
422  r = RSA_private_decrypt((int)fromlen,
423  (unsigned char*)from, (unsigned char*)to,
424  env->key, crypto_get_rsa_padding(padding));
425 
426  if (r<0) {
428  "performing RSA decryption");
429  return -1;
430  }
431  return r;
432 }
433 
442 MOCK_IMPL(int,
443 crypto_pk_public_checksig,(const crypto_pk_t *env, char *to,
444  size_t tolen,
445  const char *from, size_t fromlen))
446 {
447  int r;
448  tor_assert(env);
449  tor_assert(from);
450  tor_assert(to);
451  tor_assert(fromlen < INT_MAX);
452  tor_assert(tolen >= crypto_pk_keysize(env));
453  r = RSA_public_decrypt((int)fromlen,
454  (unsigned char*)from, (unsigned char*)to,
455  env->key, RSA_PKCS1_PADDING);
456 
457  if (r<0) {
458  crypto_openssl_log_errors(LOG_INFO, "checking RSA signature");
459  return -1;
460  }
461  return r;
462 }
463 
472 int
473 crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
474  const char *from, size_t fromlen)
475 {
476  int r;
477  tor_assert(env);
478  tor_assert(from);
479  tor_assert(to);
480  tor_assert(fromlen < INT_MAX);
481  tor_assert(tolen >= crypto_pk_keysize(env));
482  if (!crypto_pk_key_is_private(env))
483  /* Not a private key */
484  return -1;
485 
486  r = RSA_private_encrypt((int)fromlen,
487  (unsigned char*)from, (unsigned char*)to,
488  (RSA*)env->key, RSA_PKCS1_PADDING);
489  if (r<0) {
490  crypto_openssl_log_errors(LOG_WARN, "generating RSA signature");
491  return -1;
492  }
493  return r;
494 }
495 
499 int
500 crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
501 {
502  int len;
503  unsigned char *buf = NULL;
504 
505  len = i2d_RSAPublicKey(pk->key, &buf);
506  if (len < 0 || buf == NULL)
507  return -1;
508 
509  if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
510  OPENSSL_free(buf);
511  return -1;
512  }
513  /* We don't encode directly into 'dest', because that would be illegal
514  * type-punning. (C99 is smarter than me, C99 is smarter than me...)
515  */
516  memcpy(dest,buf,len);
517  OPENSSL_free(buf);
518  return len;
519 }
520 
524 crypto_pk_t *
525 crypto_pk_asn1_decode(const char *str, size_t len)
526 {
527  RSA *rsa;
528  unsigned char *buf;
529  const unsigned char *cp;
530  cp = buf = tor_malloc(len);
531  memcpy(buf,str,len);
532  rsa = d2i_RSAPublicKey(NULL, &cp, len);
533  tor_free(buf);
534  if (!rsa) {
535  crypto_openssl_log_errors(LOG_WARN,"decoding public key");
536  return NULL;
537  }
538  return crypto_new_pk_from_openssl_rsa_(rsa);
539 }
540 
544 int
545 crypto_pk_asn1_encode_private(const crypto_pk_t *pk, char *dest,
546  size_t dest_len)
547 {
548  int len;
549  unsigned char *buf = NULL;
550 
551  len = i2d_RSAPrivateKey(pk->key, &buf);
552  if (len < 0 || buf == NULL)
553  return -1;
554 
555  if ((size_t)len > dest_len || dest_len > SIZE_T_CEILING) {
556  OPENSSL_free(buf);
557  return -1;
558  }
559  /* We don't encode directly into 'dest', because that would be illegal
560  * type-punning. (C99 is smarter than me, C99 is smarter than me...)
561  */
562  memcpy(dest,buf,len);
563  OPENSSL_free(buf);
564  return len;
565 }
566 
570 crypto_pk_t *
571 crypto_pk_asn1_decode_private(const char *str, size_t len)
572 {
573  RSA *rsa;
574  unsigned char *buf;
575  const unsigned char *cp;
576  cp = buf = tor_malloc(len);
577  memcpy(buf,str,len);
578  rsa = d2i_RSAPrivateKey(NULL, &cp, len);
579  tor_free(buf);
580  if (!rsa) {
581  crypto_openssl_log_errors(LOG_WARN,"decoding public key");
582  return NULL;
583  }
584  crypto_pk_t *result = crypto_new_pk_from_openssl_rsa_(rsa);
585  if (! crypto_pk_is_valid_private_key(result)) {
586  crypto_pk_free(result);
587  return NULL;
588  }
589  return result;
590 }
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.
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b)
#define LOG_INFO
Definition: log.h:41
Headers for crypto_rsa.c.
void crypto_openssl_log_errors(int severity, const char *doing)
void crypto_pk_free_(crypto_pk_t *env)
#define tor_free(p)
Definition: malloc.h:52
#define tor_fragile_assert()
Definition: util_bug.h:221
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 SIZE_T_CEILING
Definition: torint.h:126
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:49
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)
#define LOG_ERR
Definition: log.h:52
int crypto_pk_public_exponent_ok(const crypto_pk_t *env)
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)
Wrappers for reading and writing data to files on disk.
#define LOG_DEBUG
Definition: log.h:38
crypto_pk_t * crypto_pk_copy_full(crypto_pk_t *orig)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
int crypto_pk_num_bits(crypto_pk_t *env)
#define LD_CRYPTO
Definition: log.h:60
int crypto_pk_asn1_encode(const crypto_pk_t *pk, char *dest, size_t dest_len)
Macros to manage assertions, fatal and non-fatal.