|
|
00e791 |
From 705d47ac2c90b8de07a4ef3e1930de6c4b8fece0 Mon Sep 17 00:00:00 2001
|
|
|
00e791 |
From: Peter Jones <pjones@redhat.com>
|
|
|
00e791 |
Date: Wed, 22 Jul 2020 19:54:58 -0400
|
|
|
00e791 |
Subject: [PATCH 59/62] Make openssl accept the right set of KU/EKUs
|
|
|
00e791 |
|
|
|
00e791 |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
00e791 |
Upstream: pr#211
|
|
|
00e791 |
---
|
|
|
00e791 |
Cryptlib/Pk/CryptPkcs7Verify.c | 87 ++++++++++++++++++++++++++++++++++
|
|
|
00e791 |
1 file changed, 87 insertions(+)
|
|
|
00e791 |
|
|
|
00e791 |
diff --git a/Cryptlib/Pk/CryptPkcs7Verify.c b/Cryptlib/Pk/CryptPkcs7Verify.c
|
|
|
00e791 |
index dcaba436797..09895d8c66a 100644
|
|
|
00e791 |
--- a/Cryptlib/Pk/CryptPkcs7Verify.c
|
|
|
00e791 |
+++ b/Cryptlib/Pk/CryptPkcs7Verify.c
|
|
|
00e791 |
@@ -30,6 +30,91 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
00e791 |
|
|
|
00e791 |
UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
|
|
|
00e791 |
|
|
|
00e791 |
+#if 1
|
|
|
00e791 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
|
00e791 |
+#define X509_OBJECT_get0_X509(obj) ((obj)->data.x509)
|
|
|
00e791 |
+#define X509_OBJECT_get_type(obj) ((obj)->type)
|
|
|
00e791 |
+#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
|
|
|
00e791 |
+#define X509_STORE_get0_objects(certs) ((certs)->objs)
|
|
|
00e791 |
+#define X509_get_extended_key_usage(cert) ((cert)->ex_xkusage)
|
|
|
00e791 |
+#if OPENSSL_VERSION_NUMBER < 0x10020000L
|
|
|
00e791 |
+#define X509_STORE_CTX_get0_store(ctx) ((ctx)->ctx)
|
|
|
00e791 |
+#endif
|
|
|
00e791 |
+#endif
|
|
|
00e791 |
+
|
|
|
00e791 |
+static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
|
|
|
00e791 |
+{
|
|
|
00e791 |
+ X509_OBJECT obj;
|
|
|
00e791 |
+ obj.type = X509_LU_X509;
|
|
|
00e791 |
+ obj.data.x509 = cert;
|
|
|
00e791 |
+ return X509_OBJECT_retrieve_match(ctx->ctx->objs, &obj) != NULL;
|
|
|
00e791 |
+}
|
|
|
00e791 |
+#else
|
|
|
00e791 |
+/*
|
|
|
00e791 |
+ * Later versions of openssl will need this instead.
|
|
|
00e791 |
+ */
|
|
|
00e791 |
+static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
|
|
|
00e791 |
+{
|
|
|
00e791 |
+ STACK_OF(X509_OBJECT) *objs;
|
|
|
00e791 |
+ X509_OBJECT *obj;
|
|
|
00e791 |
+ int i;
|
|
|
00e791 |
+
|
|
|
00e791 |
+ objs = X509_STORE_get0_objects(X509_STORE_CTX_get0_store(ctx));
|
|
|
00e791 |
+
|
|
|
00e791 |
+ for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
|
|
|
00e791 |
+ obj = sk_X509_OBJECT_value(objs, i);
|
|
|
00e791 |
+
|
|
|
00e791 |
+ if (X509_OBJECT_get_type(obj) == X509_LU_X509 &&
|
|
|
00e791 |
+ !X509_cmp(X509_OBJECT_get0_X509(obj), cert))
|
|
|
00e791 |
+ return 1;
|
|
|
00e791 |
+ }
|
|
|
00e791 |
+
|
|
|
00e791 |
+ return 0;
|
|
|
00e791 |
+}
|
|
|
00e791 |
+#endif
|
|
|
00e791 |
+
|
|
|
00e791 |
+int
|
|
|
00e791 |
+X509VerifyCb (
|
|
|
00e791 |
+ IN int Status,
|
|
|
00e791 |
+ IN X509_STORE_CTX *Context
|
|
|
00e791 |
+ )
|
|
|
00e791 |
+{
|
|
|
00e791 |
+ INTN Error;
|
|
|
00e791 |
+
|
|
|
00e791 |
+ Error = (INTN) X509_STORE_CTX_get_error (Context);
|
|
|
00e791 |
+
|
|
|
00e791 |
+ /* Accept code-signing keys */
|
|
|
00e791 |
+ if (Error == X509_V_ERR_INVALID_PURPOSE &&
|
|
|
00e791 |
+ X509_get_extended_key_usage(X509_STORE_CTX_get0_cert(Context)) == XKU_CODE_SIGN) {
|
|
|
00e791 |
+ Status = 1;
|
|
|
00e791 |
+ } else if (Error == X509_V_ERR_CERT_UNTRUSTED ||
|
|
|
00e791 |
+ Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT ||
|
|
|
00e791 |
+ Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
|
|
|
00e791 |
+ Error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) {
|
|
|
00e791 |
+ /* all certs in our cert database are explicitly trusted */
|
|
|
00e791 |
+
|
|
|
00e791 |
+ if (cert_in_store(X509_STORE_CTX_get_current_cert(Context), Context))
|
|
|
00e791 |
+ Status = 1;
|
|
|
00e791 |
+ } else if (Error == X509_V_ERR_CERT_HAS_EXPIRED ||
|
|
|
00e791 |
+ Error == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ||
|
|
|
00e791 |
+ Error == X509_V_ERR_CERT_NOT_YET_VALID ||
|
|
|
00e791 |
+ Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
|
|
|
00e791 |
+ Error == X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD) {
|
|
|
00e791 |
+ /* UEFI explicitly allows expired certificates */
|
|
|
00e791 |
+ Status = 1;
|
|
|
00e791 |
+#if 0
|
|
|
00e791 |
+ } else if (Error == X509_V_ERR_INVALID_CA) {
|
|
|
00e791 |
+ /* Due to the historical reason, we have to relax the the x509 v3 extension
|
|
|
00e791 |
+ * check to allow the CA certificates without the CA flag in the basic
|
|
|
00e791 |
+ * constraints or KeyCertSign in the key usage to be loaded. In the future,
|
|
|
00e791 |
+ * this callback should be removed to enforce the proper check. */
|
|
|
00e791 |
+ Status = 1;
|
|
|
00e791 |
+#endif
|
|
|
00e791 |
+ }
|
|
|
00e791 |
+
|
|
|
00e791 |
+ return Status;
|
|
|
00e791 |
+}
|
|
|
00e791 |
+
|
|
|
00e791 |
/**
|
|
|
00e791 |
Check input P7Data is a wrapped ContentInfo structure or not. If not construct
|
|
|
00e791 |
a new structure to wrap P7Data.
|
|
|
00e791 |
@@ -844,6 +929,8 @@ Pkcs7Verify (
|
|
|
00e791 |
goto _Exit;
|
|
|
00e791 |
}
|
|
|
00e791 |
|
|
|
00e791 |
+ X509_STORE_set_verify_cb (CertStore, X509VerifyCb);
|
|
|
00e791 |
+
|
|
|
00e791 |
//
|
|
|
00e791 |
// For generic PKCS#7 handling, InData may be NULL if the content is present
|
|
|
00e791 |
// in PKCS#7 structure. So ignore NULL checking here.
|
|
|
00e791 |
--
|
|
|
00e791 |
2.26.2
|
|
|
00e791 |
|