mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-17 04:37:46 +09:00
Telemetry: Remove stubs and related code
This commit is contained in:
parent
10053448d6
commit
aea50f182f
134 changed files with 68 additions and 3422 deletions
|
|
@ -4,11 +4,9 @@
|
|||
|
||||
#include "PublicKeyPinningService.h"
|
||||
|
||||
#include "RootCertificateTelemetryUtils.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsISiteSecurityService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsSiteSecurityService.h"
|
||||
|
|
@ -233,8 +231,7 @@ FindPinningInformation(const char* hostname, mozilla::pkix::Time time,
|
|||
static nsresult
|
||||
CheckPinsForHostname(const UniqueCERTCertList& certList, const char* hostname,
|
||||
bool enforceTestMode, mozilla::pkix::Time time,
|
||||
/*out*/ bool& chainHasValidPins,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo)
|
||||
/*out*/ bool& chainHasValidPins)
|
||||
{
|
||||
chainHasValidPins = false;
|
||||
if (!certList) {
|
||||
|
|
@ -265,47 +262,11 @@ CheckPinsForHostname(const UniqueCERTCertList& certList, const char* hostname,
|
|||
return rv;
|
||||
}
|
||||
chainHasValidPins = enforceTestModeResult;
|
||||
Telemetry::ID histogram = staticFingerprints->mIsMoz
|
||||
? Telemetry::CERT_PINNING_MOZ_RESULTS
|
||||
: Telemetry::CERT_PINNING_RESULTS;
|
||||
if (staticFingerprints->mTestMode) {
|
||||
histogram = staticFingerprints->mIsMoz
|
||||
? Telemetry::CERT_PINNING_MOZ_TEST_RESULTS
|
||||
: Telemetry::CERT_PINNING_TEST_RESULTS;
|
||||
if (!enforceTestMode) {
|
||||
chainHasValidPins = true;
|
||||
}
|
||||
}
|
||||
// We can collect per-host pinning violations for this host because it is
|
||||
// operationally critical to Firefox.
|
||||
if (pinningTelemetryInfo) {
|
||||
if (staticFingerprints->mId != kUnknownId) {
|
||||
int32_t bucket = staticFingerprints->mId * 2
|
||||
+ (enforceTestModeResult ? 1 : 0);
|
||||
histogram = staticFingerprints->mTestMode
|
||||
? Telemetry::CERT_PINNING_MOZ_TEST_RESULTS_BY_HOST
|
||||
: Telemetry::CERT_PINNING_MOZ_RESULTS_BY_HOST;
|
||||
pinningTelemetryInfo->certPinningResultBucket = bucket;
|
||||
} else {
|
||||
pinningTelemetryInfo->certPinningResultBucket =
|
||||
enforceTestModeResult ? 1 : 0;
|
||||
}
|
||||
pinningTelemetryInfo->accumulateResult = true;
|
||||
pinningTelemetryInfo->certPinningResultHistogram = histogram;
|
||||
}
|
||||
|
||||
// We only collect per-CA pinning statistics upon failures.
|
||||
CERTCertListNode* rootNode = CERT_LIST_TAIL(certList);
|
||||
// Only log telemetry if the certificate list is non-empty.
|
||||
if (!CERT_LIST_END(rootNode, certList)) {
|
||||
if (!enforceTestModeResult && pinningTelemetryInfo) {
|
||||
int32_t binNumber = RootCABinNumber(&rootNode->cert->derCert);
|
||||
if (binNumber != ROOT_CERTIFICATE_UNKNOWN ) {
|
||||
pinningTelemetryInfo->accumulateForRoot = true;
|
||||
pinningTelemetryInfo->rootBucket = binNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug,
|
||||
("pkpin: Pin check %s for %s host '%s' (mode=%s)\n",
|
||||
|
|
@ -322,8 +283,7 @@ PublicKeyPinningService::ChainHasValidPins(const UniqueCERTCertList& certList,
|
|||
const char* hostname,
|
||||
mozilla::pkix::Time time,
|
||||
bool enforceTestMode,
|
||||
/*out*/ bool& chainHasValidPins,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo)
|
||||
/*out*/ bool& chainHasValidPins)
|
||||
{
|
||||
chainHasValidPins = false;
|
||||
if (!certList) {
|
||||
|
|
@ -334,8 +294,7 @@ PublicKeyPinningService::ChainHasValidPins(const UniqueCERTCertList& certList,
|
|||
}
|
||||
nsAutoCString canonicalizedHostname(CanonicalizeHostname(hostname));
|
||||
return CheckPinsForHostname(certList, canonicalizedHostname.get(),
|
||||
enforceTestMode, time, chainHasValidPins,
|
||||
pinningTelemetryInfo);
|
||||
enforceTestMode, time, chainHasValidPins);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ public:
|
|||
const char* hostname,
|
||||
mozilla::pkix::Time time,
|
||||
bool enforceTestMode,
|
||||
/*out*/ bool& chainHasValidPins,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo);
|
||||
/*out*/ bool& chainHasValidPins);
|
||||
/**
|
||||
* Sets chainMatchesPinset to true if there is any intersection between the
|
||||
* certificate list and the pins specified in the aSHA256keys array.
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "RootCertificateTelemetryUtils.h"
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "RootHashes.inc" // Note: Generated by genRootCAHashes.js
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
mozilla::LazyLogModule gPublicKeyPinningTelemetryLog("PublicKeyPinningTelemetryService");
|
||||
|
||||
// Used in the BinarySearch method, this does a memcmp between the pointer
|
||||
// provided to its construtor and whatever the binary search is looking for.
|
||||
//
|
||||
// This implementation assumes everything to be of HASH_LEN, so it should not
|
||||
// be used generically.
|
||||
class BinaryHashSearchArrayComparator
|
||||
{
|
||||
public:
|
||||
explicit BinaryHashSearchArrayComparator(const uint8_t* aTarget, size_t len)
|
||||
: mTarget(aTarget)
|
||||
{
|
||||
NS_ASSERTION(len == HASH_LEN, "Hashes should be of the same length.");
|
||||
}
|
||||
|
||||
int operator()(const CertAuthorityHash val) const {
|
||||
return memcmp(mTarget, val.hash, HASH_LEN);
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* mTarget;
|
||||
};
|
||||
|
||||
// Perform a hash of the provided cert, then search in the RootHashes.inc data
|
||||
// structure for a matching bin number.
|
||||
int32_t
|
||||
RootCABinNumber(const SECItem* cert)
|
||||
{
|
||||
Digest digest;
|
||||
|
||||
// Compute SHA256 hash of the certificate
|
||||
nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->data, cert->len);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return ROOT_CERTIFICATE_HASH_FAILURE;
|
||||
}
|
||||
|
||||
// Compare against list of stored hashes
|
||||
size_t idx;
|
||||
|
||||
MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
|
||||
("pkpinTelem: First bytes %02hx %02hx %02hx %02hx\n",
|
||||
digest.get().data[0], digest.get().data[1], digest.get().data[2], digest.get().data[3]));
|
||||
|
||||
if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE),
|
||||
BinaryHashSearchArrayComparator(static_cast<uint8_t*>(digest.get().data),
|
||||
digest.get().len),
|
||||
&idx)) {
|
||||
|
||||
MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug,
|
||||
("pkpinTelem: Telemetry index was %lu, bin is %d\n",
|
||||
idx, ROOT_TABLE[idx].binNumber));
|
||||
return (int32_t) ROOT_TABLE[idx].binNumber;
|
||||
}
|
||||
|
||||
// Didn't match.
|
||||
return ROOT_CERTIFICATE_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
// Attempt to increment the appropriate bin in the provided Telemetry probe ID. If
|
||||
// there was a hash failure, we do nothing.
|
||||
void
|
||||
AccumulateTelemetryForRootCA(mozilla::Telemetry::ID probe,
|
||||
const CERTCertificate* cert)
|
||||
{
|
||||
int32_t binId = RootCABinNumber(&cert->derCert);
|
||||
|
||||
if (binId != ROOT_CERTIFICATE_HASH_FAILURE) {
|
||||
Accumulate(probe, binId);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 RootCertificateTelemetryUtils_h
|
||||
#define RootCertificateTelemetryUtils_h
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "certt.h"
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
// Note: New CAs will show up as UNKNOWN_ROOT until
|
||||
// RootHashes.inc is updated to include them. 0 is reserved by
|
||||
// genRootCAHashes.js for the unknowns.
|
||||
#define ROOT_CERTIFICATE_UNKNOWN 0
|
||||
#define ROOT_CERTIFICATE_HASH_FAILURE -1
|
||||
|
||||
int32_t
|
||||
RootCABinNumber(const SECItem* cert);
|
||||
|
||||
void
|
||||
AccumulateTelemetryForRootCA(mozilla::Telemetry::ID probe, const CERTCertificate* cert);
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // RootCertificateTelemetryUtils_h
|
||||
|
|
@ -102,7 +102,6 @@
|
|||
#include "ExtendedValidation.h"
|
||||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "PSMRunnable.h"
|
||||
#include "RootCertificateTelemetryUtils.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
#include "SharedSSLState.h"
|
||||
|
|
@ -112,7 +111,6 @@
|
|||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
|
|
@ -150,11 +148,6 @@ namespace {
|
|||
// do not use a nsCOMPtr to avoid static initializer/destructor
|
||||
nsIThreadPool* gCertVerificationThreadPool = nullptr;
|
||||
|
||||
// We avoid using a mutex for the success case to avoid lock-related
|
||||
// performance issues. However, we do use a lock in the error case to simplify
|
||||
// the code, since performance in the error case is not important.
|
||||
Mutex* gSSLVerificationTelemetryMutex = nullptr;
|
||||
|
||||
// We add a mutex to serialize PKCS11 database operations
|
||||
Mutex* gSSLVerificationPK11Mutex = nullptr;
|
||||
|
||||
|
|
@ -173,7 +166,6 @@ Mutex* gSSLVerificationPK11Mutex = nullptr;
|
|||
void
|
||||
InitializeSSLServerCertVerificationThreads()
|
||||
{
|
||||
gSSLVerificationTelemetryMutex = new Mutex("SSLVerificationTelemetryMutex");
|
||||
gSSLVerificationPK11Mutex = new Mutex("SSLVerificationPK11Mutex");
|
||||
// TODO: tuning, make parameters preferences
|
||||
// XXX: instantiate nsThreadPool directly, to make this more bulletproof.
|
||||
|
|
@ -207,10 +199,6 @@ void StopSSLServerCertVerificationThreads()
|
|||
gCertVerificationThreadPool->Shutdown();
|
||||
NS_RELEASE(gCertVerificationThreadPool);
|
||||
}
|
||||
if (gSSLVerificationTelemetryMutex) {
|
||||
delete gSSLVerificationTelemetryMutex;
|
||||
gSSLVerificationTelemetryMutex = nullptr;
|
||||
}
|
||||
if (gSSLVerificationPK11Mutex) {
|
||||
delete gSSLVerificationPK11Mutex;
|
||||
gSSLVerificationPK11Mutex = nullptr;
|
||||
|
|
@ -244,8 +232,6 @@ public:
|
|||
|
||||
SSLServerCertVerificationResult(nsNSSSocketInfo* infoObject,
|
||||
PRErrorCode errorCode,
|
||||
Telemetry::ID telemetryID = Telemetry::HistogramCount,
|
||||
uint32_t telemetryValue = -1,
|
||||
SSLErrorMessageType errorMessageType =
|
||||
PlainErrorMessage);
|
||||
|
||||
|
|
@ -255,8 +241,6 @@ private:
|
|||
public:
|
||||
const PRErrorCode mErrorCode;
|
||||
const SSLErrorMessageType mErrorMessageType;
|
||||
const Telemetry::ID mTelemetryID;
|
||||
const uint32_t mTelemetryValue;
|
||||
};
|
||||
|
||||
class CertErrorRunnable : public SyncRunnableBase
|
||||
|
|
@ -297,63 +281,6 @@ private:
|
|||
const uint32_t mProviderFlags;
|
||||
};
|
||||
|
||||
// A probe value of 1 means "no error".
|
||||
uint32_t
|
||||
MapOverridableErrorToProbeValue(PRErrorCode errorCode)
|
||||
{
|
||||
switch (errorCode)
|
||||
{
|
||||
case SEC_ERROR_UNKNOWN_ISSUER: return 2;
|
||||
case SEC_ERROR_CA_CERT_INVALID: return 3;
|
||||
case SEC_ERROR_UNTRUSTED_ISSUER: return 4;
|
||||
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: return 5;
|
||||
case SEC_ERROR_UNTRUSTED_CERT: return 6;
|
||||
case SEC_ERROR_INADEQUATE_KEY_USAGE: return 7;
|
||||
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: return 8;
|
||||
case SSL_ERROR_BAD_CERT_DOMAIN: return 9;
|
||||
case SEC_ERROR_EXPIRED_CERTIFICATE: return 10;
|
||||
case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY: return 11;
|
||||
case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA: return 12;
|
||||
case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE: return 13;
|
||||
case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: return 14;
|
||||
case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
|
||||
return 15;
|
||||
case SEC_ERROR_INVALID_TIME: return 16;
|
||||
case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME: return 17;
|
||||
}
|
||||
NS_WARNING("Unknown certificate error code. Does MapOverridableErrorToProbeValue "
|
||||
"handle everything in DetermineCertOverrideErrors?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
MapCertErrorToProbeValue(PRErrorCode errorCode)
|
||||
{
|
||||
uint32_t probeValue;
|
||||
switch (errorCode)
|
||||
{
|
||||
// see security/pkix/include/pkix/Result.h
|
||||
#define MOZILLA_PKIX_MAP(name, value, nss_name) case nss_name: probeValue = value; break;
|
||||
MOZILLA_PKIX_MAP_LIST
|
||||
#undef MOZILLA_PKIX_MAP
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
// Since FATAL_ERROR_FLAG is 0x800, fatal error values are much larger than
|
||||
// non-fatal error values. To conserve space, we remap these so they start at
|
||||
// (decimal) 90 instead of 0x800. Currently there are ~50 non-fatal errors
|
||||
// mozilla::pkix might return, so saving space for 90 should be sufficient
|
||||
// (similarly, there are 4 fatal errors, so saving space for 10 should also
|
||||
// be sufficient).
|
||||
static_assert(FATAL_ERROR_FLAG == 0x800,
|
||||
"mozilla::pkix::FATAL_ERROR_FLAG is not what we were expecting");
|
||||
if (probeValue & FATAL_ERROR_FLAG) {
|
||||
probeValue ^= FATAL_ERROR_FLAG;
|
||||
probeValue += 90;
|
||||
}
|
||||
return probeValue;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
DetermineCertOverrideErrors(const UniqueCERTCertificate& cert,
|
||||
const char* hostName,
|
||||
|
|
@ -562,19 +489,6 @@ CertErrorRunnable::CheckCertOverrides()
|
|||
}
|
||||
|
||||
if (!remaining_display_errors) {
|
||||
// This can double- or triple-count one certificate with multiple
|
||||
// different types of errors. Since this is telemetry and we just
|
||||
// want a ballpark answer, we don't care.
|
||||
if (mErrorCodeTrust != 0) {
|
||||
uint32_t probeValue = MapOverridableErrorToProbeValue(mErrorCodeTrust);
|
||||
}
|
||||
if (mErrorCodeMismatch != 0) {
|
||||
uint32_t probeValue = MapOverridableErrorToProbeValue(mErrorCodeMismatch);
|
||||
}
|
||||
if (mErrorCodeTime != 0) {
|
||||
uint32_t probeValue = MapOverridableErrorToProbeValue(mErrorCodeTime);
|
||||
}
|
||||
|
||||
// all errors are covered by override rules, so let's accept the cert
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("[%p][%p] All errors covered by override rules\n",
|
||||
|
|
@ -621,8 +535,6 @@ CertErrorRunnable::CheckCertOverrides()
|
|||
SSLServerCertVerificationResult* result =
|
||||
new SSLServerCertVerificationResult(mInfoObject,
|
||||
errorCodeToReport,
|
||||
Telemetry::HistogramCount,
|
||||
-1,
|
||||
OverridableCertErrorMessage);
|
||||
|
||||
LogInvalidCertError(mInfoObject,
|
||||
|
|
@ -656,8 +568,6 @@ CreateCertErrorRunnable(CertVerifier& certVerifier,
|
|||
MOZ_ASSERT(infoObject);
|
||||
MOZ_ASSERT(cert);
|
||||
|
||||
uint32_t probeValue = MapCertErrorToProbeValue(defaultErrorCodeToReport);
|
||||
|
||||
uint32_t collected_errors = 0;
|
||||
PRErrorCode errorCodeTrust = 0;
|
||||
PRErrorCode errorCodeMismatch = 0;
|
||||
|
|
@ -861,334 +771,6 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo* infoObject,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
void
|
||||
AccumulateSubjectCommonNameTelemetry(const char* commonName,
|
||||
bool commonNameInSubjectAltNames)
|
||||
{
|
||||
if (!commonNameInSubjectAltNames) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: common name '%s' not in subject alt. names "
|
||||
"(or the subject alt. names extension is not present)\n",
|
||||
commonName));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if and only if commonName ends with altName (minus its leading
|
||||
// "*"). altName has already been checked to be of the form "*.<something>".
|
||||
// commonName may be NULL.
|
||||
static bool
|
||||
TryMatchingWildcardSubjectAltName(const char* commonName,
|
||||
const nsACString& altName)
|
||||
{
|
||||
return commonName &&
|
||||
StringEndsWith(nsDependentCString(commonName), Substring(altName, 1));
|
||||
}
|
||||
|
||||
// Gathers telemetry on Baseline Requirements 9.2.1 (Subject Alternative
|
||||
// Names Extension) and 9.2.2 (Subject Common Name Field).
|
||||
// Specifically:
|
||||
// - whether or not the subject common name field is present
|
||||
// - whether or not the subject alternative names extension is present
|
||||
// - if there is a malformed entry in the subject alt. names extension
|
||||
// - if there is an entry in the subject alt. names extension corresponding
|
||||
// to the subject common name
|
||||
// Telemetry is only gathered for certificates that chain to a trusted root
|
||||
// in Mozilla's Root CA program.
|
||||
// certList consists of a validated certificate chain. The end-entity
|
||||
// certificate is first and the root (trust anchor) is last.
|
||||
void
|
||||
GatherBaselineRequirementsTelemetry(const UniqueCERTCertList& certList)
|
||||
{
|
||||
CERTCertListNode* endEntityNode = CERT_LIST_HEAD(certList);
|
||||
CERTCertListNode* rootNode = CERT_LIST_TAIL(certList);
|
||||
PR_ASSERT(!(CERT_LIST_END(endEntityNode, certList) ||
|
||||
CERT_LIST_END(rootNode, certList)));
|
||||
if (CERT_LIST_END(endEntityNode, certList) ||
|
||||
CERT_LIST_END(rootNode, certList)) {
|
||||
return;
|
||||
}
|
||||
CERTCertificate* cert = endEntityNode->cert;
|
||||
PR_ASSERT(cert);
|
||||
if (!cert) {
|
||||
return;
|
||||
}
|
||||
UniquePORTString commonName(CERT_GetCommonName(&cert->subject));
|
||||
// This only applies to certificates issued by authorities in our root
|
||||
// program.
|
||||
CERTCertificate* rootCert = rootNode->cert;
|
||||
PR_ASSERT(rootCert);
|
||||
if (!rootCert) {
|
||||
return;
|
||||
}
|
||||
bool isBuiltIn = false;
|
||||
Result result = IsCertBuiltInRoot(rootCert, isBuiltIn);
|
||||
if (result != Success || !isBuiltIn) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: root certificate for '%s' is not a built-in root "
|
||||
"(or IsCertBuiltInRoot failed)\n", commonName.get()));
|
||||
return;
|
||||
}
|
||||
ScopedAutoSECItem altNameExtension;
|
||||
SECStatus rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
|
||||
&altNameExtension);
|
||||
if (rv != SECSuccess) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: no subject alt names extension for '%s'\n",
|
||||
commonName.get()));
|
||||
AccumulateSubjectCommonNameTelemetry(commonName.get(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
CERTGeneralName* subjectAltNames =
|
||||
CERT_DecodeAltNameExtension(arena.get(), &altNameExtension);
|
||||
if (!subjectAltNames) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: could not decode subject alt names for '%s'\n",
|
||||
commonName.get()));
|
||||
AccumulateSubjectCommonNameTelemetry(commonName.get(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
CERTGeneralName* currentName = subjectAltNames;
|
||||
bool commonNameInSubjectAltNames = false;
|
||||
bool nonDNSNameOrIPAddressPresent = false;
|
||||
bool malformedDNSNameOrIPAddressPresent = false;
|
||||
bool nonFQDNPresent = false;
|
||||
do {
|
||||
nsAutoCString altName;
|
||||
if (currentName->type == certDNSName) {
|
||||
altName.Assign(BitwiseCast<char*, unsigned char*>(
|
||||
currentName->name.other.data),
|
||||
currentName->name.other.len);
|
||||
nsDependentCString altNameWithoutWildcard(altName, 0);
|
||||
if (StringBeginsWith(altNameWithoutWildcard, NS_LITERAL_CSTRING("*."))) {
|
||||
altNameWithoutWildcard.Rebind(altName, 2);
|
||||
commonNameInSubjectAltNames |=
|
||||
TryMatchingWildcardSubjectAltName(commonName.get(), altName);
|
||||
}
|
||||
// net_IsValidHostName appears to return true for valid IP addresses,
|
||||
// which would be invalid for a DNS name.
|
||||
// Note that the net_IsValidHostName check will catch things like
|
||||
// "a.*.example.com".
|
||||
if (!net_IsValidHostName(altNameWithoutWildcard) ||
|
||||
net_IsValidIPv4Addr(altName.get(), altName.Length()) ||
|
||||
net_IsValidIPv6Addr(altName.get(), altName.Length())) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: DNSName '%s' not valid (for '%s')\n",
|
||||
altName.get(), commonName.get()));
|
||||
malformedDNSNameOrIPAddressPresent = true;
|
||||
}
|
||||
if (!altName.Contains('.')) {
|
||||
nonFQDNPresent = true;
|
||||
}
|
||||
} else if (currentName->type == certIPAddress) {
|
||||
// According to DNS.h, this includes space for the null-terminator
|
||||
char buf[net::kNetAddrMaxCStrBufSize] = { 0 };
|
||||
PRNetAddr addr;
|
||||
if (currentName->name.other.len == 4) {
|
||||
addr.inet.family = PR_AF_INET;
|
||||
memcpy(&addr.inet.ip, currentName->name.other.data,
|
||||
currentName->name.other.len);
|
||||
if (PR_NetAddrToString(&addr, buf, sizeof(buf) - 1) != PR_SUCCESS) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: IPAddress (v4) not valid (for '%s')\n",
|
||||
commonName.get()));
|
||||
malformedDNSNameOrIPAddressPresent = true;
|
||||
} else {
|
||||
altName.Assign(buf);
|
||||
}
|
||||
} else if (currentName->name.other.len == 16) {
|
||||
addr.inet.family = PR_AF_INET6;
|
||||
memcpy(&addr.ipv6.ip, currentName->name.other.data,
|
||||
currentName->name.other.len);
|
||||
if (PR_NetAddrToString(&addr, buf, sizeof(buf) - 1) != PR_SUCCESS) {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: IPAddress (v6) not valid (for '%s')\n",
|
||||
commonName.get()));
|
||||
malformedDNSNameOrIPAddressPresent = true;
|
||||
} else {
|
||||
altName.Assign(buf);
|
||||
}
|
||||
} else {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: IPAddress not valid (for '%s')\n",
|
||||
commonName.get()));
|
||||
malformedDNSNameOrIPAddressPresent = true;
|
||||
}
|
||||
} else {
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("BR telemetry: non-DNSName, non-IPAddress present for '%s'\n",
|
||||
commonName.get()));
|
||||
nonDNSNameOrIPAddressPresent = true;
|
||||
}
|
||||
if (commonName && altName.Equals(commonName.get())) {
|
||||
commonNameInSubjectAltNames = true;
|
||||
}
|
||||
currentName = CERT_GetNextGeneralName(currentName);
|
||||
} while (currentName && currentName != subjectAltNames);
|
||||
|
||||
AccumulateSubjectCommonNameTelemetry(commonName.get(),
|
||||
commonNameInSubjectAltNames);
|
||||
}
|
||||
|
||||
// Gather telemetry on whether the end-entity cert for a server has the
|
||||
// required TLS Server Authentication EKU, or any others
|
||||
void
|
||||
GatherEKUTelemetry(const UniqueCERTCertList& certList)
|
||||
{
|
||||
CERTCertListNode* endEntityNode = CERT_LIST_HEAD(certList);
|
||||
CERTCertListNode* rootNode = CERT_LIST_TAIL(certList);
|
||||
PR_ASSERT(!(CERT_LIST_END(endEntityNode, certList) ||
|
||||
CERT_LIST_END(rootNode, certList)));
|
||||
if (CERT_LIST_END(endEntityNode, certList) ||
|
||||
CERT_LIST_END(rootNode, certList)) {
|
||||
return;
|
||||
}
|
||||
CERTCertificate* endEntityCert = endEntityNode->cert;
|
||||
PR_ASSERT(endEntityCert);
|
||||
if (!endEntityCert) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only log telemetry if the root CA is built-in
|
||||
CERTCertificate* rootCert = rootNode->cert;
|
||||
PR_ASSERT(rootCert);
|
||||
if (!rootCert) {
|
||||
return;
|
||||
}
|
||||
bool isBuiltIn = false;
|
||||
Result rv = IsCertBuiltInRoot(rootCert, isBuiltIn);
|
||||
if (rv != Success || !isBuiltIn) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the EKU extension, if present
|
||||
bool foundEKU = false;
|
||||
SECOidTag oidTag;
|
||||
CERTCertExtension* ekuExtension = nullptr;
|
||||
for (size_t i = 0; endEntityCert->extensions && endEntityCert->extensions[i];
|
||||
i++) {
|
||||
oidTag = SECOID_FindOIDTag(&endEntityCert->extensions[i]->id);
|
||||
if (oidTag == SEC_OID_X509_EXT_KEY_USAGE) {
|
||||
foundEKU = true;
|
||||
ekuExtension = endEntityCert->extensions[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundEKU) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the EKU extension
|
||||
UniqueCERTOidSequence ekuSequence(
|
||||
CERT_DecodeOidSequence(&ekuExtension->value));
|
||||
if (!ekuSequence) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Search through the available EKUs
|
||||
bool foundServerAuth = false;
|
||||
bool foundOther = false;
|
||||
for (SECItem** oids = ekuSequence->oids; oids && *oids; oids++) {
|
||||
oidTag = SECOID_FindOIDTag(*oids);
|
||||
if (oidTag == SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) {
|
||||
foundServerAuth = true;
|
||||
} else {
|
||||
foundOther = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gathers telemetry on which CA is the root of a given cert chain.
|
||||
// If the root is a built-in root, then the telemetry makes a count
|
||||
// by root. Roots that are not built-in are counted in one bin.
|
||||
void
|
||||
GatherRootCATelemetry(const UniqueCERTCertList& certList)
|
||||
{
|
||||
CERTCertListNode* rootNode = CERT_LIST_TAIL(certList);
|
||||
PR_ASSERT(rootNode);
|
||||
if (!rootNode) {
|
||||
return;
|
||||
}
|
||||
PR_ASSERT(!CERT_LIST_END(rootNode, certList));
|
||||
if (CERT_LIST_END(rootNode, certList)) {
|
||||
return;
|
||||
}
|
||||
CERTCertificate* rootCert = rootNode->cert;
|
||||
PR_ASSERT(rootCert);
|
||||
if (!rootCert) {
|
||||
return;
|
||||
}
|
||||
AccumulateTelemetryForRootCA(Telemetry::CERT_VALIDATION_SUCCESS_BY_CA,
|
||||
rootCert);
|
||||
}
|
||||
|
||||
// These time are appoximate, i.e., doesn't account for leap seconds, etc
|
||||
const uint64_t ONE_WEEK_IN_SECONDS = (7 * (24 * 60 *60));
|
||||
const uint64_t ONE_YEAR_IN_WEEKS = 52;
|
||||
|
||||
// Gathers telemetry on the certificate lifetimes we observe in the wild
|
||||
void
|
||||
GatherEndEntityTelemetry(const UniqueCERTCertList& certList)
|
||||
{
|
||||
CERTCertListNode* endEntityNode = CERT_LIST_HEAD(certList);
|
||||
MOZ_ASSERT(endEntityNode && !CERT_LIST_END(endEntityNode, certList));
|
||||
if (!endEntityNode || CERT_LIST_END(endEntityNode, certList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CERTCertificate* endEntityCert = endEntityNode->cert;
|
||||
PR_ASSERT(endEntityCert);
|
||||
if (!endEntityCert) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRTime notBefore;
|
||||
PRTime notAfter;
|
||||
|
||||
if (CERT_GetCertTimes(endEntityCert, ¬Before, ¬After) != SECSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
PR_ASSERT(notAfter > notBefore);
|
||||
if (notAfter <= notBefore) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t durationInWeeks = (notAfter - notBefore)
|
||||
/ PR_USEC_PER_SEC
|
||||
/ ONE_WEEK_IN_SECONDS;
|
||||
|
||||
if (durationInWeeks > (2 * ONE_YEAR_IN_WEEKS)) {
|
||||
durationInWeeks = (2 * ONE_YEAR_IN_WEEKS) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// There are various things that we want to measure about certificate
|
||||
// chains that we accept. This is a single entry point for all of them.
|
||||
void
|
||||
GatherSuccessfulValidationTelemetry(const UniqueCERTCertList& certList)
|
||||
{
|
||||
GatherBaselineRequirementsTelemetry(certList);
|
||||
GatherEKUTelemetry(certList);
|
||||
GatherRootCATelemetry(certList);
|
||||
GatherEndEntityTelemetry(certList);
|
||||
}
|
||||
|
||||
void
|
||||
GatherTelemetryForSingleSCT(const ct::SignedCertificateTimestamp& sct)
|
||||
{
|
||||
/* STUB */
|
||||
}
|
||||
|
||||
void
|
||||
GatherCertificateTransparencyTelemetry(const UniqueCERTCertList& certList,
|
||||
const CertificateTransparencyInfo& info)
|
||||
{
|
||||
/* STUB */
|
||||
}
|
||||
|
||||
// Note: Takes ownership of |peerCertChain| if SECSuccess is not returned.
|
||||
SECStatus
|
||||
AuthCertificate(CertVerifier& certVerifier,
|
||||
|
|
@ -1214,7 +796,6 @@ AuthCertificate(CertVerifier& certVerifier,
|
|||
CertVerifier::OCSP_STAPLING_NEVER_CHECKED;
|
||||
KeySizeStatus keySizeStatus = KeySizeStatus::NeverChecked;
|
||||
SHA1ModeResult sha1ModeResult = SHA1ModeResult::NeverChecked;
|
||||
PinningTelemetryInfo pinningTelemetryInfo;
|
||||
CertificateTransparencyInfo certificateTransparencyInfo;
|
||||
|
||||
int flags = 0;
|
||||
|
|
@ -1233,22 +814,14 @@ AuthCertificate(CertVerifier& certVerifier,
|
|||
&evOidPolicy,
|
||||
&ocspStaplingStatus,
|
||||
&keySizeStatus, &sha1ModeResult,
|
||||
&pinningTelemetryInfo,
|
||||
&certificateTransparencyInfo);
|
||||
|
||||
uint32_t evStatus = (rv != Success) ? 0 // 0 = Failure
|
||||
: (evOidPolicy == SEC_OID_UNKNOWN) ? 1 // 1 = DV
|
||||
: 2; // 2 = EV
|
||||
|
||||
if (rv == Success) {
|
||||
// Certificate verification succeeded. Delete any potential record of
|
||||
// certificate error bits.
|
||||
RememberCertErrorsTable::GetInstance().RememberCertHasError(infoObject,
|
||||
nullptr,
|
||||
SECSuccess);
|
||||
GatherSuccessfulValidationTelemetry(certList);
|
||||
GatherCertificateTransparencyTelemetry(certList,
|
||||
certificateTransparencyInfo);
|
||||
|
||||
// The connection may get terminated, for example, if the server requires
|
||||
// a client cert. Let's provide a minimal SSLStatus
|
||||
|
|
@ -1363,11 +936,6 @@ SSLServerCertVerificationJob::Run()
|
|||
if (mInfoObject->isAlreadyShutDown()) {
|
||||
error = SEC_ERROR_USER_CANCELLED;
|
||||
} else {
|
||||
Telemetry::ID successTelemetry
|
||||
= Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_MOZILLAPKIX;
|
||||
Telemetry::ID failureTelemetry
|
||||
= Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_MOZILLAPKIX;
|
||||
|
||||
// Reset the error code here so we can detect if AuthCertificate fails to
|
||||
// set the error code if/when it fails.
|
||||
PR_SetError(0, 0);
|
||||
|
|
@ -1378,21 +946,15 @@ SSLServerCertVerificationJob::Run()
|
|||
MOZ_ASSERT(mPeerCertChain || rv != SECSuccess,
|
||||
"AuthCertificate() should take ownership of chain on failure");
|
||||
if (rv == SECSuccess) {
|
||||
uint32_t interval = (uint32_t) ((TimeStamp::Now() - mJobStartTime).ToMilliseconds());
|
||||
RefPtr<SSLServerCertVerificationResult> restart(
|
||||
new SSLServerCertVerificationResult(mInfoObject, 0,
|
||||
successTelemetry, interval));
|
||||
new SSLServerCertVerificationResult(mInfoObject, 0));
|
||||
restart->Dispatch();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Note: the interval is not calculated once as PR_GetError MUST be called
|
||||
// before any other function call
|
||||
// before any other function call
|
||||
error = PR_GetError();
|
||||
{
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
MutexAutoLock telemetryMutex(*gSSLVerificationTelemetryMutex);
|
||||
}
|
||||
if (error != 0) {
|
||||
RefPtr<CertErrorRunnable> runnable(
|
||||
CreateCertErrorRunnable(*mCertVerifier, error, mInfoObject, mCert,
|
||||
|
|
@ -1614,19 +1176,11 @@ AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
|
|||
|
||||
SSLServerCertVerificationResult::SSLServerCertVerificationResult(
|
||||
nsNSSSocketInfo* infoObject, PRErrorCode errorCode,
|
||||
Telemetry::ID telemetryID, uint32_t telemetryValue,
|
||||
SSLErrorMessageType errorMessageType)
|
||||
: mInfoObject(infoObject)
|
||||
, mErrorCode(errorCode)
|
||||
, mErrorMessageType(errorMessageType)
|
||||
, mTelemetryID(telemetryID)
|
||||
, mTelemetryValue(telemetryValue)
|
||||
{
|
||||
// We accumulate telemetry for (only) successful validations on the main thread
|
||||
// to avoid adversely affecting performance by acquiring the mutex that we use
|
||||
// when accumulating the telemetry for unsuccessful validations. Unsuccessful
|
||||
// validations times are accumulated elsewhere.
|
||||
MOZ_ASSERT(telemetryID == Telemetry::HistogramCount || errorCode == 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -135,7 +135,6 @@ UNIFIED_SOURCES += [
|
|||
'PSMContentListener.cpp',
|
||||
'PSMRunnable.cpp',
|
||||
'PublicKeyPinningService.cpp',
|
||||
'RootCertificateTelemetryUtils.cpp',
|
||||
'SecretDecoderRing.cpp',
|
||||
'SharedSSLState.cpp',
|
||||
'SSLServerCertVerification.cpp',
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
#include "cryptohi.h"
|
||||
#include "keyhi.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMHTMLSelectElement.h"
|
||||
#include "nsIGenKeypairInfoDlg.h"
|
||||
|
|
@ -395,13 +394,6 @@ loser:
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GatherKeygenTelemetry(uint32_t keyGenMechanism, int keysize, char* curve)
|
||||
{
|
||||
/* STUB */
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue,
|
||||
const nsAString& aChallenge,
|
||||
|
|
@ -639,8 +631,6 @@ nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue,
|
|||
CopyASCIItoUTF16(keystring.get(), aOutPublicKey);
|
||||
|
||||
rv = NS_OK;
|
||||
|
||||
GatherKeygenTelemetry(keyGenMechanism, keysize, keyparamsString);
|
||||
loser:
|
||||
if (srv != SECSuccess) {
|
||||
if ( privateKey ) {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
|
@ -1072,37 +1071,6 @@ CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
AccumulateNonECCKeySize(Telemetry::ID probe, uint32_t bits)
|
||||
{
|
||||
unsigned int value = bits < 512 ? 1 : bits == 512 ? 2
|
||||
: bits < 768 ? 3 : bits == 768 ? 4
|
||||
: bits < 1024 ? 5 : bits == 1024 ? 6
|
||||
: bits < 1280 ? 7 : bits == 1280 ? 8
|
||||
: bits < 1536 ? 9 : bits == 1536 ? 10
|
||||
: bits < 2048 ? 11 : bits == 2048 ? 12
|
||||
: bits < 3072 ? 13 : bits == 3072 ? 14
|
||||
: bits < 4096 ? 15 : bits == 4096 ? 16
|
||||
: bits < 8192 ? 17 : bits == 8192 ? 18
|
||||
: bits < 16384 ? 19 : bits == 16384 ? 20
|
||||
: 0;
|
||||
}
|
||||
|
||||
// XXX: This attempts to map a bit count to an ECC named curve identifier. In
|
||||
// the vast majority of situations, we only have the Suite B curves available.
|
||||
// In that case, this mapping works fine. If we were to have more curves
|
||||
// available, the mapping would be ambiguous since there could be multiple
|
||||
// named curves for a given size (e.g. secp256k1 vs. secp256r1). We punt on
|
||||
// that for now. See also NSS bug 323674.
|
||||
static void
|
||||
AccumulateECCCurve(Telemetry::ID probe, uint32_t bits)
|
||||
{
|
||||
unsigned int value = bits == 256 ? 23 // P-256
|
||||
: bits == 384 ? 24 // P-384
|
||||
: bits == 521 ? 25 // P-521
|
||||
: 0; // Unknown
|
||||
}
|
||||
|
||||
// In the case of session resumption, the AuthCertificate hook has been bypassed
|
||||
// (because we've previously successfully connected to our peer). That being the
|
||||
// case, we unfortunately don't know if the peer's server certificate verified
|
||||
|
|
@ -1216,11 +1184,6 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo));
|
||||
MOZ_ASSERT(rv == SECSuccess);
|
||||
if (rv == SECSuccess) {
|
||||
// Get the protocol version for telemetry
|
||||
// 1=tls1, 2=tls1.1, 3=tls1.2
|
||||
unsigned int versionEnum = channelInfo.protocolVersion & 0xFF;
|
||||
MOZ_ASSERT(versionEnum > 0);
|
||||
|
||||
SSLCipherSuiteInfo cipherInfo;
|
||||
rv = SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
|
||||
sizeof cipherInfo);
|
||||
|
|
@ -1231,16 +1194,10 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
if (infoObject->IsFullHandshake()) {
|
||||
switch (channelInfo.keaType) {
|
||||
case ssl_kea_rsa:
|
||||
AccumulateNonECCKeySize(Telemetry::SSL_KEA_RSA_KEY_SIZE_FULL,
|
||||
channelInfo.keaKeyBits);
|
||||
break;
|
||||
case ssl_kea_dh:
|
||||
AccumulateNonECCKeySize(Telemetry::SSL_KEA_DHE_KEY_SIZE_FULL,
|
||||
channelInfo.keaKeyBits);
|
||||
break;
|
||||
case ssl_kea_ecdh:
|
||||
AccumulateECCCurve(Telemetry::SSL_KEA_ECDHE_CURVE_FULL,
|
||||
channelInfo.keaKeyBits);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("impossible KEA");
|
||||
|
|
@ -1252,12 +1209,8 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
switch (channelInfo.authType) {
|
||||
case ssl_auth_rsa:
|
||||
case ssl_auth_rsa_sign:
|
||||
AccumulateNonECCKeySize(Telemetry::SSL_AUTH_RSA_KEY_SIZE_FULL,
|
||||
channelInfo.authKeyBits);
|
||||
break;
|
||||
case ssl_auth_ecdsa:
|
||||
AccumulateECCCurve(Telemetry::SSL_AUTH_ECDSA_CURVE_FULL,
|
||||
channelInfo.authKeyBits);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("impossible auth algorithm");
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsCRT.h"
|
||||
|
|
@ -785,13 +784,6 @@ nsNSSComponent::UnloadFamilySafetyRoot()
|
|||
// 2: detect Family Safety mode and import the root
|
||||
const char* kFamilySafetyModePref = "security.family_safety.mode";
|
||||
|
||||
// The telemetry gathered by this function is as follows:
|
||||
// 0-2: the value of the Family Safety mode pref
|
||||
// 3: detecting Family Safety mode failed
|
||||
// 4: Family Safety was not enabled
|
||||
// 5: Family Safety was enabled
|
||||
// 6: failed to import the Family Safety root
|
||||
// 7: successfully imported the root
|
||||
void
|
||||
nsNSSComponent::MaybeEnableFamilySafetyCompatibility()
|
||||
{
|
||||
|
|
@ -1564,15 +1556,6 @@ CipherSuiteChangeObserver::Observe(nsISupports* aSubject,
|
|||
void nsNSSComponent::setValidationOptions(bool isInitialSetting,
|
||||
const MutexAutoLock& lock)
|
||||
{
|
||||
// This preference controls whether we do OCSP fetching and does not affect
|
||||
// OCSP stapling.
|
||||
// 0 = disabled, 1 = enabled
|
||||
int32_t ocspEnabled = Preferences::GetInt("security.OCSP.enabled",
|
||||
OCSP_ENABLED_DEFAULT);
|
||||
|
||||
bool ocspRequired = ocspEnabled &&
|
||||
Preferences::GetBool("security.OCSP.require", false);
|
||||
|
||||
bool ocspStaplingEnabled = Preferences::GetBool("security.ssl.enable_ocsp_stapling",
|
||||
true);
|
||||
PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsArray.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
|
|
@ -244,21 +243,6 @@ nsNSSSocketInfo::NoteTimeUntilReady()
|
|||
void
|
||||
nsNSSSocketInfo::SetHandshakeCompleted()
|
||||
{
|
||||
if (!mHandshakeCompleted) {
|
||||
enum HandshakeType {
|
||||
Resumption = 1,
|
||||
FalseStarted = 2,
|
||||
ChoseNotToFalseStart = 3,
|
||||
NotAllowedToFalseStart = 4,
|
||||
};
|
||||
|
||||
HandshakeType handshakeType = !IsFullHandshake() ? Resumption
|
||||
: mFalseStarted ? FalseStarted
|
||||
: mFalseStartCallbackCalled ? ChoseNotToFalseStart
|
||||
: NotAllowedToFalseStart;
|
||||
}
|
||||
|
||||
|
||||
// Remove the plain text layer as it is not needed anymore.
|
||||
// The plain text layer is not always present - so its not a fatal error
|
||||
// if it cannot be removed
|
||||
|
|
@ -1050,29 +1034,6 @@ class SSLErrorRunnable : public SyncRunnableBase
|
|||
|
||||
namespace {
|
||||
|
||||
uint32_t tlsIntoleranceTelemetryBucket(PRErrorCode err)
|
||||
{
|
||||
// returns a numeric code for where we track various errors in telemetry
|
||||
// only errors that cause version fallback are tracked,
|
||||
// so this is also used to determine which errors can cause version fallback
|
||||
switch (err) {
|
||||
case SSL_ERROR_BAD_MAC_ALERT: return 1;
|
||||
case SSL_ERROR_BAD_MAC_READ: return 2;
|
||||
case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: return 3;
|
||||
case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT: return 4;
|
||||
case SSL_ERROR_ILLEGAL_PARAMETER_ALERT: return 6;
|
||||
case SSL_ERROR_NO_CYPHER_OVERLAP: return 7;
|
||||
case SSL_ERROR_UNSUPPORTED_VERSION: return 10;
|
||||
case SSL_ERROR_PROTOCOL_VERSION_ALERT: return 11;
|
||||
case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE: return 13;
|
||||
case SSL_ERROR_DECODE_ERROR_ALERT: return 14;
|
||||
case PR_CONNECT_RESET_ERROR: return 16;
|
||||
case PR_END_OF_FILE_ERROR: return 17;
|
||||
case SSL_ERROR_INTERNAL_ERROR_ALERT: return 18;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo)
|
||||
{
|
||||
|
|
@ -1097,13 +1058,6 @@ retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo)
|
|||
// this as a hard failure, but forget any intolerance so that later attempts
|
||||
// don't use this version (i.e., range.max) and trigger the error again.
|
||||
|
||||
// First, track the original cause of the version fallback. This uses the
|
||||
// same buckets as the telemetry below, except that bucket 0 will include
|
||||
// all cases where there wasn't an original reason.
|
||||
PRErrorCode originalReason =
|
||||
helpers.getIntoleranceReason(socketInfo->GetHostName(),
|
||||
socketInfo->GetPort());
|
||||
|
||||
helpers.forgetIntolerance(socketInfo->GetHostName(),
|
||||
socketInfo->GetPort());
|
||||
|
||||
|
|
@ -1139,29 +1093,14 @@ retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo)
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t reason = tlsIntoleranceTelemetryBucket(err);
|
||||
if (reason == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Telemetry::ID pre;
|
||||
Telemetry::ID post;
|
||||
switch (range.max) {
|
||||
case SSL_LIBRARY_VERSION_TLS_1_3:
|
||||
pre = Telemetry::SSL_TLS13_INTOLERANCE_REASON_PRE;
|
||||
post = Telemetry::SSL_TLS13_INTOLERANCE_REASON_POST;
|
||||
break;
|
||||
case SSL_LIBRARY_VERSION_TLS_1_2:
|
||||
pre = Telemetry::SSL_TLS12_INTOLERANCE_REASON_PRE;
|
||||
post = Telemetry::SSL_TLS12_INTOLERANCE_REASON_POST;
|
||||
break;
|
||||
case SSL_LIBRARY_VERSION_TLS_1_1:
|
||||
pre = Telemetry::SSL_TLS11_INTOLERANCE_REASON_PRE;
|
||||
post = Telemetry::SSL_TLS11_INTOLERANCE_REASON_POST;
|
||||
break;
|
||||
case SSL_LIBRARY_VERSION_TLS_1_0:
|
||||
pre = Telemetry::SSL_TLS10_INTOLERANCE_REASON_PRE;
|
||||
post = Telemetry::SSL_TLS10_INTOLERANCE_REASON_POST;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("impossible TLS version");
|
||||
|
|
@ -1187,34 +1126,6 @@ static_assert((PR_MAX_ERROR - PR_NSPR_ERROR_BASE) <= 128,
|
|||
static_assert((mozilla::pkix::ERROR_BASE - mozilla::pkix::END_OF_LIST) < 31,
|
||||
"too many moz::pkix errors");
|
||||
|
||||
static void
|
||||
reportHandshakeResult(int32_t bytesTransferred, bool wasReading, PRErrorCode err)
|
||||
{
|
||||
uint32_t bucket;
|
||||
|
||||
// A negative bytesTransferred or a 0 read are errors.
|
||||
if (bytesTransferred > 0) {
|
||||
bucket = 0;
|
||||
} else if ((bytesTransferred == 0) && !wasReading) {
|
||||
// PR_Write() is defined to never return 0, but let's make sure.
|
||||
// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR/Reference/PR_Write.
|
||||
MOZ_ASSERT(false);
|
||||
bucket = 671;
|
||||
} else if (IS_SSL_ERROR(err)) {
|
||||
bucket = err - SSL_ERROR_BASE;
|
||||
MOZ_ASSERT(bucket > 0); // SSL_ERROR_EXPORT_ONLY_SERVER isn't used.
|
||||
} else if (IS_SEC_ERROR(err)) {
|
||||
bucket = (err - SEC_ERROR_BASE) + 256;
|
||||
} else if ((err >= PR_NSPR_ERROR_BASE) && (err < PR_MAX_ERROR)) {
|
||||
bucket = (err - PR_NSPR_ERROR_BASE) + 512;
|
||||
} else if ((err >= mozilla::pkix::ERROR_BASE) &&
|
||||
(err < mozilla::pkix::ERROR_LIMIT)) {
|
||||
bucket = (err - mozilla::pkix::ERROR_BASE) + 640;
|
||||
} else {
|
||||
bucket = 671;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
checkHandshake(int32_t bytesTransfered, bool wasReading,
|
||||
PRFileDesc* ssl_layer_fd, nsNSSSocketInfo* socketInfo)
|
||||
|
|
@ -1292,10 +1203,6 @@ checkHandshake(int32_t bytesTransfered, bool wasReading,
|
|||
// set the HandshakePending attribute to false so that we don't try the logic
|
||||
// above again in a subsequent transfer.
|
||||
if (handleHandshakeResultNow) {
|
||||
// Report the result once for each handshake. Note that this does not
|
||||
// get handshakes which are cancelled before any reads or writes
|
||||
// happen.
|
||||
reportHandshakeResult(bytesTransfered, wasReading, originalError);
|
||||
socketInfo->SetHandshakeNotPending();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue