crypto.c 69.1 KB
Newer Older
1
/* Copyright (c) 2001, Matej Pfajfar.
Roger Dingledine's avatar
Roger Dingledine committed
2
 * Copyright (c) 2001-2004, Roger Dingledine.
3
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
Karsten Loesing's avatar
Karsten Loesing committed
4
 * Copyright (c) 2007-2009, The Tor Project, Inc. */
5
6
/* See LICENSE for licensing information */

Nick Mathewson's avatar
Nick Mathewson committed
7
8
/**
 * \file crypto.c
9
10
 * \brief Wrapper functions to present a consistent interface to
 * public-key and symmetric cryptography operations from OpenSSL.
Nick Mathewson's avatar
Nick Mathewson committed
11
12
 **/

13
#include "orconfig.h"
14

15
16
17
18
19
20
#ifdef MS_WINDOWS
#define WIN32_WINNT 0x400
#define _WIN32_WINNT 0x400
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wincrypt.h>
Nick Mathewson's avatar
Nick Mathewson committed
21
/* Windows defines this; so does OpenSSL 0.9.8h and later. We don't actually
22
23
 * use either definition. */
#undef OCSP_RESPONSE
24
25
#endif

26
27
28
29
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
30
#include <openssl/engine.h>
31
#include <openssl/rand.h>
32
#include <openssl/opensslv.h>
33
34
#include <openssl/bn.h>
#include <openssl/dh.h>
35
#include <openssl/conf.h>
36
#include <openssl/hmac.h>
37

38
39
40
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
41
42
43
44
45
46
47
48
49
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_FCNTL_H
#include <sys/fcntl.h>
#endif
50

51
#define CRYPTO_PRIVATE
52
#include "crypto.h"
53
#include "../common/log.h"
54
#include "aes.h"
55
#include "../common/util.h"
56
#include "container.h"
57
#include "compat.h"
58

59
#if OPENSSL_VERSION_NUMBER < 0x00907000l
Nick Mathewson's avatar
Nick Mathewson committed
60
#error "We require OpenSSL >= 0.9.7"
61
62
#endif

63
64
#include <openssl/engine.h>

65
66
67
68
69
#ifdef ANDROID
/* Android's OpenSSL seems to have removed all of its Engine support. */
#define DISABLE_ENGINES
#endif

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#if OPENSSL_VERSION_NUMBER < 0x00908000l
/* On OpenSSL versions before 0.9.8, there is no working SHA256
 * implementation, so we use Tom St Denis's nice speedy one, slightly adapted
 * to our needs */
#define SHA256_CTX sha256_state
#define SHA256_Init sha256_init
#define SHA256_Update sha256_process
#define LTC_ARGCHK(x) tor_assert(x)
#include "sha256.c"
#define SHA256_Final(a,b) sha256_done(b,a)

static unsigned char *
SHA256(const unsigned char *m, size_t len, unsigned char *d)
{
  SHA256_CTX ctx;
  SHA256_Init(&ctx);
  SHA256_Update(&ctx, m, len);
  SHA256_Final(d, &ctx);
  return d;
}
#endif

Nick Mathewson's avatar
Nick Mathewson committed
92
/** Macro: is k a valid RSA public or private key? */
93
#define PUBLIC_KEY_OK(k) ((k) && (k)->key && (k)->key->n)
Nick Mathewson's avatar
Nick Mathewson committed
94
/** Macro: is k a valid RSA private key? */
95
96
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)

97
#ifdef TOR_IS_MULTITHREADED
Nick Mathewson's avatar
Nick Mathewson committed
98
/** A number of preallocated mutexes for use by OpenSSL. */
99
static tor_mutex_t **_openssl_mutexes = NULL;
Nick Mathewson's avatar
Nick Mathewson committed
100
/** How many mutexes have we allocated for use by OpenSSL? */
101
static int _n_openssl_mutexes = 0;
102
103
#endif

Nick Mathewson's avatar
Nick Mathewson committed
104
/** A public key, or a public/private key-pair. */
105
106
struct crypto_pk_env_t
{
107
  int refs; /* reference counting so we don't have to copy keys */
108
  RSA *key;
109
110
};

