зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1791633 - separate nsITLSSocketControl from nsITransportSecurityInfo r=necko-reviewers,kershaw,jschanck
Depends on D160311 Differential Revision: https://phabricator.services.mozilla.com/D160313
This commit is contained in:
Родитель
21ac70dabe
Коммит
0a13b94a8f
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/psm/TransportSecurityInfo.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#ifndef mozilla_ipc_TransportSecurityInfoUtils_h
|
||||
#define mozilla_ipc_TransportSecurityInfoUtils_h
|
||||
|
||||
#include "ipc/EnumSerializer.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsIX509Cert.h"
|
||||
|
@ -30,6 +31,13 @@ struct ParamTraits<nsIX509Cert*> {
|
|||
static bool Read(MessageReader* aReader, RefPtr<nsIX509Cert>* aResult);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<nsITransportSecurityInfo::OverridableErrorCategory>
|
||||
: public ContiguousEnumSerializerInclusive<
|
||||
nsITransportSecurityInfo::OverridableErrorCategory,
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET,
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_TIME> {};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_ipc_TransportSecurityInfoUtils_h
|
||||
|
|
|
@ -1,366 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FuzzySecurityInfo.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/OriginAttributes.h"
|
||||
#include "nsITlsHandshakeListener.h"
|
||||
#include "nsThreadManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
FuzzySecurityInfo::FuzzySecurityInfo() {}
|
||||
|
||||
FuzzySecurityInfo::~FuzzySecurityInfo() {}
|
||||
|
||||
NS_IMPL_ISUPPORTS(FuzzySecurityInfo, nsITransportSecurityInfo,
|
||||
nsIInterfaceRequestor, nsITLSSocketControl)
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetErrorCode(int32_t* state) {
|
||||
*state = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetSecurityState(uint32_t* state) {
|
||||
*state = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetErrorCodeString(nsAString& aErrorString) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetFailedCertChain(
|
||||
nsTArray<RefPtr<nsIX509Cert>>& aFailedCertChain) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetServerCert(nsIX509Cert** aServerCert) {
|
||||
NS_ENSURE_ARG_POINTER(aServerCert);
|
||||
// This method is called by nsHttpChannel::ProcessSSLInformation()
|
||||
// in order to display certain information in the console.
|
||||
// Returning NULL is okay here and handled by the caller.
|
||||
*aServerCert = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetSucceededCertChain(
|
||||
nsTArray<RefPtr<nsIX509Cert>>& aSucceededCertChain) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetCipherName(nsACString& aCipherName) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetKeyLength(uint32_t* aKeyLength) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetSecretKeyLength(uint32_t* aSecretKeyLength) {
|
||||
MOZ_CRASH("Unused");
|
||||
*aSecretKeyLength = 4096;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetKeaGroupName(nsACString& aKeaGroup) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetSignatureSchemeName(nsACString& aSignatureScheme) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetProtocolVersion(uint16_t* aProtocolVersion) {
|
||||
NS_ENSURE_ARG_POINTER(aProtocolVersion);
|
||||
// Must be >= TLS 1.2 for HTTP2
|
||||
*aProtocolVersion = nsITransportSecurityInfo::TLS_VERSION_1_2;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetCertificateTransparencyStatus(
|
||||
uint16_t* aCertificateTransparencyStatus) {
|
||||
NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus);
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetOverridableErrorCategory(
|
||||
OverridableErrorCategory* aOverridableErrorCode) {
|
||||
NS_ENSURE_ARG_POINTER(aOverridableErrorCode);
|
||||
*aOverridableErrorCode = OverridableErrorCategory::ERROR_UNSET;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetIsExtendedValidation(bool* aIsEV) {
|
||||
NS_ENSURE_ARG_POINTER(aIsEV);
|
||||
*aIsEV = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetIsDelegatedCredential(bool* aIsDelegCred) {
|
||||
NS_ENSURE_ARG_POINTER(aIsDelegCred);
|
||||
*aIsDelegCred = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetIsAcceptedEch(bool* aIsAcceptedEch) {
|
||||
NS_ENSURE_ARG_POINTER(aIsAcceptedEch);
|
||||
*aIsAcceptedEch = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetInterface(const nsIID& uuid, void** result) {
|
||||
if (!NS_IsMainThread()) {
|
||||
MOZ_CRASH("FuzzySecurityInfo::GetInterface called off the main thread");
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
nsresult rv = NS_ERROR_NO_INTERFACE;
|
||||
if (mCallbacks) {
|
||||
rv = mCallbacks->GetInterface(uuid, result);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetNotificationCallbacks(
|
||||
nsIInterfaceRequestor** aCallbacks) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir(mCallbacks);
|
||||
ir.forget(aCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
|
||||
mCallbacks = aCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetProviderFlags(uint32_t* aProviderFlags) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetProviderTlsFlags(uint32_t* aProviderTlsFlags) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetKEAUsed(int16_t* aKea) {
|
||||
// Can be ssl_kea_dh or ssl_kea_ecdh for HTTP2
|
||||
*aKea = ssl_kea_ecdh;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetKEAKeyBits(uint32_t* aKeyBits) {
|
||||
// Must be >= 224 for ecdh and >= 2048 for dh when using HTTP2
|
||||
*aKeyBits = 256;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetSSLVersionUsed(int16_t* aSSLVersionUsed) {
|
||||
// Must be >= TLS 1.2 for HTTP2
|
||||
*aSSLVersionUsed = nsITLSSocketControl::TLS_VERSION_1_2;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetSSLVersionOffered(int16_t* aSSLVersionOffered) {
|
||||
*aSSLVersionOffered = nsITLSSocketControl::TLS_VERSION_1_2;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetMACAlgorithmUsed(int16_t* aMac) {
|
||||
// The only valid choice for HTTP2 is SSL_MAC_AEAD
|
||||
*aMac = nsITLSSocketControl::SSL_MAC_AEAD;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool FuzzySecurityInfo::GetDenyClientCert() { return false; }
|
||||
|
||||
void FuzzySecurityInfo::SetDenyClientCert(bool aDenyClientCert) {
|
||||
// Called by mozilla::net::nsHttpConnection::StartSpdy
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetClientCertSent(bool* arg) {
|
||||
*arg = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetFailedVerification(bool* arg) {
|
||||
*arg = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::ToString(nsACString& aResult) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN) {
|
||||
aNegotiatedNPN = "h2";
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetAlpnEarlySelection(nsACString& aAlpnSelected) {
|
||||
// TODO: For now we don't support early selection
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetEarlyDataAccepted(bool* aAccepted) {
|
||||
*aAccepted = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetResumed(bool* aResumed) {
|
||||
*aResumed = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::DriveHandshake() { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::IsAcceptableForHost(const nsACString& hostname,
|
||||
bool* _retval) {
|
||||
NS_ENSURE_ARG(_retval);
|
||||
*_retval = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::TestJoinConnection(const nsACString& npnProtocol,
|
||||
const nsACString& hostname, int32_t port,
|
||||
bool* _retval) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::JoinConnection(const nsACString& npnProtocol,
|
||||
const nsACString& hostname, int32_t port,
|
||||
bool* _retval) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::ProxyStartSSL() { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::StartTLS() { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::SetNPNList(nsTArray<nsCString>& protocolArray) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetEsniTxt(nsACString& aEsniTxt) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::SetEsniTxt(const nsACString& aEsniTxt) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetEchConfig(nsACString& aEchConfig) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::SetEchConfig(const nsACString& aEchConfig) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetRetryEchConfig(nsACString& aEchConfig) { return NS_OK; }
|
||||
|
||||
void FuzzySecurityInfo::SerializeToIPC(IPC::MessageWriter* aWriter) {
|
||||
MOZ_CRASH("Unused");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetPeerId(nsACString& aResult) {
|
||||
aResult.Assign(""_ns);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FuzzySecurityInfo::SetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool aIsBuiltInRoot) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FuzzySecurityInfo::GetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool* aIsBuiltInRoot) {
|
||||
*aIsBuiltInRoot = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetUsedPrivateDNS(bool* aUsedPrivateDNS) {
|
||||
*aUsedPrivateDNS = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySecurityInfo::GetMadeOCSPRequests(bool* aMadeOCSPRequests) {
|
||||
*aMadeOCSPRequests = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FuzzySecurityInfo::DisableEarlyData(void) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP FuzzySecurityInfo::SetHandshakeCallbackListener(
|
||||
nsITlsHandshakeCallbackListener* callback) {
|
||||
if (callback) {
|
||||
callback->HandshakeDone();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -1,43 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FuzzySecurityInfo_h__
|
||||
#define FuzzySecurityInfo_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsITLSSocketControl.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "prerror.h"
|
||||
#include "sslproto.h"
|
||||
#include "sslt.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class FuzzySecurityInfo final : public nsITransportSecurityInfo,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsITLSSocketControl {
|
||||
public:
|
||||
FuzzySecurityInfo();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSITRANSPORTSECURITYINFO
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSISSLSOCKETCONTROL
|
||||
|
||||
protected:
|
||||
virtual ~FuzzySecurityInfo();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
|
||||
}; // class FuzzySecurityInfo
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // FuzzySecurityInfo_h__
|
|
@ -0,0 +1,180 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "FuzzySocketControl.h"
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "nsITlsHandshakeListener.h"
|
||||
#include "sslt.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
FuzzySocketControl::FuzzySocketControl() {}
|
||||
|
||||
FuzzySocketControl::~FuzzySocketControl() {}
|
||||
|
||||
NS_IMPL_ISUPPORTS(FuzzySocketControl, nsITLSSocketControl)
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetProviderFlags(uint32_t* aProviderFlags) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetKEAUsed(int16_t* aKea) {
|
||||
// Can be ssl_kea_dh or ssl_kea_ecdh for HTTP2
|
||||
*aKea = ssl_kea_ecdh;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetKEAKeyBits(uint32_t* aKeyBits) {
|
||||
// Must be >= 224 for ecdh and >= 2048 for dh when using HTTP2
|
||||
*aKeyBits = 256;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetSSLVersionUsed(int16_t* aSSLVersionUsed) {
|
||||
// Must be >= TLS 1.2 for HTTP2
|
||||
*aSSLVersionUsed = nsITLSSocketControl::TLS_VERSION_1_2;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetSSLVersionOffered(int16_t* aSSLVersionOffered) {
|
||||
*aSSLVersionOffered = nsITLSSocketControl::TLS_VERSION_1_2;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetMACAlgorithmUsed(int16_t* aMac) {
|
||||
// The only valid choice for HTTP2 is SSL_MAC_AEAD
|
||||
*aMac = nsITLSSocketControl::SSL_MAC_AEAD;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool FuzzySocketControl::GetDenyClientCert() { return false; }
|
||||
|
||||
void FuzzySocketControl::SetDenyClientCert(bool aDenyClientCert) {
|
||||
// Called by mozilla::net::nsHttpConnection::StartSpdy
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetClientCertSent(bool* arg) {
|
||||
*arg = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetFailedVerification(bool* arg) {
|
||||
*arg = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetAlpnEarlySelection(nsACString& aAlpnSelected) {
|
||||
// TODO: For now we don't support early selection
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetEarlyDataAccepted(bool* aAccepted) {
|
||||
*aAccepted = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::DriveHandshake() { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::IsAcceptableForHost(const nsACString& hostname,
|
||||
bool* _retval) {
|
||||
NS_ENSURE_ARG(_retval);
|
||||
*_retval = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::TestJoinConnection(const nsACString& npnProtocol,
|
||||
const nsACString& hostname, int32_t port,
|
||||
bool* _retval) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::JoinConnection(const nsACString& npnProtocol,
|
||||
const nsACString& hostname, int32_t port,
|
||||
bool* _retval) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::ProxyStartSSL() { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::StartTLS() { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::SetNPNList(nsTArray<nsCString>& protocolArray) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetEsniTxt(nsACString& aEsniTxt) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::SetEsniTxt(const nsACString& aEsniTxt) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetEchConfig(nsACString& aEchConfig) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::SetEchConfig(const nsACString& aEchConfig) {
|
||||
MOZ_CRASH("Unused");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetRetryEchConfig(nsACString& aEchConfig) { return NS_OK; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::GetPeerId(nsACString& aResult) {
|
||||
aResult.Assign(""_ns);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP FuzzySocketControl::SetHandshakeCallbackListener(
|
||||
nsITlsHandshakeCallbackListener* callback) {
|
||||
if (callback) {
|
||||
callback->HandshakeDone();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::DisableEarlyData(void) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
NS_IMETHODIMP FuzzySocketControl::GetSecurityInfo(
|
||||
nsITransportSecurityInfo** aSecurityInfo) {
|
||||
*aSecurityInfo = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FuzzySocketControl::AsyncGetSecurityInfo(JSContext* aCx,
|
||||
mozilla::dom::Promise** aPromise) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FuzzySocketControl_h__
|
||||
#define FuzzySocketControl_h__
|
||||
|
||||
#include "nsITLSSocketControl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class FuzzySocketControl final : public nsITLSSocketControl {
|
||||
public:
|
||||
FuzzySocketControl();
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSITLSSOCKETCONTROL
|
||||
|
||||
protected:
|
||||
virtual ~FuzzySocketControl();
|
||||
}; // class FuzzySocketControl
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // FuzzySocketControl_h__
|
|
@ -3,13 +3,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SSLTokensCache.h"
|
||||
#include "mozilla/ArrayAlgorithm.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsIOService.h"
|
||||
#include "nsNSSIOLayer.h"
|
||||
#include "TransportSecurityInfo.h"
|
||||
|
||||
#include "CertVerifier.h"
|
||||
#include "CommonSocketControl.h"
|
||||
#include "TransportSecurityInfo.h"
|
||||
#include "mozilla/ArrayAlgorithm.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIOService.h"
|
||||
#include "ssl.h"
|
||||
#include "sslexp.h"
|
||||
|
||||
|
@ -192,7 +193,7 @@ SSLTokensCache::~SSLTokensCache() { LOG(("SSLTokensCache::~SSLTokensCache")); }
|
|||
// static
|
||||
nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
||||
uint32_t aTokenLen,
|
||||
nsITransportSecurityInfo* aSecInfo) {
|
||||
CommonSocketControl* aSocketControl) {
|
||||
PRUint32 expirationTime;
|
||||
SSLResumptionTokenInfo tokenInfo;
|
||||
if (SSL_GetResumptionTokenInfo(aToken, aTokenLen, &tokenInfo,
|
||||
|
@ -205,13 +206,13 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
expirationTime = tokenInfo.expirationTime;
|
||||
SSL_DestroyResumptionTokenInfo(&tokenInfo);
|
||||
|
||||
return Put(aKey, aToken, aTokenLen, aSecInfo, expirationTime);
|
||||
return Put(aKey, aToken, aTokenLen, aSocketControl, expirationTime);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
||||
uint32_t aTokenLen,
|
||||
nsITransportSecurityInfo* aSecInfo,
|
||||
CommonSocketControl* aSocketControl,
|
||||
PRUint32 aExpirationTime) {
|
||||
StaticMutexAutoLock lock(sLock);
|
||||
|
||||
|
@ -223,25 +224,30 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!aSecInfo) {
|
||||
if (!aSocketControl) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
nsresult rv = aSocketControl->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
aSecInfo->GetServerCert(getter_AddRefs(cert));
|
||||
securityInfo->GetServerCert(getter_AddRefs(cert));
|
||||
if (!cert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsTArray<uint8_t> certBytes;
|
||||
nsresult rv = cert->GetRawDER(certBytes);
|
||||
rv = cert->GetRawDER(certBytes);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Maybe<nsTArray<nsTArray<uint8_t>>> succeededCertChainBytes;
|
||||
nsTArray<RefPtr<nsIX509Cert>> succeededCertArray;
|
||||
rv = aSecInfo->GetSucceededCertChain(succeededCertArray);
|
||||
rv = securityInfo->GetSucceededCertChain(succeededCertArray);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -259,7 +265,7 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
}
|
||||
|
||||
bool builtInRoot = false;
|
||||
rv = aSecInfo->GetIsBuiltCertChainRootBuiltInRoot(&builtInRoot);
|
||||
rv = securityInfo->GetIsBuiltCertChainRootBuiltInRoot(&builtInRoot);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -267,27 +273,27 @@ nsresult SSLTokensCache::Put(const nsACString& aKey, const uint8_t* aToken,
|
|||
}
|
||||
|
||||
bool isEV;
|
||||
rv = aSecInfo->GetIsExtendedValidation(&isEV);
|
||||
rv = securityInfo->GetIsExtendedValidation(&isEV);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint16_t certificateTransparencyStatus;
|
||||
rv = aSecInfo->GetCertificateTransparencyStatus(
|
||||
rv = securityInfo->GetCertificateTransparencyStatus(
|
||||
&certificateTransparencyStatus);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsITransportSecurityInfo::OverridableErrorCategory overridableErrorCategory;
|
||||
rv = aSecInfo->GetOverridableErrorCategory(&overridableErrorCategory);
|
||||
rv = securityInfo->GetOverridableErrorCategory(&overridableErrorCategory);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Maybe<nsTArray<nsTArray<uint8_t>>> failedCertChainBytes;
|
||||
nsTArray<RefPtr<nsIX509Cert>> failedCertArray;
|
||||
rv = aSecInfo->GetFailedCertChain(failedCertArray);
|
||||
rv = securityInfo->GetFailedCertChain(failedCertArray);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -6,17 +6,19 @@
|
|||
#define SSLTokensCache_h_
|
||||
|
||||
#include "CertVerifier.h" // For EVStatus
|
||||
#include "TransportSecurityInfo.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTHashMap.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
class CommonSocketControl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
|
@ -44,9 +46,9 @@ class SSLTokensCache : public nsIMemoryReporter {
|
|||
static nsresult Shutdown();
|
||||
|
||||
static nsresult Put(const nsACString& aKey, const uint8_t* aToken,
|
||||
uint32_t aTokenLen, nsITransportSecurityInfo* aSecInfo);
|
||||
uint32_t aTokenLen, CommonSocketControl* aSocketControl);
|
||||
static nsresult Put(const nsACString& aKey, const uint8_t* aToken,
|
||||
uint32_t aTokenLen, nsITransportSecurityInfo* aSecInfo,
|
||||
uint32_t aTokenLen, CommonSocketControl* aSocketControl,
|
||||
PRUint32 aExpirationTime);
|
||||
static nsresult Get(const nsACString& aKey, nsTArray<uint8_t>& aToken,
|
||||
SessionCacheInfo& aResult, uint64_t* aTokenId = nullptr);
|
||||
|
|
|
@ -247,7 +247,7 @@ UNIFIED_SOURCES += [
|
|||
if CONFIG["FUZZING"]:
|
||||
SOURCES += [
|
||||
"FuzzyLayer.cpp",
|
||||
"FuzzySecurityInfo.cpp",
|
||||
"FuzzySocketControl.cpp",
|
||||
]
|
||||
|
||||
if CONFIG["FUZZING_INTERFACES"] and CONFIG["LIBFUZZER"]:
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
#if defined(FUZZING)
|
||||
# include "FuzzyLayer.h"
|
||||
# include "FuzzySecurityInfo.h"
|
||||
# include "FuzzySocketControl.h"
|
||||
# include "mozilla/StaticPrefs_fuzzing.h"
|
||||
#endif
|
||||
|
||||
|
@ -1173,19 +1173,13 @@ nsresult nsSocketTransport::BuildSocket(PRFileDesc*& fd, bool& proxyTransparent,
|
|||
// info
|
||||
bool isSSL = mTypes[i].EqualsLiteral("ssl");
|
||||
if (isSSL || mTypes[i].EqualsLiteral("starttls")) {
|
||||
// remember security info and give notification callbacks to PSM...
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
// remember security info
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mTLSSocketControl = tlsSocketControl;
|
||||
callbacks = mCallbacks;
|
||||
SOCKET_LOG((" [tlsSocketControl=%p callbacks=%p]\n",
|
||||
mTLSSocketControl.get(), mCallbacks.get()));
|
||||
}
|
||||
// don't call into PSM while holding mLock!!
|
||||
if (tlsSocketControl) {
|
||||
tlsSocketControl->SetNotificationCallbacks(callbacks);
|
||||
}
|
||||
// remember if socket type is SSL so we can ProxyStartSSL if need be.
|
||||
usingSSL = isSSL;
|
||||
} else if (mTypes[i].EqualsLiteral("socks") ||
|
||||
|
@ -1335,7 +1329,7 @@ nsresult nsSocketTransport::InitiateSocket() {
|
|||
SOCKET_LOG(("Successfully attached fuzzing IOLayer.\n"));
|
||||
|
||||
if (usingSSL) {
|
||||
mTLSSocketControl = new FuzzySecurityInfo();
|
||||
mTLSSocketControl = new FuzzySocketControl();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2233,13 +2227,6 @@ void nsSocketTransport::OnSocketDetached(PRFileDesc* fd) {
|
|||
mDNSRecord->ReportUnusable(SocketPort());
|
||||
}
|
||||
|
||||
// break any potential reference cycle between the security info object
|
||||
// and ourselves by resetting its notification callbacks object. see
|
||||
// bug 285991 for details.
|
||||
if (mTLSSocketControl) {
|
||||
mTLSSocketControl->SetNotificationCallbacks(nullptr);
|
||||
}
|
||||
|
||||
// finally, release our reference to the socket (must do this within
|
||||
// the transport lock) possibly closing the socket. Also release our
|
||||
// listeners to break potential refcount cycles.
|
||||
|
@ -2420,22 +2407,10 @@ nsSocketTransport::SetSecurityCallbacks(nsIInterfaceRequestor* callbacks) {
|
|||
NS_NewNotificationCallbacksAggregation(callbacks, nullptr,
|
||||
GetCurrentEventTarget(),
|
||||
getter_AddRefs(threadsafeCallbacks));
|
||||
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mCallbacks = threadsafeCallbacks;
|
||||
SOCKET_LOG(("Reset callbacks for tlsSocketInfo=%p callbacks=%p\n",
|
||||
mTLSSocketControl.get(), mCallbacks.get()));
|
||||
|
||||
tlsSocketControl = mTLSSocketControl;
|
||||
}
|
||||
|
||||
// don't call into PSM while holding mLock!!
|
||||
if (tlsSocketControl) {
|
||||
tlsSocketControl->SetNotificationCallbacks(threadsafeCallbacks);
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
mCallbacks = threadsafeCallbacks;
|
||||
SOCKET_LOG(("Reset callbacks for tlsSocketInfo=%p callbacks=%p\n",
|
||||
mTLSSocketControl.get(), mCallbacks.get()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsTransportUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTransportUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -55,7 +56,17 @@ class nsTransportStatusEvent : public Runnable {
|
|||
mProgress(progress),
|
||||
mProgressMax(progressMax) {}
|
||||
|
||||
~nsTransportStatusEvent() = default;
|
||||
~nsTransportStatusEvent() {
|
||||
auto ReleaseTransport = [transport(std::move(mTransport))]() mutable {
|
||||
transport = nullptr;
|
||||
};
|
||||
if (OnSocketThread()) {
|
||||
ReleaseTransport();
|
||||
} else {
|
||||
gSocketTransportService->Dispatch(NS_NewRunnableFunction(
|
||||
"nsHttpConnection::~nsHttpConnection", ReleaseTransport));
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
// since this event is being handled, we need to clear the proxy's ref.
|
||||
|
|
|
@ -62,4 +62,6 @@ LOCAL_INCLUDES += [
|
|||
"/netwerk/cache",
|
||||
]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "prio.h"
|
||||
|
||||
#if defined(FUZZING)
|
||||
# include "FuzzySecurityInfo.h"
|
||||
# include "FuzzySocketControl.h"
|
||||
# include "mozilla/StaticPrefs_fuzzing.h"
|
||||
#endif
|
||||
|
||||
|
@ -666,7 +666,7 @@ OutputStreamShim::AsyncWait(nsIOutputStreamCallback* callback,
|
|||
// target is on the socket thread. That's all we really care about.
|
||||
nsCOMPtr<nsIEventTarget> sts =
|
||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT((!target && !callback) || (target == sts));
|
||||
MOZ_ASSERT(!target || (target == sts));
|
||||
if (target && (target != sts)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -891,7 +891,7 @@ InputStreamShim::AsyncWait(nsIInputStreamCallback* callback, unsigned int flags,
|
|||
// target is on the socket thread. That's all we really care about.
|
||||
nsCOMPtr<nsIEventTarget> sts =
|
||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT((!target && !callback) || (target == sts));
|
||||
MOZ_ASSERT(!target || (target == sts));
|
||||
if (target && (target != sts)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -2398,12 +2398,11 @@ nsresult Http2Session::RecvContinuation(Http2Session* self) {
|
|||
class UpdateAltSvcEvent : public Runnable {
|
||||
public:
|
||||
UpdateAltSvcEvent(const nsCString& header, const nsCString& aOrigin,
|
||||
nsHttpConnectionInfo* aCI, nsIInterfaceRequestor* callbacks)
|
||||
nsHttpConnectionInfo* aCI)
|
||||
: Runnable("net::UpdateAltSvcEvent"),
|
||||
mHeader(header),
|
||||
mOrigin(aOrigin),
|
||||
mCI(aCI),
|
||||
mCallbacks(callbacks) {}
|
||||
mCI(aCI) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -2424,7 +2423,7 @@ class UpdateAltSvcEvent : public Runnable {
|
|||
if (XRE_IsSocketProcess()) {
|
||||
AltServiceChild::ProcessHeader(
|
||||
mHeader, originScheme, originHost, originPort, mCI->GetUsername(),
|
||||
mCI->GetPrivate(), mCallbacks, mCI->ProxyInfo(), 0,
|
||||
mCI->GetPrivate(), nullptr, mCI->ProxyInfo(), 0,
|
||||
mCI->GetOriginAttributes());
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2593,15 +2592,8 @@ nsresult Http2Session::RecvAltSvc(Http2Session* self) {
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
self->mConnection->GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
if (tlsSocketControl) {
|
||||
tlsSocketControl->GetNotificationCallbacks(getter_AddRefs(callbacks));
|
||||
}
|
||||
|
||||
RefPtr<UpdateAltSvcEvent> event =
|
||||
new UpdateAltSvcEvent(altSvcFieldValue, origin, ci, callbacks);
|
||||
new UpdateAltSvcEvent(altSvcFieldValue, origin, ci);
|
||||
NS_DispatchToMainThread(event);
|
||||
self->ResetDownstreamState();
|
||||
return NS_OK;
|
||||
|
|
|
@ -96,14 +96,10 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
|
|||
aConnInfo->ProxyInfo() ? aConnInfo->ProxyInfo()->IsHTTPS() : false;
|
||||
|
||||
// Create security control and info object for quic.
|
||||
mSocketControl = new QuicSocketControl(controlFlags, this);
|
||||
mSocketControl->SetHostName(httpsProxy ? aConnInfo->ProxyInfo()->Host().get()
|
||||
: aConnInfo->GetOrigin().get());
|
||||
mSocketControl->SetPort(httpsProxy ? aConnInfo->ProxyInfo()->Port()
|
||||
: aConnInfo->OriginPort());
|
||||
|
||||
// don't call into PSM while holding mLock!!
|
||||
mSocketControl->SetNotificationCallbacks(callbacks);
|
||||
mSocketControl = new QuicSocketControl(
|
||||
httpsProxy ? aConnInfo->ProxyInfo()->Host() : aConnInfo->GetOrigin(),
|
||||
httpsProxy ? aConnInfo->ProxyInfo()->Port() : aConnInfo->OriginPort(),
|
||||
controlFlags, this);
|
||||
|
||||
NetAddr selfAddr;
|
||||
MOZ_ALWAYS_SUCCEEDS(aSelfAddr->GetNetAddr(&selfAddr));
|
||||
|
@ -1904,7 +1900,7 @@ void Http3Session::CallCertVerification(Maybe<nsCString> aEchPublicName) {
|
|||
const nsACString& hostname =
|
||||
verifyToEchPublicName ? *aEchPublicName : mSocketControl->GetHostName();
|
||||
|
||||
SECStatus rv = AuthCertificateHookWithInfo(
|
||||
SECStatus rv = psm::AuthCertificateHookWithInfo(
|
||||
mSocketControl, hostname, static_cast<const void*>(this),
|
||||
std::move(certInfo.certs), stapledOCSPResponse, sctsFromTLSExtension,
|
||||
providerFlags);
|
||||
|
|
|
@ -7,17 +7,18 @@
|
|||
#ifndef Http3Session_H__
|
||||
#define Http3Session_H__
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIUDPSocket.h"
|
||||
#include "mozilla/net/NeqoHttp3Conn.h"
|
||||
#include "nsAHttpConnection.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "HttpTrafficAnalyzer.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "mozilla/net/NeqoHttp3Conn.h"
|
||||
#include "nsAHttpConnection.h"
|
||||
#include "nsDeque.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIUDPSocket.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsTHashMap.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
/*
|
||||
* WebTransport
|
||||
|
|
|
@ -415,9 +415,6 @@ HttpTransactionChild::OnStartRequest(nsIRequest* aRequest) {
|
|||
!protocol.IsEmpty()) {
|
||||
mProtocolVersion.Assign(protocol);
|
||||
}
|
||||
// Make sure peerId is generated.
|
||||
nsAutoCString unused;
|
||||
securityInfo->GetPeerId(unused);
|
||||
}
|
||||
|
||||
UniquePtr<nsHttpResponseHead> head(mTransaction->TakeResponseHead());
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "nsISocketProvider.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "sslt.h"
|
||||
|
@ -20,19 +19,17 @@
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(QuicSocketControl, TransportSecurityInfo,
|
||||
nsITLSSocketControl, QuicSocketControl)
|
||||
|
||||
QuicSocketControl::QuicSocketControl(uint32_t aProviderFlags,
|
||||
QuicSocketControl::QuicSocketControl(const nsCString& aHostName, int32_t aPort,
|
||||
uint32_t aProviderFlags,
|
||||
Http3Session* aHttp3Session)
|
||||
: CommonSocketControl(aProviderFlags) {
|
||||
MOZ_ASSERT(OnSocketThread());
|
||||
: CommonSocketControl(aHostName, aPort, aProviderFlags) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mHttp3Session = do_GetWeakReference(
|
||||
static_cast<nsISupportsWeakReference*>(aHttp3Session));
|
||||
mSocketThread = NS_GetCurrentThread();
|
||||
}
|
||||
|
||||
void QuicSocketControl::SetCertVerificationResult(PRErrorCode errorCode) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
SetUsedPrivateDNS(GetProviderFlags() & nsISocketProvider::USED_PRIVATE_DNS);
|
||||
|
||||
if (errorCode) {
|
||||
|
@ -40,28 +37,18 @@ void QuicSocketControl::SetCertVerificationResult(PRErrorCode errorCode) {
|
|||
SetCanceled(errorCode);
|
||||
}
|
||||
|
||||
if (OnSocketThread()) {
|
||||
CallAuthenticated();
|
||||
} else {
|
||||
DebugOnly<nsresult> rv = gSocketTransportService->Dispatch(
|
||||
NewRunnableMethod("QuicSocketControl::CallAuthenticated", this,
|
||||
&QuicSocketControl::CallAuthenticated),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
QuicSocketControl::~QuicSocketControl() {
|
||||
NS_ProxyRelease("QuicSocketControl::~QuicSocketControl", mSocketThread,
|
||||
mHttp3Session.forget());
|
||||
CallAuthenticated();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuicSocketControl::GetSSLVersionOffered(int16_t* aSSLVersionOffered) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aSSLVersionOffered = nsITLSSocketControl::TLS_VERSION_1_3;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void QuicSocketControl::CallAuthenticated() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
RefPtr<Http3Session> http3Session = do_QueryReferent(mHttp3Session);
|
||||
if (http3Session) {
|
||||
http3Session->Authenticated(GetErrorCode());
|
||||
|
@ -69,14 +56,15 @@ void QuicSocketControl::CallAuthenticated() {
|
|||
}
|
||||
|
||||
void QuicSocketControl::HandshakeCompleted() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
uint32_t state = nsIWebProgressListener::STATE_IS_SECURE;
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
// If we're here, the TLS handshake has succeeded. If the overridable error
|
||||
// category is nonzero, the user has added an override for a certificate
|
||||
// error.
|
||||
if (mOverridableErrorCategory != OverridableErrorCategory::ERROR_UNSET) {
|
||||
if (mOverridableErrorCategory.isSome() &&
|
||||
*mOverridableErrorCategory !=
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET) {
|
||||
state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
|
||||
}
|
||||
|
||||
|
@ -85,64 +73,37 @@ void QuicSocketControl::HandshakeCompleted() {
|
|||
}
|
||||
|
||||
void QuicSocketControl::SetNegotiatedNPN(const nsACString& aValue) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mNegotiatedNPN = aValue;
|
||||
mNPNCompleted = true;
|
||||
}
|
||||
|
||||
void QuicSocketControl::SetInfo(uint16_t aCipherSuite,
|
||||
uint16_t aProtocolVersion, uint16_t aKeaGroup,
|
||||
uint16_t aProtocolVersion,
|
||||
uint16_t aKeaGroupName,
|
||||
uint16_t aSignatureScheme, bool aEchAccepted) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
SSLCipherSuiteInfo cipherInfo;
|
||||
if (SSL_GetCipherSuiteInfo(aCipherSuite, &cipherInfo, sizeof cipherInfo) ==
|
||||
SECSuccess) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mHaveCipherSuiteAndProtocol = true;
|
||||
mCipherSuite = aCipherSuite;
|
||||
mProtocolVersion = aProtocolVersion & 0xFF;
|
||||
mKeaGroup = getKeaGroupName(aKeaGroup);
|
||||
mSignatureSchemeName = getSignatureName(aSignatureScheme);
|
||||
mIsAcceptedEch = aEchAccepted;
|
||||
mCipherSuite.emplace(aCipherSuite);
|
||||
mProtocolVersion.emplace(aProtocolVersion & 0xFF);
|
||||
mKeaGroupName.emplace(getKeaGroupName(aKeaGroupName));
|
||||
mSignatureSchemeName.emplace(getSignatureName(aSignatureScheme));
|
||||
mIsAcceptedEch.emplace(aEchAccepted);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP QuicSocketControl::GetPeerId(nsACString& aResult) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mPeerId.IsEmpty()) {
|
||||
aResult.Assign(mPeerId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mProviderFlags &
|
||||
nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
|
||||
mPeerId.AppendLiteral("anon:");
|
||||
}
|
||||
if (mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE) {
|
||||
mPeerId.AppendLiteral("private:");
|
||||
}
|
||||
if (mProviderFlags & nsISocketProvider::BE_CONSERVATIVE) {
|
||||
mPeerId.AppendLiteral("beConservative:");
|
||||
}
|
||||
|
||||
mPeerId.Append(mHostName);
|
||||
mPeerId.Append(':');
|
||||
mPeerId.AppendInt(GetPort());
|
||||
nsAutoCString suffix;
|
||||
mOriginAttributes.CreateSuffix(suffix);
|
||||
mPeerId.Append(suffix);
|
||||
|
||||
aResult.Assign(mPeerId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuicSocketControl::GetEchConfig(nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
aEchConfig = mEchConfig;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuicSocketControl::SetEchConfig(const nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mEchConfig = aEchConfig;
|
||||
RefPtr<Http3Session> http3Session = do_QueryReferent(mHttp3Session);
|
||||
if (http3Session) {
|
||||
|
@ -153,11 +114,13 @@ QuicSocketControl::SetEchConfig(const nsACString& aEchConfig) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
QuicSocketControl::GetRetryEchConfig(nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
aEchConfig = mRetryEchConfig;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void QuicSocketControl::SetRetryEchConfig(const nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mRetryEchConfig = aEchConfig;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@ class Http3Session;
|
|||
|
||||
class QuicSocketControl final : public CommonSocketControl {
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_QUICSOCKETCONTROL_IID)
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_QUICSOCKETCONTROL_IID);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(QuicSocketControl, CommonSocketControl);
|
||||
|
||||
NS_IMETHOD GetSSLVersionOffered(int16_t* aSSLVersionOffered) override;
|
||||
|
||||
explicit QuicSocketControl(uint32_t providerFlags,
|
||||
Http3Session* aHttp3Session);
|
||||
QuicSocketControl(const nsCString& aHostName, int32_t aPort,
|
||||
uint32_t aProviderFlags, Http3Session* aHttp3Session);
|
||||
|
||||
void SetNegotiatedNPN(const nsACString& aValue);
|
||||
void SetInfo(uint16_t aCipherSuite, uint16_t aProtocolVersion,
|
||||
|
@ -44,19 +44,16 @@ class QuicSocketControl final : public CommonSocketControl {
|
|||
void HandshakeCompleted();
|
||||
void SetCertVerificationResult(PRErrorCode errorCode) override;
|
||||
|
||||
NS_IMETHOD GetPeerId(nsACString& aResult) override;
|
||||
|
||||
NS_IMETHOD GetEchConfig(nsACString& aEchConfig) override;
|
||||
NS_IMETHOD SetEchConfig(const nsACString& aEchConfig) override;
|
||||
NS_IMETHOD GetRetryEchConfig(nsACString& aEchConfig) override;
|
||||
void SetRetryEchConfig(const nsACString& aEchConfig);
|
||||
|
||||
private:
|
||||
~QuicSocketControl();
|
||||
~QuicSocketControl() = default;
|
||||
|
||||
// For Authentication done callback and echConfig.
|
||||
nsWeakPtr mHttp3Session;
|
||||
nsCOMPtr<nsIEventTarget> mSocketThread;
|
||||
|
||||
nsCString mEchConfig;
|
||||
nsCString mRetryEchConfig;
|
||||
|
|
|
@ -139,8 +139,18 @@ TLSTransportLayer::InputStreamWrapper::AsyncWait(
|
|||
PRPollDesc pd;
|
||||
pd.fd = mTransport->mFD;
|
||||
pd.in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
|
||||
int32_t rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
|
||||
LOG(("TLSTransportLayer::InputStreamWrapper::AsyncWait rv=%d", rv));
|
||||
// Only run PR_Poll on the socket thread. Also, make sure this lives at least
|
||||
// as long as that operation.
|
||||
auto DoPoll = [self = RefPtr{this}, pd(pd)]() mutable {
|
||||
int32_t rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
|
||||
LOG(("TLSTransportLayer::InputStreamWrapper::AsyncWait rv=%d", rv));
|
||||
};
|
||||
if (OnSocketThread()) {
|
||||
DoPoll();
|
||||
} else {
|
||||
gSocketTransportService->Dispatch(NS_NewRunnableFunction(
|
||||
"TLSTransportLayer::InputStreamWrapper::AsyncWait", DoPoll));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -313,6 +323,7 @@ TLSTransportLayer::TLSTransportLayer(nsISocketTransport* aTransport,
|
|||
}
|
||||
|
||||
TLSTransportLayer::~TLSTransportLayer() {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
LOG(("TLSTransportLayer dtor this=[%p]", this));
|
||||
if (mFD) {
|
||||
PR_Close(mFD);
|
||||
|
|
|
@ -117,6 +117,17 @@ nsHttpConnection::~nsHttpConnection() {
|
|||
mForceSendTimer->Cancel();
|
||||
mForceSendTimer = nullptr;
|
||||
}
|
||||
|
||||
auto ReleaseSocketTransport =
|
||||
[socketTransport(std::move(mSocketTransport))]() mutable {
|
||||
socketTransport = nullptr;
|
||||
};
|
||||
if (OnSocketThread()) {
|
||||
ReleaseSocketTransport();
|
||||
} else {
|
||||
gSocketTransportService->Dispatch(NS_NewRunnableFunction(
|
||||
"nsHttpConnection::~nsHttpConnection", ReleaseSocketTransport));
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsHttpConnection::Init(
|
||||
|
@ -650,10 +661,10 @@ void nsHttpConnection::Close(nsresult reason, bool aIsShutdown) {
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITLSSocketControl> ssl;
|
||||
GetTLSSocketControl(getter_AddRefs(ssl));
|
||||
if (ssl) {
|
||||
ssl->SetHandshakeCallbackListener(nullptr);
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
if (tlsSocketControl) {
|
||||
tlsSocketControl->SetHandshakeCallbackListener(nullptr);
|
||||
}
|
||||
|
||||
if (NS_FAILED(reason)) {
|
||||
|
@ -811,7 +822,7 @@ bool nsHttpConnection::IsAlive() {
|
|||
nsresult rv = mSocketTransport->IsAlive(&alive);
|
||||
if (NS_FAILED(rv)) alive = false;
|
||||
|
||||
//#define TEST_RESTART_LOGIC
|
||||
// #define TEST_RESTART_LOGIC
|
||||
#ifdef TEST_RESTART_LOGIC
|
||||
if (!alive) {
|
||||
LOG(("pretending socket is still alive to test restart logic\n"));
|
||||
|
@ -1193,7 +1204,7 @@ void nsHttpConnection::UpdateTCPKeepalive(nsITimer* aTimer, void* aClosure) {
|
|||
void nsHttpConnection::GetTLSSocketControl(
|
||||
nsITLSSocketControl** tlsSocketControl) {
|
||||
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
|
||||
LOG(("nsHttpConnection::GetSecurityInfo trans=%p socket=%p\n",
|
||||
LOG(("nsHttpConnection::GetTLSSocketControl trans=%p socket=%p\n",
|
||||
mTransaction.get(), mSocketTransport.get()));
|
||||
|
||||
*tlsSocketControl = nullptr;
|
||||
|
@ -1422,24 +1433,28 @@ void nsHttpConnection::CloseTransaction(nsAHttpTransaction* trans,
|
|||
|
||||
bool nsHttpConnection::CheckCanWrite0RTTData() {
|
||||
MOZ_ASSERT(mTlsHandshaker->EarlyDataAvailable());
|
||||
nsCOMPtr<nsITLSSocketControl> ssl;
|
||||
GetTLSSocketControl(getter_AddRefs(ssl));
|
||||
if (!ssl) {
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
if (!tlsSocketControl) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsITransportSecurityInfo> info(do_QueryInterface(ssl));
|
||||
if (!info) {
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
if (NS_FAILED(
|
||||
tlsSocketControl->GetSecurityInfo(getter_AddRefs(securityInfo)))) {
|
||||
return false;
|
||||
}
|
||||
if (!securityInfo) {
|
||||
return false;
|
||||
}
|
||||
nsAutoCString negotiatedNPN;
|
||||
// If the following code fails means that the handshake is not done
|
||||
// yet, so continue writing 0RTT data.
|
||||
nsresult rv = info->GetNegotiatedNPN(negotiatedNPN);
|
||||
nsresult rv = securityInfo->GetNegotiatedNPN(negotiatedNPN);
|
||||
if (NS_FAILED(rv)) {
|
||||
return true;
|
||||
}
|
||||
bool earlyDataAccepted = false;
|
||||
rv = ssl->GetEarlyDataAccepted(&earlyDataAccepted);
|
||||
rv = tlsSocketControl->GetEarlyDataAccepted(&earlyDataAccepted);
|
||||
// If 0RTT data is accepted we can continue writing data,
|
||||
// if it is reject stop writing more data.
|
||||
return NS_SUCCEEDED(rv) && earlyDataAccepted;
|
||||
|
@ -2260,27 +2275,33 @@ void nsHttpConnection::HandshakeDoneInternal() {
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITLSSocketControl> ssl;
|
||||
GetTLSSocketControl(getter_AddRefs(ssl));
|
||||
if (!ssl) {
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
if (!tlsSocketControl) {
|
||||
mTlsHandshaker->FinishNPNSetup(false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITransportSecurityInfo> info(do_QueryInterface(ssl));
|
||||
if (!info) {
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
if (NS_FAILED(
|
||||
tlsSocketControl->GetSecurityInfo(getter_AddRefs(securityInfo)))) {
|
||||
mTlsHandshaker->FinishNPNSetup(false, false);
|
||||
return;
|
||||
}
|
||||
if (!securityInfo) {
|
||||
mTlsHandshaker->FinishNPNSetup(false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString negotiatedNPN;
|
||||
DebugOnly<nsresult> rvDebug = info->GetNegotiatedNPN(negotiatedNPN);
|
||||
DebugOnly<nsresult> rvDebug = securityInfo->GetNegotiatedNPN(negotiatedNPN);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rvDebug));
|
||||
|
||||
bool earlyDataAccepted = false;
|
||||
if (mTlsHandshaker->EarlyDataUsed()) {
|
||||
// Check if early data has been accepted.
|
||||
nsresult rvEarlyData = ssl->GetEarlyDataAccepted(&earlyDataAccepted);
|
||||
nsresult rvEarlyData =
|
||||
tlsSocketControl->GetEarlyDataAccepted(&earlyDataAccepted);
|
||||
LOG(
|
||||
("nsHttpConnection::HandshakeDone [this=%p] - early data "
|
||||
"that was sent during 0RTT %s been accepted [rv=%" PRIx32 "].",
|
||||
|
@ -2319,7 +2340,7 @@ void nsHttpConnection::HandshakeDoneInternal() {
|
|||
}
|
||||
|
||||
int16_t tlsVersion;
|
||||
ssl->GetSSLVersionUsed(&tlsVersion);
|
||||
tlsSocketControl->GetSSLVersionUsed(&tlsVersion);
|
||||
mConnInfo->SetLessThanTls13(
|
||||
(tlsVersion < nsITLSSocketControl::TLS_VERSION_1_3) &&
|
||||
(tlsVersion != nsITLSSocketControl::SSL_VERSION_UNKNOWN));
|
||||
|
@ -2337,18 +2358,19 @@ void nsHttpConnection::HandshakeDoneInternal() {
|
|||
const SpdyInformation* info = gHttpHandler->SpdyInfo();
|
||||
if (negotiatedNPN.Equals(info->VersionString)) {
|
||||
if (mTransaction) {
|
||||
StartSpdy(ssl, info->Version);
|
||||
StartSpdy(tlsSocketControl, info->Version);
|
||||
} else {
|
||||
LOG(
|
||||
("nsHttpConnection::HandshakeDone [this=%p] set "
|
||||
"mContinueHandshakeDone",
|
||||
this));
|
||||
RefPtr<nsHttpConnection> self = this;
|
||||
mContinueHandshakeDone = [self = RefPtr{this}, ssl(ssl),
|
||||
mContinueHandshakeDone = [self = RefPtr{this},
|
||||
tlsSocketControl(tlsSocketControl),
|
||||
info(info->Version)]() {
|
||||
LOG(("nsHttpConnection do mContinueHandshakeDone [this=%p]",
|
||||
self.get()));
|
||||
self->StartSpdy(ssl, info);
|
||||
self->StartSpdy(tlsSocketControl, info);
|
||||
self->mTlsHandshaker->FinishNPNSetup(true, true);
|
||||
};
|
||||
return;
|
||||
|
@ -2367,7 +2389,7 @@ void nsHttpConnection::HandshakeDoneInternal() {
|
|||
("nsHttpConnection::HandshakeDone [this=%p] - finishing "
|
||||
"StartSpdy for 0rtt spdy session %p",
|
||||
this, mSpdySession.get()));
|
||||
StartSpdy(ssl, mSpdySession->SpdyVersion());
|
||||
StartSpdy(tlsSocketControl, mSpdySession->SpdyVersion());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "ConnectionHandle.h"
|
||||
#include "HttpConnectionUDP.h"
|
||||
#include "NullHttpTransaction.h"
|
||||
#include "SpeculativeTransaction.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
|
@ -28,10 +31,11 @@
|
|||
#include "nsHttpHandler.h"
|
||||
#include "nsIClassOfService.h"
|
||||
#include "nsIDNSByTypeRecord.h"
|
||||
#include "nsIDNSRecord.h"
|
||||
#include "nsIDNSListener.h"
|
||||
#include "nsIDNSRecord.h"
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsIRequestContext.h"
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsISocketTransportService.h"
|
||||
|
@ -39,11 +43,11 @@
|
|||
#include "nsIXPConnect.h"
|
||||
#include "nsInterfaceRequestorAgg.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetSegmentUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "ConnectionHandle.h"
|
||||
#include "HttpConnectionUDP.h"
|
||||
#include "SpeculativeTransaction.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
namespace mozilla::net {
|
||||
|
||||
|
@ -2475,8 +2479,42 @@ void nsHttpConnectionMgr::OnMsgCompleteUpgrade(int32_t, ARefBase* param) {
|
|||
}
|
||||
|
||||
RefPtr<nsCompleteUpgradeData> upgradeData(data);
|
||||
auto transportAvailableFunc = [upgradeData{std::move(upgradeData)},
|
||||
aRv(rv)]() {
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStream> socketIn;
|
||||
nsCOMPtr<nsIAsyncOutputStream> socketOut;
|
||||
|
||||
// If this is for JS, the input and output sockets need to be piped over the
|
||||
// socket thread. Otherwise, the JS may attempt to read and/or write the
|
||||
// sockets on the main thread, which could cause network I/O on the main
|
||||
// thread. This is particularly bad in the case of TLS connections, because
|
||||
// PSM and NSS rely on those connections only being used on the socket
|
||||
// thread.
|
||||
if (data->mJsWrapped) {
|
||||
nsCOMPtr<nsIAsyncInputStream> pipeIn;
|
||||
uint32_t segsize = 0;
|
||||
uint32_t segcount = 0;
|
||||
net_ResolveSegmentParams(segsize, segcount);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(socketOut), true, true,
|
||||
segsize, segcount);
|
||||
rv = NS_AsyncCopy(pipeIn, data->mSocketOut, gSocketTransportService,
|
||||
NS_ASYNCCOPY_VIA_READSEGMENTS, segsize);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncOutputStream> pipeOut;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_NewPipe2(getter_AddRefs(socketIn), getter_AddRefs(pipeOut), true, true,
|
||||
segsize, segcount);
|
||||
rv = NS_AsyncCopy(data->mSocketIn, pipeOut, gSocketTransportService,
|
||||
NS_ASYNCCOPY_VIA_WRITESEGMENTS, segsize);
|
||||
}
|
||||
} else {
|
||||
socketIn = upgradeData->mSocketIn;
|
||||
socketOut = upgradeData->mSocketOut;
|
||||
}
|
||||
|
||||
auto transportAvailableFunc = [upgradeData{std::move(upgradeData)}, socketIn,
|
||||
socketOut, aRv(rv)]() {
|
||||
// Handle any potential previous errors first
|
||||
// and call OnUpgradeFailed if necessary.
|
||||
nsresult rv = aRv;
|
||||
|
@ -2493,8 +2531,7 @@ void nsHttpConnectionMgr::OnMsgCompleteUpgrade(int32_t, ARefBase* param) {
|
|||
}
|
||||
|
||||
rv = upgradeData->mUpgradeListener->OnTransportAvailable(
|
||||
upgradeData->mSocketTransport, upgradeData->mSocketIn,
|
||||
upgradeData->mSocketOut);
|
||||
upgradeData->mSocketTransport, socketIn, socketOut);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(
|
||||
("nsHttpConnectionMgr::OnMsgCompleteUpgrade OnTransportAvailable "
|
||||
|
|
|
@ -746,8 +746,10 @@ nsresult nsHttpTransaction::ReadSegments(nsAHttpSegmentReader* reader,
|
|||
mConnected = true;
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
mConnection->GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
MutexAutoLock lock(mLock);
|
||||
mTLSSocketControl = tlsSocketControl;
|
||||
if (tlsSocketControl) {
|
||||
MutexAutoLock lock(mLock);
|
||||
tlsSocketControl->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||
}
|
||||
}
|
||||
|
||||
mDeferredSendProgress = false;
|
||||
|
@ -989,9 +991,7 @@ bool nsHttpTransaction::DataSentToChildProcess() { return false; }
|
|||
|
||||
already_AddRefed<nsITransportSecurityInfo> nsHttpTransaction::SecurityInfo() {
|
||||
MutexAutoLock lock(mLock);
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo(
|
||||
do_QueryInterface(mTLSSocketControl));
|
||||
return securityInfo.forget();
|
||||
return do_AddRef(mSecurityInfo);
|
||||
}
|
||||
|
||||
bool nsHttpTransaction::HasStickyConnection() const {
|
||||
|
@ -1333,19 +1333,16 @@ bool nsHttpTransaction::ShouldRestartOn0RttError(nsresult reason) {
|
|||
mEarlyDataWasAvailable && SecurityErrorThatMayNeedRestart(reason);
|
||||
}
|
||||
|
||||
static void MaybeRemoveSSLToken(nsITLSSocketControl* aSocketControl) {
|
||||
static void MaybeRemoveSSLToken(nsITransportSecurityInfo* aSecurityInfo) {
|
||||
if (!StaticPrefs::
|
||||
network_http_remove_resumption_token_when_early_data_failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITransportSecurityInfo> info(do_QueryInterface(aSocketControl));
|
||||
if (!info) {
|
||||
if (!aSecurityInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString key;
|
||||
info->GetPeerId(key);
|
||||
aSecurityInfo->GetPeerId(key);
|
||||
nsresult rv = SSLTokensCache::RemoveAll(key);
|
||||
LOG(("RemoveSSLToken [key=%s, rv=%" PRIx32 "]", key.get(),
|
||||
static_cast<uint32_t>(rv)));
|
||||
|
@ -1415,8 +1412,10 @@ void nsHttpTransaction::Close(nsresult reason) {
|
|||
// Try to get TLSSocketControl for this transaction.
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
mConnection->GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
MutexAutoLock lock(mLock);
|
||||
mTLSSocketControl = tlsSocketControl;
|
||||
if (tlsSocketControl) {
|
||||
MutexAutoLock lock(mLock);
|
||||
tlsSocketControl->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
mConnected = false;
|
||||
|
@ -1781,13 +1780,14 @@ nsresult nsHttpTransaction::Restart() {
|
|||
if (seekable) seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
|
||||
if (mDoNotTryEarlyData) {
|
||||
MaybeRemoveSSLToken(mTLSSocketControl);
|
||||
MutexAutoLock lock(mLock);
|
||||
MaybeRemoveSSLToken(mSecurityInfo);
|
||||
}
|
||||
|
||||
// clear old connection state...
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
mTLSSocketControl = nullptr;
|
||||
mSecurityInfo = nullptr;
|
||||
}
|
||||
|
||||
if (mConnection) {
|
||||
|
@ -2991,8 +2991,10 @@ nsresult nsHttpTransaction::Finish0RTT(bool aRestart,
|
|||
mConnected = true;
|
||||
nsCOMPtr<nsITLSSocketControl> tlsSocketControl;
|
||||
mConnection->GetTLSSocketControl(getter_AddRefs(tlsSocketControl));
|
||||
MutexAutoLock lock(mLock);
|
||||
mTLSSocketControl = tlsSocketControl;
|
||||
if (tlsSocketControl) {
|
||||
MutexAutoLock lock(mLock);
|
||||
tlsSocketControl->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ class nsHttpTransaction final : public nsAHttpTransaction,
|
|||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsITransportEventSink> mTransportSink;
|
||||
nsCOMPtr<nsIEventTarget> mConsumerTarget;
|
||||
nsCOMPtr<nsITLSSocketControl> mTLSSocketControl;
|
||||
nsCOMPtr<nsITransportSecurityInfo> mSecurityInfo;
|
||||
nsCOMPtr<nsIAsyncInputStream> mPipeIn;
|
||||
nsCOMPtr<nsIAsyncOutputStream> mPipeOut;
|
||||
nsCOMPtr<nsIRequestContext> mRequestContext;
|
||||
|
|
|
@ -1,40 +1,45 @@
|
|||
#include "gtest/gtest.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "CertVerifier.h"
|
||||
#include "CommonSocketControl.h"
|
||||
#include "SSLTokensCache.h"
|
||||
#include "TransportSecurityInfo.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "SSLTokensCache.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
static already_AddRefed<nsITransportSecurityInfo> createDummySecInfo() {
|
||||
// clang-format off
|
||||
nsCString base64Serialization(
|
||||
"FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAQAAgAAAAAAAAAAAAAAAAAAAAA"
|
||||
"B4vFIJp5wRkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8F+O2DZM7ZTG6GukivU8OT5gAAAAIAAAWpMII"
|
||||
"FpTCCBI2gAwIBAgIQD4svsaKEC+QtqtsU2TF8ITANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUN"
|
||||
"lcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFN"
|
||||
"lcnZlciBDQTAeFw0xNTAyMjMwMDAwMDBaFw0xNjAzMDIxMjAwMDBaMGoxCzAJBgNVBAYTAlVTMRYwFAYDVQQHEw1TYW4gRnJhbmN"
|
||||
"pc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRUwEwYDVQQKEwxGYXN0bHksIEluYy4xFzAVBgNVBAMTDnd3dy5naXRodWIuY29tMII"
|
||||
"BIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+9WUCgrgUNwP/JC3cUefLAXeDpq8Ko/U8p8IRvny0Ri0I6Uq0t+RP/nF0LJ"
|
||||
"Avda8QHYujdgeDTePepBX7+OiwBFhA0YO+rM3C2Z8IRaN/i9eLln+Yyc68+1z+E10s1EXdZrtDGvN6MHqygGsdfkXKfBLUJ1BZEh"
|
||||
"s9sBnfcjq3kh5gZdBArdG9l5NpdmQhtceaFGsPiWuJxGxRzS4i95veUHWkhMpEYDEEBdcDGxqArvQCvzSlngdttQCfx8OUkBTb3B"
|
||||
"A2okpTwwJfqPsxVetA6qR7UNc+fVb6KHwvm0bzi2rQ3xw3D/syRHwdMkpoVDQPCk43H9WufgfBKRen87dFwIDAQABo4ICPzCCAjs"
|
||||
"wHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFGS/RLNGCZvPWh1xSaIEcouINIQjMHsGA1UdEQR0MHK"
|
||||
"CDnd3dy5naXRodWIuY29tggpnaXRodWIuY29tggwqLmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvgglnaXRodWIuaW+CFyouZ2l0aHV"
|
||||
"idXNlcmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwM"
|
||||
"BBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzMuY3J"
|
||||
"sMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzMuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb"
|
||||
"9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggrBgEFBQc"
|
||||
"wAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUN"
|
||||
"lcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAc4dbVmuKvyI7"
|
||||
"KZ4Txk+ZqcAYToJGKUIVaPL94e5SZGweUisjaCbplAOihnf6Mxt8n6vnuH2IsCaz2NRHqhdcosjT3CwAiJpJNkXPKWVL/txgdSTV"
|
||||
"2cqB1GG4esFOalvI52dzn+J4fTIYZvNF+AtGyHSLm2XRXYZCw455laUKf6Sk9RDShDgUvzhOKL4GXfTwKXv12MyMknJybH8UCpjC"
|
||||
"HZmFBVHMcUN/87HsQo20PdOekeEvkjrrMIxW+gxw22Yb67yF/qKgwrWr+43bLN709iyw+LWiU7sQcHL2xk9SYiWQDj2tYz2soObV"
|
||||
"QYTJm0VUZMEVFhtALq46cx92Zu4vFwC8AAwAAAAABAQAA");
|
||||
// clang-format on
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
EXPECT_TRUE(NS_SUCCEEDED(mozilla::psm::TransportSecurityInfo::Read(
|
||||
base64Serialization, getter_AddRefs(securityInfo))));
|
||||
return securityInfo.forget();
|
||||
static already_AddRefed<CommonSocketControl> createDummySocketControl() {
|
||||
nsCOMPtr<nsIX509CertDB> certDB(do_GetService(NS_X509CERTDB_CONTRACTID));
|
||||
EXPECT_TRUE(certDB);
|
||||
nsLiteralCString base64(
|
||||
"MIIBbjCCARWgAwIBAgIUOyCxVVqw03yUxKSfSojsMF8K/"
|
||||
"ikwCgYIKoZIzj0EAwIwHTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2azFfMjU2MCIYDzIwMjAxM"
|
||||
"TI3MDAwMDAwWhgPMjAyMzAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfM"
|
||||
"jU2LXJvb3Rfc2VjcDI1NmsxXzI1NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/"
|
||||
"u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/"
|
||||
"LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGTkNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMB"
|
||||
"Af8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0cAMEQCIFuwodUwyOUnIR4KN5ZCSrU7y4iz"
|
||||
"4/1EWRdHm5kWKi8dAiB6Ixn9sw3uBVbyxnQKYqGnOwM+qLOkJK0W8XkIE3n5sg==");
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
EXPECT_TRUE(NS_SUCCEEDED(
|
||||
certDB->ConstructX509FromBase64(base64, getter_AddRefs(cert))));
|
||||
EXPECT_TRUE(cert);
|
||||
nsTArray<nsTArray<uint8_t>> succeededCertChain;
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
nsTArray<uint8_t> certDER;
|
||||
EXPECT_TRUE(NS_SUCCEEDED(cert->GetRawDER(certDER)));
|
||||
succeededCertChain.AppendElement(std::move(certDER));
|
||||
}
|
||||
RefPtr<CommonSocketControl> socketControl(
|
||||
new CommonSocketControl(nsLiteralCString("example.com"), 433, 0));
|
||||
socketControl->SetServerCert(cert, mozilla::psm::EVStatus::NotEV);
|
||||
socketControl->SetSucceededCertChain(std::move(succeededCertChain));
|
||||
return socketControl.forget();
|
||||
}
|
||||
|
||||
static auto MakeTestData(const size_t aDataSize) {
|
||||
|
@ -45,10 +50,10 @@ static auto MakeTestData(const size_t aDataSize) {
|
|||
}
|
||||
|
||||
static void putToken(const nsACString& aKey, uint32_t aSize) {
|
||||
nsCOMPtr<nsITransportSecurityInfo> secInfo = createDummySecInfo();
|
||||
RefPtr<CommonSocketControl> socketControl = createDummySocketControl();
|
||||
nsTArray<uint8_t> token = MakeTestData(aSize);
|
||||
nsresult rv = mozilla::net::SSLTokensCache::Put(aKey, token.Elements(), aSize,
|
||||
secInfo, aSize);
|
||||
socketControl, aSize);
|
||||
ASSERT_EQ(rv, NS_OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,9 @@ function socketAccepted(socket, transport) {
|
|||
streamIn = transport
|
||||
.openInputStream(0, SEGMENT_SIZE, SEGMENT_COUNT)
|
||||
.QueryInterface(Ci.nsIAsyncInputStream);
|
||||
streamOut = transport.openOutputStream(0, 0, 0);
|
||||
streamOut = transport
|
||||
.openOutputStream(0, 0, 0)
|
||||
.QueryInterface(Ci.nsIAsyncOutputStream);
|
||||
|
||||
streamIn.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
|
||||
} catch (e) {
|
||||
|
|
|
@ -8,44 +8,127 @@
|
|||
|
||||
#include "PublicKeyPinningService.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "SharedSSLState.h"
|
||||
#include "sslt.h"
|
||||
#include "ssl.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsICertOverrideService.h"
|
||||
#include "nsISocketProvider.h"
|
||||
#include "nsITlsHandshakeListener.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsNSSHelper.h"
|
||||
#include "ssl.h"
|
||||
#include "sslt.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
extern LazyLogModule gPIPNSSLog;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(CommonSocketControl, TransportSecurityInfo,
|
||||
nsITLSSocketControl)
|
||||
NS_IMPL_ISUPPORTS(CommonSocketControl, nsITLSSocketControl)
|
||||
|
||||
CommonSocketControl::CommonSocketControl(uint32_t aProviderFlags)
|
||||
: mHandshakeCompleted(false),
|
||||
CommonSocketControl::CommonSocketControl(const nsCString& aHostName,
|
||||
int32_t aPort, uint32_t aProviderFlags)
|
||||
: mHostName(aHostName),
|
||||
mPort(aPort),
|
||||
mOriginAttributes(),
|
||||
mCanceled(false),
|
||||
mSessionCacheInfo(),
|
||||
mHandshakeCompleted(false),
|
||||
mJoined(false),
|
||||
mSentClientCert(false),
|
||||
mFailedVerification(false),
|
||||
mSSLVersionUsed(nsITLSSocketControl::SSL_VERSION_UNKNOWN),
|
||||
mProviderFlags(aProviderFlags) {}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetNotificationCallbacks(
|
||||
nsIInterfaceRequestor** aCallbacks) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
*aCallbacks = mCallbacks;
|
||||
NS_IF_ADDREF(*aCallbacks);
|
||||
return NS_OK;
|
||||
mProviderFlags(aProviderFlags),
|
||||
mSecurityState(0),
|
||||
mErrorCode(0),
|
||||
mFailedCertChain(),
|
||||
mServerCert(nullptr),
|
||||
mSucceededCertChain(),
|
||||
mCipherSuite(),
|
||||
mKeaGroupName(),
|
||||
mSignatureSchemeName(),
|
||||
mProtocolVersion(),
|
||||
mCertificateTransparencyStatus(0),
|
||||
mIsAcceptedEch(),
|
||||
mIsDelegatedCredential(),
|
||||
mOverridableErrorCategory(),
|
||||
mMadeOCSPRequests(false),
|
||||
mUsedPrivateDNS(false),
|
||||
mIsEV(),
|
||||
mNPNCompleted(false),
|
||||
mNegotiatedNPN(),
|
||||
mResumed(false),
|
||||
mIsBuiltCertChainRootBuiltInRoot(false),
|
||||
mPeerId() {
|
||||
#ifdef DEBUG
|
||||
mOwningThread = PR_GetCurrentThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::SetNotificationCallbacks(
|
||||
nsIInterfaceRequestor* aCallbacks) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mCallbacks = aCallbacks;
|
||||
return NS_OK;
|
||||
void CommonSocketControl::SetStatusErrorBits(
|
||||
const nsCOMPtr<nsIX509Cert>& cert,
|
||||
nsITransportSecurityInfo::OverridableErrorCategory
|
||||
overridableErrorCategory) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
SetServerCert(cert, mozilla::psm::EVStatus::NotEV);
|
||||
mOverridableErrorCategory = Some(overridableErrorCategory);
|
||||
}
|
||||
|
||||
static void CreateCertChain(nsTArray<RefPtr<nsIX509Cert>>& aOutput,
|
||||
nsTArray<nsTArray<uint8_t>>&& aCertList) {
|
||||
nsTArray<nsTArray<uint8_t>> certList = std::move(aCertList);
|
||||
aOutput.Clear();
|
||||
for (auto& certBytes : certList) {
|
||||
RefPtr<nsIX509Cert> cert = new nsNSSCertificate(std::move(certBytes));
|
||||
aOutput.AppendElement(cert);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonSocketControl::SetServerCert(
|
||||
const nsCOMPtr<nsIX509Cert>& aServerCert,
|
||||
mozilla::psm::EVStatus aEVStatus) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mServerCert = aServerCert;
|
||||
mIsEV = Some(aEVStatus == mozilla::psm::EVStatus::EV);
|
||||
}
|
||||
|
||||
void CommonSocketControl::SetSucceededCertChain(
|
||||
nsTArray<nsTArray<uint8_t>>&& aCertList) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return CreateCertChain(mSucceededCertChain, std::move(aCertList));
|
||||
}
|
||||
|
||||
void CommonSocketControl::SetFailedCertChain(
|
||||
nsTArray<nsTArray<uint8_t>>&& aCertList) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return CreateCertChain(mFailedCertChain, std::move(aCertList));
|
||||
}
|
||||
|
||||
void CommonSocketControl::SetCanceled(PRErrorCode errorCode) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
MOZ_ASSERT(errorCode != 0);
|
||||
if (errorCode == 0) {
|
||||
errorCode = SEC_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
mErrorCode = errorCode;
|
||||
mCanceled = true;
|
||||
}
|
||||
|
||||
// NB: GetErrorCode may be called before an error code is set (if ever). In that
|
||||
// case, this returns 0, which is treated as a successful value.
|
||||
int32_t CommonSocketControl::GetErrorCode() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
// We're in an inconsistent state if we think we've been canceled but no error
|
||||
// code was set or we haven't been canceled but an error code was set.
|
||||
MOZ_ASSERT(
|
||||
!((mCanceled && mErrorCode == 0) || (!mCanceled && mErrorCode != 0)));
|
||||
if ((mCanceled && mErrorCode == 0) || (!mCanceled && mErrorCode != 0)) {
|
||||
mCanceled = true;
|
||||
mErrorCode = SEC_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
return mErrorCode;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -76,6 +159,7 @@ NS_IMETHODIMP
|
|||
CommonSocketControl::JoinConnection(const nsACString& npnProtocol,
|
||||
const nsACString& hostname, int32_t port,
|
||||
bool* _retval) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
nsresult rv = TestJoinConnection(npnProtocol, hostname, port, _retval);
|
||||
if (NS_SUCCEEDED(rv) && *_retval) {
|
||||
// All tests pass - this is joinable
|
||||
|
@ -88,15 +172,15 @@ NS_IMETHODIMP
|
|||
CommonSocketControl::TestJoinConnection(const nsACString& npnProtocol,
|
||||
const nsACString& hostname,
|
||||
int32_t port, bool* _retval) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*_retval = false;
|
||||
|
||||
// Different ports may not be joined together
|
||||
if (port != GetPort()) return NS_OK;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
// Make sure NPN has been completed and matches requested npnProtocol
|
||||
if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol)) return NS_OK;
|
||||
// Make sure NPN has been completed and matches requested npnProtocol
|
||||
if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
IsAcceptableForHost(hostname, _retval); // sets _retval
|
||||
|
@ -106,6 +190,7 @@ CommonSocketControl::TestJoinConnection(const nsACString& npnProtocol,
|
|||
NS_IMETHODIMP
|
||||
CommonSocketControl::IsAcceptableForHost(const nsACString& hostname,
|
||||
bool* _retval) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
NS_ENSURE_ARG(_retval);
|
||||
|
||||
*_retval = false;
|
||||
|
@ -138,9 +223,7 @@ CommonSocketControl::IsAcceptableForHost(const nsACString& hostname,
|
|||
}
|
||||
|
||||
// If the cert has error bits (e.g. it is untrusted) then do not join.
|
||||
// The value of mHaveCertErrorBits is only reliable because we know that
|
||||
// the handshake completed.
|
||||
if (mHaveCertErrorBits) {
|
||||
if (mOverridableErrorCategory.isSome()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -152,10 +235,7 @@ CommonSocketControl::IsAcceptableForHost(const nsACString& hostname,
|
|||
// Ensure that the server certificate covers the hostname that would
|
||||
// like to join this connection
|
||||
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
if (NS_FAILED(GetServerCert(getter_AddRefs(cert)))) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIX509Cert> cert(GetServerCert());
|
||||
if (!cert) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -164,8 +244,6 @@ CommonSocketControl::IsAcceptableForHost(const nsACString& hostname,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
// An empty mSucceededCertChain means the server certificate verification
|
||||
// failed before, so don't join in this case.
|
||||
if (mSucceededCertChain.IsEmpty()) {
|
||||
|
@ -224,6 +302,7 @@ CommonSocketControl::IsAcceptableForHost(const nsACString& hostname,
|
|||
}
|
||||
|
||||
void CommonSocketControl::RebuildCertificateInfoFromSSLTokenCache() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mSessionCacheInfo) {
|
||||
MOZ_LOG(
|
||||
gPIPNSSLog, LogLevel::Debug,
|
||||
|
@ -235,7 +314,8 @@ void CommonSocketControl::RebuildCertificateInfoFromSSLTokenCache() {
|
|||
mozilla::net::SessionCacheInfo& info = *mSessionCacheInfo;
|
||||
nsCOMPtr<nsIX509Cert> cert(
|
||||
new nsNSSCertificate(std::move(info.mServerCertBytes)));
|
||||
if (info.mOverridableErrorCategory == OverridableErrorCategory::ERROR_UNSET) {
|
||||
if (info.mOverridableErrorCategory ==
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET) {
|
||||
SetServerCert(cert, info.mEVStatus);
|
||||
} else {
|
||||
SetStatusErrorBits(cert, info.mOverridableErrorCategory);
|
||||
|
@ -266,17 +346,14 @@ CommonSocketControl::GetKEAKeyBits(uint32_t* aKEAKeyBits) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetProviderFlags(uint32_t* aProviderFlags) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aProviderFlags = mProviderFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetProviderTlsFlags(uint32_t* aProviderTlsFlags) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetSSLVersionUsed(int16_t* aSSLVersionUsed) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aSSLVersionUsed = mSSLVersionUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -297,12 +374,14 @@ void CommonSocketControl::SetDenyClientCert(bool aDenyClientCert) {}
|
|||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetClientCertSent(bool* arg) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*arg = mSentClientCert;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetFailedVerification(bool* arg) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*arg = mFailedVerification;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -340,3 +419,102 @@ CommonSocketControl::SetHandshakeCallbackListener(
|
|||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::DisableEarlyData(void) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetPeerId(nsACString& aResult) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mPeerId.IsEmpty()) {
|
||||
aResult.Assign(mPeerId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mProviderFlags &
|
||||
nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
|
||||
mPeerId.AppendLiteral("anon:");
|
||||
}
|
||||
if (mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE) {
|
||||
mPeerId.AppendLiteral("private:");
|
||||
}
|
||||
if (mProviderFlags & nsISocketProvider::BE_CONSERVATIVE) {
|
||||
mPeerId.AppendLiteral("beConservative:");
|
||||
}
|
||||
|
||||
mPeerId.Append(mHostName);
|
||||
mPeerId.Append(':');
|
||||
mPeerId.AppendInt(GetPort());
|
||||
nsAutoCString suffix;
|
||||
mOriginAttributes.CreateSuffix(suffix);
|
||||
mPeerId.Append(suffix);
|
||||
|
||||
aResult.Assign(mPeerId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::GetSecurityInfo(nsITransportSecurityInfo** aSecurityInfo) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
// Make sure peerId is set.
|
||||
nsAutoCString unused;
|
||||
nsresult rv = GetPeerId(unused);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo(new TransportSecurityInfo(
|
||||
mSecurityState, mErrorCode, mFailedCertChain.Clone(), mServerCert,
|
||||
mSucceededCertChain.Clone(), mCipherSuite, mKeaGroupName,
|
||||
mSignatureSchemeName, mProtocolVersion, mCertificateTransparencyStatus,
|
||||
mIsAcceptedEch, mIsDelegatedCredential, mOverridableErrorCategory,
|
||||
mMadeOCSPRequests, mUsedPrivateDNS, mIsEV, mNPNCompleted, mNegotiatedNPN,
|
||||
mResumed, mIsBuiltCertChainRootBuiltInRoot, mPeerId));
|
||||
securityInfo.forget(aSecurityInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CommonSocketControl::AsyncGetSecurityInfo(JSContext* aCx,
|
||||
mozilla::dom::Promise** aPromise) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(aCx);
|
||||
NS_ENSURE_ARG_POINTER(aPromise);
|
||||
|
||||
nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx);
|
||||
if (!globalObject) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
ErrorResult result;
|
||||
RefPtr<mozilla::dom::Promise> promise =
|
||||
mozilla::dom::Promise::Create(globalObject, result);
|
||||
if (result.Failed()) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> runnable(NS_NewRunnableFunction(
|
||||
"CommonSocketControl::AsyncGetSecurityInfo",
|
||||
[promise, self = RefPtr{this}]() mutable {
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
nsresult rv = self->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
nsCOMPtr<nsIRunnable> runnable(NS_NewRunnableFunction(
|
||||
"CommonSocketControl::AsyncGetSecurityInfoResolve",
|
||||
[rv, promise = std::move(promise),
|
||||
securityInfo = std::move(securityInfo)]() {
|
||||
if (NS_FAILED(rv)) {
|
||||
promise->MaybeReject(rv);
|
||||
} else {
|
||||
promise->MaybeResolve(securityInfo);
|
||||
}
|
||||
}));
|
||||
NS_DispatchToMainThread(runnable.forget());
|
||||
}));
|
||||
nsCOMPtr<nsIEventTarget> target(
|
||||
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID));
|
||||
if (!target) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
promise.forget(aPromise);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -7,30 +7,149 @@
|
|||
#ifndef CommonSocketControl_h
|
||||
#define CommonSocketControl_h
|
||||
|
||||
#include "CertVerifier.h"
|
||||
#include "TransportSecurityInfo.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/net/SSLTokensCache.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsITLSSocketControl.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
|
||||
class CommonSocketControl : public mozilla::psm::TransportSecurityInfo,
|
||||
public nsITLSSocketControl {
|
||||
#ifdef DEBUG
|
||||
# include "prthread.h"
|
||||
# define COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD() \
|
||||
MOZ_ASSERT(mOwningThread == PR_GetCurrentThread())
|
||||
#else
|
||||
# define COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD() \
|
||||
do { \
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
// CommonSocketControl is the base class that implements nsITLSSocketControl.
|
||||
// Various concrete TLS socket control implementations inherit from this class.
|
||||
// Currently these implementations consist of NSSSocketControl (a socket
|
||||
// control for NSS) and QuicSocketControl (a socket control for quic).
|
||||
// NB: these classes must only be used on the socket thread (the one exception
|
||||
// being tests that incidentally use CommonSocketControl on the main thread
|
||||
// (and only the main thread)). This is enforced via the macro
|
||||
// COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD() that should be called at the
|
||||
// beginning of every function in this class and all subclasses.
|
||||
class CommonSocketControl : public nsITLSSocketControl {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSITLSSOCKETCONTROL
|
||||
|
||||
explicit CommonSocketControl(uint32_t providerFlags);
|
||||
CommonSocketControl(const nsCString& aHostName, int32_t aPort,
|
||||
uint32_t aProviderFlags);
|
||||
|
||||
uint32_t GetProviderFlags() const { return mProviderFlags; }
|
||||
void SetSSLVersionUsed(int16_t version) { mSSLVersionUsed = version; }
|
||||
// Use "errorCode" 0 to indicate success.
|
||||
virtual void SetCertVerificationResult(PRErrorCode errorCode) {
|
||||
MOZ_ASSERT_UNREACHABLE("Subclasses must override this.");
|
||||
}
|
||||
|
||||
const nsACString& GetHostName() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mHostName;
|
||||
}
|
||||
int32_t GetPort() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mPort;
|
||||
}
|
||||
void SetMadeOCSPRequests(bool aMadeOCSPRequests) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mMadeOCSPRequests = aMadeOCSPRequests;
|
||||
}
|
||||
bool GetMadeOCSPRequests() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mMadeOCSPRequests;
|
||||
}
|
||||
void SetUsedPrivateDNS(bool aUsedPrivateDNS) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mUsedPrivateDNS = aUsedPrivateDNS;
|
||||
}
|
||||
bool GetUsedPrivateDNS() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mUsedPrivateDNS;
|
||||
}
|
||||
|
||||
void SetServerCert(const nsCOMPtr<nsIX509Cert>& aServerCert,
|
||||
mozilla::psm::EVStatus aEVStatus);
|
||||
already_AddRefed<nsIX509Cert> GetServerCert() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return do_AddRef(mServerCert);
|
||||
}
|
||||
bool HasServerCert() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mServerCert != nullptr;
|
||||
}
|
||||
void SetStatusErrorBits(const nsCOMPtr<nsIX509Cert>& cert,
|
||||
nsITransportSecurityInfo::OverridableErrorCategory
|
||||
overridableErrorCategory);
|
||||
bool HasUserOverriddenCertificateError() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mOverridableErrorCategory.isSome() &&
|
||||
*mOverridableErrorCategory !=
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
|
||||
}
|
||||
void SetSucceededCertChain(nsTArray<nsTArray<uint8_t>>&& certList);
|
||||
void SetFailedCertChain(nsTArray<nsTArray<uint8_t>>&& certList);
|
||||
void SetIsBuiltCertChainRootBuiltInRoot(
|
||||
bool aIsBuiltCertChainRootBuiltInRoot) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mIsBuiltCertChainRootBuiltInRoot = aIsBuiltCertChainRootBuiltInRoot;
|
||||
}
|
||||
void SetCertificateTransparencyStatus(
|
||||
uint16_t aCertificateTransparencyStatus) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mCertificateTransparencyStatus = aCertificateTransparencyStatus;
|
||||
}
|
||||
void SetOriginAttributes(const mozilla::OriginAttributes& aOriginAttributes) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mOriginAttributes = aOriginAttributes;
|
||||
}
|
||||
mozilla::OriginAttributes& GetOriginAttributes() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mOriginAttributes;
|
||||
}
|
||||
|
||||
void SetSecurityState(uint32_t aSecurityState) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mSecurityState = aSecurityState;
|
||||
}
|
||||
void SetResumed(bool aResumed) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mResumed = aResumed;
|
||||
}
|
||||
|
||||
uint32_t GetProviderFlags() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mProviderFlags;
|
||||
}
|
||||
void SetSSLVersionUsed(uint16_t version) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mSSLVersionUsed = version;
|
||||
}
|
||||
void SetSessionCacheInfo(mozilla::net::SessionCacheInfo&& aInfo) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mSessionCacheInfo.reset();
|
||||
mSessionCacheInfo.emplace(std::move(aInfo));
|
||||
}
|
||||
void RebuildCertificateInfoFromSSLTokenCache();
|
||||
void SetCanceled(PRErrorCode errorCode);
|
||||
bool IsCanceled() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mCanceled;
|
||||
}
|
||||
int32_t GetErrorCode();
|
||||
|
||||
protected:
|
||||
~CommonSocketControl() = default;
|
||||
virtual ~CommonSocketControl() = default;
|
||||
|
||||
nsCString mHostName;
|
||||
int32_t mPort;
|
||||
mozilla::OriginAttributes mOriginAttributes;
|
||||
|
||||
bool mCanceled;
|
||||
mozilla::Maybe<mozilla::net::SessionCacheInfo> mSessionCacheInfo;
|
||||
bool mHandshakeCompleted;
|
||||
bool mJoined;
|
||||
|
@ -38,6 +157,35 @@ class CommonSocketControl : public mozilla::psm::TransportSecurityInfo,
|
|||
bool mFailedVerification;
|
||||
uint16_t mSSLVersionUsed;
|
||||
uint32_t mProviderFlags;
|
||||
|
||||
// Fields used to build a TransportSecurityInfo
|
||||
uint32_t mSecurityState;
|
||||
PRErrorCode mErrorCode;
|
||||
// Peer cert chain for failed connections.
|
||||
nsTArray<RefPtr<nsIX509Cert>> mFailedCertChain;
|
||||
nsCOMPtr<nsIX509Cert> mServerCert;
|
||||
nsTArray<RefPtr<nsIX509Cert>> mSucceededCertChain;
|
||||
mozilla::Maybe<uint16_t> mCipherSuite;
|
||||
mozilla::Maybe<nsCString> mKeaGroupName;
|
||||
mozilla::Maybe<nsCString> mSignatureSchemeName;
|
||||
mozilla::Maybe<uint16_t> mProtocolVersion;
|
||||
uint16_t mCertificateTransparencyStatus;
|
||||
mozilla::Maybe<bool> mIsAcceptedEch;
|
||||
mozilla::Maybe<bool> mIsDelegatedCredential;
|
||||
mozilla::Maybe<nsITransportSecurityInfo::OverridableErrorCategory>
|
||||
mOverridableErrorCategory;
|
||||
bool mMadeOCSPRequests;
|
||||
bool mUsedPrivateDNS;
|
||||
mozilla::Maybe<bool> mIsEV;
|
||||
bool mNPNCompleted;
|
||||
nsCString mNegotiatedNPN;
|
||||
bool mResumed;
|
||||
bool mIsBuiltCertChainRootBuiltInRoot;
|
||||
nsCString mPeerId;
|
||||
|
||||
#ifdef DEBUG
|
||||
const PRThread* mOwningThread;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // CommonSocketControl_h
|
||||
|
|
|
@ -6,18 +6,19 @@
|
|||
|
||||
#include "NSSSocketControl.h"
|
||||
|
||||
#include "nsISocketProvider.h"
|
||||
#include "ssl.h"
|
||||
#include "sslexp.h"
|
||||
|
||||
NSSSocketControl::NSSSocketControl(SharedSSLState& aState,
|
||||
NSSSocketControl::NSSSocketControl(const nsCString& aHostName, int32_t aPort,
|
||||
SharedSSLState& aState,
|
||||
uint32_t providerFlags,
|
||||
uint32_t providerTlsFlags)
|
||||
: CommonSocketControl(providerFlags),
|
||||
: CommonSocketControl(aHostName, aPort, providerFlags),
|
||||
mFd(nullptr),
|
||||
mCertVerificationState(before_cert_verification),
|
||||
mSharedState(aState),
|
||||
mForSTARTTLS(false),
|
||||
mTLSVersionRange{0, 0},
|
||||
mHandshakePending(true),
|
||||
mPreliminaryHandshakeDone(false),
|
||||
mEarlyDataAccepted(false),
|
||||
|
@ -35,50 +36,41 @@ NSSSocketControl::NSSSocketControl(SharedSSLState& aState,
|
|||
mMACAlgorithmUsed(nsITLSSocketControl::SSL_MAC_UNKNOWN),
|
||||
mProviderTlsFlags(providerTlsFlags),
|
||||
mSocketCreationTimestamp(TimeStamp::Now()),
|
||||
mPlaintextBytesRead(0) {
|
||||
mTLSVersionRange.min = 0;
|
||||
mTLSVersionRange.max = 0;
|
||||
}
|
||||
|
||||
NSSSocketControl::~NSSSocketControl() = default;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(NSSSocketControl, TransportSecurityInfo,
|
||||
nsITLSSocketControl)
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetProviderTlsFlags(uint32_t* aProviderTlsFlags) {
|
||||
*aProviderTlsFlags = mProviderTlsFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
mPlaintextBytesRead(0) {}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetKEAUsed(int16_t* aKea) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aKea = mKEAUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetKEAKeyBits(uint32_t* aKeyBits) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aKeyBits = mKEAKeyBits;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetSSLVersionOffered(int16_t* aSSLVersionOffered) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aSSLVersionOffered = mTLSVersionRange.max;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetMACAlgorithmUsed(int16_t* aMac) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aMac = mMACAlgorithmUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void NSSSocketControl::NoteTimeUntilReady() {
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mNotedTimeUntilReady) return;
|
||||
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (mNotedTimeUntilReady) {
|
||||
return;
|
||||
}
|
||||
mNotedTimeUntilReady = true;
|
||||
|
||||
auto timestampNow = TimeStamp::Now();
|
||||
|
@ -113,6 +105,7 @@ void NSSSocketControl::NoteTimeUntilReady() {
|
|||
}
|
||||
|
||||
void NSSSocketControl::SetHandshakeCompleted() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mHandshakeCompleted) {
|
||||
enum HandshakeType {
|
||||
Resumption = 1,
|
||||
|
@ -126,11 +119,12 @@ void NSSSocketControl::SetHandshakeCompleted() {
|
|||
: mFalseStartCallbackCalled
|
||||
? ChoseNotToFalseStart
|
||||
: NotAllowedToFalseStart;
|
||||
MutexAutoLock lock(mMutex);
|
||||
// This will include TCP and proxy tunnel wait time
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::SSL_TIME_UNTIL_HANDSHAKE_FINISHED_KEYED_BY_KA, mKeaGroup,
|
||||
mSocketCreationTimestamp, TimeStamp::Now());
|
||||
if (mKeaGroupName.isSome()) {
|
||||
Telemetry::AccumulateTimeDelta(
|
||||
Telemetry::SSL_TIME_UNTIL_HANDSHAKE_FINISHED_KEYED_BY_KA,
|
||||
*mKeaGroupName, mSocketCreationTimestamp, TimeStamp::Now());
|
||||
}
|
||||
|
||||
// If the handshake is completed for the first time from just 1 callback
|
||||
// that means that TLS session resumption must have been used.
|
||||
|
@ -167,7 +161,7 @@ void NSSSocketControl::SetHandshakeCompleted() {
|
|||
}
|
||||
|
||||
void NSSSocketControl::SetNegotiatedNPN(const char* value, uint32_t length) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!value) {
|
||||
mNegotiatedNPN.Truncate();
|
||||
} else {
|
||||
|
@ -180,6 +174,7 @@ void NSSSocketControl::SetNegotiatedNPN(const char* value, uint32_t length) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetAlpnEarlySelection(nsACString& aAlpnSelected) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
aAlpnSelected.Truncate();
|
||||
|
||||
SSLPreliminaryChannelInfo info;
|
||||
|
@ -208,22 +203,29 @@ NSSSocketControl::GetAlpnEarlySelection(nsACString& aAlpnSelected) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetEarlyDataAccepted(bool* aAccepted) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aAccepted = mEarlyDataAccepted;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void NSSSocketControl::SetEarlyDataAccepted(bool aAccepted) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mEarlyDataAccepted = aAccepted;
|
||||
}
|
||||
|
||||
bool NSSSocketControl::GetDenyClientCert() { return mDenyClientCert; }
|
||||
bool NSSSocketControl::GetDenyClientCert() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mDenyClientCert;
|
||||
}
|
||||
|
||||
void NSSSocketControl::SetDenyClientCert(bool aDenyClientCert) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mDenyClientCert = aDenyClientCert;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::DriveHandshake() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mFd) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -254,20 +256,31 @@ NSSSocketControl::DriveHandshake() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool NSSSocketControl::GetForSTARTTLS() { return mForSTARTTLS; }
|
||||
bool NSSSocketControl::GetForSTARTTLS() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mForSTARTTLS;
|
||||
}
|
||||
|
||||
void NSSSocketControl::SetForSTARTTLS(bool aForSTARTTLS) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mForSTARTTLS = aForSTARTTLS;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::ProxyStartSSL() { return ActivateSSL(); }
|
||||
NSSSocketControl::ProxyStartSSL() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return ActivateSSL();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::StartTLS() { return ActivateSSL(); }
|
||||
NSSSocketControl::StartTLS() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return ActivateSSL();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::SetNPNList(nsTArray<nsCString>& protocolArray) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mFd) return NS_ERROR_FAILURE;
|
||||
|
||||
// the npn list is a concatenated list of 8 bit byte strings.
|
||||
|
@ -290,6 +303,7 @@ NSSSocketControl::SetNPNList(nsTArray<nsCString>& protocolArray) {
|
|||
}
|
||||
|
||||
nsresult NSSSocketControl::ActivateSSL() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (SECSuccess != SSL_OptionSet(mFd, SSL_SECURITY, true))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (SECSuccess != SSL_ResetHandshake(mFd, false)) return NS_ERROR_FAILURE;
|
||||
|
@ -300,16 +314,19 @@ nsresult NSSSocketControl::ActivateSSL() {
|
|||
}
|
||||
|
||||
nsresult NSSSocketControl::GetFileDescPtr(PRFileDesc** aFilePtr) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
*aFilePtr = mFd;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NSSSocketControl::SetFileDescPtr(PRFileDesc* aFilePtr) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mFd = aFilePtr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void NSSSocketControl::SetCertVerificationWaiting() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
// mCertVerificationState may be before_cert_verification for the first
|
||||
// handshake on the connection, or after_cert_verification for subsequent
|
||||
// renegotiation handshakes.
|
||||
|
@ -323,6 +340,7 @@ void NSSSocketControl::SetCertVerificationWaiting() {
|
|||
// attempt to acquire locks that are already held by libssl when it calls
|
||||
// callbacks.
|
||||
void NSSSocketControl::SetCertVerificationResult(PRErrorCode errorCode) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
SetUsedPrivateDNS(GetProviderFlags() & nsISocketProvider::USED_PRIVATE_DNS);
|
||||
MOZ_ASSERT(mCertVerificationState == waiting_for_cert_verification,
|
||||
"Invalid state transition to cert_verification_finished");
|
||||
|
@ -358,6 +376,7 @@ void NSSSocketControl::SetCertVerificationResult(PRErrorCode errorCode) {
|
|||
|
||||
void NSSSocketControl::ClientAuthCertificateSelected(
|
||||
nsTArray<uint8_t>& certBytes, nsTArray<nsTArray<uint8_t>>& certChainBytes) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
// If mFd is nullptr, the connection has been closed already, so we don't
|
||||
// need to do anything here.
|
||||
if (!mFd) {
|
||||
|
@ -406,14 +425,19 @@ void NSSSocketControl::ClientAuthCertificateSelected(
|
|||
sendingClientAuthCert ? cert.release() : nullptr);
|
||||
}
|
||||
|
||||
SharedSSLState& NSSSocketControl::SharedState() { return mSharedState; }
|
||||
SharedSSLState& NSSSocketControl::SharedState() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mSharedState;
|
||||
}
|
||||
|
||||
void NSSSocketControl::SetSharedOwningReference(SharedSSLState* aRef) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mOwningSharedRef = aRef;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::DisableEarlyData() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mFd) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -430,11 +454,13 @@ NSSSocketControl::DisableEarlyData() {
|
|||
NS_IMETHODIMP
|
||||
NSSSocketControl::SetHandshakeCallbackListener(
|
||||
nsITlsHandshakeCallbackListener* callback) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mTlsHandshakeCallback = callback;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRStatus NSSSocketControl::CloseSocketAndDestroy() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
PRFileDesc* popped = PR_PopIOLayer(mFd, PR_TOP_IO_LAYER);
|
||||
MOZ_ASSERT(
|
||||
popped && popped->identity == nsSSLIOLayerHelpers::nsSSLIOLayerIdentity,
|
||||
|
@ -476,12 +502,14 @@ PRStatus NSSSocketControl::CloseSocketAndDestroy() {
|
|||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetEsniTxt(nsACString& aEsniTxt) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
aEsniTxt = mEsniTxt;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::SetEsniTxt(const nsACString& aEsniTxt) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mEsniTxt = aEsniTxt;
|
||||
|
||||
if (mEsniTxt.Length()) {
|
||||
|
@ -508,12 +536,14 @@ NSSSocketControl::SetEsniTxt(const nsACString& aEsniTxt) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetEchConfig(nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
aEchConfig = mEchConfig;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::SetEchConfig(const nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mEchConfig = aEchConfig;
|
||||
|
||||
if (mEchConfig.Length()) {
|
||||
|
@ -533,6 +563,7 @@ NSSSocketControl::SetEchConfig(const nsACString& aEchConfig) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetRetryEchConfig(nsACString& aEchConfig) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mFd) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -549,7 +580,7 @@ NSSSocketControl::GetRetryEchConfig(nsACString& aEchConfig) {
|
|||
|
||||
NS_IMETHODIMP
|
||||
NSSSocketControl::GetPeerId(nsACString& aResult) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mPeerId.IsEmpty()) {
|
||||
aResult.Assign(mPeerId);
|
||||
return NS_OK;
|
||||
|
@ -580,6 +611,7 @@ NSSSocketControl::GetPeerId(nsACString& aResult) {
|
|||
}
|
||||
|
||||
nsresult NSSSocketControl::SetResumptionTokenFromExternalCache() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mFd) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -634,3 +666,15 @@ nsresult NSSSocketControl::SetResumptionTokenFromExternalCache() {
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void NSSSocketControl::SetPreliminaryHandshakeInfo(
|
||||
const SSLChannelInfo& channelInfo, const SSLCipherSuiteInfo& cipherInfo) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mResumed = channelInfo.resumed;
|
||||
mCipherSuite.emplace(channelInfo.cipherSuite);
|
||||
mProtocolVersion.emplace(channelInfo.protocolVersion & 0xFF);
|
||||
mKeaGroupName.emplace(getKeaGroupName(channelInfo.keaGroup));
|
||||
mSignatureSchemeName.emplace(getSignatureName(channelInfo.signatureScheme));
|
||||
mIsDelegatedCredential.emplace(channelInfo.peerDelegCred);
|
||||
mIsAcceptedEch.emplace(channelInfo.echAccepted);
|
||||
}
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
|
||||
class NSSSocketControl final : public CommonSocketControl {
|
||||
public:
|
||||
NSSSocketControl(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags,
|
||||
NSSSocketControl(const nsCString& aHostName, int32_t aPort,
|
||||
mozilla::psm::SharedSSLState& aState, uint32_t providerFlags,
|
||||
uint32_t providerTlsFlags);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(NSSSocketControl, CommonSocketControl);
|
||||
|
||||
void SetForSTARTTLS(bool aForSTARTTLS);
|
||||
bool GetForSTARTTLS();
|
||||
|
@ -23,11 +24,23 @@ class NSSSocketControl final : public CommonSocketControl {
|
|||
nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
|
||||
nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
|
||||
|
||||
bool IsHandshakePending() const { return mHandshakePending; }
|
||||
void SetHandshakeNotPending() { mHandshakePending = false; }
|
||||
bool IsHandshakePending() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mHandshakePending;
|
||||
}
|
||||
void SetHandshakeNotPending() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mHandshakePending = false;
|
||||
}
|
||||
|
||||
void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; }
|
||||
SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; };
|
||||
void SetTLSVersionRange(SSLVersionRange range) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mTLSVersionRange = range;
|
||||
}
|
||||
SSLVersionRange GetTLSVersionRange() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mTLSVersionRange;
|
||||
};
|
||||
|
||||
// From nsITLSSocketControl.
|
||||
NS_IMETHOD ProxyStartSSL(void) override;
|
||||
|
@ -36,10 +49,8 @@ class NSSSocketControl final : public CommonSocketControl {
|
|||
NS_IMETHOD GetAlpnEarlySelection(nsACString& _retval) override;
|
||||
NS_IMETHOD GetEarlyDataAccepted(bool* aEarlyDataAccepted) override;
|
||||
NS_IMETHOD DriveHandshake(void) override;
|
||||
using nsITLSSocketControl::GetKEAUsed;
|
||||
NS_IMETHOD GetKEAUsed(int16_t* aKEAUsed) override;
|
||||
NS_IMETHOD GetKEAKeyBits(uint32_t* aKEAKeyBits) override;
|
||||
NS_IMETHOD GetProviderTlsFlags(uint32_t* aProviderTlsFlags) override;
|
||||
NS_IMETHOD GetSSLVersionOffered(int16_t* aSSLVersionOffered) override;
|
||||
NS_IMETHOD GetMACAlgorithmUsed(int16_t* aMACAlgorithmUsed) override;
|
||||
bool GetDenyClientCert() override;
|
||||
|
@ -60,27 +71,50 @@ class NSSSocketControl final : public CommonSocketControl {
|
|||
void SetEarlyDataAccepted(bool aAccepted);
|
||||
|
||||
void SetHandshakeCompleted();
|
||||
bool IsHandshakeCompleted() const { return mHandshakeCompleted; }
|
||||
bool IsHandshakeCompleted() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mHandshakeCompleted;
|
||||
}
|
||||
void NoteTimeUntilReady();
|
||||
|
||||
void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; }
|
||||
void SetFalseStarted() { mFalseStarted = true; }
|
||||
void SetFalseStartCallbackCalled() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mFalseStartCallbackCalled = true;
|
||||
}
|
||||
void SetFalseStarted() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mFalseStarted = true;
|
||||
}
|
||||
|
||||
// Note that this is only valid *during* a handshake; at the end of the
|
||||
// handshake, it gets reset back to false.
|
||||
void SetFullHandshake() { mIsFullHandshake = true; }
|
||||
bool IsFullHandshake() const { return mIsFullHandshake; }
|
||||
void SetFullHandshake() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mIsFullHandshake = true;
|
||||
}
|
||||
bool IsFullHandshake() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mIsFullHandshake;
|
||||
}
|
||||
|
||||
void UpdateEchExtensionStatus(EchExtensionStatus aEchExtensionStatus) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mEchExtensionStatus = std::max(aEchExtensionStatus, mEchExtensionStatus);
|
||||
}
|
||||
EchExtensionStatus GetEchExtensionStatus() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mEchExtensionStatus;
|
||||
}
|
||||
|
||||
bool GetJoined() { return mJoined; }
|
||||
bool GetJoined() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mJoined;
|
||||
}
|
||||
|
||||
uint32_t GetProviderTlsFlags() const { return mProviderTlsFlags; }
|
||||
uint32_t GetProviderTlsFlags() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mProviderTlsFlags;
|
||||
}
|
||||
|
||||
mozilla::psm::SharedSSLState& SharedState();
|
||||
|
||||
|
@ -100,32 +134,57 @@ class NSSSocketControl final : public CommonSocketControl {
|
|||
|
||||
// for logging only
|
||||
PRBool IsWaitingForCertVerification() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mCertVerificationState == waiting_for_cert_verification;
|
||||
}
|
||||
void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; }
|
||||
void AddPlaintextBytesRead(uint64_t val) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mPlaintextBytesRead += val;
|
||||
}
|
||||
|
||||
bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; }
|
||||
void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; }
|
||||
bool IsPreliminaryHandshakeDone() const {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mPreliminaryHandshakeDone;
|
||||
}
|
||||
void SetPreliminaryHandshakeDone() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mPreliminaryHandshakeDone = true;
|
||||
}
|
||||
|
||||
void SetKEAUsed(uint16_t kea) { mKEAUsed = kea; }
|
||||
void SetKEAUsed(int16_t kea) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mKEAUsed = kea;
|
||||
}
|
||||
|
||||
void SetKEAKeyBits(uint32_t keaBits) { mKEAKeyBits = keaBits; }
|
||||
void SetKEAKeyBits(uint32_t keaBits) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mKEAKeyBits = keaBits;
|
||||
}
|
||||
|
||||
void SetMACAlgorithmUsed(int16_t mac) { mMACAlgorithmUsed = mac; }
|
||||
void SetMACAlgorithmUsed(int16_t mac) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mMACAlgorithmUsed = mac;
|
||||
}
|
||||
|
||||
void SetShortWritePending(int32_t amount, unsigned char data) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mIsShortWritePending = true;
|
||||
mShortWriteOriginalAmount = amount;
|
||||
mShortWritePendingByte = data;
|
||||
}
|
||||
|
||||
bool IsShortWritePending() { return mIsShortWritePending; }
|
||||
bool IsShortWritePending() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return mIsShortWritePending;
|
||||
}
|
||||
|
||||
unsigned char const* GetShortWritePendingByteRef() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
return &mShortWritePendingByte;
|
||||
}
|
||||
|
||||
int32_t ResetShortWritePending() {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mIsShortWritePending = false;
|
||||
return mShortWriteOriginalAmount;
|
||||
}
|
||||
|
@ -135,11 +194,13 @@ class NSSSocketControl final : public CommonSocketControl {
|
|||
// as it was previously when we hit the short-write. This is a measure
|
||||
// to make sure we communicate correctly to the consumer.
|
||||
void RememberShortWrittenBuffer(const unsigned char* data) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
mShortWriteBufferCheck =
|
||||
mozilla::MakeUnique<char[]>(mShortWriteOriginalAmount);
|
||||
memcpy(mShortWriteBufferCheck.get(), data, mShortWriteOriginalAmount);
|
||||
}
|
||||
void CheckShortWrittenBuffer(const unsigned char* data, int32_t amount) {
|
||||
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
|
||||
if (!mShortWriteBufferCheck) return;
|
||||
MOZ_ASSERT(amount >= mShortWriteOriginalAmount,
|
||||
"unexpected amount length after short write");
|
||||
|
@ -154,10 +215,11 @@ class NSSSocketControl final : public CommonSocketControl {
|
|||
|
||||
nsresult SetResumptionTokenFromExternalCache();
|
||||
|
||||
protected:
|
||||
virtual ~NSSSocketControl();
|
||||
void SetPreliminaryHandshakeInfo(const SSLChannelInfo& channelInfo,
|
||||
const SSLCipherSuiteInfo& cipherInfo);
|
||||
|
||||
private:
|
||||
~NSSSocketControl() = default;
|
||||
PRFileDesc* mFd;
|
||||
|
||||
CertVerificationState mCertVerificationState;
|
||||
|
|
|
@ -65,11 +65,10 @@
|
|||
//
|
||||
// SSLServerCertVerificationResult must be dispatched to the socket transport
|
||||
// thread because we must only call SSL_* functions on the socket transport
|
||||
// thread since they may do I/O, because many parts of NSSSocketControl (the
|
||||
// subclass of TransportSecurityInfo used when validating certificates during
|
||||
// an SSL handshake) and the PSM NSS I/O layer are not thread-safe, and because
|
||||
// we need the event to interrupt the PR_Poll that may waiting for I/O on the
|
||||
// socket for which we are validating the cert.
|
||||
// thread since they may do I/O, because many parts of NSSSocketControl and the
|
||||
// PSM NSS I/O layer are not thread-safe, and because we need the event to
|
||||
// interrupt the PR_Poll that may waiting for I/O on the socket for which we
|
||||
// are validating the cert.
|
||||
//
|
||||
// When socket process is enabled, libssl is running on socket process. To
|
||||
// perform certificate authentication with CertVerifier, we have to send all
|
||||
|
@ -105,7 +104,6 @@
|
|||
#include "ScopedNSSTypes.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
#include "SharedSSLState.h"
|
||||
#include "TransportSecurityInfo.h"
|
||||
#include "VerifySSLServerCertChild.h"
|
||||
#include "cert.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
@ -383,16 +381,23 @@ static nsresult OverrideAllowedForHost(
|
|||
// Prohibit changing the server cert only if we negotiated SPDY,
|
||||
// in order to support SPDY's cross-origin connection pooling.
|
||||
static SECStatus BlockServerCertChangeForSpdy(
|
||||
NSSSocketControl* infoObject, const UniqueCERTCertificate& serverCert) {
|
||||
if (!infoObject->IsHandshakeCompleted()) {
|
||||
NSSSocketControl* socketControl, const UniqueCERTCertificate& serverCert) {
|
||||
if (!socketControl->IsHandshakeCompleted()) {
|
||||
// first handshake on this connection, not a
|
||||
// renegotiation.
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
// Filter out sockets that did not neogtiate SPDY via NPN
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
nsresult rv = socketControl->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "GetSecurityInfo() failed during renegotiation");
|
||||
if (NS_FAILED(rv) || !securityInfo) {
|
||||
PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
nsAutoCString negotiatedNPN;
|
||||
nsresult rv = infoObject->GetNegotiatedNPN(negotiatedNPN);
|
||||
rv = securityInfo->GetNegotiatedNPN(negotiatedNPN);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv),
|
||||
"GetNegotiatedNPN() failed during renegotiation");
|
||||
|
||||
|
@ -407,8 +412,7 @@ static SECStatus BlockServerCertChangeForSpdy(
|
|||
}
|
||||
|
||||
// Check to see if the cert has actually changed
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
infoObject->GetServerCert(getter_AddRefs(cert));
|
||||
nsCOMPtr<nsIX509Cert> cert(socketControl->GetServerCert());
|
||||
if (!cert) {
|
||||
PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
|
||||
return SECFailure;
|
||||
|
@ -814,7 +818,7 @@ SSLServerCertVerificationJob::Run() {
|
|||
// Takes information needed for cert verification, does some consistency
|
||||
// checks and calls SSLServerCertVerificationJob::Dispatch.
|
||||
SECStatus AuthCertificateHookInternal(
|
||||
TransportSecurityInfo* infoObject, const void* aPtrForLogging,
|
||||
CommonSocketControl* socketControl, const void* aPtrForLogging,
|
||||
const nsACString& hostName, nsTArray<nsTArray<uint8_t>>&& peerCertChain,
|
||||
Maybe<nsTArray<uint8_t>>& stapledOCSPResponse,
|
||||
Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension,
|
||||
|
@ -825,7 +829,7 @@ SECStatus AuthCertificateHookInternal(
|
|||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("[%p] starting AuthCertificateHookInternal\n", aPtrForLogging));
|
||||
|
||||
if (!infoObject || peerCertChain.IsEmpty()) {
|
||||
if (!socketControl || peerCertChain.IsEmpty()) {
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -853,12 +857,12 @@ SECStatus AuthCertificateHookInternal(
|
|||
|
||||
uint64_t addr = reinterpret_cast<uintptr_t>(aPtrForLogging);
|
||||
RefPtr<SSLServerCertVerificationResult> resultTask =
|
||||
new SSLServerCertVerificationResult(infoObject);
|
||||
new SSLServerCertVerificationResult(socketControl);
|
||||
|
||||
if (XRE_IsSocketProcess()) {
|
||||
return RemoteProcessCertVerification(
|
||||
std::move(peerCertChain), hostName, infoObject->GetPort(),
|
||||
infoObject->GetOriginAttributes(), stapledOCSPResponse,
|
||||
std::move(peerCertChain), hostName, socketControl->GetPort(),
|
||||
socketControl->GetOriginAttributes(), stapledOCSPResponse,
|
||||
sctsFromTLSExtension, dcInfo, providerFlags, certVerifierFlags,
|
||||
resultTask);
|
||||
}
|
||||
|
@ -868,8 +872,8 @@ SECStatus AuthCertificateHookInternal(
|
|||
// and we *want* to do certificate verification on a background thread
|
||||
// because of the performance benefits of doing so.
|
||||
return SSLServerCertVerificationJob::Dispatch(
|
||||
addr, infoObject, std::move(peerCertChain), hostName,
|
||||
infoObject->GetPort(), infoObject->GetOriginAttributes(),
|
||||
addr, socketControl, std::move(peerCertChain), hostName,
|
||||
socketControl->GetPort(), socketControl->GetOriginAttributes(),
|
||||
stapledOCSPResponse, sctsFromTLSExtension, dcInfo, providerFlags, Now(),
|
||||
certVerifierFlags, resultTask);
|
||||
}
|
||||
|
@ -983,7 +987,7 @@ SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig,
|
|||
// checks and calls SSLServerCertVerificationJob::Dispatch.
|
||||
// This function is used for Quic.
|
||||
SECStatus AuthCertificateHookWithInfo(
|
||||
TransportSecurityInfo* infoObject, const nsACString& aHostName,
|
||||
CommonSocketControl* socketControl, const nsACString& aHostName,
|
||||
const void* aPtrForLogging, nsTArray<nsTArray<uint8_t>>&& peerCertChain,
|
||||
Maybe<nsTArray<nsTArray<uint8_t>>>& stapledOCSPResponses,
|
||||
Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension, uint32_t providerFlags) {
|
||||
|
@ -1011,7 +1015,7 @@ SECStatus AuthCertificateHookWithInfo(
|
|||
// for Delegated Credentials.
|
||||
Maybe<DelegatedCredentialInfo> dcInfo;
|
||||
|
||||
return AuthCertificateHookInternal(infoObject, aPtrForLogging, aHostName,
|
||||
return AuthCertificateHookInternal(socketControl, aPtrForLogging, aHostName,
|
||||
std::move(peerCertChain),
|
||||
stapledOCSPResponse, sctsFromTLSExtension,
|
||||
dcInfo, providerFlags, certVerifierFlags);
|
||||
|
@ -1020,9 +1024,9 @@ SECStatus AuthCertificateHookWithInfo(
|
|||
NS_IMPL_ISUPPORTS_INHERITED0(SSLServerCertVerificationResult, Runnable)
|
||||
|
||||
SSLServerCertVerificationResult::SSLServerCertVerificationResult(
|
||||
TransportSecurityInfo* infoObject)
|
||||
CommonSocketControl* socketControl)
|
||||
: Runnable("psm::SSLServerCertVerificationResult"),
|
||||
mInfoObject(infoObject),
|
||||
mSocketControl(socketControl),
|
||||
mCertificateTransparencyStatus(0),
|
||||
mEVStatus(EVStatus::NotEV),
|
||||
mSucceeded(false),
|
||||
|
@ -1092,33 +1096,33 @@ SSLServerCertVerificationResult::Run() {
|
|||
SaveIntermediateCerts(mBuiltChain);
|
||||
}
|
||||
|
||||
mInfoObject->SetMadeOCSPRequest(mMadeOCSPRequests);
|
||||
mSocketControl->SetMadeOCSPRequests(mMadeOCSPRequests);
|
||||
|
||||
if (mSucceeded) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("SSLServerCertVerificationResult::Run setting NEW cert"));
|
||||
nsTArray<uint8_t> certBytes(mBuiltChain.ElementAt(0).Clone());
|
||||
nsCOMPtr<nsIX509Cert> cert(new nsNSSCertificate(std::move(certBytes)));
|
||||
mInfoObject->SetServerCert(cert, mEVStatus);
|
||||
mInfoObject->SetSucceededCertChain(std::move(mBuiltChain));
|
||||
mSocketControl->SetServerCert(cert, mEVStatus);
|
||||
mSocketControl->SetSucceededCertChain(std::move(mBuiltChain));
|
||||
|
||||
mInfoObject->SetIsBuiltCertChainRootBuiltInRoot(
|
||||
mSocketControl->SetIsBuiltCertChainRootBuiltInRoot(
|
||||
mIsBuiltCertChainRootBuiltInRoot);
|
||||
mInfoObject->SetCertificateTransparencyStatus(
|
||||
mSocketControl->SetCertificateTransparencyStatus(
|
||||
mCertificateTransparencyStatus);
|
||||
} else {
|
||||
nsTArray<uint8_t> certBytes(mPeerCertChain.ElementAt(0).Clone());
|
||||
nsCOMPtr<nsIX509Cert> cert(new nsNSSCertificate(std::move(certBytes)));
|
||||
// Certificate validation failed; store the peer certificate chain on
|
||||
// infoObject so it can be used for error reporting.
|
||||
mInfoObject->SetFailedCertChain(std::move(mPeerCertChain));
|
||||
// mSocketControl so it can be used for error reporting.
|
||||
mSocketControl->SetFailedCertChain(std::move(mPeerCertChain));
|
||||
if (mOverridableErrorCategory !=
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET) {
|
||||
mInfoObject->SetStatusErrorBits(cert, mOverridableErrorCategory);
|
||||
mSocketControl->SetStatusErrorBits(cert, mOverridableErrorCategory);
|
||||
}
|
||||
}
|
||||
|
||||
mInfoObject->SetCertVerificationResult(mFinalError);
|
||||
mSocketControl->SetCertVerificationResult(mFinalError);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define _SSLSERVERCERTVERIFICATION_H
|
||||
|
||||
#include "CertVerifier.h"
|
||||
#include "CommonSocketControl.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozpkix/pkix.h"
|
||||
|
@ -24,7 +25,6 @@ using namespace mozilla::pkix;
|
|||
namespace mozilla {
|
||||
namespace psm {
|
||||
|
||||
class TransportSecurityInfo;
|
||||
enum class EVStatus : uint8_t;
|
||||
|
||||
SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig,
|
||||
|
@ -34,7 +34,7 @@ SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig,
|
|||
// asynchronous and the info object will be notified when the verification has
|
||||
// completed via SetCertVerificationResult.
|
||||
SECStatus AuthCertificateHookWithInfo(
|
||||
TransportSecurityInfo* infoObject, const nsACString& aHostName,
|
||||
CommonSocketControl* socketControl, const nsACString& aHostName,
|
||||
const void* aPtrForLogging, nsTArray<nsTArray<uint8_t>>&& peerCertChain,
|
||||
Maybe<nsTArray<nsTArray<uint8_t>>>& stapledOCSPResponses,
|
||||
Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension, uint32_t providerFlags);
|
||||
|
@ -68,7 +68,7 @@ class SSLServerCertVerificationResult final
|
|||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
explicit SSLServerCertVerificationResult(TransportSecurityInfo* infoObject);
|
||||
explicit SSLServerCertVerificationResult(CommonSocketControl* socketControl);
|
||||
|
||||
void Dispatch(nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
|
@ -82,7 +82,7 @@ class SSLServerCertVerificationResult final
|
|||
private:
|
||||
~SSLServerCertVerificationResult() = default;
|
||||
|
||||
const RefPtr<TransportSecurityInfo> mInfoObject;
|
||||
const RefPtr<CommonSocketControl> mSocketControl;
|
||||
nsTArray<nsTArray<uint8_t>> mBuiltChain;
|
||||
nsTArray<nsTArray<uint8_t>> mPeerCertChain;
|
||||
uint16_t mCertificateTransparencyStatus;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -9,209 +9,87 @@
|
|||
|
||||
#include "CertVerifier.h" // For CertificateTransparencyInfo, EVStatus
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "certt.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/ipc/TransportSecurityInfoUtils.h"
|
||||
#include "mozpkix/pkixtypes.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace psm {
|
||||
|
||||
class TransportSecurityInfo : public nsITransportSecurityInfo,
|
||||
public nsIInterfaceRequestor {
|
||||
protected:
|
||||
virtual ~TransportSecurityInfo() = default;
|
||||
|
||||
// TransportSecurityInfo implements nsITransportSecurityInfo, which is a
|
||||
// collection of attributes describing the outcome of a TLS handshake. It is
|
||||
// constant - once created, it cannot be modified. It should probably not be
|
||||
// instantiated directly, but rather accessed via
|
||||
// nsITLSSocketControl.securityInfo.
|
||||
class TransportSecurityInfo : public nsITransportSecurityInfo {
|
||||
public:
|
||||
TransportSecurityInfo();
|
||||
TransportSecurityInfo(
|
||||
uint32_t aSecurityState, PRErrorCode aErrorCode,
|
||||
nsTArray<RefPtr<nsIX509Cert>>&& aFailedCertChain,
|
||||
nsCOMPtr<nsIX509Cert>& aServerCert,
|
||||
nsTArray<RefPtr<nsIX509Cert>>&& aSucceededCertChain,
|
||||
Maybe<uint16_t> aCipherSuite, Maybe<nsCString> aKeaGroupName,
|
||||
Maybe<nsCString> aSignatureSchemeName, Maybe<uint16_t> aProtocolVersion,
|
||||
uint16_t aCertificateTransparencyStatus, Maybe<bool> aIsAcceptedEch,
|
||||
Maybe<bool> aIsDelegatedCredential,
|
||||
Maybe<OverridableErrorCategory> aOverridableErrorCategory,
|
||||
bool aMadeOCSPRequests, bool aUsedPrivateDNS, Maybe<bool> aIsEV,
|
||||
bool aNPNCompleted, const nsCString& aNegotiatedNPN, bool aResumed,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot, const nsCString& aPeerId);
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSITRANSPORTSECURITYINFO
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
static bool DeserializeFromIPC(IPC::MessageReader* aReader,
|
||||
RefPtr<nsITransportSecurityInfo>* aResult);
|
||||
static nsresult Read(const nsCString& aSerializedSecurityInfo,
|
||||
nsITransportSecurityInfo** aResult);
|
||||
|
||||
void SetPreliminaryHandshakeInfo(const SSLChannelInfo& channelInfo,
|
||||
const SSLCipherSuiteInfo& cipherInfo);
|
||||
|
||||
void SetSecurityState(uint32_t aState);
|
||||
|
||||
inline int32_t GetErrorCode() {
|
||||
int32_t result;
|
||||
mozilla::DebugOnly<nsresult> rv = GetErrorCode(&result);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsACString& GetHostName() const {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mHostName;
|
||||
}
|
||||
|
||||
void SetHostName(const char* host);
|
||||
|
||||
int32_t GetPort() const { return mPort; }
|
||||
void SetPort(int32_t aPort);
|
||||
|
||||
const OriginAttributes& GetOriginAttributes() const {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mOriginAttributes;
|
||||
}
|
||||
const OriginAttributes& GetOriginAttributes(
|
||||
MutexAutoLock& aProofOfLock) const {
|
||||
return mOriginAttributes;
|
||||
}
|
||||
void SetOriginAttributes(const OriginAttributes& aOriginAttributes);
|
||||
|
||||
void SetCanceled(PRErrorCode errorCode);
|
||||
bool IsCanceled();
|
||||
|
||||
void SetStatusErrorBits(const nsCOMPtr<nsIX509Cert>& cert,
|
||||
OverridableErrorCategory overridableErrorCategory);
|
||||
|
||||
nsresult SetFailedCertChain(nsTArray<nsTArray<uint8_t>>&& certList);
|
||||
|
||||
void SetServerCert(const nsCOMPtr<nsIX509Cert>& aServerCert,
|
||||
EVStatus aEVStatus);
|
||||
|
||||
nsresult SetSucceededCertChain(nsTArray<nsTArray<uint8_t>>&& certList);
|
||||
|
||||
bool HasServerCert() {
|
||||
MutexAutoLock lock(mMutex);
|
||||
return mServerCert != nullptr;
|
||||
}
|
||||
|
||||
static uint16_t ConvertCertificateTransparencyInfoToStatus(
|
||||
const mozilla::psm::CertificateTransparencyInfo& info);
|
||||
|
||||
// Use errorCode == 0 to indicate success;
|
||||
virtual void SetCertVerificationResult(PRErrorCode errorCode){};
|
||||
|
||||
void SetCertificateTransparencyStatus(
|
||||
uint16_t aCertificateTransparencyStatus) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mCertificateTransparencyStatus = aCertificateTransparencyStatus;
|
||||
}
|
||||
|
||||
void SetMadeOCSPRequest(bool aMadeOCSPRequests) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mMadeOCSPRequests = aMadeOCSPRequests;
|
||||
}
|
||||
|
||||
void SetUsedPrivateDNS(bool aUsedPrivateDNS) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUsedPrivateDNS = aUsedPrivateDNS;
|
||||
}
|
||||
|
||||
void SetResumed(bool aResumed);
|
||||
|
||||
Atomic<OverridableErrorCategory> mOverridableErrorCategory;
|
||||
Atomic<bool> mIsEV;
|
||||
Atomic<bool> mHasIsEVStatus;
|
||||
|
||||
Atomic<bool> mHaveCipherSuiteAndProtocol;
|
||||
|
||||
/* mHaveCertErrrorBits is relied on to determine whether or not a SPDY
|
||||
connection is eligible for joining in NSSSocketControl::JoinConnection() */
|
||||
Atomic<bool> mHaveCertErrorBits;
|
||||
|
||||
private:
|
||||
// True if SetCanceled has been called (or if this was deserialized with a
|
||||
// non-zero mErrorCode, which can only be the case if SetCanceled was called
|
||||
// on the original TransportSecurityInfo).
|
||||
Atomic<bool> mCanceled;
|
||||
virtual ~TransportSecurityInfo() = default;
|
||||
|
||||
protected:
|
||||
mutable ::mozilla::Mutex mMutex;
|
||||
|
||||
uint16_t mCipherSuite MOZ_GUARDED_BY(mMutex);
|
||||
uint16_t mProtocolVersion MOZ_GUARDED_BY(mMutex);
|
||||
uint16_t mCertificateTransparencyStatus MOZ_GUARDED_BY(mMutex);
|
||||
nsCString mKeaGroup MOZ_GUARDED_BY(mMutex);
|
||||
nsCString mSignatureSchemeName MOZ_GUARDED_BY(mMutex);
|
||||
|
||||
bool mIsAcceptedEch MOZ_GUARDED_BY(mMutex);
|
||||
bool mIsDelegatedCredential MOZ_GUARDED_BY(mMutex);
|
||||
bool mMadeOCSPRequests MOZ_GUARDED_BY(mMutex);
|
||||
bool mUsedPrivateDNS MOZ_GUARDED_BY(mMutex);
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks MOZ_GUARDED_BY(mMutex);
|
||||
nsTArray<RefPtr<nsIX509Cert>> mSucceededCertChain MOZ_GUARDED_BY(mMutex);
|
||||
bool mNPNCompleted MOZ_GUARDED_BY(mMutex);
|
||||
nsCString mNegotiatedNPN MOZ_GUARDED_BY(mMutex);
|
||||
bool mResumed MOZ_GUARDED_BY(mMutex);
|
||||
bool mIsBuiltCertChainRootBuiltInRoot MOZ_GUARDED_BY(mMutex);
|
||||
nsCString mPeerId MOZ_GUARDED_BY(mMutex);
|
||||
nsCString mHostName MOZ_GUARDED_BY(mMutex);
|
||||
OriginAttributes mOriginAttributes MOZ_GUARDED_BY(mMutex);
|
||||
|
||||
private:
|
||||
static nsresult ReadBoolAndSetAtomicFieldHelper(nsIObjectInputStream* stream,
|
||||
Atomic<bool>& atomic) {
|
||||
bool tmpBool;
|
||||
nsresult rv = stream->ReadBoolean(&tmpBool);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
atomic = tmpBool;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static nsresult ReadUint32AndSetAtomicFieldHelper(
|
||||
nsIObjectInputStream* stream, Atomic<uint32_t>& atomic) {
|
||||
uint32_t tmpInt;
|
||||
nsresult rv = stream->Read32(&tmpInt);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
atomic = tmpInt;
|
||||
return rv;
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
static bool ReadParamAtomicHelper(IPC::MessageReader* aReader,
|
||||
Atomic<P>& atomic) {
|
||||
P tmpStore;
|
||||
bool result = ReadParam(aReader, &tmpStore);
|
||||
if (result == false) {
|
||||
return result;
|
||||
}
|
||||
atomic = tmpStore;
|
||||
return result;
|
||||
}
|
||||
|
||||
Atomic<uint32_t> mSecurityState;
|
||||
|
||||
Atomic<PRErrorCode> mErrorCode;
|
||||
|
||||
Atomic<int32_t> mPort;
|
||||
|
||||
nsCOMPtr<nsIX509Cert> mServerCert MOZ_GUARDED_BY(mMutex);
|
||||
|
||||
/* Peer cert chain for failed connections (for error reporting) */
|
||||
nsTArray<RefPtr<nsIX509Cert>> mFailedCertChain MOZ_GUARDED_BY(mMutex);
|
||||
const uint32_t mSecurityState;
|
||||
const PRErrorCode mErrorCode;
|
||||
// Peer cert chain for failed connections.
|
||||
const nsTArray<RefPtr<nsIX509Cert>> mFailedCertChain;
|
||||
const nsCOMPtr<nsIX509Cert> mServerCert;
|
||||
const nsTArray<RefPtr<nsIX509Cert>> mSucceededCertChain;
|
||||
const mozilla::Maybe<uint16_t> mCipherSuite;
|
||||
const mozilla::Maybe<nsCString> mKeaGroupName;
|
||||
const mozilla::Maybe<nsCString> mSignatureSchemeName;
|
||||
const mozilla::Maybe<uint16_t> mProtocolVersion;
|
||||
const uint16_t mCertificateTransparencyStatus;
|
||||
const mozilla::Maybe<bool> mIsAcceptedEch;
|
||||
const mozilla::Maybe<bool> mIsDelegatedCredential;
|
||||
const mozilla::Maybe<OverridableErrorCategory> mOverridableErrorCategory;
|
||||
const bool mMadeOCSPRequests;
|
||||
const bool mUsedPrivateDNS;
|
||||
const mozilla::Maybe<bool> mIsEV;
|
||||
const bool mNPNCompleted;
|
||||
const nsCString mNegotiatedNPN;
|
||||
const bool mResumed;
|
||||
const bool mIsBuiltCertChainRootBuiltInRoot;
|
||||
const nsCString mPeerId;
|
||||
|
||||
static nsresult ReadOldOverridableErrorBits(
|
||||
nsIObjectInputStream* aStream,
|
||||
OverridableErrorCategory& aOverridableErrorCategory);
|
||||
static nsresult ReadSSLStatus(
|
||||
nsIObjectInputStream* aStream, nsCOMPtr<nsIX509Cert>& aServerCert,
|
||||
uint16_t& aCipherSuite, uint16_t& aProtocolVersion,
|
||||
OverridableErrorCategory& aOverridableErrorCategory, bool& aIsEV,
|
||||
bool& aHasIsEVStatus, bool& aHaveCipherSuiteAndProtocol,
|
||||
bool& aHaveCertErrorBits, uint16_t& aCertificateTransparencyStatus,
|
||||
nsCString& aKeaGroup, nsCString& aSignatureSchemeName,
|
||||
Maybe<uint16_t>& aCipherSuite, Maybe<uint16_t>& aProtocolVersion,
|
||||
Maybe<OverridableErrorCategory>& aOverridableErrorCategory,
|
||||
Maybe<bool>& aIsEV, uint16_t& aCertificateTransparencyStatus,
|
||||
Maybe<nsCString>& aKeaGroupName, Maybe<nsCString>& aSignatureSchemeName,
|
||||
nsTArray<RefPtr<nsIX509Cert>>& aSucceededCertChain);
|
||||
|
||||
// This function is used to read the binary that are serialized
|
||||
|
|
|
@ -95,8 +95,6 @@ Classes = [
|
|||
'cid': '{16786594-0296-4471-8096-8f84497ca428}',
|
||||
'contract_ids': ['@mozilla.org/security/transportsecurityinfo;1'],
|
||||
'type': 'mozilla::psm::TransportSecurityInfo',
|
||||
'legacy_constructor':
|
||||
'mozilla::psm::NSSConstructor<mozilla::psm::TransportSecurityInfo>',
|
||||
},
|
||||
{
|
||||
'cid': '{16955eee-6c48-4152-9309-c42a465138a1}',
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIInterfaceRequestor;
|
||||
interface nsIX509Cert;
|
||||
interface nsITlsHandshakeCallbackListener;
|
||||
interface nsITransportSecurityInfo;
|
||||
interface nsIX509Cert;
|
||||
|
||||
%{C++
|
||||
#include "nsStringFwd.h"
|
||||
|
@ -16,10 +17,12 @@ interface nsITlsHandshakeCallbackListener;
|
|||
%}
|
||||
[ref] native nsCStringTArrayRef(nsTArray<nsCString>);
|
||||
|
||||
// An interface describing an object that controls and holds information about
|
||||
// a TLS handshake.
|
||||
// NB: The implementations of this interface may only be used on the socket
|
||||
// thread (except for asyncGetSecurityInfo);
|
||||
[scriptable, builtinclass, uuid(418265c8-654e-4fbb-ba62-4eed27de1f03)]
|
||||
interface nsITLSSocketControl : nsISupports {
|
||||
attribute nsIInterfaceRequestor notificationCallbacks;
|
||||
|
||||
void proxyStartSSL();
|
||||
void StartTLS();
|
||||
|
||||
|
@ -92,11 +95,6 @@ interface nsITLSSocketControl : nsISupports {
|
|||
*/
|
||||
readonly attribute uint32_t providerFlags;
|
||||
|
||||
/*
|
||||
* The original TLS flags from the socket provider.
|
||||
*/
|
||||
readonly attribute uint32_t providerTlsFlags;
|
||||
|
||||
/* These values are defined by TLS. */
|
||||
const short SSL_VERSION_3 = 0x0300;
|
||||
const short TLS_VERSION_1 = 0x0301;
|
||||
|
@ -162,4 +160,23 @@ interface nsITLSSocketControl : nsISupports {
|
|||
[noscript] void disableEarlyData();
|
||||
|
||||
[noscript] void setHandshakeCallbackListener(in nsITlsHandshakeCallbackListener callback);
|
||||
|
||||
/**
|
||||
* The id used to uniquely identify the connection to the peer.
|
||||
*/
|
||||
readonly attribute ACString peerId;
|
||||
|
||||
/**
|
||||
* The securityInfo of the TLS handshake.
|
||||
*/
|
||||
readonly attribute nsITransportSecurityInfo securityInfo;
|
||||
|
||||
/**
|
||||
* Asynchronously obtain the securityInfo of the TLS handshake. Resolves
|
||||
* with an nsITransportSecurityInfo. This should probably only be used in
|
||||
* tests, where JS running on the main thread cannot access any of the
|
||||
* other fields of nsITLSSocketControl.
|
||||
*/
|
||||
[implicit_jscontext, must_use]
|
||||
Promise asyncGetSecurityInfo();
|
||||
};
|
||||
|
|
|
@ -128,7 +128,7 @@ interface nsITransportSecurityInfo : nsISupports {
|
|||
/**
|
||||
* True iff the succeededCertChain is built in root.
|
||||
*/
|
||||
attribute boolean isBuiltCertChainRootBuiltInRoot;
|
||||
readonly attribute boolean isBuiltCertChainRootBuiltInRoot;
|
||||
|
||||
/**
|
||||
* The id used to uniquely identify the connection to the peer.
|
||||
|
|
|
@ -699,12 +699,15 @@ nsCString getSignatureName(uint32_t aSignatureScheme) {
|
|||
return signatureName;
|
||||
}
|
||||
|
||||
// call with shutdown prevention lock held
|
||||
static void PreliminaryHandshakeDone(PRFileDesc* fd) {
|
||||
NSSSocketControl* infoObject = (NSSSocketControl*)fd->higher->secret;
|
||||
if (!infoObject) {
|
||||
NSSSocketControl* socketControl = (NSSSocketControl*)fd->higher->secret;
|
||||
if (!socketControl) {
|
||||
return;
|
||||
}
|
||||
if (socketControl->IsPreliminaryHandshakeDone()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSLChannelInfo channelInfo;
|
||||
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) != SECSuccess) {
|
||||
return;
|
||||
|
@ -714,17 +717,12 @@ static void PreliminaryHandshakeDone(PRFileDesc* fd) {
|
|||
sizeof(cipherInfo)) != SECSuccess) {
|
||||
return;
|
||||
}
|
||||
infoObject->SetPreliminaryHandshakeInfo(channelInfo, cipherInfo);
|
||||
infoObject->SetSSLVersionUsed(channelInfo.protocolVersion);
|
||||
infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted);
|
||||
infoObject->SetKEAUsed(channelInfo.keaType);
|
||||
infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
|
||||
infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
|
||||
|
||||
// Don't update NPN details on renegotiation.
|
||||
if (infoObject->IsPreliminaryHandshakeDone()) {
|
||||
return;
|
||||
}
|
||||
socketControl->SetPreliminaryHandshakeInfo(channelInfo, cipherInfo);
|
||||
socketControl->SetSSLVersionUsed(channelInfo.protocolVersion);
|
||||
socketControl->SetEarlyDataAccepted(channelInfo.earlyDataAccepted);
|
||||
socketControl->SetKEAUsed(channelInfo.keaType);
|
||||
socketControl->SetKEAKeyBits(channelInfo.keaKeyBits);
|
||||
socketControl->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
|
||||
|
||||
// Get the NPN value.
|
||||
SSLNextProtoState state;
|
||||
|
@ -736,17 +734,17 @@ static void PreliminaryHandshakeDone(PRFileDesc* fd) {
|
|||
SECSuccess) {
|
||||
if (state == SSL_NEXT_PROTO_NEGOTIATED ||
|
||||
state == SSL_NEXT_PROTO_SELECTED) {
|
||||
infoObject->SetNegotiatedNPN(BitwiseCast<char*, unsigned char*>(npnbuf),
|
||||
npnlen);
|
||||
socketControl->SetNegotiatedNPN(
|
||||
BitwiseCast<char*, unsigned char*>(npnbuf), npnlen);
|
||||
} else {
|
||||
infoObject->SetNegotiatedNPN(nullptr, 0);
|
||||
socketControl->SetNegotiatedNPN(nullptr, 0);
|
||||
}
|
||||
mozilla::Telemetry::Accumulate(Telemetry::SSL_NPN_TYPE, state);
|
||||
} else {
|
||||
infoObject->SetNegotiatedNPN(nullptr, 0);
|
||||
socketControl->SetNegotiatedNPN(nullptr, 0);
|
||||
}
|
||||
|
||||
infoObject->SetPreliminaryHandshakeDone();
|
||||
socketControl->SetPreliminaryHandshakeDone();
|
||||
}
|
||||
|
||||
SECStatus CanFalseStartCallback(PRFileDesc* fd, void* client_data,
|
||||
|
@ -1059,8 +1057,6 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
: Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_RESUMED,
|
||||
channelInfo.keaType);
|
||||
|
||||
MOZ_ASSERT(infoObject->GetKEAUsed() == channelInfo.keaType);
|
||||
|
||||
if (infoObject->IsFullHandshake()) {
|
||||
switch (channelInfo.keaType) {
|
||||
case ssl_kea_rsa:
|
||||
|
@ -1148,13 +1144,8 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
infoObject->RebuildCertificateInfoFromSSLTokenCache();
|
||||
}
|
||||
|
||||
nsITransportSecurityInfo::OverridableErrorCategory overridableErrorCategory;
|
||||
// This returns NS_OK, so don't even bother checking the return value.
|
||||
Unused << infoObject->GetOverridableErrorCategory(&overridableErrorCategory);
|
||||
// If we're here, the TLS handshake has succeeded. Thus if any of these
|
||||
// booleans are true, the user has added an override for a certificate error.
|
||||
if (overridableErrorCategory !=
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET) {
|
||||
// Check if the user has added an override for a certificate error.
|
||||
if (infoObject->HasUserOverriddenCertificateError()) {
|
||||
state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
|
||||
}
|
||||
|
||||
|
|
|
@ -578,21 +578,26 @@ static void reportHandshakeResult(int32_t bytesTransferred, bool wasReading,
|
|||
Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_RESULT, bucket);
|
||||
|
||||
if (bucket == 0) {
|
||||
nsCOMPtr<nsITransportSecurityInfo> securityInfo;
|
||||
if (NS_FAILED(socketInfo->GetSecurityInfo(getter_AddRefs(securityInfo))) ||
|
||||
!securityInfo) {
|
||||
return;
|
||||
}
|
||||
// Web Privacy Telemetry for successful connections.
|
||||
bool success = true;
|
||||
|
||||
bool usedPrivateDNS = false;
|
||||
success &= socketInfo->GetUsedPrivateDNS(&usedPrivateDNS) == NS_OK;
|
||||
success &= securityInfo->GetUsedPrivateDNS(&usedPrivateDNS) == NS_OK;
|
||||
|
||||
bool madeOCSPRequest = false;
|
||||
success &= socketInfo->GetMadeOCSPRequests(&madeOCSPRequest) == NS_OK;
|
||||
success &= securityInfo->GetMadeOCSPRequests(&madeOCSPRequest) == NS_OK;
|
||||
|
||||
uint16_t protocolVersion = 0;
|
||||
success &= socketInfo->GetProtocolVersion(&protocolVersion) == NS_OK;
|
||||
success &= securityInfo->GetProtocolVersion(&protocolVersion) == NS_OK;
|
||||
bool usedTLS13 = protocolVersion == 4;
|
||||
|
||||
bool usedECH = false;
|
||||
success &= socketInfo->GetIsAcceptedEch(&usedECH) == NS_OK;
|
||||
success &= securityInfo->GetIsAcceptedEch(&usedECH) == NS_OK;
|
||||
|
||||
// As bucket is 0 we are reporting the results of a sucessful connection
|
||||
// and so TransportSecurityInfo should be populated. However, this isn't
|
||||
|
@ -1553,13 +1558,12 @@ nsresult nsSSLIOLayerAddToSocket(int32_t family, const char* host, int32_t port,
|
|||
}
|
||||
|
||||
NSSSocketControl* infoObject =
|
||||
new NSSSocketControl(*sharedState, providerFlags, providerTlsFlags);
|
||||
new NSSSocketControl(nsDependentCString(host), port, *sharedState,
|
||||
providerFlags, providerTlsFlags);
|
||||
if (!infoObject) return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(infoObject);
|
||||
infoObject->SetForSTARTTLS(forSTARTTLS);
|
||||
infoObject->SetHostName(host);
|
||||
infoObject->SetPort(port);
|
||||
infoObject->SetOriginAttributes(originAttributes);
|
||||
if (allocatedState) {
|
||||
infoObject->SetSharedOwningReference(allocatedState);
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "OSReauthenticator.h"
|
||||
#include "PKCS11ModuleDB.h"
|
||||
#include "SecretDecoderRing.h"
|
||||
#include "TransportSecurityInfo.h"
|
||||
#include "mozilla/MacroArgs.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
|
@ -100,7 +99,6 @@ IMPL(nsCertTree, nullptr)
|
|||
IMPL(nsCryptoHash, nullptr, ProcessRestriction::AnyProcess)
|
||||
IMPL(ContentSignatureVerifier, nullptr)
|
||||
IMPL(nsRandomGenerator, nullptr, ProcessRestriction::AnyProcess)
|
||||
IMPL(TransportSecurityInfo, nullptr, ProcessRestriction::AnyProcess)
|
||||
IMPL(OSKeyStore, nullptr, ProcessRestriction::ParentProcessOnly,
|
||||
ThreadRestriction::MainThreadOnly)
|
||||
IMPL(OSReauthenticator, nullptr, ProcessRestriction::ParentProcessOnly,
|
||||
|
|
|
@ -617,7 +617,7 @@ async function asyncConnectTo(
|
|||
return connection.go();
|
||||
}
|
||||
|
||||
return connectTo(aHost).then(function(conn) {
|
||||
return connectTo(aHost).then(async function(conn) {
|
||||
info("handling " + aHost);
|
||||
let expectedNSResult =
|
||||
aExpectedResult == PRErrorCodeSuccess
|
||||
|
@ -630,9 +630,7 @@ async function asyncConnectTo(
|
|||
);
|
||||
if (aWithSecurityInfo) {
|
||||
aWithSecurityInfo(
|
||||
conn.transport.tlsSocketControl.QueryInterface(
|
||||
Ci.nsITransportSecurityInfo
|
||||
)
|
||||
await conn.transport.tlsSocketControl.asyncGetSecurityInfo()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче