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 */
8 * \brief Wrapper functions to present a consistent interface to
9 * TLS and SSL X.509 functions from NSS.
14 #define TORTLS_PRIVATE
15 #define TOR_X509_PRIVATE
22 #include "lib/crypt_ops/crypto_cipher.h"
23 #include "lib/crypt_ops/crypto_rand.h"
24 #include "lib/crypt_ops/crypto_dh.h"
25 #include "lib/crypt_ops/crypto_util.h"
26 #include "lib/crypt_ops/crypto_nss_mgt.h"
27 #include "lib/string/printf.h"
29 #include "lib/tls/x509.h"
30 #include "lib/tls/x509_internal.h"
31 #include "lib/tls/tortls.h"
32 #include "lib/tls/tortls_st.h"
33 #include "lib/tls/tortls_internal.h"
34 #include "lib/tls/nss_countbytes.h"
35 #include "lib/log/util_bug.h"
37 DISABLE_GCC_WARNING("-Wstrict-prototypes")
39 // For access to rar sockets.
40 #include <private/pprio.h>
45 ENABLE_GCC_WARNING("-Wstrict-prototypes")
47 static SECStatus
always_accept_cert_cb(void *, PRFileDesc
*, PRBool
, PRBool
);
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
))
56 tor_assert(id_cert_out
);
59 *cert_out
= *id_cert_out
= NULL
;
61 CERTCertificate
*peer
= SSL_PeerCertificate(tls
->ssl
);
64 *cert_out
= peer
; /* Now owns pointer. */
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
);
74 CERT_DestroyCertList(chain
);
78 we_like_ssl_cipher(SSLCipherAlgorithm 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;
91 case ssl_calg_aes
: return true;
92 case ssl_calg_aes_gcm
: return true;
93 case ssl_calg_chacha20
: return true;
98 we_like_ssl_kea(SSLKEAType 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;
107 case ssl_kea_dh
: return true;
108 case ssl_kea_ecdh
: return true;
109 case ssl_kea_tls13_any
: return true;
111 case ssl_kea_size
: return true; /* prevent a warning. */
112 default: return true;
117 we_like_mac_algorithm(SSLMACAlgorithm ma
)
120 case ssl_mac_null
: return false;
121 case ssl_mac_md5
: return false;
122 case ssl_hmac_md5
: return false;
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;
134 we_like_auth_type(SSLAuthType 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;
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;
150 case ssl_auth_size
: return true; /* prevent a warning. */
151 default: return true;
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
161 ciphersuite_has_nss_export_bug(const SSLCipherSuiteInfo
*info
)
163 /* For more information on the bug, see
164 https://bugzilla.mozilla.org/show_bug.cgi?id=1312976 */
166 /* This bug only exists in TLS 1.2. */
167 if (info
->authType
== ssl_auth_tls13_any
)
170 /* Sadly, there's no way to get this information from the
171 * CipherSuiteInfo object itself other than by looking at the
173 if (strstr(info
->cipherSuiteName
, "_SHA384") ||
174 strstr(info
->cipherSuiteName
, "_SHA512")) {
182 tor_tls_context_new(crypto_pk_t
*identity
,
183 unsigned int key_lifetime
, unsigned flags
, int is_client
)
186 tor_assert(identity
);
190 tor_tls_context_t
*ctx
= tor_malloc_zero(sizeof(tor_tls_context_t
));
194 if (tor_tls_context_init_certificates(ctx
, identity
,
195 key_lifetime
, flags
) < 0) {
201 /* Create the "model" PRFileDesc that we will use to base others on. */
202 PRFileDesc
*tcp
= PR_NewTCPSocket();
206 ctx
->ctx
= SSL_ImportFD(NULL
, tcp
);
213 // Configure the certificate.
215 s
= SSL_ConfigServerCert(ctx
->ctx
,
216 ctx
->my_link_cert
->cert
,
218 crypto_pk_get_nss_privkey(ctx
->link_key
),
219 NULL
, /* ExtraServerCertData */
225 // We need a certificate from the other side.
227 // XXXX does this do anything?
228 s
= SSL_OptionSet(ctx
->ctx
, SSL_REQUIRE_CERTIFICATE
, PR_TRUE
);
233 // Always accept other side's cert; we'll check it ourselves in goofy
235 s
= SSL_AuthCertificateHook(ctx
->ctx
, always_accept_cert_cb
, NULL
);
237 // We allow simultaneous read and write.
238 s
= SSL_OptionSet(ctx
->ctx
, SSL_ENABLE_FDX
, PR_TRUE
);
241 // XXXX SSL_ROLLBACK_DETECTION??
242 // XXXX SSL_ENABLE_ALPN??
244 // Force client-mode or server_mode.
245 s
= SSL_OptionSet(ctx
->ctx
,
246 is_client
? SSL_HANDSHAKE_AS_CLIENT
: SSL_HANDSHAKE_AS_SERVER
,
251 // Disable everything before TLS 1.0; support everything else.
253 SSLVersionRange vrange
;
254 memset(&vrange
, 0, sizeof(vrange
));
255 s
= SSL_VersionRangeGetSupported(ssl_variant_stream
, &vrange
);
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
);
265 // Only support strong ciphers.
267 const PRUint16
*ciphers
= SSL_GetImplementedCiphers();
268 const PRUint16 n_ciphers
= SSL_GetNumImplementedCiphers();
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
));
276 if (BUG(info
.cipherSuite
!= ciphers
[i
]))
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 */;
285 if (ciphersuite_has_nss_export_bug(&info
)) {
286 /* SSL_ExportKeyingMaterial will fail; we can't use this cipher.
291 s
= SSL_CipherPrefSet(ctx
->ctx
, ciphers
[i
],
292 disable
? PR_FALSE
: PR_TRUE
);
298 // Only use DH and ECDH keys once.
299 s
= SSL_OptionSet(ctx
->ctx
, SSL_REUSE_SERVER_ECDHE_KEY
, PR_FALSE
);
303 // don't cache sessions.
304 s
= SSL_OptionSet(ctx
->ctx
, SSL_NO_CACHE
, PR_TRUE
);
309 s
= SSL_OptionSet(ctx
->ctx
, SSL_ENABLE_SERVER_DHE
, PR_TRUE
);
313 // Set DH and ECDH groups.
314 SSLNamedGroup groups
[] = {
315 ssl_grp_ec_curve25519
,
316 ssl_grp_ec_secp256r1
,
317 ssl_grp_ec_secp224r1
,
320 s
= SSL_NamedGroupConfig(ctx
->ctx
, groups
, ARRAY_LENGTH(groups
));
324 // These features are off by default, so we don't need to disable them:
331 tor_tls_context_decref(ctx
);
338 tor_tls_context_impl_free_(tor_tls_context_impl_t
*ctx
)
346 tor_tls_get_state_description(tor_tls_t
*tls
, char *buf
, size_t sz
)
351 // AFAICT, NSS doesn't expose its internal state.
358 tor_nss_countbytes_init();
362 tls_log_errors(tor_tls_t
*tls
, int severity
, int domain
,
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
371 PRErrorCode code
= PORT_GetError();
373 tls
->last_error
= code
;
375 const char *addr
= tls
? tls
->address
: NULL
;
376 const char *string
= PORT_ErrorToString(code
);
377 const char *name
= PORT_ErrorToName(code
);
380 string
= "<unrecognized>";
382 tor_snprintf(buf
, sizeof(buf
), "%d", code
);
386 const char *with
= addr
? " with " : "";
387 addr
= addr
? addr
: "";
389 log_fn(severity
, domain
, "TLS error %s while %s%s%s: %s",
390 name
, doing
, with
, addr
, string
);
392 log_fn(severity
, domain
, "TLS error %s%s%s: %s", name
, string
,
397 tor_tls_get_last_error_msg(const tor_tls_t
*tls
)
402 if (tls
->last_error
== 0) {
405 return PORT_ErrorToString((PRErrorCode
)tls
->last_error
);
409 tor_tls_new(tor_socket_t sock
, int is_server
)
412 tor_tls_context_t
*ctx
= tor_tls_context_get(is_server
);
414 PRFileDesc
*tcp
= NULL
;
415 if (SOCKET_OK(sock
)) {
416 tcp
= PR_ImportTCPSocket(sock
);
418 tcp
= PR_NewTCPSocket();
424 PRFileDesc
*count
= tor_wrap_prfiledesc_with_byte_counter(tcp
);
428 PRFileDesc
*ssl
= SSL_ImportFD(ctx
->ctx
, count
);
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
) {
444 tor_tls_t
*tls
= tor_malloc_zero(sizeof(tor_tls_t
));
445 tls
->magic
= TOR_TLS_MAGIC
;
447 tor_tls_context_incref(ctx
);
450 tls
->state
= TOR_TLS_ST_HANDSHAKE
;
451 tls
->isServer
= !!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
);
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");
468 tor_tls_set_renegotiate_callback(tor_tls_t
*tls
,
469 void (*cb
)(tor_tls_t
*, void *arg
),
476 /* We don't support renegotiation-based TLS with NSS. */
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.
484 tor_tls_release_socket(tor_tls_t
*tls
)
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.
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.
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.
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 "
508 PRFileDesc
*tcp
= PR_GetIdentitiesLayer(tls
->ssl
, PR_NSPR_IO_LAYER
);
510 tor_close_socket(sock
);
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. */
517 tor_release_socket_ownership(sock
);
521 tor_tls_impl_free_(tor_tls_impl_t
*tls
)
523 // XXXX This will close the underlying fd, which our OpenSSL version does
532 tor_tls_peer_has_cert(tor_tls_t
*tls
)
534 CERTCertificate
*cert
= SSL_PeerCertificate(tls
->ssl
);
535 int result
= (cert
!= NULL
);
536 CERT_DestroyCertificate(cert
);
540 MOCK_IMPL(tor_x509_cert_t
*,
541 tor_tls_get_peer_cert
,(tor_tls_t
*tls
))
543 CERTCertificate
*cert
= SSL_PeerCertificate(tls
->ssl
);
545 return tor_x509_cert_new(cert
);
550 MOCK_IMPL(tor_x509_cert_t
*,
551 tor_tls_get_own_cert
,(tor_tls_t
*tls
))
554 CERTCertificate
*cert
= SSL_LocalCertificate(tls
->ssl
);
556 return tor_x509_cert_new(cert
);
562 tor_tls_read
, (tor_tls_t
*tls
, char *cp
, size_t len
))
566 tor_assert(len
< INT_MAX
);
568 PRInt32 rv
= PR_Read(tls
->ssl
, cp
, (int)len
);
569 // log_debug(LD_NET, "PR_Read(%zu) returned %d", n, (int)rv);
574 return TOR_TLS_CLOSE
;
575 PRErrorCode err
= PORT_GetError();
576 if (err
== PR_WOULD_BLOCK_ERROR
) {
577 return TOR_TLS_WANTREAD
; // XXXX ????
579 tls_log_errors(tls
, LOG_NOTICE
, LD_CRYPTO
, "reading"); // XXXX
580 return TOR_TLS_ERROR_MISC
; // ????
585 tor_tls_write(tor_tls_t
*tls
, const char *cp
, size_t n
)
588 tor_assert(cp
|| n
== 0);
589 tor_assert(n
< INT_MAX
);
595 PRInt32 rv
= PR_Write(tls
->ssl
, cp
, (int)n
);
596 // log_debug(LD_NET, "PR_Write(%zu) returned %d", n, (int)rv);
601 return TOR_TLS_ERROR_MISC
;
602 PRErrorCode err
= PORT_GetError();
604 if (err
== PR_WOULD_BLOCK_ERROR
) {
605 return TOR_TLS_WANTWRITE
; // XXXX ????
607 tls_log_errors(tls
, LOG_NOTICE
, LD_CRYPTO
, "writing"); // XXXX
608 return TOR_TLS_ERROR_MISC
; // ????
613 tor_tls_handshake(tor_tls_t
*tls
)
616 tor_assert(tls
->state
== TOR_TLS_ST_HANDSHAKE
);
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
);
624 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR
)
625 return TOR_TLS_WANTREAD
; /* XXXX What about wantwrite? */
627 return TOR_TLS_ERROR_MISC
; // XXXX
631 tor_tls_finish_handshake(tor_tls_t
*tls
)
634 // We don't need to do any of the weird handshake nonsense stuff on NSS,
635 // since we only support recent handshakes.
640 tor_tls_unblock_renegotiation(tor_tls_t
*tls
)
643 /* We don't support renegotiation with NSS. */
647 tor_tls_block_renegotiation(tor_tls_t
*tls
)
650 /* We don't support renegotiation with NSS. */
654 tor_tls_get_pending_bytes(tor_tls_t
*tls
)
657 int n
= SSL_DataPending(tls
->ssl
);
659 tls_log_errors(tls
, LOG_WARN
, LD_CRYPTO
, "looking up pending bytes");
666 tor_tls_get_forced_write_size(tor_tls_t
*tls
)
669 /* NSS doesn't have the same "forced write" restriction as openssl. */
674 tor_tls_get_n_raw_bytes(tor_tls_t
*tls
,
675 size_t *n_read
, size_t *n_written
)
679 tor_assert(n_written
);
681 if (tor_get_prfiledesc_byte_counts(tls
->ssl
, &r
, &w
) < 0) {
682 *n_read
= *n_written
= 0;
686 *n_read
= (size_t)(r
- tls
->last_read_count
);
687 *n_written
= (size_t)(w
- tls
->last_write_count
);
689 tls
->last_read_count
= r
;
690 tls
->last_write_count
= w
;
694 tor_tls_get_buffer_sizes(tor_tls_t
*tls
,
695 size_t *rbuf_capacity
, size_t *rbuf_bytes
,
696 size_t *wbuf_capacity
, size_t *wbuf_bytes
)
699 tor_assert(rbuf_capacity
);
700 tor_assert(rbuf_bytes
);
701 tor_assert(wbuf_capacity
);
702 tor_assert(wbuf_bytes
);
704 /* This is an acceptable way to say "we can't measure this." */
709 tls_get_write_overhead_ratio
, (void))
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. */
717 tor_tls_used_v1_handshake(tor_tls_t
*tls
)
720 /* We don't support or allow the V1 handshake with NSS.
726 tor_tls_server_got_renegotiate(tor_tls_t
*tls
)
729 return 0; /* We don't support renegotiation with NSS */
733 tor_tls_cert_matches_key
,(const tor_tls_t
*tls
,
734 const struct tor_x509_cert_t
*cert
))
737 tor_assert(cert
->cert
);
741 tor_x509_cert_t
*peercert
= tor_tls_get_peer_cert((tor_tls_t
*)tls
);
743 if (!peercert
|| !peercert
->cert
)
746 CERTSubjectPublicKeyInfo
*peer_info
= &peercert
->cert
->subjectPublicKeyInfo
;
747 CERTSubjectPublicKeyInfo
*cert_info
= &cert
->cert
->subjectPublicKeyInfo
;
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
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
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.
762 const unsigned int peer_info_orig_len
= peer_info
->subjectPublicKey
.len
;
763 const unsigned int cert_info_orig_len
= cert_info
->subjectPublicKey
.len
;
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.
773 peer_info
->subjectPublicKey
.len
= ((peer_info_orig_len
+ 7) >> 3);
774 cert_info
->subjectPublicKey
.len
= ((cert_info_orig_len
+ 7) >> 3);
776 rv
= SECOID_CompareAlgorithmID(&peer_info
->algorithm
,
777 &cert_info
->algorithm
) == 0 &&
778 SECITEM_ItemsAreEqual(&peer_info
->subjectPublicKey
,
779 &cert_info
->subjectPublicKey
);
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
;
786 tor_x509_cert_free(peercert
);
792 tor_tls_get_tlssecrets
,(tor_tls_t
*tls
, uint8_t *secrets_out
))
795 tor_assert(secrets_out
);
797 /* There's no way to get this information out of NSS. */
803 tor_tls_export_key_material
,(tor_tls_t
*tls
, uint8_t *secrets_out
,
804 const uint8_t *context
,
809 tor_assert(secrets_out
);
812 tor_assert(strlen(label
) <= UINT_MAX
);
813 tor_assert(context_len
<= UINT_MAX
);
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
) {
825 tls_log_errors(tls
, LOG_WARN
, LD_CRYPTO
,
826 "exporting key material for a TLS handshake");
829 return (s
== SECSuccess
) ? 0 : -1;
833 tor_tls_get_ciphersuite_name(tor_tls_t
*tls
)
837 SSLChannelInfo channel_info
;
838 SSLCipherSuiteInfo cipher_info
;
840 memset(&channel_info
, 0, sizeof(channel_info
));
841 memset(&cipher_info
, 0, sizeof(cipher_info
));
843 SECStatus s
= SSL_GetChannelInfo(tls
->ssl
,
844 &channel_info
, sizeof(channel_info
));
848 s
= SSL_GetCipherSuiteInfo(channel_info
.cipherSuite
,
849 &cipher_info
, sizeof(cipher_info
));
853 return cipher_info
.cipherSuiteName
;
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
860 evaluate_ecgroup_for_tls(const char *ecgroup
)
865 tag
= SEC_OID_TOR_DEFAULT_ECDHE_GROUP
;
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
;
873 /* I don't think we need any additional tests here for NSS */
880 always_accept_cert_cb(void *arg
, PRFileDesc
*ssl
, PRBool checkSig
,