Tor 0.4.9.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-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
49MOCK_IMPL(void,
50try_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
77static bool
78we_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}
97static bool
98we_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
116static bool
117we_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
133static bool
134we_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 **/
160static bool
161ciphersuite_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
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
337void
338tor_tls_context_impl_free_(tor_tls_context_impl_t *ctx)
339{
340 if (!ctx)
341 return;
342 PR_Close(ctx);
343}
344
345void
346tor_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
355void
357{
359}
360
361void
362tls_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}
396const 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
408tor_tls_t *
409tor_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
467void
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 */
483void
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
520void
521tor_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
531int
533{
534 CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
535 int result = (cert != NULL);
536 CERT_DestroyCertificate(cert);
537 return result;
538}
539
540MOCK_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
550MOCK_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
561MOCK_IMPL(int,
562tor_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
584int
585tor_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 if (n == 0) {
592 return 0;
593 }
594
595 PRInt32 rv = PR_Write(tls->ssl, cp, (int)n);
596 // log_debug(LD_NET, "PR_Write(%zu) returned %d", n, (int)rv);
597 if (rv > 0) {
598 return rv;
599 }
600 if (rv == 0)
601 return TOR_TLS_ERROR_MISC;
602 PRErrorCode err = PORT_GetError();
603
604 if (err == PR_WOULD_BLOCK_ERROR) {
605 return TOR_TLS_WANTWRITE; // XXXX ????
606 } else {
607 tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "writing"); // XXXX
608 return TOR_TLS_ERROR_MISC; // ????
609 }
610}
611
612int
614{
615 tor_assert(tls);
616 tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
617
618 SECStatus s = SSL_ForceHandshake(tls->ssl);
619 if (s == SECSuccess) {
620 tls->state = TOR_TLS_ST_OPEN;
621 log_debug(LD_NET, "SSL handshake is supposedly complete.");
622 return tor_tls_finish_handshake(tls);
623 }
624 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR)
625 return TOR_TLS_WANTREAD; /* XXXX What about wantwrite? */
626
627 return TOR_TLS_ERROR_MISC; // XXXX
628}
629
630int
632{
633 tor_assert(tls);
634 // We don't need to do any of the weird handshake nonsense stuff on NSS,
635 // since we only support recent handshakes.
636 return TOR_TLS_DONE;
637}
638
639void
641{
642 tor_assert(tls);
643 /* We don't support renegotiation with NSS. */
644}
645
646void
648{
649 tor_assert(tls);
650 /* We don't support renegotiation with NSS. */
651}
652
653int
655{
656 tor_assert(tls);
657 int n = SSL_DataPending(tls->ssl);
658 if (n < 0) {
659 tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "looking up pending bytes");
660 return 0;
661 }
662 return (int)n;
663}
664
665size_t
667{
668 tor_assert(tls);
669 /* NSS doesn't have the same "forced write" restriction as openssl. */
670 return 0;
671}
672
673void
675 size_t *n_read, size_t *n_written)
676{
677 tor_assert(tls);
678 tor_assert(n_read);
679 tor_assert(n_written);
680 uint64_t r, w;
681 if (tor_get_prfiledesc_byte_counts(tls->ssl, &r, &w) < 0) {
682 *n_read = *n_written = 0;
683 return;
684 }
685
686 *n_read = (size_t)(r - tls->last_read_count);
687 *n_written = (size_t)(w - tls->last_write_count);
688
689 tls->last_read_count = r;
690 tls->last_write_count = w;
691}
692
693int
695 size_t *rbuf_capacity, size_t *rbuf_bytes,
696 size_t *wbuf_capacity, size_t *wbuf_bytes)
697{
698 tor_assert(tls);
699 tor_assert(rbuf_capacity);
700 tor_assert(rbuf_bytes);
701 tor_assert(wbuf_capacity);
702 tor_assert(wbuf_bytes);
703
704 /* This is an acceptable way to say "we can't measure this." */
705 return -1;
706}
707
708MOCK_IMPL(double,
710{
711 /* XXX We don't currently have a way to measure this in NSS; we could do that
712 * XXX with a PRIO layer, but it'll take a little coding. */
713 return 0.95;
714}
715
716int
718{
719 tor_assert(tls);
720 /* We don't support or allow the V1 handshake with NSS.
721 */
722 return 0;
723}
724
725int
727{
728 tor_assert(tls);
729 return 0; /* We don't support renegotiation with NSS */
730}
731
732MOCK_IMPL(int,
733tor_tls_cert_matches_key,(const tor_tls_t *tls,
734 const struct tor_x509_cert_t *cert))
735{
736 tor_assert(cert);
737 tor_assert(cert->cert);
738
739 int rv = 0;
740
741 tor_x509_cert_t *peercert = tor_tls_get_peer_cert((tor_tls_t *)tls);
742
743 if (!peercert || !peercert->cert)
744 goto done;
745
746 CERTSubjectPublicKeyInfo *peer_info = &peercert->cert->subjectPublicKeyInfo;
747 CERTSubjectPublicKeyInfo *cert_info = &cert->cert->subjectPublicKeyInfo;
748
749 /* NSS stores the `len` field in bits, instead of bytes, for the
750 * `subjectPublicKey` field in CERTSubjectPublicKeyInfo, but
751 * `SECITEM_ItemsAreEqual()` compares the two bitstrings using a length field
752 * defined in bytes.
753 *
754 * We convert the `len` field from bits to bytes, do our comparison with
755 * `SECITEM_ItemsAreEqual()`, and reset the length field from bytes to bits
756 * again.
757 *
758 * See also NSS's own implementation of `SECKEY_CopySubjectPublicKeyInfo()`
759 * in seckey.c in the NSS source tree. This function also does the conversion
760 * between bits and bytes.
761 */
762 const unsigned int peer_info_orig_len = peer_info->subjectPublicKey.len;
763 const unsigned int cert_info_orig_len = cert_info->subjectPublicKey.len;
764
765 /* We convert the length from bits to bytes, but instead of using NSS's
766 * `DER_ConvertBitString()` macro on both of peer_info->subjectPublicKey and
767 * cert_info->subjectPublicKey, we have to do the conversion explicitly since
768 * both of the two subjectPublicKey fields are allowed to point to the same
769 * memory address. Otherwise, the bits to bytes conversion would potentially
770 * be applied twice, which would lead to us comparing too few of the bytes
771 * when we call SECITEM_ItemsAreEqual(), which would be catastrophic.
772 */
773 peer_info->subjectPublicKey.len = ((peer_info_orig_len + 7) >> 3);
774 cert_info->subjectPublicKey.len = ((cert_info_orig_len + 7) >> 3);
775
776 rv = SECOID_CompareAlgorithmID(&peer_info->algorithm,
777 &cert_info->algorithm) == 0 &&
778 SECITEM_ItemsAreEqual(&peer_info->subjectPublicKey,
779 &cert_info->subjectPublicKey);
780
781 /* Convert from bytes back to bits. */
782 peer_info->subjectPublicKey.len = peer_info_orig_len;
783 cert_info->subjectPublicKey.len = cert_info_orig_len;
784
785 done:
786 tor_x509_cert_free(peercert);
787
788 return rv;
789}
790
791MOCK_IMPL(int,
792tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out))
793{
794 tor_assert(tls);
795 tor_assert(secrets_out);
796
797 /* There's no way to get this information out of NSS. */
798
799 return -1;
800}
801
802MOCK_IMPL(int,
803tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out,
804 const uint8_t *context,
805 size_t context_len,
806 const char *label))
807{
808 tor_assert(tls);
809 tor_assert(secrets_out);
810 tor_assert(context);
811 tor_assert(label);
812 tor_assert(strlen(label) <= UINT_MAX);
813 tor_assert(context_len <= UINT_MAX);
814
815 SECStatus s;
816 /* Make sure that the error code is set here, so that we can be sure that
817 * any error code set after a failure was in fact caused by
818 * SSL_ExportKeyingMaterial. */
819 PR_SetError(PR_UNKNOWN_ERROR, 0);
820 s = SSL_ExportKeyingMaterial(tls->ssl,
821 label, (unsigned)strlen(label),
822 PR_TRUE, context, (unsigned)context_len,
823 secrets_out, DIGEST256_LEN);
824 if (s != SECSuccess) {
826 "exporting key material for a TLS handshake");
827 }
828
829 return (s == SECSuccess) ? 0 : -1;
830}
831
832const char *
833tor_tls_get_ciphersuite_name(tor_tls_t *tls)
834{
835 tor_assert(tls);
836
837 SSLChannelInfo channel_info;
838 SSLCipherSuiteInfo cipher_info;
839
840 memset(&channel_info, 0, sizeof(channel_info));
841 memset(&cipher_info, 0, sizeof(cipher_info));
842
843 SECStatus s = SSL_GetChannelInfo(tls->ssl,
844 &channel_info, sizeof(channel_info));
845 if (s != SECSuccess)
846 return NULL;
847
848 s = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
849 &cipher_info, sizeof(cipher_info));
850 if (s != SECSuccess)
851 return NULL;
852
853 return cipher_info.cipherSuiteName;
854}
855
856/** The group we should use for ecdhe when none was selected. */
857#define SEC_OID_TOR_DEFAULT_ECDHE_GROUP SEC_OID_ANSIX962_EC_PRIME256V1
858
859int
860evaluate_ecgroup_for_tls(const char *ecgroup)
861{
862 SECOidTag tag;
863
864 if (!ecgroup)
866 else if (!strcasecmp(ecgroup, "P256"))
867 tag = SEC_OID_ANSIX962_EC_PRIME256V1;
868 else if (!strcasecmp(ecgroup, "P224"))
869 tag = SEC_OID_SECG_EC_SECP224R1;
870 else
871 return 0;
872
873 /* I don't think we need any additional tests here for NSS */
874 (void) tag;
875
876 return 1;
877}
878
879static SECStatus
880always_accept_cert_cb(void *arg, PRFileDesc *ssl, PRBool checkSig,
881 PRBool isServer)
882{
883 (void)arg;
884 (void)ssl;
885 (void)checkSig;
886 (void)isServer;
887 return SECSuccess;
888}
#define ARRAY_LENGTH(x)
const char * name
Definition: config.c:2462
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:111
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:119
int tor_tls_context_init_certificates(tor_tls_context_t *result, crypto_pk_t *identity, unsigned key_lifetime, unsigned flags)
Definition: tortls.c:292
Headers for tortls.c.
int tor_tls_server_got_renegotiate(tor_tls_t *tls)
Definition: tortls_nss.c:726
void tor_tls_block_renegotiation(tor_tls_t *tls)
Definition: tortls_nss.c:647
int tor_tls_peer_has_cert(tor_tls_t *tls)
Definition: tortls_nss.c:532
int tor_tls_used_v1_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:717
void tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written)
Definition: tortls_nss.c:674
int tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
Definition: tortls_nss.c:562
void tor_tls_unblock_renegotiation(tor_tls_t *tls)
Definition: tortls_nss.c:640
double tls_get_write_overhead_ratio(void)
Definition: tortls_nss.c:709
int evaluate_ecgroup_for_tls(const char *ecgroup)
Definition: tortls_nss.c:860
void tor_tls_set_renegotiate_callback(tor_tls_t *tls, void(*cb)(tor_tls_t *, void *arg), void *arg)
Definition: tortls_nss.c:468
int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
Definition: tortls_nss.c:585
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:694
struct tor_x509_cert_t * tor_tls_get_peer_cert(tor_tls_t *tls)
Definition: tortls_nss.c:541
void tor_tls_init(void)
Definition: tortls_nss.c:356
int tor_tls_get_pending_bytes(tor_tls_t *tls)
Definition: tortls_nss.c:654
int tor_tls_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:613
int tor_tls_finish_handshake(tor_tls_t *tls)
Definition: tortls_nss.c:631
tor_tls_t * tor_tls_new(tor_socket_t sock, int is_server)
Definition: tortls_nss.c:409
const char * tor_tls_get_last_error_msg(const tor_tls_t *tls)
Definition: tortls_nss.c:397
void tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
Definition: tortls_nss.c:362
struct tor_x509_cert_t * tor_tls_get_own_cert(tor_tls_t *tls)
Definition: tortls_nss.c:551
int tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
Definition: tortls_nss.c:792
void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz)
Definition: tortls_nss.c:346
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:806
size_t tor_tls_get_forced_write_size(tor_tls_t *tls)
Definition: tortls_nss.c:666
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:182
static bool ciphersuite_has_nss_export_bug(const SSLCipherSuiteInfo *info)
Definition: tortls_nss.c:161
#define SEC_OID_TOR_DEFAULT_ECDHE_GROUP
Definition: tortls_nss.c:857
void tor_tls_release_socket(tor_tls_t *tls)
Definition: tortls_nss.c:484
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.