Bug 1304923 - adding key exchange group and signature scheme details to devtools view, r=keeler, Honza

This patch adds the group used for TLS key exchange and the siganture scheme of the certificate to SSLStatus and displays it in devtools.

MozReview-Commit-ID: 7aTj0U5GIvo

--HG--
extra : rebase_source : 7afe39dcf2a13d9ca9e35e45c333a1bcba424729
This commit is contained in:
Franziskus Kiefer 2017-08-28 15:29:19 +02:00
parent 5a51ebb76a
commit 6aa0aa4140
9 changed files with 211 additions and 13 deletions

View File

@ -762,6 +762,33 @@ netmonitor.security.protocolVersion=Protocol version:
# in the security tab describing the cipher suite used to secure this connection.
netmonitor.security.cipherSuite=Cipher suite:
# LOCALIZATION NOTE (netmonitor.security.keaGroup): This is the label displayed
# in the security tab describing the key exchange group suite used to secure
# this connection.
netmonitor.security.keaGroup=Key Exchange Group:
# LOCALIZATION NOTE (netmonitor.security.keaGroup.none): This is the label
# displayed in the security tab describing the case when no group was used.
netmonitor.security.keaGroup.none=none
# LOCALIZATION NOTE (netmonitor.security.keaGroup.unknown): This is the value
# displayed in the security tab describing an unknown group.
netmonitor.security.keaGroup.unknown=unknown group
# LOCALIZATION NOTE (netmonitor.security.signatureScheme): This is the label
# displayed in the security tab describing the signature scheme used by for
# the server certificate in this connection.
netmonitor.security.signatureScheme=Signature Scheme:
# LOCALIZATION NOTE (netmonitor.security.signatureScheme.none): This is the
# label displayed in the security tab describing the case when no signature
# was used.
netmonitor.security.signatureScheme.none=none
# LOCALIZATION NOTE (netmonitor.security.signatureScheme.unknown): This is the
# value displayed in the security tab describing an unknown signature scheme.
netmonitor.security.signatureScheme.unknown=unknown signature scheme
# LOCALIZATION NOTE (netmonitor.security.hsts): This is the label displayed
# in the security tab describing the usage of HTTP Strict Transport Security.
netmonitor.security.hsts=HTTP Strict Transport Security:

View File

@ -45,6 +45,10 @@ function SecurityPanel({ request }) {
securityInfo.protocolVersion || notAvailable,
[L10N.getStr("netmonitor.security.cipherSuite")]:
securityInfo.cipherSuite || notAvailable,
[L10N.getStr("netmonitor.security.keaGroup")]:
securityInfo.keaGroupName || notAvailable,
[L10N.getStr("netmonitor.security.signatureScheme")]:
securityInfo.signatureSchemeName || notAvailable,
},
[L10N.getFormatStr("netmonitor.security.hostHeader", getUrlHost(url))]: {
[L10N.getStr("netmonitor.security.hsts")]:

View File

@ -48,31 +48,34 @@ add_task(function* () {
is(tabpanel.querySelectorAll(".treeLabel.objectLabel")[1].textContent,
"Host example.com:",
"Label has the expected value.");
is(textboxes[2].value, "Disabled", "Label has the expected value.");
is(textboxes[3].value, "Disabled", "Label has the expected value.");
// These two values can change. So only check they're not empty.
ok(textboxes[2].value !== "", "Label value is not empty.");
ok(textboxes[3].value !== "", "Label value is not empty.");
is(textboxes[4].value, "Disabled", "Label has the expected value.");
is(textboxes[5].value, "Disabled", "Label has the expected value.");
// Cert
is(textboxes[4].value, "example.com", "Label has the expected value.");
is(textboxes[5].value, "<Not Available>", "Label has the expected value.");
is(textboxes[6].value, "<Not Available>", "Label has the expected value.");
is(textboxes[6].value, "example.com", "Label has the expected value.");
is(textboxes[7].value, "<Not Available>", "Label has the expected value.");
is(textboxes[8].value, "<Not Available>", "Label has the expected value.");
is(textboxes[7].value, "Temporary Certificate Authority",
is(textboxes[9].value, "Temporary Certificate Authority",
"Label has the expected value.");
is(textboxes[8].value, "Mozilla Testing", "Label has the expected value.");
is(textboxes[9].value, "Profile Guided Optimization", "Label has the expected value.");
is(textboxes[10].value, "Mozilla Testing", "Label has the expected value.");
is(textboxes[11].value, "Profile Guided Optimization", "Label has the expected value.");
// Locale sensitive and varies between timezones. Cant't compare equality or
// the test fails depending on which part of the world the test is executed.
// cert validity begins
isnot(textboxes[10].value, "", "Label was not empty.");
isnot(textboxes[12].value, "", "Label was not empty.");
// cert validity expires
isnot(textboxes[11].value, "", "Label was not empty.");
isnot(textboxes[13].value, "", "Label was not empty.");
// cert sha1 fingerprint
isnot(textboxes[12].value, "", "Label was not empty.");
isnot(textboxes[14].value, "", "Label was not empty.");
// cert sha256 fingerprint
isnot(textboxes[13].value, "", "Label was not empty.");
isnot(textboxes[15].value, "", "Label was not empty.");
yield teardown(monitor);
});

View File

@ -63,6 +63,8 @@ const {components, Cc, Ci} = require("chrome");
loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const Services = require("Services");
const { LocalizationHelper } = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/netmonitor.properties");
// The cache used in the `nsIURL` function.
const gNSURLStore = new Map();
@ -620,6 +622,28 @@ var NetworkHelper = {
// Cipher suite.
info.cipherSuite = SSLStatus.cipherName;
// Key exchange group name.
info.keaGroupName = SSLStatus.keaGroupName;
// Localise two special values.
if (info.keaGroupName == "none") {
info.keaGroupName = L10N.getStr("netmonitor.security.keaGroup.none");
}
if (info.keaGroupName == "unknown group") {
info.keaGroupName = L10N.getStr("netmonitor.security.keaGroup.unknown");
}
// Certificate signature scheme.
info.signatureSchemeName = SSLStatus.signatureSchemeName;
// Localise two special values.
if (info.signatureSchemeName == "none") {
info.signatureSchemeName =
L10N.getStr("netmonitor.security.signatureScheme.none");
}
if (info.signatureSchemeName == "unknown signature") {
info.signatureSchemeName =
L10N.getStr("netmonitor.security.signatureScheme.unknown");
}
// Protocol version.
info.protocolVersion =
this.formatSecurityProtocol(SSLStatus.protocolVersion);

View File

@ -18,6 +18,10 @@ interface nsISSLStatus : nsISupports {
readonly attribute unsigned long keyLength;
[must_use]
readonly attribute unsigned long secretKeyLength;
[must_use]
readonly attribute ACString keaGroupName;
[must_use]
readonly attribute ACString signatureSchemeName;
const short SSL_VERSION_3 = 0;
const short TLS_VERSION_1 = 1;

View File

@ -826,6 +826,93 @@ PK11PasswordPrompt(PK11SlotInfo* slot, PRBool /*retry*/, void* arg)
return runnable->mResult;
}
static nsCString
getKeaGroupName(uint32_t aKeaGroup)
{
nsCString groupName;
switch (aKeaGroup) {
case ssl_grp_ec_secp256r1:
groupName = NS_LITERAL_CSTRING("P256");
break;
case ssl_grp_ec_secp384r1:
groupName = NS_LITERAL_CSTRING("P384");
break;
case ssl_grp_ec_secp521r1:
groupName = NS_LITERAL_CSTRING("P521");
break;
case ssl_grp_ec_curve25519:
groupName = NS_LITERAL_CSTRING("x25519");
break;
case ssl_grp_ffdhe_2048:
groupName = NS_LITERAL_CSTRING("FF 2048");
break;
case ssl_grp_ffdhe_3072:
groupName = NS_LITERAL_CSTRING("FF 3072");
break;
case ssl_grp_none:
groupName = NS_LITERAL_CSTRING("none");
break;
// All other groups are not enabled in Firefox. See namedGroups in
// nsNSSIOLayer.cpp.
default:
// This really shouldn't happen!
MOZ_ASSERT_UNREACHABLE("Invalid key exchange group.");
groupName = NS_LITERAL_CSTRING("unknown group");
}
return groupName;
}
static nsCString
getSignatureName(uint32_t aSignatureScheme)
{
nsCString signatureName;
switch (aSignatureScheme) {
case ssl_sig_none:
signatureName = NS_LITERAL_CSTRING("none");
break;
case ssl_sig_rsa_pkcs1_sha256:
signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA256");
break;
case ssl_sig_rsa_pkcs1_sha384:
signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA384");
break;
case ssl_sig_rsa_pkcs1_sha512:
signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA512");
break;
case ssl_sig_ecdsa_secp256r1_sha256:
signatureName = NS_LITERAL_CSTRING("ECDSA-P256-SHA256");
break;
case ssl_sig_ecdsa_secp384r1_sha384:
signatureName = NS_LITERAL_CSTRING("ECDSA-P384-SHA384");
break;
case ssl_sig_ecdsa_secp521r1_sha512:
signatureName = NS_LITERAL_CSTRING("ECDSA-P521-SHA512");
break;
case ssl_sig_rsa_pss_sha256:
signatureName = NS_LITERAL_CSTRING("RSA-PSS-SHA256");
break;
case ssl_sig_rsa_pss_sha384:
signatureName = NS_LITERAL_CSTRING("RSA-PSS-SHA384");
break;
case ssl_sig_rsa_pss_sha512:
signatureName = NS_LITERAL_CSTRING("RSA-PSS-SHA512");
break;
case ssl_sig_ecdsa_sha1:
signatureName = NS_LITERAL_CSTRING("ECDSA-SHA1");
break;
case ssl_sig_rsa_pkcs1_sha1md5:
signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA1MD5");
break;
// All other groups are not enabled in Firefox. See sEnabledSignatureSchemes
// in nsNSSIOLayer.cpp.
default:
// This really shouldn't happen!
MOZ_ASSERT_UNREACHABLE("Invalid signature scheme.");
signatureName = NS_LITERAL_CSTRING("unknown signature");
}
return signatureName;
}
// call with shutdown prevention lock held
static void
PreliminaryHandshakeDone(PRFileDesc* fd)
@ -852,6 +939,9 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
status->mHaveCipherSuiteAndProtocol = true;
status->mCipherSuite = channelInfo.cipherSuite;
status->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
status->mKeaGroup.Assign(getKeaGroupName(channelInfo.keaGroup));
status->mSignatureSchemeName.Assign(
getSignatureName(channelInfo.signatureScheme));
infoObject->SetKEAUsed(channelInfo.keaType);
infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);

View File

@ -2535,6 +2535,8 @@ loser:
return nullptr;
}
// Please change getSignatureName in nsNSSCallbacks.cpp when changing the list
// here.
static const SSLSignatureScheme sEnabledSignatureSchemes[] = {
ssl_sig_ecdsa_secp256r1_sha256,
ssl_sig_ecdsa_secp384r1_sha384,
@ -2645,6 +2647,8 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
}
// Include a modest set of named groups.
// Please change getKeaGroupName in nsNSSCallbacks.cpp when changing the list
// here.
const SSLNamedGroup namedGroups[] = {
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072

View File

@ -76,6 +76,28 @@ nsSSLStatus::GetCipherName(nsACString& aCipherName)
return NS_OK;
}
NS_IMETHODIMP
nsSSLStatus::GetKeaGroupName(nsACString& aKeaGroup)
{
if (!mHaveCipherSuiteAndProtocol) {
return NS_ERROR_NOT_AVAILABLE;
}
aKeaGroup.Assign(mKeaGroup);
return NS_OK;
}
NS_IMETHODIMP
nsSSLStatus::GetSignatureSchemeName(nsACString& aSignatureScheme)
{
if (!mHaveCipherSuiteAndProtocol) {
return NS_ERROR_NOT_AVAILABLE;
}
aSignatureScheme.Assign(mSignatureSchemeName);
return NS_OK;
}
NS_IMETHODIMP
nsSSLStatus::GetProtocolVersion(uint16_t* aProtocolVersion)
{
@ -194,6 +216,15 @@ nsSSLStatus::Read(nsIObjectInputStream* aStream)
NS_ENSURE_SUCCESS(rv, rv);
}
// Added in version 2 (see bug 1304923).
if (streamFormatVersion >= 2) {
rv = aStream->ReadCString(mKeaGroup);
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->ReadCString(mSignatureSchemeName);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
@ -201,7 +232,7 @@ NS_IMETHODIMP
nsSSLStatus::Write(nsIObjectOutputStream* aStream)
{
// The current version of the binary stream format.
const uint8_t STREAM_FORMAT_VERSION = 1;
const uint8_t STREAM_FORMAT_VERSION = 2;
nsresult rv = aStream->WriteCompoundObject(mServerCert,
NS_GET_IID(nsIX509Cert),
@ -237,6 +268,13 @@ nsSSLStatus::Write(nsIObjectOutputStream* aStream)
rv = aStream->Write16(mCertificateTransparencyStatus);
NS_ENSURE_SUCCESS(rv, rv);
// Added in version 2.
rv = aStream->WriteStringZ(mKeaGroup.get());
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->WriteStringZ(mSignatureSchemeName.get());
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -300,6 +338,8 @@ nsSSLStatus::nsSSLStatus()
, mProtocolVersion(0)
, mCertificateTransparencyStatus(nsISSLStatus::
CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE)
, mKeaGroup()
, mSignatureSchemeName()
, mIsDomainMismatch(false)
, mIsNotValidAtThisTime(false)
, mIsUntrusted(false)

View File

@ -50,6 +50,8 @@ public:
uint16_t mCipherSuite;
uint16_t mProtocolVersion;
uint16_t mCertificateTransparencyStatus;
nsCString mKeaGroup;
nsCString mSignatureSchemeName;
bool mIsDomainMismatch;
bool mIsNotValidAtThisTime;