tor  0.4.2.0-alpha-dev
tortls_nss.c
Go to the documentation of this file.
1 /* Copyright (c) 2003, Roger Dingledine.
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
12 #include "orconfig.h"
13 
14 #define TORTLS_PRIVATE
15 #define TOR_X509_PRIVATE
16 
17 #ifdef _WIN32
18  #include <winsock2.h>
19  #include <ws2tcpip.h>
20 #endif
21 
27 #include "lib/string/printf.h"
28 
29 #include "lib/tls/x509.h"
30 #include "lib/tls/x509_internal.h"
31 #include "lib/tls/tortls.h"
32 #include "lib/tls/tortls_st.h"
33 #include "lib/tls/tortls_internal.h"
34 #include "lib/tls/nss_countbytes.h"
35 #include "lib/log/util_bug.h"
36 
37 DISABLE_GCC_WARNING(strict-prototypes)
38 #include <prio.h>
39 // For access to rar sockets.
40 #include <private/pprio.h>
41 #include <ssl.h>
42 #include <sslt.h>
43 #include <sslproto.h>
44 #include <certt.h>
45 ENABLE_GCC_WARNING(strict-prototypes)
46 
47 static SECStatus always_accept_cert_cb(void *, PRFileDesc *, PRBool, PRBool);
48 
49 MOCK_IMPL(void,
50 try_to_extract_certs_from_tls,(int severity, tor_tls_t *tls,
51  tor_x509_cert_impl_t **cert_out,
52  tor_x509_cert_impl_t **id_cert_out))
53 {
54  tor_assert(tls);
55  tor_assert(cert_out);
56  tor_assert(id_cert_out);
57  (void) severity;
58 
59  *cert_out = *id_cert_out = NULL;
60 
61  CERTCertificate *peer = SSL_PeerCertificate(tls->ssl);
62  if (!peer)
63  return;
64  *cert_out = peer; /* Now owns pointer. */
65 
66  CERTCertList *chain = SSL_PeerCertificateChain(tls->ssl);
67  CERTCertListNode *c = CERT_LIST_HEAD(chain);
68  for (; !CERT_LIST_END(c, chain); c = CERT_LIST_NEXT(c)) {
69  if (CERT_CompareCerts(c->cert, peer) == PR_FALSE) {
70  *id_cert_out = CERT_DupCertificate(c->cert);
71  break;
72  }
73  }
74  CERT_DestroyCertList(chain);
75 }
76 
77 static bool
78 we_like_ssl_cipher(SSLCipherAlgorithm ca)
79 {
80  switch (ca) {
81  case ssl_calg_null: return false;
82  case ssl_calg_rc4: return false;
83  case ssl_calg_rc2: return false;
84  case ssl_calg_des: return false;
85  case ssl_calg_3des: return false; /* ???? */
86  case ssl_calg_idea: return false;
87  case ssl_calg_fortezza: return false;
88  case ssl_calg_camellia: return false;
89  case ssl_calg_seed: return false;
90 
91  case ssl_calg_aes: return true;
92  case ssl_calg_aes_gcm: return true;
93  case ssl_calg_chacha20: return true;
94  default: return true;
95  }
96 }
97 static bool
98 we_like_ssl_kea(SSLKEAType kt)
99 {
100  switch (kt) {
101  case ssl_kea_null: return false;
102  case ssl_kea_rsa: return false; /* ??? */
103  case ssl_kea_fortezza: return false;
104  case ssl_kea_ecdh_psk: return false;
105  case ssl_kea_dh_psk: return false;
106 
107  case ssl_kea_dh: return true;
108  case ssl_kea_ecdh: return true;
109  case ssl_kea_tls13_any: return true;
110 
111  case ssl_kea_size: return true; /* prevent a warning. */
112  default: return true;
113  }
114 }
115 
116 static bool
117 we_like_mac_algorithm(SSLMACAlgorithm ma)
118 {
119  switch (ma) {
120  case ssl_mac_null: return false;
121  case ssl_mac_md5: return false;
122  case ssl_hmac_md5: return false;
123 
124  case ssl_mac_sha: return true;
125  case ssl_hmac_sha: return true;
126  case ssl_hmac_sha256: return true;
127  case ssl_mac_aead: return true;
128  case ssl_hmac_sha384: return true;
129  default: return true;
130  }
131 }
132 
133 static bool
134 we_like_auth_type(SSLAuthType at)
135 {
136  switch (at) {
137  case ssl_auth_null: return false;
138  case ssl_auth_rsa_decrypt: return false;
139  case ssl_auth_dsa: return false;
140  case ssl_auth_kea: return false;
141 
142  case ssl_auth_ecdsa: return true;
143  case ssl_auth_ecdh_rsa: return true;
144  case ssl_auth_ecdh_ecdsa: return true;
145  case ssl_auth_rsa_sign: return true;
146  case ssl_auth_rsa_pss: return true;
147  case ssl_auth_psk: return true;
148  case ssl_auth_tls13_any: return true;
149 
150  case ssl_auth_size: return true; /* prevent a warning. */
151  default: return true;
152  }
153 }
154 
160 static bool
161 ciphersuite_has_nss_export_bug(const SSLCipherSuiteInfo *info)
162 {
163  /* For more information on the bug, see
164  https://bugzilla.mozilla.org/show_bug.cgi?id=1312976 */
165 
166  /* This bug only exists in TLS 1.2. */
167  if (info->authType == ssl_auth_tls13_any)
168  return false;
169 
170  /* Sadly, there's no way to get this information from the
171  * CipherSuiteInfo object itself other than by looking at the
172  * name. */
173  if (strstr(info->cipherSuiteName, "_SHA384") ||
174  strstr(info->cipherSuiteName, "_SHA512")) {
175  return true;
176  }
177 
178  return false;
179 }
180 
182 tor_tls_context_new(crypto_pk_t *identity,
183  unsigned int key_lifetime, unsigned flags, int is_client)
184 {
185  SECStatus s;
186  tor_assert(identity);
187 
188  tor_tls_init();
189 
190  tor_tls_context_t *ctx = tor_malloc_zero(sizeof(tor_tls_context_t));
191  ctx->refcnt = 1;
192 
193  if (! is_client) {
194  if (tor_tls_context_init_certificates(ctx, identity,
195  key_lifetime, flags) < 0) {
196  goto err;
197  }
198  }
199 
200  {
201  /* Create the "model" PRFileDesc that we will use to base others on. */
202  PRFileDesc *tcp = PR_NewTCPSocket();
203  if (!tcp)
204  goto err;
205 
206  ctx->ctx = SSL_ImportFD(NULL, tcp);
207  if (!ctx->ctx) {
208  PR_Close(tcp);
209  goto err;
210  }
211  }
212 
213  // Configure the certificate.
214  if (!is_client) {
215  s = SSL_ConfigServerCert(ctx->ctx,
216  ctx->my_link_cert->cert,
217  (SECKEYPrivateKey *)
218  crypto_pk_get_nss_privkey(ctx->link_key),
219  NULL, /* ExtraServerCertData */
220  0 /* DataLen */);
221  if (s != SECSuccess)
222  goto err;
223  }
224 
225  // We need a certificate from the other side.
226  if (is_client) {
227  // XXXX does this do anything?
228  s = SSL_OptionSet(ctx->ctx, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
229  if (s != SECSuccess)
230  goto err;
231  }
232 
233  // Always accept other side's cert; we'll check it ourselves in goofy
234  // tor ways.
235  s = SSL_AuthCertificateHook(ctx->ctx, always_accept_cert_cb, NULL);
236 
237  // We allow simultaneous read and write.
238  s = SSL_OptionSet(ctx->ctx, SSL_ENABLE_FDX, PR_TRUE);
239  if (s != SECSuccess)
240  goto err;
241  // XXXX SSL_ROLLBACK_DETECTION??
242  // XXXX SSL_ENABLE_ALPN??
243 
244  // Force client-mode or server_mode.
245  s = SSL_OptionSet(ctx->ctx,
246  is_client ? SSL_HANDSHAKE_AS_CLIENT : SSL_HANDSHAKE_AS_SERVER,
247  PR_TRUE);
248  if (s != SECSuccess)
249  goto err;
250 
251  // Disable everything before TLS 1.0; support everything else.
252  {
253  SSLVersionRange vrange;
254  memset(&vrange, 0, sizeof(vrange));
255  s = SSL_VersionRangeGetSupported(ssl_variant_stream, &vrange);
256  if (s != SECSuccess)
257  goto err;
258  if (vrange.min < SSL_LIBRARY_VERSION_TLS_1_0)
259  vrange.min = SSL_LIBRARY_VERSION_TLS_1_0;
260  s = SSL_VersionRangeSet(ctx->ctx, &vrange);
261  if (s != SECSuccess)
262  goto err;
263  }
264 
265  // Only support strong ciphers.
266  {
267  const PRUint16 *ciphers = SSL_GetImplementedCiphers();
268  const PRUint16 n_ciphers = SSL_GetNumImplementedCiphers();
269  PRUint16 i;
270  for (i = 0; i < n_ciphers; ++i) {
271  SSLCipherSuiteInfo info;
272  memset(&info, 0, sizeof(info));
273  s = SSL_GetCipherSuiteInfo(ciphers[i], &info, sizeof(info));
274  if (s != SECSuccess)
275  goto err;
276  if (BUG(info.cipherSuite != ciphers[i]))
277  goto err;
278  int disable = info.effectiveKeyBits < 128 ||
279  info.macBits < 128 ||
280  !we_like_ssl_cipher(info.symCipher) ||
281  !we_like_ssl_kea(info.keaType) ||
282  !we_like_mac_algorithm(info.macAlgorithm) ||
283  !we_like_auth_type(info.authType)/* Requires NSS 3.24 */;
284 
285  if (ciphersuite_has_nss_export_bug(&info)) {
286  /* SSL_ExportKeyingMaterial will fail; we can't use this cipher.
287  */
288  disable = 1;
289  }
290 
291  s = SSL_CipherPrefSet(ctx->ctx, ciphers[i],
292  disable ? PR_FALSE : PR_TRUE);
293  if (s != SECSuccess)
294  goto err;
295  }
296  }
297 
298  // Only use DH and ECDH keys once.
299  s = SSL_OptionSet(ctx->ctx, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
300  if (s != SECSuccess)
301  goto err;
302 
303  // don't cache sessions.
304  s = SSL_OptionSet(ctx->ctx, SSL_NO_CACHE, PR_TRUE);
305  if (s != SECSuccess)
306  goto err;
307 
308  // Enable DH.
309  s = SSL_OptionSet(ctx->ctx, SSL_ENABLE_SERVER_DHE, PR_TRUE);
310  if (s != SECSuccess)
311  goto err;
312 
313  // Set DH and ECDH groups.
314  SSLNamedGroup groups[] = {
315  ssl_grp_ec_curve25519,
316  ssl_grp_ec_secp256r1,
317  ssl_grp_ec_secp224r1,
318  ssl_grp_ffdhe_2048,
319  };
320  s = SSL_NamedGroupConfig(ctx->ctx, groups, ARRAY_LENGTH(groups));
321  if (s != SECSuccess)
322  goto err;
323 
324  // These features are off by default, so we don't need to disable them:
325  // Session tickets
326  // Renegotiation
327  // Compression
328 
329  goto done;
330  err:
332  ctx = NULL;
333  done:
334  return ctx;
335 }
336 
337 void
338 tor_tls_context_impl_free_(tor_tls_context_impl_t *ctx)
339 {
340  if (!ctx)
341  return;
342  PR_Close(ctx);
343 }
344 
345 void
346 tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz)
347 {
348  (void)tls;
349  (void)buf;
350  (void)sz;
351  // AFAICT, NSS doesn't expose its internal state.
352  buf[0]=0;
353 }
354 
355 void
357 {
359 }
360 
361 void
362 tls_log_errors(tor_tls_t *tls, int severity, int domain,
363  const char *doing)
364 {
365  /* This implementation is a little different for NSS than it is for OpenSSL
366  -- it logs the last error whether anything actually failed or not. So we
367  have to only call it when something has gone wrong and we have a real
368  error to report. */
369 
370  (void)tls;
371  PRErrorCode code = PORT_GetError();
372 
373  const char *addr = tls ? tls->address : NULL;
374  const char *string = PORT_ErrorToString(code);
375  const char *name = PORT_ErrorToName(code);
376  char buf[16];
377  if (!string)
378  string = "<unrecognized>";
379  if (!name) {
380  tor_snprintf(buf, sizeof(buf), "%d", code);
381  name = buf;
382  }
383 
384  const char *with = addr ? " with " : "";
385  addr = addr ? addr : "";
386  if (doing) {
387  log_fn(severity, domain, "TLS error %s while %s%s%s: %s",
388  name, doing, with, addr, string);
389  } else {
390  log_fn(severity, domain, "TLS error %s%s%s: %s", name, string,
391  with, addr);
392  }
393 }
394 
395 tor_tls_t *
396 tor_tls_new(tor_socket_t sock, int is_server)
397 {
398  (void)sock;
399  tor_tls_context_t *ctx = tor_tls_context_get(is_server);
400 
401  PRFileDesc *tcp = NULL;
402  if (SOCKET_OK(sock)) {
403  tcp = PR_ImportTCPSocket(sock);
404  } else {
405  tcp = PR_NewTCPSocket();
406  }
407 
408  if (!tcp)
409  return NULL;
410 
411  PRFileDesc *count = tor_wrap_prfiledesc_with_byte_counter(tcp);
412  if (! count)
413  return NULL;
414 
415  PRFileDesc *ssl = SSL_ImportFD(ctx->ctx, count);
416  if (!ssl) {
417  PR_Close(tcp);
418  return NULL;
419  }
420 
421  tor_tls_t *tls = tor_malloc_zero(sizeof(tor_tls_t));
422  tls->magic = TOR_TLS_MAGIC;
423  tls->context = ctx;
425  tls->ssl = ssl;
426  tls->socket = sock;
427  tls->state = TOR_TLS_ST_HANDSHAKE;
428  tls->isServer = !!is_server;
429 
430  if (!is_server) {
431  /* Set a random SNI */
432  char *fake_hostname = crypto_random_hostname(4,25, "www.",".com");
433  SSL_SetURL(tls->ssl, fake_hostname);
434  tor_free(fake_hostname);
435  }
436  SECStatus s = SSL_ResetHandshake(ssl, is_server ? PR_TRUE : PR_FALSE);
437  if (s != SECSuccess) {
438  tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "resetting handshake state");
439  }
440 
441  return tls;
442 }
443 
444 void
446  void (*cb)(tor_tls_t *, void *arg),
447  void *arg)
448 {
449  tor_assert(tls);
450  (void)cb;
451  (void)arg;
452 
453  /* We don't support renegotiation-based TLS with NSS. */
454 }
455 
460 void
462 {
463  if (! tls)
464  return;
465 
466  /* NSS doesn't have the equivalent of BIO_NO_CLOSE. If you replace the
467  * fd with something that's invalid, it causes a memory leak in PR_Close.
468  *
469  * If there were a way to put the PRFileDesc into the CLOSED state, that
470  * would prevent it from closing its fd -- but there doesn't seem to be a
471  * supported way to do that either.
472  *
473  * So instead: we make a new sacrificial socket, and replace the original
474  * socket with that one. This seems to be the best we can do, until we
475  * redesign the mainloop code enough to make this function unnecessary.
476  */
477  tor_socket_t sock =
478  tor_open_socket_nonblocking(AF_INET, SOCK_STREAM, IPPROTO_TCP);
479  if (! SOCKET_OK(sock)) {
480  log_warn(LD_NET, "Out of sockets when trying to shut down an NSS "
481  "connection");
482  return;
483  }
484 
485  PRFileDesc *tcp = PR_GetIdentitiesLayer(tls->ssl, PR_NSPR_IO_LAYER);
486  if (BUG(! tcp)) {
487  tor_close_socket(sock);
488  return;
489  }
490 
491  PR_ChangeFileDescNativeHandle(tcp, sock);
492  /* Tell our socket accounting layer that we don't own this socket any more:
493  * NSS is about to free it for us. */
495 }
496 
497 void
498 tor_tls_impl_free_(tor_tls_impl_t *tls)
499 {
500  // XXXX This will close the underlying fd, which our OpenSSL version does
501  // not do!
502  if (!tls)
503  return;
504 
505  PR_Close(tls);
506 }
507 
508 int
510 {
511  CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
512  int result = (cert != NULL);
513  CERT_DestroyCertificate(cert);
514  return result;
515 }
516 
517 MOCK_IMPL(tor_x509_cert_t *,
518 tor_tls_get_peer_cert,(tor_tls_t *tls))
519 {
520  CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
521  if (cert)
522  return tor_x509_cert_new(cert);
523  else
524  return NULL;
525 }
526 
527 MOCK_IMPL(tor_x509_cert_t *,
528 tor_tls_get_own_cert,(tor_tls_t *tls))
529 {
530  tor_assert(tls);
531  CERTCertificate *cert = SSL_LocalCertificate(tls->ssl);
532  if (cert)
533  return tor_x509_cert_new(cert);
534  else
535  return NULL;
536 }
537 
538 MOCK_IMPL(int,
539 tor_tls_read, (tor_tls_t *tls, char *cp, size_t len))
540 {
541  tor_assert(tls);
542  tor_assert(cp);
543  tor_assert(len < INT_MAX);
544 
545  PRInt32 rv = PR_Read(tls->ssl, cp, (int)len);
546  // log_debug(LD_NET, "PR_Read(%zu) returned %d", n, (int)rv);
547  if (rv > 0) {
548  return rv;
549  }
550  if (rv == 0)
551  return TOR_TLS_CLOSE;
552  PRErrorCode err = PORT_GetError();
553  if (err == PR_WOULD_BLOCK_ERROR) {
554  return TOR_TLS_WANTREAD; // XXXX ????
555  } else {
556  tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "reading"); // XXXX
557  return TOR_TLS_ERROR_MISC; // ????
558  }
559 }
560 
561 int
562 tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
563 {
564  tor_assert(tls);
565  tor_assert(cp || n == 0);
566  tor_assert(n < INT_MAX);
567 
568  PRInt32 rv = PR_Write(tls->ssl, cp, (int)n);
569  // log_debug(LD_NET, "PR_Write(%zu) returned %d", n, (int)rv);
570  if (rv > 0) {
571  return rv;
572  }
573  if (rv == 0)
574  return TOR_TLS_ERROR_MISC;
575  PRErrorCode err = PORT_GetError();
576 
577  if (err == PR_WOULD_BLOCK_ERROR) {
578  return TOR_TLS_WANTWRITE; // XXXX ????
579  } else {
580  tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "writing"); // XXXX
581  return TOR_TLS_ERROR_MISC; // ????
582  }
583 }
584 
585 int
587 {
588  tor_assert(tls);
589  tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
590 
591  SECStatus s = SSL_ForceHandshake(tls->ssl);
592  if (s == SECSuccess) {
593  tls->state = TOR_TLS_ST_OPEN;
594  log_debug(LD_NET, "SSL handshake is supposedly complete.");
595  return tor_tls_finish_handshake(tls);
596  }
597  if (PORT_GetError() == PR_WOULD_BLOCK_ERROR)
598  return TOR_TLS_WANTREAD; /* XXXX What about wantwrite? */
599 
600  return TOR_TLS_ERROR_MISC; // XXXX
601 }
602 
603 int
605 {
606  tor_assert(tls);
607  // We don't need to do any of the weird handshake nonsense stuff on NSS,
608  // since we only support recent handshakes.
609  return TOR_TLS_DONE;
610 }
611 
612 void
614 {
615  tor_assert(tls);
616  /* We don't support renegotiation with NSS. */
617 }
618 
619 void
621 {
622  tor_assert(tls);
623  /* We don't support renegotiation with NSS. */
624 }
625 
626 void
628 {
629  tor_assert(tls);
630  /* We don't support renegotiation with NSS. */
631 }
632 
633 int
635 {
636  tor_assert(tls);
637  int n = SSL_DataPending(tls->ssl);
638  if (n < 0) {
639  tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "looking up pending bytes");
640  return 0;
641  }
642  return (int)n;
643 }
644 
645 size_t
647 {
648  tor_assert(tls);
649  /* NSS doesn't have the same "forced write" restriction as openssl. */
650  return 0;
651 }
652 
653 void
655  size_t *n_read, size_t *n_written)
656 {
657  tor_assert(tls);
658  tor_assert(n_read);
659  tor_assert(n_written);
660  uint64_t r, w;
661  if (tor_get_prfiledesc_byte_counts(tls->ssl, &r, &w) < 0) {
662  *n_read = *n_written = 0;
663  return;
664  }
665 
666  *n_read = (size_t)(r - tls->last_read_count);
667  *n_written = (size_t)(w - tls->last_write_count);
668 
669  tls->last_read_count = r;
670  tls->last_write_count = w;
671 }
672 
673 int
675  size_t *rbuf_capacity, size_t *rbuf_bytes,
676  size_t *wbuf_capacity, size_t *wbuf_bytes)
677 {
678  tor_assert(tls);
679  tor_assert(rbuf_capacity);
680  tor_assert(rbuf_bytes);
681  tor_assert(wbuf_capacity);
682  tor_assert(wbuf_bytes);
683 
684  /* This is an acceptable way to say "we can't measure this." */
685  return -1;
686 }
687 
688 MOCK_IMPL(double,
689 tls_get_write_overhead_ratio, (void))
690 {
691  /* XXX We don't currently have a way to measure this in NSS; we could do that
692  * XXX with a PRIO layer, but it'll take a little coding. */
693  return 0.95;
694 }
695 
696 int
698 {
699  tor_assert(tls);
700  /* We don't support or allow the V1 handshake with NSS.
701  */
702  return 0;
703 }
704 
705 int
707 {
708  tor_assert(tls);
709  return 0; /* We don't support renegotiation with NSS */
710 }
711 
712 MOCK_IMPL(int,
713 tor_tls_cert_matches_key,(const tor_tls_t *tls,
714  const struct tor_x509_cert_t *cert))
715 {
716  tor_assert(tls);
717  tor_assert(cert);
718  int rv = 0;
719 
720  CERTCertificate *peercert = SSL_PeerCertificate(tls->ssl);
721  if (!peercert)
722  goto done;
723  CERTSubjectPublicKeyInfo *peer_info = &peercert->subjectPublicKeyInfo;
724  CERTSubjectPublicKeyInfo *cert_info = &cert->cert->subjectPublicKeyInfo;
725  rv = SECOID_CompareAlgorithmID(&peer_info->algorithm,
726  &cert_info->algorithm) == 0 &&
727  SECITEM_ItemsAreEqual(&peer_info->subjectPublicKey,
728  &cert_info->subjectPublicKey);
729 
730  done:
731  if (peercert)
732  CERT_DestroyCertificate(peercert);
733  return rv;
734 }
735 
736 MOCK_IMPL(int,
737 tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out))
738 {
739  tor_assert(tls);
740  tor_assert(secrets_out);
741 
742  /* There's no way to get this information out of NSS. */
743 
744  return -1;
745 }
746 
747 MOCK_IMPL(int,
748 tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out,
749  const uint8_t *context,
750  size_t context_len,
751  const char *label))
752 {
753  tor_assert(tls);
754  tor_assert(secrets_out);
755  tor_assert(context);
756  tor_assert(label);
757  tor_assert(strlen(label) <= UINT_MAX);
758  tor_assert(context_len <= UINT_MAX);
759 
760  SECStatus s;
761  /* Make sure that the error code is set here, so that we can be sure that
762  * any error code set after a failure was in fact caused by
763  * SSL_ExportKeyingMaterial. */
764  PR_SetError(PR_UNKNOWN_ERROR, 0);
765  s = SSL_ExportKeyingMaterial(tls->ssl,
766  label, (unsigned)strlen(label),
767  PR_TRUE, context, (unsigned)context_len,
768  secrets_out, DIGEST256_LEN);
769  if (s != SECSuccess) {
771  "exporting key material for a TLS handshake");
772  }
773 
774  return (s == SECSuccess) ? 0 : -1;
775 }
776 
777 const char *
778 tor_tls_get_ciphersuite_name(tor_tls_t *tls)
779 {
780  tor_assert(tls);
781 
782  SSLChannelInfo channel_info;
783  SSLCipherSuiteInfo cipher_info;
784 
785  memset(&channel_info, 0, sizeof(channel_info));
786  memset(&cipher_info, 0, sizeof(cipher_info));
787 
788  SECStatus s = SSL_GetChannelInfo(tls->ssl,
789  &channel_info, sizeof(channel_info));
790  if (s != SECSuccess)
791  return NULL;
792 
793  s = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
794  &cipher_info, sizeof(cipher_info));
795  if (s != SECSuccess)
796  return NULL;
797 
798  return cipher_info.cipherSuiteName;
799 }
800 
802 #define SEC_OID_TOR_DEFAULT_ECDHE_GROUP SEC_OID_ANSIX962_EC_PRIME256V1
803 
804 int
805 evaluate_ecgroup_for_tls(const char *ecgroup)
806 {
807  SECOidTag tag;
808 
809  if (!ecgroup)
811  else if (!strcasecmp(ecgroup, "P256"))
812  tag = SEC_OID_ANSIX962_EC_PRIME256V1;
813  else if (!strcasecmp(ecgroup, "P224"))
814  tag = SEC_OID_SECG_EC_SECP224R1;
815  else
816  return 0;
817 
818  /* I don't think we need any additional tests here for NSS */
819  (void) tag;
820 
821  return 1;
822 }
823 
824 static SECStatus
825 always_accept_cert_cb(void *arg, PRFileDesc *ssl, PRBool checkSig,
826  PRBool isServer)
827 {
828  (void)arg;
829  (void)ssl;
830  (void)checkSig;
831  (void)isServer;
832  return SECSuccess;
833 }
char * address
Definition: tortls_st.h:39
void tor_tls_block_renegotiation(tor_tls_t *tls)
Definition: tortls_nss.c:620
tor_socket_t socket
Definition: tortls_st.h:37
tor_tls_context_t * tor_tls_context_get(int is_server)
Definition: tortls.c:40
#define SEC_OID_TOR_DEFAULT_ECDHE_GROUP
Definition: tortls_nss.c:802
Common functions for using (pseudo-)random number generators.
Header for printf.c.
Headers for crypto_dh.c.
int evaluate_ecgroup_for_tls(const char *ecgroup)
Definition: tortls_nss.c:805
Headers for crypto_cipher.c.
void tor_tls_init(void)
Definition: tortls_nss.c:356
int tor_tls_get_buffer_sizes(tor_tls_t *tls, size_t *rbuf_capacity, size_t *rbuf_bytes, size_t *wbuf_capacity, size_t *wbuf_bytes)
Definition: tortls_nss.c:674
void tor_nss_countbytes_init(void)
tor_tls_t * tor_tls_new(tor_socket_t sock, int is_server)
Definition: tortls_nss.c:396
#define tor_free(p)
Definition: malloc.h:52
void tor_tls_context_decref(tor_tls_context_t *ctx)
Definition: tortls.c:114
#define LOG_NOTICE
Definition: log.h:48
unsigned int isServer
Definition: tortls_st.h:43
#define SOCKET_OK(s)
Definition: nettypes.h:39
int tor_tls_server_got_renegotiate(tor_tls_t *tls)
Definition: tortls_nss.c:706
#define DIGEST256_LEN
Definition: digest_sizes.h:23
PRFileDesc * tor_wrap_prfiledesc_with_byte_counter(PRFileDesc *stack)
Header for nss_countbytes.c, which lets us count the number of bytes actually written on a PRFileDesc...
Common functions for cryptographic routines.
tor_assert(buffer)
void tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls)
Definition: tortls_nss.c:627
void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz)
Definition: tortls_nss.c:346
int tor_get_prfiledesc_byte_counts(PRFileDesc *fd, uint64_t *n_read_out, uint64_t *n_written_out)
int tor_tls_used_v1_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:697
void tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
Definition: tortls_nss.c:362
int tor_tls_context_init_certificates(tor_tls_context_t *result, crypto_pk_t *identity, unsigned key_lifetime, unsigned flags)
Definition: tortls.c:287
#define LOG_WARN
Definition: log.h:51
#define tor_socket_t
Definition: nettypes.h:36
Headers for tortls.c.
void tor_tls_unblock_renegotiation(tor_tls_t *tls)
Definition: tortls_nss.c:613
void tor_tls_set_renegotiate_callback(tor_tls_t *tls, void(*cb)(tor_tls_t *, void *arg), void *arg)
Definition: tortls_nss.c:445
int tor_tls_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:586
int tor_tls_finish_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:604
tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol)
Definition: socket.c:260
tor_tls_impl_t * ssl
Definition: tortls_st.h:36
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
tor_tls_state_bitfield_t state
Definition: tortls_st.h:40
int tor_tls_peer_has_cert(tor_tls_t *tls)
Definition: tortls_nss.c:509
#define ARRAY_LENGTH(x)
#define log_fn(severity, domain, args,...)
Definition: log.h:273
Headers for tortls.c.
size_t tor_tls_get_forced_write_size(tor_tls_t *tls)
Definition: tortls_nss.c:646
void tor_release_socket_ownership(tor_socket_t s)
Definition: socket.c:349
int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
Definition: tortls_nss.c:562
void tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written)
Definition: tortls_nss.c:654
#define LD_NET
Definition: log.h:64
int tor_tls_get_pending_bytes(tor_tls_t *tls)
Definition: tortls_nss.c:634
void tor_tls_context_incref(tor_tls_context_t *ctx)
Definition: tortls.c:106
#define LD_CRYPTO
Definition: log.h:62
Macros to manage assertions, fatal and non-fatal.
static bool ciphersuite_has_nss_export_bug(const SSLCipherSuiteInfo *info)
Definition: tortls_nss.c:161
char * crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix, const char *suffix)
Definition: crypto_rand.c:552
void tor_tls_release_socket(tor_tls_t *tls)
Definition: tortls_nss.c:461
Headers for crypto_nss_mgt.c.