tortls.c 40.1 KB
Newer Older
1
2
3
/* Copyright (c) 2003, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 * Copyright (c) 2007, The Tor Project, Inc. */
4
5
/* See LICENSE for licensing information */
/* $Id$ */
6
7
const char tortls_c_id[] =
  "$Id$";
8

Nick Mathewson's avatar
Nick Mathewson committed
9
10
/**
 * \file tortls.c
11
12
 * \brief Wrapper functions to present a consistent interface to
 * TLS, SSL, and X.509 functions from OpenSSL.
Nick Mathewson's avatar
Nick Mathewson committed
13
 **/
14

Nick Mathewson's avatar
Nick Mathewson committed
15
/* (Unlike other tor functions, these
16
17
 * are prefixed with tor_ in order to avoid conflicting with OpenSSL
 * functions and variables.)
Nick Mathewson's avatar
Nick Mathewson committed
18
 */
19

20
#include "orconfig.h"
21
22
23

#include <assert.h>
#include <openssl/ssl.h>
24
#include <openssl/ssl3.h>
25
26
27
28
#include <openssl/err.h>
#include <openssl/tls1.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
29
30
31
32
33
#include <openssl/opensslv.h>

#if OPENSSL_VERSION_NUMBER < 0x00907000l
#error "We require openssl >= 0.9.7"
#endif
34

35
#define CRYPTO_PRIVATE /* to import prototypes from crypto.h */
36

37
38
39
40
41
#include "crypto.h"
#include "tortls.h"
#include "util.h"
#include "log.h"
#include "container.h"
42
#include <string.h>
43

44
// #define V2_HANDSHAKE_SERVER
45
// #define V2_HANDSHAKE_CLIENT
46

47
/* Copied from or.h */
48
49
#define LEGAL_NICKNAME_CHARACTERS \
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
50

Nick Mathewson's avatar
Nick Mathewson committed
51
/** How long do identity certificates live? (sec) */
52
#define IDENTITY_CERT_LIFETIME  (365*24*60*60)
Nick Mathewson's avatar
Nick Mathewson committed
53

54
/** Structure holding the TLS state for a single connection. */
55
typedef struct tor_tls_context_t {
56
  int refcnt;
57
  SSL_CTX *ctx;
58
59
  X509 *my_cert;
  X509 *my_id_cert;
60
  crypto_pk_env_t *key;
61
} tor_tls_context_t;
62

Nick Mathewson's avatar
Nick Mathewson committed
63
/** Holds a SSL object and its associated data.  Members are only
64
 * accessed from within tortls.c.
65
 */
66
struct tor_tls_t {
67
  tor_tls_context_t *context; /**DOCDOC */
68
69
  SSL *ssl; /**< An OpenSSL SSL object. */
  int socket; /**< The underlying file descriptor for this TLS connection. */
70
71
  enum {
    TOR_TLS_ST_HANDSHAKE, TOR_TLS_ST_OPEN, TOR_TLS_ST_GOTCLOSE,
72
    TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED, TOR_TLS_ST_RENEGOTIATE,
73
  } state : 3; /**< The current SSL state, depending on which operations have
74
75
                * completed successfully. */
  unsigned int isServer:1; /**< True iff this is a server-side connection */
76
  unsigned int hadCert:1; /**< Docdoc */
77
  unsigned int wasV2Handshake:1; /**< DOCDOC */
78
79
  size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last
                       * time. */
80
81
  unsigned long last_write_count;
  unsigned long last_read_count;
82
83
  void (*negotiated_callback)(tor_tls_t *tls, void *arg);
  void *callback_arg;
84
85
};

86
87
static void tor_tls_context_decref(tor_tls_context_t *ctx);
static void tor_tls_context_incref(tor_tls_context_t *ctx);
88
static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
89
90
91
92
                                        crypto_pk_env_t *rsa_sign,
                                        const char *cname,
                                        const char *cname_sign,
                                        unsigned int lifetime);
93

Nick Mathewson's avatar
Nick Mathewson committed
94
/** Global tls context. We keep it here because nobody else needs to
95
 * touch it. */
96
static tor_tls_context_t *global_tls_context = NULL;
Nick Mathewson's avatar
Nick Mathewson committed
97
/** True iff tor_tls_init() has been called. */
98
static int tls_library_is_initialized = 0;
99

100
/* Module-internal error codes. */
101
102
#define _TOR_TLS_SYSCALL    (_MIN_TOR_TLS_ERROR_VAL - 2)
#define _TOR_TLS_ZERORETURN (_MIN_TOR_TLS_ERROR_VAL - 1)
103

Nick Mathewson's avatar
Nick Mathewson committed
104
105
/** Log all pending tls errors at level <b>severity</b>.  Use
 * <b>doing</b> to describe our current activities.
106
 */
Nick Mathewson's avatar
Nick Mathewson committed
107
static void
Nick Mathewson's avatar
Nick Mathewson committed
108
tls_log_errors(int severity, const char *doing)
Nick Mathewson's avatar
Nick Mathewson committed
109
{
Nick Mathewson's avatar
Nick Mathewson committed
110
111
112
113
114
115
116
117
  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) {
118
119
      log(severity, LD_NET, "TLS error while %s: %s (in %s:%s)",
          doing, msg, lib,func);
Nick Mathewson's avatar
Nick Mathewson committed
120
    } else {
121
      log(severity, LD_NET, "TLS error: %s (in %s:%s)", msg, lib, func);
Nick Mathewson's avatar
Nick Mathewson committed
122
    }
Nick Mathewson's avatar
Nick Mathewson committed
123
124
  }
}
125

126
127
/** Convert an errno (or a WSAerrno on windows) into a TOR_TLS_* error
 * code. */
128
static int
129
130
tor_errno_to_tls_error(int e)
{
131
#if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
132
  switch (e) {
133
134
135
136
137
138
139
140
141
142
143
144
    case WSAECONNRESET: // most common
      return TOR_TLS_ERROR_CONNRESET;
    case WSAETIMEDOUT:
      return TOR_TLS_ERROR_TIMEOUT;
    case WSAENETUNREACH:
    case WSAEHOSTUNREACH:
      return TOR_TLS_ERROR_NO_ROUTE;
    case WSAECONNREFUSED:
      return TOR_TLS_ERROR_CONNREFUSED; // least common
    default:
      return TOR_TLS_ERROR_MISC;
  }
145
146
#else
  switch (e) {
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
    case ECONNRESET: // most common
      return TOR_TLS_ERROR_CONNRESET;
    case ETIMEDOUT:
      return TOR_TLS_ERROR_TIMEOUT;
    case EHOSTUNREACH:
    case ENETUNREACH:
      return TOR_TLS_ERROR_NO_ROUTE;
    case ECONNREFUSED:
      return TOR_TLS_ERROR_CONNREFUSED; // least common
    default:
      return TOR_TLS_ERROR_MISC;
  }
#endif
}

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/** DOCDOC */
const char *
tor_tls_err_to_string(int err)
{
  if (err >= 0)
    return "[Not an error.]";
  switch (err) {
    case TOR_TLS_ERROR_MISC: return "misc error";
    case TOR_TLS_ERROR_IO: return "unexpected close";
    case TOR_TLS_ERROR_CONNREFUSED: return "connection refused";
    case TOR_TLS_ERROR_CONNRESET: return "connection reset";
    case TOR_TLS_ERROR_NO_ROUTE: return "host unreachable";
    case TOR_TLS_ERROR_TIMEOUT: return "connection timed out";
    case TOR_TLS_CLOSE: return "closed";
    case TOR_TLS_WANTREAD: return "want to read";
    case TOR_TLS_WANTWRITE: return "want to write";
    default: return "(unknown error code)";
  }
}

182
183
184
#define CATCH_SYSCALL 1
#define CATCH_ZERO    2

Nick Mathewson's avatar
Nick Mathewson committed
185
/** Given a TLS object and the result of an SSL_* call, use
186
187
188
189
190
191
 * SSL_get_error to determine whether an error has occurred, and if so
 * which one.  Return one of TOR_TLS_{DONE|WANTREAD|WANTWRITE|ERROR}.
 * If extra&CATCH_SYSCALL is true, return _TOR_TLS_SYSCALL instead of
 * reporting syscall errors.  If extra&CATCH_ZERO is true, return
 * _TOR_TLS_ZERORETURN instead of reporting zero-return errors.
 *
Nick Mathewson's avatar
Nick Mathewson committed
192
193
 * If an error has occurred, log it at level <b>severity</b> and describe the
 * current action as <b>doing</b>.
194
 */
195
static int
196
tor_tls_get_error(tor_tls_t *tls, int r, int extra,
197
                  const char *doing, int severity)
198
199
{
  int err = SSL_get_error(tls->ssl, r);
200
  int tor_error = TOR_TLS_ERROR_MISC;
201
202
203
204
205
206
207
208
  switch (err) {
    case SSL_ERROR_NONE:
      return TOR_TLS_DONE;
    case SSL_ERROR_WANT_READ:
      return TOR_TLS_WANTREAD;
    case SSL_ERROR_WANT_WRITE:
      return TOR_TLS_WANTWRITE;
    case SSL_ERROR_SYSCALL:
209
      if (extra&CATCH_SYSCALL)
210
        return _TOR_TLS_SYSCALL;
211
      if (r == 0) {
212
        log(severity, LD_NET, "TLS error: unexpected close while %s", doing);
213
214
        tor_error = TOR_TLS_ERROR_IO;
      } else {
215
        int e = tor_socket_errno(tls->socket);
216
217
        log(severity, LD_NET,
            "TLS error: <syscall error while %s> (errno=%d: %s)",
218
            doing, e, tor_socket_strerror(e));
219
        tor_error = tor_errno_to_tls_error(e);
220
      }
Nick Mathewson's avatar
Nick Mathewson committed
221
      tls_log_errors(severity, doing);
222
      return tor_error;
223
    case SSL_ERROR_ZERO_RETURN:
224
      if (extra&CATCH_ZERO)
225
        return _TOR_TLS_ZERORETURN;
226
      log(severity, LD_NET, "TLS error: Zero return");
Nick Mathewson's avatar
Nick Mathewson committed
227
      tls_log_errors(severity, doing);
228
      /* XXXX020 Actually, a 'zero return' error has a pretty specific meaning:
229
       * the connection has been closed cleanly.  */
230
      return TOR_TLS_ERROR_MISC;
231
    default:
Nick Mathewson's avatar
Nick Mathewson committed
232
      tls_log_errors(severity, doing);
233
      return TOR_TLS_ERROR_MISC;
234
235
236
  }
}

