Bug 1713603 - Use NSS only on socket thread in CertVerifier::VerifyCertificateTransparencyPolicy r=keeler

Differential Revision: https://phabricator.services.mozilla.com/D117560
This commit is contained in:
R. Martinho Fernandes 2021-08-19 16:35:28 +00:00
Родитель 1916934834
Коммит fe7cd2dd7f
2 изменённых файлов: 41 добавлений и 28 удалений

Просмотреть файл

@ -26,6 +26,7 @@
#include "nsServiceManagerUtils.h"
#include "pk11pub.h"
#include "mozpkix/pkix.h"
#include "mozpkix/pkixcheck.h"
#include "mozpkix/pkixnss.h"
#include "mozpkix/pkixutil.h"
#include "secmod.h"
@ -38,19 +39,32 @@ mozilla::LazyLogModule gCertVerifierLog("certverifier");
// Returns the certificate validity period in calendar months (rounded down).
// "extern" to allow unit tests in CTPolicyEnforcerTest.cpp.
extern mozilla::pkix::Result GetCertLifetimeInFullMonths(PRTime certNotBefore,
PRTime certNotAfter,
extern mozilla::pkix::Result GetCertLifetimeInFullMonths(Time certNotBefore,
Time certNotAfter,
size_t& months) {
if (certNotBefore >= certNotAfter) {
MOZ_ASSERT_UNREACHABLE("Expected notBefore < notAfter");
return mozilla::pkix::Result::FATAL_ERROR_INVALID_ARGS;
}
uint64_t notBeforeSeconds;
Result rv = SecondsSinceEpochFromTime(certNotBefore, &notBeforeSeconds);
if (rv != Success) {
return rv;
}
uint64_t notAfterSeconds;
rv = SecondsSinceEpochFromTime(certNotAfter, &notAfterSeconds);
if (rv != Success) {
return rv;
}
// PRTime is microseconds
PRTime notBeforePR = static_cast<PRTime>(notBeforeSeconds) * 1000000;
PRTime notAfterPR = static_cast<PRTime>(notAfterSeconds) * 1000000;
PRExplodedTime explodedNotBefore;
PRExplodedTime explodedNotAfter;
PR_ExplodeTime(certNotBefore, PR_LocalTimeParameters, &explodedNotBefore);
PR_ExplodeTime(certNotAfter, PR_LocalTimeParameters, &explodedNotAfter);
PR_ExplodeTime(notBeforePR, PR_LocalTimeParameters, &explodedNotBefore);
PR_ExplodeTime(notAfterPR, PR_LocalTimeParameters, &explodedNotAfter);
PRInt32 signedMonths =
(explodedNotAfter.tm_year - explodedNotBefore.tm_year) * 12 +
@ -354,6 +368,7 @@ Result CertVerifier::VerifyCertificateTransparencyPolicy(
if (rv != Success) {
return rv;
}
BackCert issuerBackCert(issuerInput, EndEntityOrCA::MustBeCA, nullptr);
rv = issuerBackCert.Init();
if (rv != Success) {
@ -361,18 +376,6 @@ Result CertVerifier::VerifyCertificateTransparencyPolicy(
}
Input issuerPublicKeyInput = issuerBackCert.GetSubjectPublicKeyInfo();
SECItem endEntityDERItem = UnsafeMapInputToSECItem(endEntityInput);
UniqueCERTCertificate endEntityCert(CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &endEntityDERItem, nullptr, false, true));
if (!endEntityCert) {
return Result::FATAL_ERROR_LIBRARY_FAILURE;
}
if (endEntityCert->subjectName) {
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
("Verifying CT Policy compliance of subject %s\n",
endEntityCert->subjectName));
}
CTVerifyResult result;
rv = mCTVerifier->Verify(endEntityInput, issuerPublicKeyInput, embeddedSCTs,
sctsFromOCSP, sctsFromTLS, time, result);
@ -421,11 +424,17 @@ Result CertVerifier::VerifyCertificateTransparencyPolicy(
invalidSignatureCount, invalidTimestampCount, result.decodingErrors));
}
PRTime notBefore;
PRTime notAfter;
if (CERT_GetCertTimes(endEntityCert.get(), &notBefore, &notAfter) !=
SECSuccess) {
return Result::FATAL_ERROR_LIBRARY_FAILURE;
BackCert endEntityBackCert(endEntityInput, EndEntityOrCA::MustBeEndEntity,
nullptr);
rv = endEntityBackCert.Init();
if (rv != Success) {
return rv;
}
Time notBefore(Time::uninitialized);
Time notAfter(Time::uninitialized);
rv = ParseValidity(endEntityBackCert.GetValidity(), &notBefore, &notAfter);
if (rv != Success) {
return rv;
}
size_t lifetimeInMonths;
rv = GetCertLifetimeInFullMonths(notBefore, notAfter, lifetimeInMonths);

Просмотреть файл

@ -13,14 +13,15 @@
#include "CTLogVerifier.h"
#include "CTVerifyResult.h"
#include "SignedCertificateTimestamp.h"
#include "mozpkix/Time.h"
#include "gtest/gtest.h"
#include "hasht.h"
#include "prtime.h"
// Implemented in CertVerifier.cpp.
extern mozilla::pkix::Result GetCertLifetimeInFullMonths(PRTime certNotBefore,
PRTime certNotAfter,
size_t& months);
extern mozilla::pkix::Result GetCertLifetimeInFullMonths(
mozilla::pkix::Time certNotBefore, mozilla::pkix::Time certNotAfter,
size_t& months);
namespace mozilla {
namespace ct {
@ -341,8 +342,8 @@ TEST_F(CTPolicyEnforcerTest,
TEST_F(CTPolicyEnforcerTest, TestEdgeCasesOfGetCertLifetimeInFullMonths) {
const struct TestData {
PRTime notBefore;
PRTime notAfter;
uint64_t notBefore;
uint64_t notAfter;
size_t expectedMonths;
} kTestData[] = {
{ // 1 second less than 1 month
@ -372,8 +373,11 @@ TEST_F(CTPolicyEnforcerTest, TestEdgeCasesOfGetCertLifetimeInFullMonths) {
size_t months;
ASSERT_EQ(Success,
GetCertLifetimeInFullMonths(kTestData[i].notBefore,
kTestData[i].notAfter, months))
GetCertLifetimeInFullMonths(mozilla::pkix::TimeFromEpochInSeconds(
kTestData[i].notBefore / 1000000),
mozilla::pkix::TimeFromEpochInSeconds(
kTestData[i].notAfter / 1000000),
months))
<< "i=" << i;
EXPECT_EQ(kTestData[i].expectedMonths, months) << "i=" << i;
}