diff options
Diffstat (limited to 'netwerk/protocol/http/Http3Session.cpp')
-rw-r--r-- | netwerk/protocol/http/Http3Session.cpp | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/netwerk/protocol/http/Http3Session.cpp b/netwerk/protocol/http/Http3Session.cpp index 0369da94ac..80ee3267fa 100644 --- a/netwerk/protocol/http/Http3Session.cpp +++ b/netwerk/protocol/http/Http3Session.cpp @@ -29,6 +29,7 @@ #include "nsSocketTransportService2.h" #include "nsThreadUtils.h" #include "sslerr.h" +#include "WebTransportCertificateVerifier.h" namespace mozilla::net { @@ -153,7 +154,20 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo, SessionCacheInfo info; udpConn->ChangeConnectionState(ConnectionState::TLS_HANDSHAKING); - if (StaticPrefs::network_http_http3_enable_0rtt() && + auto hasServCertHashes = [&]() -> bool { + if (!mConnInfo->GetWebTransport()) { + return false; + } + const nsTArray<RefPtr<nsIWebTransportHash>>* servCertHashes = + gHttpHandler->ConnMgr()->GetServerCertHashes(mConnInfo); + return servCertHashes && !servCertHashes->IsEmpty(); + }; + + // In WebTransport, when servCertHashes is specified, it indicates that the + // connection to the WebTransport server should authenticate using the + // expected certificate hash. Therefore, 0RTT should be disabled in this + // context to ensure the certificate hash is checked. + if (StaticPrefs::network_http_http3_enable_0rtt() && !hasServCertHashes() && NS_SUCCEEDED(SSLTokensCache::Get(peerId, token, info))) { LOG(("Found a resumption token in the cache.")); mHttp3Connection->SetResumptionToken(token); @@ -1514,7 +1528,7 @@ nsresult Http3Session::SendData(nsIUDPSocket* socket) { while (CanSendData() && (stream = mReadyForWrite.PopFront())) { LOG(("Http3Session::SendData call ReadSegments from stream=%p [this=%p]", stream.get(), this)); - + stream->SetInTxQueue(false); rv = stream->ReadSegments(); // on stream error we return earlier to let the error be handled. @@ -1557,7 +1571,15 @@ nsresult Http3Session::SendData(nsIUDPSocket* socket) { void Http3Session::StreamReadyToWrite(Http3StreamBase* aStream) { MOZ_ASSERT(aStream); + // Http3Session::StreamReadyToWrite can be called multiple times when we get + // duplicate DataWrite events from neqo at the same time. In this case, we + // only want to insert the stream in `mReadyForWrite` once. + if (aStream->IsInTxQueue()) { + return; + } + mReadyForWrite.Push(aStream); + aStream->SetInTxQueue(true); if (CanSendData() && mConnection) { Unused << mConnection->ResumeSend(); } @@ -2119,6 +2141,32 @@ void Http3Session::CallCertVerification(Maybe<nsCString> aEchPublicName) { return; } + if (mConnInfo->GetWebTransport()) { + // if our connection is webtransport, we might do a verification + // based on serverCertificatedHashes + const nsTArray<RefPtr<nsIWebTransportHash>>* servCertHashes = + gHttpHandler->ConnMgr()->GetServerCertHashes(mConnInfo); + if (servCertHashes && !servCertHashes->IsEmpty() && + certInfo.certs.Length() >= 1) { + // ok, we verify based on serverCertificateHashes + mozilla::pkix::Result rv = AuthCertificateWithServerCertificateHashes( + certInfo.certs[0], *servCertHashes); + if (rv != mozilla::pkix::Result::Success) { + // ok we failed, report it back + LOG( + ("Http3Session::CallCertVerification [this=%p] " + "AuthCertificateWithServerCertificateHashes failed", + this)); + mHttp3Connection->PeerAuthenticated(SSL_ERROR_BAD_CERTIFICATE); + mError = psm::GetXPCOMFromNSSError(SSL_ERROR_BAD_CERTIFICATE); + return; + } + // ok, we succeded + Authenticated(0); + return; + } + } + Maybe<nsTArray<nsTArray<uint8_t>>> stapledOCSPResponse; if (certInfo.stapled_ocsp_responses_present) { stapledOCSPResponse.emplace(std::move(certInfo.stapled_ocsp_responses)); |