111
/** Key and stream information for a stream cipher. */
112
113
struct crypto_cipher_env_t
{
114
  char key[CIPHER_KEY_LEN];
115
  aes_cnt_cipher_t *cipher;
116
117
};

118
119
/** A structure to hold the first half (x, g^x) of a Diffie-Hellman handshake
 * while we're waiting for the second.*/
120
121
122
struct crypto_dh_env_t {
  DH *dh;
};
Nick Mathewson's avatar
Nick Mathewson committed
123

124
static int setup_openssl_threading(void);
125
static int tor_check_dh_key(int severity, BIGNUM *bn);
126

Nick Mathewson's avatar
Nick Mathewson committed
127
/** Return the number of bytes added by padding method <b>padding</b>.
128
 */
129
static INLINE int
130
131
crypto_get_rsa_padding_overhead(int padding)
{
132
  switch (padding)
133
    {
134
135
136
    case RSA_NO_PADDING: return 0;
    case RSA_PKCS1_OAEP_PADDING: return 42;
    case RSA_PKCS1_PADDING: return 11;
137
    default: tor_assert(0); return -1;
138
139
140
    }
}

Nick Mathewson's avatar
Nick Mathewson committed
141
/** Given a padding method <b>padding</b>, return the correct OpenSSL constant.
142
 */
143
static INLINE int
144
145
crypto_get_rsa_padding(int padding)
{
146
  switch (padding)
147
    {
148
149
150
    case PK_NO_PADDING: return RSA_NO_PADDING;
    case PK_PKCS1_PADDING: return RSA_PKCS1_PADDING;
    case PK_PKCS1_OAEP_PADDING: return RSA_PKCS1_OAEP_PADDING;
151
    default: tor_assert(0); return -1;
152
153
154
    }
}

Nick Mathewson's avatar
Nick Mathewson committed
155
/** Boolean: has OpenSSL's crypto been initialized? */
156
157
static int _crypto_global_initialized = 0;

Nick Mathewson's avatar
Nick Mathewson committed
158
159
/** Log all pending crypto errors at level <b>severity</b>.  Use
 * <b>doing</b> to describe our current activities.
160
 */
161
162
163
static void
crypto_log_errors(int severity, const char *doing)
{
164
  unsigned long err;
165
166
167
168
169
170
  const char *msg, *lib, *func;
  while ((err = ERR_get_error()) != 0) {
    msg = (const char*)ERR_reason_error_string(err);
    lib = (const char*)ERR_lib_error_string(err);
    func = (const char*)ERR_func_error_string(err);
    if (!msg) msg = "(null)";
171
172
    if (!lib) lib = "(null)";
    if (!func) func = "(null)";
173
    if (doing) {
174
175
      log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
          doing, msg, lib, func);
176
    } else {
177
      log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)", msg, lib, func);
178
179
180
    }
  }
}
Nick Mathewson's avatar
Nick Mathewson committed
181

182
#ifndef DISABLE_ENGINES
183
/** Log any OpenSSL engines we're using at NOTICE. */
184
185
186
187
188
189
190
static void
log_engine(const char *fn, ENGINE *e)
{
  if (e) {
    const char *name, *id;
    name = ENGINE_get_name(e);
    id = ENGINE_get_id(e);
191
    log(LOG_NOTICE, LD_CRYPTO, "Using OpenSSL engine %s [%s] for %s",
192
193
        name?name:"?", id?id:"?", fn);
  } else {
194
    log(LOG_INFO, LD_CRYPTO, "Using default implementation for %s", fn);
195
196
  }
}
197
#endif
198

199
#ifndef DISABLE_ENGINES
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/** Try to load an engine in a shared library via fully qualified path.
 */
static ENGINE *
try_load_engine(const char *path, const char *engine)
{
  ENGINE *e = ENGINE_by_id("dynamic");
  if (e) {
    if (!ENGINE_ctrl_cmd_string(e, "ID", engine, 0) ||
        !ENGINE_ctrl_cmd_string(e, "DIR_LOAD", "2", 0) ||
        !ENGINE_ctrl_cmd_string(e, "DIR_ADD", path, 0) ||
        !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
      ENGINE_free(e);
      e = NULL;
    }
  }
  return e;
}
217
#endif
218

