mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 1492414 - Modify CertBlocklist interface to a form that should work with Rust XPCom bindings r=keeler
Differential Revision: https://phabricator.services.mozilla.com/D6260 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
6d86e85fe6
commit
41b314b255
@ -206,16 +206,20 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
// certificates.
|
||||
if (mCertDBTrustType == trustSSL) {
|
||||
bool isCertRevoked;
|
||||
nsresult nsrv = mCertBlocklist->IsCertRevoked(
|
||||
candidateCert->derIssuer.data,
|
||||
candidateCert->derIssuer.len,
|
||||
candidateCert->serialNumber.data,
|
||||
candidateCert->serialNumber.len,
|
||||
candidateCert->derSubject.data,
|
||||
candidateCert->derSubject.len,
|
||||
candidateCert->derPublicKey.data,
|
||||
candidateCert->derPublicKey.len,
|
||||
&isCertRevoked);
|
||||
|
||||
nsAutoCString encIssuer;
|
||||
nsAutoCString encSerial;
|
||||
nsAutoCString encSubject;
|
||||
nsAutoCString encPubKey;
|
||||
|
||||
nsresult nsrv = BuildRevocationCheckStrings(candidateCert.get(), encIssuer, encSerial, encSubject, encPubKey);
|
||||
|
||||
if (NS_FAILED(nsrv)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
nsrv = mCertBlocklist->IsCertRevoked(
|
||||
encIssuer, encSerial, encSubject, encPubKey, &isCertRevoked);
|
||||
if (NS_FAILED(nsrv)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
@ -1285,6 +1289,47 @@ DefaultServerNicknameForCert(const CERTCertificate* cert,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
BuildRevocationCheckStrings(const CERTCertificate* cert,
|
||||
/*out*/ nsCString& encIssuer,
|
||||
/*out*/ nsCString& encSerial,
|
||||
/*out*/ nsCString& encSubject,
|
||||
/*out*/ nsCString& encPubKey)
|
||||
{
|
||||
// Convert issuer, serial, subject and pubKey data to Base64 encoded DER
|
||||
nsDependentCSubstring issuerString(
|
||||
BitwiseCast<char*, uint8_t*>(cert->derIssuer.data),
|
||||
cert->derIssuer.len);
|
||||
nsDependentCSubstring serialString(
|
||||
BitwiseCast<char*, uint8_t*>(cert->serialNumber.data),
|
||||
cert->serialNumber.len);
|
||||
nsDependentCSubstring subjectString(
|
||||
BitwiseCast<char*, uint8_t*>(cert->derSubject.data),
|
||||
cert->derSubject.len);
|
||||
nsDependentCSubstring pubKeyString(
|
||||
BitwiseCast<char*, uint8_t*>(cert->derPublicKey.data),
|
||||
cert->derPublicKey.len);
|
||||
|
||||
nsresult rv = Base64Encode(issuerString, encIssuer);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Base64Encode(serialString, encSerial);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Base64Encode(subjectString, encSubject);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Base64Encode(pubKeyString, encPubKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of certificates representing a verified certificate path from an
|
||||
* end-entity certificate to a trust anchor, imports the intermediate
|
||||
|
@ -58,6 +58,30 @@ void UnloadLoadableRoots();
|
||||
nsresult DefaultServerNicknameForCert(const CERTCertificate* cert,
|
||||
/*out*/ nsCString& nickname);
|
||||
|
||||
/**
|
||||
* Build strings of base64 encoded issuer, serial, subject and public key data
|
||||
* from the supplied certificate for use in revocation checks.
|
||||
*
|
||||
* @param cert
|
||||
* The CERTCertificate* from which to extract the data.
|
||||
* @param out encIssuer
|
||||
* The string to populate with base64 encoded issuer data.
|
||||
* @param out encSerial
|
||||
* The string to populate with base64 encoded serial number data.
|
||||
* @param out encSubject
|
||||
* The string to populate with base64 encoded subject data.
|
||||
* @param out encPubKey
|
||||
* The string to populate with base64 encoded public key data.
|
||||
* @return
|
||||
* NS_OK, unless there's a Base64 encoding problem, in which case
|
||||
* NS_ERROR_FAILURE.
|
||||
*/
|
||||
nsresult BuildRevocationCheckStrings(const CERTCertificate* cert,
|
||||
/*out*/ nsCString& encIssuer,
|
||||
/*out*/ nsCString& encSerial,
|
||||
/*out*/ nsCString& encSubject,
|
||||
/*out*/ nsCString& encPubKey);
|
||||
|
||||
void SaveIntermediateCerts(const UniqueCERTCertList& certList);
|
||||
|
||||
class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "pkix/pkixnss.h"
|
||||
@ -44,17 +45,19 @@ CSTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
}
|
||||
|
||||
nsAutoCString encIssuer;
|
||||
nsAutoCString encSerial;
|
||||
nsAutoCString encSubject;
|
||||
nsAutoCString encPubKey;
|
||||
|
||||
nsresult nsrv = BuildRevocationCheckStrings(candidateCert.get(), encIssuer, encSerial, encSubject, encPubKey);
|
||||
if (NS_FAILED(nsrv)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
||||
bool isCertRevoked;
|
||||
nsresult nsrv = mCertBlocklist->IsCertRevoked(
|
||||
candidateCert->derIssuer.data,
|
||||
candidateCert->derIssuer.len,
|
||||
candidateCert->serialNumber.data,
|
||||
candidateCert->serialNumber.len,
|
||||
candidateCert->derSubject.data,
|
||||
candidateCert->derSubject.len,
|
||||
candidateCert->derPublicKey.data,
|
||||
candidateCert->derPublicKey.len,
|
||||
&isCertRevoked);
|
||||
nsrv = mCertBlocklist->IsCertRevoked(
|
||||
encIssuer, encSerial, encSubject, encPubKey, &isCertRevoked);
|
||||
if (NS_FAILED(nsrv)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
|
@ -508,48 +508,54 @@ CertBlocklist::SaveEntries()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CertBlocklist::IsCertRevoked(const uint8_t* aIssuer,
|
||||
uint32_t aIssuerLength,
|
||||
const uint8_t* aSerial,
|
||||
uint32_t aSerialLength,
|
||||
const uint8_t* aSubject,
|
||||
uint32_t aSubjectLength,
|
||||
const uint8_t* aPubKey,
|
||||
uint32_t aPubKeyLength,
|
||||
CertBlocklist::IsCertRevoked(const nsACString& aIssuerString,
|
||||
const nsACString& aSerialNumberString,
|
||||
const nsACString& aSubjectString,
|
||||
const nsACString& aPubKeyString,
|
||||
bool* _retval)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning, ("CertBlocklist::IsCertRevoked"));
|
||||
|
||||
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
|
||||
("CertBlocklist::IsCertRevoked?"));
|
||||
nsresult rv = EnsureBackingFileInitialized(lock);
|
||||
nsCString decodedIssuer;
|
||||
nsCString decodedSerial;
|
||||
nsCString decodedSubject;
|
||||
nsCString decodedPubKey;
|
||||
|
||||
nsresult rv = Base64Decode(aIssuerString, decodedIssuer);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Base64Decode(aSerialNumberString, decodedSerial);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Base64Decode(aSubjectString, decodedSubject);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = Base64Decode(aPubKeyString, decodedPubKey);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Input issuer;
|
||||
Input serial;
|
||||
if (issuer.Init(aIssuer, aIssuerLength) != Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (serial.Init(aSerial, aSerialLength) != Success) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CertBlocklistItem issuerSerial(aIssuer, aIssuerLength, aSerial, aSerialLength,
|
||||
BlockByIssuerAndSerial);
|
||||
|
||||
nsAutoCString encDN;
|
||||
nsAutoCString encOther;
|
||||
|
||||
issuerSerial.ToBase64(encDN, encOther);
|
||||
rv = EnsureBackingFileInitialized(lock);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
|
||||
CertBlocklistItem issuerSerial(
|
||||
BitwiseCast<const uint8_t*, const char*>(decodedIssuer.get()),
|
||||
decodedIssuer.Length(),
|
||||
BitwiseCast<const uint8_t*, const char*>(decodedSerial.get()),
|
||||
decodedSerial.Length(),
|
||||
BlockByIssuerAndSerial);
|
||||
|
||||
MOZ_LOG(gCertBlockPRLog,
|
||||
LogLevel::Warning,
|
||||
("CertBlocklist::IsCertRevoked issuer %s - serial %s",
|
||||
encDN.get(), encOther.get()));
|
||||
PromiseFlatCString(aIssuerString).get(),
|
||||
PromiseFlatCString(aSerialNumberString).get()));
|
||||
|
||||
*_retval = mBlocklist.Contains(issuerSerial);
|
||||
|
||||
@ -567,7 +573,9 @@ CertBlocklist::IsCertRevoked(const uint8_t* aIssuer,
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = crypto->Update(aPubKey, aPubKeyLength);
|
||||
rv = crypto->Update(
|
||||
BitwiseCast<const uint8_t*, const char*>(decodedPubKey.get()),
|
||||
decodedPubKey.Length());
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -579,20 +587,24 @@ CertBlocklist::IsCertRevoked(const uint8_t* aIssuer,
|
||||
}
|
||||
|
||||
CertBlocklistItem subjectPubKey(
|
||||
aSubject,
|
||||
static_cast<size_t>(aSubjectLength),
|
||||
BitwiseCast<const uint8_t*, const char*>(decodedSubject.get()),
|
||||
decodedSubject.Length(),
|
||||
BitwiseCast<const uint8_t*, const char*>(hashString.get()),
|
||||
hashString.Length(),
|
||||
BlockBySubjectAndPubKey);
|
||||
|
||||
rv = subjectPubKey.ToBase64(encDN, encOther);
|
||||
nsCString encodedHash;
|
||||
rv = Base64Encode(hashString, encodedHash);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
|
||||
("CertBlocklist::IsCertRevoked subject %s - pubKey hash %s",
|
||||
encDN.get(), encOther.get()));
|
||||
MOZ_LOG(gCertBlockPRLog,
|
||||
LogLevel::Warning,
|
||||
("CertBlocklist::IsCertRevoked subject %s - pubKeyHash %s (pubKey %s)",
|
||||
PromiseFlatCString(aSubjectString).get(),
|
||||
PromiseFlatCString(encodedHash).get(),
|
||||
PromiseFlatCString(aPubKeyString).get()));
|
||||
*_retval = mBlocklist.Contains(subjectPubKey);
|
||||
|
||||
MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
|
||||
|
@ -42,20 +42,16 @@ interface nsICertBlocklist : nsISupports {
|
||||
|
||||
/**
|
||||
* Check if a certificate is blocked.
|
||||
* issuer - issuer name, DER encoded
|
||||
* serial - serial number, DER encoded
|
||||
* subject - subject name, DER encoded
|
||||
* pubkey - public key, DER encoded
|
||||
* issuer - issuer name, DER, Base64 encoded
|
||||
* serial - serial number, DER, BAse64 encoded
|
||||
* subject - subject name, DER, Base64 encoded
|
||||
* pubkey - public key, DER, Base64 encoded
|
||||
*/
|
||||
[must_use]
|
||||
boolean isCertRevoked([const, array, size_is(issuer_length)] in octet issuer,
|
||||
in unsigned long issuer_length,
|
||||
[const, array, size_is(serial_length)] in octet serial,
|
||||
in unsigned long serial_length,
|
||||
[const, array, size_is(subject_length)] in octet subject,
|
||||
in unsigned long subject_length,
|
||||
[const, array, size_is(pubkey_length)] in octet pubkey,
|
||||
in unsigned long pubkey_length);
|
||||
boolean isCertRevoked(in ACString issuer,
|
||||
in ACString serial,
|
||||
in ACString subject,
|
||||
in ACString pubkey);
|
||||
|
||||
/**
|
||||
* Check that the blocklist data is current. Specifically, that the current
|
||||
|
@ -162,10 +162,6 @@ var addonManager = Cc["@mozilla.org/addons/integration;1"]
|
||||
.QueryInterface(Ci.nsITimerCallback);
|
||||
addonManager.observe(null, "addons-startup", null);
|
||||
|
||||
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
|
||||
function verify_cert(file, expectedError) {
|
||||
let ee = constructCertFromFile(file);
|
||||
return checkCertErrorGeneric(certDB, ee, expectedError,
|
||||
@ -190,19 +186,8 @@ function load_cert(cert, trust) {
|
||||
|
||||
function test_is_revoked(certList, issuerString, serialString, subjectString,
|
||||
pubKeyString) {
|
||||
let issuer = converter.convertToByteArray(issuerString || "", {});
|
||||
let serial = converter.convertToByteArray(serialString || "", {});
|
||||
let subject = converter.convertToByteArray(subjectString || "", {});
|
||||
let pubKey = converter.convertToByteArray(pubKeyString || "", {});
|
||||
|
||||
return certList.isCertRevoked(issuer,
|
||||
issuerString ? issuerString.length : 0,
|
||||
serial,
|
||||
serialString ? serialString.length : 0,
|
||||
subject,
|
||||
subjectString ? subjectString.length : 0,
|
||||
pubKey,
|
||||
pubKeyString ? pubKeyString.length : 0);
|
||||
return certList.isCertRevoked(btoa(issuerString), btoa(serialString),
|
||||
btoa(subjectString), btoa(pubKeyString));
|
||||
}
|
||||
|
||||
function fetch_blocklist() {
|
||||
|
Loading…
Reference in New Issue
Block a user