Nick Mathewson's avatar
Nick Mathewson committed
237
/** Initialize OpenSSL, unless it has already been initialized.
238
 */
239
static void
240
241
tor_tls_init(void)
{
242
243
  if (!tls_library_is_initialized) {
    SSL_library_init();
244
    SSL_load_error_strings();
245
    crypto_global_init(-1);
246
247
248
249
    tls_library_is_initialized = 1;
  }
}

250
/** Free all global TLS structures. */
251
252
253
254
void
tor_tls_free_all(void)
{
  if (global_tls_context) {
255
    tor_tls_context_decref(global_tls_context);
256
257
258
259
    global_tls_context = NULL;
  }
}

Nick Mathewson's avatar
Nick Mathewson committed
260
/** We need to give OpenSSL a callback to verify certificates. This is
261
262
263
 * it: We always accept peer certs and complete the handshake.  We
 * don't validate them until later.
 */
264
265
266
static int
always_accept_verify_cb(int preverify_ok,
                        X509_STORE_CTX *x509_ctx)
267
{
268
269
270
  /* avoid "unused parameter" warning. */
  preverify_ok = 0;
  x509_ctx = NULL;
271
272
273
  return 1;
}

Nick Mathewson's avatar
Nick Mathewson committed
274
275
276
277
/** Generate and sign an X509 certificate with the public key <b>rsa</b>,
 * signed by the private key <b>rsa_sign</b>.  The commonName of the
 * certificate will be <b>cname</b>; the commonName of the issuer will be
 * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
278
279
 * starting from now.  Return a certificate on success, NULL on
 * failure.
280
 */
281
static X509 *
282
tor_tls_create_certificate(crypto_pk_env_t *rsa,
283
284
285
286
                           crypto_pk_env_t *rsa_sign,
                           const char *cname,
                           const char *cname_sign,
                           unsigned int cert_lifetime)
287
288
{
  time_t start_time, end_time;
289
  EVP_PKEY *sign_pkey = NULL, *pkey=NULL;
290
  X509 *x509 = NULL;
291
  X509_NAME *name = NULL, *name_issuer=NULL;
292
  int nid;
293

294
295
  tor_tls_init();

296
297
  start_time = time(NULL);

298
299
300
301
  tor_assert(rsa);
  tor_assert(cname);
  tor_assert(rsa_sign);
  tor_assert(cname_sign);
302
303
304
305
  if (!(sign_pkey = _crypto_pk_env_get_evp_pkey(rsa_sign,1)))
    goto error;
  if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0)))
    goto error;
306
  if (!(x509 = X509_new()))
307
    goto error;
308
  if (!(X509_set_version(x509, 2)))
309
    goto error;
310
  if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)start_time)))
311
    goto error;
312

313
  if (!(name = X509_NAME_new()))
314
    goto error;
315
316
  if ((nid = OBJ_txt2nid("organizationName")) == NID_undef)
    goto error;
317
  if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
318
                                   (unsigned char*)"t o r", -1, -1, 0)))
319
    goto error;
320
  if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
321
  if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
322
323
                                   (unsigned char*)cname, -1, -1, 0)))
    goto error;
324
325
  if (!(X509_set_subject_name(x509, name)))
    goto error;
326

327
  if (!(name_issuer = X509_NAME_new()))
328
    goto error;
329
330
  if ((nid = OBJ_txt2nid("organizationName")) == NID_undef)
    goto error;
331
  if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC,
332
                                   (unsigned char*)"t o r", -1, -1, 0)))
333
    goto error;
334
335
  if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
  if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC,
336
337
                              (unsigned char*)cname_sign, -1, -1, 0)))
    goto error;
338
  if (!(X509_set_issuer_name(x509, name_issuer)))
339
    goto error;
340

341
  if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time))
342
    goto error;
343
  end_time = start_time + cert_lifetime;
344
  if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time))
345
    goto error;
346
  if (!X509_set_pubkey(x509, pkey))
347
    goto error;
348
  if (!X509_sign(x509, sign_pkey, EVP_sha1()))
349
    goto error;
350

351
352
  goto done;
 error:
353
  if (x509) {
354
    X509_free(x509);
355
356
    x509 = NULL;
  }
357
 done:
358
  tls_log_errors(LOG_WARN, "generating certificate");
359
360
  if (sign_pkey)
    EVP_PKEY_free(sign_pkey);
361
362
363
364
  if (pkey)
    EVP_PKEY_free(pkey);
  if (name)
    X509_NAME_free(name);
365
366
  if (name_issuer)
    X509_NAME_free(name_issuer);
367
  return x509;