219
/** Initialize the crypto library.  Return 0 on success, -1 on failure.
220
 */
221
int
222
crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
223
{
224
  if (!_crypto_global_initialized) {
225
226
227
228
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
    _crypto_global_initialized = 1;
    setup_openssl_threading();
229
    if (useAccel > 0) {
230
231
232
233
234
#ifdef DISABLE_ENGINES
      (void)accelName;
      (void)accelDir;
      log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
#else
235
      ENGINE *e = NULL;
236

237
      log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
238
      ENGINE_load_builtin_engines();
239
      ENGINE_register_all_complete();
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
      if (accelName) {
        if (accelDir) {
          log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\""
                   " via path \"%s\".", accelName, accelDir);
          e = try_load_engine(accelName, accelDir);
        } else {
          log_info(LD_CRYPTO, "Initializing dynamic OpenSSL engine \"%s\""
                   " acceleration support.", accelName);
          e = ENGINE_by_id(accelName);
        }
        if (!e) {
          log_warn(LD_CRYPTO, "Unable to load dynamic OpenSSL engine \"%s\".",
                   accelName);
        } else {
          log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".",
                   accelName);
        }
      }
      if (e) {
        log_info(LD_CRYPTO, "Loaded OpenSSL hardware acceleration engine,"
                 " setting default ciphers.");
        ENGINE_set_default(e, ENGINE_METHOD_ALL);
      }
264
265
266
267
268
269
      log_engine("RSA", ENGINE_get_default_RSA());
      log_engine("DH", ENGINE_get_default_DH());
      log_engine("RAND", ENGINE_get_default_RAND());
      log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
      log_engine("3DES", ENGINE_get_cipher_engine(NID_des_ede3_ecb));
      log_engine("AES", ENGINE_get_cipher_engine(NID_aes_128_ecb));
270
#endif
271
272
    } else {
      log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
273
    }
274
    return crypto_seed_rng(1);
275
  }
276
277
278
  return 0;
}

279
280
281
282
283
284
285
/** Free crypto resources held by this thread. */
void
crypto_thread_cleanup(void)
{
  ERR_remove_state(0);
}

286
/** Uninitialize the crypto library. Return 0 on success, -1 on failure.
287
 */
288
289
int
crypto_global_cleanup(void)
290
{
291
  EVP_cleanup();
292
  ERR_remove_state(0);
293
  ERR_free_strings();
294
295

#ifndef DISABLE_ENGINES
296
  ENGINE_cleanup();
297
298
#endif

299
300
  CONF_modules_unload(1);
  CRYPTO_cleanup_all_ex_data();
301
302
#ifdef TOR_IS_MULTITHREADED
  if (_n_openssl_mutexes) {
303
304
    int n = _n_openssl_mutexes;
    tor_mutex_t **ms = _openssl_mutexes;
305
    int i;
306
    _openssl_mutexes = NULL;
307
    _n_openssl_mutexes = 0;
308
309
310
311
    for (i=0;i<n;++i) {
      tor_mutex_free(ms[i]);
    }
    tor_free(ms);
312
313
  }
#endif
314
315
316
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
317
/** used by tortls.c: wrap an RSA* in a crypto_pk_env_t. */
318
319
crypto_pk_env_t *
_crypto_new_pk_env_rsa(RSA *rsa)
320
321
{
  crypto_pk_env_t *env;
322
  tor_assert(rsa);
323
  env = tor_malloc(sizeof(crypto_pk_env_t));
324
  env->refs = 1;
325
  env->key = rsa;
326
327
328
  return env;
}

329
330
331
332
333
334
335
336
337
338
339
/** used by tortls.c: wrap the RSA from an evp_pkey in a crypto_pk_env_t.
 * returns NULL if this isn't an RSA key. */
crypto_pk_env_t *
_crypto_new_pk_env_evp_pkey(EVP_PKEY *pkey)
{
  RSA *rsa;
  if (!(rsa = EVP_PKEY_get1_RSA(pkey)))
    return NULL;
  return _crypto_new_pk_env_rsa(rsa);
}

340
341
/** Helper, used by tor-checkkey.c and tor-gencert.c.  Return the RSA from a
 * crypto_pk_env_t. */
342
343
344
345
346
347
RSA *
_crypto_pk_env_get_rsa(crypto_pk_env_t *env)
{
  return env->key;
}

Nick Mathewson's avatar
Nick Mathewson committed
348
/** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_env_t.  Iff
349
 * private is set, include the private-key portion of the key. */
350
351
EVP_PKEY *
_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private)
352
353
354
{
  RSA *key = NULL;
  EVP_PKEY *pkey = NULL;
355
  tor_assert(env->key);
356
357
358
359
360
361
362
  if (private) {
    if (!(key = RSAPrivateKey_dup(env->key)))
      goto error;
  } else {
    if (!(key = RSAPublicKey_dup(env->key)))
      goto error;
  }
363
364
365
366
367
368
369
370
371
372
373
374
375
  if (!(pkey = EVP_PKEY_new()))
    goto error;
  if (!(EVP_PKEY_assign_RSA(pkey, key)))
    goto error;
  return pkey;
 error:
  if (pkey)
    EVP_PKEY_free(pkey);
  if (key)
    RSA_free(key);
  return NULL;
}

Nick Mathewson's avatar
Nick Mathewson committed
376
/** Used by tortls.c: Get the DH* from a crypto_dh_env_t.
377
 */
378
379
DH *
_crypto_dh_env_get_dh(crypto_dh_env_t *dh)
380
381
382
383
{
  return dh->dh;
}

Nick Mathewson's avatar
Nick Mathewson committed
384
/** Allocate and return storage for a public key.  The key itself will not yet
385
386
 * be set.
 */
387
388
crypto_pk_env_t *
crypto_new_pk_env(void)
389
390
391
{
  RSA *rsa;

392
393
394
  rsa = RSA_new();
  if (!rsa) return NULL;
  return _crypto_new_pk_env_rsa(rsa);
395
396
}

Nick Mathewson's avatar
Nick Mathewson committed
397
/** Release a reference to an asymmetric key; when all the references
398
 * are released, free the key.
399
 */
400
401
void
crypto_free_pk_env(crypto_pk_env_t *env)
402
{
403
404
  if (!env)
    return;
405

406
  if (--env->refs > 0)
407
    return;
408

409
410
  if (env->key)
    RSA_free(env->key);
411

412
  tor_free(env);
413
414
}

Nick Mathewson's avatar
Nick Mathewson committed
415
/** Create a new symmetric cipher for a given key and encryption flag
416
417
 * (1=encrypt, 0=decrypt).  Return the crypto object on success; NULL
 * on failure.
418
419
 */
crypto_cipher_env_t *
420
crypto_create_init_cipher(const char *key, int encrypt_mode)
421
422
423
424
{
  int r;
  crypto_cipher_env_t *crypto = NULL;

425
  if (! (crypto = crypto_new_cipher_env())) {
426
    log_warn(LD_CRYPTO, "Unable to allocate crypto object");
427
428
429
430
    return NULL;
  }

  if (crypto_cipher_set_key(crypto, key)) {
431
    crypto_log_errors(LOG_WARN, "setting symmetric key");
432
433
434
435
436
437
438
439
    goto error;
  }

  if (encrypt_mode)
    r = crypto_cipher_encrypt_init_cipher(crypto);
  else
    r = crypto_cipher_decrypt_init_cipher(crypto);

440
  if (r)
441
442
443
444
445
446
447
448
449
    goto error;
  return crypto;

 error:
  if (crypto)
    crypto_free_cipher_env(crypto);
  return NULL;
}

Nick Mathewson's avatar
Nick Mathewson committed
450
/** Allocate and return a new symmetric cipher.
451
 */
