Make openssl accept the right set of KU/EKUs

Signed-off-by: Peter Jones <pjones@redhat.com>
Upstream: pr#211
This commit is contained in:
Peter Jones 2020-07-22 19:54:58 -04:00
parent 76c0447e20
commit 705d47ac2c

View File

@ -30,6 +30,91 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
#if 1
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_OBJECT_get0_X509(obj) ((obj)->data.x509)
#define X509_OBJECT_get_type(obj) ((obj)->type)
#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
#define X509_STORE_get0_objects(certs) ((certs)->objs)
#define X509_get_extended_key_usage(cert) ((cert)->ex_xkusage)
#if OPENSSL_VERSION_NUMBER < 0x10020000L
#define X509_STORE_CTX_get0_store(ctx) ((ctx)->ctx)
#endif
#endif
static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
{
X509_OBJECT obj;
obj.type = X509_LU_X509;
obj.data.x509 = cert;
return X509_OBJECT_retrieve_match(ctx->ctx->objs, &obj) != NULL;
}
#else
/*
* Later versions of openssl will need this instead.
*/
static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
{
STACK_OF(X509_OBJECT) *objs;
X509_OBJECT *obj;
int i;
objs = X509_STORE_get0_objects(X509_STORE_CTX_get0_store(ctx));
for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
obj = sk_X509_OBJECT_value(objs, i);
if (X509_OBJECT_get_type(obj) == X509_LU_X509 &&
!X509_cmp(X509_OBJECT_get0_X509(obj), cert))
return 1;
}
return 0;
}
#endif
int
X509VerifyCb (
IN int Status,
IN X509_STORE_CTX *Context
)
{
INTN Error;
Error = (INTN) X509_STORE_CTX_get_error (Context);
/* Accept code-signing keys */
if (Error == X509_V_ERR_INVALID_PURPOSE &&
X509_get_extended_key_usage(X509_STORE_CTX_get0_cert(Context)) == XKU_CODE_SIGN) {
Status = 1;
} else if (Error == X509_V_ERR_CERT_UNTRUSTED ||
Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT ||
Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
Error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) {
/* all certs in our cert database are explicitly trusted */
if (cert_in_store(X509_STORE_CTX_get_current_cert(Context), Context))
Status = 1;
} else if (Error == X509_V_ERR_CERT_HAS_EXPIRED ||
Error == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ||
Error == X509_V_ERR_CERT_NOT_YET_VALID ||
Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
Error == X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD) {
/* UEFI explicitly allows expired certificates */
Status = 1;
#if 0
} else if (Error == X509_V_ERR_INVALID_CA) {
/* Due to the historical reason, we have to relax the the x509 v3 extension
* check to allow the CA certificates without the CA flag in the basic
* constraints or KeyCertSign in the key usage to be loaded. In the future,
* this callback should be removed to enforce the proper check. */
Status = 1;
#endif
}
return Status;
}
/** /**
Check input P7Data is a wrapped ContentInfo structure or not. If not construct Check input P7Data is a wrapped ContentInfo structure or not. If not construct
a new structure to wrap P7Data. a new structure to wrap P7Data.
@ -844,6 +929,8 @@ Pkcs7Verify (
goto _Exit; goto _Exit;
} }
X509_STORE_set_verify_cb (CertStore, X509VerifyCb);
// //
// For generic PKCS#7 handling, InData may be NULL if the content is present // For generic PKCS#7 handling, InData may be NULL if the content is present
// in PKCS#7 structure. So ignore NULL checking here. // in PKCS#7 structure. So ignore NULL checking here.