crypto.c 36.9 KB
Newer Older
1
/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
2
3
4
/* See LICENSE for licensing information */
/* $Id$ */

Nick Mathewson's avatar
Nick Mathewson committed
5
6
7
8
9
10
/**
 * \file crypto.c
 *
 * \brief Low-level cryptographic functions.
 **/

11
#include "orconfig.h"
12

13
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>
#endif

21
22
23
24
25
26
27
#include <string.h>

#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
28
#include <openssl/opensslv.h>
29
30
#include <openssl/bn.h>
#include <openssl/dh.h>
31
32
#include <openssl/rsa.h>
#include <openssl/dh.h>
33
34

#include <stdlib.h>
35
#include <assert.h>
36
#include <stdio.h>
37
#include <limits.h>
38

39
40
41
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
42
43
44
45
46
47
48
49
50
#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
51

52
53
#include "crypto.h"
#include "log.h"
54
#include "aes.h"
55
#include "util.h"
56

57
58
59
60
61
62
#if OPENSSL_VERSION_NUMBER < 0x00905000l
#error "We require openssl >= 0.9.5"
#elif OPENSSL_VERSION_NUMBER < 0x00906000l
#define OPENSSL_095
#endif

63
/* Certain functions that return a success code in OpenSSL 0.9.6 return void
64
65
66
67
68
69
70
71
72
73
 * (and don't indicate errors) in OpenSSL version 0.9.5.
 *
 * [OpenSSL 0.9.5 matters, because it ships with Redhat 6.2.]
 */
#ifdef OPENSSL_095
#define RETURN_SSL_OUTCOME(exp) (exp); return 0
#else
#define RETURN_SSL_OUTCOME(exp) return !(exp)
#endif

Nick Mathewson's avatar
Nick Mathewson committed
74
/** Macro: is k a valid RSA public or private key? */
75
#define PUBLIC_KEY_OK(k) ((k) && (k)->key && (k)->key->n)
Nick Mathewson's avatar
Nick Mathewson committed
76
/** Macro: is k a valid RSA private key? */
77
78
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)

79
80
struct crypto_pk_env_t
{
81
  int refs; /* reference counting so we don't have to copy keys */
82
  RSA *key;
83
84
85
86
};

struct crypto_cipher_env_t
{
87
88
  unsigned char key[CIPHER_KEY_LEN];
  aes_cnt_cipher_t *cipher;
89
90
};

91
92
93
struct crypto_dh_env_t {
  DH *dh;
};
Nick Mathewson's avatar
Nick Mathewson committed
94

Nick Mathewson's avatar
Nick Mathewson committed
95
/** Return the number of bytes added by padding method <b>padding</b>.
96
 */
97
static INLINE int
98
99
crypto_get_rsa_padding_overhead(int padding) {
  switch(padding)
100
    {
101
102
103
    case RSA_NO_PADDING: return 0;
    case RSA_PKCS1_OAEP_PADDING: return 42;
    case RSA_PKCS1_PADDING: return 11;
104
    default: tor_assert(0); return -1;
105
106
107
    }
}

Nick Mathewson's avatar
Nick Mathewson committed
108
/** Given a padding method <b>padding</b>, return the correct OpenSSL constant.
109
 */
110
static INLINE int
111
crypto_get_rsa_padding(int padding) {
112
113
  switch(padding)
    {
114
115
116
    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;
117
    default: tor_assert(0); return -1;
118
119
120
    }
}

Nick Mathewson's avatar
Nick Mathewson committed
121
/** Boolean: has OpenSSL's crypto been initialized? */
122
123
static int _crypto_global_initialized = 0;

Nick Mathewson's avatar
Nick Mathewson committed
124
125
/** Log all pending crypto errors at level <b>severity</b>.  Use
 * <b>doing</b> to describe our current activities.
126
 */
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
static void
crypto_log_errors(int severity, const char *doing)
{
  int err;
  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)";
    if (doing) {
      log(severity, "crypto error while %s: %s (in %s:%s)", doing, msg, lib,func);
    } else {
      log(severity, "crypto error: %s (in %s:%s)", msg, lib, func);
    }
  }
}
Nick Mathewson's avatar
Nick Mathewson committed
144
145

/** Initialize the crypto library.
146
 */