452
453
crypto_cipher_env_t *
crypto_new_cipher_env(void)
454
455
{
  crypto_cipher_env_t *env;
456

457
458
  env = tor_malloc_zero(sizeof(crypto_cipher_env_t));
  env->cipher = aes_new_cipher();
459
  return env;
460
461
}

Nick Mathewson's avatar
Nick Mathewson committed
462
/** Free a symmetric cipher.
463
 */
464
465
void
crypto_free_cipher_env(crypto_cipher_env_t *env)
466
{
467
468
  if (!env)
    return;
469

470
  tor_assert(env->cipher);
471
  aes_free_cipher(env->cipher);
472
  memset(env, 0, sizeof(crypto_cipher_env_t));
473
  tor_free(env);
474
475
476
}

/* public key crypto */
477

478
479
/** Generate a <b>bits</b>-bit new public/private keypair in <b>env</b>.
 * Return 0 on success, -1 on failure.
480
 */
481
int
482
crypto_pk_generate_key_with_bits(crypto_pk_env_t *env, int bits)
483
{
484
  tor_assert(env);
485

486
487
  if (env->key)
    RSA_free(env->key);
488
#if OPENSSL_VERSION_NUMBER < 0x00908000l
Nick Mathewson's avatar
Nick Mathewson committed
489
  /* In OpenSSL 0.9.7, RSA_generate_key is all we have. */
490
  env->key = RSA_generate_key(bits, 65537, NULL, NULL);
491
#else
Nick Mathewson's avatar
Nick Mathewson committed
492
  /* In OpenSSL 0.9.8, RSA_generate_key is deprecated. */
493
494
495
496
497
498
499
500
501
502
  {
    BIGNUM *e = BN_new();
    RSA *r = NULL;
    if (!e)
      goto done;
    if (! BN_set_word(e, 65537))
      goto done;
    r = RSA_new();
    if (!r)
      goto done;
503
    if (RSA_generate_key_ex(r, bits, e, NULL) == -1)
504
505
506
507
508
509
510
511
512
513
514
      goto done;

    env->key = r;
    r = NULL;
  done:
    if (e)
      BN_free(e);
    if (r)
      RSA_free(r);
    }
#endif
515
516
  if (!env->key) {
    crypto_log_errors(LOG_WARN, "generating RSA key");
517
    return -1;
518
  }
519

520
521
522
  return 0;
}

523
/** Read a PEM-encoded private key from the string <b>s</b> into <b>env</b>.
524
 * Return 0 on success, -1 on failure.
525
 */
526
527
/* Used here, and used for testing. */
int
528
529
crypto_pk_read_private_key_from_string(crypto_pk_env_t *env,
                                       const char *s)
530
{
531
532
  BIO *b;

533
534
  tor_assert(env);
  tor_assert(s);
535

Nick Mathewson's avatar
Nick Mathewson committed
536
  /* Create a read-only memory BIO, backed by the NUL-terminated string 's' */
537
  b = BIO_new_mem_buf((char*)s, -1);
538

539
540
  if (env->key)
    RSA_free(env->key);
541
542
543
544
545

  env->key = PEM_read_bio_RSAPrivateKey(b,NULL,NULL,NULL);

  BIO_free(b);

546
  if (!env->key) {
547
    crypto_log_errors(LOG_WARN, "Error parsing private key");
548
    return -1;
549
  }
550
551
  return 0;
}
552

Nick Mathewson's avatar
Nick Mathewson committed
553
554
/** Read a PEM-encoded private key from the file named by
 * <b>keyfile</b> into <b>env</b>.  Return 0 on success, -1 on failure.
555
 */
556
int
557
558
crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env,
                                         const char *keyfile)
559
{
560
561
  char *contents;
  int r;
562

563
  /* Read the file into a string. */
564
  contents = read_file_to_str(keyfile, 0, NULL);
565
  if (!contents) {
566
    log_warn(LD_CRYPTO, "Error reading private key from \"%s\"", keyfile);
567
568
    return -1;
  }
569

570
571
572
573
574
575
576
  /* Try to parse it. */
  r = crypto_pk_read_private_key_from_string(env, contents);
  tor_free(contents);
  if (r)
    return -1; /* read_private_key_from_string already warned, so we don't.*/

  /* Make sure it's valid. */
577
  if (crypto_pk_check_key(env) <= 0)
578
    return -1;
579

580
581
  return 0;
}
582

