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"
33 MOZ_MTLOG_MODULE("mtransport")
35 static PRDescIdentity transport_layer_identity
= PR_INVALID_IO_LAYER
;
37 // TODO: Implement a mode for this where
38 // the channel is not ready until confirmed externally
39 // (e.g., after cert check).
41 #define UNIMPLEMENTED \
42 MOZ_MTLOG(ML_ERROR, "Call to unimplemented function " << __FUNCTION__); \
44 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0)
46 #define MAX_ALPN_LENGTH 255
48 // We need to adapt the NSPR/libssl model to the TransportFlow model.
49 // The former wants pull semantics and TransportFlow wants push.
51 // - A TransportLayerDtls assumes it is sitting on top of another
52 // TransportLayer, which means that events come in asynchronously.
53 // - NSS (libssl) wants to sit on top of a PRFileDesc and poll.
54 // - The TransportLayerNSPRAdapter is a PRFileDesc containing a
56 // - When TransportLayerDtls.PacketReceived() is called, we insert
57 // the packets in the FIFO and then do a PR_Recv() on the NSS
58 // PRFileDesc, which eventually reads off the FIFO.
60 // All of this stuff is assumed to happen solely in a single thread
61 // (generally the SocketTransportService thread)
63 void TransportLayerNSPRAdapter::PacketReceived(MediaPacket
& packet
) {
65 input_
.push(new MediaPacket(std::move(packet
)));
69 int32_t TransportLayerNSPRAdapter::Recv(void* buf
, int32_t buflen
) {
71 PR_SetError(PR_WOULD_BLOCK_ERROR
, 0);
75 MediaPacket
* front
= input_
.front();
76 int32_t count
= static_cast<int32_t>(front
->len());
79 MOZ_ASSERT(false, "Not enough buffer space to receive into");
80 PR_SetError(PR_BUFFER_OVERFLOW_ERROR
, 0);
84 memcpy(buf
, front
->data(), count
);
92 int32_t TransportLayerNSPRAdapter::Write(const void* buf
, int32_t length
) {
94 MOZ_MTLOG(ML_WARNING
, "Writing to disabled transport layer");
100 packet
.Copy(static_cast<const uint8_t*>(buf
), static_cast<size_t>(length
));
101 packet
.SetType(MediaPacket::DTLS
);
103 TransportResult r
= output_
->SendPacket(packet
);
108 if (r
== TE_WOULDBLOCK
) {
109 PR_SetError(PR_WOULD_BLOCK_ERROR
, 0);
111 PR_SetError(PR_IO_ERROR
, 0);
117 // Implementation of NSPR methods
118 static PRStatus
TransportLayerClose(PRFileDesc
* f
) {
123 static int32_t TransportLayerRead(PRFileDesc
* f
, void* buf
, int32_t length
) {
128 static int32_t TransportLayerWrite(PRFileDesc
* f
, const void* buf
,
130 TransportLayerNSPRAdapter
* io
=
131 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
=
205 reinterpret_cast<TransportLayerNSPRAdapter
*>(f
->secret
);
206 io
->SetEnabled(false);
210 // This function does not support peek, or waiting until `to`
211 static int32_t TransportLayerRecv(PRFileDesc
* f
, void* buf
, int32_t buflen
,
212 int32_t flags
, PRIntervalTime to
) {
213 MOZ_ASSERT(flags
== 0);
215 PR_SetError(PR_NOT_IMPLEMENTED_ERROR
, 0);
219 TransportLayerNSPRAdapter
* io
=
220 reinterpret_cast<TransportLayerNSPRAdapter
*>(f
->secret
);
221 return io
->Recv(buf
, buflen
);
224 // Note: this is always nonblocking and assumes a zero timeout.
225 static int32_t TransportLayerSend(PRFileDesc
* f
, const void* buf
,
226 int32_t amount
, int32_t flags
,
228 int32_t written
= TransportLayerWrite(f
, buf
, amount
);
232 static int32_t TransportLayerRecvfrom(PRFileDesc
* f
, void* buf
, int32_t amount
,
233 int32_t flags
, PRNetAddr
* addr
,
239 static int32_t TransportLayerSendto(PRFileDesc
* f
, const void* buf
,
240 int32_t amount
, int32_t flags
,
241 const PRNetAddr
* addr
, PRIntervalTime to
) {
246 static int16_t TransportLayerPoll(PRFileDesc
* f
, int16_t in_flags
,
247 int16_t* out_flags
) {
252 static int32_t TransportLayerAcceptRead(PRFileDesc
* sd
, PRFileDesc
** nd
,
253 PRNetAddr
** raddr
, void* buf
,
254 int32_t amount
, PRIntervalTime t
) {
259 static int32_t TransportLayerTransmitFile(PRFileDesc
* sd
, PRFileDesc
* f
,
260 const void* headers
, int32_t hlen
,
261 PRTransmitFileFlags flags
,
267 static PRStatus
TransportLayerGetpeername(PRFileDesc
* f
, PRNetAddr
* addr
) {
268 // TODO: Modify to return unique names for each channel
269 // somehow, as opposed to always the same static address. The current
270 // implementation messes up the session cache, which is why it's off
272 addr
->inet
.family
= PR_AF_INET
;
279 static PRStatus
TransportLayerGetsockname(PRFileDesc
* f
, PRNetAddr
* addr
) {
284 static PRStatus
TransportLayerGetsockoption(PRFileDesc
* f
,
285 PRSocketOptionData
* opt
) {
286 switch (opt
->option
) {
287 case PR_SockOpt_Nonblocking
:
288 opt
->value
.non_blocking
= PR_TRUE
;
298 // Imitate setting socket options. These are mostly noops.
299 static PRStatus
TransportLayerSetsockoption(PRFileDesc
* f
,
300 const PRSocketOptionData
* opt
) {
301 switch (opt
->option
) {
302 case PR_SockOpt_Nonblocking
:
304 case PR_SockOpt_NoDelay
:
314 static int32_t TransportLayerSendfile(PRFileDesc
* out
, PRSendFileData
* in
,
315 PRTransmitFileFlags flags
,
321 static PRStatus
TransportLayerConnectContinue(PRFileDesc
* f
, int16_t flags
) {
326 static int32_t TransportLayerReserved(PRFileDesc
* f
) {
331 static const struct PRIOMethods TransportLayerMethods
= {
336 TransportLayerAvailable
,
337 TransportLayerAvailable64
,
340 TransportLayerSeek64
,
341 TransportLayerFileInfo
,
342 TransportLayerFileInfo64
,
343 TransportLayerWritev
,
344 TransportLayerConnect
,
345 TransportLayerAccept
,
347 TransportLayerListen
,
348 TransportLayerShutdown
,
351 TransportLayerRecvfrom
,
352 TransportLayerSendto
,
354 TransportLayerAcceptRead
,
355 TransportLayerTransmitFile
,
356 TransportLayerGetsockname
,
357 TransportLayerGetpeername
,
358 TransportLayerReserved
,
359 TransportLayerReserved
,
360 TransportLayerGetsockoption
,
361 TransportLayerSetsockoption
,
362 TransportLayerSendfile
,
363 TransportLayerConnectContinue
,
364 TransportLayerReserved
,
365 TransportLayerReserved
,
366 TransportLayerReserved
,
367 TransportLayerReserved
};
369 TransportLayerDtls::~TransportLayerDtls() {
370 // Destroy the NSS instance first so it can still send out an alert before
371 // we disable the nspr_io_adapter_.
373 nspr_io_adapter_
->SetEnabled(false);
379 nsresult
TransportLayerDtls::InitInternal() {
380 // Get the transport service as an event target
382 target_
= do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID
, &rv
);
385 MOZ_MTLOG(ML_ERROR
, "Couldn't get socket transport service");
389 timer_
= NS_NewTimer();
391 MOZ_MTLOG(ML_ERROR
, "Couldn't get timer");
398 void TransportLayerDtls::WasInserted() {
399 // Connect to the lower layers
401 TL_SET_STATE(TS_ERROR
);
405 // Set the permitted and default ALPN identifiers.
406 // The default is here to allow for peers that don't want to negotiate ALPN
407 // in that case, the default string will be reported from GetNegotiatedAlpn().
408 // Setting the default to the empty string causes the transport layer to fail
409 // if ALPN is not negotiated.
410 // Note: we only support Unicode strings here, which are encoded into UTF-8,
411 // even though ALPN ostensibly allows arbitrary octet sequences.
412 nsresult
TransportLayerDtls::SetAlpn(const std::set
<std::string
>& alpn_allowed
,
413 const std::string
& alpn_default
) {
414 alpn_allowed_
= alpn_allowed
;
415 alpn_default_
= alpn_default
;
420 nsresult
TransportLayerDtls::SetVerificationAllowAll() {
421 // Defensive programming
422 if (verification_mode_
!= VERIFY_UNSET
) return NS_ERROR_ALREADY_INITIALIZED
;
424 verification_mode_
= VERIFY_ALLOW_ALL
;
429 nsresult
TransportLayerDtls::SetVerificationDigest(const DtlsDigest
& digest
) {
430 // Defensive programming
431 if (verification_mode_
!= VERIFY_UNSET
&&
432 verification_mode_
!= VERIFY_DIGEST
) {
433 return NS_ERROR_ALREADY_INITIALIZED
;
436 digests_
.push_back(digest
);
437 verification_mode_
= VERIFY_DIGEST
;
441 // These are the named groups that we will allow.
442 static const SSLNamedGroup NamedGroupPreferences
[] = {
443 ssl_grp_ec_curve25519
, ssl_grp_ec_secp256r1
, ssl_grp_ec_secp384r1
,
444 ssl_grp_ffdhe_2048
, ssl_grp_ffdhe_3072
};
446 // TODO: make sure this is called from STS. Otherwise
447 // we have thread safety issues
448 bool TransportLayerDtls::Setup() {
453 MOZ_MTLOG(ML_ERROR
, "DTLS layer with nothing below. This is useless");
456 nspr_io_adapter_
= MakeUnique
<TransportLayerNSPRAdapter
>(downward_
);
459 MOZ_MTLOG(ML_ERROR
, "Can't start DTLS without an identity");
463 if (verification_mode_
== VERIFY_UNSET
) {
465 "Can't start DTLS without specifying a verification mode");
469 if (transport_layer_identity
== PR_INVALID_IO_LAYER
) {
470 transport_layer_identity
= PR_GetUniqueIdentity("nssstreamadapter");
473 UniquePRFileDesc
pr_fd(
474 PR_CreateIOLayerStub(transport_layer_identity
, &TransportLayerMethods
));
475 MOZ_ASSERT(pr_fd
!= nullptr);
476 if (!pr_fd
) return false;
477 pr_fd
->secret
= reinterpret_cast<PRFilePrivate
*>(nspr_io_adapter_
.get());
479 UniquePRFileDesc
ssl_fd(DTLS_ImportFD(nullptr, pr_fd
.get()));
480 MOZ_ASSERT(ssl_fd
!= nullptr); // This should never happen
485 Unused
<< pr_fd
.release(); // ownership transfered to ssl_fd;
487 if (role_
== CLIENT
) {
488 MOZ_MTLOG(ML_INFO
, "Setting up DTLS as client");
489 rv
= SSL_GetClientAuthDataHook(ssl_fd
.get(), GetClientAuthDataHook
, this);
490 if (rv
!= SECSuccess
) {
491 MOZ_MTLOG(ML_ERROR
, "Couldn't set identity");
495 MOZ_MTLOG(ML_INFO
, "Setting up DTLS as server");
497 rv
= SSL_ConfigSecureServer(ssl_fd
.get(), identity_
->cert().get(),
498 identity_
->privkey().get(),
499 identity_
->auth_type());
500 if (rv
!= SECSuccess
) {
501 MOZ_MTLOG(ML_ERROR
, "Couldn't set identity");
505 UniqueCERTCertList
zero_certs(CERT_NewCertList());
506 rv
= SSL_SetTrustAnchors(ssl_fd
.get(), zero_certs
.get());
507 if (rv
!= SECSuccess
) {
508 MOZ_MTLOG(ML_ERROR
, "Couldn't set trust anchors");
512 // Insist on a certificate from the client
513 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_REQUEST_CERTIFICATE
, PR_TRUE
);
514 if (rv
!= SECSuccess
) {
515 MOZ_MTLOG(ML_ERROR
, "Couldn't request certificate");
519 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_REQUIRE_CERTIFICATE
, PR_TRUE
);
520 if (rv
!= SECSuccess
) {
521 MOZ_MTLOG(ML_ERROR
, "Couldn't require certificate");
526 // Require TLS 1.1 or 1.2. Perhaps some day in the future we will allow TLS
527 // 1.0 for stream modes.
528 SSLVersionRange version_range
= {SSL_LIBRARY_VERSION_TLS_1_1
,
529 SSL_LIBRARY_VERSION_TLS_1_2
};
531 rv
= SSL_VersionRangeSet(ssl_fd
.get(), &version_range
);
532 if (rv
!= SECSuccess
) {
533 MOZ_MTLOG(ML_ERROR
, "Can't disable SSLv3");
537 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_SESSION_TICKETS
, PR_FALSE
);
538 if (rv
!= SECSuccess
) {
539 MOZ_MTLOG(ML_ERROR
, "Couldn't disable session tickets");
543 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_NO_CACHE
, PR_TRUE
);
544 if (rv
!= SECSuccess
) {
545 MOZ_MTLOG(ML_ERROR
, "Couldn't disable session caching");
549 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_DEFLATE
, PR_FALSE
);
550 if (rv
!= SECSuccess
) {
551 MOZ_MTLOG(ML_ERROR
, "Couldn't disable deflate");
555 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_RENEGOTIATION
,
556 SSL_RENEGOTIATE_NEVER
);
557 if (rv
!= SECSuccess
) {
558 MOZ_MTLOG(ML_ERROR
, "Couldn't disable renegotiation");
562 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_FALSE_START
, PR_FALSE
);
563 if (rv
!= SECSuccess
) {
564 MOZ_MTLOG(ML_ERROR
, "Couldn't disable false start");
568 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_NO_LOCKS
, PR_TRUE
);
569 if (rv
!= SECSuccess
) {
570 MOZ_MTLOG(ML_ERROR
, "Couldn't disable locks");
574 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_REUSE_SERVER_ECDHE_KEY
, PR_FALSE
);
575 if (rv
!= SECSuccess
) {
576 MOZ_MTLOG(ML_ERROR
, "Couldn't disable ECDHE key reuse");
580 if (!SetupCipherSuites(ssl_fd
)) {
584 rv
= SSL_NamedGroupConfig(ssl_fd
.get(), NamedGroupPreferences
,
585 mozilla::ArrayLength(NamedGroupPreferences
));
586 if (rv
!= SECSuccess
) {
587 MOZ_MTLOG(ML_ERROR
, "Couldn't set named groups");
591 // Certificate validation
592 rv
= SSL_AuthCertificateHook(ssl_fd
.get(), AuthCertificateHook
,
593 reinterpret_cast<void*>(this));
594 if (rv
!= SECSuccess
) {
595 MOZ_MTLOG(ML_ERROR
, "Couldn't set certificate validation hook");
599 if (!SetupAlpn(ssl_fd
)) {
603 // Now start the handshake
604 rv
= SSL_ResetHandshake(ssl_fd
.get(), role_
== SERVER
? PR_TRUE
: PR_FALSE
);
605 if (rv
!= SECSuccess
) {
606 MOZ_MTLOG(ML_ERROR
, "Couldn't reset handshake");
609 ssl_fd_
= std::move(ssl_fd
);
611 // Finally, get ready to receive data
612 downward_
->SignalStateChange
.connect(this, &TransportLayerDtls::StateChange
);
613 downward_
->SignalPacketReceived
.connect(this,
614 &TransportLayerDtls::PacketReceived
);
616 if (downward_
->state() == TS_OPEN
) {
617 TL_SET_STATE(TS_CONNECTING
);
624 bool TransportLayerDtls::SetupAlpn(UniquePRFileDesc
& ssl_fd
) const {
625 if (alpn_allowed_
.empty()) {
629 SECStatus rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_NPN
, PR_FALSE
);
630 if (rv
!= SECSuccess
) {
631 MOZ_MTLOG(ML_ERROR
, "Couldn't disable NPN");
635 rv
= SSL_OptionSet(ssl_fd
.get(), SSL_ENABLE_ALPN
, PR_TRUE
);
636 if (rv
!= SECSuccess
) {
637 MOZ_MTLOG(ML_ERROR
, "Couldn't enable ALPN");
641 unsigned char buf
[MAX_ALPN_LENGTH
];
643 for (const auto& tag
: alpn_allowed_
) {
644 if ((offset
+ 1 + tag
.length()) >= sizeof(buf
)) {
645 MOZ_MTLOG(ML_ERROR
, "ALPN too long");
648 buf
[offset
++] = tag
.length();
649 memcpy(buf
+ offset
, tag
.c_str(), tag
.length());
650 offset
+= tag
.length();
652 rv
= SSL_SetNextProtoNego(ssl_fd
.get(), buf
, offset
);
653 if (rv
!= SECSuccess
) {
654 MOZ_MTLOG(ML_ERROR
, "Couldn't set ALPN string");
660 // Ciphers we need to enable. These are on by default in standard firefox
661 // builds, but can be disabled with prefs and they aren't on in our unit tests
662 // since that uses NSS default configuration.
664 // Only override prefs to comply with MUST statements in the security-arch doc.
665 // Anything outside this list is governed by the usual combination of policy
666 // and user preferences.
667 static const uint32_t EnabledCiphers
[] = {
668 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
,
669 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
};
671 // Disable all NSS suites modes without PFS or with old and rusty ciphersuites.
672 // Anything outside this list is governed by the usual combination of policy
673 // and user preferences.
674 static const uint32_t DisabledCiphers
[] = {
675 // Bug 1310061: disable all SHA384 ciphers until fixed
676 TLS_AES_256_GCM_SHA384
,
677 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
,
678 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
,
679 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
,
680 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
,
681 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
,
682 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
,
684 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
,
685 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
,
687 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
,
688 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
689 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
690 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
692 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
,
693 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
,
694 TLS_DHE_DSS_WITH_RC4_128_SHA
,
696 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
697 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
698 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
699 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
700 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
701 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
702 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
703 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
705 TLS_RSA_WITH_AES_128_GCM_SHA256
,
706 TLS_RSA_WITH_AES_256_GCM_SHA384
,
707 TLS_RSA_WITH_AES_128_CBC_SHA
,
708 TLS_RSA_WITH_AES_128_CBC_SHA256
,
709 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
,
710 TLS_RSA_WITH_AES_256_CBC_SHA
,
711 TLS_RSA_WITH_AES_256_CBC_SHA256
,
712 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
,
713 TLS_RSA_WITH_SEED_CBC_SHA
,
714 TLS_RSA_WITH_3DES_EDE_CBC_SHA
,
715 TLS_RSA_WITH_RC4_128_SHA
,
716 TLS_RSA_WITH_RC4_128_MD5
,
718 TLS_DHE_RSA_WITH_DES_CBC_SHA
,
719 TLS_DHE_DSS_WITH_DES_CBC_SHA
,
720 TLS_RSA_WITH_DES_CBC_SHA
,
722 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
723 TLS_ECDHE_RSA_WITH_NULL_SHA
,
724 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
725 TLS_ECDH_RSA_WITH_NULL_SHA
,
726 TLS_RSA_WITH_NULL_SHA
,
727 TLS_RSA_WITH_NULL_SHA256
,
728 TLS_RSA_WITH_NULL_MD5
,
731 bool TransportLayerDtls::SetupCipherSuites(UniquePRFileDesc
& ssl_fd
) {
734 // Set the SRTP ciphers
735 if (!enabled_srtp_ciphers_
.empty()) {
736 rv
= SSL_InstallExtensionHooks(ssl_fd
.get(), ssl_use_srtp_xtn
,
737 TransportLayerDtls::WriteSrtpXtn
, this,
738 TransportLayerDtls::HandleSrtpXtn
, this);
739 if (rv
!= SECSuccess
) {
740 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "unable to set SRTP extension handler");
745 for (const auto& cipher
: EnabledCiphers
) {
746 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Enabling: " << cipher
);
747 rv
= SSL_CipherPrefSet(ssl_fd
.get(), cipher
, PR_TRUE
);
748 if (rv
!= SECSuccess
) {
749 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Unable to enable suite: " << cipher
);
754 for (const auto& cipher
: DisabledCiphers
) {
755 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Disabling: " << cipher
);
757 PRBool enabled
= false;
758 rv
= SSL_CipherPrefGet(ssl_fd
.get(), cipher
, &enabled
);
759 if (rv
!= SECSuccess
) {
760 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "Unable to check if suite is enabled: "
765 rv
= SSL_CipherPrefSet(ssl_fd
.get(), cipher
, PR_FALSE
);
766 if (rv
!= SECSuccess
) {
768 LAYER_INFO
<< "Unable to disable suite: " << cipher
);
777 nsresult
TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite
) const {
780 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "GetCipherSuite passed a nullptr");
781 return NS_ERROR_NULL_POINTER
;
783 if (state_
!= TS_OPEN
) {
784 return NS_ERROR_NOT_AVAILABLE
;
787 SECStatus rv
= SSL_GetChannelInfo(ssl_fd_
.get(), &info
, sizeof(info
));
788 if (rv
!= SECSuccess
) {
789 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "GetCipherSuite can't get channel info");
790 return NS_ERROR_FAILURE
;
792 *cipherSuite
= info
.cipherSuite
;
796 std::vector
<uint16_t> TransportLayerDtls::GetDefaultSrtpCiphers() {
797 std::vector
<uint16_t> ciphers
;
799 ciphers
.push_back(kDtlsSrtpAeadAes128Gcm
);
800 // Since we don't support DTLS 1.3 or SHA384 ciphers (see bug 1312976)
801 // we don't really enough entropy to prefer this over 128 bit
802 ciphers
.push_back(kDtlsSrtpAeadAes256Gcm
);
803 ciphers
.push_back(kDtlsSrtpAes128CmHmacSha1_80
);
804 #ifndef NIGHTLY_BUILD
805 // To support bug 1491583 lets try to find out if we get bug reports if we no
806 // longer offer this in Nightly builds.
807 ciphers
.push_back(kDtlsSrtpAes128CmHmacSha1_32
);
813 void TransportLayerDtls::StateChange(TransportLayer
* layer
, State state
) {
816 MOZ_ASSERT(false); // Can't happen
821 LAYER_INFO
<< "State change of lower layer to INIT forbidden");
822 TL_SET_STATE(TS_ERROR
);
826 MOZ_MTLOG(ML_INFO
, LAYER_INFO
<< "Lower layer is connecting.");
832 LAYER_INFO
<< "Lower layer is now open; starting TLS");
834 timer_
->SetTarget(target_
);
835 // Async, since the ICE layer might need to send a STUN response, and we
836 // don't want the handshake to start until that is sent.
837 timer_
->InitWithNamedFuncCallback(TimerCallback
, this, 0,
838 nsITimer::TYPE_ONE_SHOT
,
839 "TransportLayerDtls::TimerCallback");
840 TL_SET_STATE(TS_CONNECTING
);
842 // We have already completed DTLS. Can happen if the ICE layer failed
843 // due to a loss of network, and then recovered.
844 TL_SET_STATE(TS_OPEN
);
849 MOZ_MTLOG(ML_INFO
, LAYER_INFO
<< "Lower layer is now closed");
850 TL_SET_STATE(TS_CLOSED
);
854 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Lower layer experienced an error");
855 TL_SET_STATE(TS_ERROR
);
860 void TransportLayerDtls::Handshake() {
862 // We are done with DTLS, regardless of the state changes of lower layers
866 // Clear the retransmit timer
869 MOZ_ASSERT(state_
== TS_CONNECTING
);
871 SECStatus rv
= SSL_ForceHandshake(ssl_fd_
.get());
873 if (rv
== SECSuccess
) {
874 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "****** SSL handshake completed ******");
876 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Certificate check never occurred");
877 TL_SET_STATE(TS_ERROR
);
881 // Despite connecting, the connection doesn't have a valid ALPN label.
882 // Forcibly close the connection so that the peer isn't left hanging
883 // (assuming the close_notify isn't dropped).
885 TL_SET_STATE(TS_ERROR
);
889 TL_SET_STATE(TS_OPEN
);
891 RecordTlsTelemetry();
894 int32_t err
= PR_GetError();
896 case SSL_ERROR_RX_MALFORMED_HANDSHAKE
:
897 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Malformed DTLS message; ignoring");
898 // If this were TLS (and not DTLS), this would be fatal, but
899 // here we're required to ignore bad messages, so fall through
901 case PR_WOULD_BLOCK_ERROR
:
902 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "Handshake would have blocked");
903 PRIntervalTime timeout
;
904 rv
= DTLS_GetHandshakeTimeout(ssl_fd_
.get(), &timeout
);
905 if (rv
== SECSuccess
) {
906 uint32_t timeout_ms
= PR_IntervalToMilliseconds(timeout
);
909 LAYER_INFO
<< "Setting DTLS timeout to " << timeout_ms
);
910 timer_
->SetTarget(target_
);
911 timer_
->InitWithNamedFuncCallback(
912 TimerCallback
, this, timeout_ms
, nsITimer::TYPE_ONE_SHOT
,
913 "TransportLayerDtls::TimerCallback");
917 const char* err_msg
= PR_ErrorToName(err
);
918 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "DTLS handshake error " << err
<< " ("
920 TL_SET_STATE(TS_ERROR
);
926 // Checks if ALPN was negotiated correctly and returns false if it wasn't.
927 // After this returns successfully, alpn_ will be set to the negotiated
929 bool TransportLayerDtls::CheckAlpn() {
930 if (alpn_allowed_
.empty()) {
934 SSLNextProtoState alpnState
;
935 char chosenAlpn
[MAX_ALPN_LENGTH
];
936 unsigned int chosenAlpnLen
;
937 SECStatus rv
= SSL_GetNextProto(ssl_fd_
.get(), &alpnState
,
938 reinterpret_cast<unsigned char*>(chosenAlpn
),
939 &chosenAlpnLen
, sizeof(chosenAlpn
));
940 if (rv
!= SECSuccess
) {
941 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "ALPN error");
945 case SSL_NEXT_PROTO_SELECTED
:
946 case SSL_NEXT_PROTO_NEGOTIATED
:
949 case SSL_NEXT_PROTO_NO_SUPPORT
:
951 LAYER_INFO
<< "ALPN not negotiated, "
952 << (alpn_default_
.empty() ? "failing"
953 : "selecting default"));
954 alpn_
= alpn_default_
;
955 return !alpn_
.empty();
957 case SSL_NEXT_PROTO_NO_OVERLAP
:
958 // This only happens if there is a custom NPN/ALPN callback installed and
959 // that callback doesn't properly handle ALPN.
960 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "error in ALPN selection callback");
963 case SSL_NEXT_PROTO_EARLY_VALUE
:
964 MOZ_CRASH("Unexpected 0-RTT ALPN value");
968 // Warning: NSS won't null terminate the ALPN string for us.
969 std::string
chosen(chosenAlpn
, chosenAlpnLen
);
970 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "Selected ALPN string: " << chosen
);
971 if (alpn_allowed_
.find(chosen
) == alpn_allowed_
.end()) {
972 // Maybe our peer chose a protocol we didn't offer (when we are client), or
973 // something is seriously wrong.
974 std::ostringstream ss
;
975 for (auto i
= alpn_allowed_
.begin(); i
!= alpn_allowed_
.end(); ++i
) {
976 ss
<< (i
== alpn_allowed_
.begin() ? " '" : ", '") << *i
<< "'";
978 MOZ_MTLOG(ML_ERROR
, LAYER_INFO
<< "Bad ALPN string: '" << chosen
979 << "'; permitted:" << ss
.str());
986 void TransportLayerDtls::PacketReceived(TransportLayer
* layer
,
987 MediaPacket
& packet
) {
989 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "PacketReceived(" << packet
.len() << ")");
991 if (state_
!= TS_CONNECTING
&& state_
!= TS_OPEN
) {
993 LAYER_INFO
<< "Discarding packet in inappropriate state");
997 if (!packet
.data()) {
998 // Something ate this, probably the SRTP layer
1002 if (packet
.type() != MediaPacket::DTLS
) {
1006 nspr_io_adapter_
->PacketReceived(packet
);
1007 GetDecryptedPackets();
1010 void TransportLayerDtls::GetDecryptedPackets() {
1011 // If we're still connecting, try to handshake
1012 if (state_
== TS_CONNECTING
) {
1016 // Now try a recv if we're open, since there might be data left
1017 if (state_
== TS_OPEN
) {
1019 // One packet might contain several DTLS packets
1021 // nICEr uses a 9216 bytes buffer to allow support for jumbo frames
1022 // Can we peek to get a better idea of the actual size?
1023 static const size_t kBufferSize
= 9216;
1024 auto buffer
= MakeUnique
<uint8_t[]>(kBufferSize
);
1025 rv
= PR_Recv(ssl_fd_
.get(), buffer
.get(), kBufferSize
, 0,
1026 PR_INTERVAL_NO_WAIT
);
1029 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Read " << rv
<< " bytes from NSS");
1031 packet
.SetType(MediaPacket::SCTP
);
1032 packet
.Take(std::move(buffer
), static_cast<size_t>(rv
));
1033 SignalPacketReceived(this, packet
);
1034 } else if (rv
== 0) {
1035 TL_SET_STATE(TS_CLOSED
);
1037 int32_t err
= PR_GetError();
1039 if (err
== PR_WOULD_BLOCK_ERROR
) {
1040 // This gets ignored
1041 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Receive would have blocked");
1043 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "NSS Error " << err
);
1044 TL_SET_STATE(TS_ERROR
);
1051 void TransportLayerDtls::SetState(State state
, const char* file
,
1069 TransportLayer::SetState(state
, file
, line
);
1072 TransportResult
TransportLayerDtls::SendPacket(MediaPacket
& packet
) {
1074 if (state_
!= TS_OPEN
) {
1076 LAYER_INFO
<< "Can't call SendPacket() in state " << state_
);
1080 int32_t rv
= PR_Send(ssl_fd_
.get(), packet
.data(), packet
.len(), 0,
1081 PR_INTERVAL_NO_WAIT
);
1085 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Wrote " << rv
<< " bytes to SSL Layer");
1090 TL_SET_STATE(TS_CLOSED
);
1094 int32_t err
= PR_GetError();
1096 if (err
== PR_WOULD_BLOCK_ERROR
) {
1097 // This gets ignored
1098 MOZ_MTLOG(ML_DEBUG
, LAYER_INFO
<< "Send would have blocked");
1099 return TE_WOULDBLOCK
;
1102 MOZ_MTLOG(ML_NOTICE
, LAYER_INFO
<< "NSS Error " << err
);
1103 TL_SET_STATE(TS_ERROR
);
1107 SECStatus
TransportLayerDtls::GetClientAuthDataHook(
1108 void* arg
, PRFileDesc
* fd
, CERTDistNames
* caNames
,
1109 CERTCertificate
** pRetCert
, SECKEYPrivateKey
** pRetKey
) {
1110 MOZ_MTLOG(ML_DEBUG
, "Server requested client auth");
1112 TransportLayerDtls
* stream
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1113 stream
->CheckThread();
1115 if (!stream
->identity_
) {
1116 MOZ_MTLOG(ML_ERROR
, "No identity available");
1117 PR_SetError(SSL_ERROR_NO_CERTIFICATE
, 0);
1121 *pRetCert
= CERT_DupCertificate(stream
->identity_
->cert().get());
1123 PR_SetError(PR_OUT_OF_MEMORY_ERROR
, 0);
1127 *pRetKey
= SECKEY_CopyPrivateKey(stream
->identity_
->privkey().get());
1129 CERT_DestroyCertificate(*pRetCert
);
1130 *pRetCert
= nullptr;
1131 PR_SetError(PR_OUT_OF_MEMORY_ERROR
, 0);
1138 nsresult
TransportLayerDtls::SetSrtpCiphers(
1139 const std::vector
<uint16_t>& ciphers
) {
1140 enabled_srtp_ciphers_
= std::move(ciphers
);
1144 nsresult
TransportLayerDtls::GetSrtpCipher(uint16_t* cipher
) const {
1146 if (srtp_cipher_
== 0) {
1147 return NS_ERROR_NOT_AVAILABLE
;
1149 *cipher
= srtp_cipher_
;
1153 static uint8_t* WriteUint16(uint8_t* cursor
, uint16_t v
) {
1155 *cursor
++ = v
& 0xff;
1159 static SSLHandshakeType
SrtpXtnServerMessage(PRFileDesc
* fd
) {
1160 SSLPreliminaryChannelInfo preinfo
;
1161 SECStatus rv
= SSL_GetPreliminaryChannelInfo(fd
, &preinfo
, sizeof(preinfo
));
1162 if (rv
!= SECSuccess
) {
1163 MOZ_ASSERT(false, "Can't get version info");
1164 return ssl_hs_client_hello
;
1166 return (preinfo
.protocolVersion
>= SSL_LIBRARY_VERSION_TLS_1_3
)
1167 ? ssl_hs_encrypted_extensions
1168 : ssl_hs_server_hello
;
1172 PRBool
TransportLayerDtls::WriteSrtpXtn(PRFileDesc
* fd
,
1173 SSLHandshakeType message
, uint8_t* data
,
1174 unsigned int* len
, unsigned int max_len
,
1176 auto self
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1178 // ClientHello: send all supported versions.
1179 if (message
== ssl_hs_client_hello
) {
1180 MOZ_ASSERT(self
->role_
== CLIENT
);
1181 MOZ_ASSERT(self
->enabled_srtp_ciphers_
.size(), "Haven't enabled SRTP");
1182 // We will take 2 octets for each cipher, plus a 2 octet length and 1 octet
1183 // for the length of the empty MKI.
1184 if (max_len
< self
->enabled_srtp_ciphers_
.size() * 2 + 3) {
1185 MOZ_ASSERT(false, "Not enough space to send SRTP extension");
1188 uint8_t* cursor
= WriteUint16(data
, self
->enabled_srtp_ciphers_
.size() * 2);
1189 for (auto cs
: self
->enabled_srtp_ciphers_
) {
1190 cursor
= WriteUint16(cursor
, cs
);
1192 *cursor
++ = 0; // MKI is empty
1193 *len
= cursor
- data
;
1197 if (message
== SrtpXtnServerMessage(fd
)) {
1198 MOZ_ASSERT(self
->role_
== SERVER
);
1199 if (!self
->srtp_cipher_
) {
1200 // Not negotiated. Definitely bad, but the connection can fail later.
1204 MOZ_ASSERT(false, "Not enough space to send SRTP extension");
1208 uint8_t* cursor
= WriteUint16(data
, 2); // Length = 2.
1209 cursor
= WriteUint16(cursor
, self
->srtp_cipher_
);
1210 *cursor
++ = 0; // No MKI
1211 *len
= cursor
- data
;
1220 TlsParser(const uint8_t* data
, size_t len
) : cursor_(data
), remaining_(len
) {}
1222 bool error() const { return error_
; }
1223 size_t remaining() const { return remaining_
; }
1225 template <typename T
,
1226 class = typename
std::enable_if
<std::is_unsigned
<T
>::value
>::type
>
1227 void Read(T
* v
, size_t sz
= sizeof(T
)) {
1228 MOZ_ASSERT(sz
<= sizeof(T
),
1229 "Type is too small to hold the value requested");
1230 if (remaining_
< sz
) {
1236 for (size_t i
= 0; i
< sz
; ++i
) {
1237 result
= (result
<< 8) | *cursor_
++;
1243 template <typename T
,
1244 class = typename
std::enable_if
<std::is_unsigned
<T
>::value
>::type
>
1245 void ReadVector(std::vector
<T
>* v
, size_t w
) {
1246 MOZ_ASSERT(v
->empty(), "vector needs to be empty");
1250 if (error_
|| len
% sizeof(T
) != 0 || len
> remaining_
) {
1255 size_t count
= len
/ sizeof(T
);
1257 for (T i
= 0; !error_
&& i
< count
; ++i
) {
1266 void Skip(size_t n
) {
1267 if (remaining_
< n
) {
1275 size_t SkipVector(size_t w
) {
1283 const uint8_t* cursor_
;
1285 bool error_
= false;
1289 SECStatus
TransportLayerDtls::HandleSrtpXtn(
1290 PRFileDesc
* fd
, SSLHandshakeType message
, const uint8_t* data
,
1291 unsigned int len
, SSLAlertDescription
* alert
, void* arg
) {
1292 static const uint8_t kTlsAlertHandshakeFailure
= 40;
1293 static const uint8_t kTlsAlertIllegalParameter
= 47;
1294 static const uint8_t kTlsAlertDecodeError
= 50;
1295 static const uint8_t kTlsAlertUnsupportedExtension
= 110;
1297 auto self
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1299 // Parse the extension.
1300 TlsParser
parser(data
, len
);
1301 std::vector
<uint16_t> advertised
;
1302 parser
.ReadVector(&advertised
, 2);
1303 size_t mki_len
= parser
.SkipVector(1);
1304 if (parser
.error() || parser
.remaining() > 0) {
1305 *alert
= kTlsAlertDecodeError
;
1309 if (message
== ssl_hs_client_hello
) {
1310 MOZ_ASSERT(self
->role_
== SERVER
);
1311 if (self
->enabled_srtp_ciphers_
.empty()) {
1312 // We don't have SRTP enabled, which is probably bad, but no sense in
1313 // having the handshake fail at this point, let the client decide if this
1318 for (auto supported
: self
->enabled_srtp_ciphers_
) {
1319 auto it
= std::find(advertised
.begin(), advertised
.end(), supported
);
1320 if (it
!= advertised
.end()) {
1321 self
->srtp_cipher_
= supported
;
1326 // No common cipher.
1327 *alert
= kTlsAlertHandshakeFailure
;
1331 if (message
== SrtpXtnServerMessage(fd
)) {
1332 MOZ_ASSERT(self
->role_
== CLIENT
);
1333 if (advertised
.size() != 1 || mki_len
> 0) {
1334 *alert
= kTlsAlertIllegalParameter
;
1337 self
->srtp_cipher_
= advertised
[0];
1341 *alert
= kTlsAlertUnsupportedExtension
;
1345 nsresult
TransportLayerDtls::ExportKeyingMaterial(const std::string
& label
,
1347 const std::string
& context
,
1349 unsigned int outlen
) {
1351 if (state_
!= TS_OPEN
) {
1352 MOZ_ASSERT(false, "Transport must be open for ExportKeyingMaterial");
1353 return NS_ERROR_NOT_AVAILABLE
;
1355 SECStatus rv
= SSL_ExportKeyingMaterial(
1356 ssl_fd_
.get(), label
.c_str(), label
.size(), use_context
,
1357 reinterpret_cast<const unsigned char*>(context
.c_str()), context
.size(),
1359 if (rv
!= SECSuccess
) {
1360 MOZ_MTLOG(ML_ERROR
, "Couldn't export SSL keying material");
1361 return NS_ERROR_FAILURE
;
1367 SECStatus
TransportLayerDtls::AuthCertificateHook(void* arg
, PRFileDesc
* fd
,
1370 TransportLayerDtls
* stream
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1371 stream
->CheckThread();
1372 return stream
->AuthCertificateHook(fd
, checksig
, isServer
);
1375 SECStatus
TransportLayerDtls::CheckDigest(
1376 const DtlsDigest
& digest
, UniqueCERTCertificate
& peer_cert
) const {
1377 DtlsDigest
computed_digest(digest
.algorithm_
);
1380 LAYER_INFO
<< "Checking digest, algorithm=" << digest
.algorithm_
);
1381 nsresult res
= DtlsIdentity::ComputeFingerprint(peer_cert
, &computed_digest
);
1382 if (NS_FAILED(res
)) {
1383 MOZ_MTLOG(ML_ERROR
, "Could not compute peer fingerprint for digest "
1384 << digest
.algorithm_
);
1386 PR_SetError(SSL_ERROR_BAD_CERTIFICATE
, 0);
1390 if (computed_digest
!= digest
) {
1391 MOZ_MTLOG(ML_ERROR
, "Digest does not match");
1392 PR_SetError(SSL_ERROR_BAD_CERTIFICATE
, 0);
1399 SECStatus
TransportLayerDtls::AuthCertificateHook(PRFileDesc
* fd
,
1403 UniqueCERTCertificate
peer_cert(SSL_PeerCertificate(fd
));
1405 // We are not set up to take this being called multiple
1406 // times. Change this if we ever add renegotiation.
1407 MOZ_ASSERT(!auth_hook_called_
);
1408 if (auth_hook_called_
) {
1409 PR_SetError(PR_UNKNOWN_ERROR
, 0);
1412 auth_hook_called_
= true;
1414 MOZ_ASSERT(verification_mode_
!= VERIFY_UNSET
);
1416 switch (verification_mode_
) {
1418 // Break out to error exit
1419 PR_SetError(PR_UNKNOWN_ERROR
, 0);
1422 case VERIFY_ALLOW_ALL
:
1426 case VERIFY_DIGEST
: {
1427 MOZ_ASSERT(digests_
.size() != 0);
1428 // Check all the provided digests
1430 // Checking functions call PR_SetError()
1431 SECStatus rv
= SECFailure
;
1432 for (auto digest
: digests_
) {
1433 rv
= CheckDigest(digest
, peer_cert
);
1435 // Matches a digest, we are good to go
1436 if (rv
== SECSuccess
) {
1443 MOZ_CRASH(); // Can't happen
1449 void TransportLayerDtls::TimerCallback(nsITimer
* timer
, void* arg
) {
1450 TransportLayerDtls
* dtls
= reinterpret_cast<TransportLayerDtls
*>(arg
);
1452 MOZ_MTLOG(ML_DEBUG
, "DTLS timer expired");
1457 void TransportLayerDtls::RecordTlsTelemetry() {
1458 MOZ_ASSERT(state_
== TS_OPEN
);
1459 SSLChannelInfo info
;
1460 SECStatus ss
= SSL_GetChannelInfo(ssl_fd_
.get(), &info
, sizeof(info
));
1461 if (ss
!= SECSuccess
) {
1462 MOZ_MTLOG(ML_NOTICE
,
1463 LAYER_INFO
<< "RecordTlsTelemetry failed to get channel info");
1467 auto protocol_label
=
1468 mozilla::Telemetry::LABELS_WEBRTC_DTLS_PROTOCOL_VERSION::Unknown
;
1470 switch (info
.protocolVersion
) {
1471 case SSL_LIBRARY_VERSION_TLS_1_1
:
1473 Telemetry::LABELS_WEBRTC_DTLS_PROTOCOL_VERSION::Dtls_version_1_0
;
1475 case SSL_LIBRARY_VERSION_TLS_1_2
:
1477 Telemetry::LABELS_WEBRTC_DTLS_PROTOCOL_VERSION::Dtls_version_1_2
;
1479 case SSL_LIBRARY_VERSION_TLS_1_3
:
1481 Telemetry::LABELS_WEBRTC_DTLS_PROTOCOL_VERSION::Dtls_version_1_3
;
1485 Telemetry::AccumulateCategorical(protocol_label
);
1487 uint16_t telemetry_cipher
= 0;
1489 switch (info
.cipherSuite
) {
1490 /* Old DHE ciphers: candidates for removal, see bug 1227519 */
1491 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA
:
1492 telemetry_cipher
= 1;
1494 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA
:
1495 telemetry_cipher
= 2;
1497 /* Current ciphers */
1498 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
:
1499 telemetry_cipher
= 3;
1501 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
:
1502 telemetry_cipher
= 4;
1504 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
:
1505 telemetry_cipher
= 5;
1507 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
:
1508 telemetry_cipher
= 6;
1510 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
:
1511 telemetry_cipher
= 7;
1513 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
:
1514 telemetry_cipher
= 8;
1516 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
:
1517 telemetry_cipher
= 9;
1519 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
:
1520 telemetry_cipher
= 10;
1522 /* TLS 1.3 ciphers */
1523 case TLS_AES_128_GCM_SHA256
:
1524 telemetry_cipher
= 11;
1526 case TLS_CHACHA20_POLY1305_SHA256
:
1527 telemetry_cipher
= 12;
1529 case TLS_AES_256_GCM_SHA384
:
1530 telemetry_cipher
= 13;
1534 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CIPHER
, telemetry_cipher
);
1537 nsresult rv
= GetSrtpCipher(&cipher
);
1539 if (NS_FAILED(rv
)) {
1540 MOZ_MTLOG(ML_DEBUG
, "No SRTP cipher suite");
1544 auto cipher_label
= mozilla::Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Unknown
;
1547 case kDtlsSrtpAes128CmHmacSha1_80
:
1548 cipher_label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_80
;
1550 case kDtlsSrtpAes128CmHmacSha1_32
:
1551 cipher_label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_32
;
1553 case kDtlsSrtpAeadAes128Gcm
:
1554 cipher_label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes128Gcm
;
1556 case kDtlsSrtpAeadAes256Gcm
:
1557 cipher_label
= Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes256Gcm
;
1561 Telemetry::AccumulateCategorical(cipher_label
);
1564 } // namespace mozilla