1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // Original author: ekr@rtfm.com
9 #include "transportlayerdtls.h"
15 #include "dtlsidentity.h"
18 #include "mozilla/Telemetry.h"
19 #include "mozilla/UniquePtr.h"
20 #include "mozilla/Unused.h"
22 #include "nsComponentManagerUtils.h"
23 #include "nsComponentManagerUtils.h"
24 #include "nsIEventTarget.h"
26 #include "nsServiceManagerUtils.h"
29 #include "transportflow.h"
34 MOZ_MTLOG_MODULE("mtransport")
36 static PRDescIdentity transport_layer_identity
= PR_INVALID_IO_LAYER
;
38 // TODO: Implement a mode for this where
39 // the channel is not ready until confirmed externally
40 // (e.g., after cert check).
42 #define UNIMPLEMENTED \
44 "Call to unimplemented function "<< __FUNCTION__); \
46 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0)
48 #define MAX_ALPN_LENGTH 255
50 // We need to adapt the NSPR/libssl model to the TransportFlow model.
51 // The former wants pull semantics and TransportFlow wants push.
53 // - A TransportLayerDtls assumes it is sitting on top of another
54 // TransportLayer, which means that events come in asynchronously.
55 // - NSS (libssl) wants to sit on top of a PRFileDesc and poll.
56 // - The TransportLayerNSPRAdapter is a PRFileDesc containing a
58 // - When TransportLayerDtls.PacketReceived() is called, we insert
59 // the packets in the FIFO and then do a PR_Recv() on the NSS
60 // PRFileDesc, which eventually reads off the FIFO.
62 // All of this stuff is assumed to happen solely in a single thread
63 // (generally the SocketTransportService thread)
65 void TransportLayerNSPRAdapter::PacketReceived(MediaPacket
& packet
) {
67 input_
.push(new MediaPacket(std::move(packet
)));
71 int32_t TransportLayerNSPRAdapter::Recv(void *buf
, int32_t buflen
) {
73 PR_SetError(PR_WOULD_BLOCK_ERROR
, 0);
77 MediaPacket
* front
= input_
.front();
78 int32_t count
= static_cast<int32_t>(front
->len());
81 MOZ_ASSERT(false, "Not enough buffer space to receive into");
82 PR_SetError(PR_BUFFER_OVERFLOW_ERROR
, 0);
86 memcpy(buf
, front
->data(), count
);
94 int32_t TransportLayerNSPRAdapter::Write(const void *buf
, int32_t length
) {
96 MOZ_MTLOG(ML_WARNING
, "Writing to disabled transport layer");
102 packet
.Copy(static_cast<const uint8_t*>(buf
), static_cast<size_t>(length
));
104 TransportResult r
= output_
->SendPacket(packet
);
109 if (r
== TE_WOULDBLOCK
) {
110 PR_SetError(PR_WOULD_BLOCK_ERROR
, 0);
112 PR_SetError(PR_IO_ERROR
, 0);
119 // Implementation of NSPR methods
120 static PRStatus
TransportLayerClose(PRFileDesc
*f
) {
125 static int32_t TransportLayerRead(PRFileDesc
*f
, void *buf
, int32_t length
) {
130 static int32_t TransportLayerWrite(PRFileDesc
*f
, const void *buf
, int32_t length
) {
131 TransportLayerNSPRAdapter
*io
= reinterpret_cast<TransportLayerNSPRAdapter
*>(f
->secret
);
132 return io
->Write(buf
, length
);
135 static int32_t TransportLayerAvailable(PRFileDesc
*f
) {
140 int64_t TransportLayerAvailable64(PRFileDesc
*f
) {
145 static PRStatus
TransportLayerSync(PRFileDesc
*f
) {
150 static int32_t TransportLayerSeek(PRFileDesc
*f
, int32_t offset
,
156 static int64_t TransportLayerSeek64(PRFileDesc
*f
, int64_t offset
,
162 static PRStatus
TransportLayerFileInfo(PRFileDesc
*f
, PRFileInfo
*info
) {
167 static PRStatus
TransportLayerFileInfo64(PRFileDesc
*f
, PRFileInfo64
*info
) {
172 static int32_t TransportLayerWritev(PRFileDesc
*f
, const PRIOVec
*iov
,
173 int32_t iov_size
, PRIntervalTime to
) {
178 static PRStatus
TransportLayerConnect(PRFileDesc
*f
, const PRNetAddr
*addr
,
184 static PRFileDesc
*TransportLayerAccept(PRFileDesc
*sd
, PRNetAddr
*addr
,
190 static PRStatus
TransportLayerBind(PRFileDesc
*f
, const PRNetAddr
*addr
) {
195 static PRStatus
TransportLayerListen(PRFileDesc
*f
, int32_t depth
) {
200 static PRStatus
TransportLayerShutdown(PRFileDesc
*f
, int32_t how
) {
201 // This is only called from NSS when we are the server and the client refuses
202 // to provide a certificate. In this case, the handshake is destined for
203 // failure, so we will just let this pass.
204 TransportLayerNSPRAdapter
*io
= reinterpret_cast<TransportLayerNSPRAdapter
*>(f
->secret
);
205 io
->SetEnabled(false);
209 // This function does not support peek, or waiting until `to`
210 static int32_t TransportLayerRecv(PRFileDesc
*f
, void *buf
, int32_t buflen
,
211 int32_t flags
, PRIntervalTime to
) {
212 MOZ_ASSERT(flags
== 0);
214 PR_SetError(PR_NOT_IMPLEMENTED_ERROR
, 0);
218 TransportLayerNSPRAdapter
*io
= reinterpret_cast<TransportLayerNSPRAdapter
*>(f
->secret
);
219 return io
->Recv(buf
, buflen
);
222 // Note: this is always nonblocking and assumes a zero timeout.
223 static int32_t TransportLayerSend(PRFileDesc
*f
, const void *buf
, int32_t amount
,
224 int32_t flags
, PRIntervalTime to
) {
225 int32_t written
= TransportLayerWrite(f
, buf
, amount
);
229 static int32_t TransportLayerRecvfrom(PRFileDesc
*f
, void *buf
, int32_t amount
,
230 int32_t flags
, PRNetAddr
*addr
, PRIntervalTime to
) {
235 static int32_t TransportLayerSendto(PRFileDesc
*f
, const void *buf
, int32_t amount
,
236 int32_t flags
, const PRNetAddr
*addr
, PRIntervalTime to
) {
241 static int16_t TransportLayerPoll(PRFileDesc
*f
, int16_t in_flags
, int16_t *out_flags
) {
246 static int32_t TransportLayerAcceptRead(PRFileDesc
*sd
, PRFileDesc
**nd
,
248 void *buf
, int32_t amount
, PRIntervalTime t
) {
253 static int32_t TransportLayerTransmitFile(PRFileDesc
*sd
, PRFileDesc
*f
,
254 const void *headers
, int32_t hlen
,
255 PRTransmitFileFlags flags
, PRIntervalTime t
) {
260 static PRStatus
TransportLayerGetpeername(PRFileDesc
*f
, PRNetAddr
*addr
) {
261 // TODO: Modify to return unique names for each channel
262 // somehow, as opposed to always the same static address. The current
263 // implementation messes up the session cache, which is why it's off
265 addr
->inet
.family
= PR_AF_INET
;
272 static PRStatus
TransportLayerGetsockname(PRFileDesc
*f
, PRNetAddr
*addr
) {
277 static PRStatus
TransportLayerGetsockoption(PRFileDesc
*f
, PRSocketOptionData
*opt
) {
278 switch (opt
->option
) {
279 case PR_SockOpt_Nonblocking
:
280 opt
->value
.non_blocking
= PR_TRUE
;
290 // Imitate setting socket options. These are mostly noops.
291 static PRStatus
TransportLayerSetsockoption(PRFileDesc
*f
,
292 const PRSocketOptionData
*opt
) {
293 switch (opt
->option
) {
294 case PR_SockOpt_Nonblocking
:
296 case PR_SockOpt_NoDelay
:
306 static int32_t TransportLayerSendfile(PRFileDesc
*out
, PRSendFileData
*in
,
307 PRTransmitFileFlags flags
, PRIntervalTime to
) {
312 static PRStatus
TransportLayerConnectContinue(PRFileDesc
*f
, int16_t flags
) {
317 static int32_t TransportLayerReserved(PRFileDesc
*f
) {
322 static const struct PRIOMethods TransportLayerMethods
= {
327 TransportLayerAvailable
,
328 TransportLayerAvailable64
,
331 TransportLayerSeek64
,
332 TransportLayerFileInfo
,
333 TransportLayerFileInfo64
,
334 TransportLayerWritev
,
335 TransportLayerConnect
,
336 TransportLayerAccept
,
338 TransportLayerListen
,
339 TransportLayerShutdown
,
342 TransportLayerRecvfrom
,
343 TransportLayerSendto
,
345 TransportLayerAcceptRead
,
346 TransportLayerTransmitFile
,
347 TransportLayerGetsockname
,
348 TransportLayerGetpeername
,
349 TransportLayerReserved
,
350 TransportLayerReserved
,
351 TransportLayerGetsockoption
,
352 TransportLayerSetsockoption
,
353 TransportLayerSendfile
,
354 TransportLayerConnectContinue
,
355 TransportLayerReserved
,
356 TransportLayerReserved
,
357 TransportLayerReserved
,
358 TransportLayerReserved
361 TransportLayerDtls::~TransportLayerDtls() {
362 // Destroy the NSS instance first so it can still send out an alert before
363 // we disable the nspr_io_adapter_.
365 nspr_io_adapter_
->SetEnabled(false);
371 nsresult
TransportLayerDtls::InitInternal() {
372 // Get the transport service as an event target
374 target_
= do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID
, &rv
);
377 MOZ_MTLOG(ML_ERROR
, "Couldn't get socket transport service");
381 timer_
= NS_NewTimer();
383 MOZ_MTLOG(ML_ERROR
, "Couldn't get timer");
391 void TransportLayerDtls::WasInserted() {
392 // Connect to the lower layers
394 TL_SET_STATE(TS_ERROR
);
399 // Set the permitted and default ALPN identifiers.
400 // The default is here to allow for peers that don't want to negotiate ALPN
401 // in that case, the default string will be reported from GetNegotiatedAlpn().
402 // Setting the default to the empty string causes the transport layer to fail
403 // if ALPN is not negotiated.
404 // Note: we only support Unicode strings here, which are encoded into UTF-8,
405 // even though ALPN ostensibly allows arbitrary octet sequences.
406 nsresult
TransportLayerDtls::SetAlpn(
407 const std::set
<std::string
>& alpn_allowed
,
408 const std::string
& alpn_default
) {
410 alpn_allowed_
= alpn_allowed
;
411 alpn_default_
= alpn_default
;
417 nsresult
TransportLayerDtls::SetVerificationAllowAll() {
418 // Defensive programming
419 if (verification_mode_
!= VERIFY_UNSET
)
420 return NS_ERROR_ALREADY_INITIALIZED
;
422 verification_mode_
= VERIFY_ALLOW_ALL
;
428 TransportLayerDtls::SetVerificationDigest(const std::string digest_algorithm
,
429 const unsigned char *digest_value
,
431 // Defensive programming
432 if (verification_mode_
!= VERIFY_UNSET
&&
433 verification_mode_
!= VERIFY_DIGEST
) {
434 return NS_ERROR_ALREADY_INITIALIZED
;
437 // Note that we do not sanity check these values for length.
438 // We merely ensure they will fit into the buffer.
439 // TODO: is there a Data construct we could use?
440 if (digest_len
> kMaxDigestLength
)
441 return NS_ERROR_INVALID_ARG
;
443 digests_
.push_back(new VerificationDigest(
444 digest_algorithm
, digest_value
, digest_len
));
446 verification_mode_
= VERIFY_DIGEST
;
451 // These are the named groups that we will allow.
452 static const SSLNamedGroup NamedGroupPreferences
[] = {
453 ssl_grp_ec_curve25519
,
454 ssl_grp_ec_secp256r1
,
455 ssl_grp_ec_secp384r1
,
460 // TODO: make sure this is called from STS. Otherwise
461 // we have thread safety issues
462 bool TransportLayerDtls::Setup() {
467 MOZ_MTLOG(ML_ERROR
, "DTLS layer with nothing below. This is useless");
470 nspr_io_adapter_
= MakeUnique
<TransportLayerNSPRAdapter
>(downward_
);
473 MOZ_MTLOG(ML_ERROR
, "Can't start DTLS without an identity");
477 if (verification_mode_
== VERIFY_UNSET
) {
479 "Can't start DTLS without specifying a verification mode");
483 if (transport_layer_identity
== PR_INVALID_IO_LAYER
) {
484 transport_layer_identity
= PR_GetUniqueIdentity("nssstreamadapter");
487 UniquePRFileDesc
pr_fd(PR_CreateIOLayerStub(transport_layer_identity
,
488 &TransportLayerMethods
));
489 MOZ_ASSERT(pr_fd
!= nullptr);
492 pr_fd
->secret
= reinterpret_cast<PRFilePrivate
*>(nspr_io_adapter_
.get());
494 UniquePRFileDesc
ssl_fd(DTLS_ImportFD(nullptr, pr_fd
.get()));
495 MOZ_ASSERT(ssl_fd
!= nullptr); // This should never happen
500 Unused
<< pr_fd
.release(); // ownership transfered to ssl_fd;
502 if (role_
== CLIENT
) {
503 MOZ_MTLOG(ML_INFO
, "Setting up DTLS as client");
504 rv
= SSL_GetClientAuthDataHook(ssl_fd
.get(), GetClientAuthDataHook
,
506 if (rv
!= SECSuccess
) {
507 MOZ_MTLOG(ML_ERROR
, "Couldn't set identity");
511 MOZ_MTLOG(ML_INFO
, "Setting up DTLS as server");
513 rv
= SSL_ConfigSecureServer(ssl_fd
.get(), identity_
->cert().get(),
514 identity_
->privkey().get(),
515 identity_
->auth_type());
516 if (rv
!= SECSuccess
) {
517 MOZ_MTLOG(ML_ERROR
, "Couldn't set identity");
521 UniqueCERTCertList
zero_certs(CERT_NewCertList());
522 rv
= SSL_SetTrustAnchors(ssl_fd
.get(), zero_certs
.get());
523 if (rv
!= SECSuccess
) {
524 MOZ_MTLOG(ML_ERROR
, "Couldn't set trust anchors");
528 // Insist on a certificate from the client
529 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_REQUEST_CERTIFICATE
, PR_TRUE
);
530 if (rv
!= SECSuccess
) {
531 MOZ_MTLOG(ML_ERROR
, "Couldn't request certificate");
535 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_REQUIRE_CERTIFICATE
, PR_TRUE
);
536 if (rv
!= SECSuccess
) {
537 MOZ_MTLOG(ML_ERROR
, "Couldn't require certificate");
542 // Require TLS 1.1 or 1.2. Perhaps some day in the future we will allow TLS
543 // 1.0 for stream modes.
544 SSLVersionRange version_range
= {
545 SSL_LIBRARY_VERSION_TLS_1_1
,
546 SSL_LIBRARY_VERSION_TLS_1_2
549 rv
= SSL_VersionRangeSet(ssl_fd
.get(), &version_range
);
550 if (rv
!= SECSuccess
) {
551 MOZ_MTLOG(ML_ERROR
, "Can't disable SSLv3");
555 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_SESSION_TICKETS
, PR_FALSE
);
556 if (rv
!= SECSuccess
) {
557 MOZ_MTLOG(ML_ERROR
, "Couldn't disable session tickets");
561 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_NO_CACHE
, PR_TRUE
);
562 if (rv
!= SECSuccess
) {
563 MOZ_MTLOG(ML_ERROR
, "Couldn't disable session caching");
567 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_DEFLATE
, PR_FALSE
);
568 if (rv
!= SECSuccess
) {
569 MOZ_MTLOG(ML_ERROR
, "Couldn't disable deflate");
573 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_RENEGOTIATION
,
574 SSL_RENEGOTIATE_NEVER
);
575 if (rv
!= SECSuccess
) {
576 MOZ_MTLOG(ML_ERROR
, "Couldn't disable renegotiation");
580 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_FALSE_START
, PR_FALSE
);
581 if (rv
!= SECSuccess
) {
582 MOZ_MTLOG(ML_ERROR
, "Couldn't disable false start");
586 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_NO_LOCKS
, PR_TRUE
);
587 if (rv
!= SECSuccess
) {
588 MOZ_MTLOG(ML_ERROR
, "Couldn't disable locks");
592 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_REUSE_SERVER_ECDHE_KEY
, PR_FALSE
);
593 if (rv
!= SECSuccess
) {
594 MOZ_MTLOG(ML_ERROR
, "Couldn't disable ECDHE key reuse");
598 if (!SetupCipherSuites(ssl_fd
)) {
602 rv
= SSL_NamedGroupConfig(ssl_fd
.get(), NamedGroupPreferences
,
603 mozilla::ArrayLength(NamedGroupPreferences
));
604 if (rv
!= SECSuccess
) {
605 MOZ_MTLOG(ML_ERROR
, "Couldn't set named groups");
609 // Certificate validation
610 rv
= SSL_AuthCertificateHook(ssl_fd
.get(), AuthCertificateHook
,
611 reinterpret_cast<void *>(this));
612 if (rv
!= SECSuccess
) {
613 MOZ_MTLOG(ML_ERROR
, "Couldn't set certificate validation hook");
617 if (!SetupAlpn(ssl_fd
)) {
621 // Now start the handshake
622 rv
= SSL_ResetHandshake(ssl_fd
.get(), role_
== SERVER
? PR_TRUE
: PR_FALSE
);
623 if (rv
!= SECSuccess
) {
624 MOZ_MTLOG(ML_ERROR
, "Couldn't reset handshake");
627 ssl_fd_
= std::move(ssl_fd
);
629 // Finally, get ready to receive data
630 downward_
->SignalStateChange
.connect(this, &TransportLayerDtls::StateChange
);
631 downward_
->SignalPacketReceived
.connect(this, &TransportLayerDtls::PacketReceived
);
633 if (downward_
->state() == TS_OPEN
) {
634 TL_SET_STATE(TS_CONNECTING
);
641 bool TransportLayerDtls::SetupAlpn(UniquePRFileDesc
& ssl_fd
) const {
642 if (alpn_allowed_
.empty()) {
646 SECStatus rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_NPN
, PR_FALSE
);
647 if (rv
!= SECSuccess
) {
648 MOZ_MTLOG(ML_ERROR
, "Couldn't disable NPN");
652 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_ALPN
, PR_TRUE
);
653 if (rv
!= SECSuccess
) {
654 MOZ_MTLOG(ML_ERROR
, "Couldn't enable ALPN");
658 unsigned char buf
[MAX_ALPN_LENGTH
];
660 for (const auto& tag
: alpn_allowed_
) {
661 if ((offset
+ 1 + tag
.length()) >= sizeof(buf
)) {
662 MOZ_MTLOG(ML_ERROR
, "ALPN too long");
665 buf
[offset
++] = tag
.length();
666 memcpy(buf
+ offset
, tag
.c_str(), tag
.length());
667 offset
+= tag
.length();
669 rv
= SSL_SetNextProtoNego(ssl_fd
.get(), buf
, offset
);
670 if (rv
!= SECSuccess
) {
671 MOZ_MTLOG(ML_ERROR
, "Couldn't set ALPN string");
677 // Ciphers we need to enable. These are on by default in standard firefox
678 // builds, but can be disabled with prefs and they aren't on in our unit tests
679 // since that uses NSS default configuration.
681 // Only override prefs to comply with MUST statements in the security-arch doc.
682 // Anything outside this list is governed by the usual combination of policy
683 // and user preferences.
684 static const uint32_t EnabledCiphers
[] = {
685 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
,
686 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
689 // Disable all NSS suites modes without PFS or with old and rusty ciphersuites.
690 // Anything outside this list is governed by the usual combination of policy
691 // and user preferences.
692 static const uint32_t DisabledCiphers
[] = {
693 // Bug 1310061: disable all SHA384 ciphers until fixed
694 TLS_AES_256_GCM_SHA384
,
695 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
,
696 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
,
697 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
,
698 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
,
699 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
,
700 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
,
702 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
,
703 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
704 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
705 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
707 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
,
708 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
,
709 TLS_DHE_DSS_WITH_RC4_128_SHA
,
711 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
712 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
713 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
714 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
715 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
716 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
717 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
718 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
720 TLS_RSA_WITH_AES_128_GCM_SHA256
,
721 TLS_RSA_WITH_AES_256_GCM_SHA384
,
722 TLS_RSA_WITH_AES_128_CBC_SHA
,
723 TLS_RSA_WITH_AES_128_CBC_SHA256
,
724 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
,
725 TLS_RSA_WITH_AES_256_CBC_SHA
,
726 TLS_RSA_WITH_AES_256_CBC_SHA256
,
727 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
,
728 TLS_RSA_WITH_SEED_CBC_SHA
,
729 TLS_RSA_WITH_3DES_EDE_CBC_SHA
,
730 TLS_RSA_WITH_RC4_128_SHA
,
731 TLS_RSA_WITH_RC4_128_MD5
,
733 TLS_DHE_RSA_WITH_DES_CBC_SHA
,
734 TLS_DHE_DSS_WITH_DES_CBC_SHA
,
735 TLS_RSA_WITH_DES_CBC_SHA
,
737 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
738 TLS_ECDHE_RSA_WITH_NULL_SHA
,
739 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
740 TLS_ECDH_RSA_WITH_NULL_SHA
,
741 TLS_RSA_WITH_NULL_SHA
,
742 TLS_RSA_WITH_NULL_SHA256
,
743 TLS_RSA_WITH_NULL_MD5
,
746 bool TransportLayerDtls::SetupCipherSuites(UniquePRFileDesc
& ssl_fd
) {
749 // Set the SRTP ciphers
750 if (!enabled_srtp_ciphers_
.empty()) {
751 rv
= SSL_InstallExtensionHooks(ssl_fd
.get(), ssl_use_srtp_xtn
,
752 TransportLayerDtls::WriteSrtpXtn
, this,
753 TransportLayerDtls::HandleSrtpXtn
, this);
754 if (rv
!= SECSuccess
) {
755 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "unable to set SRTP extension handler");
760 for (const auto& cipher
: EnabledCiphers
) {
761 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Enabling: " << cipher
);
762 rv
= SSL_CipherPrefSet(ssl_fd
.get(), cipher
, PR_TRUE
);
763 if (rv
!= SECSuccess
) {
764 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<<
765 "Unable to enable suite: " << cipher
);
770 for (const auto& cipher
: DisabledCiphers
) {
771 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Disabling: " << cipher
);
773 PRBool enabled
= false;
774 rv
= SSL_CipherPrefGet(ssl_fd
.get(), cipher
, &enabled
);
775 if (rv
!= SECSuccess
) {
776 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<<
777 "Unable to check if suite is enabled: " << cipher
);
781 rv
= SSL_CipherPrefSet(ssl_fd
.get(), cipher
, PR_FALSE
);
782 if (rv
!= SECSuccess
) {
783 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<<
784 "Unable to disable suite: " << cipher
);
793 nsresult
TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite
) const {
796 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "GetCipherSuite passed a nullptr");
797 return NS_ERROR_NULL_POINTER
;
799 if (state_
!= TS_OPEN
) {
800 return NS_ERROR_NOT_AVAILABLE
;
803 SECStatus rv
= SSL_GetChannelInfo(ssl_fd_
.get(), &info
, sizeof(info
));
804 if (rv
!= SECSuccess
) {
805 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "GetCipherSuite can't get channel info");
806 return NS_ERROR_FAILURE
;
808 *cipherSuite
= info
.cipherSuite
;
812 void TransportLayerDtls::StateChange(TransportLayer
*layer
, State state
) {
813 if (state
<= state_
) {
814 MOZ_MTLOG(ML_ERROR
, "Lower layer state is going backwards from ours");
815 TL_SET_STATE(TS_ERROR
);
821 MOZ_ASSERT(false); // Can't happen
826 LAYER_INFO
<< "State change of lower layer to INIT forbidden");
827 TL_SET_STATE(TS_ERROR
);
831 MOZ_MTLOG(ML_INFO
, LAYER_INFO
<< "Lower layer is connecting.");
836 LAYER_INFO
<< "Lower layer is now open; starting TLS");
837 // Async, since the ICE layer might need to send a STUN response, and we
838 // don't want the handshake to start until that is sent.
839 TL_SET_STATE(TS_CONNECTING
);
841 timer_
->SetTarget(target_
);
842 timer_
->InitWithNamedFuncCallback(TimerCallback
,
845 nsITimer::TYPE_ONE_SHOT
,
846 "TransportLayerDtls::TimerCallback");
850 MOZ_MTLOG(ML_INFO
, LAYER_INFO
<< "Lower layer is now closed");
851 TL_SET_STATE(TS_CLOSED
);
855 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Lower layer experienced an error");
856 TL_SET_STATE(TS_ERROR
);
861 void TransportLayerDtls::Handshake() {
862 // Clear the retransmit timer
865 MOZ_ASSERT(state_
== TS_CONNECTING
);
867 SECStatus rv
= SSL_ForceHandshake(ssl_fd_
.get());
869 if (rv
== SECSuccess
) {
871 LAYER_INFO
<< "****** SSL handshake completed ******");
873 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Certificate check never occurred");
874 TL_SET_STATE(TS_ERROR
);
878 // Despite connecting, the connection doesn't have a valid ALPN label.
879 // Forcibly close the connection so that the peer isn't left hanging
880 // (assuming the close_notify isn't dropped).
882 TL_SET_STATE(TS_ERROR
);
885 if (!enabled_srtp_ciphers_
.empty() && srtp_cipher_
== 0) {
886 // We enabled SRTP, but got no cipher, this should have failed.
888 TL_SET_STATE(TS_ERROR
);
892 TL_SET_STATE(TS_OPEN
);
894 RecordCipherTelemetry();
896 int32_t err
= PR_GetError();
898 case SSL_ERROR_RX_MALFORMED_HANDSHAKE
:
899 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Malformed DTLS message; ignoring");
900 // If this were TLS (and not DTLS), this would be fatal, but
901 // here we're required to ignore bad messages, so fall through
903 case PR_WOULD_BLOCK_ERROR
:
904 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "Handshake would have blocked");
905 PRIntervalTime timeout
;
906 rv
= DTLS_GetHandshakeTimeout(ssl_fd_
.get(), &timeout
);
907 if (rv
== SECSuccess
) {
908 uint32_t timeout_ms
= PR_IntervalToMilliseconds(timeout
);
911 LAYER_INFO
<< "Setting DTLS timeout to " << timeout_ms
);
912 timer_
->SetTarget(target_
);
913 timer_
->InitWithNamedFuncCallback(TimerCallback
,
915 nsITimer::TYPE_ONE_SHOT
,
916 "TransportLayerDtls::TimerCallback");
920 const char *err_msg
= PR_ErrorToName(err
);
921 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "DTLS handshake error " << err
<< " ("
923 TL_SET_STATE(TS_ERROR
);
929 // Checks if ALPN was negotiated correctly and returns false if it wasn't.
930 // After this returns successfully, alpn_ will be set to the negotiated
932 bool TransportLayerDtls::CheckAlpn() {
933 if (alpn_allowed_
.empty()) {
937 SSLNextProtoState alpnState
;
938 char chosenAlpn
[MAX_ALPN_LENGTH
];
939 unsigned int chosenAlpnLen
;
940 SECStatus rv
= SSL_GetNextProto(ssl_fd_
.get(), &alpnState
,
941 reinterpret_cast<unsigned char*>(chosenAlpn
),
942 &chosenAlpnLen
, sizeof(chosenAlpn
));
943 if (rv
!= SECSuccess
) {
944 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "ALPN error");
948 case SSL_NEXT_PROTO_SELECTED
:
949 case SSL_NEXT_PROTO_NEGOTIATED
:
952 case SSL_NEXT_PROTO_NO_SUPPORT
:
953 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "ALPN not negotiated, "
954 << (alpn_default_
.empty() ? "failing" : "selecting default"));
955 alpn_
= alpn_default_
;
956 return !alpn_
.empty();
958 case SSL_NEXT_PROTO_NO_OVERLAP
:
959 // This only happens if there is a custom NPN/ALPN callback installed and
960 // that callback doesn't properly handle ALPN.
961 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "error in ALPN selection callback");
964 case SSL_NEXT_PROTO_EARLY_VALUE
:
965 MOZ_CRASH("Unexpected 0-RTT ALPN value");
969 // Warning: NSS won't null terminate the ALPN string for us.
970 std::string
chosen(chosenAlpn
, chosenAlpnLen
);
971 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "Selected ALPN string: " << chosen
);
972 if (alpn_allowed_
.find(chosen
) == alpn_allowed_
.end()) {
973 // Maybe our peer chose a protocol we didn't offer (when we are client), or
974 // something is seriously wrong.
975 std::ostringstream ss
;
976 for (auto i
= alpn_allowed_
.begin(); i
!= alpn_allowed_
.end(); ++i
) {
977 ss
<< (i
== alpn_allowed_
.begin() ? " '" : ", '") << *i
<< "'";
979 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Bad ALPN string: '" << chosen
980 << "'; permitted:" << ss
.str());
988 void TransportLayerDtls::PacketReceived(TransportLayer
* layer
,
989 MediaPacket
& packet
) {
991 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "PacketReceived(" << packet
.len() << ")");
993 if (state_
!= TS_CONNECTING
&& state_
!= TS_OPEN
) {
995 LAYER_INFO
<< "Discarding packet in inappropriate state");
999 if (!packet
.data()) {
1000 // Something ate this, probably the SRTP layer
1004 // not DTLS per RFC 7983
1005 if (packet
.data()[0] < 20 || packet
.data()[0] > 63) {
1009 nspr_io_adapter_
->PacketReceived(packet
);
1010 GetDecryptedPackets();
1014 TransportLayerDtls::GetDecryptedPackets()
1016 // If we're still connecting, try to handshake
1017 if (state_
== TS_CONNECTING
) {
1021 // Now try a recv if we're open, since there might be data left
1022 if (state_
== TS_OPEN
) {
1024 // One packet might contain several DTLS packets
1026 // nICEr uses a 9216 bytes buffer to allow support for jumbo frames
1027 // Can we peek to get a better idea of the actual size?
1028 static const size_t kBufferSize
= 9216;
1029 auto buffer
= MakeUnique
<uint8_t[]>(kBufferSize
);
1030 rv
= PR_Recv(ssl_fd_
.get(), buffer
.get(), kBufferSize
, 0, PR_INTERVAL_NO_WAIT
);
1033 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Read " << rv
<< " bytes from NSS");
1035 packet
.Take(std::move(buffer
), static_cast<size_t>(rv
));
1036 SignalPacketReceived(this, packet
);
1037 } else if (rv
== 0) {
1038 TL_SET_STATE(TS_CLOSED
);
1040 int32_t err
= PR_GetError();
1042 if (err
== PR_WOULD_BLOCK_ERROR
) {
1043 // This gets ignored
1044 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Receive would have blocked");
1046 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "NSS Error " << err
);
1047 TL_SET_STATE(TS_ERROR
);
1054 void TransportLayerDtls::SetState(State state
,
1057 if (state
> state_
) {
1064 handshake_started_
= TimeStamp::Now();
1070 if (state_
== TS_CONNECTING
) {
1071 RecordHandshakeCompletionTelemetry(state
);
1076 MOZ_ASSERT(false, "Invalid state transition");
1079 TransportLayer::SetState(state
, file
, line
);
1082 TransportResult
TransportLayerDtls::SendPacket(MediaPacket
& packet
) {
1084 if (state_
!= TS_OPEN
) {
1085 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Can't call SendPacket() in state "
1090 int32_t rv
= PR_Send(ssl_fd_
.get(), packet
.data(), packet
.len(), 0,
1091 PR_INTERVAL_NO_WAIT
);
1095 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Wrote " << rv
<< " bytes to SSL Layer");
1100 TL_SET_STATE(TS_CLOSED
);
1104 int32_t err
= PR_GetError();
1106 if (err
== PR_WOULD_BLOCK_ERROR
) {
1107 // This gets ignored
1108 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Send would have blocked");
1109 return TE_WOULDBLOCK
;
1112 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "NSS Error " << err
);
1113 TL_SET_STATE(TS_ERROR
);
1117 SECStatus
TransportLayerDtls::GetClientAuthDataHook(void *arg
, PRFileDesc
*fd
,
1118 CERTDistNames
*caNames
,
1119 CERTCertificate
**pRetCert
,
1120 SECKEYPrivateKey
**pRetKey
) {
1121 MOZ_MTLOG(ML_DEBUG
, "Server requested client auth");
1123 TransportLayerDtls
*stream
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1124 stream
->CheckThread();
1126 if (!stream
->identity_
) {
1127 MOZ_MTLOG(ML_ERROR
, "No identity available");
1128 PR_SetError(SSL_ERROR_NO_CERTIFICATE
, 0);
1132 *pRetCert
= CERT_DupCertificate(stream
->identity_
->cert().get());
1134 PR_SetError(PR_OUT_OF_MEMORY_ERROR
, 0);
1138 *pRetKey
= SECKEY_CopyPrivateKey(stream
->identity_
->privkey().get());
1140 CERT_DestroyCertificate(*pRetCert
);
1141 *pRetCert
= nullptr;
1142 PR_SetError(PR_OUT_OF_MEMORY_ERROR
, 0);
1149 nsresult
TransportLayerDtls::SetSrtpCiphers(const std::vector
<uint16_t>& ciphers
) {
1150 enabled_srtp_ciphers_
= std::move(ciphers
);
1154 nsresult
TransportLayerDtls::GetSrtpCipher(uint16_t *cipher
) const {
1156 if (srtp_cipher_
== 0) {
1157 return NS_ERROR_NOT_AVAILABLE
;
1159 *cipher
= srtp_cipher_
;
1163 static uint8_t* WriteUint16(uint8_t* cursor
, uint16_t v
) {
1165 *cursor
++ = v
& 0xff;
1169 static SSLHandshakeType
SrtpXtnServerMessage(PRFileDesc
* fd
) {
1170 SSLPreliminaryChannelInfo preinfo
;
1171 SECStatus rv
= SSL_GetPreliminaryChannelInfo(fd
, &preinfo
, sizeof(preinfo
));
1172 if (rv
!= SECSuccess
) {
1173 MOZ_ASSERT(false, "Can't get version info");
1174 return ssl_hs_client_hello
;
1176 return (preinfo
.protocolVersion
>= SSL_LIBRARY_VERSION_TLS_1_3
)
1177 ? ssl_hs_encrypted_extensions
1178 : ssl_hs_server_hello
;
1181 /* static */ PRBool
TransportLayerDtls::WriteSrtpXtn(
1182 PRFileDesc
* fd
, SSLHandshakeType message
, uint8_t* data
,
1183 unsigned int* len
, unsigned int max_len
, void* arg
) {
1184 auto self
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1186 // ClientHello: send all supported versions.
1187 if (message
== ssl_hs_client_hello
) {
1188 MOZ_ASSERT(self
->role_
== CLIENT
);
1189 MOZ_ASSERT(self
->enabled_srtp_ciphers_
.size(), "Haven't enabled SRTP");
1190 // We will take 2 octets for each cipher, plus a 2 octet length and 1 octet
1191 // for the length of the empty MKI.
1192 if (max_len
< self
->enabled_srtp_ciphers_
.size() * 2 + 3) {
1193 MOZ_ASSERT(false, "Not enough space to send SRTP extension");
1196 uint8_t* cursor
= WriteUint16(data
, self
->enabled_srtp_ciphers_
.size() * 2);
1197 for (auto cs
: self
->enabled_srtp_ciphers_
) {
1198 cursor
= WriteUint16(cursor
, cs
);
1200 *cursor
++ = 0; // MKI is empty
1201 *len
= cursor
- data
;
1205 if (message
== SrtpXtnServerMessage(fd
)) {
1206 MOZ_ASSERT(self
->role_
== SERVER
);
1207 if (!self
->srtp_cipher_
) {
1208 // Not negotiated. Definitely bad, but the connection can fail later.
1212 MOZ_ASSERT(false, "Not enough space to send SRTP extension");
1216 uint8_t* cursor
= WriteUint16(data
, 2); // Length = 2.
1217 cursor
= WriteUint16(cursor
, self
->srtp_cipher_
);
1218 *cursor
++ = 0; // No MKI
1219 *len
= cursor
- data
;
1228 TlsParser(const uint8_t* data
, size_t len
)
1229 : cursor_(data
), remaining_(len
) {}
1231 bool error() const { return error_
; }
1232 size_t remaining() const { return remaining_
; }
1234 template<typename T
,
1235 class = typename
std::enable_if
<std::is_unsigned
<T
>::value
>::type
>
1236 void Read(T
* v
, size_t sz
= sizeof(T
)) {
1237 MOZ_ASSERT(sz
<= sizeof(T
), "Type is too small to hold the value requested");
1238 if (remaining_
< sz
) {
1244 for (size_t i
= 0; i
< sz
; ++i
) {
1245 result
= (result
<< 8) | *cursor_
++;
1251 template<typename T
,
1252 class = typename
std::enable_if
<std::is_unsigned
<T
>::value
>::type
>
1253 void ReadVector(std::vector
<T
>* v
, size_t w
) {
1254 MOZ_ASSERT(v
->empty(), "vector needs to be empty");
1258 if (error_
|| len
% sizeof(T
) != 0 || len
> remaining_
) {
1263 size_t count
= len
/ sizeof(T
);
1265 for (T i
= 0; !error_
&& i
< count
; ++i
) {
1274 void Skip(size_t n
) {
1275 if (remaining_
< n
) {
1283 size_t SkipVector(size_t w
) {
1291 const uint8_t* cursor_
;
1293 bool error_
= false;
1296 /* static */ SECStatus
TransportLayerDtls::HandleSrtpXtn(
1297 PRFileDesc
* fd
, SSLHandshakeType message
, const uint8_t* data
,
1298 unsigned int len
, SSLAlertDescription
* alert
, void* arg
) {
1299 static const uint8_t kTlsAlertHandshakeFailure
= 40;
1300 static const uint8_t kTlsAlertIllegalParameter
= 47;
1301 static const uint8_t kTlsAlertDecodeError
= 50;
1302 static const uint8_t kTlsAlertUnsupportedExtension
= 110;
1304 auto self
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1306 // Parse the extension.
1307 TlsParser
parser(data
, len
);
1308 std::vector
<uint16_t> advertised
;
1309 parser
.ReadVector(&advertised
, 2);
1310 size_t mki_len
= parser
.SkipVector(1);
1311 if (parser
.error() || parser
.remaining() > 0) {
1312 *alert
= kTlsAlertDecodeError
;
1316 if (message
== ssl_hs_client_hello
) {
1317 MOZ_ASSERT(self
->role_
== SERVER
);
1318 if (self
->enabled_srtp_ciphers_
.empty()) {
1319 // We don't have SRTP enabled, which is probably bad, but no sense in
1320 // having the handshake fail at this point, let the client decide if this
1325 for (auto supported
: self
->enabled_srtp_ciphers_
) {
1326 auto it
= std::find(advertised
.begin(), advertised
.end(), supported
);
1327 if (it
!= advertised
.end()) {
1328 self
->srtp_cipher_
= supported
;
1333 // No common cipher.
1334 *alert
= kTlsAlertHandshakeFailure
;
1338 if (message
== SrtpXtnServerMessage(fd
)) {
1339 MOZ_ASSERT(self
->role_
== CLIENT
);
1340 if (advertised
.size() != 1 || mki_len
> 0) {
1341 *alert
= kTlsAlertIllegalParameter
;
1344 self
->srtp_cipher_
= advertised
[0];
1348 *alert
= kTlsAlertUnsupportedExtension
;
1352 nsresult
TransportLayerDtls::ExportKeyingMaterial(const std::string
& label
,
1354 const std::string
& context
,
1356 unsigned int outlen
) {
1358 if (state_
!= TS_OPEN
) {
1359 MOZ_ASSERT(false, "Transport must be open for ExportKeyingMaterial");
1360 return NS_ERROR_NOT_AVAILABLE
;
1362 SECStatus rv
= SSL_ExportKeyingMaterial(ssl_fd_
.get(),
1366 reinterpret_cast<const unsigned char *>(
1371 if (rv
!= SECSuccess
) {
1372 MOZ_MTLOG(ML_ERROR
, "Couldn't export SSL keying material");
1373 return NS_ERROR_FAILURE
;
1379 SECStatus
TransportLayerDtls::AuthCertificateHook(void *arg
,
1383 TransportLayerDtls
*stream
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1384 stream
->CheckThread();
1385 return stream
->AuthCertificateHook(fd
, checksig
, isServer
);
1389 TransportLayerDtls::CheckDigest(const RefPtr
<VerificationDigest
>& digest
,
1390 UniqueCERTCertificate
& peer_cert
) const {
1391 unsigned char computed_digest
[kMaxDigestLength
];
1392 size_t computed_digest_len
;
1394 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Checking digest, algorithm="
1395 << digest
->algorithm_
);
1397 DtlsIdentity::ComputeFingerprint(peer_cert
,
1400 sizeof(computed_digest
),
1401 &computed_digest_len
);
1402 if (NS_FAILED(res
)) {
1403 MOZ_MTLOG(ML_ERROR
, "Could not compute peer fingerprint for digest " <<
1404 digest
->algorithm_
);
1406 PR_SetError(SSL_ERROR_BAD_CERTIFICATE
, 0);
1410 if (computed_digest_len
!= digest
->len_
) {
1411 MOZ_MTLOG(ML_ERROR
, "Digest is wrong length " << digest
->len_
<<
1412 " should be " << computed_digest_len
<< " for algorithm " <<
1413 digest
->algorithm_
);
1414 PR_SetError(SSL_ERROR_BAD_CERTIFICATE
, 0);
1418 if (memcmp(digest
->value_
, computed_digest
, computed_digest_len
) != 0) {
1419 MOZ_MTLOG(ML_ERROR
, "Digest does not match");
1420 PR_SetError(SSL_ERROR_BAD_CERTIFICATE
, 0);
1428 SECStatus
TransportLayerDtls::AuthCertificateHook(PRFileDesc
*fd
,
1432 UniqueCERTCertificate
peer_cert(SSL_PeerCertificate(fd
));
1434 // We are not set up to take this being called multiple
1435 // times. Change this if we ever add renegotiation.
1436 MOZ_ASSERT(!auth_hook_called_
);
1437 if (auth_hook_called_
) {
1438 PR_SetError(PR_UNKNOWN_ERROR
, 0);
1441 auth_hook_called_
= true;
1443 MOZ_ASSERT(verification_mode_
!= VERIFY_UNSET
);
1445 switch (verification_mode_
) {
1447 // Break out to error exit
1448 PR_SetError(PR_UNKNOWN_ERROR
, 0);
1451 case VERIFY_ALLOW_ALL
:
1457 MOZ_ASSERT(digests_
.size() != 0);
1458 // Check all the provided digests
1460 // Checking functions call PR_SetError()
1461 SECStatus rv
= SECFailure
;
1462 for (auto digest
: digests_
) {
1463 rv
= CheckDigest(digest
, peer_cert
);
1465 // Matches a digest, we are good to go
1466 if (rv
== SECSuccess
) {
1474 MOZ_CRASH(); // Can't happen
1480 void TransportLayerDtls::TimerCallback(nsITimer
*timer
, void *arg
) {
1481 TransportLayerDtls
*dtls
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1483 MOZ_MTLOG(ML_DEBUG
, "DTLS timer expired");
1489 TransportLayerDtls::RecordHandshakeCompletionTelemetry(
1490 TransportLayer::State endState
) {
1491 int32_t delta
= (TimeStamp::Now() - handshake_started_
).ToMilliseconds();
1494 case TransportLayer::State::TS_OPEN
:
1495 if (role_
== TransportLayerDtls::CLIENT
) {
1496 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CLIENT_SUCCESS_TIME
,
1499 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_SERVER_SUCCESS_TIME
,
1503 case TransportLayer::State::TS_ERROR
:
1504 if (role_
== TransportLayerDtls::CLIENT
) {
1505 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CLIENT_FAILURE_TIME
,
1508 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_SERVER_FAILURE_TIME
,
1512 case TransportLayer::State::TS_CLOSED
:
1513 if (role_
== TransportLayerDtls::CLIENT
) {
1514 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CLIENT_ABORT_TIME
, delta
);
1516 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_SERVER_ABORT_TIME
, delta
);
1525 TransportLayerDtls::RecordCipherTelemetry() {
1528 nsresult rv
= GetCipherSuite(&cipher
);
1530 if (NS_FAILED(rv
)) {
1531 MOZ_MTLOG(ML_ERROR
, "Failed to get DTLS cipher suite");
1535 uint16_t t_cipher
= 0;
1538 /* Old DHE ciphers: candidates for removal, see bug 1227519 */
1539 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA
:
1542 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA
:
1545 /* Current ciphers */
1546 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
:
1549 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
:
1552 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
:
1555 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
:
1558 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
:
1561 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
:
1564 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
:
1567 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
:
1570 /* TLS 1.3 ciphers */
1571 case TLS_AES_128_GCM_SHA256
:
1574 case TLS_CHACHA20_POLY1305_SHA256
:
1577 case TLS_AES_256_GCM_SHA384
:
1582 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CIPHER
, t_cipher
);
1584 rv
= GetSrtpCipher(&cipher
);
1586 if (NS_FAILED(rv
)) {
1587 MOZ_MTLOG(ML_ERROR
, "Failed to get SRTP cipher suite");
1591 mozilla::Telemetry::LABELS_WEBRTC_SRTP_CIPHER label
=
1592 mozilla::Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Unknown
;
1595 case kDtlsSrtpAes128CmHmacSha1_80
:
1596 label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_80
;
1598 case kDtlsSrtpAes128CmHmacSha1_32
:
1599 label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_32
;
1601 case kDtlsSrtpAeadAes128Gcm
:
1602 label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes128Gcm
;
1604 case kDtlsSrtpAeadAes256Gcm
:
1605 label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes256Gcm
;
1609 Telemetry::AccumulateCategorical(label
);
1613 } // close namespace