583
584
585
586
/** Helper function to implement crypto_pk_write_*_key_to_string. */
static int
crypto_pk_write_key_to_string_impl(crypto_pk_env_t *env, char **dest,
                                   size_t *len, int is_public)
587
{
588
  BUF_MEM *buf;
589
  BIO *b;
590
  int r;
591

592
593
594
  tor_assert(env);
  tor_assert(env->key);
  tor_assert(dest);
595

596
  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
597

598
599
600
  /* Now you can treat b as if it were a file.  Just use the
   * PEM_*_bio_* functions instead of the non-bio variants.
   */
601
602
603
604
605
606
607
  if (is_public)
    r = PEM_write_bio_RSAPublicKey(b, env->key);
  else
    r = PEM_write_bio_RSAPrivateKey(b, env->key, NULL,NULL,0,NULL,NULL);

  if (!r) {
    crypto_log_errors(LOG_WARN, "writing RSA key to string");
608
    BIO_free(b);
609
    return -1;
610
  }
611

612
  BIO_get_mem_ptr(b, &buf);
613
  (void)BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
614
  BIO_free(b);
615

Roger Dingledine's avatar
Roger Dingledine committed
616
  tor_assert(buf->length >= 0);
617
618
  *dest = tor_malloc(buf->length+1);
  memcpy(*dest, buf->data, buf->length);
619
  (*dest)[buf->length] = 0; /* nul terminate it */
620
621
  *len = buf->length;
  BUF_MEM_free(buf);
622

623
624
625
  return 0;
}

626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
/** PEM-encode the public key portion of <b>env</b> and write it to a
 * newly allocated string.  On success, set *<b>dest</b> to the new
 * string, *<b>len</b> to the string's length, and return 0.  On
 * failure, return -1.
 */
int
crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest,
                                     size_t *len)
{
  return crypto_pk_write_key_to_string_impl(env, dest, len, 1);
}

/** PEM-encode the private key portion of <b>env</b> and write it to a
 * newly allocated string.  On success, set *<b>dest</b> to the new
 * string, *<b>len</b> to the string's length, and return 0.  On
 * failure, return -1.
 */
int
crypto_pk_write_private_key_to_string(crypto_pk_env_t *env, char **dest,
                                     size_t *len)
{
  return crypto_pk_write_key_to_string_impl(env, dest, len, 0);
}

Nick Mathewson's avatar
Nick Mathewson committed
650
651
/** Read a PEM-encoded public key from the first <b>len</b> characters of
 * <b>src</b>, and store the result in <b>env</b>.  Return 0 on success, -1 on
652
653
 * failure.
 */
654
int
655
656
crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src,
                                      size_t len)
657
{
658
  BIO *b;
659

660
661
  tor_assert(env);
  tor_assert(src);
662
  tor_assert(len<INT_MAX);
663

664
  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
665

666
  BIO_write(b, src, (int)len);
667

668
669
670
  if (env->key)
    RSA_free(env->key);
  env->key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
671
  BIO_free(b);
672
  if (!env->key) {
673
    crypto_log_errors(LOG_WARN, "reading public key from string");
674
    return -1;
675
  }
676

677
678
679
  return 0;
}

680
/** Write the private key from <b>env</b> into the file named by <b>fname</b>,
681
682
 * PEM-encoded.  Return 0 on success, -1 on failure.
 */