147
int crypto_global_init()
148
{
149
150
151
152
  if (!_crypto_global_initialized) {
      ERR_load_crypto_strings();
      _crypto_global_initialized = 1;
  }
153
154
155
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
156
/** Uninitialize the crypto library.
157
 */
158
159
160
161
162
163
int crypto_global_cleanup()
{
  ERR_free_strings();
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
164
/** used by tortls.c: wrap an RSA* in a crypto_pk_env_t. */
165
crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa)
166
167
{
  crypto_pk_env_t *env;
168
  tor_assert(rsa);
169
  env = tor_malloc(sizeof(crypto_pk_env_t));
170
  env->refs = 1;
171
  env->key = rsa;
172
173
174
  return env;
}

175
/** used by tortls.c: return the RSA* from a crypto_pk_env_t. */
176
177
RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env)
{
178
  return env->key;
179
180
}

Nick Mathewson's avatar
Nick Mathewson committed
181
/** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_env_t.  Iff
182
 * private is set, include the private-key portion of the key. */
183
EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private)
184
185
186
{
  RSA *key = NULL;
  EVP_PKEY *pkey = NULL;
187
  tor_assert(env->key);
188
189
190
191
192
193
194
  if (private) {
    if (!(key = RSAPrivateKey_dup(env->key)))
      goto error;
  } else {
    if (!(key = RSAPublicKey_dup(env->key)))
      goto error;
  }
195
196
197
198
199
200
201
202
203
204
205
206
207
  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
208
/** Used by tortls.c: Get the DH* from a crypto_dh_env_t.
209
 */
210
211
212
213
214
DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh)
{
  return dh->dh;
}

Nick Mathewson's avatar
Nick Mathewson committed
215
/** Allocate and return storage for a public key.  The key itself will not yet
216
217
 * be set.
 */
218
crypto_pk_env_t *crypto_new_pk_env(void)
219
220
221
{
  RSA *rsa;

222
223
224
  rsa = RSA_new();
  if (!rsa) return NULL;
  return _crypto_new_pk_env_rsa(rsa);
225
226
}

Nick Mathewson's avatar
Nick Mathewson committed
227
/** Release a reference to an asymmetric key; when all the references
228
 * are released, free the key.
229
 */
230
231
void crypto_free_pk_env(crypto_pk_env_t *env)
{
232
  tor_assert(env);
233
234
235

  if(--env->refs > 0)
    return;
236

237
238
  if (env->key)
    RSA_free(env->key);
239

240
  free(env);
241
242
}

Nick Mathewson's avatar
Nick Mathewson committed
243
/** Create a new symmetric cipher for a given key and encryption flag
244
245
 * (1=encrypt, 0=decrypt).  Return the crypto object on success; NULL
 * on failure.
246
247
 */