368
369
}

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
#define SERVER_CIPHER_LIST                      \
  (TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":"        \
   TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":"        \
   SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
/* Note: for setting up your own private testing network with link crypto
 * disabled, set the cipher lists to your cipher list to
 * SSL3_TXT_RSA_NULL_SHA.  If you do this, you won't be able to communicate
 * with any of the "real" Tors, though. */

#if OPENSSL_VERSION_NUMBER >= 0x00908000l
#define CLIENT_CIPHER_LIST                         \
  (TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ":"   \
   TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA ":"     \
   TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":"           \
   TLS1_TXT_DHE_DSS_WITH_AES_256_SHA ":"           \
   TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA ":"      \
   TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA ":"    \
   TLS1_TXT_RSA_WITH_AES_256_SHA ":"               \
   TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA ":"       \
   TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ":"   \
   TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA ":"         \
   TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA ":"     \
   TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":"           \
   TLS1_TXT_DHE_DSS_WITH_AES_128_SHA ":"           \
   TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA":"           \
   TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA":"       \
   TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA  ":"       \
   TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA ":"    \
   SSL3_TXT_RSA_RC4_128_MD5 ":"                    \
   SSL3_TXT_RSA_RC4_128_SHA ":"                    \
   TLS1_TXT_RSA_WITH_AES_128_SHA ":"               \
   TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA ":"  \
   TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA ":"    \
   SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA ":"           \
   SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA ":"           \
   TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA ":"     \
   TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA ":"   \
   SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA ":"     \
   SSL3_TXT_RSA_DES_192_CBC3_SHA)
409
#else
410
411
412
413
414
415
416
417
418
419
420
421
422
/* Ug. We don't have as many ciphers with openssl 0.9.7 as we'd like.  Fix
 * this list into something that sucks less. */
#define CLIENT_CIPHER_LIST \
  (TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":"        \
   TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":"        \
   SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA ":"        \
   SSL3_TXT_RSA_RC4_128_SHA)
#endif

#ifndef V2_HANDSHAKE_CLIENT
#undef CLIENT_CIPHER_LIST
#define CLIENT_CIPHER_LIST  (TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":"      \
                             SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
423
424
#endif

425
426
/** DOCDOC */
static void
427
tor_tls_context_decref(tor_tls_context_t *ctx)
428
{
429
430
431
432
433
  tor_assert(ctx);
  if (--ctx->refcnt == 0) {
    SSL_CTX_free(ctx->ctx);
    X509_free(ctx->my_cert);
    X509_free(ctx->my_id_cert);
434
    crypto_free_pk_env(ctx->key);
435
436
437
438
439
440
441
442
443
    tor_free(ctx);
  }
}

/** DOCDOC */
static void
tor_tls_context_incref(tor_tls_context_t *ctx)
{
  ++ctx->refcnt;
444
445
}

446
447
448
449
/** Create a new TLS context for use with Tor TLS handshakes.
 * <b>identity</b> should be set to the identity key used to sign the
 * certificate, and <b>nickname</b> set to the nickname to use.
 *
450
 * You can call this function multiple times.  Each time you call it,
451
452
 * it generates new certificates; all new connections will use
 * the new SSL context.
453
 */
454
int
455
tor_tls_context_new(crypto_pk_env_t *identity, const char *nickname,
456
                    unsigned int key_lifetime)
457
{
458
  crypto_pk_env_t *rsa = NULL;
459
460
  crypto_dh_env_t *dh = NULL;
  EVP_PKEY *pkey = NULL;
461
  tor_tls_context_t *result = NULL;
462
  X509 *cert = NULL, *idcert = NULL;
Nick Mathewson's avatar
Nick Mathewson committed
463
  char nn2[128];
464
465
  if (!nickname)
    nickname = "null";
466
  tor_snprintf(nn2, sizeof(nn2), "%s <signing>", nickname);
467

468
469
  tor_tls_init();

470
471
472
473
474
475
476
477
478
479
480
481
482
483
  /* Generate short-term RSA key. */
  if (!(rsa = crypto_new_pk_env()))
    goto error;
  if (crypto_pk_generate_key(rsa)<0)
    goto error;
  /* Create certificate signed by identity key. */
  cert = tor_tls_create_certificate(rsa, identity, nickname, nn2,
                                    key_lifetime);
  /* Create self-signed certificate for identity key. */
  idcert = tor_tls_create_certificate(identity, identity, nn2, nn2,
                                      IDENTITY_CERT_LIFETIME);
  if (!cert || !idcert) {
    log(LOG_WARN, LD_CRYPTO, "Error creating certificate");
    goto error;
484
485
  }

486
  result = tor_malloc_zero(sizeof(tor_tls_context_t));
487
  result->refcnt = 1;
488
489
  result->my_cert = X509_dup(cert);
  result->my_id_cert = X509_dup(idcert);
490
  result->key = crypto_pk_dup_key(rsa);
491

492
#ifdef EVERYONE_HAS_AES
493
494
495
  /* Tell OpenSSL to only use TLS1 */
  if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
    goto error;
496
#else
497
498
499
500
  /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
  if (!(result->ctx = SSL_CTX_new(SSLv23_method())))
    goto error;
  SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2);
501
#endif
502
503
504
505
506
  SSL_CTX_set_options(result->ctx, SSL_OP_SINGLE_DH_USE);
  if (cert && !SSL_CTX_use_certificate(result->ctx,cert))
    goto error;
  X509_free(cert); /* We just added a reference to cert. */
  cert=NULL;
507
#if 0
508
509
  if (idcert && !SSL_CTX_add_extra_chain_cert(result->ctx,idcert))
    goto error;
510
511
512
513
514
515
516
#else
  if (idcert) {
    X509_STORE *s = SSL_CTX_get_cert_store(result->ctx);
    tor_assert(s);
    X509_STORE_add_cert(s, idcert);
  }
#endif
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
  idcert=NULL; /* The context now owns the reference to idcert */
  SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
  tor_assert(rsa);
  if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
    goto error;
  if (!SSL_CTX_use_PrivateKey(result->ctx, pkey))
    goto error;
  EVP_PKEY_free(pkey);
  pkey = NULL;
  if (!SSL_CTX_check_private_key(result->ctx))
    goto error;
  dh = crypto_dh_new();
  SSL_CTX_set_tmp_dh(result->ctx, _crypto_dh_env_get_dh(dh));
  crypto_dh_free(dh);
  SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
                     always_accept_verify_cb);
  /* let us realloc bufs that we're writing from */
  SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
535
536
537
538
  /* Free the old context if one exists. */
  if (global_tls_context) {
    /* This is safe even if there are open connections: OpenSSL does
     * reference counting with SSL and SSL_CTX objects. */
539
    tor_tls_context_decref(global_tls_context);
540
  }
541
  global_tls_context = result;
Nick Mathewson's avatar
Nick Mathewson committed
542
543
  if (rsa)
    crypto_free_pk_env(rsa);
544
  return 0;
545
546

 error:
547
  tls_log_errors(LOG_WARN, "creating TLS context");
548
549
  if (pkey)
    EVP_PKEY_free(pkey);
550
551
  if (rsa)
    crypto_free_pk_env(rsa);
552
553
554
  if (dh)
    crypto_dh_free(dh);
  if (result)
555
    tor_tls_context_decref(result);
Nick Mathewson's avatar
Nick Mathewson committed
556
557
558
  if (cert)
    X509_free(cert);
  if (idcert)
559
    X509_free(idcert);
560
  return -1;
561
562
}

563
#ifdef V2_HANDSHAKE_SERVER
564
565
566
/** DOCDOC */
static int
tor_tls_client_is_using_v2_ciphers(const SSL *ssl)
567
568
569
570
571
572
573
{
  int i;
  SSL_SESSION *session;
  /* If we reached this point, we just got a client hello.  See if there is
   * a cipher list. */
  if (!(session = SSL_get_session(ssl))) {
    log_warn(LD_NET, "No session on TLS?");
574
    return 0;
575
576
577
  }
  if (!session->ciphers) {
    log_warn(LD_NET, "No ciphers on session");
578
    return 0;
579
580
581
582
583
584
585
  }
  /* Now we need to see if there are any ciphers whose presence means we're
   * dealing with an updated Tor. */
  for (i = 0; i < sk_SSL_CIPHER_num(session->ciphers); ++i) {
    SSL_CIPHER *cipher = sk_SSL_CIPHER_value(session->ciphers, i);
    const char *ciphername = SSL_CIPHER_get_name(cipher);
    if (strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA) &&
586
        strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA) &&
587
588
589
590
        strcmp(ciphername, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA) &&
        strcmp(ciphername, "(NONE)")) {
      /* XXXX should be ld_debug */
      log_info(LD_NET, "Got a non-version-1 cipher called '%s'",ciphername);
591
592
      // return 1;
      goto dump_list;
593
594
    }
  }
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
  return 0;
 dump_list:
  {
    smartlist_t *elts = smartlist_create();
    char *s;
    for (i = 0; i < sk_SSL_CIPHER_num(session->ciphers); ++i) {
      SSL_CIPHER *cipher = sk_SSL_CIPHER_value(session->ciphers, i);
      const char *ciphername = SSL_CIPHER_get_name(cipher);
      smartlist_add(elts, (char*)ciphername);
    }
    s = smartlist_join_strings(elts, ":", 0, NULL);
    log_info(LD_NET, "Got a non-version-1 cipher list.  It is: '%s'", s);
    tor_free(s);
    smartlist_free(elts);
  }
  return 1;
}
612

613
614
615
616
617
618
619
620
621
622
623
/** DOCDOC */
static void
tor_tls_server_info_callback(const SSL *ssl, int type, int val)
{
  (void) val;
  if (type != SSL_CB_ACCEPT_LOOP)
    return;
  if (ssl->state != SSL3_ST_SW_SRVR_HELLO_A)
    return;

  if (tor_tls_client_is_using_v2_ciphers(ssl)) {
624
625
626
627
628
629
630
631
632
633
634
    /* Yes, we're casting away the const from ssl.  This is very naughty of us.
     * Let's hope openssl doesn't notice! */

    /* Set SSL_MODE_NO_AUTO_CHAIN to keep from sending back any extra certs. */
    SSL_set_mode((SSL*) ssl, SSL_MODE_NO_AUTO_CHAIN);
    /* Don't send a hello request. */
    SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
  }
}
#endif

