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

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