CryptoPkg/BaseCryptLib: Use X509_V_FLAG_PARTIAL_CHAIN

Since OpenSSL 1.0.2 we can set this flag on the X509_STORE to instruct
OpenSSL to accept non-self-signed certificates as trusted. So we don't
need two entirely identical copies of a verify_cb() function which makes
it ignore the resulting errors.

We also *didn't* use that verify_cb() function for X509VerifyCert(), but
probably should have done. So that can get X509_V_FLAG_PARTIAL_CHAIN for
consistency, too.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Qin Long <qin.long@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18703 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
David Woodhouse 2015-10-29 14:16:45 +00:00 committed by qlong
parent e6eaada468
commit 68547181f3
3 changed files with 15 additions and 171 deletions

View File

@ -30,87 +30,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UINT8 mOidValue[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 };
/**
Verification callback function to override any existing callbacks in OpenSSL
for intermediate certificate supports.
@param[in] Status Original status before calling this callback.
@param[in] Context X509 store context.
@retval 1 Current X509 certificate is verified successfully.
@retval 0 Verification failed.
**/
int
X509VerifyCb (
IN int Status,
IN X509_STORE_CTX *Context
)
{
X509_OBJECT *Obj;
INTN Error;
INTN Index;
INTN Count;
Obj = NULL;
Error = (INTN) X509_STORE_CTX_get_error (Context);
//
// X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT and X509_V_ERR_UNABLE_TO_GET_ISSUER_
// CERT_LOCALLY mean a X509 certificate is not self signed and its issuer
// can not be found in X509_verify_cert of X509_vfy.c.
// In order to support intermediate certificate node, we override the
// errors if the certification is obtained from X509 store, i.e. it is
// a trusted ceritifcate node that is enrolled by user.
// Besides,X509_V_ERR_CERT_UNTRUSTED and X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
// are also ignored to enable such feature.
//
if ((Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) ||
(Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)) {
Obj = (X509_OBJECT *) malloc (sizeof (X509_OBJECT));
if (Obj == NULL) {
return 0;
}
Obj->type = X509_LU_X509;
Obj->data.x509 = Context->current_cert;
CRYPTO_w_lock (CRYPTO_LOCK_X509_STORE);
if (X509_OBJECT_retrieve_match (Context->ctx->objs, Obj)) {
Status = 1;
} else {
//
// If any certificate in the chain is enrolled as trusted certificate,
// pass the certificate verification.
//
if (Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
Count = (INTN) sk_X509_num (Context->chain);
for (Index = 0; Index < Count; Index++) {
Obj->data.x509 = sk_X509_value (Context->chain, (int) Index);
if (X509_OBJECT_retrieve_match (Context->ctx->objs, Obj)) {
Status = 1;
break;
}
}
}
}
CRYPTO_w_unlock (CRYPTO_LOCK_X509_STORE);
}
if ((Error == X509_V_ERR_CERT_UNTRUSTED) ||
(Error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) {
Status = 1;
}
if (Obj != NULL) {
OPENSSL_free (Obj);
}
return Status;
}
/**
Check input P7Data is a wrapped ContentInfo structure or not. If not construct
a new structure to wrap P7Data.
@ -635,12 +554,6 @@ Pkcs7Verify (
goto _Exit;
}
//
// Register customized X509 verification callback function to support
// trusted intermediate certificate anchor.
//
CertStore->verify_cb = X509VerifyCb;
//
// For generic PKCS#7 handling, InData may be NULL if the content is present
// in PKCS#7 structure. So ignore NULL checking here.
@ -654,6 +567,12 @@ Pkcs7Verify (
goto _Exit;
}
//
// Allow partial certificate chains, terminated by a non-self-signed but
// still trusted intermediate certificate.
//
X509_STORE_set_flags (CertStore, X509_V_FLAG_PARTIAL_CHAIN);
//
// OpenSSL PKCS7 Verification by default checks for SMIME (email signing) and
// doesn't support the extended key usage for Authenticode Code Signing.

View File

@ -136,87 +136,6 @@ ASN1_SEQUENCE (TS_TST_INFO) = {
IMPLEMENT_ASN1_FUNCTIONS (TS_TST_INFO)
/**
Verification callback function to override any existing callbacks in OpenSSL
for intermediate TSA certificate supports.
@param[in] Status Original status before calling this callback.
@param[in] Context X509 store context.
@retval 1 Current X509 certificate is verified successfully.
@retval 0 Verification failed.
**/
int
TSVerifyCallback (
IN int Status,
IN X509_STORE_CTX *Context
)
{
X509_OBJECT *Obj;
INTN Error;
INTN Index;
INTN Count;
Obj = NULL;
Error = (INTN) X509_STORE_CTX_get_error (Context);
//
// X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT and X509_V_ERR_UNABLE_TO_GET_ISSUER_
// CERT_LOCALLY mean a X509 certificate is not self signed and its issuer
// can not be found in X509_verify_cert of X509_vfy.c.
// In order to support intermediate certificate node, we override the
// errors if the certification is obtained from X509 store, i.e. it is
// a trusted ceritifcate node that is enrolled by user.
// Besides,X509_V_ERR_CERT_UNTRUSTED and X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
// are also ignored to enable such feature.
//
if ((Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) ||
(Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)) {
Obj = (X509_OBJECT *) malloc (sizeof (X509_OBJECT));
if (Obj == NULL) {
return 0;
}
Obj->type = X509_LU_X509;
Obj->data.x509 = Context->current_cert;
CRYPTO_w_lock (CRYPTO_LOCK_X509_STORE);
if (X509_OBJECT_retrieve_match (Context->ctx->objs, Obj)) {
Status = 1;
} else {
//
// If any certificate in the chain is enrolled as trusted certificate,
// pass the certificate verification.
//
if (Error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) {
Count = (INTN) sk_X509_num (Context->chain);
for (Index = 0; Index < Count; Index++) {
Obj->data.x509 = sk_X509_value (Context->chain, (int) Index);
if (X509_OBJECT_retrieve_match (Context->ctx->objs, Obj)) {
Status = 1;
break;
}
}
}
}
CRYPTO_w_unlock (CRYPTO_LOCK_X509_STORE);
}
if ((Error == X509_V_ERR_CERT_UNTRUSTED) ||
(Error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) {
Status = 1;
}
if (Obj != NULL) {
OPENSSL_free (Obj);
}
return Status;
}
/**
Convert ASN.1 GeneralizedTime to EFI Time.
@ -506,10 +425,10 @@ TimestampTokenVerify (
}
//
// Register customized X509 verification callback function to support
// trusted intermediate TSA certificate anchor.
// Allow partial certificate chains, terminated by a non-self-signed but
// still trusted intermediate certificate.
//
CertStore->verify_cb = TSVerifyCallback;
X509_STORE_set_flags (CertStore, X509_V_FLAG_PARTIAL_CHAIN);
X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);

View File

@ -463,6 +463,12 @@ X509VerifyCert (
goto _Exit;
}
//
// Allow partial certificate chains, terminated by a non-self-signed but
// still trusted intermediate certificate.
//
X509_STORE_set_flags (CertStore, X509_V_FLAG_PARTIAL_CHAIN);
//
// Set up X509_STORE_CTX for the subsequent verification operation.
//