Nick Mathewson's avatar
Nick Mathewson committed
635
636
/** Create a new TLS object from a file descriptor, and a flag to
 * determine whether it is functioning as a server.
637
 */
638
tor_tls_t *
639
tor_tls_new(int sock, int isServer)
640
{
641
  BIO *bio = NULL;
642
  tor_tls_t *result = tor_malloc_zero(sizeof(tor_tls_t));
643

644
  tor_assert(global_tls_context); /* make sure somebody made it first */
645
  if (!(result->ssl = SSL_new(global_tls_context->ctx))) {
646
647
    tls_log_errors(LOG_WARN, "generating TLS context");
    tor_free(result);
648
    return NULL;
649
  }
650
651
652
653
654
655
  if (!SSL_set_cipher_list(result->ssl,
                     isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST)) {
    SSL_free(result->ssl);
    tor_free(result);
    return NULL;
  }
656
  result->socket = sock;
657
658
659
660
661
662
663
#ifdef USE_BSOCKETS
  bio = BIO_new_bsocket(sock, BIO_NOCLOSE);
#else
  bio = BIO_new_socket(sock, BIO_NOCLOSE);
#endif
  if (! bio) {
    tls_log_errors(LOG_WARN, "opening BIO");
664
    SSL_free(result->ssl);
665
666
667
668
    tor_free(result);
    return NULL;
  }
  SSL_set_bio(result->ssl, bio, bio);
669
670
  tor_tls_context_incref(global_tls_context);
  result->context = global_tls_context;
671
672
  result->state = TOR_TLS_ST_HANDSHAKE;
  result->isServer = isServer;
673
  result->wantwrite_n = 0;
674
675
676
677
678
#ifdef V2_HANDSHAKE_SERVER
  if (isServer) {
    SSL_set_info_callback(result->ssl, tor_tls_server_info_callback);
  }
#endif
679
680
  /* Not expected to get called. */
  tls_log_errors(LOG_WARN, "generating TLS context");
681
682
683
  return result;
}

684
685
686
687
688
689
690
691
692
693
/**DOCDOC*/
void
tor_tls_set_renegotiate_callback(tor_tls_t *tls,
                                 void (*cb)(tor_tls_t *, void *arg),
                                 void *arg)
{
  tls->negotiated_callback = cb;
  tls->callback_arg = arg;
}

694
695
696
/** Return whether this tls initiated the connect (client) or
 * received it (server). */
int
697
tor_tls_is_server(tor_tls_t *tls)
698
699
700
701
702
{
  tor_assert(tls);
  return tls->isServer;
}

Nick Mathewson's avatar
Nick Mathewson committed
703
/** Release resources associated with a TLS object.  Does not close the
704
705
706
 * underlying file descriptor.
 */
void
707
tor_tls_free(tor_tls_t *tls)
708
{
709
  tor_assert(tls && tls->ssl);
710
  SSL_free(tls->ssl);
711
  tls->ssl = NULL;
712
  tls->negotiated_callback = NULL;
713
714
  if (tls->context)
    tor_tls_context_decref(tls->context);
715
  tor_free(tls);
716
717
}

Nick Mathewson's avatar
Nick Mathewson committed
718
719
720
721
/** Underlying function for TLS reading.  Reads up to <b>len</b>
 * characters from <b>tls</b> into <b>cp</b>.  On success, returns the
 * number of characters read.  On failure, returns TOR_TLS_ERROR,
 * TOR_TLS_CLOSE, TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
722
723
 */
int
724
tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
725
726
{
  int r, err;
727
728
  tor_assert(tls);
  tor_assert(tls->ssl);
729
  tor_assert(tls->state == TOR_TLS_ST_OPEN);
730
  r = SSL_read(tls->ssl, cp, len);
731
732
733
734
735
736
  if (r > 0) {
#ifdef V2_HANDSHAKE_SERVER
    if (!tls->hadCert && tls->ssl->session && tls->ssl->session->peer) {
      tls->hadCert = 1;
      /* New certificate! */
      log_info(LD_NET, "Got a TLS renegotiation.");
737
738
      if (tls->negotiated_callback)
        tls->negotiated_callback(tls, tls->callback_arg);
739
740
    }
#endif
741
    return r;
742
  }
743
  err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG);
744
  if (err == _TOR_TLS_ZERORETURN) {
745
    log_debug(LD_NET,"read returned r=%d; TLS is closed",r);
746
747
748
    tls->state = TOR_TLS_ST_CLOSED;
    return TOR_TLS_CLOSE;
  } else {
749
    tor_assert(err != TOR_TLS_DONE);
750
    log_debug(LD_NET,"read returned r=%d, err=%d",r,err);
751
752
753
754
    return err;
  }
}

Nick Mathewson's avatar
Nick Mathewson committed
755
756
757
758
/** Underlying function for TLS writing.  Write up to <b>n</b>
 * characters from <b>cp</b> onto <b>tls</b>.  On success, returns the
 * number of characters written.  On failure, returns TOR_TLS_ERROR,
 * TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
759
760
 */