683
684
int
crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env,
685
686
687
688
689
                                        const char *fname)
{
  BIO *bio;
  char *cp;
  long len;
690
  char *s;
691
  int r;
692

693
  tor_assert(PRIVATE_KEY_OK(env));
694

695
696
  if (!(bio = BIO_new(BIO_s_mem())))
    return -1;
697
  if (PEM_write_bio_RSAPrivateKey(bio, env->key, NULL,NULL,0,NULL,NULL)
698
      == 0) {
699
    crypto_log_errors(LOG_WARN, "writing private key");
700
701
702
703
    BIO_free(bio);
    return -1;
  }
  len = BIO_get_mem_data(bio, &cp);
Roger Dingledine's avatar
Roger Dingledine committed
704
  tor_assert(len >= 0);
705
  s = tor_malloc(len+1);
706
707
  memcpy(s, cp, len);
  s[len]='\0';
708
  r = write_str_to_file(fname, s, 0);
709
  BIO_free(bio);
710
  tor_free(s);
711
712
713
  return r;
}

Nick Mathewson's avatar
Nick Mathewson committed
714
/** Return true iff <b>env</b> has a valid key.
715
 */
716
717
int
crypto_pk_check_key(crypto_pk_env_t *env)
718
{
719
  int r;
720
  tor_assert(env);
721

722
723
724
725
  r = RSA_check_key(env->key);
  if (r <= 0)
    crypto_log_errors(LOG_WARN,"checking RSA key");
  return r;
726
727
}

728
729
730
731
732
733
734
735
736
/** Return true iff <b>key</b> contains the private-key portion of the RSA
 * key. */
int
crypto_pk_key_is_private(const crypto_pk_env_t *key)
{
  tor_assert(key);
  return PRIVATE_KEY_OK(key);
}

Nick Mathewson's avatar
Nick Mathewson committed
737
738
/** Compare the public-key components of a and b.  Return -1 if a\<b, 0
 * if a==b, and 1 if a\>b.
739
 */
740
741
742
int
crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b)
{
743
744
  int result;

745
746
  if (!a || !b)
    return -1;
747

748
749
  if (!a->key || !b->key)
    return -1;
750

751
752
  tor_assert(PUBLIC_KEY_OK(a));
  tor_assert(PUBLIC_KEY_OK(b));
753
754
755
756
  result = BN_cmp((a->key)->n, (b->key)->n);
  if (result)
    return result;
  return BN_cmp((a->key)->e, (b->key)->e);
757
758
}

Nick Mathewson's avatar
Nick Mathewson committed
759
/** Return the size of the public key modulus in <b>env</b>, in bytes. */
760
761
size_t
crypto_pk_keysize(crypto_pk_env_t *env)
762
{
763
764
  tor_assert(env);
  tor_assert(env->key);
765

766
  return (size_t) RSA_size(env->key);
767
}
768

769
/** Increase the reference count of <b>env</b>, and return it.
770
 */
771
772
773
crypto_pk_env_t *
crypto_pk_dup_key(crypto_pk_env_t *env)
{
774
775
  tor_assert(env);
  tor_assert(env->key);
776

777
  env->refs++;
778
779
780
  return env;
}

781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
/** Make a real honest-to-goodness copy of <b>env</b>, and return it. */
crypto_pk_env_t *
crypto_pk_copy_full(crypto_pk_env_t *env)
{
  RSA *new_key;
  tor_assert(env);
  tor_assert(env->key);

  if (PRIVATE_KEY_OK(env)) {
    new_key = RSAPrivateKey_dup(env->key);
  } else {
    new_key = RSAPublicKey_dup(env->key);
  }

  return _crypto_new_pk_env_rsa(new_key);
}

Nick Mathewson's avatar
Nick Mathewson committed
798
799
800
801
/** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
 * in <b>env</b>, using the padding method <b>padding</b>.  On success,
 * write the result to <b>to</b>, and return the number of bytes
 * written.  On failure, return -1.
802
 */
803
int
804
805
crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to,
                         const char *from, size_t fromlen, int padding)
806
{
807
  int r;
808
809
810
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
811
  tor_assert(fromlen<INT_MAX);
812

813
814
  r = RSA_public_encrypt((int)fromlen,
                         (unsigned char*)from, (unsigned char*)to,
815
                         env->key, crypto_get_rsa_padding(padding));
816
  if (r<0) {
817
    crypto_log_errors(LOG_WARN, "performing RSA encryption");
818
819
    return -1;
  }
820
  return r;
821
822
}

