diff options
Diffstat (limited to 'netwerk/protocol/webtransport')
-rw-r--r-- | netwerk/protocol/webtransport/WebTransportSessionProxy.cpp | 80 | ||||
-rw-r--r-- | netwerk/protocol/webtransport/WebTransportSessionProxy.h | 6 | ||||
-rw-r--r-- | netwerk/protocol/webtransport/nsIWebTransport.idl | 9 |
3 files changed, 35 insertions, 60 deletions
diff --git a/netwerk/protocol/webtransport/WebTransportSessionProxy.cpp b/netwerk/protocol/webtransport/WebTransportSessionProxy.cpp index e650a74d5b..dd4ba7e7d0 100644 --- a/netwerk/protocol/webtransport/WebTransportSessionProxy.cpp +++ b/netwerk/protocol/webtransport/WebTransportSessionProxy.cpp @@ -27,7 +27,8 @@ namespace mozilla::net { LazyLogModule webTransportLog("nsWebTransport"); NS_IMPL_ISUPPORTS(WebTransportSessionProxy, WebTransportSessionEventListener, - nsIWebTransport, nsIRedirectResultListener, nsIStreamListener, + WebTransportConnectionSettings, nsIWebTransport, + nsIRedirectResultListener, nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor); WebTransportSessionProxy::WebTransportSessionProxy() @@ -63,17 +64,17 @@ WebTransportSessionProxy::~WebTransportSessionProxy() { //----------------------------------------------------------------------------- nsresult WebTransportSessionProxy::AsyncConnect( - nsIURI* aURI, + nsIURI* aURI, bool aDedicated, const nsTArray<RefPtr<nsIWebTransportHash>>& aServerCertHashes, nsIPrincipal* aPrincipal, uint32_t aSecurityFlags, WebTransportSessionEventListener* aListener) { - return AsyncConnectWithClient(aURI, std::move(aServerCertHashes), aPrincipal, - aSecurityFlags, aListener, + return AsyncConnectWithClient(aURI, aDedicated, std::move(aServerCertHashes), + aPrincipal, aSecurityFlags, aListener, Maybe<dom::ClientInfo>()); } nsresult WebTransportSessionProxy::AsyncConnectWithClient( - nsIURI* aURI, + nsIURI* aURI, bool aDedicated, const nsTArray<RefPtr<nsIWebTransportHash>>& aServerCertHashes, nsIPrincipal* aPrincipal, uint32_t aSecurityFlags, WebTransportSessionEventListener* aListener, @@ -126,7 +127,10 @@ nsresult WebTransportSessionProxy::AsyncConnectWithClient( return NS_ERROR_ABORT; } + mDedicatedConnection = aDedicated; + if (!aServerCertHashes.IsEmpty()) { + mServerCertHashes.Clear(); mServerCertHashes.AppendElements(aServerCertHashes); } @@ -235,6 +239,18 @@ WebTransportSessionProxy::CloseSession(uint32_t status, return NS_OK; } +NS_IMETHODIMP WebTransportSessionProxy::GetDedicated(bool* dedicated) { + *dedicated = mDedicatedConnection; + return NS_OK; +} + +NS_IMETHODIMP WebTransportSessionProxy::GetServerCertificateHashes( + nsTArray<RefPtr<nsIWebTransportHash>>& aServerCertHashes) { + aServerCertHashes.Clear(); + aServerCertHashes.AppendElements(mServerCertHashes); + return NS_OK; +} + void WebTransportSessionProxy::CloseSessionInternalLocked() { MutexAutoLock lock(mMutex); CloseSessionInternal(); @@ -573,8 +589,7 @@ WebTransportSessionProxy::OnStartRequest(nsIRequest* aRequest) { nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel); if (!httpChannel || NS_FAILED(httpChannel->GetResponseStatus(&status)) || - !(status >= 200 && status < 300) || - !CheckServerCertificateIfNeeded()) { + !(status >= 200 && status < 300)) { listener = mListener; mListener = nullptr; mChannel = nullptr; @@ -990,57 +1005,6 @@ void WebTransportSessionProxy::CallOnSessionClosed() { } } -bool WebTransportSessionProxy::CheckServerCertificateIfNeeded() { - if (mServerCertHashes.IsEmpty()) { - return true; - } - - nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel); - MOZ_ASSERT(httpChannel, "Not a http channel ?"); - nsCOMPtr<nsITransportSecurityInfo> tsi; - httpChannel->GetSecurityInfo(getter_AddRefs(tsi)); - MOZ_ASSERT(tsi, - "We shouln't reach this code before setting the security info."); - nsCOMPtr<nsIX509Cert> cert; - nsresult rv = tsi->GetServerCert(getter_AddRefs(cert)); - if (!cert || NS_WARN_IF(NS_FAILED(rv))) return true; - nsTArray<uint8_t> certDER; - if (NS_FAILED(cert->GetRawDER(certDER))) { - return false; - } - // https://w3c.github.io/webtransport/#compute-a-certificate-hash - nsTArray<uint8_t> certHash; - if (NS_FAILED(Digest::DigestBuf(SEC_OID_SHA256, certDER.Elements(), - certDER.Length(), certHash)) || - certHash.Length() != SHA256_LENGTH) { - return false; - } - auto verifyCertDer = [&certHash](const auto& hash) { - return certHash.Length() == hash.Length() && - memcmp(certHash.Elements(), hash.Elements(), certHash.Length()) == 0; - }; - - // https://w3c.github.io/webtransport/#verify-a-certificate-hash - for (const auto& hash : mServerCertHashes) { - nsCString algorithm; - if (NS_FAILED(hash->GetAlgorithm(algorithm)) || algorithm != "sha-256") { - continue; - LOG(("Unexpected non-SHA-256 hash")); - } - - nsTArray<uint8_t> value; - if (NS_FAILED(hash->GetValue(value))) { - continue; - LOG(("Unexpected corrupted hash")); - } - - if (verifyCertDer(value)) { - return true; - } - } - return false; -} - void WebTransportSessionProxy::ChangeState( WebTransportSessionProxyState newState) { mMutex.AssertCurrentThreadOwns(); diff --git a/netwerk/protocol/webtransport/WebTransportSessionProxy.h b/netwerk/protocol/webtransport/WebTransportSessionProxy.h index aebb446e21..9e6f785d80 100644 --- a/netwerk/protocol/webtransport/WebTransportSessionProxy.h +++ b/netwerk/protocol/webtransport/WebTransportSessionProxy.h @@ -121,6 +121,7 @@ class WebTransportStreamCallbackWrapper; class WebTransportSessionProxy final : public nsIWebTransport, public WebTransportSessionEventListener, + public WebTransportConnectionSettings, public nsIStreamListener, public nsIChannelEventSink, public nsIRedirectResultListener, @@ -129,6 +130,7 @@ class WebTransportSessionProxy final : public nsIWebTransport, NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIWEBTRANSPORT NS_DECL_WEBTRANSPORTSESSIONEVENTLISTENER + NS_DECL_WEBTRANSPORTCONNECTIONSETTINGS NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER NS_DECL_NSICHANNELEVENTSINK @@ -170,11 +172,9 @@ class WebTransportSessionProxy final : public nsIWebTransport, void OnMaxDatagramSizeInternal(uint64_t aSize); void OnOutgoingDatagramOutComeInternal( uint64_t aId, WebTransportSessionEventListener::DatagramOutcome aOutCome); - bool CheckServerCertificateIfNeeded(); nsCOMPtr<nsIChannel> mChannel; nsCOMPtr<nsIChannel> mRedirectChannel; - nsTArray<RefPtr<nsIWebTransportHash>> mServerCertHashes; nsCOMPtr<WebTransportSessionEventListener> mListener MOZ_GUARDED_BY(mMutex); RefPtr<Http3WebTransportSession> mWebTransportSession MOZ_GUARDED_BY(mMutex); uint64_t mSessionId MOZ_GUARDED_BY(mMutex) = UINT64_MAX; @@ -188,6 +188,8 @@ class WebTransportSessionProxy final : public nsIWebTransport, nsTArray<std::function<void(nsresult)>> mPendingCreateStreamEvents MOZ_GUARDED_BY(mMutex); nsCOMPtr<nsIEventTarget> mTarget MOZ_GUARDED_BY(mMutex); + nsTArray<RefPtr<nsIWebTransportHash>> mServerCertHashes; + bool mDedicatedConnection; // for WebTranport }; } // namespace mozilla::net diff --git a/netwerk/protocol/webtransport/nsIWebTransport.idl b/netwerk/protocol/webtransport/nsIWebTransport.idl index faf99e61b6..2283c42977 100644 --- a/netwerk/protocol/webtransport/nsIWebTransport.idl +++ b/netwerk/protocol/webtransport/nsIWebTransport.idl @@ -38,12 +38,14 @@ interface nsIWebTransport : nsISupports { // When called, perform steps in "Initialization WebTransport over HTTP". void asyncConnect(in nsIURI aURI, + in boolean aDedicated, in Array<nsIWebTransportHash> aServerCertHashes, in nsIPrincipal aLoadingPrincipal, in unsigned long aSecurityFlags, in WebTransportSessionEventListener aListener); void asyncConnectWithClient(in nsIURI aURI, + in boolean aDedicated, in Array<nsIWebTransportHash> aServerCertHashes, in nsIPrincipal aLoadingPrincipal, in unsigned long aSecurityFlags, @@ -116,6 +118,13 @@ interface WebTransportSessionEventListener : nsISupports { // void onStatsAvailable(in WebTransportStats aStats); }; +[uuid(faad75bd-83c6-420b-9fdb-a70bd70be449)] +interface WebTransportConnectionSettings : nsISupports { + // WebTransport specific connection information + readonly attribute bool dedicated; + void getServerCertificateHashes(out Array<nsIWebTransportHash> aServerCertHashes); +}; + // This interface is used as a callback when creating an outgoing // unidirectional or bidirectional stream. [scriptable, uuid(c6eeff1d-599b-40a8-9157-c7a40c3d51a2)] |