int
761
tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
762
763
{
  int r, err;
764
765
  tor_assert(tls);
  tor_assert(tls->ssl);
766
  tor_assert(tls->state == TOR_TLS_ST_OPEN);
Nick Mathewson's avatar
Nick Mathewson committed
767
768
  if (n == 0)
    return 0;
769
  if (tls->wantwrite_n) {
770
    /* if WANTWRITE last time, we must use the _same_ n as before */
771
    tor_assert(n >= tls->wantwrite_n);
772
773
    log_debug(LD_NET,"resuming pending-write, (%d to flush, reusing %d)",
              (int)n, (int)tls->wantwrite_n);
774
775
776
    n = tls->wantwrite_n;
    tls->wantwrite_n = 0;
  }
777
  r = SSL_write(tls->ssl, cp, n);
778
  err = tor_tls_get_error(tls, r, 0, "writing", LOG_INFO);
Nick Mathewson's avatar
Nick Mathewson committed
779
  if (err == TOR_TLS_DONE) {
780
    return r;
781
  }
782
  if (err == TOR_TLS_WANTWRITE || err == TOR_TLS_WANTREAD) {
783
784
785
    tls->wantwrite_n = n;
  }
  return err;
786
787
}

Nick Mathewson's avatar
Nick Mathewson committed
788
/** Perform initial handshake on <b>tls</b>.  When finished, returns
789
 * TOR_TLS_DONE.  On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
790
 * or TOR_TLS_WANTWRITE.
791
792
 */
int
793
tor_tls_handshake(tor_tls_t *tls)
794
795
{
  int r;
796
797
  tor_assert(tls);
  tor_assert(tls->ssl);
798
  tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
799
  check_no_tls_errors();
800
801
802
803
804
  if (tls->isServer) {
    r = SSL_accept(tls->ssl);
  } else {
    r = SSL_connect(tls->ssl);
  }
805
  r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO);
806
  if (ERR_peek_error() != 0) {
807
    tls_log_errors(tls->isServer ? LOG_INFO : LOG_WARN,
808
                   "handshaking");
809
    return TOR_TLS_ERROR_MISC;
810
  }
811
  if (r == TOR_TLS_DONE) {
812
    tls->state = TOR_TLS_ST_OPEN;
813
814
815
816
    tls->hadCert = tor_tls_peer_has_cert(tls) ? 1 : 0;
    if (tls->isServer) {
      SSL_set_info_callback(tls->ssl, NULL);
      SSL_set_verify(tls->ssl, SSL_VERIFY_NONE, always_accept_verify_cb);
817
      /* There doesn't seem to be a clear OpenSSL API to clear mode flags. */
818
      tls->ssl->mode &= ~SSL_MODE_NO_AUTO_CHAIN;
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
#ifdef V2_HANDSHAKE_SERVER
      if (tor_tls_client_is_using_v2_ciphers(tls->ssl)) {
        /* This check is redundant, but back when we did it in the callback,
         * we didn't have access to the tor_tls_t struct.  We could make some
         * kind of static map linking SSLs to tor_tls_ts, but that way lies
         * sadness. */
        tls->wasV2Handshake = 1;
      } else {
        tls->wasV2Handshake = 0;
      }
#endif
    } else {
#ifdef V2_HANDSHAKE_CLIENT
      /* If we got no ID cert, we're a v2 handshake. */
      X509 *cert = SSL_get_peer_certificate(tls->ssl);/*XXXX020 refcnt?*/
      STACK_OF(X509) *chain = SSL_get_peer_cert_chain(tls->ssl);
      int n_certs = sk_X509_num(chain);
      if (n_certs > 1 || (n_certs == 1 && cert != sk_X509_value(chain, 0)))
        tls->wasV2Handshake = 0;
      else
        tls->wasV2Handshake = 1;
#endif
      SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST);
842
    }
843
  }
844
845
  return r;
}
846

847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
/** Client only: Renegotiate a TLS session.  When finished, returns
 * TOR_TLS_DONE.  On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD, or
 * TOR_TLS_WANTWRITE.
 */
int
tor_tls_renegotiate(tor_tls_t *tls)
{
  int r;
  tor_assert(tls);
  /* We could do server-initiated renegotiation too, but that would be tricky.
   * Instead of "SSL_renegotiate, then SSL_do_handshake until done" */
  tor_assert(!tls->isServer);
  if (tls->state != TOR_TLS_ST_RENEGOTIATE) {
    int r = SSL_renegotiate(tls->ssl);
    if (r <= 0) {
      return tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO,
                               "renegotiating", LOG_WARN);
    }
    tls->state = TOR_TLS_ST_RENEGOTIATE;
  }
  r = SSL_do_handshake(tls->ssl);
  if (r == 1) {
    tls->state = TOR_TLS_ST_OPEN;
    return TOR_TLS_DONE;
  } else
    return tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO,
                             "renegotiating handshake", LOG_WARN);
}

