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