Bug Summary

File:root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp
Warning:line 1612, column 7
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name transportlayerdtls.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D LINUX -D HAVE_STRDUP -D NR_SOCKET_IS_VOID_PTR -D R_DEFINED_INT2=int16_t -D R_DEFINED_UINT2=uint16_t -D R_DEFINED_INT4=int32_t -D R_DEFINED_UINT4=uint32_t -D R_DEFINED_INT8=int64_t -D R_DEFINED_UINT8=uint64_t -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/media/webrtc/transport/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/dom/media/webrtc/transport -I /root/firefox-clang/dom/media/webrtc/transport/third_party -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/crypto -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/net -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/util -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/event -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/log -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/generic/include -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/registry -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/share -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr -I /root/firefox-clang/third_party/libsrtp/src/crypto/include -I /root/firefox-clang/third_party/libsrtp/src/include -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/linux/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ /root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5// Original author: ekr@rtfm.com
6
7#include "transportlayerdtls.h"
8
9#include <algorithm>
10#include <iomanip>
11#include <optional>
12#include <sstream>
13
14#include "dtlsidentity.h"
15#include "keyhi.h"
16#include "logging.h"
17#include "mozilla/StaticPrefs_media.h"
18#include "mozilla/StaticPrefs_security.h"
19#include "mozilla/UniquePtr.h"
20#include "mozilla/glean/DomMediaWebrtcMetrics.h"
21#include "nsCOMPtr.h"
22#include "nsNetCID.h"
23#include "nsServiceManagerUtils.h"
24#include "sslexp.h"
25#include "sslproto.h"
26
27namespace mozilla {
28
29MOZ_MTLOG_MODULE("mtransport")static mozilla::LogModule* getLogModule() { static mozilla::LazyLogModule
log("mtransport"); return static_cast<mozilla::LogModule*
>(log); }
30
31static PRDescIdentity transport_layer_identity = PR_INVALID_IO_LAYER(PRDescIdentity) - 1;
32
33// TODO: Implement a mode for this where
34// the channel is not ready until confirmed externally
35// (e.g., after cert check).
36
37#define UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 37); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")"); do
{ MOZ_CrashSequence(__null, 37); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); PR_SetError((-5992L
), 0)
\
38 MOZ_MTLOG(ML_ERROR, "Call to unimplemented function " << __FUNCTION__)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
; \
39 MOZ_ASSERT(false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 39); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")"); do
{ MOZ_CrashSequence(__null, 39); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
; \
40 PR_SetError(PR_NOT_IMPLEMENTED_ERROR(-5992L), 0)
41
42#define MAX_ALPN_LENGTH255 255
43
44// We need to adapt the NSPR/libssl model to the TransportFlow model.
45// The former wants pull semantics and TransportFlow wants push.
46//
47// - A TransportLayerDtls assumes it is sitting on top of another
48// TransportLayer, which means that events come in asynchronously.
49// - NSS (libssl) wants to sit on top of a PRFileDesc and poll.
50// - The TransportLayerNSPRAdapter is a PRFileDesc containing a
51// FIFO.
52// - When TransportLayerDtls.PacketReceived() is called, we insert
53// the packets in the FIFO and then do a PR_Recv() on the NSS
54// PRFileDesc, which eventually reads off the FIFO.
55//
56// All of this stuff is assumed to happen solely in a single thread
57// (generally the SocketTransportService thread)
58
59void TransportLayerNSPRAdapter::PacketReceived(MediaPacket& packet) {
60 if (enabled_) {
61 input_.push(new MediaPacket(std::move(packet)));
62 }
63}
64
65int32_t TransportLayerNSPRAdapter::Recv(void* buf, int32_t buflen) {
66 if (input_.empty()) {
67 PR_SetError(PR_WOULD_BLOCK_ERROR(-5998L), 0);
68 return -1;
69 }
70
71 MediaPacket* front = input_.front();
72 int32_t count = static_cast<int32_t>(front->len());
73
74 if (buflen < count) {
75 MOZ_ASSERT(false, "Not enough buffer space to receive into")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Not enough buffer space to receive into"
")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 75); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") (" "Not enough buffer space to receive into"
")"); do { MOZ_CrashSequence(__null, 75); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
76 PR_SetError(PR_BUFFER_OVERFLOW_ERROR(-5962L), 0);
77 return -1;
78 }
79
80 memcpy(buf, front->data(), count);
81
82 input_.pop();
83 delete front;
84
85 return count;
86}
87
88int32_t TransportLayerNSPRAdapter::Write(const void* buf, int32_t length) {
89 if (!enabled_) {
90 MOZ_MTLOG(ML_WARNING, "Writing to disabled transport layer")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Warning)), 0))) { std::stringstream str
; str << "Writing to disabled transport layer"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Warning)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Warning, "{}", str.str()
.c_str()); } } while (0); } } while (0)
;
91 return -1;
92 }
93
94 MediaPacket packet;
95 // Copies. Oh well.
96 packet.Copy(static_cast<const uint8_t*>(buf), static_cast<size_t>(length));
97 packet.SetType(MediaPacket::DTLS);
98
99 TransportResult r = output_->SendPacket(packet);
100 if (r >= 0) {
101 return r;
102 }
103
104 if (r == TE_WOULDBLOCK) {
105 PR_SetError(PR_WOULD_BLOCK_ERROR(-5998L), 0);
106 } else {
107 PR_SetError(PR_IO_ERROR(-5991L), 0);
108 }
109
110 return -1;
111}
112
113// Implementation of NSPR methods
114static PRStatus TransportLayerClose(PRFileDesc* f) {
115 f->dtor(f);
116 return PR_SUCCESS;
117}
118
119static int32_t TransportLayerRead(PRFileDesc* f, void* buf, int32_t length) {
120 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 120); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
121 return -1;
122}
123
124static int32_t TransportLayerWrite(PRFileDesc* f, const void* buf,
125 int32_t length) {
126 TransportLayerNSPRAdapter* io =
127 reinterpret_cast<TransportLayerNSPRAdapter*>(f->secret);
128 return io->Write(buf, length);
129}
130
131static int32_t TransportLayerAvailable(PRFileDesc* f) {
132 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 132); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 132); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
133 return -1;
134}
135
136int64_t TransportLayerAvailable64(PRFileDesc* f) {
137 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 137); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 137); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
138 return -1;
139}
140
141static PRStatus TransportLayerSync(PRFileDesc* f) {
142 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 142); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
143 return PR_FAILURE;
144}
145
146static int32_t TransportLayerSeek(PRFileDesc* f, int32_t offset,
147 PRSeekWhence how) {
148 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 148); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 148); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
149 return -1;
150}
151
152static int64_t TransportLayerSeek64(PRFileDesc* f, int64_t offset,
153 PRSeekWhence how) {
154 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 154); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
155 return -1;
156}
157
158static PRStatus TransportLayerFileInfo(PRFileDesc* f, PRFileInfo* info) {
159 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 159); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 159); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
160 return PR_FAILURE;
161}
162
163static PRStatus TransportLayerFileInfo64(PRFileDesc* f, PRFileInfo64* info) {
164 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 164); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 164); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
165 return PR_FAILURE;
166}
167
168static int32_t TransportLayerWritev(PRFileDesc* f, const PRIOVec* iov,
169 int32_t iov_size, PRIntervalTime to) {
170 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 170); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 170); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
171 return -1;
172}
173
174static PRStatus TransportLayerConnect(PRFileDesc* f, const PRNetAddr* addr,
175 PRIntervalTime to) {
176 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 176); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 176); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
177 return PR_FAILURE;
178}
179
180static PRFileDesc* TransportLayerAccept(PRFileDesc* sd, PRNetAddr* addr,
181 PRIntervalTime to) {
182 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 182); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 182); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
183 return nullptr;
184}
185
186static PRStatus TransportLayerBind(PRFileDesc* f, const PRNetAddr* addr) {
187 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 187); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 187); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
188 return PR_FAILURE;
189}
190
191static PRStatus TransportLayerListen(PRFileDesc* f, int32_t depth) {
192 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 192); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
193 return PR_FAILURE;
194}
195
196static PRStatus TransportLayerShutdown(PRFileDesc* f, int32_t how) {
197 // This is only called from NSS when we are the server and the client refuses
198 // to provide a certificate. In this case, the handshake is destined for
199 // failure, so we will just let this pass.
200 TransportLayerNSPRAdapter* io =
201 reinterpret_cast<TransportLayerNSPRAdapter*>(f->secret);
202 io->SetEnabled(false);
203 return PR_SUCCESS;
204}
205
206// This function does not support peek, or waiting until `to`
207static int32_t TransportLayerRecv(PRFileDesc* f, void* buf, int32_t buflen,
208 int32_t flags, PRIntervalTime to) {
209 MOZ_ASSERT(flags == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(flags == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(flags == 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("flags == 0", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 209); AnnotateMozCrashReason("MOZ_ASSERT" "(" "flags == 0" ")"
); do { MOZ_CrashSequence(__null, 209); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
210 if (flags != 0) {
211 PR_SetError(PR_NOT_IMPLEMENTED_ERROR(-5992L), 0);
212 return -1;
213 }
214
215 TransportLayerNSPRAdapter* io =
216 reinterpret_cast<TransportLayerNSPRAdapter*>(f->secret);
217 return io->Recv(buf, buflen);
218}
219
220// Note: this is always nonblocking and assumes a zero timeout.
221static int32_t TransportLayerSend(PRFileDesc* f, const void* buf,
222 int32_t amount, int32_t flags,
223 PRIntervalTime to) {
224 int32_t written = TransportLayerWrite(f, buf, amount);
225 return written;
226}
227
228static int32_t TransportLayerRecvfrom(PRFileDesc* f, void* buf, int32_t amount,
229 int32_t flags, PRNetAddr* addr,
230 PRIntervalTime to) {
231 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 231); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 231); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
232 return -1;
233}
234
235static int32_t TransportLayerSendto(PRFileDesc* f, const void* buf,
236 int32_t amount, int32_t flags,
237 const PRNetAddr* addr, PRIntervalTime to) {
238 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 238); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 238); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
239 return -1;
240}
241
242static int16_t TransportLayerPoll(PRFileDesc* f, int16_t in_flags,
243 int16_t* out_flags) {
244 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 244); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 244); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
245 return -1;
246}
247
248static int32_t TransportLayerAcceptRead(PRFileDesc* sd, PRFileDesc** nd,
249 PRNetAddr** raddr, void* buf,
250 int32_t amount, PRIntervalTime t) {
251 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 251); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 251); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
252 return -1;
253}
254
255static int32_t TransportLayerTransmitFile(PRFileDesc* sd, PRFileDesc* f,
256 const void* headers, int32_t hlen,
257 PRTransmitFileFlags flags,
258 PRIntervalTime t) {
259 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 259); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 259); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
260 return -1;
261}
262
263static PRStatus TransportLayerGetpeername(PRFileDesc* f, PRNetAddr* addr) {
264 // TODO: Modify to return unique names for each channel
265 // somehow, as opposed to always the same static address. The current
266 // implementation messes up the session cache, which is why it's off
267 // elsewhere
268 addr->inet.family = PR_AF_INET2;
269 addr->inet.port = 0;
270 addr->inet.ip = 0;
271
272 return PR_SUCCESS;
273}
274
275static PRStatus TransportLayerGetsockname(PRFileDesc* f, PRNetAddr* addr) {
276 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 276); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
277 return PR_FAILURE;
278}
279
280static PRStatus TransportLayerGetsockoption(PRFileDesc* f,
281 PRSocketOptionData* opt) {
282 switch (opt->option) {
283 case PR_SockOpt_Nonblocking:
284 opt->value.non_blocking = PR_TRUE1;
285 return PR_SUCCESS;
286 default:
287 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 287); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 287); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
288 break;
289 }
290
291 return PR_FAILURE;
292}
293
294// Imitate setting socket options. These are mostly noops.
295static PRStatus TransportLayerSetsockoption(PRFileDesc* f,
296 const PRSocketOptionData* opt) {
297 switch (opt->option) {
298 case PR_SockOpt_Nonblocking:
299 return PR_SUCCESS;
300 case PR_SockOpt_NoDelay:
301 return PR_SUCCESS;
302 default:
303 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 303); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 303); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
304 break;
305 }
306
307 return PR_FAILURE;
308}
309
310static int32_t TransportLayerSendfile(PRFileDesc* out, PRSendFileData* in,
311 PRTransmitFileFlags flags,
312 PRIntervalTime to) {
313 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 313); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 313); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
314 return -1;
315}
316
317static PRStatus TransportLayerConnectContinue(PRFileDesc* f, int16_t flags) {
318 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 318); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 318); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
319 return PR_FAILURE;
320}
321
322static int32_t TransportLayerReserved(PRFileDesc* f) {
323 UNIMPLEMENTEDdo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Call to unimplemented function " << __FUNCTION__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0); do { static_assert( mozilla
::detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 323); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 323); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false); PR_SetError(
(-5992L), 0)
;
324 return -1;
325}
326
327static const struct PRIOMethods TransportLayerMethods = {
328 PR_DESC_LAYERED,
329 TransportLayerClose,
330 TransportLayerRead,
331 TransportLayerWrite,
332 TransportLayerAvailable,
333 TransportLayerAvailable64,
334 TransportLayerSync,
335 TransportLayerSeek,
336 TransportLayerSeek64,
337 TransportLayerFileInfo,
338 TransportLayerFileInfo64,
339 TransportLayerWritev,
340 TransportLayerConnect,
341 TransportLayerAccept,
342 TransportLayerBind,
343 TransportLayerListen,
344 TransportLayerShutdown,
345 TransportLayerRecv,
346 TransportLayerSend,
347 TransportLayerRecvfrom,
348 TransportLayerSendto,
349 TransportLayerPoll,
350 TransportLayerAcceptRead,
351 TransportLayerTransmitFile,
352 TransportLayerGetsockname,
353 TransportLayerGetpeername,
354 TransportLayerReserved,
355 TransportLayerReserved,
356 TransportLayerGetsockoption,
357 TransportLayerSetsockoption,
358 TransportLayerSendfile,
359 TransportLayerConnectContinue,
360 TransportLayerReserved,
361 TransportLayerReserved,
362 TransportLayerReserved,
363 TransportLayerReserved};
364
365TransportLayerDtls::~TransportLayerDtls() {
366 // Destroy the NSS instance first so it can still send out an alert before
367 // we disable the nspr_io_adapter_.
368 ssl_fd_ = nullptr;
369 nspr_io_adapter_->SetEnabled(false);
370 if (timer_) {
371 timer_->Cancel();
372 }
373}
374
375nsresult TransportLayerDtls::InitInternal() {
376 // Get the transport service as an event target
377 nsresult rv;
378 target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/socket-transport-service;1", &rv);
379
380 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
381 MOZ_MTLOG(ML_ERROR, "Couldn't get socket transport service")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't get socket transport service"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
382 return rv;
383 }
384
385 timer_ = NS_NewTimer();
386 if (!timer_) {
387 MOZ_MTLOG(ML_ERROR, "Couldn't get timer")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't get timer"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
388 return rv;
389 }
390
391 return NS_OK;
392}
393
394void TransportLayerDtls::WasInserted() {
395 // Connect to the lower layers
396 if (!Setup()) {
397 mErrorDescription = "Internal error";
398 mHasDtlsFailureError = true;
399 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 399)
;
400 }
401}
402
403// Set the permitted and default ALPN identifiers.
404// The default is here to allow for peers that don't want to negotiate ALPN
405// in that case, the default string will be reported from GetNegotiatedAlpn().
406// Setting the default to the empty string causes the transport layer to fail
407// if ALPN is not negotiated.
408// Note: we only support Unicode strings here, which are encoded into UTF-8,
409// even though ALPN ostensibly allows arbitrary octet sequences.
410nsresult TransportLayerDtls::SetAlpn(const std::set<std::string>& alpn_allowed,
411 const std::string& alpn_default) {
412 alpn_allowed_ = alpn_allowed;
413 alpn_default_ = alpn_default;
414
415 return NS_OK;
416}
417
418nsresult TransportLayerDtls::SetVerificationAllowAll() {
419 // Defensive programming
420 if (verification_mode_ != VERIFY_UNSET) return NS_ERROR_ALREADY_INITIALIZED;
421
422 verification_mode_ = VERIFY_ALLOW_ALL;
423
424 return NS_OK;
425}
426
427nsresult TransportLayerDtls::SetVerificationDigest(const DtlsDigest& digest) {
428 // Defensive programming
429 if (verification_mode_ != VERIFY_UNSET &&
430 verification_mode_ != VERIFY_DIGEST) {
431 return NS_ERROR_ALREADY_INITIALIZED;
432 }
433
434 digests_.push_back(digest);
435 verification_mode_ = VERIFY_DIGEST;
436 return NS_OK;
437}
438
439void TransportLayerDtls::SetMinMaxVersion(Version min_version,
440 Version max_version) {
441 if (min_version < Version::DTLS_1_0 || min_version > Version::DTLS_1_3 ||
442 max_version < Version::DTLS_1_0 || max_version > Version::DTLS_1_3 ||
443 min_version > max_version || max_version < min_version) {
444 return;
445 }
446 minVersion_ = min_version;
447 maxVersion_ = max_version;
448}
449
450// TODO: make sure this is called from STS. Otherwise
451// we have thread safety issues
452bool TransportLayerDtls::Setup() {
453 CheckThread();
454 SECStatus rv;
455
456 if (!downward_) {
457 MOZ_MTLOG(ML_ERROR, "DTLS layer with nothing below. This is useless")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "DTLS layer with nothing below. This is useless"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
458 return false;
459 }
460 nspr_io_adapter_ = MakeUnique<TransportLayerNSPRAdapter>(downward_);
461
462 if (!identity_) {
463 MOZ_MTLOG(ML_ERROR, "Can't start DTLS without an identity")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Can't start DTLS without an identity"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
464 return false;
465 }
466
467 if (verification_mode_ == VERIFY_UNSET) {
468 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Can't start DTLS without specifying a verification mode"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
469 "Can't start DTLS without specifying a verification mode")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Can't start DTLS without specifying a verification mode"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
470 return false;
471 }
472
473 if (transport_layer_identity == PR_INVALID_IO_LAYER(PRDescIdentity) - 1) {
474 transport_layer_identity = PR_GetUniqueIdentity("nssstreamadapter");
475 }
476
477 UniquePRFileDesc pr_fd(
478 PR_CreateIOLayerStub(transport_layer_identity, &TransportLayerMethods));
479 MOZ_ASSERT(pr_fd != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pr_fd != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pr_fd != nullptr))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("pr_fd != nullptr"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 479); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pr_fd != nullptr"
")"); do { MOZ_CrashSequence(__null, 479); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
480 if (!pr_fd) return false;
481 pr_fd->secret = reinterpret_cast<PRFilePrivate*>(nspr_io_adapter_.get());
482
483 UniquePRFileDesc ssl_fd(DTLS_ImportFD(nullptr, pr_fd.get()));
484 MOZ_ASSERT(ssl_fd != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ssl_fd != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ssl_fd != nullptr))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("ssl_fd != nullptr"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 484); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ssl_fd != nullptr"
")"); do { MOZ_CrashSequence(__null, 484); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; // This should never happen
485 if (!ssl_fd) {
486 return false;
487 }
488
489 (void)pr_fd.release(); // ownership transfered to ssl_fd;
490
491 if (role_ == CLIENT) {
492 MOZ_MTLOG(ML_INFO, "Setting up DTLS as client")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Setting up DTLS as client"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Debug)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Debug, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
493 rv = SSL_GetClientAuthDataHook(ssl_fd.get(), GetClientAuthDataHook, this);
494 if (rv != SECSuccess) {
495 MOZ_MTLOG(ML_ERROR, "Couldn't set identity")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set identity"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
496 return false;
497 }
498
499 if (maxVersion_ >= Version::DTLS_1_3) {
500 MOZ_MTLOG(ML_INFO, "Setting DTLS1.3 supported_versions workaround")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Setting DTLS1.3 supported_versions workaround"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
501 rv = SSL_SetDtls13VersionWorkaround(ssl_fd.get(), PR_TRUE)(SSL_GetExperimentalAPI("SSL_SetDtls13VersionWorkaround") ? (
(SECStatus(*) (PRFileDesc * _fd, PRBool _enabled))SSL_GetExperimentalAPI
("SSL_SetDtls13VersionWorkaround"))(ssl_fd.get(), 1) : SECFailure
)
;
502 if (rv != SECSuccess) {
503 MOZ_MTLOG(ML_ERROR, "Couldn't set DTLS1.3 workaround")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set DTLS1.3 workaround"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
504 return false;
505 }
506 }
507 } else {
508 MOZ_MTLOG(ML_INFO, "Setting up DTLS as server")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Setting up DTLS as server"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Debug)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Debug, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
509 // Server side
510 rv = SSL_ConfigSecureServer(ssl_fd.get(), identity_->cert().get(),
511 identity_->privkey().get(),
512 identity_->auth_type());
513 if (rv != SECSuccess) {
514 MOZ_MTLOG(ML_ERROR, "Couldn't set identity")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set identity"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
515 return false;
516 }
517
518 UniqueCERTCertList zero_certs(CERT_NewCertList());
519 rv = SSL_SetTrustAnchors(ssl_fd.get(), zero_certs.get());
520 if (rv != SECSuccess) {
521 MOZ_MTLOG(ML_ERROR, "Couldn't set trust anchors")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set trust anchors"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
522 return false;
523 }
524
525 // Insist on a certificate from the client
526 rv = SSL_OptionSet(ssl_fd.get(), SSL_REQUEST_CERTIFICATE3, PR_TRUE1);
527 if (rv != SECSuccess) {
528 MOZ_MTLOG(ML_ERROR, "Couldn't request certificate")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't request certificate"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
529 return false;
530 }
531
532 rv = SSL_OptionSet(ssl_fd.get(), SSL_REQUIRE_CERTIFICATE10, PR_TRUE1);
533 if (rv != SECSuccess) {
534 MOZ_MTLOG(ML_ERROR, "Couldn't require certificate")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't require certificate"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
535 return false;
536 }
537 }
538
539 SSLVersionRange version_range = {static_cast<PRUint16>(minVersion_),
540 static_cast<PRUint16>(maxVersion_)};
541
542 rv = SSL_VersionRangeSet(ssl_fd.get(), &version_range);
543 if (rv != SECSuccess) {
544 MOZ_MTLOG(ML_ERROR, "Can't disable SSLv3")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Can't disable SSLv3"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
545 return false;
546 }
547
548 rv = SSL_OptionSet(ssl_fd.get(), SSL_ENABLE_SESSION_TICKETS18, PR_FALSE0);
549 if (rv != SECSuccess) {
550 MOZ_MTLOG(ML_ERROR, "Couldn't disable session tickets")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable session tickets"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
551 return false;
552 }
553
554 rv = SSL_OptionSet(ssl_fd.get(), SSL_NO_CACHE9, PR_TRUE1);
555 if (rv != SECSuccess) {
556 MOZ_MTLOG(ML_ERROR, "Couldn't disable session caching")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable session caching"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
557 return false;
558 }
559
560 rv = SSL_OptionSet(ssl_fd.get(), SSL_ENABLE_DEFLATE19, PR_FALSE0);
561 if (rv != SECSuccess) {
562 MOZ_MTLOG(ML_ERROR, "Couldn't disable deflate")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable deflate"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
563 return false;
564 }
565
566 rv = SSL_OptionSet(ssl_fd.get(), SSL_ENABLE_RENEGOTIATION20,
567 SSL_RENEGOTIATE_NEVER((PRBool)0));
568 if (rv != SECSuccess) {
569 MOZ_MTLOG(ML_ERROR, "Couldn't disable renegotiation")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable renegotiation"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
570 return false;
571 }
572
573 rv = SSL_OptionSet(ssl_fd.get(), SSL_ENABLE_FALSE_START22, PR_FALSE0);
574 if (rv != SECSuccess) {
575 MOZ_MTLOG(ML_ERROR, "Couldn't disable false start")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable false start"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
576 return false;
577 }
578
579 rv = SSL_OptionSet(ssl_fd.get(), SSL_NO_LOCKS17, PR_TRUE1);
580 if (rv != SECSuccess) {
581 MOZ_MTLOG(ML_ERROR, "Couldn't disable locks")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable locks"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
582 return false;
583 }
584
585 rv = SSL_OptionSet(ssl_fd.get(), SSL_REUSE_SERVER_ECDHE_KEY27, PR_FALSE0);
586 if (rv != SECSuccess) {
587 MOZ_MTLOG(ML_ERROR, "Couldn't disable ECDHE key reuse")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable ECDHE key reuse"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
588 return false;
589 }
590
591 if (!SetupCipherSuites(ssl_fd)) {
592 return false;
593 }
594
595 // If the version is DTLS1.3 and pq in enabled, we will indicate support for
596 // ML-KEM
597 bool enable_mlkem = maxVersion_ >= Version::DTLS_1_3 &&
598 StaticPrefs::media_webrtc_enable_pq_hybrid_kex();
599
600 bool send_mlkem = StaticPrefs::media_webrtc_send_mlkem_keyshare();
601
602 if (!enable_mlkem && send_mlkem) {
603 MOZ_MTLOG(ML_NOTICE,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "The PQ preferences are inconsistent. ML-KEM support will not be "
"advertised, nor will the ML-KEM key share be sent."; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
604 "The PQ preferences are inconsistent. ML-KEM support will not be "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "The PQ preferences are inconsistent. ML-KEM support will not be "
"advertised, nor will the ML-KEM key share be sent."; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
605 "advertised, nor will the ML-KEM key share be sent.")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "The PQ preferences are inconsistent. ML-KEM support will not be "
"advertised, nor will the ML-KEM key share be sent."; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
606 }
607
608 std::vector<SSLNamedGroup> namedGroups;
609
610 if (enable_mlkem && send_mlkem) {
611 // RFC 8446: client_shares: A list of offered KeyShareEntry values in
612 // descending order of client preference.
613 // {ssl_grp_kem_mlkem768x25519}, {ssl_grp_ec_curve2551} key shared to be
614 // sent ML-KEM has the highest preference, so it's sent first.
615 namedGroups = {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519,
616 ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
617 ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072};
618
619 if (SECSuccess != SSL_SendAdditionalKeyShares(ssl_fd.get(), 1)) {
620 MOZ_MTLOG(ML_ERROR, "Couldn't set up additional key shares")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set up additional key shares"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
621 return false;
622 }
623 }
624 // Else we don't send any additional key share
625 else if (enable_mlkem && !send_mlkem) {
626 // Here the order of the namedGroups is different than in the first if
627 // {ssl_grp_ec_curve25519} is first because it's the key share
628 // that will be sent by default
629 namedGroups = {ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519,
630 ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
631 ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072};
632 }
633 // ml_kem is disabled
634 // {ssl_grp_ec_curve25519} will be send as a default key_share
635 else {
636 namedGroups = {ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1,
637 ssl_grp_ec_secp384r1, ssl_grp_ffdhe_2048,
638 ssl_grp_ffdhe_3072};
639 }
640
641 rv = SSL_NamedGroupConfig(ssl_fd.get(), namedGroups.data(),
642 std::size(namedGroups));
643
644 if (rv != SECSuccess) {
645 MOZ_MTLOG(ML_ERROR, "Couldn't set named groups")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set named groups"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
646 return false;
647 }
648
649 // Certificate validation
650 rv = SSL_AuthCertificateHook(ssl_fd.get(), AuthCertificateHook,
651 reinterpret_cast<void*>(this));
652 if (rv != SECSuccess) {
653 MOZ_MTLOG(ML_ERROR, "Couldn't set certificate validation hook")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set certificate validation hook"; do {
const ::mozilla::LogModule* moz_real_module = getLogModule()
; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
654 return false;
655 }
656
657 if (!SetupAlpn(ssl_fd)) {
658 return false;
659 }
660
661 // Now start the handshake
662 rv = SSL_ResetHandshake(ssl_fd.get(), role_ == SERVER ? PR_TRUE1 : PR_FALSE0);
663 if (rv != SECSuccess) {
664 MOZ_MTLOG(ML_ERROR, "Couldn't reset handshake")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't reset handshake"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
665 return false;
666 }
667 ssl_fd_ = std::move(ssl_fd);
668
669 // Finally, get ready to receive data
670 downward_->SignalStateChange.connect(this, &TransportLayerDtls::StateChange);
671 downward_->SignalPacketReceived.connect(this,
672 &TransportLayerDtls::PacketReceived);
673
674 if (downward_->state() == TS_OPEN) {
675 TL_SET_STATE(TS_CONNECTING)SetState((TS_CONNECTING), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 675)
;
676 Handshake();
677 }
678
679 return true;
680}
681
682bool TransportLayerDtls::SetupAlpn(UniquePRFileDesc& ssl_fd) const {
683 if (alpn_allowed_.empty()) {
684 return true;
685 }
686
687 SECStatus rv = SSL_OptionSet(ssl_fd.get(), SSL_ENABLE_NPN25, PR_FALSE0);
688 if (rv != SECSuccess) {
689 MOZ_MTLOG(ML_ERROR, "Couldn't disable NPN")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't disable NPN"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
690 return false;
691 }
692
693 rv = SSL_OptionSet(ssl_fd.get(), SSL_ENABLE_ALPN26, PR_TRUE1);
694 if (rv != SECSuccess) {
695 MOZ_MTLOG(ML_ERROR, "Couldn't enable ALPN")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't enable ALPN"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
696 return false;
697 }
698
699 unsigned char buf[MAX_ALPN_LENGTH255];
700 size_t offset = 0;
701 for (const auto& tag : alpn_allowed_) {
702 if ((offset + 1 + tag.length()) >= sizeof(buf)) {
703 MOZ_MTLOG(ML_ERROR, "ALPN too long")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "ALPN too long"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
704 return false;
705 }
706 buf[offset++] = tag.length();
707 memcpy(buf + offset, tag.c_str(), tag.length());
708 offset += tag.length();
709 }
710 rv = SSL_SetNextProtoNego(ssl_fd.get(), buf, offset);
711 if (rv != SECSuccess) {
712 MOZ_MTLOG(ML_ERROR, "Couldn't set ALPN string")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set ALPN string"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
713 return false;
714 }
715 return true;
716}
717
718// Ciphers we need to enable. These are on by default in standard firefox
719// builds, but can be disabled with prefs and they aren't on in our unit tests
720// since that uses NSS default configuration.
721//
722// Only override prefs to comply with MUST statements in the security-arch
723// doc. Anything outside this list is governed by the usual combination of
724// policy and user preferences.
725static const uint32_t EnabledCiphers[] = {
726 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA2560xC02B,
727 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA0xC009};
728
729// Disable all NSS suites modes without PFS or with old and rusty
730// ciphersuites. Anything outside this list is governed by the usual
731// combination of policy and user preferences.
732static const uint32_t DisabledCiphers[] = {
733 // Bug 1310061: disable all SHA384 ciphers until fixed
734 TLS_AES_256_GCM_SHA3840x1302,
735 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA3840xC02C,
736 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA3840xC030,
737 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA3840xC024,
738 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA3840xC028,
739 TLS_DHE_RSA_WITH_AES_256_GCM_SHA3840x009F,
740 TLS_DHE_DSS_WITH_AES_256_GCM_SHA3840x00A3,
741
742 TLS_DHE_RSA_WITH_AES_128_CBC_SHA0x0033,
743 TLS_DHE_RSA_WITH_AES_256_CBC_SHA0x0039,
744
745 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA0xC008,
746 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA0xC012,
747 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA0xC007,
748 TLS_ECDHE_RSA_WITH_RC4_128_SHA0xC011,
749
750 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA0x0016,
751 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA0x0013,
752 TLS_DHE_DSS_WITH_RC4_128_SHA0x0066,
753
754 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA0xC004,
755 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA0xC00E,
756 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA0xC005,
757 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA0xC00F,
758 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA0xC003,
759 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA0xC00D,
760 TLS_ECDH_ECDSA_WITH_RC4_128_SHA0xC002,
761 TLS_ECDH_RSA_WITH_RC4_128_SHA0xC00C,
762
763 TLS_RSA_WITH_AES_128_GCM_SHA2560x009C,
764 TLS_RSA_WITH_AES_256_GCM_SHA3840x009D,
765 TLS_RSA_WITH_AES_128_CBC_SHA0x002F,
766 TLS_RSA_WITH_AES_128_CBC_SHA2560x003C,
767 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA0x0041,
768 TLS_RSA_WITH_AES_256_CBC_SHA0x0035,
769 TLS_RSA_WITH_AES_256_CBC_SHA2560x003D,
770 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA0x0084,
771 TLS_RSA_WITH_SEED_CBC_SHA0x0096,
772 TLS_RSA_WITH_3DES_EDE_CBC_SHA0x000a,
773 TLS_RSA_WITH_RC4_128_SHA0x0005,
774 TLS_RSA_WITH_RC4_128_MD50x0004,
775
776 TLS_DHE_RSA_WITH_DES_CBC_SHA0x0015,
777 TLS_DHE_DSS_WITH_DES_CBC_SHA0x0012,
778 TLS_RSA_WITH_DES_CBC_SHA0x0009,
779
780 TLS_ECDHE_ECDSA_WITH_NULL_SHA0xC006,
781 TLS_ECDHE_RSA_WITH_NULL_SHA0xC010,
782 TLS_ECDH_ECDSA_WITH_NULL_SHA0xC001,
783 TLS_ECDH_RSA_WITH_NULL_SHA0xC00B,
784 TLS_RSA_WITH_NULL_SHA0x0002,
785 TLS_RSA_WITH_NULL_SHA2560x003B,
786 TLS_RSA_WITH_NULL_MD50x0001,
787};
788
789bool TransportLayerDtls::SetupCipherSuites(UniquePRFileDesc& ssl_fd) {
790 SECStatus rv;
791
792 // Set the SRTP ciphers
793 if (!enabled_srtp_ciphers_.empty()) {
794 rv = SSL_InstallExtensionHooks(ssl_fd.get(), ssl_use_srtp_xtn,(SSL_GetExperimentalAPI("SSL_InstallExtensionHooks") ? ((SECStatus
(*) (PRFileDesc * _fd, PRUint16 _extension, SSLExtensionWriter
_writer, void *_writerArg, SSLExtensionHandler _handler, void
*_handlerArg))SSL_GetExperimentalAPI("SSL_InstallExtensionHooks"
))(ssl_fd.get(), ssl_use_srtp_xtn, TransportLayerDtls::WriteSrtpXtn
, this, TransportLayerDtls::HandleSrtpXtn, this) : SECFailure
)
795 TransportLayerDtls::WriteSrtpXtn, this,(SSL_GetExperimentalAPI("SSL_InstallExtensionHooks") ? ((SECStatus
(*) (PRFileDesc * _fd, PRUint16 _extension, SSLExtensionWriter
_writer, void *_writerArg, SSLExtensionHandler _handler, void
*_handlerArg))SSL_GetExperimentalAPI("SSL_InstallExtensionHooks"
))(ssl_fd.get(), ssl_use_srtp_xtn, TransportLayerDtls::WriteSrtpXtn
, this, TransportLayerDtls::HandleSrtpXtn, this) : SECFailure
)
796 TransportLayerDtls::HandleSrtpXtn, this)(SSL_GetExperimentalAPI("SSL_InstallExtensionHooks") ? ((SECStatus
(*) (PRFileDesc * _fd, PRUint16 _extension, SSLExtensionWriter
_writer, void *_writerArg, SSLExtensionHandler _handler, void
*_handlerArg))SSL_GetExperimentalAPI("SSL_InstallExtensionHooks"
))(ssl_fd.get(), ssl_use_srtp_xtn, TransportLayerDtls::WriteSrtpXtn
, this, TransportLayerDtls::HandleSrtpXtn, this) : SECFailure
)
;
797 if (rv != SECSuccess) {
798 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "unable to set SRTP extension handler")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "unable to set SRTP extension handler"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
799 return false;
800 }
801 }
802
803 rv = SSL_AlertSentCallback(ssl_fd.get(),
804 TransportLayerDtls::SentAlertCallback, this);
805 if (rv != SECSuccess) {
806 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Unable to register alert sent callback")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to register alert sent callback"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
807 }
808
809 rv = SSL_AlertReceivedCallback(
810 ssl_fd.get(), TransportLayerDtls::ReceivedAlertCallback, this);
811 if (rv != SECSuccess) {
812 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to register alert received callback"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
813 LAYER_INFO << "Unable to register alert received callback")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to register alert received callback"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
814 }
815
816 for (const auto& cipher : EnabledCiphers) {
817 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Enabling: " << cipher)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Enabling: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
;
818 rv = SSL_CipherPrefSet(ssl_fd.get(), cipher, PR_TRUE1);
819 if (rv != SECSuccess) {
820 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Unable to enable suite: " << cipher)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to enable suite: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
821 return false;
822 }
823 }
824
825 for (const auto& cipher : DisabledCiphers) {
826 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Disabling: " << cipher)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Disabling: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
;
827
828 PRBool enabled = false;
829 rv = SSL_CipherPrefGet(ssl_fd.get(), cipher, &enabled);
830 if (rv != SECSuccess) {
831 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Unable to check if suite is enabled: "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to check if suite is enabled: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
832 << cipher)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to check if suite is enabled: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
833 return false;
834 }
835 if (enabled) {
836 rv = SSL_CipherPrefSet(ssl_fd.get(), cipher, PR_FALSE0);
837 if (rv != SECSuccess) {
838 MOZ_MTLOG(ML_NOTICE,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to disable suite: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
839 LAYER_INFO << "Unable to disable suite: " << cipher)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Unable to disable suite: "
<< cipher; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
840 return false;
841 }
842 }
843 }
844
845 return true;
846}
847
848nsresult TransportLayerDtls::GetChannelInfo(SSLChannelInfo* info) const {
849 CheckThread();
850 if (state_ != TS_OPEN) {
851 return NS_ERROR_NOT_AVAILABLE;
852 }
853 if (SSL_GetChannelInfo(ssl_fd_.get(), info, sizeof(*info)) != SECSuccess) {
854 return NS_ERROR_FAILURE;
855 }
856 return NS_OK;
857}
858
859nsTArray<nsTArray<uint8_t>> TransportLayerDtls::GetPeerCertChainDer() const {
860 CheckThread();
861 nsTArray<nsTArray<uint8_t>> result;
862 UniqueSECItemArray chain;
863 if (SSL_PeerCertificateChainDER(ssl_fd_.get(), TempPtrToSetter(&chain))(SSL_GetExperimentalAPI("SSL_PeerCertificateChainDER") ? ((SECStatus
(*) (PRFileDesc * _fd, SECItemArray * *_out))SSL_GetExperimentalAPI
("SSL_PeerCertificateChainDER"))(ssl_fd_.get(), TempPtrToSetter
(&chain)) : SECFailure)
!=
864 SECSuccess) {
865 MOZ_MTLOG(ML_NOTICE,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "SSL_PeerCertificateChainDER returned no certs"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
866 LAYER_INFO << "SSL_PeerCertificateChainDER returned no certs")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "SSL_PeerCertificateChainDER returned no certs"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
867 return result;
868 }
869 for (unsigned int i = 0; i < chain->len; ++i) {
870 const SECItem& der = chain->items[i];
871 nsTArray<uint8_t> bytes;
872 bytes.AppendElements(der.data, der.len);
873 result.AppendElement(std::move(bytes));
874 }
875 return result;
876}
877
878nsTArray<uint8_t> TransportLayerDtls::GetLocalCertDer() const {
879 CheckThread();
880 nsTArray<uint8_t> result;
881 if (!identity_) {
882 return result;
883 }
884 const UniqueCERTCertificate& cert = identity_->cert();
885 if (!cert) {
886 return result;
887 }
888 const SECItem& der = cert->derCert;
889 result.AppendElements(der.data, der.len);
890 return result;
891}
892
893nsresult TransportLayerDtls::GetCipherSuite(uint16_t* cipherSuite) const {
894 if (!cipherSuite) {
895 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "GetCipherSuite passed a nullptr")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "GetCipherSuite passed a nullptr"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
896 return NS_ERROR_NULL_POINTER;
897 }
898 SSLChannelInfo info;
899 nsresult rv = GetChannelInfo(&info);
900 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
901 if (rv == NS_ERROR_FAILURE) {
902 MOZ_MTLOG(ML_NOTICE,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "GetCipherSuite can't get channel info"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
903 LAYER_INFO << "GetCipherSuite can't get channel info")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "GetCipherSuite can't get channel info"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
904 }
905 return rv;
906 }
907 *cipherSuite = info.cipherSuite;
908 return NS_OK;
909}
910
911std::vector<uint16_t> TransportLayerDtls::GetDefaultSrtpCiphers() {
912 std::vector<uint16_t> ciphers;
913
914 ciphers.push_back(kDtlsSrtpAeadAes128Gcm);
915 // Since we don't support DTLS 1.3 or SHA384 ciphers (see bug 1312976)
916 // we don't really enough entropy to prefer this over 128 bit
917 ciphers.push_back(kDtlsSrtpAeadAes256Gcm);
918 ciphers.push_back(kDtlsSrtpAes128CmHmacSha1_80);
919#ifndef NIGHTLY_BUILD1
920 // To support bug 1491583 lets try to find out if we get bug reports if we
921 // no longer offer this in Nightly builds.
922 ciphers.push_back(kDtlsSrtpAes128CmHmacSha1_32);
923#endif
924
925 return ciphers;
926}
927
928const char* TransportLayerDtls::GetSrtpCipherName(uint16_t cipher) {
929 switch (cipher) {
930 case kDtlsSrtpAes128CmHmacSha1_80:
931 return "SRTP_AES128_CM_HMAC_SHA1_80";
932 case kDtlsSrtpAes128CmHmacSha1_32:
933 return "SRTP_AES128_CM_HMAC_SHA1_32";
934 case kDtlsSrtpAeadAes128Gcm:
935 return "SRTP_AEAD_AES_128_GCM";
936 case kDtlsSrtpAeadAes256Gcm:
937 return "SRTP_AEAD_AES_256_GCM";
938 }
939 return nullptr;
940}
941
942void TransportLayerDtls::StateChange(TransportLayer* layer, State state) {
943 switch (state) {
944 case TS_NONE:
945 MOZ_ASSERT(false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 945); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 945); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false)
; // Can't happen
946 break;
947
948 case TS_INIT:
949 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "State change of lower layer to INIT forbidden"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
950 LAYER_INFO << "State change of lower layer to INIT forbidden")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "State change of lower layer to INIT forbidden"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
951 mErrorDescription = "Internal Error";
952 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 952)
;
953 break;
954
955 case TS_CONNECTING:
956 MOZ_MTLOG(ML_INFO, LAYER_INFO << "Lower layer is connecting.")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Lower layer is connecting."
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
957 break;
958
959 case TS_OPEN:
960 if (timer_) {
961 MOZ_MTLOG(ML_INFO,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Lower layer is now open; starting TLS"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
962 LAYER_INFO << "Lower layer is now open; starting TLS")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Lower layer is now open; starting TLS"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
963 timer_->Cancel();
964 timer_->SetTarget(target_);
965 // Async, since the ICE layer might need to send a STUN response, and
966 // we don't want the handshake to start until that is sent.
967 timer_->InitWithNamedFuncCallback(
968 TimerCallback, this, 0, nsITimer::TYPE_ONE_SHOT,
969 "TransportLayerDtls::TimerCallback"_ns);
970 TL_SET_STATE(TS_CONNECTING)SetState((TS_CONNECTING), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 970)
;
971 } else {
972 // We have already completed DTLS. Can happen if the ICE layer failed
973 // due to a loss of network, and then recovered.
974 TL_SET_STATE(TS_OPEN)SetState((TS_OPEN), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 974)
;
975 }
976 break;
977
978 case TS_CLOSED:
979 MOZ_MTLOG(ML_INFO, LAYER_INFO << "Lower layer is now closed")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Lower layer is now closed"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
980 TL_SET_STATE(TS_CLOSED)SetState((TS_CLOSED), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 980)
;
981 break;
982
983 case TS_ERROR:
984 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Lower layer experienced an error")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Lower layer experienced an error"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
985 mErrorDescription = "ICE encountered an error";
986 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 986)
;
987 break;
988 }
989}
990
991void TransportLayerDtls::Handshake() {
992 if (!timer_) {
993 // We are done with DTLS, regardless of the state changes of lower layers
994 return;
995 }
996
997 if (!handshakeTelemetryRecorded) {
998 RecordStartedHandshakeTelemetry();
999 handshakeTelemetryRecorded = true;
1000 }
1001
1002 // Clear the retransmit timer
1003 timer_->Cancel();
1004
1005 MOZ_ASSERT(state_ == TS_CONNECTING)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state_ == TS_CONNECTING)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state_ == TS_CONNECTING))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("state_ == TS_CONNECTING"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1005); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state_ == TS_CONNECTING"
")"); do { MOZ_CrashSequence(__null, 1005); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1006
1007 SECStatus rv = SSL_ForceHandshake(ssl_fd_.get());
1008
1009 if (rv == SECSuccess) {
1010 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "****** SSL handshake completed ******")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "****** SSL handshake completed ******"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1011 if (!cert_ok_) {
1012 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Certificate check never occurred")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Certificate check never occurred"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1013 RecordHandshakeCompletionTelemetry("CERT_FAILURE");
1014 mErrorDescription = "Internal error";
1015 mHasDtlsFailureError = true;
1016 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1016)
;
1017 return;
1018 }
1019 if (!CheckAlpn()) {
1020 // Despite connecting, the connection doesn't have a valid ALPN label.
1021 // Forcibly close the connection so that the peer isn't left hanging
1022 // (assuming the close_notify isn't dropped).
1023 ssl_fd_ = nullptr;
1024 RecordHandshakeCompletionTelemetry("ALPN_FAILURE");
1025 // CheckAlpn sets mErrorDescription
1026 mHasDtlsFailureError = true;
1027 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1027)
;
1028 return;
1029 }
1030
1031 RecordHandshakeCompletionTelemetry("SUCCESS");
1032 TL_SET_STATE(TS_OPEN)SetState((TS_OPEN), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1032)
;
1033
1034 RecordTlsTelemetry();
1035 timer_ = nullptr;
1036 } else {
1037 int32_t err = PR_GetError();
1038 switch (err) {
1039 case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
1040 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Malformed DTLS message; ignoring"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1041 // If this were TLS (and not DTLS), this would be fatal, but
1042 // here we're required to ignore bad messages, so fall through
1043 [[fallthrough]];
1044 case PR_WOULD_BLOCK_ERROR(-5998L):
1045 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Handshake would have blocked")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Handshake would have blocked"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1046 PRIntervalTime timeout;
1047 rv = DTLS_GetHandshakeTimeout(ssl_fd_.get(), &timeout);
1048 if (rv == SECSuccess) {
1049 uint32_t timeout_ms = PR_IntervalToMilliseconds(timeout);
1050
1051 MOZ_MTLOG(ML_DEBUG,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Setting DTLS timeout to "
<< timeout_ms; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
1052 LAYER_INFO << "Setting DTLS timeout to " << timeout_ms)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Setting DTLS timeout to "
<< timeout_ms; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
;
1053 timer_->SetTarget(target_);
1054 timer_->InitWithNamedFuncCallback(
1055 TimerCallback, this, timeout_ms, nsITimer::TYPE_ONE_SHOT,
1056 "TransportLayerDtls::TimerCallback"_ns);
1057 }
1058 break;
1059 default:
1060 const char* err_msg = PR_ErrorToName(err);
1061 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "DTLS handshake error " << err << " ("do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "DTLS handshake error "
<< err << " (" << err_msg << ")"; do
{ const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
1062 << err_msg << ")")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "DTLS handshake error "
<< err << " (" << err_msg << ")"; do
{ const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1063 RecordHandshakeCompletionTelemetry(err_msg);
1064 mErrorDescription = "DTLS handshake failure";
1065 mHasDtlsFailureError = true;
1066 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1066)
;
1067 break;
1068 }
1069 }
1070}
1071
1072// Checks if ALPN was negotiated correctly and returns false if it wasn't.
1073// After this returns successfully, alpn_ will be set to the negotiated
1074// protocol.
1075bool TransportLayerDtls::CheckAlpn() {
1076 if (alpn_allowed_.empty()) {
1077 return true;
1078 }
1079
1080 SSLNextProtoState alpnState;
1081 char chosenAlpn[MAX_ALPN_LENGTH255];
1082 unsigned int chosenAlpnLen;
1083 SECStatus rv = SSL_GetNextProto(ssl_fd_.get(), &alpnState,
1084 reinterpret_cast<unsigned char*>(chosenAlpn),
1085 &chosenAlpnLen, sizeof(chosenAlpn));
1086 if (rv != SECSuccess) {
1087 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "ALPN error")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "ALPN error"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1088 mErrorDescription = "Internal error";
1089 return false;
1090 }
1091 switch (alpnState) {
1092 case SSL_NEXT_PROTO_SELECTED:
1093 case SSL_NEXT_PROTO_NEGOTIATED:
1094 break; // OK
1095
1096 case SSL_NEXT_PROTO_NO_SUPPORT:
1097 MOZ_MTLOG(ML_NOTICE,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "ALPN not negotiated, "
<< (alpn_default_.empty() ? "failing" : "selecting default"
); do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
1098 LAYER_INFO << "ALPN not negotiated, "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "ALPN not negotiated, "
<< (alpn_default_.empty() ? "failing" : "selecting default"
); do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
1099 << (alpn_default_.empty() ? "failing"do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "ALPN not negotiated, "
<< (alpn_default_.empty() ? "failing" : "selecting default"
); do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
1100 : "selecting default"))do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "ALPN not negotiated, "
<< (alpn_default_.empty() ? "failing" : "selecting default"
); do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1101 alpn_ = alpn_default_;
1102 if (alpn_.empty()) {
1103 mErrorDescription = "No ALPN";
1104 }
1105 return !alpn_.empty();
1106
1107 case SSL_NEXT_PROTO_NO_OVERLAP:
1108 // This only happens if there is a custom NPN/ALPN callback installed
1109 // and that callback doesn't properly handle ALPN.
1110 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "error in ALPN selection callback")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "error in ALPN selection callback"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1111 mErrorDescription = "Internal error";
1112 return false;
1113
1114 case SSL_NEXT_PROTO_EARLY_VALUE:
1115 MOZ_CRASH("Unexpected 0-RTT ALPN value")do { do { } while (false); MOZ_ReportCrash("" "Unexpected 0-RTT ALPN value"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1115); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected 0-RTT ALPN value"
")"); do { MOZ_CrashSequence(__null, 1115); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1116 mErrorDescription = "Internal error";
1117 return false;
1118 }
1119
1120 // Warning: NSS won't null terminate the ALPN string for us.
1121 std::string chosen(chosenAlpn, chosenAlpnLen);
1122 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Selected ALPN string: " << chosen)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Selected ALPN string: "
<< chosen; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
1123 if (alpn_allowed_.find(chosen) == alpn_allowed_.end()) {
1124 // Maybe our peer chose a protocol we didn't offer (when we are client),
1125 // or something is seriously wrong.
1126 std::ostringstream ss;
1127 for (auto i = alpn_allowed_.begin(); i != alpn_allowed_.end(); ++i) {
1128 ss << (i == alpn_allowed_.begin() ? " '" : ", '") << *i << "'";
1129 }
1130 MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Bad ALPN string: '" << chosendo { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Bad ALPN string: '"
<< chosen << "'; permitted:" << ss.str(); do
{ const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
1131 << "'; permitted:" << ss.str())do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Bad ALPN string: '"
<< chosen << "'; permitted:" << ss.str(); do
{ const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1132 mErrorDescription = fmt::format("Invalid ALPN: {}", chosen);
1133 return false;
1134 }
1135 alpn_ = std::move(chosen);
1136 return true;
1137}
1138
1139void TransportLayerDtls::PacketReceived(TransportLayer* layer,
1140 MediaPacket& packet) {
1141 CheckThread();
1142 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "PacketReceived(" << packet.len() << ")")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "PacketReceived("
<< packet.len() << ")"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1143
1144 if (state_ != TS_CONNECTING && state_ != TS_OPEN) {
1145 MOZ_MTLOG(ML_DEBUG,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Discarding packet in inappropriate state"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Verbose)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Verbose, "{}", str.str()
.c_str()); } } while (0); } } while (0)
1146 LAYER_INFO << "Discarding packet in inappropriate state")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Discarding packet in inappropriate state"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Verbose)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Verbose, "{}", str.str()
.c_str()); } } while (0); } } while (0)
;
1147 return;
1148 }
1149
1150 if (!packet.data()) {
1151 // Something ate this, probably the SRTP layer
1152 return;
1153 }
1154
1155 if (packet.type() != MediaPacket::DTLS) {
1156 return;
1157 }
1158
1159 nspr_io_adapter_->PacketReceived(packet);
1160 GetDecryptedPackets();
1161}
1162
1163void TransportLayerDtls::GetDecryptedPackets() {
1164 // If we're still connecting, try to handshake
1165 if (state_ == TS_CONNECTING) {
1166 Handshake();
1167 }
1168
1169 // Now try a recv if we're open, since there might be data left
1170 if (state_ == TS_OPEN) {
1171 int32_t rv;
1172 // One packet might contain several DTLS packets
1173 do {
1174 // nICEr uses a 9216 bytes buffer to allow support for jumbo frames
1175 // Can we peek to get a better idea of the actual size?
1176 static const size_t kBufferSize = 9216;
1177 auto buffer = MakeUnique<uint8_t[]>(kBufferSize);
1178 rv = PR_Recv(ssl_fd_.get(), buffer.get(), kBufferSize, 0,
1179 PR_INTERVAL_NO_WAIT0UL);
1180 if (rv > 0) {
1181 // We have data
1182 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read " << rv << " bytes from NSS")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Read " <<
rv << " bytes from NSS"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1183 MediaPacket packet;
1184 packet.SetType(MediaPacket::SCTP);
1185 packet.Take(std::move(buffer), static_cast<size_t>(rv));
1186 SignalPacketReceived(this, packet);
1187 } else if (rv == 0) {
1188 TL_SET_STATE(TS_CLOSED)SetState((TS_CLOSED), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1188)
;
1189 } else {
1190 int32_t err = PR_GetError();
1191
1192 if (err == PR_WOULD_BLOCK_ERROR(-5998L)) {
1193 // This gets ignored
1194 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Receive would have blocked")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Receive would have blocked"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Verbose)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Verbose, "{}", str.str()
.c_str()); } } while (0); } } while (0)
;
1195 } else {
1196 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "NSS Error " << err)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "NSS Error "
<< err; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
1197 mErrorDescription = "DTLS receive failed";
1198 mHasDtlsFailureError = true;
1199 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1199)
;
1200 }
1201 }
1202 } while (rv > 0);
1203 }
1204}
1205
1206void TransportLayerDtls::SetState(State state, const char* file,
1207 unsigned line) {
1208 if (timer_) {
1209 switch (state) {
1210 case TS_NONE:
1211 case TS_INIT:
1212 MOZ_ASSERT(false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1212); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")")
; do { MOZ_CrashSequence(__null, 1212); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1213 break;
1214 case TS_CONNECTING:
1215 break;
1216 case TS_OPEN:
1217 case TS_CLOSED:
1218 case TS_ERROR:
1219 timer_->Cancel();
1220 break;
1221 }
1222 }
1223
1224 TransportLayer::SetState(state, file, line);
1225}
1226
1227TransportResult TransportLayerDtls::SendPacket(MediaPacket& packet) {
1228 CheckThread();
1229 if (state_ != TS_OPEN) {
1230 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Can't call SendPacket() in state "
<< state_; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
1231 LAYER_INFO << "Can't call SendPacket() in state " << state_)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Can't call SendPacket() in state "
<< state_; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
1232 return TE_ERROR;
1233 }
1234
1235 int32_t rv = PR_Send(ssl_fd_.get(), packet.data(), packet.len(), 0,
1236 PR_INTERVAL_NO_WAIT0UL);
1237
1238 if (rv > 0) {
1239 // We have data
1240 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Wrote " << rv << " bytes to SSL Layer")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Wrote " <<
rv << " bytes to SSL Layer"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1241 return rv;
1242 }
1243
1244 if (rv == 0) {
1245 TL_SET_STATE(TS_CLOSED)SetState((TS_CLOSED), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1245)
;
1246 return 0;
1247 }
1248
1249 int32_t err = PR_GetError();
1250
1251 if (err == PR_WOULD_BLOCK_ERROR(-5998L)) {
1252 // This gets ignored
1253 MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Send would have blocked")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Send would have blocked"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Verbose)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Verbose, "{}", str.str()
.c_str()); } } while (0); } } while (0)
;
1254 return TE_WOULDBLOCK;
1255 }
1256
1257 MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "NSS Error " << err)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "NSS Error "
<< err; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Info)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Info
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
1258 mErrorDescription = "DTLS send failed";
1259 mHasDtlsFailureError = true;
1260 TL_SET_STATE(TS_ERROR)SetState((TS_ERROR), "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1260)
;
1261 return TE_ERROR;
1262}
1263
1264SECStatus TransportLayerDtls::GetClientAuthDataHook(
1265 void* arg, PRFileDesc* fd, CERTDistNames* caNames,
1266 CERTCertificate** pRetCert, SECKEYPrivateKey** pRetKey) {
1267 MOZ_MTLOG(ML_DEBUG, "Server requested client auth")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Server requested client auth"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1268
1269 TransportLayerDtls* stream = reinterpret_cast<TransportLayerDtls*>(arg);
1270 stream->CheckThread();
1271
1272 if (!stream->identity_) {
1273 MOZ_MTLOG(ML_ERROR, "No identity available")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "No identity available"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1274 PR_SetError(SSL_ERROR_NO_CERTIFICATE, 0);
1275 return SECFailure;
1276 }
1277
1278 *pRetCert = CERT_DupCertificate(stream->identity_->cert().get());
1279 if (!*pRetCert) {
1280 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
1281 return SECFailure;
1282 }
1283
1284 *pRetKey = SECKEY_CopyPrivateKey(stream->identity_->privkey().get());
1285 if (!*pRetKey) {
1286 CERT_DestroyCertificate(*pRetCert);
1287 *pRetCert = nullptr;
1288 PR_SetError(PR_OUT_OF_MEMORY_ERROR(-6000L), 0);
1289 return SECFailure;
1290 }
1291
1292 return SECSuccess;
1293}
1294
1295nsresult TransportLayerDtls::SetSrtpCiphers(
1296 const std::vector<uint16_t>& ciphers) {
1297 enabled_srtp_ciphers_ = std::move(ciphers);
1298 return NS_OK;
1299}
1300
1301nsresult TransportLayerDtls::GetSrtpCipher(uint16_t* cipher) const {
1302 CheckThread();
1303 if (srtp_cipher_ == 0) {
1304 return NS_ERROR_NOT_AVAILABLE;
1305 }
1306 *cipher = srtp_cipher_;
1307 return NS_OK;
1308}
1309
1310static uint8_t* WriteUint16(uint8_t* cursor, uint16_t v) {
1311 *cursor++ = v >> 8;
1312 *cursor++ = v & 0xff;
1313 return cursor;
1314}
1315
1316static SSLHandshakeType SrtpXtnServerMessage(PRFileDesc* fd) {
1317 SSLPreliminaryChannelInfo preinfo;
1318 SECStatus rv = SSL_GetPreliminaryChannelInfo(fd, &preinfo, sizeof(preinfo));
1319 if (rv != SECSuccess) {
1320 MOZ_ASSERT(false, "Can't get version info")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Can't get version info"
")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Can't get version info" ")"); do { MOZ_CrashSequence(__null
, 1320); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
1321 return ssl_hs_client_hello;
1322 }
1323 return (preinfo.protocolVersion >= SSL_LIBRARY_VERSION_TLS_1_30x0304)
1324 ? ssl_hs_encrypted_extensions
1325 : ssl_hs_server_hello;
1326}
1327
1328/* static */
1329PRBool TransportLayerDtls::WriteSrtpXtn(PRFileDesc* fd,
1330 SSLHandshakeType message, uint8_t* data,
1331 unsigned int* len, unsigned int max_len,
1332 void* arg) {
1333 auto self = reinterpret_cast<TransportLayerDtls*>(arg);
1334
1335 // ClientHello: send all supported versions.
1336 if (message == ssl_hs_client_hello) {
1337 MOZ_ASSERT(self->role_ == CLIENT)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->role_ == CLIENT)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->role_ == CLIENT))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("self->role_ == CLIENT"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1337); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->role_ == CLIENT"
")"); do { MOZ_CrashSequence(__null, 1337); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1338 MOZ_ASSERT(self->enabled_srtp_ciphers_.size(), "Haven't enabled SRTP")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->enabled_srtp_ciphers_.size())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(self->enabled_srtp_ciphers_.size()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("self->enabled_srtp_ciphers_.size()"
" (" "Haven't enabled SRTP" ")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1338); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->enabled_srtp_ciphers_.size()"
") (" "Haven't enabled SRTP" ")"); do { MOZ_CrashSequence(__null
, 1338); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
1339 // We will take 2 octets for each cipher, plus a 2 octet length and 1
1340 // octet for the length of the empty MKI.
1341 if (max_len < self->enabled_srtp_ciphers_.size() * 2 + 3) {
1342 MOZ_ASSERT(false, "Not enough space to send SRTP extension")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Not enough space to send SRTP extension"
")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1342); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Not enough space to send SRTP extension" ")"); do { MOZ_CrashSequence
(__null, 1342); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1343 return false;
1344 }
1345 uint8_t* cursor = WriteUint16(data, self->enabled_srtp_ciphers_.size() * 2);
1346 for (auto cs : self->enabled_srtp_ciphers_) {
1347 cursor = WriteUint16(cursor, cs);
1348 }
1349 *cursor++ = 0; // MKI is empty
1350 *len = cursor - data;
1351 return true;
1352 }
1353
1354 if (message == SrtpXtnServerMessage(fd)) {
1355 MOZ_ASSERT(self->role_ == SERVER)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->role_ == SERVER)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->role_ == SERVER))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("self->role_ == SERVER"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1355); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->role_ == SERVER"
")"); do { MOZ_CrashSequence(__null, 1355); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1356 if (!self->srtp_cipher_) {
1357 // Not negotiated. Definitely bad, but the connection can fail later.
1358 return false;
1359 }
1360 if (max_len < 5) {
1361 MOZ_ASSERT(false, "Not enough space to send SRTP extension")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Not enough space to send SRTP extension"
")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Not enough space to send SRTP extension" ")"); do { MOZ_CrashSequence
(__null, 1361); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1362 return false;
1363 }
1364
1365 uint8_t* cursor = WriteUint16(data, 2); // Length = 2.
1366 cursor = WriteUint16(cursor, self->srtp_cipher_);
1367 *cursor++ = 0; // No MKI
1368 *len = cursor - data;
1369 return true;
1370 }
1371
1372 return false;
1373}
1374
1375class TlsParser {
1376 public:
1377 TlsParser(const uint8_t* data, size_t len) : cursor_(data), remaining_(len) {}
1378
1379 bool error() const { return error_; }
1380 size_t remaining() const { return remaining_; }
1381
1382 template <typename T, class = std::enable_if_t<std::is_unsigned_v<T>>>
1383 void Read(T* v, size_t sz = sizeof(T)) {
1384 MOZ_ASSERT(sz <= sizeof(T),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sz <= sizeof(T))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sz <= sizeof(T)))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("sz <= sizeof(T)"
" (" "Type is too small to hold the value requested" ")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1385); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sz <= sizeof(T)"
") (" "Type is too small to hold the value requested" ")"); do
{ MOZ_CrashSequence(__null, 1385); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1385 "Type is too small to hold the value requested")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sz <= sizeof(T))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sz <= sizeof(T)))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("sz <= sizeof(T)"
" (" "Type is too small to hold the value requested" ")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1385); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sz <= sizeof(T)"
") (" "Type is too small to hold the value requested" ")"); do
{ MOZ_CrashSequence(__null, 1385); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1386 if (remaining_ < sz) {
1387 error_ = true;
1388 return;
1389 }
1390
1391 T result = 0;
1392 for (size_t i = 0; i < sz; ++i) {
1393 result = (result << 8) | *cursor_++;
1394 remaining_--;
1395 }
1396 *v = result;
1397 }
1398
1399 template <typename T, class = std::enable_if_t<std::is_unsigned_v<T>>>
1400 void ReadVector(std::vector<T>* v, size_t w) {
1401 MOZ_ASSERT(v->empty(), "vector needs to be empty")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(v->empty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(v->empty()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("v->empty()" " ("
"vector needs to be empty" ")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1401); AnnotateMozCrashReason("MOZ_ASSERT" "(" "v->empty()"
") (" "vector needs to be empty" ")"); do { MOZ_CrashSequence
(__null, 1401); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1402
1403 uint32_t len;
1404 Read(&len, w);
1405 if (error_ || len % sizeof(T) != 0 || len > remaining_) {
1406 error_ = true;
1407 return;
1408 }
1409
1410 size_t count = len / sizeof(T);
1411 v->reserve(count);
1412 for (T i = 0; !error_ && i < count; ++i) {
1413 T item;
1414 Read(&item);
1415 if (!error_) {
1416 v->push_back(item);
1417 }
1418 }
1419 }
1420
1421 void Skip(size_t n) {
1422 if (remaining_ < n) {
1423 error_ = true;
1424 } else {
1425 cursor_ += n;
1426 remaining_ -= n;
1427 }
1428 }
1429
1430 size_t SkipVector(size_t w) {
1431 uint32_t len = 0;
1432 Read(&len, w);
1433 Skip(len);
1434 return len;
1435 }
1436
1437 private:
1438 const uint8_t* cursor_;
1439 size_t remaining_;
1440 bool error_ = false;
1441};
1442
1443/* static */
1444SECStatus TransportLayerDtls::HandleSrtpXtn(
1445 PRFileDesc* fd, SSLHandshakeType message, const uint8_t* data,
1446 unsigned int len, SSLAlertDescription* alert, void* arg) {
1447 static const uint8_t kTlsAlertHandshakeFailure = 40;
1448 static const uint8_t kTlsAlertIllegalParameter = 47;
1449 static const uint8_t kTlsAlertDecodeError = 50;
1450 static const uint8_t kTlsAlertUnsupportedExtension = 110;
1451
1452 auto self = reinterpret_cast<TransportLayerDtls*>(arg);
1453
1454 // Parse the extension.
1455 TlsParser parser(data, len);
1456 std::vector<uint16_t> advertised;
1457 parser.ReadVector(&advertised, 2);
1458 size_t mki_len = parser.SkipVector(1);
1459 if (parser.error() || parser.remaining() > 0) {
1460 *alert = kTlsAlertDecodeError;
1461 return SECFailure;
1462 }
1463
1464 std::optional<uint16_t> preferred_common_cipher;
1465 for (auto supported : self->enabled_srtp_ciphers_) {
1466 auto it = std::find(advertised.begin(), advertised.end(), supported);
1467 if (it != advertised.end()) {
1468 preferred_common_cipher = supported;
1469 break;
1470 }
1471 }
1472
1473 if (message == ssl_hs_client_hello) {
1474 MOZ_ASSERT(self->role_ == SERVER)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->role_ == SERVER)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->role_ == SERVER))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("self->role_ == SERVER"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1474); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->role_ == SERVER"
")"); do { MOZ_CrashSequence(__null, 1474); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1475 if (!preferred_common_cipher.has_value()) {
1476 *alert = kTlsAlertHandshakeFailure;
1477 return SECFailure;
1478 }
1479 self->srtp_cipher_ = preferred_common_cipher.value();
1480 return SECSuccess;
1481 }
1482
1483 if (message == SrtpXtnServerMessage(fd)) {
1484 MOZ_ASSERT(self->role_ == CLIENT)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->role_ == CLIENT)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->role_ == CLIENT))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("self->role_ == CLIENT"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1484); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->role_ == CLIENT"
")"); do { MOZ_CrashSequence(__null, 1484); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1485 if (advertised.size() != 1 || mki_len > 0 ||
1486 !preferred_common_cipher.has_value()) {
1487 *alert = kTlsAlertIllegalParameter;
1488 return SECFailure;
1489 }
1490 self->srtp_cipher_ = preferred_common_cipher.value();
1491 return SECSuccess;
1492 }
1493
1494 *alert = kTlsAlertUnsupportedExtension;
1495 return SECFailure;
1496}
1497
1498static constexpr uint8_t kAlertFatal = 2;
1499
1500/* static */
1501void TransportLayerDtls::SentAlertCallback(const PRFileDesc* fd, void* arg,
1502 const SSLAlert* alert) {
1503 auto self = reinterpret_cast<TransportLayerDtls*>(arg);
1504 if (alert->level == kAlertFatal && !self->mSentAlert.isSome()) {
1505 self->mSentAlert = Some(alert->description);
1506 }
1507}
1508
1509/* static */
1510void TransportLayerDtls::ReceivedAlertCallback(const PRFileDesc* fd, void* arg,
1511 const SSLAlert* alert) {
1512 auto self = reinterpret_cast<TransportLayerDtls*>(arg);
1513 if (alert->level == kAlertFatal && !self->mReceivedAlert.isSome()) {
1514 self->mReceivedAlert = Some(alert->description);
1515 }
1516}
1517
1518nsresult TransportLayerDtls::ExportKeyingMaterial(const std::string& label,
1519 bool use_context,
1520 const std::string& context,
1521 unsigned char* out,
1522 unsigned int outlen) {
1523 CheckThread();
1524 if (state_ != TS_OPEN) {
1525 MOZ_ASSERT(false, "Transport must be open for ExportKeyingMaterial")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Transport must be open for ExportKeyingMaterial"
")", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1525); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Transport must be open for ExportKeyingMaterial" ")"); do {
MOZ_CrashSequence(__null, 1525); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1526 return NS_ERROR_NOT_AVAILABLE;
1527 }
1528 SECStatus rv = SSL_ExportKeyingMaterial(
1529 ssl_fd_.get(), label.c_str(), label.size(), use_context,
1530 reinterpret_cast<const unsigned char*>(context.c_str()), context.size(),
1531 out, outlen);
1532 if (rv != SECSuccess) {
1533 MOZ_MTLOG(ML_ERROR, "Couldn't export SSL keying material")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't export SSL keying material"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1534 return NS_ERROR_FAILURE;
1535 }
1536
1537 return NS_OK;
1538}
1539
1540SECStatus TransportLayerDtls::AuthCertificateHook(void* arg, PRFileDesc* fd,
1541 PRBool checksig,
1542 PRBool isServer) {
1543 TransportLayerDtls* stream = reinterpret_cast<TransportLayerDtls*>(arg);
1544 stream->CheckThread();
1545 return stream->AuthCertificateHook(fd, checksig, isServer);
1546}
1547
1548SECStatus TransportLayerDtls::CheckDigest(const DtlsDigest& digest,
1549 const SECItem& peer_cert_der) const {
1550 DtlsDigest computed_digest(digest.algorithm_);
1551
1552 MOZ_MTLOG(ML_DEBUG,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Checking digest, algorithm="
<< digest.algorithm_; do { const ::mozilla::LogModule*
moz_real_module = getLogModule(); if ((__builtin_expect(!!(mozilla
::detail::log_test(moz_real_module, mozilla::LogLevel::Verbose
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, mozilla
::LogLevel::Verbose, "{}", str.str().c_str()); } } while (0);
} } while (0)
1553 LAYER_INFO << "Checking digest, algorithm=" << digest.algorithm_)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "Checking digest, algorithm="
<< digest.algorithm_; do { const ::mozilla::LogModule*
moz_real_module = getLogModule(); if ((__builtin_expect(!!(mozilla
::detail::log_test(moz_real_module, mozilla::LogLevel::Verbose
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, mozilla
::LogLevel::Verbose, "{}", str.str().c_str()); } } while (0);
} } while (0)
;
1554 nsresult res = DtlsIdentity::ComputeFingerprint(
1555 peer_cert_der.data, peer_cert_der.len, &computed_digest);
1556 if (NS_FAILED(res)((bool)(__builtin_expect(!!(NS_FAILED_impl(res)), 0)))) {
1557 MOZ_MTLOG(ML_ERROR, "Could not compute peer fingerprint for digest "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Could not compute peer fingerprint for digest "
<< digest.algorithm_; do { const ::mozilla::LogModule*
moz_real_module = getLogModule(); if ((__builtin_expect(!!(mozilla
::detail::log_test(moz_real_module, mozilla::LogLevel::Error)
), 0))) { mozilla::detail::log_print_fmt(moz_real_module, mozilla
::LogLevel::Error, "{}", str.str().c_str()); } } while (0); }
} while (0)
1558 << digest.algorithm_)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Could not compute peer fingerprint for digest "
<< digest.algorithm_; do { const ::mozilla::LogModule*
moz_real_module = getLogModule(); if ((__builtin_expect(!!(mozilla
::detail::log_test(moz_real_module, mozilla::LogLevel::Error)
), 0))) { mozilla::detail::log_print_fmt(moz_real_module, mozilla
::LogLevel::Error, "{}", str.str().c_str()); } } while (0); }
} while (0)
;
1559 // Go to end
1560 PR_SetError(SSL_ERROR_BAD_CERTIFICATE, 0);
1561 return SECFailure;
1562 }
1563
1564 if (computed_digest != digest) {
1565 MOZ_MTLOG(ML_ERROR, "Digest does not match")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Digest does not match"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1566 PR_SetError(SSL_ERROR_BAD_CERTIFICATE, 0);
1567 return SECFailure;
1568 }
1569
1570 return SECSuccess;
1571}
1572
1573SECStatus TransportLayerDtls::AuthCertificateHook(PRFileDesc* fd,
1574 PRBool checksig,
1575 PRBool isServer) {
1576 CheckThread();
1577
1578 // We are not set up to take this being called multiple
1579 // times. Change this if we ever add renegotiation.
1580 MOZ_ASSERT(!auth_hook_called_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!auth_hook_called_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!auth_hook_called_))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!auth_hook_called_"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1580); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!auth_hook_called_"
")"); do { MOZ_CrashSequence(__null, 1580); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1581 if (auth_hook_called_) {
1582 PR_SetError(PR_UNKNOWN_ERROR(-5994L), 0);
1583 return SECFailure;
1584 }
1585 auth_hook_called_ = true;
1586
1587 MOZ_ASSERT(verification_mode_ != VERIFY_UNSET)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(verification_mode_ != VERIFY_UNSET)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(verification_mode_ != VERIFY_UNSET
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"verification_mode_ != VERIFY_UNSET", "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1587); AnnotateMozCrashReason("MOZ_ASSERT" "(" "verification_mode_ != VERIFY_UNSET"
")"); do { MOZ_CrashSequence(__null, 1587); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1588
1589 switch (verification_mode_) {
1590 case VERIFY_UNSET:
1591 // Break out to error exit
1592 PR_SetError(PR_UNKNOWN_ERROR(-5994L), 0);
1593 break;
1594
1595 case VERIFY_ALLOW_ALL:
1596 cert_ok_ = true;
1597 return SECSuccess;
1598
1599 case VERIFY_DIGEST: {
1600 MOZ_ASSERT(!digests_.empty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!digests_.empty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!digests_.empty()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!digests_.empty()"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1600); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!digests_.empty()"
")"); do { MOZ_CrashSequence(__null, 1600); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1601 UniqueSECItemArray peer_cert_chain;
1602 SECStatus rv =
1603 SSL_PeerCertificateChainDER(fd, TempPtrToSetter(&peer_cert_chain))(SSL_GetExperimentalAPI("SSL_PeerCertificateChainDER") ? ((SECStatus
(*) (PRFileDesc * _fd, SECItemArray * *_out))SSL_GetExperimentalAPI
("SSL_PeerCertificateChainDER"))(fd, TempPtrToSetter(&peer_cert_chain
)) : SECFailure)
;
1604 if (rv != SECSuccess || peer_cert_chain->len == 0) {
1605 PR_SetError(SSL_ERROR_BAD_CERTIFICATE, 0);
1606 break;
1607 }
1608
1609 // Check all the provided digests
1610
1611 // Checking functions call PR_SetError()
1612 rv = SECFailure;
Value stored to 'rv' is never read
1613 for (const auto& digest : digests_) {
1614 rv = CheckDigest(digest, peer_cert_chain->items[0]);
1615
1616 // Matches a digest, we are good to go
1617 if (rv == SECSuccess) {
1618 cert_ok_ = true;
1619 return SECSuccess;
1620 }
1621 }
1622 } break;
1623 default:
1624 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1624); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { MOZ_CrashSequence
(__null, 1624); __attribute__((nomerge)) ::abort(); } while (
false); } while (false)
; // Can't happen
1625 }
1626
1627 mHasFingerprintError = true;
1628 return SECFailure;
1629}
1630
1631void TransportLayerDtls::TimerCallback(nsITimer* timer, void* arg) {
1632 TransportLayerDtls* dtls = reinterpret_cast<TransportLayerDtls*>(arg);
1633
1634 MOZ_MTLOG(ML_DEBUG, "DTLS timer expired")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "DTLS timer expired"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1635
1636 dtls->Handshake();
1637}
1638
1639void TransportLayerDtls::RecordHandshakeCompletionTelemetry(
1640 const char* aResult) {
1641 if (role_ == CLIENT) {
1642 mozilla::glean::webrtcdtls::client_handshake_result.Get(nsCString(aResult))
1643 .Add(1);
1644 } else {
1645 mozilla::glean::webrtcdtls::server_handshake_result.Get(nsCString(aResult))
1646 .Add(1);
1647 }
1648}
1649
1650void TransportLayerDtls::RecordStartedHandshakeTelemetry() {
1651 if (role_ == CLIENT) {
1652 mozilla::glean::webrtcdtls::client_handshake_started_counter.Add(1);
1653 } else {
1654 mozilla::glean::webrtcdtls::server_handshake_started_counter.Add(1);
1655 }
1656}
1657
1658void TransportLayerDtls::RecordTlsTelemetry() {
1659 MOZ_ASSERT(state_ == TS_OPEN)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(state_ == TS_OPEN)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(state_ == TS_OPEN))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("state_ == TS_OPEN"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1659); AnnotateMozCrashReason("MOZ_ASSERT" "(" "state_ == TS_OPEN"
")"); do { MOZ_CrashSequence(__null, 1659); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1660 SSLChannelInfo info;
1661 nsresult rv = GetChannelInfo(&info);
1662 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1663 if (rv == NS_ERROR_FAILURE) {
1664 MOZ_MTLOG(ML_NOTICE,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "RecordTlsTelemetry failed to get channel info"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
1665 LAYER_INFO << "RecordTlsTelemetry failed to get channel info")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "Flow[" << flow_id() << "(none)" <<
"]; Layer[" << id() << "]: " << "RecordTlsTelemetry failed to get channel info"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1666 }
1667 return;
1668 }
1669
1670 switch (info.protocolVersion) {
1671 case SSL_LIBRARY_VERSION_TLS_1_10x0302:
1672 mozilla::glean::webrtcdtls::protocol_version.Get("1.0"_ns).Add(1);
1673 break;
1674 case SSL_LIBRARY_VERSION_TLS_1_20x0303:
1675 mozilla::glean::webrtcdtls::protocol_version.Get("1.2"_ns).Add(1);
1676 break;
1677 case SSL_LIBRARY_VERSION_TLS_1_30x0304:
1678 mozilla::glean::webrtcdtls::protocol_version.Get("1.3"_ns).Add(1);
1679 break;
1680 default:
1681 MOZ_CRASH("Unknown SSL version")do { do { } while (false); MOZ_ReportCrash("" "Unknown SSL version"
, "/root/firefox-clang/dom/media/webrtc/transport/transportlayerdtls.cpp"
, 1681); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown SSL version"
")"); do { MOZ_CrashSequence(__null, 1681); __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1682 }
1683
1684 {
1685 std::ostringstream oss;
1686 // Record TLS cipher-suite ID as a string (eg;
1687 // TLS_DHE_RSA_WITH_AES_128_CBC_SHA is 0x0033)
1688 oss << "0x" << std::setfill('0') << std::setw(4) << std::hex
1689 << info.cipherSuite;
1690 mozilla::glean::webrtcdtls::cipher.Get(nsCString(oss.str().c_str())).Add(1);
1691 MOZ_MTLOG(ML_DEBUG, "cipher: " << oss.str())do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "cipher: " << oss.str(); do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1692 }
1693
1694 // Record Key Exchange Algorithm Type
1695 // keyExchange null=0, rsa=1, dh=2, ecdh=4, ecdh_hybrid=8
1696 mozilla::glean::webrtcdtls::key_exchange_algorithm.AccumulateSingleSample(
1697 info.keaType);
1698
1699 uint16_t cipher;
1700 rv = GetSrtpCipher(&cipher);
1701
1702 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1703 MOZ_MTLOG(ML_DEBUG, "No SRTP cipher suite")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "No SRTP cipher suite"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1704 return;
1705 }
1706
1707 {
1708 std::ostringstream oss;
1709 // Record SRTP cipher-suite ID as a string (eg;
1710 // SRTP_AES128_CM_HMAC_SHA1_80 is 0x0001)
1711 oss << "0x" << std::setfill('0') << std::setw(4) << std::hex << cipher;
1712 mozilla::glean::webrtcdtls::srtp_cipher.Get(nsCString(oss.str().c_str()))
1713 .Add(1);
1714 MOZ_MTLOG(ML_DEBUG, "srtp cipher: " << oss.str())do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "srtp cipher: " << oss.str(); do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Verbose)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Verbose, "{}", str.str()
.c_str()); } } while (0); } } while (0)
;
1715 }
1716}
1717
1718} // namespace mozilla