Nick Mathewson's avatar
Nick Mathewson committed
876
/** Shut down an open tls connection <b>tls</b>.  When finished, returns
877
878
879
880
 * TOR_TLS_DONE.  On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
 * or TOR_TLS_WANTWRITE.
 */
int
881
tor_tls_shutdown(tor_tls_t *tls)
882
883
884
{
  int r, err;
  char buf[128];
885
886
  tor_assert(tls);
  tor_assert(tls->ssl);
887

Nick Mathewson's avatar
Nick Mathewson committed
888
889
890
891
892
893
  while (1) {
    if (tls->state == TOR_TLS_ST_SENTCLOSE) {
      /* If we've already called shutdown once to send a close message,
       * we read until the other side has closed too.
       */
      do {
894
        r = SSL_read(tls->ssl, buf, 128);
Nick Mathewson's avatar
Nick Mathewson committed
895
      } while (r>0);
896
897
      err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading to shut down",
                              LOG_INFO);
Nick Mathewson's avatar
Nick Mathewson committed
898
      if (err == _TOR_TLS_ZERORETURN) {
899
900
        tls->state = TOR_TLS_ST_GOTCLOSE;
        /* fall through... */
Nick Mathewson's avatar
Nick Mathewson committed
901
      } else {
902
        return err;
Nick Mathewson's avatar
Nick Mathewson committed
903
904
905
906
907
908
909
910
911
      }
    }

    r = SSL_shutdown(tls->ssl);
    if (r == 1) {
      /* If shutdown returns 1, the connection is entirely closed. */
      tls->state = TOR_TLS_ST_CLOSED;
      return TOR_TLS_DONE;
    }
912
913
    err = tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO, "shutting down",
                            LOG_INFO);
Nick Mathewson's avatar
Nick Mathewson committed
914
915
    if (err == _TOR_TLS_SYSCALL) {
      /* The underlying TCP connection closed while we were shutting down. */
916
      tls->state = TOR_TLS_ST_CLOSED;
Nick Mathewson's avatar
Nick Mathewson committed
917
918
919
920
921
922
923
      return TOR_TLS_DONE;
    } else if (err == _TOR_TLS_ZERORETURN) {
      /* The TLS connection says that it sent a shutdown record, but
       * isn't done shutting down yet.  Make sure that this hasn't
       * happened before, then go back to the start of the function
       * and try to read.
       */
924
925
      if (tls->state == TOR_TLS_ST_GOTCLOSE ||
         tls->state == TOR_TLS_ST_SENTCLOSE) {
926
        log(LOG_WARN, LD_NET,
927
            "TLS returned \"half-closed\" value while already half-closed");
928
        return TOR_TLS_ERROR_MISC;
Nick Mathewson's avatar
Nick Mathewson committed
929
930
931
      }
      tls->state = TOR_TLS_ST_SENTCLOSE;
      /* fall through ... */
932
933
934
    } else {
      return err;
    }
Nick Mathewson's avatar
Nick Mathewson committed
935
  } /* end loop */
936
}
937

Nick Mathewson's avatar
Nick Mathewson committed
938
/** Return true iff this TLS connection is authenticated.
939
940
 */
int
941
tor_tls_peer_has_cert(tor_tls_t *tls)
942
943
{
  X509 *cert;
944
945
946
  cert = SSL_get_peer_certificate(tls->ssl);
  tls_log_errors(LOG_WARN, "getting peer certificate");
  if (!cert)
947
948
949
950
951
    return 0;
  X509_free(cert);
  return 1;
}

952
953
954
955
956
957
958
959
/** DOCDOC */
int
tor_tls_get_cert_digests(tor_tls_t *tls,
                         char *my_digest_out,
                         char *peer_digest_out)
{
  X509 *cert;
  unsigned int len;
960
  tor_assert(tls && tls->context);
961
  cert = tls->context->my_cert;
962
963
964
965
966
967
968
969
970
971
972
973
974
975
  if (cert) {
    X509_digest(cert, EVP_sha1(), (unsigned char*)my_digest_out, &len);
    if (len != DIGEST_LEN)
      return -1;
  }
  cert = SSL_get_peer_certificate(tls->ssl);
  if (cert) {
    X509_digest(cert, EVP_sha1(), (unsigned char*)peer_digest_out, &len);
    if (len != DIGEST_LEN)
      return -1;
  }
  return 0;
}

976
977
978
979
980
981
982
/** DOCDOC */
crypto_pk_env_t *
tor_tls_dup_private_key(tor_tls_t *tls)
{
  return crypto_pk_dup_key(tls->context->key);
}

983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/** DOCDOC */
char *
tor_tls_encode_my_certificate(tor_tls_t *tls, size_t *size_out,
                              int conn_cert)
{
  unsigned char *result, *cp;
  int certlen;
  X509 *cert;
  tor_assert(tls && tls->context);
  cert = conn_cert ? tls->context->my_cert : tls->context->my_id_cert;
  tor_assert(cert);
  certlen = i2d_X509(cert, NULL);
  tor_assert(certlen >= 0);
  cp = result = tor_malloc(certlen);
  i2d_X509(cert, &cp);
  tor_assert(cp-result == certlen);
  *size_out = (size_t)certlen;
  return (char*) result;