crypto_cipher_env_t *
248
crypto_create_init_cipher(const char *key, int encrypt_mode)
249
250
251
252
{
  int r;
  crypto_cipher_env_t *crypto = NULL;

253
  if (! (crypto = crypto_new_cipher_env())) {
Roger Dingledine's avatar
Roger Dingledine committed
254
    log_fn(LOG_WARN, "Unable to allocate crypto object");
255
256
257
258
    return NULL;
  }

  if (crypto_cipher_set_key(crypto, key)) {
259
    crypto_log_errors(LOG_WARN, "setting symmetric key");
260
261
262
263
264
265
266
267
    goto error;
  }

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

268
  if (r)
269
270
271
272
273
274
275
276
277
    goto error;
  return crypto;

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

Nick Mathewson's avatar
Nick Mathewson committed
278
/** Allocate and return a new symmetric cipher.
279
 */
280
crypto_cipher_env_t *crypto_new_cipher_env()
281
282
{
  crypto_cipher_env_t *env;
283

284
285
  env = tor_malloc_zero(sizeof(crypto_cipher_env_t));
  env->cipher = aes_new_cipher();
286
  return env;
287
288
}

Nick Mathewson's avatar
Nick Mathewson committed
289
/** Free a symmetric cipher.
290
 */
291
292
void crypto_free_cipher_env(crypto_cipher_env_t *env)
{
293
  tor_assert(env);
294

295
  tor_assert(env->cipher);
296
297
  aes_free_cipher(env->cipher);
  tor_free(env);
298
299
300
}

/* public key crypto */
301

Nick Mathewson's avatar
Nick Mathewson committed
302
/** Generate a new public/private keypair in <b>env</b>.  Return 0 on
303
304
 * success, -1 on failure.
 */
305
306
int crypto_pk_generate_key(crypto_pk_env_t *env)
{
307
  tor_assert(env);
308

309
310
  if (env->key)
    RSA_free(env->key);
311
  env->key = RSA_generate_key(PK_BYTES*8,65537, NULL, NULL);
312
313
  if (!env->key) {
    crypto_log_errors(LOG_WARN, "generating RSA key");
314
    return -1;
315
  }
316

317
318
319
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
320
/** Read a PEM-encoded private key from <b>src</b> into <b>env</b>.
321
 */
322
323
static int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env,
                                                FILE *src)
324
{
325
  tor_assert(env && src);
326

327
328
329
  if (env->key)
    RSA_free(env->key);
  env->key = PEM_read_RSAPrivateKey(src, NULL, NULL, NULL);
330
331
  if (!env->key) {
    crypto_log_errors(LOG_WARN, "reading private key from file");
332
    return -1;
333
  }
334

335
336
  return 0;
}
337

Nick Mathewson's avatar
Nick Mathewson committed
338
339
/** 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.
340
 */
341
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile)
342
343
{
  FILE *f_pr;
344

345
  tor_assert(env && keyfile);
346

347
348
349
350
351
352
353
354
355
  if(strspn(keyfile,CONFIG_LEGAL_FILENAME_CHARACTERS) != strlen(keyfile)) {
    /* filename contains nonlegal characters */
    return -1;
  }

  /* open the keyfile */
  f_pr=fopen(keyfile,"rb");
  if (!f_pr)
    return -1;
356

357
358
  /* read the private key */
  if(crypto_pk_read_private_key_from_file(env, f_pr) < 0) {
359
    fclose(f_pr);
360
361
362
    return -1;
  }
  fclose(f_pr);
363

364
  /* check the private key */
365
  if (crypto_pk_check_key(env) <= 0)
366
    return -1;
367

368
369
  return 0;
}
370

Nick Mathewson's avatar
Nick Mathewson committed
371
372
373
374
/** 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.
375
 */
376
377
int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len) {
  BUF_MEM *buf;
378
  BIO *b;
379

380
  tor_assert(env && env->key && dest);
381

382
  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
383

384
385
386
  /* Now you can treat b as if it were a file.  Just use the
   * PEM_*_bio_* functions instead of the non-bio variants.
   */
387
388
  if(!PEM_write_bio_RSAPublicKey(b, env->key)) {
    crypto_log_errors(LOG_WARN, "writing public key to string");
389
    return -1;
390
  }
391

392
393
394
  BIO_get_mem_ptr(b, &buf);
  BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
  BIO_free(b);
395

396
397
398
399
400
  *dest = tor_malloc(buf->length+1);
  memcpy(*dest, buf->data, buf->length);
  (*dest)[buf->length] = 0; /* null terminate it */
  *len = buf->length;
  BUF_MEM_free(buf);
401

402
403
404
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
405
406
/** 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
407
408
 * failure.
 */
409
int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src, int len) {
410
  BIO *b;
411

412
  tor_assert(env && src);
413

414
  b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
415

416
  BIO_write(b, src, len);
417

418
419
420
  if (env->key)
    RSA_free(env->key);
  env->key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
421
  BIO_free(b);
422
423
  if(!env->key) {
    crypto_log_errors(LOG_WARN, "reading public key from string");
424
    return -1;
425
  }
426

427
428
429
  return 0;
}

430
431
432
/* Write the private key from 'env' into the file named by 'fname',
 * PEM-encoded.  Return 0 on success, -1 on failure.
 */
433
434
int
crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env,
435
436
437
438
439
                                        const char *fname)
{
  BIO *bio;
  char *cp;
  long len;
440
  char *s;
441
  int r;
442

443
  tor_assert(PRIVATE_KEY_OK(env));
444

445
446
  if (!(bio = BIO_new(BIO_s_mem())))
    return -1;
447
  if (PEM_write_bio_RSAPrivateKey(bio, env->key, NULL,NULL,0,NULL,NULL)
448
      == 0) {
449
    crypto_log_errors(LOG_WARN, "writing private key");
450
451
452
453
    BIO_free(bio);
    return -1;
  }
  len = BIO_get_mem_data(bio, &cp);
454
455
456
457
  s = tor_malloc(len+1);
  strncpy(s, cp, len);
  s[len] = '\0';
  r = write_str_to_file(fname, s);
458
  BIO_free(bio);
459
  free(s);
460
461
462
  return r;
}

