Blame SOURCES/0017-check_cert_db-try-even-harder-to-pick-a-reasonable-v.patch

0ac9f2
From 0456758e0c0873d1251bdf77d27f0f6175cbf289 Mon Sep 17 00:00:00 2001
0ac9f2
From: Peter Jones <pjones@redhat.com>
0ac9f2
Date: Tue, 25 Apr 2017 16:25:02 -0400
0ac9f2
Subject: [PATCH 17/29] check_cert_db(): try even harder to pick a reasonable
0ac9f2
 validation time.
0ac9f2
0ac9f2
Signed-off-by: Peter Jones <pjones@redhat.com>
0ac9f2
---
0ac9f2
 src/certdb.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
0ac9f2
 1 file changed, 66 insertions(+), 9 deletions(-)
0ac9f2
0ac9f2
diff --git a/src/certdb.c b/src/certdb.c
0ac9f2
index b7c99bb..1a4baf1 100644
0ac9f2
--- a/src/certdb.c
0ac9f2
+++ b/src/certdb.c
0ac9f2
@@ -250,12 +250,53 @@ check_db_hash(db_specifier which, pesigcheck_context *ctx)
0ac9f2
 	return check_db(which, ctx, check_hash, NULL, 0);
0ac9f2
 }
0ac9f2
 
0ac9f2
-static PRTime
0ac9f2
-determine_reasonable_time(CERTCertificate *cert)
0ac9f2
+static void
0ac9f2
+find_cert_times(SEC_PKCS7ContentInfo *cinfo,
0ac9f2
+		PRTime *notBefore, PRTime *notAfter)
0ac9f2
 {
0ac9f2
-	PRTime notBefore, notAfter;
0ac9f2
-	CERT_GetCertTimes(cert, &notBefore, &notAfter);
0ac9f2
-	return notBefore;
0ac9f2
+	CERTCertDBHandle *defaultdb, *certdb;
0ac9f2
+	SEC_PKCS7SignedData *sdp;
0ac9f2
+	CERTCertificate **certs = NULL;
0ac9f2
+	SECItem **rawcerts;
0ac9f2
+	int i, certcount;
0ac9f2
+	SECStatus rv;
0ac9f2
+
0ac9f2
+	if (cinfo->contentTypeTag->offset != SEC_OID_PKCS7_SIGNED_DATA) {
0ac9f2
+err:
0ac9f2
+		*notBefore = 0;
0ac9f2
+		*notAfter = 0x7fffffffffffffff;
0ac9f2
+		return;
0ac9f2
+	}
0ac9f2
+
0ac9f2
+	sdp = cinfo->content.signedData;
0ac9f2
+	rawcerts = sdp->rawCerts;
0ac9f2
+
0ac9f2
+	defaultdb = CERT_GetDefaultCertDB();
0ac9f2
+
0ac9f2
+	certdb = defaultdb;
0ac9f2
+	if (certdb == NULL)
0ac9f2
+		goto err;
0ac9f2
+
0ac9f2
+	certcount = 0;
0ac9f2
+	if (rawcerts != NULL) {
0ac9f2
+		for (; rawcerts[certcount] != NULL; certcount++)
0ac9f2
+			;
0ac9f2
+	}
0ac9f2
+	rv = CERT_ImportCerts(certdb, certUsageObjectSigner, certcount,
0ac9f2
+			      rawcerts, &certs, PR_FALSE, PR_FALSE, NULL);
0ac9f2
+	if (rv != SECSuccess)
0ac9f2
+		goto err;
0ac9f2
+
0ac9f2
+	for (i = 0; i < certcount; i++) {
0ac9f2
+		PRTime nb = 0, na = 0x7fffffffffff;
0ac9f2
+		CERT_GetCertTimes(certs[i], &nb, &na);
0ac9f2
+		if (*notBefore < nb)
0ac9f2
+			*notBefore = nb;
0ac9f2
+		if (*notAfter > na)
0ac9f2
+			*notAfter = na;
0ac9f2
+	}
0ac9f2
+
0ac9f2
+	CERT_DestroyCertArray(certs, certcount);
0ac9f2
 }
0ac9f2
 
0ac9f2
 static db_status
0ac9f2
@@ -271,6 +312,8 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype,
0ac9f2
 	PRBool result;
0ac9f2
 	SECStatus rv;
0ac9f2
 	db_status status = NOT_FOUND;
0ac9f2
+	PRTime earlyNow = 0, lateNow = 0x7fffffffffffffff;
0ac9f2
+	PRTime notBefore = 0, notAfter = 0x7fffffffffffffff;
0ac9f2
 
0ac9f2
 	efi_guid_t efi_x509 = efi_guid_x509_cert;
0ac9f2
 
0ac9f2
@@ -327,16 +370,30 @@ check_cert(pesigcheck_context *ctx, SECItem *sig, efi_guid_t *sigtype,
0ac9f2
 	}
0ac9f2
 	cert->timeOK = PR_TRUE;
0ac9f2
 
0ac9f2
+	find_cert_times(cinfo, &notBefore, &notAfter);
0ac9f2
+	if (earlyNow < notBefore)
0ac9f2
+		earlyNow = notBefore;
0ac9f2
+	if (lateNow > notAfter)
0ac9f2
+		lateNow = notAfter;
0ac9f2
+
0ac9f2
 	SECItem *eTime;
0ac9f2
 	PRTime atTime;
0ac9f2
 	// atTime = determine_reasonable_time(cert);
0ac9f2
 	eTime = SEC_PKCS7GetSigningTime(cinfo);
0ac9f2
 	if (eTime != NULL) {
0ac9f2
-		if (DER_DecodeTimeChoice (&atTime, eTime) != SECSuccess)
0ac9f2
-			atTime = determine_reasonable_time(cert);
0ac9f2
-	} else {
0ac9f2
-		atTime = determine_reasonable_time(cert);
0ac9f2
+		if (DER_DecodeTimeChoice (&atTime, eTime) == SECSuccess) {
0ac9f2
+			if (earlyNow < atTime)
0ac9f2
+				earlyNow = atTime;
0ac9f2
+			if (lateNow > atTime)
0ac9f2
+				lateNow = atTime;
0ac9f2
+		}
0ac9f2
 	}
0ac9f2
+
0ac9f2
+	if (lateNow < earlyNow)
0ac9f2
+		printf("Impossible time constraints: %ld <= %ld\n",
0ac9f2
+		       earlyNow / 1000000, lateNow / 1000000);
0ac9f2
+	atTime = earlyNow / 2 + lateNow / 2;
0ac9f2
+
0ac9f2
 	/* Verify the signature */
0ac9f2
 	result = SEC_PKCS7VerifyDetachedSignatureAtTime(cinfo,
0ac9f2
 						certUsageObjectSigner,
0ac9f2
-- 
0ac9f2
2.13.4
0ac9f2