Tor  0.4.5.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-2020, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file tortls_nss.c
8  * \brief Wrapper functions to present a consistent interface to
9  * TLS and SSL X.509 functions from NSS.
10  **/
11 
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"
34 #include "lib/tls/nss_countbytes.h"
35 #include "lib/log/util_bug.h"
36 
37 DISABLE_GCC_WARNING("-Wstrict-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("-Wstrict-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 
155 /**
156  * Return true iff this ciphersuite will be hit by a mozilla bug 1312976,
157  * which makes TLS key exporters not work with TLS 1.2 non-SHA256
158  * ciphersuites.
159  **/
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 
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  if (tls)
373  tls->last_error = code;
374 
375  const char *addr = tls ? tls->address : NULL;
376  const char *string = PORT_ErrorToString(code);
377  const char *name = PORT_ErrorToName(code);
378  char buf[16];
379  if (!string)
380  string = "<unrecognized>";
381  if (!name) {
382  tor_snprintf(buf, sizeof(buf), "%d", code);
383  name = buf;
384  }
385 
386  const char *with = addr ? " with " : "";
387  addr = addr ? addr : "";
388  if (doing) {
389  log_fn(severity, domain, "TLS error %s while %s%s%s: %s",
390  name, doing, with, addr, string);
391  } else {
392  log_fn(severity, domain, "TLS error %s%s%s: %s", name, string,
393  with, addr);
394  }
395 }
396 const char *
398 {
399  IF_BUG_ONCE(!tls) {
400  return NULL;
401  }
402  if (tls->last_error == 0) {
403  return NULL;
404  }
405  return PORT_ErrorToString((PRErrorCode)tls->last_error);
406 }
407 
408 tor_tls_t *
409 tor_tls_new(tor_socket_t sock, int is_server)
410 {
411  (void)sock;
412  tor_tls_context_t *ctx = tor_tls_context_get(is_server);
413 
414  PRFileDesc *tcp = NULL;
415  if (SOCKET_OK(sock)) {
416  tcp = PR_ImportTCPSocket(sock);
417  } else {
418  tcp = PR_NewTCPSocket();
419  }
420 
421  if (!tcp)
422  return NULL;
423 
424  PRFileDesc *count = tor_wrap_prfiledesc_with_byte_counter(tcp);
425  if (! count)
426  return NULL;
427 
428  PRFileDesc *ssl = SSL_ImportFD(ctx->ctx, count);
429  if (!ssl) {
430  PR_Close(tcp);
431  return NULL;
432  }
433 
434  /* even if though the socket is already nonblocking, we need to tell NSS
435  * about the fact, so that it knows what to do when it says EAGAIN. */
436  PRSocketOptionData data;
437  data.option = PR_SockOpt_Nonblocking;
438  data.value.non_blocking = 1;
439  if (PR_SetSocketOption(ssl, &data) != PR_SUCCESS) {
440  PR_Close(ssl);
441  return NULL;
442  }
443 
444  tor_tls_t *tls = tor_malloc_zero(sizeof(tor_tls_t));
445  tls->magic = TOR_TLS_MAGIC;
446  tls->context = ctx;
448  tls->ssl = ssl;
449  tls->socket = sock;
450  tls->state = TOR_TLS_ST_HANDSHAKE;
451  tls->isServer = !!is_server;
452 
453  if (!is_server) {
454  /* Set a random SNI */
455  char *fake_hostname = crypto_random_hostname(4,25, "www.",".com");
456  SSL_SetURL(tls->ssl, fake_hostname);
457  tor_free(fake_hostname);
458  }
459  SECStatus s = SSL_ResetHandshake(ssl, is_server ? PR_TRUE : PR_FALSE);
460  if (s != SECSuccess) {
461  tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "resetting handshake state");
462  }
463 
464  return tls;
465 }
466 
467 void
469  void (*cb)(tor_tls_t *, void *arg),
470  void *arg)
471 {
472  tor_assert(tls);
473  (void)cb;
474  (void)arg;
475 
476  /* We don't support renegotiation-based TLS with NSS. */
477 }
478 
479 /**
480  * Tell the TLS library that the underlying socket for <b>tls</b> has been
481  * closed, and the library should not attempt to free that socket itself.
482  */
483 void
485 {
486  if (! tls)
487  return;
488 
489  /* NSS doesn't have the equivalent of BIO_NO_CLOSE. If you replace the
490  * fd with something that's invalid, it causes a memory leak in PR_Close.
491  *
492  * If there were a way to put the PRFileDesc into the CLOSED state, that
493  * would prevent it from closing its fd -- but there doesn't seem to be a
494  * supported way to do that either.
495  *
496  * So instead: we make a new sacrificial socket, and replace the original
497  * socket with that one. This seems to be the best we can do, until we
498  * redesign the mainloop code enough to make this function unnecessary.
499  */
500  tor_socket_t sock =
501  tor_open_socket_nonblocking(AF_INET, SOCK_STREAM, IPPROTO_TCP);
502  if (! SOCKET_OK(sock)) {
503  log_warn(LD_NET, "Out of sockets when trying to shut down an NSS "
504  "connection");
505  return;
506  }
507 
508  PRFileDesc *tcp = PR_GetIdentitiesLayer(tls->ssl, PR_NSPR_IO_LAYER);
509  if (BUG(! tcp)) {
510  tor_close_socket(sock);
511  return;
512  }
513 
514  PR_ChangeFileDescNativeHandle(tcp, sock);
515  /* Tell our socket accounting layer that we don't own this socket any more:
516  * NSS is about to free it for us. */
518 }
519 
520 void
521 tor_tls_impl_free_(tor_tls_impl_t *tls)
522 {
523  // XXXX This will close the underlying fd, which our OpenSSL version does
524  // not do!
525  if (!tls)
526  return;
527 
528  PR_Close(tls);
529 }
530 
531 int
533 {
534  CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
535  int result = (cert != NULL);
536  CERT_DestroyCertificate(cert);
537  return result;
538 }
539 
540 MOCK_IMPL(tor_x509_cert_t *,
542 {
543  CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
544  if (cert)
545  return tor_x509_cert_new(cert);
546  else
547  return NULL;
548 }
549 
550 MOCK_IMPL(tor_x509_cert_t *,
552 {
553  tor_assert(tls);
554  CERTCertificate *cert = SSL_LocalCertificate(tls->ssl);
555  if (cert)
556  return tor_x509_cert_new(cert);
557  else
558  return NULL;
559 }
560 
561 MOCK_IMPL(int,
562 tor_tls_read, (tor_tls_t *tls, char *cp, size_t len))
563 {
564  tor_assert(tls);
565  tor_assert(cp);
566  tor_assert(len < INT_MAX);
567 
568  PRInt32 rv = PR_Read(tls->ssl, cp, (int)len);
569  // log_debug(LD_NET, "PR_Read(%zu) returned %d", n, (int)rv);
570  if (rv > 0) {
571  return rv;
572  }
573  if (rv == 0)
574  return TOR_TLS_CLOSE;
575  PRErrorCode err = PORT_GetError();
576  if (err == PR_WOULD_BLOCK_ERROR) {
577  return TOR_TLS_WANTREAD; // XXXX ????
578  } else {
579  tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "reading"); // XXXX
580  return TOR_TLS_ERROR_MISC; // ????
581  }
582 }
583 
584 int
585 tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
586 {
587  tor_assert(tls);
588  tor_assert(cp || n == 0);
589  tor_assert(n < INT_MAX);
590 
591  PRInt32 rv = PR_Write(tls->ssl, cp, (int)n);
592  // log_debug(LD_NET, "PR_Write(%zu) returned %d", n, (int)rv);
593  if (rv > 0) {
594  return rv;
595  }
596  if (rv == 0)
597  return TOR_TLS_ERROR_MISC;
598  PRErrorCode err = PORT_GetError();
599 
600  if (err == PR_WOULD_BLOCK_ERROR) {
601  return TOR_TLS_WANTWRITE; // XXXX ????
602  } else {
603  tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "writing"); // XXXX
604  return TOR_TLS_ERROR_MISC; // ????
605  }
606 }
607 
608 int
610 {
611  tor_assert(tls);
612  tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
613 
614  SECStatus s = SSL_ForceHandshake(tls->ssl);
615  if (s == SECSuccess) {
616  tls->state = TOR_TLS_ST_OPEN;
617  log_debug(LD_NET, "SSL handshake is supposedly complete.");
618  return tor_tls_finish_handshake(tls);
619  }
620  if (PORT_GetError() == PR_WOULD_BLOCK_ERROR)
621  return TOR_TLS_WANTREAD; /* XXXX What about wantwrite? */
622 
623  return TOR_TLS_ERROR_MISC; // XXXX
624 }
625 
626 int
628 {
629  tor_assert(tls);
630  // We don't need to do any of the weird handshake nonsense stuff on NSS,
631  // since we only support recent handshakes.
632  return TOR_TLS_DONE;
633 }
634 
635 void
637 {
638  tor_assert(tls);
639  /* We don't support renegotiation with NSS. */
640 }
641 
642 void
644 {
645  tor_assert(tls);
646  /* We don't support renegotiation with NSS. */
647 }
648 
649 void
651 {
652  tor_assert(tls);
653  /* We don't support renegotiation with NSS. */
654 }
655 
656 int
658 {
659  tor_assert(tls);
660  int n = SSL_DataPending(tls->ssl);
661  if (n < 0) {
662  tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "looking up pending bytes");
663  return 0;
664  }
665  return (int)n;
666 }
667 
668 size_t
670 {
671  tor_assert(tls);
672  /* NSS doesn't have the same "forced write" restriction as openssl. */
673  return 0;
674 }
675 
676 void
678  size_t *n_read, size_t *n_written)
679 {
680  tor_assert(tls);
681  tor_assert(n_read);
682  tor_assert(n_written);
683  uint64_t r, w;
684  if (tor_get_prfiledesc_byte_counts(tls->ssl, &r, &w) < 0) {
685  *n_read = *n_written = 0;
686  return;
687  }
688 
689  *n_read = (size_t)(r - tls->last_read_count);
690  *n_written = (size_t)(w - tls->last_write_count);
691 
692  tls->last_read_count = r;
693  tls->last_write_count = w;
694 }
695 
696 int
698  size_t *rbuf_capacity, size_t *rbuf_bytes,
699  size_t *wbuf_capacity, size_t *wbuf_bytes)
700 {
701  tor_assert(tls);
702  tor_assert(rbuf_capacity);
703  tor_assert(rbuf_bytes);
704  tor_assert(wbuf_capacity);
705  tor_assert(wbuf_bytes);
706 
707  /* This is an acceptable way to say "we can't measure this." */
708  return -1;
709 }
710 
711 MOCK_IMPL(double,
713 {
714  /* XXX We don't currently have a way to measure this in NSS; we could do that
715  * XXX with a PRIO layer, but it'll take a little coding. */
716  return 0.95;
717 }
718 
719 int
721 {
722  tor_assert(tls);
723  /* We don't support or allow the V1 handshake with NSS.
724  */
725  return 0;
726 }
727 
728 int
730 {
731  tor_assert(tls);
732  return 0; /* We don't support renegotiation with NSS */
733 }
734 
735 MOCK_IMPL(int,
736 tor_tls_cert_matches_key,(const tor_tls_t *tls,
737  const struct tor_x509_cert_t *cert))
738 {
739  tor_assert(cert);
740  tor_assert(cert->cert);
741 
742  int rv = 0;
743 
744  tor_x509_cert_t *peercert = tor_tls_get_peer_cert((tor_tls_t *)tls);
745 
746  if (!peercert || !peercert->cert)
747  goto done;
748 
749  CERTSubjectPublicKeyInfo *peer_info = &peercert->cert->subjectPublicKeyInfo;
750  CERTSubjectPublicKeyInfo *cert_info = &cert->cert->subjectPublicKeyInfo;
751 
752  /* NSS stores the `len` field in bits, instead of bytes, for the
753  * `subjectPublicKey` field in CERTSubjectPublicKeyInfo, but
754  * `SECITEM_ItemsAreEqual()` compares the two bitstrings using a length field
755  * defined in bytes.
756  *
757  * We convert the `len` field from bits to bytes, do our comparison with
758  * `SECITEM_ItemsAreEqual()`, and reset the length field from bytes to bits
759  * again.
760  *
761  * See also NSS's own implementation of `SECKEY_CopySubjectPublicKeyInfo()`
762  * in seckey.c in the NSS source tree. This function also does the conversion
763  * between bits and bytes.
764  */
765  const unsigned int peer_info_orig_len = peer_info->subjectPublicKey.len;
766  const unsigned int cert_info_orig_len = cert_info->subjectPublicKey.len;
767 
768  /* We convert the length from bits to bytes, but instead of using NSS's
769  * `DER_ConvertBitString()` macro on both of peer_info->subjectPublicKey and
770  * cert_info->subjectPublicKey, we have to do the conversion explicitly since
771  * both of the two subjectPublicKey fields are allowed to point to the same
772  * memory address. Otherwise, the bits to bytes conversion would potentially
773  * be applied twice, which would lead to us comparing too few of the bytes
774  * when we call SECITEM_ItemsAreEqual(), which would be catastrophic.
775  */
776  peer_info->subjectPublicKey.len = ((peer_info_orig_len + 7) >> 3);
777  cert_info->subjectPublicKey.len = ((cert_info_orig_len + 7) >> 3);
778 
779  rv = SECOID_CompareAlgorithmID(&peer_info->algorithm,
780  &cert_info->algorithm) == 0 &&
781  SECITEM_ItemsAreEqual(&peer_info->subjectPublicKey,
782  &cert_info->subjectPublicKey);
783 
784  /* Convert from bytes back to bits. */
785  peer_info->subjectPublicKey.len = peer_info_orig_len;
786  cert_info->subjectPublicKey.len = cert_info_orig_len;
787 
788  done:
789  tor_x509_cert_free(peercert);
790 
791  return rv;
792 }
793 
794 MOCK_IMPL(int,
795 tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out))
796 {
797  tor_assert(tls);
798  tor_assert(secrets_out);
799 
800  /* There's no way to get this information out of NSS. */
801 
802  return -1;
803 }
804 
805 MOCK_IMPL(int,
806 tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out,
807  const uint8_t *context,
808  size_t context_len,
809  const char *label))
810 {
811  tor_assert(tls);
812  tor_assert(secrets_out);
813  tor_assert(context);
814  tor_assert(label);
815  tor_assert(strlen(label) <= UINT_MAX);
816  tor_assert(context_len <= UINT_MAX);
817 
818  SECStatus s;
819  /* Make sure that the error code is set here, so that we can be sure that
820  * any error code set after a failure was in fact caused by
821  * SSL_ExportKeyingMaterial. */
822  PR_SetError(PR_UNKNOWN_ERROR, 0);
823  s = SSL_ExportKeyingMaterial(tls->ssl,
824  label, (unsigned)strlen(label),
825  PR_TRUE, context, (unsigned)context_len,
826  secrets_out, DIGEST256_LEN);
827  if (s != SECSuccess) {
829  "exporting key material for a TLS handshake");
830  }
831 
832  return (s == SECSuccess) ? 0 : -1;
833 }
834 
835 const char *
836 tor_tls_get_ciphersuite_name(tor_tls_t *tls)
837 {
838  tor_assert(tls);
839 
840  SSLChannelInfo channel_info;
841  SSLCipherSuiteInfo cipher_info;
842 
843  memset(&channel_info, 0, sizeof(channel_info));
844  memset(&cipher_info, 0, sizeof(cipher_info));
845 
846  SECStatus s = SSL_GetChannelInfo(tls->ssl,
847  &channel_info, sizeof(channel_info));
848  if (s != SECSuccess)
849  return NULL;
850 
851  s = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
852  &cipher_info, sizeof(cipher_info));
853  if (s != SECSuccess)
854  return NULL;
855 
856  return cipher_info.cipherSuiteName;
857 }
858 
859 /** The group we should use for ecdhe when none was selected. */
860 #define SEC_OID_TOR_DEFAULT_ECDHE_GROUP SEC_OID_ANSIX962_EC_PRIME256V1
861 
862 int
863 evaluate_ecgroup_for_tls(const char *ecgroup)
864 {
865  SECOidTag tag;
866 
867  if (!ecgroup)
869  else if (!strcasecmp(ecgroup, "P256"))
870  tag = SEC_OID_ANSIX962_EC_PRIME256V1;
871  else if (!strcasecmp(ecgroup, "P224"))
872  tag = SEC_OID_SECG_EC_SECP224R1;
873  else
874  return 0;
875 
876  /* I don't think we need any additional tests here for NSS */
877  (void) tag;
878 
879  return 1;
880 }
881 
882 static SECStatus
883 always_accept_cert_cb(void *arg, PRFileDesc *ssl, PRBool checkSig,
884  PRBool isServer)
885 {
886  (void)arg;
887  (void)ssl;
888  (void)checkSig;
889  (void)isServer;
890  return SECSuccess;
891 }
log_fn
#define log_fn(severity, domain, args,...)
Definition: log.h:287
tor_tls_finish_handshake
int tor_tls_finish_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:627
tor_free
#define tor_free(p)
Definition: malloc.h:52
tor_close_socket
int tor_close_socket(tor_socket_t s)
Definition: socket.c:217
name
const char * name
Definition: config.c:2443
tor_tls_get_pending_bytes
int tor_tls_get_pending_bytes(tor_tls_t *tls)
Definition: tortls_nss.c:657
LOG_NOTICE
#define LOG_NOTICE
Definition: log.h:50
MOCK_IMPL
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
tor_tls_get_state_description
void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz)
Definition: tortls_nss.c:346
tor_assert
#define tor_assert(expr)
Definition: util_bug.h:102
tor_tls_context_new
tor_tls_context_t * tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime, unsigned flags, int is_client)
Definition: tortls_nss.c:182
tor_tls_get_last_error_msg
const char * tor_tls_get_last_error_msg(const tor_tls_t *tls)
Definition: tortls_nss.c:397
tor_tls_t::address
char * address
Definition: tortls_st.h:47
tor_tls_peer_has_cert
int tor_tls_peer_has_cert(tor_tls_t *tls)
Definition: tortls_nss.c:532
crypto_random_hostname
char * crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix, const char *suffix)
Definition: crypto_rand.c:552
tor_tls_t::state
tor_tls_state_bitfield_t state
Definition: tortls_st.h:48
tor_tls_used_v1_handshake
int tor_tls_used_v1_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:720
tls_log_errors
void tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
Definition: tortls_nss.c:362
util_bug.h
Macros to manage assertions, fatal and non-fatal.
tor_snprintf
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
tor_wrap_prfiledesc_with_byte_counter
PRFileDesc * tor_wrap_prfiledesc_with_byte_counter(PRFileDesc *stack)
Definition: nss_countbytes.c:193
tor_tls_get_tlssecrets
int tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
Definition: tortls_nss.c:795
tor_tls_context_t
Definition: tortls_st.h:28
crypto_util.h
Common functions for cryptographic routines.
tor_tls_get_n_raw_bytes
void tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written)
Definition: tortls_nss.c:677
crypto_nss_mgt.h
Headers for crypto_nss_mgt.c.
tor_tls_t
Definition: tortls_st.h:41
tor_tls_context_init_certificates
int tor_tls_context_init_certificates(tor_tls_context_t *result, crypto_pk_t *identity, unsigned key_lifetime, unsigned flags)
Definition: tortls.c:292
tor_tls_unblock_renegotiation
void tor_tls_unblock_renegotiation(tor_tls_t *tls)
Definition: tortls_nss.c:636
tor_tls_t::ssl
tor_tls_impl_t * ssl
Definition: tortls_st.h:44
tortls.h
Headers for tortls.c.
tor_tls_read
int tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
Definition: tortls_nss.c:562
printf.h
Header for printf.c.
tor_tls_get_own_cert
struct tor_x509_cert_t * tor_tls_get_own_cert(tor_tls_t *tls)
Definition: tortls_nss.c:551
crypto_dh.h
Headers for crypto_dh.c.
tor_tls_context_incref
void tor_tls_context_incref(tor_tls_context_t *ctx)
Definition: tortls.c:111
tor_release_socket_ownership
void tor_release_socket_ownership(tor_socket_t s)
Definition: socket.c:348
tortls_st.h
Structure declarations for internal TLS types.
tor_tls_t::socket
tor_socket_t socket
Definition: tortls_st.h:45
tor_tls_context_get
tor_tls_context_t * tor_tls_context_get(int is_server)
Definition: tortls.c:45
SEC_OID_TOR_DEFAULT_ECDHE_GROUP
#define SEC_OID_TOR_DEFAULT_ECDHE_GROUP
Definition: tortls_nss.c:860
DIGEST256_LEN
#define DIGEST256_LEN
Definition: digest_sizes.h:23
ciphersuite_has_nss_export_bug
static bool ciphersuite_has_nss_export_bug(const SSLCipherSuiteInfo *info)
Definition: tortls_nss.c:161
tor_tls_write
int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
Definition: tortls_nss.c:585
tor_open_socket_nonblocking
tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol)
Definition: socket.c:259
ARRAY_LENGTH
#define ARRAY_LENGTH(x)
Definition: compat_compiler.h:222
crypto_rand.h
Common functions for using (pseudo-)random number generators.
tor_tls_get_forced_write_size
size_t tor_tls_get_forced_write_size(tor_tls_t *tls)
Definition: tortls_nss.c:669
tortls_internal.h
Declare internal functions for lib/tls.
tor_tls_init
void tor_tls_init(void)
Definition: tortls_nss.c:356
LD_CRYPTO
#define LD_CRYPTO
Definition: log.h:64
tor_tls_get_buffer_sizes
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:697
tls_get_write_overhead_ratio
double tls_get_write_overhead_ratio(void)
Definition: tortls_nss.c:712
IF_BUG_ONCE
#define IF_BUG_ONCE(cond)
Definition: util_bug.h:246
crypto_cipher.h
Headers for crypto_cipher.c.
nss_countbytes.h
Header for nss_countbytes.c, which lets us count the number of bytes actually written on a PRFileDesc...
tor_tls_new
tor_tls_t * tor_tls_new(tor_socket_t sock, int is_server)
Definition: tortls_nss.c:409
tor_tls_t::isServer
unsigned int isServer
Definition: tortls_st.h:51
crypto_pk_t
Definition: crypto_rsa_nss.c:37
tor_tls_server_got_renegotiate
int tor_tls_server_got_renegotiate(tor_tls_t *tls)
Definition: tortls_nss.c:729
tor_tls_context_decref
void tor_tls_context_decref(tor_tls_context_t *ctx)
Definition: tortls.c:119
tor_nss_countbytes_init
void tor_nss_countbytes_init(void)
Definition: nss_countbytes.c:57
LOG_WARN
#define LOG_WARN
Definition: log.h:53
tor_tls_assert_renegotiation_unblocked
void tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls)
Definition: tortls_nss.c:650
tor_tls_handshake
int tor_tls_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:609
tor_tls_release_socket
void tor_tls_release_socket(tor_tls_t *tls)
Definition: tortls_nss.c:484
tor_tls_get_peer_cert
struct tor_x509_cert_t * tor_tls_get_peer_cert(tor_tls_t *tls)
Definition: tortls_nss.c:541
LD_NET
#define LD_NET
Definition: log.h:66
tor_tls_block_renegotiation
void tor_tls_block_renegotiation(tor_tls_t *tls)
Definition: tortls_nss.c:643
tor_tls_export_key_material
int tor_tls_export_key_material(tor_tls_t *tls, uint8_t *secrets_out, const uint8_t *context, size_t context_len, const char *label)
Definition: tortls_nss.c:809
tor_tls_set_renegotiate_callback
void tor_tls_set_renegotiate_callback(tor_tls_t *tls, void(*cb)(tor_tls_t *, void *arg), void *arg)
Definition: tortls_nss.c:468
tor_socket_t
#define tor_socket_t
Definition: nettypes.h:36
evaluate_ecgroup_for_tls
int evaluate_ecgroup_for_tls(const char *ecgroup)
Definition: tortls_nss.c:863
tor_get_prfiledesc_byte_counts
int tor_get_prfiledesc_byte_counts(PRFileDesc *fd, uint64_t *n_read_out, uint64_t *n_written_out)
Definition: nss_countbytes.c:225
SOCKET_OK
#define SOCKET_OK(s)
Definition: nettypes.h:39
x509.h
Headers for tortls.c.