Nick Mathewson's avatar
Nick Mathewson committed
463
/** Return true iff <b>env</b> has a valid key.
464
 */
465
466
int crypto_pk_check_key(crypto_pk_env_t *env)
{
467
  int r;
468
  tor_assert(env);
469

470
471
472
473
  r = RSA_check_key(env->key);
  if (r <= 0)
    crypto_log_errors(LOG_WARN,"checking RSA key");
  return r;
474
475
}

Nick Mathewson's avatar
Nick Mathewson committed
476
477
/** Compare the public-key components of a and b.  Return -1 if a\<b, 0
 * if a==b, and 1 if a\>b.
478
 */
479
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) {
480
481
  int result;

482
483
  if (!a || !b)
    return -1;
484

485
486
  if (!a->key || !b->key)
    return -1;
487

488
489
  tor_assert(PUBLIC_KEY_OK(a));
  tor_assert(PUBLIC_KEY_OK(b));
490
491
492
493
  result = BN_cmp((a->key)->n, (b->key)->n);
  if (result)
    return result;
  return BN_cmp((a->key)->e, (b->key)->e);
494
495
}

Nick Mathewson's avatar
Nick Mathewson committed
496
/** Return the size of the public key modulus in <b>env</b>, in bytes. */
497
498
int crypto_pk_keysize(crypto_pk_env_t *env)
{
499
  tor_assert(env && env->key);
500

501
  return RSA_size(env->key);
502
}
503

Nick Mathewson's avatar
Nick Mathewson committed
504
/** Increase the reference count of <b>env</b>.
505
 */
506
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) {
507
  tor_assert(env && env->key);
508

509
  env->refs++;
510
511
512
  return env;
}

Nick Mathewson's avatar
Nick Mathewson committed
513
514
515
516
/** 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.
517
 */
518
int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding)
519
{
520
  int r;
521
  tor_assert(env && from && to);
522

523
  r = RSA_public_encrypt(fromlen, (unsigned char*)from, to, env->key,
524
                            crypto_get_rsa_padding(padding));
525
  if (r<0) {
526
    crypto_log_errors(LOG_WARN, "performing RSA encryption");
527
528
    return -1;
  }
529
  return r;
530
531
}

Nick Mathewson's avatar
Nick Mathewson committed
532
533
534
535
/** 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.
536
 */
537
int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding)
538
{
539
  int r;
540
  tor_assert(env && from && to && env->key);
541
542
543
  if (!env->key->p)
    /* Not a private key */
    return -1;
544

545
  r = RSA_private_decrypt(fromlen, (unsigned char*)from, to, env->key,
546
                             crypto_get_rsa_padding(padding));
547
  if (r<0) {
548
    crypto_log_errors(LOG_WARN, "performing RSA decryption");
549
550
    return -1;
  }
551
  return r;
552
553
}

Nick Mathewson's avatar
Nick Mathewson committed
554
555
556
/** 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
557
 * On failure, return -1.
558
 */
559
int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to)
560
{
561
  int r;
562
  tor_assert(env && from && to);
563
564
  r = RSA_public_decrypt(fromlen, (unsigned char*)from, to, env->key, RSA_PKCS1_PADDING);

Roger Dingledine's avatar
Roger Dingledine committed
565
  if (r<0) {
566
    crypto_log_errors(LOG_WARN, "checking RSA signature");
Roger Dingledine's avatar
Roger Dingledine committed
567
568
    return -1;
  }
569
  return r;
570
571
}

Nick Mathewson's avatar
Nick Mathewson committed
572
573
574
/** 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
575
576
 * -1.
 */
577
int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to)
578
{
579
  int r;
580
  tor_assert(env && from && to);
581
582
583
  if (!env->key->p)
    /* Not a private key */
    return -1;
584

585
  r = RSA_private_encrypt(fromlen, (unsigned char*)from, to, env->key, RSA_PKCS1_PADDING);
Roger Dingledine's avatar
Roger Dingledine committed
586
  if (r<0) {
587
    crypto_log_errors(LOG_WARN, "generating RSA signature");
Roger Dingledine's avatar
Roger Dingledine committed
588
589
    return -1;
  }
590
  return r;
591
592
}

