bug 1003448 - HTTP/2 Alternate Service and Opportunistic Security [1/2 PSM] r=keeler

This commit is contained in:
Patrick McManus 2014-08-20 16:30:16 -04:00
parent d0054eac24
commit a798c39649
4 changed files with 131 additions and 19 deletions

View File

@ -15,7 +15,7 @@ class nsCString;
%}
[ref] native nsCStringTArrayRef(nsTArray<nsCString>);
[scriptable, builtinclass, uuid(89b819dc-31b0-4d09-915a-66f8a3703483)]
[scriptable, builtinclass, uuid(f160ec31-01f3-47f2-b542-0e12a647b07f)]
interface nsISSLSocketControl : nsISupports {
attribute nsIInterfaceRequestor notificationCallbacks;
@ -53,6 +53,11 @@ interface nsISSLSocketControl : nsISupports {
in ACString hostname,
in long port);
/* Determine if existing connection should be trusted to convey information about
* a hostname.
*/
boolean isAcceptableForHost(in ACString hostname);
/* The Key Exchange Algorithm is used when determining whether or
not to do false start and whether or not HTTP/2 can be used.
@ -103,5 +108,26 @@ interface nsISSLSocketControl : nsISupports {
* the user or searching the set of rememebered user cert decisions.
*/
attribute nsIX509Cert clientCert;
/**
* If you wish to verify the host certificate using a different name than
* was used for the tcp connection, but without using proxy semantics, you
* can set authenticationName and authenticationPort
*/
attribute ACString authenticationName;
[infallible] attribute long authenticationPort;
/**
* set bypassAuthentication to true if the server certificate checks should
* not be enforced. This is to enable non-secure transport over TLS.
*/
[infallible] attribute boolean bypassAuthentication;
/*
* failedVerification is true if any enforced certificate checks have failed.
* Connections that have not yet tried to verify, have verifications bypassed,
* or are using acceptable exceptions will all return false.
*/
[infallible] readonly attribute boolean failedVerification;
};

View File

@ -400,6 +400,16 @@ CertErrorRunnable::CheckCertOverrides()
mDefaultErrorCodeToReport);
}
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
if (sslSocketControl &&
sslSocketControl->GetBypassAuthentication()) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p][%p] Bypass Auth in CheckCertOverrides\n",
mFdForLogging, this));
return new SSLServerCertVerificationResult(mInfoObject, 0);
}
int32_t port;
mInfoObject->GetPort(&port);
@ -489,8 +499,6 @@ CertErrorRunnable::CheckCertOverrides()
// First, deliver the technical details of the broken SSL status.
// Try to get a nsIBadCertListener2 implementation from the socket consumer.
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
if (sslSocketControl) {
nsCOMPtr<nsIInterfaceRequestor> cb;
sslSocketControl->GetNotificationCallbacks(getter_AddRefs(cb));

View File

@ -132,11 +132,13 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
mJoined(false),
mSentClientCert(false),
mNotedTimeUntilReady(false),
mFailedVerification(false),
mKEAUsed(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN),
mKEAExpected(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN),
mKEAKeyBits(0),
mSSLVersionUsed(nsISSLSocketControl::SSL_VERSION_UNKNOWN),
mMACAlgorithmUsed(nsISSLSocketControl::SSL_MAC_UNKNOWN),
mBypassAuthentication(false),
mProviderFlags(providerFlags),
mSocketCreationTimestamp(TimeStamp::Now()),
mPlaintextBytesRead(0),
@ -226,6 +228,52 @@ nsNSSSocketInfo::SetClientCert(nsIX509Cert* aClientCert)
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetBypassAuthentication(bool* arg)
{
*arg = mBypassAuthentication;
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::SetBypassAuthentication(bool arg)
{
mBypassAuthentication = arg;
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetFailedVerification(bool* arg)
{
*arg = mFailedVerification;
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetAuthenticationName(nsACString& aAuthenticationName)
{
aAuthenticationName = GetHostName();
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::SetAuthenticationName(const nsACString& aAuthenticationName)
{
return SetHostName(PromiseFlatCString(aAuthenticationName).get());
}
NS_IMETHODIMP
nsNSSSocketInfo::GetAuthenticationPort(int32_t* aAuthenticationPort)
{
return GetPort(aAuthenticationPort);
}
NS_IMETHODIMP
nsNSSSocketInfo::SetAuthenticationPort(int32_t aAuthenticationPort)
{
return SetPort(aAuthenticationPort);
}
NS_IMETHODIMP
nsNSSSocketInfo::GetRememberClientAuthCertificate(bool* aRemember)
{
@ -378,21 +426,8 @@ nsNSSSocketInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN)
}
NS_IMETHODIMP
nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol,
const nsACString& hostname,
int32_t port,
bool* _retval)
nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval)
{
*_retval = false;
// Different ports may not be joined together
if (port != GetPort())
return NS_OK;
// Make sure NPN has been completed and matches requested npnProtocol
if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol))
return NS_OK;
// If this is the same hostname then the certicate status does not
// need to be considered. They are joinable.
if (hostname.Equals(GetHostName())) {
@ -462,12 +497,36 @@ nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol,
return NS_OK;
}
// All tests pass - this is joinable
mJoined = true;
// All tests pass
*_retval = true;
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::JoinConnection(const nsACString& npnProtocol,
const nsACString& hostname,
int32_t port,
bool* _retval)
{
*_retval = false;
// Different ports may not be joined together
if (port != GetPort())
return NS_OK;
// Make sure NPN has been completed and matches requested npnProtocol
if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol))
return NS_OK;
IsAcceptableForHost(hostname, _retval);
if (*_retval) {
// All tests pass - this is joinable
mJoined = true;
}
return NS_OK;
}
bool
nsNSSSocketInfo::GetForSTARTTLS()
{
@ -632,6 +691,7 @@ nsNSSSocketInfo::SetCertVerificationResult(PRErrorCode errorCode,
}
if (errorCode) {
mFailedVerification = true;
SetCanceled(errorCode, errorMessageType);
}

View File

@ -113,6 +113,22 @@ public:
void SetMACAlgorithmUsed(int16_t mac) { mMACAlgorithmUsed = mac; }
inline bool GetBypassAuthentication()
{
bool result = false;
mozilla::DebugOnly<nsresult> rv = GetBypassAuthentication(&result);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return result;
}
inline int32_t GetAuthenticationPort()
{
int32_t result = -1;
mozilla::DebugOnly<nsresult> rv = GetAuthenticationPort(&result);
MOZ_ASSERT(NS_SUCCEEDED(rv));
return result;
}
protected:
virtual ~nsNSSSocketInfo();
@ -139,6 +155,7 @@ private:
bool mJoined;
bool mSentClientCert;
bool mNotedTimeUntilReady;
bool mFailedVerification;
// mKEA* are used in false start and http/2 detetermination
// Values are from nsISSLSocketControl
@ -147,6 +164,7 @@ private:
uint32_t mKEAKeyBits;
int16_t mSSLVersionUsed;
int16_t mMACAlgorithmUsed;
bool mBypassAuthentication;
uint32_t mProviderFlags;
mozilla::TimeStamp mSocketCreationTimestamp;