resolve one more, and leave two for nick.
[tor.git] / src / common / tortls.c
blob2259d9e5a724862acffbd8192e9f925fa0659e69
1 /* Copyright (c) 2003, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2008, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 /* $Id$ */
6 const char tortls_c_id[] =
7 "$Id$";
9 /**
10 * \file tortls.c
11 * \brief Wrapper functions to present a consistent interface to
12 * TLS, SSL, and X.509 functions from OpenSSL.
13 **/
15 /* (Unlike other tor functions, these
16 * are prefixed with tor_ in order to avoid conflicting with OpenSSL
17 * functions and variables.)
20 #include "orconfig.h"
22 #include <assert.h>
23 #include <openssl/ssl.h>
24 #include <openssl/ssl3.h>
25 #include <openssl/err.h>
26 #include <openssl/tls1.h>
27 #include <openssl/asn1.h>
28 #include <openssl/bio.h>
29 #include <openssl/opensslv.h>
31 #if OPENSSL_VERSION_NUMBER < 0x00907000l
32 #error "We require openssl >= 0.9.7"
33 #endif
35 #define CRYPTO_PRIVATE /* to import prototypes from crypto.h */
37 #include "crypto.h"
38 #include "tortls.h"
39 #include "util.h"
40 #include "log.h"
41 #include "container.h"
42 #include "ht.h"
43 #include <string.h>
45 // #define V2_HANDSHAKE_SERVER
46 // #define V2_HANDSHAKE_CLIENT
48 /* Copied from or.h */
49 #define LEGAL_NICKNAME_CHARACTERS \
50 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
52 /** How long do identity certificates live? (sec) */
53 #define IDENTITY_CERT_LIFETIME (365*24*60*60)
55 #define ADDR(tls) (((tls) && (tls)->address) ? tls->address : "peer")
57 /** Structure holding the TLS state for a single connection. */
58 typedef struct tor_tls_context_t {
59 int refcnt;
60 SSL_CTX *ctx;
61 X509 *my_cert;
62 X509 *my_id_cert;
63 crypto_pk_env_t *key;
64 } tor_tls_context_t;
66 /** Holds a SSL object and its associated data. Members are only
67 * accessed from within tortls.c.
69 struct tor_tls_t {
70 HT_ENTRY(tor_tls_t) node;
71 tor_tls_context_t *context; /** A link to the context object for this tls */
72 SSL *ssl; /**< An OpenSSL SSL object. */
73 int socket; /**< The underlying file descriptor for this TLS connection. */
74 char *address; /**< An address to log when describing this connectinon. */
75 enum {
76 TOR_TLS_ST_HANDSHAKE, TOR_TLS_ST_OPEN, TOR_TLS_ST_GOTCLOSE,
77 TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED, TOR_TLS_ST_RENEGOTIATE,
78 } state : 3; /**< The current SSL state, depending on which operations have
79 * completed successfully. */
80 unsigned int isServer:1; /**< True iff this is a server-side connection */
81 unsigned int wasV2Handshake:1; /**< True iff the original handshake for
82 * this connection used the updated version
83 * of the connection protocol (client sends
84 * different cipher list, server sends only
85 * one certificate). */
86 int got_renegotiate:1; /**< True iff we should call negotiated_callback
87 * when we're done reading. */
88 size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last
89 * time. */
90 /** Last values retrieved from BIO_number_read()/write(); see
91 * tor_tls_get_n_raw_bytes() for usage.
93 unsigned long last_write_count;
94 unsigned long last_read_count;
95 /** If set, a callback to invoke whenever the client tries to renegotiate
96 * the handshake. */
97 void (*negotiated_callback)(tor_tls_t *tls, void *arg);
98 /** Argument to pass to negotiated_callback. */
99 void *callback_arg;
102 /** Helper: compare tor_tls_t objects by its SSL. */
103 static INLINE int
104 tor_tls_entries_eq(const tor_tls_t *a, const tor_tls_t *b)
106 return a->ssl == b->ssl;
109 /** Helper: return a hash value for a tor_tls_t by its SSL. */
110 static INLINE unsigned int
111 tor_tls_entry_hash(const tor_tls_t *a)
113 #if SIZEOF_INT == SIZEOF_VOID_P
114 return ((unsigned int)a->ssl);
115 #else
116 return (unsigned int) ((((uint64_t)a->ssl)>>2) & UINT_MAX);
117 #endif
120 /** Map from SSL* pointers to tor_tls_t objects using those pointers.
122 static HT_HEAD(tlsmap, tor_tls_t) tlsmap_root = HT_INITIALIZER();
124 HT_PROTOTYPE(tlsmap, tor_tls_t, node, tor_tls_entry_hash,
125 tor_tls_entries_eq)
126 HT_GENERATE(tlsmap, tor_tls_t, node, tor_tls_entry_hash,
127 tor_tls_entries_eq, 0.6, malloc, realloc, free)
129 /** Helper: given a SSL* pointer, return the tor_tls_t object using that
130 * pointer. */
131 static INLINE tor_tls_t *
132 tor_tls_get_by_ssl(const SSL *ssl)
134 tor_tls_t search, *result;
135 memset(&search, 0, sizeof(search));
136 search.ssl = (SSL*)ssl;
137 result = HT_FIND(tlsmap, &tlsmap_root, &search);
138 return result;
141 static void tor_tls_context_decref(tor_tls_context_t *ctx);
142 static void tor_tls_context_incref(tor_tls_context_t *ctx);
143 static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
144 crypto_pk_env_t *rsa_sign,
145 const char *cname,
146 const char *cname_sign,
147 unsigned int lifetime);
149 /** Global tls context. We keep it here because nobody else needs to
150 * touch it. */
151 static tor_tls_context_t *global_tls_context = NULL;
152 /** True iff tor_tls_init() has been called. */
153 static int tls_library_is_initialized = 0;
155 /* Module-internal error codes. */
156 #define _TOR_TLS_SYSCALL (_MIN_TOR_TLS_ERROR_VAL - 2)
157 #define _TOR_TLS_ZERORETURN (_MIN_TOR_TLS_ERROR_VAL - 1)
159 /** Log all pending tls errors at level <b>severity</b>. Use
160 * <b>doing</b> to describe our current activities.
162 static void
163 tls_log_errors(tor_tls_t *tls, int severity, const char *doing)
165 int err;
166 const char *msg, *lib, *func, *addr;
167 addr = tls ? tls->address : NULL;
168 while ((err = ERR_get_error()) != 0) {
169 msg = (const char*)ERR_reason_error_string(err);
170 lib = (const char*)ERR_lib_error_string(err);
171 func = (const char*)ERR_func_error_string(err);
172 if (!msg) msg = "(null)";
173 if (doing) {
174 log(severity, LD_NET, "TLS error while %s%s%s: %s (in %s:%s)",
175 doing, addr?" with ":"", addr?addr:"",
176 msg, lib, func);
177 } else {
178 log(severity, LD_NET, "TLS error%s%s: %s (in %s:%s)",
179 addr?" with ":"", addr?addr:"",
180 msg, lib, func);
185 /** Convert an errno (or a WSAerrno on windows) into a TOR_TLS_* error
186 * code. */
187 static int
188 tor_errno_to_tls_error(int e)
190 #if defined(MS_WINDOWS) && !defined(USE_BSOCKETS)
191 switch (e) {
192 case WSAECONNRESET: // most common
193 return TOR_TLS_ERROR_CONNRESET;
194 case WSAETIMEDOUT:
195 return TOR_TLS_ERROR_TIMEOUT;
196 case WSAENETUNREACH:
197 case WSAEHOSTUNREACH:
198 return TOR_TLS_ERROR_NO_ROUTE;
199 case WSAECONNREFUSED:
200 return TOR_TLS_ERROR_CONNREFUSED; // least common
201 default:
202 return TOR_TLS_ERROR_MISC;
204 #else
205 switch (e) {
206 case ECONNRESET: // most common
207 return TOR_TLS_ERROR_CONNRESET;
208 case ETIMEDOUT:
209 return TOR_TLS_ERROR_TIMEOUT;
210 case EHOSTUNREACH:
211 case ENETUNREACH:
212 return TOR_TLS_ERROR_NO_ROUTE;
213 case ECONNREFUSED:
214 return TOR_TLS_ERROR_CONNREFUSED; // least common
215 default:
216 return TOR_TLS_ERROR_MISC;
218 #endif
221 /** Given a TOR_TLS_* error code, return a string equivalent. */
222 const char *
223 tor_tls_err_to_string(int err)
225 if (err >= 0)
226 return "[Not an error.]";
227 switch (err) {
228 case TOR_TLS_ERROR_MISC: return "misc error";
229 case TOR_TLS_ERROR_IO: return "unexpected close";
230 case TOR_TLS_ERROR_CONNREFUSED: return "connection refused";
231 case TOR_TLS_ERROR_CONNRESET: return "connection reset";
232 case TOR_TLS_ERROR_NO_ROUTE: return "host unreachable";
233 case TOR_TLS_ERROR_TIMEOUT: return "connection timed out";
234 case TOR_TLS_CLOSE: return "closed";
235 case TOR_TLS_WANTREAD: return "want to read";
236 case TOR_TLS_WANTWRITE: return "want to write";
237 default: return "(unknown error code)";
241 #define CATCH_SYSCALL 1
242 #define CATCH_ZERO 2
244 /** Given a TLS object and the result of an SSL_* call, use
245 * SSL_get_error to determine whether an error has occurred, and if so
246 * which one. Return one of TOR_TLS_{DONE|WANTREAD|WANTWRITE|ERROR}.
247 * If extra&CATCH_SYSCALL is true, return _TOR_TLS_SYSCALL instead of
248 * reporting syscall errors. If extra&CATCH_ZERO is true, return
249 * _TOR_TLS_ZERORETURN instead of reporting zero-return errors.
251 * If an error has occurred, log it at level <b>severity</b> and describe the
252 * current action as <b>doing</b>.
254 static int
255 tor_tls_get_error(tor_tls_t *tls, int r, int extra,
256 const char *doing, int severity)
258 int err = SSL_get_error(tls->ssl, r);
259 int tor_error = TOR_TLS_ERROR_MISC;
260 switch (err) {
261 case SSL_ERROR_NONE:
262 return TOR_TLS_DONE;
263 case SSL_ERROR_WANT_READ:
264 return TOR_TLS_WANTREAD;
265 case SSL_ERROR_WANT_WRITE:
266 return TOR_TLS_WANTWRITE;
267 case SSL_ERROR_SYSCALL:
268 if (extra&CATCH_SYSCALL)
269 return _TOR_TLS_SYSCALL;
270 if (r == 0) {
271 log(severity, LD_NET, "TLS error: unexpected close while %s", doing);
272 tor_error = TOR_TLS_ERROR_IO;
273 } else {
274 int e = tor_socket_errno(tls->socket);
275 log(severity, LD_NET,
276 "TLS error: <syscall error while %s> (errno=%d: %s)",
277 doing, e, tor_socket_strerror(e));
278 tor_error = tor_errno_to_tls_error(e);
280 tls_log_errors(tls, severity, doing);
281 return tor_error;
282 case SSL_ERROR_ZERO_RETURN:
283 if (extra&CATCH_ZERO)
284 return _TOR_TLS_ZERORETURN;
285 log(severity, LD_NET, "TLS error: Zero return");
286 tls_log_errors(tls, severity, doing);
287 /* XXXX020rc Actually, a 'zero return' error has a pretty specific
288 * meaning: the connection has been closed cleanly. -NM
289 * Great. Do something smart here then. :) -RD */
290 return TOR_TLS_ERROR_MISC;
291 default:
292 tls_log_errors(tls, severity, doing);
293 return TOR_TLS_ERROR_MISC;
297 /** Initialize OpenSSL, unless it has already been initialized.
299 static void
300 tor_tls_init(void)
302 if (!tls_library_is_initialized) {
303 SSL_library_init();
304 SSL_load_error_strings();
305 crypto_global_init(-1);
306 tls_library_is_initialized = 1;
310 /** Free all global TLS structures. */
311 void
312 tor_tls_free_all(void)
314 if (global_tls_context) {
315 tor_tls_context_decref(global_tls_context);
316 global_tls_context = NULL;
320 /** We need to give OpenSSL a callback to verify certificates. This is
321 * it: We always accept peer certs and complete the handshake. We
322 * don't validate them until later.
324 static int
325 always_accept_verify_cb(int preverify_ok,
326 X509_STORE_CTX *x509_ctx)
328 (void) preverify_ok;
329 (void) x509_ctx;
330 return 1;
333 /** Return a newly allocated X509 name with commonName <b>cname</b>. */
334 static X509_NAME *
335 tor_x509_name_new(const char *cname)
337 int nid;
338 X509_NAME *name;
339 if (!(name = X509_NAME_new()))
340 return NULL;
341 if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
342 if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
343 (unsigned char*)cname, -1, -1, 0)))
344 goto error;
345 return name;
346 error:
347 X509_NAME_free(name);
348 return NULL;
351 /** Generate and sign an X509 certificate with the public key <b>rsa</b>,
352 * signed by the private key <b>rsa_sign</b>. The commonName of the
353 * certificate will be <b>cname</b>; the commonName of the issuer will be
354 * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
355 * starting from now. Return a certificate on success, NULL on
356 * failure.
358 static X509 *
359 tor_tls_create_certificate(crypto_pk_env_t *rsa,
360 crypto_pk_env_t *rsa_sign,
361 const char *cname,
362 const char *cname_sign,
363 unsigned int cert_lifetime)
365 time_t start_time, end_time;
366 EVP_PKEY *sign_pkey = NULL, *pkey=NULL;
367 X509 *x509 = NULL;
368 X509_NAME *name = NULL, *name_issuer=NULL;
370 tor_tls_init();
372 start_time = time(NULL);
374 tor_assert(rsa);
375 tor_assert(cname);
376 tor_assert(rsa_sign);
377 tor_assert(cname_sign);
378 if (!(sign_pkey = _crypto_pk_env_get_evp_pkey(rsa_sign,1)))
379 goto error;
380 if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0)))
381 goto error;
382 if (!(x509 = X509_new()))
383 goto error;
384 if (!(X509_set_version(x509, 2)))
385 goto error;
386 if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)start_time)))
387 goto error;
389 if (!(name = tor_x509_name_new(cname)))
390 goto error;
391 if (!(X509_set_subject_name(x509, name)))
392 goto error;
393 if (!(name_issuer = tor_x509_name_new(cname_sign)))
394 goto error;
395 if (!(X509_set_issuer_name(x509, name_issuer)))
396 goto error;
398 if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time))
399 goto error;
400 end_time = start_time + cert_lifetime;
401 if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time))
402 goto error;
403 if (!X509_set_pubkey(x509, pkey))
404 goto error;
405 if (!X509_sign(x509, sign_pkey, EVP_sha1()))
406 goto error;
408 goto done;
409 error:
410 if (x509) {
411 X509_free(x509);
412 x509 = NULL;
414 done:
415 tls_log_errors(NULL, LOG_WARN, "generating certificate");
416 if (sign_pkey)
417 EVP_PKEY_free(sign_pkey);
418 if (pkey)
419 EVP_PKEY_free(pkey);
420 if (name)
421 X509_NAME_free(name);
422 if (name_issuer)
423 X509_NAME_free(name_issuer);
424 return x509;
427 #define SERVER_CIPHER_LIST \
428 (TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
429 TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
430 SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
431 /* Note: for setting up your own private testing network with link crypto
432 * disabled, set the cipher lists to your cipher list to
433 * SSL3_TXT_RSA_NULL_SHA. If you do this, you won't be able to communicate
434 * with any of the "real" Tors, though. */
436 #if OPENSSL_VERSION_NUMBER >= 0x00908000l
437 #define CLIENT_CIPHER_LIST \
438 (TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ":" \
439 TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA ":" \
440 TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
441 TLS1_TXT_DHE_DSS_WITH_AES_256_SHA ":" \
442 TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA ":" \
443 TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA ":" \
444 TLS1_TXT_RSA_WITH_AES_256_SHA ":" \
445 TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA ":" \
446 TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ":" \
447 TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA ":" \
448 TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA ":" \
449 TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
450 TLS1_TXT_DHE_DSS_WITH_AES_128_SHA ":" \
451 TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA":" \
452 TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA":" \
453 TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA ":" \
454 TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA ":" \
455 SSL3_TXT_RSA_RC4_128_MD5 ":" \
456 SSL3_TXT_RSA_RC4_128_SHA ":" \
457 TLS1_TXT_RSA_WITH_AES_128_SHA ":" \
458 TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA ":" \
459 TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA ":" \
460 SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA ":" \
461 SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA ":" \
462 TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA ":" \
463 TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA ":" \
464 /*SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA ":"*/ \
465 SSL3_TXT_RSA_DES_192_CBC3_SHA)
466 /* SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA is commented out because it doesn't
467 * really exist; if I understand correctly, it's a bit of silliness that
468 * netscape did on its own before any standard for what they wanted was
469 * formally approved. Nonetheless, Firefox still uses it, so we need to
470 * fake it at some point soon. XXXX021 -NM */
471 #else
472 /* Ug. We don't have as many ciphers with openssl 0.9.7 as we'd like. Fix
473 * this list into something that sucks less. */
474 #define CLIENT_CIPHER_LIST \
475 (TLS1_TXT_DHE_RSA_WITH_AES_256_SHA ":" \
476 TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
477 SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA ":" \
478 SSL3_TXT_RSA_RC4_128_SHA)
479 #endif
481 #ifndef V2_HANDSHAKE_CLIENT
482 #undef CLIENT_CIPHER_LIST
483 #define CLIENT_CIPHER_LIST (TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
484 SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
485 #endif
487 /** Remove a reference to <b>ctx</b>, and free it if it has no more
488 * references. */
489 static void
490 tor_tls_context_decref(tor_tls_context_t *ctx)
492 tor_assert(ctx);
493 if (--ctx->refcnt == 0) {
494 SSL_CTX_free(ctx->ctx);
495 X509_free(ctx->my_cert);
496 X509_free(ctx->my_id_cert);
497 crypto_free_pk_env(ctx->key);
498 tor_free(ctx);
502 /** Increase the reference count of <b>ctx</b>. */
503 static void
504 tor_tls_context_incref(tor_tls_context_t *ctx)
506 ++ctx->refcnt;
509 /** Create a new TLS context for use with Tor TLS handshakes.
510 * <b>identity</b> should be set to the identity key used to sign the
511 * certificate, and <b>nickname</b> set to the nickname to use.
513 * You can call this function multiple times. Each time you call it,
514 * it generates new certificates; all new connections will use
515 * the new SSL context.
518 tor_tls_context_new(crypto_pk_env_t *identity, unsigned int key_lifetime)
520 crypto_pk_env_t *rsa = NULL;
521 crypto_dh_env_t *dh = NULL;
522 EVP_PKEY *pkey = NULL;
523 tor_tls_context_t *result = NULL;
524 X509 *cert = NULL, *idcert = NULL;
525 char *nickname = NULL, *nn2 = NULL;
527 tor_tls_init();
528 nickname = crypto_random_hostname(8, 20, "www.", ".net");
529 nn2 = crypto_random_hostname(8, 20, "www.", ".net");
531 /* Generate short-term RSA key. */
532 if (!(rsa = crypto_new_pk_env()))
533 goto error;
534 if (crypto_pk_generate_key(rsa)<0)
535 goto error;
536 /* Create certificate signed by identity key. */
537 cert = tor_tls_create_certificate(rsa, identity, nickname, nn2,
538 key_lifetime);
539 /* Create self-signed certificate for identity key. */
540 idcert = tor_tls_create_certificate(identity, identity, nn2, nn2,
541 IDENTITY_CERT_LIFETIME);
542 if (!cert || !idcert) {
543 log(LOG_WARN, LD_CRYPTO, "Error creating certificate");
544 goto error;
547 result = tor_malloc_zero(sizeof(tor_tls_context_t));
548 result->refcnt = 1;
549 result->my_cert = X509_dup(cert);
550 result->my_id_cert = X509_dup(idcert);
551 result->key = crypto_pk_dup_key(rsa);
553 #ifdef EVERYONE_HAS_AES
554 /* Tell OpenSSL to only use TLS1 */
555 if (!(result->ctx = SSL_CTX_new(TLSv1_method())))
556 goto error;
557 #else
558 /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
559 if (!(result->ctx = SSL_CTX_new(SSLv23_method())))
560 goto error;
561 SSL_CTX_set_options(result->ctx, SSL_OP_NO_SSLv2);
562 #endif
563 SSL_CTX_set_options(result->ctx, SSL_OP_SINGLE_DH_USE);
564 if (cert && !SSL_CTX_use_certificate(result->ctx,cert))
565 goto error;
566 X509_free(cert); /* We just added a reference to cert. */
567 cert=NULL;
568 if (idcert) {
569 X509_STORE *s = SSL_CTX_get_cert_store(result->ctx);
570 tor_assert(s);
571 X509_STORE_add_cert(s, idcert);
572 X509_free(idcert); /* The context now owns the reference to idcert */
573 idcert = NULL;
575 SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
576 tor_assert(rsa);
577 if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
578 goto error;
579 if (!SSL_CTX_use_PrivateKey(result->ctx, pkey))
580 goto error;
581 EVP_PKEY_free(pkey);
582 pkey = NULL;
583 if (!SSL_CTX_check_private_key(result->ctx))
584 goto error;
585 dh = crypto_dh_new();
586 SSL_CTX_set_tmp_dh(result->ctx, _crypto_dh_env_get_dh(dh));
587 crypto_dh_free(dh);
588 SSL_CTX_set_verify(result->ctx, SSL_VERIFY_PEER,
589 always_accept_verify_cb);
590 /* let us realloc bufs that we're writing from */
591 SSL_CTX_set_mode(result->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
592 /* Free the old context if one exists. */
593 if (global_tls_context) {
594 /* This is safe even if there are open connections: OpenSSL does
595 * reference counting with SSL and SSL_CTX objects. */
596 tor_tls_context_decref(global_tls_context);
598 global_tls_context = result;
599 if (rsa)
600 crypto_free_pk_env(rsa);
601 tor_free(nickname);
602 tor_free(nn2);
603 return 0;
605 error:
606 tls_log_errors(NULL, LOG_WARN, "creating TLS context");
607 tor_free(nickname);
608 tor_free(nn2);
609 if (pkey)
610 EVP_PKEY_free(pkey);
611 if (rsa)
612 crypto_free_pk_env(rsa);
613 if (dh)
614 crypto_dh_free(dh);
615 if (result)
616 tor_tls_context_decref(result);
617 if (cert)
618 X509_free(cert);
619 if (idcert)
620 X509_free(idcert);
621 return -1;
624 #ifdef V2_HANDSHAKE_SERVER
625 /** Return true iff the cipher list suggested by the client for <b>ssl</b> is
626 * a list that indicates that the client know how to do the v2 TLS connection
627 * handshake. */
628 static int
629 tor_tls_client_is_using_v2_ciphers(const SSL *ssl, const char *address)
631 int i;
632 SSL_SESSION *session;
633 /* If we reached this point, we just got a client hello. See if there is
634 * a cipher list. */
635 if (!(session = SSL_get_session(ssl))) {
636 log_warn(LD_NET, "No session on TLS?");
637 return 0;
639 if (!session->ciphers) {
640 log_warn(LD_NET, "No ciphers on session");
641 return 0;
643 /* Now we need to see if there are any ciphers whose presence means we're
644 * dealing with an updated Tor. */
645 for (i = 0; i < sk_SSL_CIPHER_num(session->ciphers); ++i) {
646 SSL_CIPHER *cipher = sk_SSL_CIPHER_value(session->ciphers, i);
647 const char *ciphername = SSL_CIPHER_get_name(cipher);
648 if (strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA) &&
649 strcmp(ciphername, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA) &&
650 strcmp(ciphername, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA) &&
651 strcmp(ciphername, "(NONE)")) {
652 /* XXXX should be ld_debug */
653 log_info(LD_NET, "Got a non-version-1 cipher called '%s'", ciphername);
654 // return 1;
655 goto dump_list;
658 return 0;
659 dump_list:
661 smartlist_t *elts = smartlist_create();
662 char *s;
663 for (i = 0; i < sk_SSL_CIPHER_num(session->ciphers); ++i) {
664 SSL_CIPHER *cipher = sk_SSL_CIPHER_value(session->ciphers, i);
665 const char *ciphername = SSL_CIPHER_get_name(cipher);
666 smartlist_add(elts, (char*)ciphername);
668 s = smartlist_join_strings(elts, ":", 0, NULL);
669 log_info(LD_NET, "Got a non-version-1 cipher list from %s. It is: '%s'",
670 s, address);
671 tor_free(s);
672 smartlist_free(elts);
674 return 1;
677 /** Invoked when we're accepting a connection on <b>ssl</b>, and the connection
678 * changes state. We use this:
679 * <ul><li>To alter the state of the handshake partway through, so we
680 * do not send or request extra certificates in v2 handshakes.</li>
681 * <li>To detect renegotiation</li></ul>
683 static void
684 tor_tls_server_info_callback(const SSL *ssl, int type, int val)
686 tor_tls_t *tls;
687 (void) val;
688 if (type != SSL_CB_ACCEPT_LOOP)
689 return;
690 if (ssl->state != SSL3_ST_SW_SRVR_HELLO_A)
691 return;
693 tls = tor_tls_get_by_ssl(ssl);
694 if (tls) {
695 /* Check whether we're watching for renegotiates. If so, this is one! */
696 if (tls->negotiated_callback)
697 tls->got_renegotiate = 1;
698 } else {
699 log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
702 /* Now check the cipher list. */
703 if (tor_tls_client_is_using_v2_ciphers(ssl, ADDR(tls))) {
704 /*XXXX_TLS keep this from happening more than once! */
706 /* Yes, we're casting away the const from ssl. This is very naughty of us.
707 * Let's hope openssl doesn't notice! */
709 /* Set SSL_MODE_NO_AUTO_CHAIN to keep from sending back any extra certs. */
710 SSL_set_mode((SSL*) ssl, SSL_MODE_NO_AUTO_CHAIN);
711 /* Don't send a hello request. */
712 SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
714 if (tls) {
715 tls->wasV2Handshake = 1;
716 } else {
717 log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
721 #endif
723 /** Create a new TLS object from a file descriptor, and a flag to
724 * determine whether it is functioning as a server.
726 tor_tls_t *
727 tor_tls_new(int sock, int isServer)
729 BIO *bio = NULL;
730 tor_tls_t *result = tor_malloc_zero(sizeof(tor_tls_t));
732 tor_assert(global_tls_context); /* make sure somebody made it first */
733 if (!(result->ssl = SSL_new(global_tls_context->ctx))) {
734 tls_log_errors(NULL, LOG_WARN, "generating TLS context");
735 tor_free(result);
736 return NULL;
738 if (!SSL_set_cipher_list(result->ssl,
739 isServer ? SERVER_CIPHER_LIST : CLIENT_CIPHER_LIST)) {
740 SSL_free(result->ssl);
741 tor_free(result);
742 return NULL;
744 result->socket = sock;
745 #ifdef USE_BSOCKETS
746 bio = BIO_new_bsocket(sock, BIO_NOCLOSE);
747 #else
748 bio = BIO_new_socket(sock, BIO_NOCLOSE);
749 #endif
750 if (! bio) {
751 tls_log_errors(NULL, LOG_WARN, "opening BIO");
752 SSL_free(result->ssl);
753 tor_free(result);
754 return NULL;
756 HT_INSERT(tlsmap, &tlsmap_root, result);
757 SSL_set_bio(result->ssl, bio, bio);
758 tor_tls_context_incref(global_tls_context);
759 result->context = global_tls_context;
760 result->state = TOR_TLS_ST_HANDSHAKE;
761 result->isServer = isServer;
762 result->wantwrite_n = 0;
763 #ifdef V2_HANDSHAKE_SERVER
764 if (isServer) {
765 SSL_set_info_callback(result->ssl, tor_tls_server_info_callback);
767 #endif
768 /* Not expected to get called. */
769 tls_log_errors(NULL, LOG_WARN, "generating TLS context");
770 return result;
773 /** Make future log messages about <b>tls</b> display the address
774 * <b>address</b>.
776 void
777 tor_tls_set_logged_address(tor_tls_t *tls, const char *address)
779 tor_assert(tls);
780 tor_free(tls->address);
781 tls->address = tor_strdup(address);
784 /** Set <b>cb</b> to be called with argument <b>arg</b> whenever <b>tls</b>
785 * next gets a client-side renegotiate in the middle of a read. Do not
786 * invoke this function untile <em>after</em> initial handshaking is done!
788 void
789 tor_tls_set_renegotiate_callback(tor_tls_t *tls,
790 void (*cb)(tor_tls_t *, void *arg),
791 void *arg)
793 tls->negotiated_callback = cb;
794 tls->callback_arg = arg;
795 tls->got_renegotiate = 0;
796 #ifdef V2_HANDSHAKE_SERVER
797 if (cb) {
798 SSL_set_info_callback(tls->ssl, tor_tls_server_info_callback);
799 } else {
800 SSL_set_info_callback(tls->ssl, NULL);
802 #endif
805 /** Return whether this tls initiated the connect (client) or
806 * received it (server). */
808 tor_tls_is_server(tor_tls_t *tls)
810 tor_assert(tls);
811 return tls->isServer;
814 /** Release resources associated with a TLS object. Does not close the
815 * underlying file descriptor.
817 void
818 tor_tls_free(tor_tls_t *tls)
820 tor_tls_t *removed;
821 tor_assert(tls && tls->ssl);
822 removed = HT_REMOVE(tlsmap, &tlsmap_root, tls);
823 if (!removed) {
824 log_warn(LD_BUG, "Freeing a TLS that was not in the ssl->tls map.");
826 SSL_free(tls->ssl);
827 tls->ssl = NULL;
828 tls->negotiated_callback = NULL;
829 if (tls->context)
830 tor_tls_context_decref(tls->context);
831 tor_free(tls->address);
832 tor_free(tls);
835 /** Underlying function for TLS reading. Reads up to <b>len</b>
836 * characters from <b>tls</b> into <b>cp</b>. On success, returns the
837 * number of characters read. On failure, returns TOR_TLS_ERROR,
838 * TOR_TLS_CLOSE, TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
841 tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
843 int r, err;
844 tor_assert(tls);
845 tor_assert(tls->ssl);
846 tor_assert(tls->state == TOR_TLS_ST_OPEN);
847 r = SSL_read(tls->ssl, cp, len);
848 if (r > 0) {
849 #ifdef V2_HANDSHAKE_SERVER
850 if (tls->got_renegotiate) {
851 /* Renegotiation happened! */
852 log_info(LD_NET, "Got a TLS renegotiation from %s", ADDR(tls));
853 if (tls->negotiated_callback)
854 tls->negotiated_callback(tls, tls->callback_arg);
855 tls->got_renegotiate = 0;
857 #endif
858 return r;
860 err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG);
861 if (err == _TOR_TLS_ZERORETURN) {
862 log_debug(LD_NET,"read returned r=%d; TLS is closed",r);
863 tls->state = TOR_TLS_ST_CLOSED;
864 return TOR_TLS_CLOSE;
865 } else {
866 tor_assert(err != TOR_TLS_DONE);
867 log_debug(LD_NET,"read returned r=%d, err=%d",r,err);
868 return err;
872 /** Underlying function for TLS writing. Write up to <b>n</b>
873 * characters from <b>cp</b> onto <b>tls</b>. On success, returns the
874 * number of characters written. On failure, returns TOR_TLS_ERROR,
875 * TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
878 tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
880 int r, err;
881 tor_assert(tls);
882 tor_assert(tls->ssl);
883 tor_assert(tls->state == TOR_TLS_ST_OPEN);
884 if (n == 0)
885 return 0;
886 if (tls->wantwrite_n) {
887 /* if WANTWRITE last time, we must use the _same_ n as before */
888 tor_assert(n >= tls->wantwrite_n);
889 log_debug(LD_NET,"resuming pending-write, (%d to flush, reusing %d)",
890 (int)n, (int)tls->wantwrite_n);
891 n = tls->wantwrite_n;
892 tls->wantwrite_n = 0;
894 r = SSL_write(tls->ssl, cp, n);
895 err = tor_tls_get_error(tls, r, 0, "writing", LOG_INFO);
896 if (err == TOR_TLS_DONE) {
897 return r;
899 if (err == TOR_TLS_WANTWRITE || err == TOR_TLS_WANTREAD) {
900 tls->wantwrite_n = n;
902 return err;
905 /** Perform initial handshake on <b>tls</b>. When finished, returns
906 * TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
907 * or TOR_TLS_WANTWRITE.
910 tor_tls_handshake(tor_tls_t *tls)
912 int r;
913 tor_assert(tls);
914 tor_assert(tls->ssl);
915 tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
916 check_no_tls_errors();
917 if (tls->isServer) {
918 r = SSL_accept(tls->ssl);
919 } else {
920 r = SSL_connect(tls->ssl);
922 r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO);
923 if (ERR_peek_error() != 0) {
924 tls_log_errors(tls, tls->isServer ? LOG_INFO : LOG_WARN,
925 "handshaking");
926 return TOR_TLS_ERROR_MISC;
928 if (r == TOR_TLS_DONE) {
929 tls->state = TOR_TLS_ST_OPEN;
930 if (tls->isServer) {
931 SSL_set_info_callback(tls->ssl, NULL);
932 SSL_set_verify(tls->ssl, SSL_VERIFY_NONE, always_accept_verify_cb);
933 /* There doesn't seem to be a clear OpenSSL API to clear mode flags. */
934 tls->ssl->mode &= ~SSL_MODE_NO_AUTO_CHAIN;
935 #ifdef V2_HANDSHAKE_SERVER
936 if (tor_tls_client_is_using_v2_ciphers(tls->ssl, ADDR(tls))) {
937 /* This check is redundant, but back when we did it in the callback,
938 * we might have not been able to look up the tor_tls_t if the code
939 * was buggy. Fixing that. */
940 if (!tls->wasV2Handshake) {
941 log_warn(LD_BUG, "For some reason, wasV2Handshake didn't"
942 " get set. Fixing that.");
944 tls->wasV2Handshake = 1;
945 log_debug(LD_NET, "Completed V2 TLS handshake with client; waiting "
946 "for renegotiation.");
947 } else {
948 tls->wasV2Handshake = 0;
950 #endif
951 } else {
952 #ifdef V2_HANDSHAKE_CLIENT
953 /* If we got no ID cert, we're a v2 handshake. */
954 X509 *cert = SSL_get_peer_certificate(tls->ssl);
955 STACK_OF(X509) *chain = SSL_get_peer_cert_chain(tls->ssl);
956 int n_certs = sk_X509_num(chain);
957 if (n_certs > 1 || (n_certs == 1 && cert != sk_X509_value(chain, 0)))
958 tls->wasV2Handshake = 0;
959 else {
960 log_debug(LD_NET, "Server sent back a single certificate; looks like "
961 "a v2 handshake on %p.", tls);
962 tls->wasV2Handshake = 1;
964 if (cert)
965 X509_free(cert);
966 #endif
967 SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST);
970 return r;
973 /** Client only: Renegotiate a TLS session. When finished, returns
974 * TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD, or
975 * TOR_TLS_WANTWRITE.
978 tor_tls_renegotiate(tor_tls_t *tls)
980 int r;
981 tor_assert(tls);
982 /* We could do server-initiated renegotiation too, but that would be tricky.
983 * Instead of "SSL_renegotiate, then SSL_do_handshake until done" */
984 tor_assert(!tls->isServer);
985 if (tls->state != TOR_TLS_ST_RENEGOTIATE) {
986 int r = SSL_renegotiate(tls->ssl);
987 if (r <= 0) {
988 return tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO,
989 "renegotiating", LOG_WARN);
991 tls->state = TOR_TLS_ST_RENEGOTIATE;
993 r = SSL_do_handshake(tls->ssl);
994 if (r == 1) {
995 tls->state = TOR_TLS_ST_OPEN;
996 return TOR_TLS_DONE;
997 } else
998 return tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO,
999 "renegotiating handshake", LOG_WARN);
1002 /** Shut down an open tls connection <b>tls</b>. When finished, returns
1003 * TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
1004 * or TOR_TLS_WANTWRITE.
1007 tor_tls_shutdown(tor_tls_t *tls)
1009 int r, err;
1010 char buf[128];
1011 tor_assert(tls);
1012 tor_assert(tls->ssl);
1014 while (1) {
1015 if (tls->state == TOR_TLS_ST_SENTCLOSE) {
1016 /* If we've already called shutdown once to send a close message,
1017 * we read until the other side has closed too.
1019 do {
1020 r = SSL_read(tls->ssl, buf, 128);
1021 } while (r>0);
1022 err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading to shut down",
1023 LOG_INFO);
1024 if (err == _TOR_TLS_ZERORETURN) {
1025 tls->state = TOR_TLS_ST_GOTCLOSE;
1026 /* fall through... */
1027 } else {
1028 return err;
1032 r = SSL_shutdown(tls->ssl);
1033 if (r == 1) {
1034 /* If shutdown returns 1, the connection is entirely closed. */
1035 tls->state = TOR_TLS_ST_CLOSED;
1036 return TOR_TLS_DONE;
1038 err = tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO, "shutting down",
1039 LOG_INFO);
1040 if (err == _TOR_TLS_SYSCALL) {
1041 /* The underlying TCP connection closed while we were shutting down. */
1042 tls->state = TOR_TLS_ST_CLOSED;
1043 return TOR_TLS_DONE;
1044 } else if (err == _TOR_TLS_ZERORETURN) {
1045 /* The TLS connection says that it sent a shutdown record, but
1046 * isn't done shutting down yet. Make sure that this hasn't
1047 * happened before, then go back to the start of the function
1048 * and try to read.
1050 if (tls->state == TOR_TLS_ST_GOTCLOSE ||
1051 tls->state == TOR_TLS_ST_SENTCLOSE) {
1052 log(LOG_WARN, LD_NET,
1053 "TLS returned \"half-closed\" value while already half-closed");
1054 return TOR_TLS_ERROR_MISC;
1056 tls->state = TOR_TLS_ST_SENTCLOSE;
1057 /* fall through ... */
1058 } else {
1059 return err;
1061 } /* end loop */
1064 /** Return true iff this TLS connection is authenticated.
1067 tor_tls_peer_has_cert(tor_tls_t *tls)
1069 X509 *cert;
1070 cert = SSL_get_peer_certificate(tls->ssl);
1071 tls_log_errors(tls, LOG_WARN, "getting peer certificate");
1072 if (!cert)
1073 return 0;
1074 X509_free(cert);
1075 return 1;
1078 /** Warn that a certificate lifetime extends through a certain range. */
1079 static void
1080 log_cert_lifetime(X509 *cert, const char *problem)
1082 BIO *bio = NULL;
1083 BUF_MEM *buf;
1084 char *s1=NULL, *s2=NULL;
1085 char mytime[33];
1086 time_t now = time(NULL);
1087 struct tm tm;
1089 if (problem)
1090 log_warn(LD_GENERAL,
1091 "Certificate %s: is your system clock set incorrectly?",
1092 problem);
1094 if (!(bio = BIO_new(BIO_s_mem()))) {
1095 log_warn(LD_GENERAL, "Couldn't allocate BIO!"); goto end;
1097 if (!(ASN1_TIME_print(bio, X509_get_notBefore(cert)))) {
1098 tls_log_errors(NULL, LOG_WARN, "printing certificate lifetime");
1099 goto end;
1101 BIO_get_mem_ptr(bio, &buf);
1102 s1 = tor_strndup(buf->data, buf->length);
1104 (void)BIO_reset(bio);
1105 if (!(ASN1_TIME_print(bio, X509_get_notAfter(cert)))) {
1106 tls_log_errors(NULL, LOG_WARN, "printing certificate lifetime");
1107 goto end;
1109 BIO_get_mem_ptr(bio, &buf);
1110 s2 = tor_strndup(buf->data, buf->length);
1112 strftime(mytime, 32, "%b %d %H:%M:%S %Y GMT", tor_gmtime_r(&now, &tm));
1114 log_warn(LD_GENERAL,
1115 "(certificate lifetime runs from %s through %s. Your time is %s.)",
1116 s1,s2,mytime);
1118 end:
1119 /* Not expected to get invoked */
1120 tls_log_errors(NULL, LOG_WARN, "getting certificate lifetime");
1121 if (bio)
1122 BIO_free(bio);
1123 if (s1)
1124 tor_free(s1);
1125 if (s2)
1126 tor_free(s2);
1129 /** Helper function: try to extract a link certificate and an identity
1130 * certificate from <b>tls</b>, and store them in *<b>cert_out</b> and
1131 * *<b>id_cert_out</b> respectively. Log all messages at level
1132 * <b>severity</b>.
1134 * Note that a reference is added to cert_out, so it needs to be
1135 * freed. id_cert_out doesn't. */
1136 static void
1137 try_to_extract_certs_from_tls(int severity, tor_tls_t *tls,
1138 X509 **cert_out, X509 **id_cert_out)
1140 X509 *cert = NULL, *id_cert = NULL;
1141 STACK_OF(X509) *chain = NULL;
1142 int num_in_chain, i;
1143 *cert_out = *id_cert_out = NULL;
1145 if (!(cert = SSL_get_peer_certificate(tls->ssl)))
1146 return;
1147 *cert_out = cert;
1148 if (!(chain = SSL_get_peer_cert_chain(tls->ssl)))
1149 return;
1150 num_in_chain = sk_X509_num(chain);
1151 /* 1 means we're receiving (server-side), and it's just the id_cert.
1152 * 2 means we're connecting (client-side), and it's both the link
1153 * cert and the id_cert.
1155 if (num_in_chain < 1) {
1156 log_fn(severity,LD_PROTOCOL,
1157 "Unexpected number of certificates in chain (%d)",
1158 num_in_chain);
1159 return;
1161 for (i=0; i<num_in_chain; ++i) {
1162 id_cert = sk_X509_value(chain, i);
1163 if (X509_cmp(id_cert, cert) != 0)
1164 break;
1166 *id_cert_out = id_cert;
1169 /** If the provided tls connection is authenticated and has a
1170 * certificate chain that is currently valid and signed, then set
1171 * *<b>identity_key</b> to the identity certificate's key and return
1172 * 0. Else, return -1 and log complaints with log-level <b>severity</b>.
1175 tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_env_t **identity_key)
1177 X509 *cert = NULL, *id_cert = NULL;
1178 EVP_PKEY *id_pkey = NULL;
1179 RSA *rsa;
1180 int r = -1;
1182 *identity_key = NULL;
1184 try_to_extract_certs_from_tls(severity, tls, &cert, &id_cert);
1185 if (!cert)
1186 goto done;
1187 if (!id_cert) {
1188 log_fn(severity,LD_PROTOCOL,"No distinct identity certificate found");
1189 goto done;
1191 if (!(id_pkey = X509_get_pubkey(id_cert)) ||
1192 X509_verify(cert, id_pkey) <= 0) {
1193 log_fn(severity,LD_PROTOCOL,"X509_verify on cert and pkey returned <= 0");
1194 tls_log_errors(tls, severity,"verifying certificate");
1195 goto done;
1198 rsa = EVP_PKEY_get1_RSA(id_pkey);
1199 if (!rsa)
1200 goto done;
1201 *identity_key = _crypto_new_pk_env_rsa(rsa);
1203 r = 0;
1205 done:
1206 if (cert)
1207 X509_free(cert);
1208 if (id_pkey)
1209 EVP_PKEY_free(id_pkey);
1211 /* This should never get invoked, but let's make sure in case OpenSSL
1212 * acts unexpectedly. */
1213 tls_log_errors(tls, LOG_WARN, "finishing tor_tls_verify");
1215 return r;
1218 /** Check whether the certificate set on the connection <b>tls</b> is
1219 * expired or not-yet-valid, give or take <b>tolerance</b>
1220 * seconds. Return 0 for valid, -1 for failure.
1222 * NOTE: you should call tor_tls_verify before tor_tls_check_lifetime.
1225 tor_tls_check_lifetime(tor_tls_t *tls, int tolerance)
1227 time_t now, t;
1228 X509 *cert;
1229 int r = -1;
1231 now = time(NULL);
1233 if (!(cert = SSL_get_peer_certificate(tls->ssl)))
1234 goto done;
1236 t = now + tolerance;
1237 if (X509_cmp_time(X509_get_notBefore(cert), &t) > 0) {
1238 log_cert_lifetime(cert, "not yet valid");
1239 goto done;
1241 t = now - tolerance;
1242 if (X509_cmp_time(X509_get_notAfter(cert), &t) < 0) {
1243 log_cert_lifetime(cert, "already expired");
1244 goto done;
1247 r = 0;
1248 done:
1249 if (cert)
1250 X509_free(cert);
1251 /* Not expected to get invoked */
1252 tls_log_errors(tls, LOG_WARN, "checking certificate lifetime");
1254 return r;
1257 /** Return the number of bytes available for reading from <b>tls</b>.
1260 tor_tls_get_pending_bytes(tor_tls_t *tls)
1262 tor_assert(tls);
1263 return SSL_pending(tls->ssl);
1266 /** If <b>tls</b> requires that the next write be of a particular size,
1267 * return that size. Otherwise, return 0. */
1268 size_t
1269 tor_tls_get_forced_write_size(tor_tls_t *tls)
1271 return tls->wantwrite_n;
1274 /** Sets n_read and n_written to the number of bytes read and written,
1275 * respectivey, on the raw socket used by <b>tls</b> since the last time this
1276 * function was called on <b>tls</b>. */
1277 void
1278 tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written)
1280 unsigned long r, w;
1281 r = BIO_number_read(SSL_get_rbio(tls->ssl));
1282 w = BIO_number_written(SSL_get_wbio(tls->ssl));
1284 /* We are ok with letting these unsigned ints go "negative" here:
1285 * If we wrapped around, this should still give us the right answer, unless
1286 * we wrapped around by more than ULONG_MAX since the last time we called
1287 * this function.
1290 *n_read = (size_t)(r - tls->last_read_count);
1291 *n_written = (size_t)(w - tls->last_write_count);
1292 tls->last_read_count = r;
1293 tls->last_write_count = w;
1296 /** Implement check_no_tls_errors: If there are any pending OpenSSL
1297 * errors, log an error message. */
1298 void
1299 _check_no_tls_errors(const char *fname, int line)
1301 if (ERR_peek_error() == 0)
1302 return;
1303 log(LOG_WARN, LD_CRYPTO, "Unhandled OpenSSL errors found at %s:%d: ",
1304 tor_fix_source_file(fname), line);
1305 tls_log_errors(NULL, LOG_WARN, NULL);
1308 /** Return true iff the initial TLS connection at <b>tls</b> did not use a v2
1309 * TLS handshake. Output undefined if the handshake isn't finished. */
1311 tor_tls_used_v1_handshake(tor_tls_t *tls)
1313 if (tls->isServer) {
1314 #ifdef V2_HANDSHAKE_SERVER
1315 return ! tls->wasV2Handshake;
1316 #endif
1317 } else {
1318 #ifdef V2_HANDSHAKE_CLIENT
1319 return ! tls->wasV2Handshake;
1320 #endif
1322 return 1;