Nick Mathewson's avatar
Nick Mathewson committed
593
594
595
596
/** 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.
597
 */
598
int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen)
599
{
600
601
  char digest[DIGEST_LEN];
  char buf[PK_BYTES+1];
602
603
  int r;

604
  tor_assert(env && data && sig);
605

606
  if (crypto_digest(data,datalen,digest)<0) {
607
608
609
610
    log_fn(LOG_WARN, "couldn't compute digest");
    return -1;
  }
  r = crypto_pk_public_checksig(env,sig,siglen,buf);
611
  if (r != DIGEST_LEN) {
612
613
614
    log_fn(LOG_WARN, "Invalid signature");
    return -1;
  }
615
  if (memcmp(buf, digest, DIGEST_LEN)) {
616
617
618
619
620
621
622
    log_fn(LOG_WARN, "Signature mismatched with digest.");
    return -1;
  }

  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
623
624
625
626
/** Compute a SHA1 digest of <b>fromlen</b> bytes of data stored at
 * <b>from</b>; sign the data with the private key in <b>env</b>, and
 * store it in <b>to</b>.  Return the number of bytes written on
 * success, and -1 on failure.
627
 */
628
int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to)
629
{
630
631
  char digest[DIGEST_LEN];
  if (crypto_digest(from,fromlen,digest)<0)
632
    return -1;
633
  return crypto_pk_private_sign(env,digest,DIGEST_LEN,to);
634
635
636
}


Nick Mathewson's avatar
Nick Mathewson committed
637
638
639
/** Perform a hybrid (public/secret) encryption on <b>fromlen</b>
 * bytes of data from <b>from</b>, with padding type 'padding',
 * storing the results on <b>to</b>.
640
641
 *
 * If no padding is used, the public key must be at least as large as
Nick Mathewson's avatar
Nick Mathewson committed
642
 * <b>from</b>.
643
644
645
646
 *
 * Returns the number of bytes written on success, -1 on failure.
 *
 * The encrypted data consists of:
Nick Mathewson's avatar
Nick Mathewson committed
647
648
649
650
651
652
 *   - The source data, padded and encrypted with the public key, if the
 *     padded source data is no longer than the public key, and <b>force</b>
 *     is false, OR
 *   - The beginning of the source data prefixed with a 16-byte symmetric key,
 *     padded and encrypted with the public key; followed by the rest of
 *     the source data encrypted in AES-CTR mode with the symmetric key.
653
 */
654
655
656
int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
                                    const unsigned char *from,
                                    int fromlen, unsigned char *to,
657
                                    int padding, int force)
658
659
660
{
  int overhead, pkeylen, outlen, r, symlen;
  crypto_cipher_env_t *cipher = NULL;
661
  char buf[PK_BYTES+1];
662

663
  tor_assert(env && from && to);
664

665
  overhead = crypto_get_rsa_padding_overhead(crypto_get_rsa_padding(padding));
666
667
  pkeylen = crypto_pk_keysize(env);

668
  if (padding == PK_NO_PADDING && fromlen < pkeylen)
669
670
    return -1;

671
  if (!force && fromlen+overhead <= pkeylen) {
672
673
674
    /* It all fits in a single encrypt. */
    return crypto_pk_public_encrypt(env,from,fromlen,to,padding);
  }
675
  cipher = crypto_new_cipher_env();
676
677
678
  if (!cipher) return -1;
  if (crypto_cipher_generate_key(cipher)<0)
    goto err;
679
680
681
682
683
684
  /* You can't just run around RSA-encrypting any bitstream: if it's
   * greater than the RSA key, then OpenSSL will happily encrypt, and
   * later decrypt to the wrong value.  So we set the first bit of
   * 'cipher->key' to 0 if we aren't padding.  This means that our
   * symmetric key is really only 127 bits.
   */
685
  if (padding == PK_NO_PADDING)
686
687
688
    cipher->key[0] &= 0x7f;
  if (crypto_cipher_encrypt_init_cipher(cipher)<0)
    goto err;
689
690
  memcpy(buf, cipher->key, CIPHER_KEY_LEN);
  memcpy(buf+CIPHER_KEY_LEN, from, pkeylen-overhead-CIPHER_KEY_LEN);
691
692

  /* Length of symmetrically encrypted data. */
693
  symlen = fromlen-(pkeylen-overhead-CIPHER_KEY_LEN);
694
695
696
697
698
699

  outlen = crypto_pk_public_encrypt(env,buf,pkeylen-overhead,to,padding);
  if (outlen!=pkeylen) {
    goto err;
  }
  r = crypto_cipher_encrypt(cipher,
700
701
                            from+pkeylen-overhead-CIPHER_KEY_LEN, symlen,
                            to+outlen);
702
703

  if (r<0) goto err;
704
  memset(buf, 0, sizeof(buf));
705
706
707
  crypto_free_cipher_env(cipher);
  return outlen + symlen;
 err:
708
  memset(buf, 0, sizeof(buf));
709
710
711
712
  if (cipher) crypto_free_cipher_env(cipher);
  return -1;
}