Nick Mathewson's avatar
Nick Mathewson committed
823
824
825
826
/** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
 * in <b>env</b>, using the padding method <b>padding</b>.  On success,
 * write the result to <b>to</b>, and return the number of bytes
 * written.  On failure, return -1.
827
 */
828
int
829
830
crypto_pk_private_decrypt(crypto_pk_env_t *env, char *to,
                          const char *from, size_t fromlen,
831
                          int padding, int warnOnFailure)
832
{
833
  int r;
834
835
836
837
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
  tor_assert(env->key);
838
  tor_assert(fromlen<INT_MAX);
839
840
841
  if (!env->key->p)
    /* Not a private key */
    return -1;
842

843
844
  r = RSA_private_decrypt((int)fromlen,
                          (unsigned char*)from, (unsigned char*)to,
845
846
                          env->key, crypto_get_rsa_padding(padding));

847
  if (r<0) {
848
    crypto_log_errors(warnOnFailure?LOG_WARN:LOG_DEBUG,
849
                      "performing RSA decryption");
850
851
    return -1;
  }
852
  return r;
853
854
}

Nick Mathewson's avatar
Nick Mathewson committed
855
856
857
/** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
 * public key in <b>env</b>, using PKCS1 padding.  On success, write the
 * signed data to <b>to</b>, and return the number of bytes written.
Roger Dingledine's avatar
Roger Dingledine committed
858
 * On failure, return -1.
859
 */
860
int
861
862
crypto_pk_public_checksig(crypto_pk_env_t *env, char *to,
                          const char *from, size_t fromlen)
863
{
864
  int r;
865
866
867
  tor_assert(env);
  tor_assert(from);
  tor_assert(to);
868
  tor_assert(fromlen < INT_MAX);
869
870
  r = RSA_public_decrypt((int)fromlen,
                         (unsigned char*)from, (unsigned char*)to,
871
                         env->key, RSA_PKCS1_PADDING);
872

Roger Dingledine's avatar
Roger Dingledine committed
873
  if (r<0) {
874
    crypto_log_errors(LOG_WARN, "checking RSA signature");
Roger Dingledine's avatar
Roger Dingledine committed
875
876
    return -1;
  }
877
  return r;
878
879
}

Nick Mathewson's avatar
Nick Mathewson committed
880
881
882
883
/** Check a siglen-byte long signature at <b>sig</b> against
 * <b>datalen</b> bytes of data at <b>data</b>, using the public key
 * in <b>env</b>. Return 0 if <b>sig</b> is a correct signature for
 * SHA1(data).  Else return -1.
884
 */
885
int
886
crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const char *data,
887
                               size_t datalen, const char *sig, size_t siglen)
888
{
889
  char digest[DIGEST_LEN];
890
  char *buf;
891
892
  int r;

893
894
895
  tor_assert(env);
  tor_assert(data);
  tor_assert(sig);
896

897
  if (crypto_digest(digest,data,datalen)<0) {
898
    log_warn(LD_BUG, "couldn't compute digest");
899
900
    return -1;
  }
901
  buf = tor_malloc(crypto_pk_keysize(env)+1);
902
  r = crypto_pk_public_checksig(env,buf,sig,siglen);
903
  if (r != DIGEST_LEN) {
904
    log_warn(LD_CRYPTO, "Invalid signature");
905
    tor_free(buf);
906
907
    return -1;
  }
908
  if (memcmp(buf, digest, DIGEST_LEN)) {
909
    log_warn(LD_CRYPTO, "Signature mismatched with digest.");
910
    tor_free(buf);
911
912
    return -1;
  }
913
  tor_free(buf);
914
915
916
917

  return 0;
}

918
919
920
921
922
923
/** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in
 * <b>env</b>, using PKCS1 padding.  On success, write the signature to
 * <b>to</b>, and return the number of bytes written.  On failure, return
 * -1.
 */
int
924
925
crypto_pk_private_sign(crypto_pk_env_t *env, char *to,
                       const char *from, size_t fromlen)
926
927
928
929
930
{
  int r;
  tor_assert(env);
  tor_assert(from);