Bug 1497984 - whitelist allowPtrace scope, too r=bstack
[gecko.git] / media / mtransport / transportlayerdtls.cpp
blobfc522b262a5cc57a206e555ef5bc497b6dc7799f
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"
11 #include <algorithm>
12 #include <queue>
13 #include <sstream>
15 #include "dtlsidentity.h"
16 #include "keyhi.h"
17 #include "logging.h"
18 #include "mozilla/Telemetry.h"
19 #include "mozilla/UniquePtr.h"
20 #include "mozilla/Unused.h"
21 #include "nsCOMPtr.h"
22 #include "nsComponentManagerUtils.h"
23 #include "nsComponentManagerUtils.h"
24 #include "nsIEventTarget.h"
25 #include "nsNetCID.h"
26 #include "nsServiceManagerUtils.h"
27 #include "sslexp.h"
28 #include "sslproto.h"
29 #include "transportflow.h"
32 namespace mozilla {
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 \
43 MOZ_MTLOG(ML_ERROR, \
44 "Call to unimplemented function "<< __FUNCTION__); \
45 MOZ_ASSERT(false); \
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
57 // FIFO.
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) {
66 if (enabled_) {
67 input_.push(new MediaPacket(std::move(packet)));
71 int32_t TransportLayerNSPRAdapter::Recv(void *buf, int32_t buflen) {
72 if (input_.empty()) {
73 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
74 return -1;
77 MediaPacket* front = input_.front();
78 int32_t count = static_cast<int32_t>(front->len());
80 if (buflen < count) {
81 MOZ_ASSERT(false, "Not enough buffer space to receive into");
82 PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
83 return -1;
86 memcpy(buf, front->data(), count);
88 input_.pop();
89 delete front;
91 return count;
94 int32_t TransportLayerNSPRAdapter::Write(const void *buf, int32_t length) {
95 if (!enabled_) {
96 MOZ_MTLOG(ML_WARNING, "Writing to disabled transport layer");
97 return -1;
100 MediaPacket packet;
101 // Copies. Oh well.
102 packet.Copy(static_cast<const uint8_t*>(buf), static_cast<size_t>(length));
104 TransportResult r = output_->SendPacket(packet);
105 if (r >= 0) {
106 return r;
109 if (r == TE_WOULDBLOCK) {
110 PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
111 } else {
112 PR_SetError(PR_IO_ERROR, 0);
115 return -1;
119 // Implementation of NSPR methods
120 static PRStatus TransportLayerClose(PRFileDesc *f) {
121 f->dtor(f);
122 return PR_SUCCESS;
125 static int32_t TransportLayerRead(PRFileDesc *f, void *buf, int32_t length) {
126 UNIMPLEMENTED;
127 return -1;
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) {
136 UNIMPLEMENTED;
137 return -1;
140 int64_t TransportLayerAvailable64(PRFileDesc *f) {
141 UNIMPLEMENTED;
142 return -1;
145 static PRStatus TransportLayerSync(PRFileDesc *f) {
146 UNIMPLEMENTED;
147 return PR_FAILURE;
150 static int32_t TransportLayerSeek(PRFileDesc *f, int32_t offset,
151 PRSeekWhence how) {
152 UNIMPLEMENTED;
153 return -1;
156 static int64_t TransportLayerSeek64(PRFileDesc *f, int64_t offset,
157 PRSeekWhence how) {
158 UNIMPLEMENTED;
159 return -1;
162 static PRStatus TransportLayerFileInfo(PRFileDesc *f, PRFileInfo *info) {
163 UNIMPLEMENTED;
164 return PR_FAILURE;
167 static PRStatus TransportLayerFileInfo64(PRFileDesc *f, PRFileInfo64 *info) {
168 UNIMPLEMENTED;
169 return PR_FAILURE;
172 static int32_t TransportLayerWritev(PRFileDesc *f, const PRIOVec *iov,
173 int32_t iov_size, PRIntervalTime to) {
174 UNIMPLEMENTED;
175 return -1;
178 static PRStatus TransportLayerConnect(PRFileDesc *f, const PRNetAddr *addr,
179 PRIntervalTime to) {
180 UNIMPLEMENTED;
181 return PR_FAILURE;
184 static PRFileDesc *TransportLayerAccept(PRFileDesc *sd, PRNetAddr *addr,
185 PRIntervalTime to) {
186 UNIMPLEMENTED;
187 return nullptr;
190 static PRStatus TransportLayerBind(PRFileDesc *f, const PRNetAddr *addr) {
191 UNIMPLEMENTED;
192 return PR_FAILURE;
195 static PRStatus TransportLayerListen(PRFileDesc *f, int32_t depth) {
196 UNIMPLEMENTED;
197 return PR_FAILURE;
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);
206 return PR_SUCCESS;
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);
213 if (flags != 0) {
214 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
215 return -1;
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);
226 return written;
229 static int32_t TransportLayerRecvfrom(PRFileDesc *f, void *buf, int32_t amount,
230 int32_t flags, PRNetAddr *addr, PRIntervalTime to) {
231 UNIMPLEMENTED;
232 return -1;
235 static int32_t TransportLayerSendto(PRFileDesc *f, const void *buf, int32_t amount,
236 int32_t flags, const PRNetAddr *addr, PRIntervalTime to) {
237 UNIMPLEMENTED;
238 return -1;
241 static int16_t TransportLayerPoll(PRFileDesc *f, int16_t in_flags, int16_t *out_flags) {
242 UNIMPLEMENTED;
243 return -1;
246 static int32_t TransportLayerAcceptRead(PRFileDesc *sd, PRFileDesc **nd,
247 PRNetAddr **raddr,
248 void *buf, int32_t amount, PRIntervalTime t) {
249 UNIMPLEMENTED;
250 return -1;
253 static int32_t TransportLayerTransmitFile(PRFileDesc *sd, PRFileDesc *f,
254 const void *headers, int32_t hlen,
255 PRTransmitFileFlags flags, PRIntervalTime t) {
256 UNIMPLEMENTED;
257 return -1;
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
264 // elsewhere
265 addr->inet.family = PR_AF_INET;
266 addr->inet.port = 0;
267 addr->inet.ip = 0;
269 return PR_SUCCESS;
272 static PRStatus TransportLayerGetsockname(PRFileDesc *f, PRNetAddr *addr) {
273 UNIMPLEMENTED;
274 return PR_FAILURE;
277 static PRStatus TransportLayerGetsockoption(PRFileDesc *f, PRSocketOptionData *opt) {
278 switch (opt->option) {
279 case PR_SockOpt_Nonblocking:
280 opt->value.non_blocking = PR_TRUE;
281 return PR_SUCCESS;
282 default:
283 UNIMPLEMENTED;
284 break;
287 return PR_FAILURE;
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:
295 return PR_SUCCESS;
296 case PR_SockOpt_NoDelay:
297 return PR_SUCCESS;
298 default:
299 UNIMPLEMENTED;
300 break;
303 return PR_FAILURE;
306 static int32_t TransportLayerSendfile(PRFileDesc *out, PRSendFileData *in,
307 PRTransmitFileFlags flags, PRIntervalTime to) {
308 UNIMPLEMENTED;
309 return -1;
312 static PRStatus TransportLayerConnectContinue(PRFileDesc *f, int16_t flags) {
313 UNIMPLEMENTED;
314 return PR_FAILURE;
317 static int32_t TransportLayerReserved(PRFileDesc *f) {
318 UNIMPLEMENTED;
319 return -1;
322 static const struct PRIOMethods TransportLayerMethods = {
323 PR_DESC_LAYERED,
324 TransportLayerClose,
325 TransportLayerRead,
326 TransportLayerWrite,
327 TransportLayerAvailable,
328 TransportLayerAvailable64,
329 TransportLayerSync,
330 TransportLayerSeek,
331 TransportLayerSeek64,
332 TransportLayerFileInfo,
333 TransportLayerFileInfo64,
334 TransportLayerWritev,
335 TransportLayerConnect,
336 TransportLayerAccept,
337 TransportLayerBind,
338 TransportLayerListen,
339 TransportLayerShutdown,
340 TransportLayerRecv,
341 TransportLayerSend,
342 TransportLayerRecvfrom,
343 TransportLayerSendto,
344 TransportLayerPoll,
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_.
364 ssl_fd_ = nullptr;
365 nspr_io_adapter_->SetEnabled(false);
366 if (timer_) {
367 timer_->Cancel();
371 nsresult TransportLayerDtls::InitInternal() {
372 // Get the transport service as an event target
373 nsresult rv;
374 target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
376 if (NS_FAILED(rv)) {
377 MOZ_MTLOG(ML_ERROR, "Couldn't get socket transport service");
378 return rv;
381 timer_ = NS_NewTimer();
382 if (!timer_) {
383 MOZ_MTLOG(ML_ERROR, "Couldn't get timer");
384 return rv;
387 return NS_OK;
391 void TransportLayerDtls::WasInserted() {
392 // Connect to the lower layers
393 if (!Setup()) {
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;
413 return NS_OK;
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;
424 return NS_OK;
427 nsresult
428 TransportLayerDtls::SetVerificationDigest(const std::string digest_algorithm,
429 const unsigned char *digest_value,
430 size_t digest_len) {
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;
448 return NS_OK;
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,
456 ssl_grp_ffdhe_2048,
457 ssl_grp_ffdhe_3072
460 // TODO: make sure this is called from STS. Otherwise
461 // we have thread safety issues
462 bool TransportLayerDtls::Setup() {
463 CheckThread();
464 SECStatus rv;
466 if (!downward_) {
467 MOZ_MTLOG(ML_ERROR, "DTLS layer with nothing below. This is useless");
468 return false;
470 nspr_io_adapter_ = MakeUnique<TransportLayerNSPRAdapter>(downward_);
472 if (!identity_) {
473 MOZ_MTLOG(ML_ERROR, "Can't start DTLS without an identity");
474 return false;
477 if (verification_mode_ == VERIFY_UNSET) {
478 MOZ_MTLOG(ML_ERROR,
479 "Can't start DTLS without specifying a verification mode");
480 return false;
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);
490 if (!pr_fd)
491 return false;
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
496 if (!ssl_fd) {
497 return false;
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,
505 this);
506 if (rv != SECSuccess) {
507 MOZ_MTLOG(ML_ERROR, "Couldn't set identity");
508 return false;
510 } else {
511 MOZ_MTLOG(ML_INFO, "Setting up DTLS as server");
512 // Server side
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");
518 return false;
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");
525 return false;
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");
532 return false;
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");
538 return false;
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");
552 return false;
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");
558 return false;
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");
564 return false;
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");
570 return false;
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");
577 return false;
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");
583 return false;
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");
589 return false;
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");
595 return false;
598 if (!SetupCipherSuites(ssl_fd)) {
599 return false;
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");
606 return false;
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");
614 return false;
617 if (!SetupAlpn(ssl_fd)) {
618 return false;
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");
625 return false;
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);
635 Handshake();
638 return true;
641 bool TransportLayerDtls::SetupAlpn(UniquePRFileDesc& ssl_fd) const {
642 if (alpn_allowed_.empty()) {
643 return true;
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");
649 return false;
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");
655 return false;
658 unsigned char buf[MAX_ALPN_LENGTH];
659 size_t offset = 0;
660 for (const auto& tag : alpn_allowed_) {
661 if ((offset + 1 + tag.length()) >= sizeof(buf)) {
662 MOZ_MTLOG(ML_ERROR, "ALPN too long");
663 return false;
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");
672 return false;
674 return true;
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) {
747 SECStatus rv;
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");
756 return false;
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);
766 return false;
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);
778 return false;
780 if (enabled) {
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);
785 return false;
790 return true;
793 nsresult TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite) const {
794 CheckThread();
795 if (!cipherSuite) {
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;
802 SSLChannelInfo info;
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;
809 return NS_OK;
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);
816 return;
819 switch (state) {
820 case TS_NONE:
821 MOZ_ASSERT(false); // Can't happen
822 break;
824 case TS_INIT:
825 MOZ_MTLOG(ML_ERROR,
826 LAYER_INFO << "State change of lower layer to INIT forbidden");
827 TL_SET_STATE(TS_ERROR);
828 break;
830 case TS_CONNECTING:
831 MOZ_MTLOG(ML_INFO, LAYER_INFO << "Lower layer is connecting.");
832 break;
834 case TS_OPEN:
835 MOZ_MTLOG(ML_INFO,
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);
840 timer_->Cancel();
841 timer_->SetTarget(target_);
842 timer_->InitWithNamedFuncCallback(TimerCallback,
843 this,
845 nsITimer::TYPE_ONE_SHOT,
846 "TransportLayerDtls::TimerCallback");
847 break;
849 case TS_CLOSED:
850 MOZ_MTLOG(ML_INFO, LAYER_INFO << "Lower layer is now closed");
851 TL_SET_STATE(TS_CLOSED);
852 break;
854 case TS_ERROR:
855 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Lower layer experienced an error");
856 TL_SET_STATE(TS_ERROR);
857 break;
861 void TransportLayerDtls::Handshake() {
862 // Clear the retransmit timer
863 timer_->Cancel();
865 MOZ_ASSERT(state_ == TS_CONNECTING);
867 SECStatus rv = SSL_ForceHandshake(ssl_fd_.get());
869 if (rv == SECSuccess) {
870 MOZ_MTLOG(ML_NOTICE,
871 LAYER_INFO << "****** SSL handshake completed ******");
872 if (!cert_ok_) {
873 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Certificate check never occurred");
874 TL_SET_STATE(TS_ERROR);
875 return;
877 if (!CheckAlpn()) {
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).
881 ssl_fd_ = nullptr;
882 TL_SET_STATE(TS_ERROR);
883 return;
885 if (!enabled_srtp_ciphers_.empty() && srtp_cipher_ == 0) {
886 // We enabled SRTP, but got no cipher, this should have failed.
887 ssl_fd_ = nullptr;
888 TL_SET_STATE(TS_ERROR);
889 return;
892 TL_SET_STATE(TS_OPEN);
894 RecordCipherTelemetry();
895 } else {
896 int32_t err = PR_GetError();
897 switch(err) {
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
902 MOZ_FALLTHROUGH;
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);
910 MOZ_MTLOG(ML_DEBUG,
911 LAYER_INFO << "Setting DTLS timeout to " << timeout_ms);
912 timer_->SetTarget(target_);
913 timer_->InitWithNamedFuncCallback(TimerCallback,
914 this, timeout_ms,
915 nsITimer::TYPE_ONE_SHOT,
916 "TransportLayerDtls::TimerCallback");
918 break;
919 default:
920 const char *err_msg = PR_ErrorToName(err);
921 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "DTLS handshake error " << err << " ("
922 << err_msg << ")");
923 TL_SET_STATE(TS_ERROR);
924 break;
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
931 // protocol.
932 bool TransportLayerDtls::CheckAlpn() {
933 if (alpn_allowed_.empty()) {
934 return true;
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");
945 return false;
947 switch (alpnState) {
948 case SSL_NEXT_PROTO_SELECTED:
949 case SSL_NEXT_PROTO_NEGOTIATED:
950 break; // OK
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");
962 return false;
964 case SSL_NEXT_PROTO_EARLY_VALUE:
965 MOZ_CRASH("Unexpected 0-RTT ALPN value");
966 return false;
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());
981 return false;
983 alpn_ = chosen;
984 return true;
988 void TransportLayerDtls::PacketReceived(TransportLayer* layer,
989 MediaPacket& packet) {
990 CheckThread();
991 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "PacketReceived(" << packet.len() << ")");
993 if (state_ != TS_CONNECTING && state_ != TS_OPEN) {
994 MOZ_MTLOG(ML_DEBUG,
995 LAYER_INFO << "Discarding packet in inappropriate state");
996 return;
999 if (!packet.data()) {
1000 // Something ate this, probably the SRTP layer
1001 return;
1004 // not DTLS per RFC 7983
1005 if (packet.data()[0] < 20 || packet.data()[0] > 63) {
1006 return;
1009 nspr_io_adapter_->PacketReceived(packet);
1010 GetDecryptedPackets();
1013 void
1014 TransportLayerDtls::GetDecryptedPackets()
1016 // If we're still connecting, try to handshake
1017 if (state_ == TS_CONNECTING) {
1018 Handshake();
1021 // Now try a recv if we're open, since there might be data left
1022 if (state_ == TS_OPEN) {
1023 int32_t rv;
1024 // One packet might contain several DTLS packets
1025 do {
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);
1031 if (rv > 0) {
1032 // We have data
1033 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read " << rv << " bytes from NSS");
1034 MediaPacket packet;
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);
1039 } else {
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");
1045 } else {
1046 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "NSS Error " << err);
1047 TL_SET_STATE(TS_ERROR);
1050 } while (rv > 0);
1054 void TransportLayerDtls::SetState(State state,
1055 const char *file,
1056 unsigned line) {
1057 if (state > state_) {
1058 switch (state) {
1059 case TS_NONE:
1060 case TS_INIT:
1061 MOZ_ASSERT(false);
1062 break;
1063 case TS_CONNECTING:
1064 handshake_started_ = TimeStamp::Now();
1065 break;
1066 case TS_OPEN:
1067 case TS_CLOSED:
1068 case TS_ERROR:
1069 timer_->Cancel();
1070 if (state_ == TS_CONNECTING) {
1071 RecordHandshakeCompletionTelemetry(state);
1073 break;
1075 } else {
1076 MOZ_ASSERT(false, "Invalid state transition");
1079 TransportLayer::SetState(state, file, line);
1082 TransportResult TransportLayerDtls::SendPacket(MediaPacket& packet) {
1083 CheckThread();
1084 if (state_ != TS_OPEN) {
1085 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Can't call SendPacket() in state "
1086 << state_);
1087 return TE_ERROR;
1090 int32_t rv = PR_Send(ssl_fd_.get(), packet.data(), packet.len(), 0,
1091 PR_INTERVAL_NO_WAIT);
1093 if (rv > 0) {
1094 // We have data
1095 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Wrote " << rv << " bytes to SSL Layer");
1096 return rv;
1099 if (rv == 0) {
1100 TL_SET_STATE(TS_CLOSED);
1101 return 0;
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);
1114 return TE_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);
1129 return SECFailure;
1132 *pRetCert = CERT_DupCertificate(stream->identity_->cert().get());
1133 if (!*pRetCert) {
1134 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
1135 return SECFailure;
1138 *pRetKey = SECKEY_CopyPrivateKey(stream->identity_->privkey().get());
1139 if (!*pRetKey) {
1140 CERT_DestroyCertificate(*pRetCert);
1141 *pRetCert = nullptr;
1142 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
1143 return SECFailure;
1146 return SECSuccess;
1149 nsresult TransportLayerDtls::SetSrtpCiphers(const std::vector<uint16_t>& ciphers) {
1150 enabled_srtp_ciphers_ = std::move(ciphers);
1151 return NS_OK;
1154 nsresult TransportLayerDtls::GetSrtpCipher(uint16_t *cipher) const {
1155 CheckThread();
1156 if (srtp_cipher_ == 0) {
1157 return NS_ERROR_NOT_AVAILABLE;
1159 *cipher = srtp_cipher_;
1160 return NS_OK;
1163 static uint8_t* WriteUint16(uint8_t* cursor, uint16_t v) {
1164 *cursor++ = v >> 8;
1165 *cursor++ = v & 0xff;
1166 return cursor;
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");
1194 return false;
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;
1202 return true;
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.
1209 return false;
1211 if (max_len < 5) {
1212 MOZ_ASSERT(false, "Not enough space to send SRTP extension");
1213 return false;
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;
1220 return true;
1223 return false;
1226 class TlsParser {
1227 public:
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) {
1239 error_ = true;
1240 return;
1243 T result = 0;
1244 for (size_t i = 0; i < sz; ++i) {
1245 result = (result << 8) | *cursor_++;
1246 remaining_--;
1248 *v = result;
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");
1256 uint32_t len;
1257 Read(&len, w);
1258 if (error_ || len % sizeof(T) != 0 || len > remaining_) {
1259 error_ = true;
1260 return;
1263 size_t count = len / sizeof(T);
1264 v->reserve(count);
1265 for (T i = 0; !error_ && i < count; ++i) {
1266 T item;
1267 Read(&item);
1268 if (!error_) {
1269 v->push_back(item);
1274 void Skip(size_t n) {
1275 if (remaining_ < n) {
1276 error_ = true;
1277 } else {
1278 cursor_ += n;
1279 remaining_ -= n;
1283 size_t SkipVector(size_t w) {
1284 uint32_t len = 0;
1285 Read(&len, w);
1286 Skip(len);
1287 return len;
1290 private:
1291 const uint8_t* cursor_;
1292 size_t remaining_;
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;
1313 return SECFailure;
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
1321 // is a problem.
1322 return SECSuccess;
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;
1329 return SECSuccess;
1333 // No common cipher.
1334 *alert = kTlsAlertHandshakeFailure;
1335 return SECFailure;
1338 if (message == SrtpXtnServerMessage(fd)) {
1339 MOZ_ASSERT(self->role_ == CLIENT);
1340 if (advertised.size() != 1 || mki_len > 0) {
1341 *alert = kTlsAlertIllegalParameter;
1342 return SECFailure;
1344 self->srtp_cipher_ = advertised[0];
1345 return SECSuccess;
1348 *alert = kTlsAlertUnsupportedExtension;
1349 return SECFailure;
1352 nsresult TransportLayerDtls::ExportKeyingMaterial(const std::string& label,
1353 bool use_context,
1354 const std::string& context,
1355 unsigned char *out,
1356 unsigned int outlen) {
1357 CheckThread();
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(),
1363 label.c_str(),
1364 label.size(),
1365 use_context,
1366 reinterpret_cast<const unsigned char *>(
1367 context.c_str()),
1368 context.size(),
1369 out,
1370 outlen);
1371 if (rv != SECSuccess) {
1372 MOZ_MTLOG(ML_ERROR, "Couldn't export SSL keying material");
1373 return NS_ERROR_FAILURE;
1376 return NS_OK;
1379 SECStatus TransportLayerDtls::AuthCertificateHook(void *arg,
1380 PRFileDesc *fd,
1381 PRBool checksig,
1382 PRBool isServer) {
1383 TransportLayerDtls *stream = reinterpret_cast<TransportLayerDtls *>(arg);
1384 stream->CheckThread();
1385 return stream->AuthCertificateHook(fd, checksig, isServer);
1388 SECStatus
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_);
1396 nsresult res =
1397 DtlsIdentity::ComputeFingerprint(peer_cert,
1398 digest->algorithm_,
1399 computed_digest,
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_);
1405 // Go to end
1406 PR_SetError(SSL_ERROR_BAD_CERTIFICATE, 0);
1407 return SECFailure;
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);
1415 return SECFailure;
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);
1421 return SECFailure;
1424 return SECSuccess;
1428 SECStatus TransportLayerDtls::AuthCertificateHook(PRFileDesc *fd,
1429 PRBool checksig,
1430 PRBool isServer) {
1431 CheckThread();
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);
1439 return SECFailure;
1441 auth_hook_called_ = true;
1443 MOZ_ASSERT(verification_mode_ != VERIFY_UNSET);
1445 switch (verification_mode_) {
1446 case VERIFY_UNSET:
1447 // Break out to error exit
1448 PR_SetError(PR_UNKNOWN_ERROR, 0);
1449 break;
1451 case VERIFY_ALLOW_ALL:
1452 cert_ok_ = true;
1453 return SECSuccess;
1455 case VERIFY_DIGEST:
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) {
1467 cert_ok_ = true;
1468 return SECSuccess;
1472 break;
1473 default:
1474 MOZ_CRASH(); // Can't happen
1477 return SECFailure;
1480 void TransportLayerDtls::TimerCallback(nsITimer *timer, void *arg) {
1481 TransportLayerDtls *dtls = reinterpret_cast<TransportLayerDtls *>(arg);
1483 MOZ_MTLOG(ML_DEBUG, "DTLS timer expired");
1485 dtls->Handshake();
1488 void
1489 TransportLayerDtls::RecordHandshakeCompletionTelemetry(
1490 TransportLayer::State endState) {
1491 int32_t delta = (TimeStamp::Now() - handshake_started_).ToMilliseconds();
1493 switch (endState) {
1494 case TransportLayer::State::TS_OPEN:
1495 if (role_ == TransportLayerDtls::CLIENT) {
1496 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CLIENT_SUCCESS_TIME,
1497 delta);
1498 } else {
1499 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_SERVER_SUCCESS_TIME,
1500 delta);
1502 return;
1503 case TransportLayer::State::TS_ERROR:
1504 if (role_ == TransportLayerDtls::CLIENT) {
1505 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CLIENT_FAILURE_TIME,
1506 delta);
1507 } else {
1508 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_SERVER_FAILURE_TIME,
1509 delta);
1511 return;
1512 case TransportLayer::State::TS_CLOSED:
1513 if (role_ == TransportLayerDtls::CLIENT) {
1514 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CLIENT_ABORT_TIME, delta);
1515 } else {
1516 Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_SERVER_ABORT_TIME, delta);
1518 return;
1519 default:
1520 MOZ_ASSERT(false);
1524 void
1525 TransportLayerDtls::RecordCipherTelemetry() {
1526 uint16_t cipher;
1528 nsresult rv = GetCipherSuite(&cipher);
1530 if (NS_FAILED(rv)) {
1531 MOZ_MTLOG(ML_ERROR, "Failed to get DTLS cipher suite");
1532 return;
1535 uint16_t t_cipher = 0;
1537 switch (cipher) {
1538 /* Old DHE ciphers: candidates for removal, see bug 1227519 */
1539 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
1540 t_cipher = 1;
1541 break;
1542 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
1543 t_cipher = 2;
1544 break;
1545 /* Current ciphers */
1546 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
1547 t_cipher = 3;
1548 break;
1549 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
1550 t_cipher = 4;
1551 break;
1552 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
1553 t_cipher = 5;
1554 break;
1555 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
1556 t_cipher = 6;
1557 break;
1558 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
1559 t_cipher = 7;
1560 break;
1561 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
1562 t_cipher = 8;
1563 break;
1564 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
1565 t_cipher = 9;
1566 break;
1567 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
1568 t_cipher = 10;
1569 break;
1570 /* TLS 1.3 ciphers */
1571 case TLS_AES_128_GCM_SHA256:
1572 t_cipher = 11;
1573 break;
1574 case TLS_CHACHA20_POLY1305_SHA256:
1575 t_cipher = 12;
1576 break;
1577 case TLS_AES_256_GCM_SHA384:
1578 t_cipher = 13;
1579 break;
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");
1588 return;
1591 mozilla::Telemetry::LABELS_WEBRTC_SRTP_CIPHER label =
1592 mozilla::Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Unknown;
1594 switch (cipher) {
1595 case kDtlsSrtpAes128CmHmacSha1_80:
1596 label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_80;
1597 break;
1598 case kDtlsSrtpAes128CmHmacSha1_32:
1599 label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_32;
1600 break;
1601 case kDtlsSrtpAeadAes128Gcm:
1602 label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes128Gcm;
1603 break;
1604 case kDtlsSrtpAeadAes256Gcm:
1605 label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes256Gcm;
1606 break;
1609 Telemetry::AccumulateCategorical(label);
1613 } // close namespace