Nick Mathewson's avatar
Nick Mathewson committed
713
/** Invert crypto_pk_public_hybrid_encrypt. */
714
715
716
717
int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
                                     const unsigned char *from,
                                     int fromlen, unsigned char *to,
                                     int padding)
718
719
720
{
  int overhead, pkeylen, outlen, r;
  crypto_cipher_env_t *cipher = NULL;
721
  char buf[PK_BYTES+1];
722

723
  overhead = crypto_get_rsa_padding_overhead(crypto_get_rsa_padding(padding));
724
725
726
727
728
729
730
  pkeylen = crypto_pk_keysize(env);

  if (fromlen <= pkeylen) {
    return crypto_pk_private_decrypt(env,from,fromlen,to,padding);
  }
  outlen = crypto_pk_private_decrypt(env,from,pkeylen,buf,padding);
  if (outlen<0) {
731
732
733
    /* this is only log-levelinfo, because when we're decrypting
     * onions, we try several keys to see which will work */
    log_fn(LOG_INFO, "Error decrypting public-key data");
734
735
    return -1;
  }
736
  if (outlen < CIPHER_KEY_LEN) {
737
738
739
    log_fn(LOG_WARN, "No room for a symmetric key");
    return -1;
  }
740
  cipher = crypto_create_init_cipher(buf, 0);
741
742
743
  if (!cipher) {
    return -1;
  }
744
745
  memcpy(to,buf+CIPHER_KEY_LEN,outlen-CIPHER_KEY_LEN);
  outlen -= CIPHER_KEY_LEN;
746
  r = crypto_cipher_decrypt(cipher, from+pkeylen, fromlen-pkeylen,
747
                            to+outlen);
748
749
  if (r<0)
    goto err;
750
  memset(buf,0,sizeof(buf));
751
752
753
  crypto_free_cipher_env(cipher);
  return outlen + (fromlen-pkeylen);
 err:
754
  memset(buf,0,sizeof(buf));
755
756
757
758
  if (cipher) crypto_free_cipher_env(cipher);
  return -1;
}

Nick Mathewson's avatar
Nick Mathewson committed
759
760
/** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
 * Return -1 on error, or the number of characters used on success.
761
 */
762
763
764
int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len)
{
  int len;
765
  unsigned char *buf, *cp;
766
  len = i2d_RSAPublicKey(pk->key, NULL);
767
768
  if (len < 0 || len > dest_len)
    return -1;
769
770
  cp = buf = tor_malloc(len+1);
  len = i2d_RSAPublicKey(pk->key, &cp);
Nick Mathewson's avatar
Nick Mathewson committed
771
  if (len < 0) {
772
    crypto_log_errors(LOG_WARN,"encoding public key");
Nick Mathewson's avatar
Nick Mathewson committed
773
    tor_free(buf);
774
    return -1;
Nick Mathewson's avatar
Nick Mathewson committed
775
776
777
778
779
780
  }
  /* We don't encode directly into 'dest', because that would be illegal
   * type-punning.  (C99 is smarter than me, C99 is smarter than me...)
   */
  memcpy(dest,buf,len);
  tor_free(buf);
781
782
783
  return len;
}

Nick Mathewson's avatar
Nick Mathewson committed
784
/** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
Roger Dingledine's avatar
Roger Dingledine committed
785
 * success and NULL on failure.
786
787
788
789
 */
crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len)
{
  RSA *rsa;
790
  unsigned char *buf;
791
792
793
794
  /* This ifdef suppresses a type warning.  Take out the first case once
   * everybody is using openssl 0.9.7 or later.
   */
#if OPENSSL_VERSION_NUMBER < 0x00907000l
795
  unsigned char *cp;
796
#else
797
  const unsigned char *cp;
798
#endif
799
800
801
  cp = buf = tor_malloc(len);
  memcpy(buf,str,len);
  rsa = d2i_RSAPublicKey(NULL, &cp, len);
Nick Mathewson's avatar
Nick Mathewson committed
802
  tor_free(buf);
803
804
805
806
  if (!rsa) {
    crypto_log_errors(LOG_WARN,"decoding public key");
    return NULL;
  }
807
808
809
  return _crypto_new_pk_env_rsa(rsa);
}

Nick Mathewson's avatar
Nick Mathewson committed
810
811
/** Given a private or public key <b>pk</b>, put a SHA1 hash of the
 * public key into <b>digest_out</b> (must have DIGEST_LEN bytes of space).
812
813
 */
int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out)
814
815
816
{
  unsigned char *buf, *bufp;
  int len;
817
818

  len = i2d_RSAPublicKey(pk->key, NULL);
819
820
821
  if (len < 0)
    return -1;
  buf = bufp = tor_malloc(len+1);
822
  len = i2d_RSAPublicKey(pk->key, &bufp);
823
  if (len < 0) {
824
    crypto_log_errors(LOG_WARN,"encoding public key");
825
826
827
    free(buf);
    return -1;
  }
828
  if (crypto_digest(buf, len, digest_out) < 0) {
829
830
831
    free(buf);
    return -1;
  }
832
  free(buf);
833
834
835
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
836
837
/** Given a private or public key <b>pk</b>, put a fingerprint of the
 * public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1 bytes of
838
 * space).
Nick Mathewson's avatar
Nick Mathewson committed
839
840
841
842
 *
 * Fingerprints are computed as the SHA1 digest of the ASN.1 encoding
 * of the public key, converted to hexadecimal, with a space after every
 * four digits.
843
844
845
846
847
 */
int
crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out)
{
  unsigned char *bufp;
848
  unsigned char digest[DIGEST_LEN];
849
850
851
852
853
  unsigned char buf[FINGERPRINT_LEN+1];
  int i;
  if (crypto_pk_get_digest(pk, digest)) {
    return -1;
  }
854
  bufp = buf;
855
  for (i = 0; i < DIGEST_LEN; ++i) {
856
857
858
859
860
861
862
    sprintf(bufp,"%02X",digest[i]);
    bufp += 2;
    if (i%2 && i != 19) {
      *bufp++ = ' ';
    }
  }
  *bufp = '\0';
863
864
  tor_assert(strlen(buf) == FINGERPRINT_LEN);
  tor_assert(crypto_pk_check_fingerprint_syntax(buf));
865
866
867
868
  strcpy(fp_out, buf);
  return 0;
}

Nick Mathewson's avatar
Nick Mathewson committed
869
/** Return true iff <b>s</b> is in the correct format for a fingerprint.
870
 */
871
int
872
873
874
875
876
crypto_pk_check_fingerprint_syntax(const char *s)
{
  int i;
  for (i = 0; i < FINGERPRINT_LEN; ++i) {
    if ((i%5) == 4) {
877
      if (!isspace((int)s[i])) return 0;
878
    } else {
879
      if (!isxdigit((int)s[i])) return 0;
880
881
882
883
884
885
    }
  }
  if (s[FINGERPRINT_LEN]) return 0;
  return 1;
}

886
/* symmetric crypto */
887

Nick Mathewson's avatar
Nick Mathewson committed
888
/** Generate a new random key for the symmetric cipher in <b>env</b>.
889
890
 * Return 0 on success, -1 on failure.  Does not initialize the cipher.
 */
891
892
int crypto_cipher_generate_key(crypto_cipher_env_t *env)
{
893
  tor_assert(env);
894

895
  return crypto_rand(CIPHER_KEY_LEN, env->key);
896
897
}

Nick Mathewson's avatar
Nick Mathewson committed
898
899
/** Set the symmetric key for the cipher in <b>env</b> to the first
 * CIPHER_KEY_LEN bytes of <b>key</b>. Does not initialize the cipher.
900
 */
901
int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key)
902
{
903
  tor_assert(env && key);
904
905

  if (!env->key)
906
    return -1;
907

908
  memcpy(env->key, key, CIPHER_KEY_LEN);
909

Matej Pjafjar's avatar