15#define TOR_X509_PRIVATE
30#include "lib/tls/x509_internal.h"
37DISABLE_GCC_WARNING(
"-Wstrict-prototypes")
40#include <private/pprio.h>
45ENABLE_GCC_WARNING(
"-Wstrict-prototypes")
47static SECStatus always_accept_cert_cb(
void *, PRFileDesc *, PRBool, PRBool);
50we_like_ssl_cipher(SSLCipherAlgorithm 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;
63 case ssl_calg_aes:
return true;
64 case ssl_calg_aes_gcm:
return true;
65 case ssl_calg_chacha20:
return true;
70we_like_ssl_kea(SSLKEAType 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;
79#ifdef NSS_HAS_ECDH_HYBRID
80 case ssl_kea_ecdh_hybrid_psk:
return false;
81 case ssl_kea_ecdh_hybrid:
return true;
84 case ssl_kea_dh:
return true;
85 case ssl_kea_ecdh:
return true;
86 case ssl_kea_tls13_any:
return true;
88 case ssl_kea_size:
return true;
94we_like_mac_algorithm(SSLMACAlgorithm ma)
97 case ssl_mac_null:
return false;
98 case ssl_mac_md5:
return false;
99 case ssl_hmac_md5:
return false;
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;
111we_like_auth_type(SSLAuthType 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;
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;
127 case ssl_auth_size:
return true;
128 default:
return true;
144 if (info->authType == ssl_auth_tls13_any)
150 if (strstr(info->cipherSuiteName,
"_SHA384") ||
151 strstr(info->cipherSuiteName,
"_SHA512")) {
160 unsigned int key_lifetime,
unsigned flags,
int is_client)
172 key_lifetime, flags) < 0) {
179 PRFileDesc *tcp = PR_NewTCPSocket();
183 ctx->ctx = SSL_ImportFD(NULL, tcp);
192 s = SSL_ConfigServerCert(ctx->ctx,
193 ctx->my_link_cert->cert,
195 crypto_pk_get_nss_privkey(ctx->link_key),
205 s = SSL_OptionSet(ctx->ctx, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
212 s = SSL_AuthCertificateHook(ctx->ctx, always_accept_cert_cb, NULL);
215 s = SSL_OptionSet(ctx->ctx, SSL_ENABLE_FDX, PR_TRUE);
222 s = SSL_OptionSet(ctx->ctx,
223 is_client ? SSL_HANDSHAKE_AS_CLIENT : SSL_HANDSHAKE_AS_SERVER,
230 SSLVersionRange vrange;
231 memset(&vrange, 0,
sizeof(vrange));
232 s = SSL_VersionRangeGetSupported(ssl_variant_stream, &vrange);
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);
244 const PRUint16 *ciphers = SSL_GetImplementedCiphers();
245 const PRUint16 n_ciphers = SSL_GetNumImplementedCiphers();
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));
253 if (BUG(info.cipherSuite != ciphers[i]))
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);
268 s = SSL_CipherPrefSet(ctx->ctx, ciphers[i],
269 disable ? PR_FALSE : PR_TRUE);
276 s = SSL_OptionSet(ctx->ctx, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
281 s = SSL_OptionSet(ctx->ctx, SSL_NO_CACHE, PR_TRUE);
286 s = SSL_OptionSet(ctx->ctx, SSL_ENABLE_SERVER_DHE, PR_TRUE);
291 SSLNamedGroup groups[] = {
292 ssl_grp_ec_curve25519,
293 ssl_grp_ec_secp256r1,
294 ssl_grp_ec_secp224r1,
297 s = SSL_NamedGroupConfig(ctx->ctx, groups,
ARRAY_LENGTH(groups));
315tor_tls_context_impl_free_(tor_tls_context_impl_t *ctx)
348 PRErrorCode code = PORT_GetError();
350 tls->last_error = code;
352 const char *addr = tls ? tls->
address : NULL;
353 const char *
string = PORT_ErrorToString(code);
354 const char *
name = PORT_ErrorToName(code);
357 string =
"<unrecognized>";
363 const char *with = addr ?
" with " :
"";
364 addr = addr ? addr :
"";
366 log_fn(severity, domain,
"TLS error %s while %s%s%s: %s",
367 name, doing, with, addr,
string);
369 log_fn(severity, domain,
"TLS error %s%s%s: %s",
name,
string,
379 if (tls->last_error == 0) {
382 return PORT_ErrorToString((PRErrorCode)tls->last_error);
391 PRFileDesc *tcp = NULL;
393 tcp = PR_ImportTCPSocket(sock);
395 tcp = PR_NewTCPSocket();
405 PRFileDesc *ssl = SSL_ImportFD(ctx->ctx, count);
413 PRSocketOptionData data;
414 data.option = PR_SockOpt_Nonblocking;
415 data.value.non_blocking = 1;
416 if (PR_SetSocketOption(ssl, &data) != PR_SUCCESS) {
422 tls->magic = TOR_TLS_MAGIC;
427 tls->
state = TOR_TLS_ST_HANDSHAKE;
433 SSL_SetURL(tls->
ssl, fake_hostname);
436 SECStatus s = SSL_ResetHandshake(ssl, is_server ? PR_TRUE : PR_FALSE);
437 if (s != SECSuccess) {
468 log_warn(
LD_NET,
"Out of sockets when trying to shut down an NSS "
473 PRFileDesc *tcp = PR_GetIdentitiesLayer(tls->
ssl, PR_NSPR_IO_LAYER);
479 PR_ChangeFileDescNativeHandle(tcp, sock);
486tor_tls_impl_free_(tor_tls_impl_t *tls)
499 CERTCertificate *cert = SSL_PeerCertificate(tls->
ssl);
500 int result = (cert != NULL);
501 CERT_DestroyCertificate(cert);
508 CERTCertificate *cert = SSL_PeerCertificate(tls->
ssl);
510 return tor_x509_cert_new(cert);
519 CERTCertificate *cert = SSL_LocalCertificate(tls->
ssl);
521 return tor_x509_cert_new(cert);
533 PRInt32 rv = PR_Read(tls->
ssl, cp, (
int)len);
539 return TOR_TLS_CLOSE;
540 PRErrorCode err = PORT_GetError();
541 if (err == PR_WOULD_BLOCK_ERROR) {
542 return TOR_TLS_WANTREAD;
545 return TOR_TLS_ERROR_MISC;
560 PRInt32 rv = PR_Write(tls->
ssl, cp, (
int)n);
566 return TOR_TLS_ERROR_MISC;
567 PRErrorCode err = PORT_GetError();
569 if (err == PR_WOULD_BLOCK_ERROR) {
570 return TOR_TLS_WANTWRITE;
573 return TOR_TLS_ERROR_MISC;
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.");
589 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR)
590 return TOR_TLS_WANTREAD;
592 return TOR_TLS_ERROR_MISC;
599 int n = SSL_DataPending(tls->
ssl);
617 size_t *n_read,
size_t *n_written)
624 *n_read = *n_written = 0;
628 *n_read = (size_t)(r - tls->last_read_count);
629 *n_written = (size_t)(w - tls->last_write_count);
631 tls->last_read_count = r;
632 tls->last_write_count = w;
637 size_t *rbuf_capacity,
size_t *rbuf_bytes,
638 size_t *wbuf_capacity,
size_t *wbuf_bytes)
659tor_tls_cert_matches_key,(
const tor_tls_t *tls,
660 const struct tor_x509_cert_t *cert))
669 if (!peercert || !peercert->cert)
672 CERTSubjectPublicKeyInfo *peer_info = &peercert->cert->subjectPublicKeyInfo;
673 CERTSubjectPublicKeyInfo *cert_info = &cert->cert->subjectPublicKeyInfo;
688 const unsigned int peer_info_orig_len = peer_info->subjectPublicKey.len;
689 const unsigned int cert_info_orig_len = cert_info->subjectPublicKey.len;
699 peer_info->subjectPublicKey.len = ((peer_info_orig_len + 7) >> 3);
700 cert_info->subjectPublicKey.len = ((cert_info_orig_len + 7) >> 3);
702 rv = SECOID_CompareAlgorithmID(&peer_info->algorithm,
703 &cert_info->algorithm) == 0 &&
704 SECITEM_ItemsAreEqual(&peer_info->subjectPublicKey,
705 &cert_info->subjectPublicKey);
708 peer_info->subjectPublicKey.len = peer_info_orig_len;
709 cert_info->subjectPublicKey.len = cert_info_orig_len;
712 tor_x509_cert_free(peercert);
719 const uint8_t *context,
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,
739 if (s != SECSuccess) {
741 "exporting key material for a TLS handshake");
744 return (s == SECSuccess) ? 0 : -1;
748#define SEC_OID_TOR_DEFAULT_ECDHE_GROUP SEC_OID_ANSIX962_EC_PRIME256V1
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;
771always_accept_cert_cb(
void *arg, PRFileDesc *ssl, PRBool checkSig,
Headers for crypto_cipher.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)
Common functions for using (pseudo-)random number generators.
Common functions for cryptographic routines.
#define log_fn(severity, domain, args,...)
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,...)
int tor_close_socket(tor_socket_t s)
void tor_release_socket_ownership(tor_socket_t s)
tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol)
tor_tls_state_bitfield_t state
#define MOCK_IMPL(rv, funcname, arglist)
void tor_tls_context_incref(tor_tls_context_t *ctx)
tor_tls_context_t * tor_tls_context_get(int is_server)
void tor_tls_context_decref(tor_tls_context_t *ctx)
int tor_tls_context_init_certificates(tor_tls_context_t *result, crypto_pk_t *identity, unsigned key_lifetime, unsigned flags)
int tor_tls_peer_has_cert(tor_tls_t *tls)
void tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written)
int tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
double tls_get_write_overhead_ratio(void)
int evaluate_ecgroup_for_tls(const char *ecgroup)
int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
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)
struct tor_x509_cert_t * tor_tls_get_peer_cert(tor_tls_t *tls)
int tor_tls_get_pending_bytes(tor_tls_t *tls)
int tor_tls_handshake(tor_tls_t *tls)
tor_tls_t * tor_tls_new(tor_socket_t sock, int is_server)
const char * tor_tls_get_last_error_msg(const tor_tls_t *tls)
void tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
struct tor_x509_cert_t * tor_tls_get_own_cert(tor_tls_t *tls)
void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz)
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)
size_t tor_tls_get_forced_write_size(tor_tls_t *tls)
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)
static bool ciphersuite_has_nss_export_bug(const SSLCipherSuiteInfo *info)
#define SEC_OID_TOR_DEFAULT_ECDHE_GROUP
void tor_tls_release_socket(tor_tls_t *tls)
Structure declarations for internal TLS types.
Macros to manage assertions, fatal and non-fatal.
#define IF_BUG_ONCE(cond)