Forward port changelog
[tor.git] / src / common / tortls.c
blob86cdcec48ffb18ee5db66bf53f8b5820a1bd7f4a
1 /* Copyright 2003 Roger Dingledine. */
2 /* See LICENSE for licensing information */
3 /* $Id$ */
4 const char tortls_c_id[] = "$Id$";
6 /**
7 * \file tortls.c
9 * \brief TLS wrappers for Tor.
10 **/
11 /* (Unlike other tor functions, these
12 * are prefixed with tor_ in order to avoid conflicting with OpenSSL
13 * functions and variables.)
16 #include "./crypto.h"
17 #include "./tortls.h"
18 #include "./util.h"
19 #include "./log.h"
20 #include <string.h>
22 /* Copied from or.h */
23 #define LEGAL_NICKNAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
25 #include <assert.h>
26 #include <openssl/ssl.h>
27 #include <openssl/err.h>
28 #include <openssl/tls1.h>
29 #include <openssl/asn1.h>
30 #include <openssl/bio.h>
32 /** How long do identity certificates live? (sec) */
33 #define IDENTITY_CERT_LIFETIME (365*24*60*60)
35 typedef struct tor_tls_context_st {
36 SSL_CTX *ctx;
37 SSL_CTX *client_only_ctx;
38 } tor_tls_context;
40 /** Holds a SSL object and its associated data. Members are only
41 * accessed from within tortls.c.
43 struct tor_tls_st {
44 SSL *ssl; /**< An OpenSSL SSL object. */
45 int socket; /**< The underlying file descriptor for this TLS connection. */
46 enum {
47 TOR_TLS_ST_HANDSHAKE, TOR_TLS_ST_OPEN, TOR_TLS_ST_GOTCLOSE,
48 TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED
49 } state; /**< The current SSL state, depending on which operations have
50 * completed successfully. */
51 int isServer;
52 size_t wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last time. */
55 static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
56 crypto_pk_env_t *rsa_sign,
57 const char *cname,
58 const char *cname_sign,
59 unsigned int lifetime);
61 /** Global tls context. We keep it here because nobody else needs to
62 * touch it. */
63 static tor_tls_context *global_tls_context = NULL;
64 /** True iff tor_tls_init() has been called. */
65 static int tls_library_is_initialized = 0;
67 /* Module-internal error codes. */
68 #define _TOR_TLS_SYSCALL -6
69 #define _TOR_TLS_ZERORETURN -5
71 /* These functions are declared in crypto.c but not exported. */
72 EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private);
73 crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa);
74 DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh);
76 /** Log all pending tls errors at level <b>severity</b>. Use
77 * <b>doing</b> to describe our current activities.
79 static void
80 tls_log_errors(int severity, const char *doing)
82 int err;
83 const char *msg, *lib, *func;
84 while ((err = ERR_get_error()) != 0) {
85 msg = (const char*)ERR_reason_error_string(err);
86 lib = (const char*)ERR_lib_error_string(err);
87 func = (const char*)ERR_func_error_string(err);
88 if (!msg) msg = "(null)";
89 if (doing) {
90 log(severity, "TLS error while %s: %s (in %s:%s)", doing, msg, lib,func);
91 } else {
92 log(severity, "TLS error: %s (in %s:%s)", msg, lib, func);
97 #define CATCH_SYSCALL 1
98 #define CATCH_ZERO 2
100 /** Given a TLS object and the result of an SSL_* call, use
101 * SSL_get_error to determine whether an error has occurred, and if so
102 * which one. Return one of TOR_TLS_{DONE|WANTREAD|WANTWRITE|ERROR}.
103 * If extra&CATCH_SYSCALL is true, return _TOR_TLS_SYSCALL instead of
104 * reporting syscall errors. If extra&CATCH_ZERO is true, return
105 * _TOR_TLS_ZERORETURN instead of reporting zero-return errors.
107 * If an error has occurred, log it at level <b>severity</b> and describe the
108 * current action as <b>doing</b>.
110 static int
111 tor_tls_get_error(tor_tls *tls, int r, int extra,
112 const char *doing, int severity)
114 int err = SSL_get_error(tls->ssl, r);
115 switch (err) {
116 case SSL_ERROR_NONE:
117 return TOR_TLS_DONE;
118 case SSL_ERROR_WANT_READ:
119 return TOR_TLS_WANTREAD;
120 case SSL_ERROR_WANT_WRITE:
121 return TOR_TLS_WANTWRITE;
122 case SSL_ERROR_SYSCALL:
123 if (extra&CATCH_SYSCALL)
124 return _TOR_TLS_SYSCALL;
125 if (r == 0)
126 log(severity, "TLS error: unexpected close while %s", doing);
127 else {
128 int e = tor_socket_errno(tls->socket);
129 log(severity, "TLS error: <syscall error while %s> (errno=%d: %s)",
130 doing, e, tor_socket_strerror(e));
132 tls_log_errors(severity, doing);
133 return TOR_TLS_ERROR;
134 case SSL_ERROR_ZERO_RETURN:
135 if (extra&CATCH_ZERO)
136 return _TOR_TLS_ZERORETURN;
137 log(severity, "TLS error: Zero return");
138 tls_log_errors(severity, doing);
139 return TOR_TLS_ERROR;
140 default:
141 tls_log_errors(severity, doing);
142 return TOR_TLS_ERROR;
146 /** Initialize OpenSSL, unless it has already been initialized.
148 static void
149 tor_tls_init(void) {
150 if (!tls_library_is_initialized) {
151 SSL_library_init();
152 SSL_load_error_strings();
153 crypto_global_init();
154 OpenSSL_add_all_algorithms();
155 tls_library_is_initialized = 1;
159 /** We need to give OpenSSL a callback to verify certificates. This is
160 * it: We always accept peer certs and complete the handshake. We
161 * don't validate them until later.
163 static int always_accept_verify_cb(int preverify_ok,
164 X509_STORE_CTX *x509_ctx)
166 return 1;
169 /** Generate and sign an X509 certificate with the public key <b>rsa</b>,
170 * signed by the private key <b>rsa_sign</b>. The commonName of the
171 * certificate will be <b>cname</b>; the commonName of the issuer will be
172 * <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
173 * starting from now. Return a certificate on success, NULL on
174 * failure.
176 static X509 *
177 tor_tls_create_certificate(crypto_pk_env_t *rsa,
178 crypto_pk_env_t *rsa_sign,
179 const char *cname,
180 const char *cname_sign,
181 unsigned int cert_lifetime)
183 time_t start_time, end_time;
184 EVP_PKEY *sign_pkey = NULL, *pkey=NULL;
185 X509 *x509 = NULL;
186 X509_NAME *name = NULL, *name_issuer=NULL;
187 int nid;
189 tor_tls_init();
191 start_time = time(NULL);
193 tor_assert(rsa);
194 tor_assert(cname);
195 tor_assert(rsa_sign);
196 tor_assert(cname_sign);
197 if (!(sign_pkey = _crypto_pk_env_get_evp_pkey(rsa_sign,1)))
198 goto error;
199 if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0)))
200 goto error;
201 if (!(x509 = X509_new()))
202 goto error;
203 if (!(X509_set_version(x509, 2)))
204 goto error;
205 if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509), (long)start_time)))
206 goto error;
208 if (!(name = X509_NAME_new()))
209 goto error;
210 if ((nid = OBJ_txt2nid("organizationName")) == NID_undef) goto error;
211 if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
212 (char*)"TOR", -1, -1, 0))) goto error;
213 if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
214 if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
215 (char*)cname, -1, -1, 0))) goto error;
216 if (!(X509_set_subject_name(x509, name)))
217 goto error;
219 if (!(name_issuer = X509_NAME_new()))
220 goto error;
221 if ((nid = OBJ_txt2nid("organizationName")) == NID_undef) goto error;
222 if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC,
223 (char*)"TOR", -1, -1, 0))) goto error;
224 if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
225 if (!(X509_NAME_add_entry_by_NID(name_issuer, nid, MBSTRING_ASC,
226 (char*)cname_sign, -1, -1, 0))) goto error;
227 if (!(X509_set_issuer_name(x509, name_issuer)))
228 goto error;
230 if (!X509_time_adj(X509_get_notBefore(x509),0,&start_time))
231 goto error;
232 end_time = start_time + cert_lifetime;
233 if (!X509_time_adj(X509_get_notAfter(x509),0,&end_time))
234 goto error;
235 if (!X509_set_pubkey(x509, pkey))
236 goto error;
237 if (!X509_sign(x509, sign_pkey, EVP_sha1()))
238 goto error;
240 goto done;
241 error:
242 tls_log_errors(LOG_WARN, "generating certificate");
243 if (x509) {
244 X509_free(x509);
245 x509 = NULL;
247 done:
248 if (sign_pkey)
249 EVP_PKEY_free(sign_pkey);
250 if (pkey)
251 EVP_PKEY_free(pkey);
252 if (name)
253 X509_NAME_free(name);
254 if (name_issuer)
255 X509_NAME_free(name_issuer);
256 return x509;
259 #ifdef EVERYONE_HAS_AES
260 /* Everybody is running OpenSSL 0.9.7 or later, so no backward compatibility
261 * is needed. */
262 #define CIPHER_LIST TLS1_TXT_DHE_RSA_WITH_AES_128_SHA
263 #elif defined(TLS1_TXT_DHE_RSA_WITH_AES_128_SHA)
264 /* Some people are running OpenSSL before 0.9.7, but we aren't.
265 * We can support AES and 3DES.
267 #define CIPHER_LIST (TLS1_TXT_DHE_RSA_WITH_AES_128_SHA ":" \
268 SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA)
269 #else
270 /* We're running OpenSSL before 0.9.7. We only support 3DES. */
271 #define CIPHER_LIST SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA
272 #endif
274 /** Create a new TLS context. If we are going to be using it as a
275 * server, it must have isServer set to true, <b>identity</b> set to the
276 * identity key used to sign that certificate, and <b>nickname</b> set to
277 * the server's nickname. If we're only going to be a client,
278 * isServer should be false, identity should be NULL, and nickname
279 * should be NULL. Return -1 if failure, else 0.
281 * You can call this function multiple times. Each time you call it,
282 * it generates new certificates; all new connections will use
283 * the new SSL context.
286 tor_tls_context_new(crypto_pk_env_t *identity,
287 int isServer, const char *nickname,
288 unsigned int key_lifetime)
290 crypto_pk_env_t *rsa = NULL;
291 crypto_dh_env_t *dh = NULL;
292 EVP_PKEY *pkey = NULL;
293 tor_tls_context *result = NULL;
294 X509 *cert = NULL, *idcert = NULL;
295 char nn2[128];
296 int client_only;
297 SSL_CTX **ctx;
298 if (!nickname)
299 nickname = "null";
300 tor_snprintf(nn2, sizeof(nn2), "%s <identity>", nickname);
302 tor_tls_init();
304 if (isServer) {
305 /* Generate short-term RSA key. */
306 if (!(rsa = crypto_new_pk_env()))
307 goto error;
308 if (crypto_pk_generate_key(rsa)<0)
309 goto error;
310 /* Create certificate signed by identity key. */
311 cert = tor_tls_create_certificate(rsa, identity, nickname, nn2,
312 key_lifetime);
313 /* Create self-signed certificate for identity key. */
314 idcert = tor_tls_create_certificate(identity, identity, nn2, nn2,
315 IDENTITY_CERT_LIFETIME);
316 if (!cert || !idcert) {
317 log(LOG_WARN, "Error creating certificate");
318 goto error;
322 result = tor_malloc(sizeof(tor_tls_context));
323 result->ctx = result->client_only_ctx = NULL;
324 for (client_only=0; client_only <= 1; ++client_only) {
325 ctx = client_only ? &result->client_only_ctx : &result->ctx;
326 #ifdef EVERYONE_HAS_AES
327 /* Tell OpenSSL to only use TLS1 */
328 if (!(*ctx = SSL_CTX_new(TLSv1_method())))
329 goto error;
330 #else
331 /* Tell OpenSSL to use SSL3 or TLS1 but not SSL2. */
332 if (!(*ctx = SSL_CTX_new(SSLv23_method())))
333 goto error;
334 SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
335 #endif
336 if (!SSL_CTX_set_cipher_list(*ctx, CIPHER_LIST))
337 goto error;
338 if (!client_only) {
339 if (cert && !SSL_CTX_use_certificate(*ctx,cert))
340 goto error;
341 X509_free(cert); /* We just added a reference to cert. */
342 cert=NULL;
343 if (idcert && !SSL_CTX_add_extra_chain_cert(*ctx,idcert))
344 goto error;
345 idcert=NULL; /* The context now owns the reference to idcert */
347 SSL_CTX_set_session_cache_mode(*ctx, SSL_SESS_CACHE_OFF);
348 if (isServer && !client_only) {
349 tor_assert(rsa);
350 if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
351 goto error;
352 if (!SSL_CTX_use_PrivateKey(*ctx, pkey))
353 goto error;
354 EVP_PKEY_free(pkey);
355 pkey = NULL;
356 if (!SSL_CTX_check_private_key(*ctx))
357 goto error;
359 dh = crypto_dh_new();
360 SSL_CTX_set_tmp_dh(*ctx, _crypto_dh_env_get_dh(dh));
361 crypto_dh_free(dh);
362 SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER,
363 always_accept_verify_cb);
364 /* let us realloc bufs that we're writing from */
365 SSL_CTX_set_mode(*ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
367 /* Free the old context if one exists. */
368 if (global_tls_context) {
369 /* This is safe even if there are open connections: OpenSSL does
370 * reference counting with SSL and SSL_CTX objects. */
371 SSL_CTX_free(global_tls_context->ctx);
372 SSL_CTX_free(global_tls_context->client_only_ctx);
373 tor_free(global_tls_context);
375 global_tls_context = result;
376 if (rsa)
377 crypto_free_pk_env(rsa);
378 return 0;
380 error:
381 tls_log_errors(LOG_WARN, "creating TLS context");
382 if (pkey)
383 EVP_PKEY_free(pkey);
384 if (rsa)
385 crypto_free_pk_env(rsa);
386 if (dh)
387 crypto_dh_free(dh);
388 if (result && result->ctx)
389 SSL_CTX_free(result->ctx);
390 if (result && result->client_only_ctx)
391 SSL_CTX_free(result->client_only_ctx);
392 if (result)
393 free(result);
394 if (cert)
395 X509_free(cert);
396 if (idcert)
397 X509_free(idcert);
398 return -1;
401 /** Create a new TLS object from a file descriptor, and a flag to
402 * determine whether it is functioning as a server.
404 tor_tls *
405 tor_tls_new(int sock, int isServer, int use_no_cert)
407 tor_tls *result = tor_malloc(sizeof(tor_tls));
408 SSL_CTX *ctx;
409 tor_assert(global_tls_context); /* make sure somebody made it first */
410 ctx = use_no_cert ? global_tls_context->client_only_ctx
411 : global_tls_context->ctx;
412 if (!(result->ssl = SSL_new(ctx)))
413 return NULL;
414 result->socket = sock;
415 SSL_set_fd(result->ssl, sock);
416 result->state = TOR_TLS_ST_HANDSHAKE;
417 result->isServer = isServer;
418 result->wantwrite_n = 0;
419 return result;
422 /** Release resources associated with a TLS object. Does not close the
423 * underlying file descriptor.
425 void
426 tor_tls_free(tor_tls *tls)
428 SSL_free(tls->ssl);
429 free(tls);
432 /** Underlying function for TLS reading. Reads up to <b>len</b>
433 * characters from <b>tls</b> into <b>cp</b>. On success, returns the
434 * number of characters read. On failure, returns TOR_TLS_ERROR,
435 * TOR_TLS_CLOSE, TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
438 tor_tls_read(tor_tls *tls, char *cp, size_t len)
440 int r, err;
441 tor_assert(tls);
442 tor_assert(tls->ssl);
443 tor_assert(tls->state == TOR_TLS_ST_OPEN);
444 r = SSL_read(tls->ssl, cp, len);
445 if (r > 0)
446 return r;
447 err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_INFO);
448 if (err == _TOR_TLS_ZERORETURN) {
449 log_fn(LOG_DEBUG,"read returned r=%d; TLS is closed",r);
450 tls->state = TOR_TLS_ST_CLOSED;
451 return TOR_TLS_CLOSE;
452 } else {
453 tor_assert(err != TOR_TLS_DONE);
454 log_fn(LOG_DEBUG,"read returned r=%d, err=%d",r,err);
455 return err;
459 /** Underlying function for TLS writing. Write up to <b>n</b>
460 * characters from <b>cp</b> onto <b>tls</b>. On success, returns the
461 * number of characters written. On failure, returns TOR_TLS_ERROR,
462 * TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
465 tor_tls_write(tor_tls *tls, char *cp, size_t n)
467 int r, err;
468 tor_assert(tls);
469 tor_assert(tls->ssl);
470 tor_assert(tls->state == TOR_TLS_ST_OPEN);
471 if (n == 0)
472 return 0;
473 if (tls->wantwrite_n) {
474 /* if WANTWRITE last time, we must use the _same_ n as before */
475 tor_assert(n >= tls->wantwrite_n);
476 log_fn(LOG_DEBUG,"resuming pending-write, (%d to flush, reusing %d)",
477 (int)n, (int)tls->wantwrite_n);
478 n = tls->wantwrite_n;
479 tls->wantwrite_n = 0;
481 r = SSL_write(tls->ssl, cp, n);
482 err = tor_tls_get_error(tls, r, 0, "writing", LOG_INFO);
483 if (err == TOR_TLS_DONE) {
484 return r;
486 if (err == TOR_TLS_WANTWRITE || err == TOR_TLS_WANTREAD) {
487 tls->wantwrite_n = n;
489 return err;
492 /** Perform initial handshake on <b>tls</b>. When finished, returns
493 * TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
494 * or TOR_TLS_WANTWRITE.
497 tor_tls_handshake(tor_tls *tls)
499 int r;
500 tor_assert(tls);
501 tor_assert(tls->ssl);
502 tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
503 if (tls->isServer) {
504 r = SSL_accept(tls->ssl);
505 } else {
506 r = SSL_connect(tls->ssl);
508 r = tor_tls_get_error(tls,r,0, "handshaking", LOG_INFO);
509 if (r == TOR_TLS_DONE) {
510 tls->state = TOR_TLS_ST_OPEN;
512 return r;
515 /** Shut down an open tls connection <b>tls</b>. When finished, returns
516 * TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
517 * or TOR_TLS_WANTWRITE.
520 tor_tls_shutdown(tor_tls *tls)
522 int r, err;
523 char buf[128];
524 tor_assert(tls);
525 tor_assert(tls->ssl);
527 while (1) {
528 if (tls->state == TOR_TLS_ST_SENTCLOSE) {
529 /* If we've already called shutdown once to send a close message,
530 * we read until the other side has closed too.
532 do {
533 r = SSL_read(tls->ssl, buf, 128);
534 } while (r>0);
535 err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading to shut down",
536 LOG_INFO);
537 if (err == _TOR_TLS_ZERORETURN) {
538 tls->state = TOR_TLS_ST_GOTCLOSE;
539 /* fall through... */
540 } else {
541 return err;
545 r = SSL_shutdown(tls->ssl);
546 if (r == 1) {
547 /* If shutdown returns 1, the connection is entirely closed. */
548 tls->state = TOR_TLS_ST_CLOSED;
549 return TOR_TLS_DONE;
551 err = tor_tls_get_error(tls, r, CATCH_SYSCALL|CATCH_ZERO, "shutting down",
552 LOG_INFO);
553 if (err == _TOR_TLS_SYSCALL) {
554 /* The underlying TCP connection closed while we were shutting down. */
555 tls->state = TOR_TLS_ST_CLOSED;
556 return TOR_TLS_DONE;
557 } else if (err == _TOR_TLS_ZERORETURN) {
558 /* The TLS connection says that it sent a shutdown record, but
559 * isn't done shutting down yet. Make sure that this hasn't
560 * happened before, then go back to the start of the function
561 * and try to read.
563 if (tls->state == TOR_TLS_ST_GOTCLOSE ||
564 tls->state == TOR_TLS_ST_SENTCLOSE) {
565 log(LOG_WARN,
566 "TLS returned \"half-closed\" value while already half-closed");
567 return TOR_TLS_ERROR;
569 tls->state = TOR_TLS_ST_SENTCLOSE;
570 /* fall through ... */
571 } else {
572 return err;
574 } /* end loop */
577 /** Return true iff this TLS connection is authenticated.
580 tor_tls_peer_has_cert(tor_tls *tls)
582 X509 *cert;
583 if (!(cert = SSL_get_peer_certificate(tls->ssl)))
584 return 0;
585 X509_free(cert);
586 return 1;
589 /** Write the nickname (if any) that the peer connected on <b>tls</b>
590 * claims to have into the first <b>buflen</b> characters of <b>buf</b>.
591 * Truncate the nickname if it is longer than buflen-1 characters. Always
592 * NUL-terminate. Return 0 on success, -1 on failure.
595 tor_tls_get_peer_cert_nickname(tor_tls *tls, char *buf, size_t buflen)
597 X509 *cert = NULL;
598 X509_NAME *name = NULL;
599 int nid;
600 int lenout;
602 if (!(cert = SSL_get_peer_certificate(tls->ssl))) {
603 log_fn(LOG_WARN, "Peer has no certificate");
604 goto error;
606 if (!(name = X509_get_subject_name(cert))) {
607 log_fn(LOG_WARN, "Peer certificate has no subject name");
608 goto error;
610 if ((nid = OBJ_txt2nid("commonName")) == NID_undef)
611 goto error;
613 lenout = X509_NAME_get_text_by_NID(name, nid, buf, buflen);
614 if (lenout == -1)
615 goto error;
616 if (((int)strspn(buf, LEGAL_NICKNAME_CHARACTERS)) < lenout) {
617 log_fn(LOG_WARN, "Peer certificate nickname has illegal characters.");
618 goto error;
620 X509_free(cert);
622 return 0;
623 error:
624 if (cert)
625 X509_free(cert);
626 return -1;
629 static void log_cert_lifetime(X509 *cert, const char *problem)
631 BIO *bio = NULL;
632 BUF_MEM *buf;
633 char *s1=NULL, *s2=NULL;
634 char mytime[33];
635 time_t now = time(NULL);
637 if (problem)
638 log_fn(LOG_WARN,"Certificate %s: is your system clock set incorrectly?",
639 problem);
641 if (!(bio = BIO_new(BIO_s_mem()))) {
642 log_fn(LOG_WARN, "Couldn't allocate BIO!"); goto end;
644 if (!(ASN1_TIME_print(bio, X509_get_notBefore(cert)))) {
645 tls_log_errors(LOG_WARN, "printing certificate lifetime");
646 goto end;
648 BIO_get_mem_ptr(bio, &buf);
649 s1 = tor_strndup(buf->data, buf->length);
651 BIO_reset(bio);
652 if (!(ASN1_TIME_print(bio, X509_get_notAfter(cert)))) {
653 tls_log_errors(LOG_WARN, "printing certificate lifetime");
654 goto end;
656 BIO_get_mem_ptr(bio, &buf);
657 s2 = tor_strndup(buf->data, buf->length);
659 strftime(mytime, 32, "%b %d %H:%M:%S %Y GMT", gmtime(&now));
661 log_fn(LOG_WARN, "(certificate lifetime runs from %s through %s. Your time is %s.)",s1,s2,mytime);
663 end:
664 if (bio)
665 BIO_free(bio);
666 if (s1)
667 tor_free(s1);
668 if (s2)
669 tor_free(s2);
672 /** If the provided tls connection is authenticated and has a
673 * certificate that is currently valid and signed, then set
674 * *<b>identity_key</b> to the identity certificate's key and return
675 * 0. Else, return -1.
678 tor_tls_verify(tor_tls *tls, crypto_pk_env_t **identity_key)
680 X509 *cert = NULL, *id_cert = NULL;
681 STACK_OF(X509) *chain = NULL;
682 EVP_PKEY *id_pkey = NULL;
683 RSA *rsa;
684 int num_in_chain;
685 int r = -1, i;
687 *identity_key = NULL;
689 if (!(cert = SSL_get_peer_certificate(tls->ssl)))
690 goto done;
691 if (!(chain = SSL_get_peer_cert_chain(tls->ssl)))
692 goto done;
693 num_in_chain = sk_X509_num(chain);
694 /* 1 means we're receiving (server-side), and it's just the id_cert.
695 * 2 means we're connecting (client-side), and it's both the link
696 * cert and the id_cert.
698 if (num_in_chain < 1) {
699 log_fn(LOG_WARN,"Unexpected number of certificates in chain (%d)",
700 num_in_chain);
701 goto done;
703 for (i=0; i<num_in_chain; ++i) {
704 id_cert = sk_X509_value(chain, i);
705 if (X509_cmp(id_cert, cert) != 0)
706 break;
708 if (!id_cert) {
709 log_fn(LOG_WARN,"No distinct identity certificate found");
710 goto done;
713 if (!(id_pkey = X509_get_pubkey(id_cert)) ||
714 X509_verify(cert, id_pkey) <= 0) {
715 log_fn(LOG_WARN,"X509_verify on cert and pkey returned <= 0");
716 tls_log_errors(LOG_WARN,"verifying certificate");
717 goto done;
720 rsa = EVP_PKEY_get1_RSA(id_pkey);
721 if (!rsa)
722 goto done;
723 *identity_key = _crypto_new_pk_env_rsa(rsa);
725 r = 0;
727 done:
728 if (cert)
729 X509_free(cert);
730 if (id_pkey)
731 EVP_PKEY_free(id_pkey);
733 /* This should never get invoked, but let's make sure in case OpenSSL
734 * acts unexpectedly. */
735 tls_log_errors(LOG_WARN, "finishing tor_tls_verify");
737 return r;
740 /** Check whether the certificate set on the connection <b>tls</b> is
741 * expired or not-yet-valid, give or take <b>tolerance</b>
742 * seconds. Return 0 for valid, -1 for failure.
744 * NOTE: you should call tor_tls_verify before tor_tls_check_lifetime.
747 tor_tls_check_lifetime(tor_tls *tls, int tolerance)
749 time_t now, t;
750 X509 *cert;
751 int r = -1;
753 now = time(NULL);
755 if (!(cert = SSL_get_peer_certificate(tls->ssl)))
756 goto done;
758 t = now + tolerance;
759 if (X509_cmp_time(X509_get_notBefore(cert), &t) > 0) {
760 log_cert_lifetime(cert, "not yet valid");
761 goto done;
763 t = now - tolerance;
764 if (X509_cmp_time(X509_get_notAfter(cert), &t) < 0) {
765 log_cert_lifetime(cert, "already expired");
766 goto done;
769 r = 0;
770 done:
771 if (cert)
772 X509_free(cert);
774 return r;
777 /** Return the number of bytes available for reading from <b>tls</b>.
780 tor_tls_get_pending_bytes(tor_tls *tls)
782 tor_assert(tls);
783 #if OPENSSL_VERSION_NUMBER < 0x0090700fl
784 if (tls->ssl->rstate == SSL_ST_READ_BODY)
785 return 0;
786 if (tls->ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA)
787 return 0;
788 #endif
789 return SSL_pending(tls->ssl);
793 /** Return the number of bytes read across the underlying socket. */
794 unsigned long tor_tls_get_n_bytes_read(tor_tls *tls)
796 tor_assert(tls);
797 return BIO_number_read(SSL_get_rbio(tls->ssl));
799 /** Return the number of bytes written across the underlying socket. */
800 unsigned long tor_tls_get_n_bytes_written(tor_tls *tls)
802 tor_assert(tls);
803 return BIO_number_written(SSL_get_wbio(tls->ssl));
806 /** Implement assert_no_tls_errors: If there are any pending OpenSSL
807 * errors, log an error message and assert(0). */
808 void _assert_no_tls_errors(const char *fname, int line)
810 if (ERR_peek_error() == 0)
811 return;
812 log_fn(LOG_ERR, "Unhandled OpenSSL errors found at %s:%d: ",
813 fname, line);
814 tls_log_errors(LOG_ERR, NULL);
816 tor_assert(0);