Use the correct macro to detect an invalid socket in tortls_nss.c
[tor.git] / src / lib / tls / tortls_nss.c
blobe1e6cc501e36bfa4629cb2fdd4fd1d63e26e8e4e
1 /* Copyright (c) 2003, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2018, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
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 **/
12 #include "orconfig.h"
14 #define TORTLS_PRIVATE
15 #define TOR_X509_PRIVATE
17 #ifdef _WIN32
18 #include <winsock2.h>
19 #include <ws2tcpip.h>
20 #endif
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(strict-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(strict-prototypes)
47 static SECStatus always_accept_cert_cb(void *, PRFileDesc *, PRBool, PRBool);
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))
54 tor_assert(tls);
55 tor_assert(cert_out);
56 tor_assert(id_cert_out);
57 (void) severity;
59 *cert_out = *id_cert_out = NULL;
61 CERTCertificate *peer = SSL_PeerCertificate(tls->ssl);
62 if (!peer)
63 return;
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);
71 break;
74 CERT_DestroyCertList(chain);
77 static bool
78 we_like_ssl_cipher(SSLCipherAlgorithm ca)
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;
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;
97 static bool
98 we_like_ssl_kea(SSLKEAType kt)
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;
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;
116 static bool
117 we_like_mac_algorithm(SSLMACAlgorithm ma)
119 switch (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;
133 static bool
134 we_like_auth_type(SSLAuthType at)
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;
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;
155 tor_tls_context_t *
156 tor_tls_context_new(crypto_pk_t *identity,
157 unsigned int key_lifetime, unsigned flags, int is_client)
159 SECStatus s;
160 tor_assert(identity);
162 tor_tls_init();
164 tor_tls_context_t *ctx = tor_malloc_zero(sizeof(tor_tls_context_t));
165 ctx->refcnt = 1;
167 if (! is_client) {
168 if (tor_tls_context_init_certificates(ctx, identity,
169 key_lifetime, flags) < 0) {
170 goto err;
175 /* Create the "model" PRFileDesc that we will use to base others on. */
176 PRFileDesc *tcp = PR_NewTCPSocket();
177 if (!tcp)
178 goto err;
180 ctx->ctx = SSL_ImportFD(NULL, tcp);
181 if (!ctx->ctx) {
182 PR_Close(tcp);
183 goto err;
187 // Configure the certificate.
188 if (!is_client) {
189 s = SSL_ConfigServerCert(ctx->ctx,
190 ctx->my_link_cert->cert,
191 (SECKEYPrivateKey *)
192 crypto_pk_get_nss_privkey(ctx->link_key),
193 NULL, /* ExtraServerCertData */
194 0 /* DataLen */);
195 if (s != SECSuccess)
196 goto err;
199 // We need a certificate from the other side.
200 if (is_client) {
201 // XXXX does this do anything?
202 s = SSL_OptionSet(ctx->ctx, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
203 if (s != SECSuccess)
204 goto err;
207 // Always accept other side's cert; we'll check it ourselves in goofy
208 // tor ways.
209 s = SSL_AuthCertificateHook(ctx->ctx, always_accept_cert_cb, NULL);
211 // We allow simultaneous read and write.
212 s = SSL_OptionSet(ctx->ctx, SSL_ENABLE_FDX, PR_TRUE);
213 if (s != SECSuccess)
214 goto err;
215 // XXXX SSL_ROLLBACK_DETECTION??
216 // XXXX SSL_ENABLE_ALPN??
218 // Force client-mode or server_mode.
219 s = SSL_OptionSet(ctx->ctx,
220 is_client ? SSL_HANDSHAKE_AS_CLIENT : SSL_HANDSHAKE_AS_SERVER,
221 PR_TRUE);
222 if (s != SECSuccess)
223 goto err;
225 // Disable everything before TLS 1.0; support everything else.
227 SSLVersionRange vrange;
228 memset(&vrange, 0, sizeof(vrange));
229 s = SSL_VersionRangeGetSupported(ssl_variant_stream, &vrange);
230 if (s != SECSuccess)
231 goto err;
232 if (vrange.min < SSL_LIBRARY_VERSION_TLS_1_0)
233 vrange.min = SSL_LIBRARY_VERSION_TLS_1_0;
234 s = SSL_VersionRangeSet(ctx->ctx, &vrange);
235 if (s != SECSuccess)
236 goto err;
239 // Only support strong ciphers.
241 const PRUint16 *ciphers = SSL_GetImplementedCiphers();
242 const PRUint16 n_ciphers = SSL_GetNumImplementedCiphers();
243 PRUint16 i;
244 for (i = 0; i < n_ciphers; ++i) {
245 SSLCipherSuiteInfo info;
246 memset(&info, 0, sizeof(info));
247 s = SSL_GetCipherSuiteInfo(ciphers[i], &info, sizeof(info));
248 if (s != SECSuccess)
249 goto err;
250 if (BUG(info.cipherSuite != ciphers[i]))
251 goto err;
252 int disable = info.effectiveKeyBits < 128 ||
253 info.macBits < 128 ||
254 !we_like_ssl_cipher(info.symCipher) ||
255 !we_like_ssl_kea(info.keaType) ||
256 !we_like_mac_algorithm(info.macAlgorithm) ||
257 !we_like_auth_type(info.authType)/* Requires NSS 3.24 */;
259 s = SSL_CipherPrefSet(ctx->ctx, ciphers[i],
260 disable ? PR_FALSE : PR_TRUE);
261 if (s != SECSuccess)
262 goto err;
266 // Only use DH and ECDH keys once.
267 s = SSL_OptionSet(ctx->ctx, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
268 if (s != SECSuccess)
269 goto err;
271 // don't cache sessions.
272 s = SSL_OptionSet(ctx->ctx, SSL_NO_CACHE, PR_TRUE);
273 if (s != SECSuccess)
274 goto err;
276 // Enable DH.
277 s = SSL_OptionSet(ctx->ctx, SSL_ENABLE_SERVER_DHE, PR_TRUE);
278 if (s != SECSuccess)
279 goto err;
281 // Set DH and ECDH groups.
282 SSLNamedGroup groups[] = {
283 ssl_grp_ec_curve25519,
284 ssl_grp_ec_secp256r1,
285 ssl_grp_ec_secp224r1,
286 ssl_grp_ffdhe_2048,
288 s = SSL_NamedGroupConfig(ctx->ctx, groups, ARRAY_LENGTH(groups));
289 if (s != SECSuccess)
290 goto err;
292 // These features are off by default, so we don't need to disable them:
293 // Session tickets
294 // Renegotiation
295 // Compression
297 goto done;
298 err:
299 tor_tls_context_decref(ctx);
300 ctx = NULL;
301 done:
302 return ctx;
305 void
306 tor_tls_context_impl_free_(tor_tls_context_impl_t *ctx)
308 if (!ctx)
309 return;
310 PR_Close(ctx);
313 void
314 tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz)
316 (void)tls;
317 (void)buf;
318 (void)sz;
319 // AFAICT, NSS doesn't expose its internal state.
320 buf[0]=0;
323 void
324 tor_tls_init(void)
326 tor_nss_countbytes_init();
329 void
330 tls_log_errors(tor_tls_t *tls, int severity, int domain,
331 const char *doing)
333 /* This implementation is a little different for NSS than it is for OpenSSL
334 -- it logs the last error whether anything actually failed or not. So we
335 have to only call it when something has gone wrong and we have a real
336 error to report. */
338 (void)tls;
339 PRErrorCode code = PORT_GetError();
341 const char *addr = tls ? tls->address : NULL;
342 const char *string = PORT_ErrorToString(code);
343 const char *name = PORT_ErrorToName(code);
344 char buf[16];
345 if (!string)
346 string = "<unrecognized>";
347 if (!name) {
348 tor_snprintf(buf, sizeof(buf), "%d", code);
349 name = buf;
352 const char *with = addr ? " with " : "";
353 addr = addr ? addr : "";
354 if (doing) {
355 log_fn(severity, domain, "TLS error %s while %s%s%s: %s",
356 name, doing, with, addr, string);
357 } else {
358 log_fn(severity, domain, "TLS error %s%s%s: %s", name, string,
359 with, addr);
363 tor_tls_t *
364 tor_tls_new(tor_socket_t sock, int is_server)
366 (void)sock;
367 tor_tls_context_t *ctx = tor_tls_context_get(is_server);
369 PRFileDesc *tcp = NULL;
370 if (SOCKET_OK(sock)) {
371 tcp = PR_ImportTCPSocket(sock);
372 } else {
373 tcp = PR_NewTCPSocket();
376 if (!tcp)
377 return NULL;
379 PRFileDesc *count = tor_wrap_prfiledesc_with_byte_counter(tcp);
380 if (! count)
381 return NULL;
383 PRFileDesc *ssl = SSL_ImportFD(ctx->ctx, count);
384 if (!ssl) {
385 PR_Close(tcp);
386 return NULL;
389 tor_tls_t *tls = tor_malloc_zero(sizeof(tor_tls_t));
390 tls->magic = TOR_TLS_MAGIC;
391 tls->context = ctx;
392 tor_tls_context_incref(ctx);
393 tls->ssl = ssl;
394 tls->socket = sock;
395 tls->state = TOR_TLS_ST_HANDSHAKE;
396 tls->isServer = !!is_server;
398 if (!is_server) {
399 /* Set a random SNI */
400 char *fake_hostname = crypto_random_hostname(4,25, "www.",".com");
401 SSL_SetURL(tls->ssl, fake_hostname);
402 tor_free(fake_hostname);
404 SECStatus s = SSL_ResetHandshake(ssl, is_server ? PR_TRUE : PR_FALSE);
405 if (s != SECSuccess) {
406 tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "resetting handshake state");
409 return tls;
412 void
413 tor_tls_set_renegotiate_callback(tor_tls_t *tls,
414 void (*cb)(tor_tls_t *, void *arg),
415 void *arg)
417 tor_assert(tls);
418 (void)cb;
419 (void)arg;
421 /* We don't support renegotiation-based TLS with NSS. */
425 * Tell the TLS library that the underlying socket for <b>tls</b> has been
426 * closed, and the library should not attempt to free that socket itself.
428 void
429 tor_tls_release_socket(tor_tls_t *tls)
431 if (! tls)
432 return;
434 /* NSS doesn't have the equivalent of BIO_NO_CLOSE. If you replace the
435 * fd with something that's invalid, it causes a memory leak in PR_Close.
437 * If there were a way to put the PRFileDesc into the CLOSED state, that
438 * would prevent it from closing its fd -- but there doesn't seem to be a
439 * supported way to do that either.
441 * So instead: we make a new sacrificial socket, and replace the original
442 * socket with that one. This seems to be the best we can do, until we
443 * redesign the mainloop code enough to make this function unnecessary.
445 tor_socket_t sock =
446 tor_open_socket_nonblocking(AF_INET, SOCK_STREAM, IPPROTO_TCP);
447 if (! SOCKET_OK(sock)) {
448 log_warn(LD_NET, "Out of sockets when trying to shut down an NSS "
449 "connection");
450 return;
453 PRFileDesc *tcp = PR_GetIdentitiesLayer(tls->ssl, PR_NSPR_IO_LAYER);
454 if (BUG(! tcp)) {
455 return;
458 PR_ChangeFileDescNativeHandle(tcp, sock);
459 /* Tell our socket accounting layer that we don't own this socket any more:
460 * NSS is about to free it for us. */
461 tor_release_socket_ownership(sock);
464 void
465 tor_tls_impl_free_(tor_tls_impl_t *tls)
467 // XXXX This will close the underlying fd, which our OpenSSL version does
468 // not do!
469 if (!tls)
470 return;
472 PR_Close(tls);
476 tor_tls_peer_has_cert(tor_tls_t *tls)
478 CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
479 int result = (cert != NULL);
480 CERT_DestroyCertificate(cert);
481 return result;
484 MOCK_IMPL(tor_x509_cert_t *,
485 tor_tls_get_peer_cert,(tor_tls_t *tls))
487 CERTCertificate *cert = SSL_PeerCertificate(tls->ssl);
488 if (cert)
489 return tor_x509_cert_new(cert);
490 else
491 return NULL;
494 MOCK_IMPL(tor_x509_cert_t *,
495 tor_tls_get_own_cert,(tor_tls_t *tls))
497 tor_assert(tls);
498 CERTCertificate *cert = SSL_LocalCertificate(tls->ssl);
499 if (cert)
500 return tor_x509_cert_new(cert);
501 else
502 return NULL;
505 MOCK_IMPL(int,
506 tor_tls_read, (tor_tls_t *tls, char *cp, size_t len))
508 tor_assert(tls);
509 tor_assert(cp);
510 tor_assert(len < INT_MAX);
512 PRInt32 rv = PR_Read(tls->ssl, cp, (int)len);
513 // log_debug(LD_NET, "PR_Read(%zu) returned %d", n, (int)rv);
514 if (rv > 0) {
515 return rv;
517 if (rv == 0)
518 return TOR_TLS_CLOSE;
519 PRErrorCode err = PORT_GetError();
520 if (err == PR_WOULD_BLOCK_ERROR) {
521 return TOR_TLS_WANTREAD; // XXXX ????
522 } else {
523 tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "reading"); // XXXX
524 return TOR_TLS_ERROR_MISC; // ????
529 tor_tls_write(tor_tls_t *tls, const char *cp, size_t n)
531 tor_assert(tls);
532 tor_assert(cp || n == 0);
533 tor_assert(n < INT_MAX);
535 PRInt32 rv = PR_Write(tls->ssl, cp, (int)n);
536 // log_debug(LD_NET, "PR_Write(%zu) returned %d", n, (int)rv);
537 if (rv > 0) {
538 return rv;
540 if (rv == 0)
541 return TOR_TLS_ERROR_MISC;
542 PRErrorCode err = PORT_GetError();
544 if (err == PR_WOULD_BLOCK_ERROR) {
545 return TOR_TLS_WANTWRITE; // XXXX ????
546 } else {
547 tls_log_errors(tls, LOG_NOTICE, LD_CRYPTO, "writing"); // XXXX
548 return TOR_TLS_ERROR_MISC; // ????
553 tor_tls_handshake(tor_tls_t *tls)
555 tor_assert(tls);
556 tor_assert(tls->state == TOR_TLS_ST_HANDSHAKE);
558 SECStatus s = SSL_ForceHandshake(tls->ssl);
559 if (s == SECSuccess) {
560 tls->state = TOR_TLS_ST_OPEN;
561 log_debug(LD_NET, "SSL handshake is supposedly complete.");
562 return tor_tls_finish_handshake(tls);
564 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR)
565 return TOR_TLS_WANTREAD; /* XXXX What about wantwrite? */
567 return TOR_TLS_ERROR_MISC; // XXXX
571 tor_tls_finish_handshake(tor_tls_t *tls)
573 tor_assert(tls);
574 // We don't need to do any of the weird handshake nonsense stuff on NSS,
575 // since we only support recent handshakes.
576 return TOR_TLS_DONE;
579 void
580 tor_tls_unblock_renegotiation(tor_tls_t *tls)
582 tor_assert(tls);
583 /* We don't support renegotiation with NSS. */
586 void
587 tor_tls_block_renegotiation(tor_tls_t *tls)
589 tor_assert(tls);
590 /* We don't support renegotiation with NSS. */
593 void
594 tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls)
596 tor_assert(tls);
597 /* We don't support renegotiation with NSS. */
601 tor_tls_get_pending_bytes(tor_tls_t *tls)
603 tor_assert(tls);
604 int n = SSL_DataPending(tls->ssl);
605 if (n < 0) {
606 tls_log_errors(tls, LOG_WARN, LD_CRYPTO, "looking up pending bytes");
607 return 0;
609 return (int)n;
612 size_t
613 tor_tls_get_forced_write_size(tor_tls_t *tls)
615 tor_assert(tls);
616 /* NSS doesn't have the same "forced write" restriction as openssl. */
617 return 0;
620 void
621 tor_tls_get_n_raw_bytes(tor_tls_t *tls,
622 size_t *n_read, size_t *n_written)
624 tor_assert(tls);
625 tor_assert(n_read);
626 tor_assert(n_written);
627 uint64_t r, w;
628 if (tor_get_prfiledesc_byte_counts(tls->ssl, &r, &w) < 0) {
629 *n_read = *n_written = 0;
630 return;
633 *n_read = (size_t)(r - tls->last_read_count);
634 *n_written = (size_t)(w - tls->last_write_count);
636 tls->last_read_count = r;
637 tls->last_write_count = w;
641 tor_tls_get_buffer_sizes(tor_tls_t *tls,
642 size_t *rbuf_capacity, size_t *rbuf_bytes,
643 size_t *wbuf_capacity, size_t *wbuf_bytes)
645 tor_assert(tls);
646 tor_assert(rbuf_capacity);
647 tor_assert(rbuf_bytes);
648 tor_assert(wbuf_capacity);
649 tor_assert(wbuf_bytes);
651 /* This is an acceptable way to say "we can't measure this." */
652 return -1;
655 MOCK_IMPL(double,
656 tls_get_write_overhead_ratio, (void))
658 /* XXX We don't currently have a way to measure this in NSS; we could do that
659 * XXX with a PRIO layer, but it'll take a little coding. */
660 return 0.95;
664 tor_tls_used_v1_handshake(tor_tls_t *tls)
666 tor_assert(tls);
667 /* We don't support or allow the V1 handshake with NSS.
669 return 0;
673 tor_tls_server_got_renegotiate(tor_tls_t *tls)
675 tor_assert(tls);
676 return 0; /* We don't support renegotiation with NSS */
679 MOCK_IMPL(int,
680 tor_tls_cert_matches_key,(const tor_tls_t *tls,
681 const struct tor_x509_cert_t *cert))
683 tor_assert(tls);
684 tor_assert(cert);
685 int rv = 0;
687 CERTCertificate *peercert = SSL_PeerCertificate(tls->ssl);
688 if (!peercert)
689 goto done;
690 CERTSubjectPublicKeyInfo *peer_info = &peercert->subjectPublicKeyInfo;
691 CERTSubjectPublicKeyInfo *cert_info = &cert->cert->subjectPublicKeyInfo;
692 rv = SECOID_CompareAlgorithmID(&peer_info->algorithm,
693 &cert_info->algorithm) == 0 &&
694 SECITEM_ItemsAreEqual(&peer_info->subjectPublicKey,
695 &cert_info->subjectPublicKey);
697 done:
698 if (peercert)
699 CERT_DestroyCertificate(peercert);
700 return rv;
703 MOCK_IMPL(int,
704 tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out))
706 tor_assert(tls);
707 tor_assert(secrets_out);
709 /* There's no way to get this information out of NSS. */
711 return -1;
714 MOCK_IMPL(int,
715 tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out,
716 const uint8_t *context,
717 size_t context_len,
718 const char *label))
720 tor_assert(tls);
721 tor_assert(secrets_out);
722 tor_assert(context);
723 tor_assert(label);
724 tor_assert(strlen(label) <= UINT_MAX);
725 tor_assert(context_len <= UINT_MAX);
727 SECStatus s;
728 s = SSL_ExportKeyingMaterial(tls->ssl,
729 label, (unsigned)strlen(label),
730 PR_TRUE, context, (unsigned)context_len,
731 secrets_out, DIGEST256_LEN);
733 return (s == SECSuccess) ? 0 : -1;
736 const char *
737 tor_tls_get_ciphersuite_name(tor_tls_t *tls)
739 tor_assert(tls);
741 SSLChannelInfo channel_info;
742 SSLCipherSuiteInfo cipher_info;
744 memset(&channel_info, 0, sizeof(channel_info));
745 memset(&cipher_info, 0, sizeof(cipher_info));
747 SECStatus s = SSL_GetChannelInfo(tls->ssl,
748 &channel_info, sizeof(channel_info));
749 if (s != SECSuccess)
750 return NULL;
752 s = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
753 &cipher_info, sizeof(cipher_info));
754 if (s != SECSuccess)
755 return NULL;
757 return cipher_info.cipherSuiteName;
760 /** The group we should use for ecdhe when none was selected. */
761 #define SEC_OID_TOR_DEFAULT_ECDHE_GROUP SEC_OID_ANSIX962_EC_PRIME256V1
764 evaluate_ecgroup_for_tls(const char *ecgroup)
766 SECOidTag tag;
768 if (!ecgroup)
769 tag = SEC_OID_TOR_DEFAULT_ECDHE_GROUP;
770 else if (!strcasecmp(ecgroup, "P256"))
771 tag = SEC_OID_ANSIX962_EC_PRIME256V1;
772 else if (!strcasecmp(ecgroup, "P224"))
773 tag = SEC_OID_SECG_EC_SECP224R1;
774 else
775 return 0;
777 /* I don't think we need any additional tests here for NSS */
778 (void) tag;
780 return 1;
783 static SECStatus
784 always_accept_cert_cb(void *arg, PRFileDesc *ssl, PRBool checkSig,
785 PRBool isServer)
787 (void)arg;
788 (void)ssl;
789 (void)checkSig;
790 (void)isServer;
791 return SECSuccess;