From: "Wenxing Hou" <wenxing.hou@intel.com>
To: devel@edk2.groups.io
Cc: Wenxing Hou <wenxing.hou@intel.com>
Subject: [edk2-staging/OpenSSL11_EOL PATCH 4/7] Update Pkcs7 api based on MbedTlsLib for CryptoPkg
Date: Fri, 17 Mar 2023 17:00:50 +0800 [thread overview]
Message-ID: <20230317090053.1895-5-wenxing.hou@intel.com> (raw)
In-Reply-To: <20230317090053.1895-1-wenxing.hou@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
.../BaseCryptLibMbedTls/InternalCryptLib.h | 32 ++
.../BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c | 5 +-
.../Pk/CryptPkcs7VerifyBase.c | 40 +-
.../Pk/CryptPkcs7VerifyCommon.c | 338 ++++++++++++-
.../Pk/CryptPkcs7VerifyEku.c | 454 ++----------------
CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf | 1 +
6 files changed, 424 insertions(+), 446 deletions(-)
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
index 674242cfeb..6871785575 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/InternalCryptLib.h
@@ -24,4 +24,36 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
int myrand( void *rng_state, unsigned char *output, size_t len );
+/**
+ Check input P7Data is a wrapped ContentInfo structure or not. If not construct
+ a new structure to wrap P7Data.
+
+ Caution: This function may receive untrusted input.
+ UEFI Authenticated Variable is external input, so this function will do basic
+ check for PKCS#7 data structure.
+
+ @param[in] P7Data Pointer to the PKCS#7 message to verify.
+ @param[in] P7Length Length of the PKCS#7 message in bytes.
+ @param[out] WrapFlag If TRUE P7Data is a ContentInfo structure, otherwise
+ return FALSE.
+ @param[out] WrapData If return status of this function is TRUE:
+ 1) when WrapFlag is TRUE, pointer to P7Data.
+ 2) when WrapFlag is FALSE, pointer to a new ContentInfo
+ structure. It's caller's responsibility to free this
+ buffer.
+ @param[out] WrapDataSize Length of ContentInfo structure in bytes.
+
+ @retval TRUE The operation is finished successfully.
+ @retval FALSE The operation is failed due to lack of resources.
+
+**/
+BOOLEAN
+WrapPkcs7Data (
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Length,
+ OUT BOOLEAN *WrapFlag,
+ OUT UINT8 **WrapData,
+ OUT UINTN *WrapDataSize
+ );
+
#endif
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
index 0c7a1d009f..21d06264d5 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c
@@ -388,7 +388,8 @@ Pkcs7Sign (
mbedtls_pk_init (&Pkey);
Ret = mbedtls_pk_parse_key (
&Pkey, NewPrivateKey, PrivateKeySize,
- KeyPassword, KeyPassword == NULL ? 0 : AsciiStrLen (KeyPassword)
+ KeyPassword, KeyPassword == NULL ? 0 : AsciiStrLen (KeyPassword),
+ NULL, NULL
);
if (Ret != 0) {
Status = FALSE;
@@ -406,7 +407,7 @@ Pkcs7Sign (
ZeroMem (Signature, MAX_SIGNATURE_SIZE);
Ret = mbedtls_pk_sign (
&Pkey, MBEDTLS_MD_SHA256, HashValue, SHA256_DIGEST_SIZE,
- Signature, &SignatureLen, myrand, NULL);
+ Signature, MAX_SIGNATURE_SIZE, &SignatureLen, myrand, NULL);
if (Ret != 0) {
Status = FALSE;
goto Cleanup;
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c
index 01fcba5513..4daea4982f 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyBase.c
@@ -7,6 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
+#include <mbedtls/pkcs7.h>
/**
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
@@ -38,12 +39,13 @@ Pkcs7GetAttachedContent (
)
{
BOOLEAN Status;
- PKCS7 *Pkcs7;
UINT8 *SignedData;
UINTN SignedDataSize;
BOOLEAN Wrapped;
- CONST UINT8 *Temp;
- ASN1_OCTET_STRING *OctStr;
+ INTN Ret;
+ mbedtls_pkcs7 Pkcs7;
+
+ mbedtls_pkcs7_init(&Pkcs7);
//
// Check input parameter.
@@ -53,9 +55,7 @@ Pkcs7GetAttachedContent (
}
*Content = NULL;
- Pkcs7 = NULL;
SignedData = NULL;
- OctStr = NULL;
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
if (!Status || (SignedDataSize > INT_MAX)) {
@@ -64,26 +64,23 @@ Pkcs7GetAttachedContent (
Status = FALSE;
- //
- // Decoding PKCS#7 SignedData
- //
- Temp = SignedData;
- Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
- if (Pkcs7 == NULL) {
- goto _Exit;
- }
+ Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
//
// The type of Pkcs7 must be signedData
//
- if (!PKCS7_type_is_signed (Pkcs7)) {
+ if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
goto _Exit;
}
//
// Check for detached or attached content
//
- if (PKCS7_get_detached (Pkcs7)) {
+
+ mbedtls_pkcs7_data *MbedtlsContent;
+ MbedtlsContent = &(Pkcs7.signed_data.content);
+
+ if (MbedtlsContent == NULL) {
//
// No Content supplied for PKCS7 detached signedData
//
@@ -93,15 +90,14 @@ Pkcs7GetAttachedContent (
//
// Retrieve the attached content in PKCS7 signedData
//
- OctStr = Pkcs7->d.sign->contents->d.data;
- if ((OctStr->length > 0) && (OctStr->data != NULL)) {
- *ContentSize = OctStr->length;
+ if ((MbedtlsContent->data.len > 0) && (MbedtlsContent->data.p != NULL)) {
+ *ContentSize = MbedtlsContent->data.len;
*Content = AllocatePool (*ContentSize);
if (*Content == NULL) {
*ContentSize = 0;
goto _Exit;
}
- CopyMem (*Content, OctStr->data, *ContentSize);
+ CopyMem (*Content, MbedtlsContent->data.p, *ContentSize);
}
}
Status = TRUE;
@@ -110,11 +106,7 @@ _Exit:
//
// Release Resources
//
- PKCS7_free (Pkcs7);
-
- if (!Wrapped) {
- OPENSSL_free (SignedData);
- }
+ mbedtls_pkcs7_free (&Pkcs7);
return Status;
}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c
index 5291f2454d..14c9d447e6 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommon.c
@@ -656,7 +656,7 @@ Pkcs7Verify (
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &WrapData, &WrapDataSize);
- if (Status) {
+ if (!Status) {
Ret = 0;
Status = FALSE;
} else {
@@ -741,5 +741,339 @@ Pkcs7GetSigners (
OUT UINTN *CertLength
)
{
-return FALSE;
+ BOOLEAN Status;
+ UINT8 *SignedData;
+ UINTN SignedDataSize;
+ BOOLEAN Wrapped;
+ INTN Ret;
+ mbedtls_pkcs7 Pkcs7;
+ mbedtls_x509_crt *Cert;
+ UINT8 Index;
+ UINT8 *CertBuf;
+ UINT8 *OldBuf;
+ UINTN BufferSize;
+ UINTN OldSize;
+ UINT8 *SingleCert;
+ UINTN SingleCertSize;
+
+
+ mbedtls_pkcs7_init(&Pkcs7);
+
+ //
+ // Check input parameter.
+ //
+ if ((P7Data == NULL) || (CertStack == NULL) || (StackLength == NULL) ||
+ (TrustedCert == NULL) || (CertLength == NULL) || (P7Length > INT_MAX))
+ {
+ return FALSE;
+ }
+
+ SignedData = NULL;
+
+ Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
+ if (!Status || (SignedDataSize > INT_MAX)) {
+ goto _Exit;
+ }
+
+ Status = FALSE;
+
+ //
+ // Retrieve PKCS#7 Data (DER encoding)
+ //
+ if (SignedDataSize > INT_MAX) {
+ goto _Exit;
+ }
+
+ Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
+
+ //
+ // The type of Pkcs7 must be signedData
+ //
+ if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
+ goto _Exit;
+ }
+
+
+ Cert = NULL;
+ CertBuf = NULL;
+ OldBuf = NULL;
+ SingleCert = NULL;
+
+
+ Cert = &Pkcs7.signed_data.certs;
+ if (Cert == NULL) {
+ goto _Exit;
+ }
+
+ //
+ // Convert CertStack to buffer in following format:
+ // UINT8 CertNumber;
+ // UINT32 Cert1Length;
+ // UINT8 Cert1[];
+ // UINT32 Cert2Length;
+ // UINT8 Cert2[];
+ // ...
+ // UINT32 CertnLength;
+ // UINT8 Certn[];
+ //
+ BufferSize = sizeof (UINT8);
+ OldSize = BufferSize;
+
+ for (Index = 0; ; Index++) {
+
+ SingleCertSize = Cert->raw.len;
+
+ OldSize = BufferSize;
+ OldBuf = CertBuf;
+ BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
+ CertBuf = AllocateZeroPool (BufferSize);
+
+ if (CertBuf == NULL) {
+ goto _Exit;
+ }
+
+ if (OldBuf != NULL) {
+ CopyMem (CertBuf, OldBuf, OldSize);
+ FreePool (OldBuf);
+ OldBuf = NULL;
+ }
+
+ WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSize);
+ CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);
+
+ FreePool (SingleCert);
+ SingleCert = NULL;
+
+ if (Cert->next == NULL) {
+ break;
+ }
+ }
+
+ if (CertBuf != NULL) {
+ //
+ // Update CertNumber.
+ //
+ CertBuf[0] = Index;
+
+ *CertLength = BufferSize - OldSize - sizeof (UINT32);
+ *TrustedCert = AllocateZeroPool (*CertLength);
+ if (*TrustedCert == NULL) {
+ goto _Exit;
+ }
+
+ CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLength);
+ *CertStack = CertBuf;
+ *StackLength = BufferSize;
+ Status = TRUE;
+ }
+
+_Exit:
+ //
+ // Release Resources
+ //
+ if (!Wrapped) {
+ FreePool (SignedData);
+ }
+
+ mbedtls_pkcs7_free (&Pkcs7);
+
+ if (SingleCert != NULL) {
+ FreePool (SingleCert);
+ }
+
+ if (!Status && (CertBuf != NULL)) {
+ FreePool (CertBuf);
+ *CertStack = NULL;
+ }
+
+ if (OldBuf != NULL) {
+ FreePool (OldBuf);
+ }
+
+ return Status;
+}
+
+/**
+ Retrieves all embedded certificates from PKCS#7 signed data as described in "PKCS #7:
+ Cryptographic Message Syntax Standard", and outputs two certificate lists chained and
+ unchained to the signer's certificates.
+ The input signed data could be wrapped in a ContentInfo structure.
+
+ @param[in] P7Data Pointer to the PKCS#7 message.
+ @param[in] P7Length Length of the PKCS#7 message in bytes.
+ @param[out] SignerChainCerts Pointer to the certificates list chained to signer's
+ certificate. It's caller's responsibility to free the buffer
+ with Pkcs7FreeSigners().
+ This data structure is EFI_CERT_STACK type.
+ @param[out] ChainLength Length of the chained certificates list buffer in bytes.
+ @param[out] UnchainCerts Pointer to the unchained certificates lists. It's caller's
+ responsibility to free the buffer with Pkcs7FreeSigners().
+ This data structure is EFI_CERT_STACK type.
+ @param[out] UnchainLength Length of the unchained certificates list buffer in bytes.
+
+ @retval TRUE The operation is finished successfully.
+ @retval FALSE Error occurs during the operation.
+
+**/
+BOOLEAN
+EFIAPI
+Pkcs7GetCertificatesList (
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Length,
+ OUT UINT8 **SignerChainCerts,
+ OUT UINTN *ChainLength,
+ OUT UINT8 **UnchainCerts,
+ OUT UINTN *UnchainLength
+ )
+{
+ BOOLEAN Status;
+ UINT8 *SignedData;
+ UINTN SignedDataSize;
+ BOOLEAN Wrapped;
+ INTN Ret;
+ mbedtls_pkcs7 Pkcs7;
+ mbedtls_x509_crt *Cert;
+ UINT8 Index;
+ UINT8 *CertBuf;
+ UINT8 *OldBuf;
+ UINTN BufferSize;
+ UINTN OldSize;
+ UINT8 *SingleCert;
+ UINTN SingleCertSize;
+
+
+ mbedtls_pkcs7_init(&Pkcs7);
+
+ //
+ // Check input parameter.
+ //
+ if ((P7Data == NULL) || (SignerChainCerts == NULL) || (ChainLength == NULL) ||
+ (UnchainCerts == NULL) || (UnchainLength == NULL) || (P7Length > INT_MAX))
+ {
+ return FALSE;
+ }
+
+ SignedData = NULL;
+
+ Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
+ if (!Status || (SignedDataSize > INT_MAX)) {
+ goto _Exit;
+ }
+
+ Status = FALSE;
+
+ //
+ // Retrieve PKCS#7 Data (DER encoding)
+ //
+ if (SignedDataSize > INT_MAX) {
+ goto _Exit;
+ }
+
+ Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
+
+ //
+ // The type of Pkcs7 must be signedData
+ //
+ if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
+ goto _Exit;
+ }
+
+
+ Cert = NULL;
+ CertBuf = NULL;
+ OldBuf = NULL;
+ SingleCert = NULL;
+
+
+ Cert = &Pkcs7.signed_data.certs;
+ if (Cert == NULL) {
+ goto _Exit;
+ }
+
+ //
+ // Converts Chained and Untrusted Certificate to Certificate Buffer in following format:
+ // UINT8 CertNumber;
+ // UINT32 Cert1Length;
+ // UINT8 Cert1[];
+ // UINT32 Cert2Length;
+ // UINT8 Cert2[];
+ // ...
+ // UINT32 CertnLength;
+ // UINT8 Certn[];
+ //
+ BufferSize = sizeof (UINT8);
+ OldSize = BufferSize;
+
+ for (Index = 0; ; Index++) {
+
+ SingleCertSize = Cert->raw.len;
+
+ OldSize = BufferSize;
+ OldBuf = CertBuf;
+ BufferSize = OldSize + SingleCertSize + sizeof (UINT32);
+ CertBuf = AllocateZeroPool (BufferSize);
+
+ if (CertBuf == NULL) {
+ goto _Exit;
+ }
+
+ if (OldBuf != NULL) {
+ CopyMem (CertBuf, OldBuf, OldSize);
+ FreePool (OldBuf);
+ OldBuf = NULL;
+ }
+
+ WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSize);
+ CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSize);
+
+ FreePool (SingleCert);
+ SingleCert = NULL;
+
+ if (Cert->next == NULL) {
+ break;
+ }
+ }
+
+ if (CertBuf != NULL) {
+ //
+ // Update CertNumber.
+ //
+ CertBuf[0] = Index;
+
+ *UnchainLength = BufferSize - OldSize - sizeof (UINT32);
+ *UnchainCerts = AllocateZeroPool (*UnchainLength);
+ if (*UnchainCerts == NULL) {
+ goto _Exit;
+ }
+
+ CopyMem (*UnchainCerts, CertBuf + OldSize + sizeof (UINT32), *UnchainLength);
+ *SignerChainCerts = CertBuf;
+ *ChainLength = BufferSize;
+ Status = TRUE;
+ }
+
+_Exit:
+ //
+ // Release Resources
+ //
+ if (!Wrapped) {
+ FreePool (SignedData);
+ }
+
+ mbedtls_pkcs7_free (&Pkcs7);
+
+ if (SingleCert != NULL) {
+ FreePool (SingleCert);
+ }
+
+ if (!Status && (CertBuf != NULL)) {
+ FreePool (CertBuf);
+ *SignerChainCerts = NULL;
+ }
+
+ if (OldBuf != NULL) {
+ FreePool (OldBuf);
+ }
+
+ return Status;
}
diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c
index 1bc4a5db13..484255830a 100644
--- a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c
+++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyEku.c
@@ -11,311 +11,8 @@
#include <Base.h>
#include "InternalCryptLib.h"
+#include <mbedtls/pkcs7.h>
-/**
- This function will return the leaf signer certificate in a chain. This is
- required because certificate chains are not guaranteed to have the
- certificates in the order that they were issued.
-
- A typical certificate chain looks like this:
-
-
- ----------------------------
- | Root |
- ----------------------------
- ^
- |
- ----------------------------
- | Policy CA | <-- Typical Trust Anchor.
- ----------------------------
- ^
- |
- ----------------------------
- | Issuing CA |
- ----------------------------
- ^
- |
- -----------------------------
- / End-Entity (leaf) signer / <-- Bottom certificate.
- ----------------------------- EKU: "1.3.6.1.4.1.311.76.9.21.1"
- (Firmware Signing)
-
-
- @param[in] CertChain Certificate chain.
-
- @param[out] SignerCert Last certificate in the chain. For PKCS7 signatures,
- this will be the end-entity (leaf) signer cert.
-
- @retval EFI_SUCCESS The required EKUs were found in the signature.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
- @retval EFI_NOT_FOUND The number of signers found was not 1.
-
-**/
-EFI_STATUS
-GetSignerCertificate (
- IN CONST PKCS7 *CertChain,
- OUT X509 **SignerCert
- )
-{
- EFI_STATUS Status;
- STACK_OF(X509) *Signers;
- INT32 NumberSigners;
-
- Status = EFI_SUCCESS;
- Signers = NULL;
- NumberSigners = 0;
-
- if (CertChain == NULL || SignerCert == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- //
- // Get the signers from the chain.
- //
- Signers = PKCS7_get0_signers ((PKCS7*) CertChain, NULL, PKCS7_BINARY);
- if (Signers == NULL) {
- //
- // Fail to get signers form PKCS7
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- //
- // There should only be one signer in the PKCS7 stack.
- //
- NumberSigners = sk_X509_num (Signers);
- if (NumberSigners != 1) {
- //
- // The number of singers should have been 1
- //
- Status = EFI_NOT_FOUND;
- goto Exit;
- }
-
- *SignerCert = sk_X509_value (Signers, 0);
-
-Exit:
- //
- // Release Resources
- //
- if (Signers != NULL) {
- sk_X509_free (Signers);
- }
-
- return Status;
-}
-
-
-/**
- Determines if the specified EKU represented in ASN1 form is present
- in a given certificate.
-
- @param[in] Cert The certificate to check.
-
- @param[in] Asn1ToFind The EKU to look for.
-
- @retval EFI_SUCCESS We successfully identified the signing type.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
- @retval EFI_NOT_FOUND One or more EKU's were not found in the signature.
-
-**/
-EFI_STATUS
-IsEkuInCertificate (
- IN CONST X509 *Cert,
- IN ASN1_OBJECT *Asn1ToFind
- )
-{
- EFI_STATUS Status;
- X509 *ClonedCert;
- X509_EXTENSION *Extension;
- EXTENDED_KEY_USAGE *Eku;
- INT32 ExtensionIndex;
- INTN NumExtensions;
- ASN1_OBJECT *Asn1InCert;
- INTN Index;
-
- Status = EFI_NOT_FOUND;
- ClonedCert = NULL;
- Extension = NULL;
- Eku = NULL;
- ExtensionIndex = -1;
- NumExtensions = 0;
- Asn1InCert = NULL;
-
- if (Cert == NULL || Asn1ToFind == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- //
- // Clone the certificate. This is required because the Extension API's
- // only work once per instance of an X509 object.
- //
- ClonedCert = X509_dup ((X509*)Cert);
- if (ClonedCert == NULL) {
- //
- // Fail to duplicate cert.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- //
- // Look for the extended key usage.
- //
- ExtensionIndex = X509_get_ext_by_NID (ClonedCert, NID_ext_key_usage, -1);
-
- if (ExtensionIndex < 0) {
- //
- // Fail to find 'NID_ext_key_usage' in Cert.
- //
- goto Exit;
- }
-
- Extension = X509_get_ext (ClonedCert, ExtensionIndex);
- if (Extension == NULL) {
- //
- // Fail to get Extension form cert.
- //
- goto Exit;
- }
-
- Eku = (EXTENDED_KEY_USAGE*)X509V3_EXT_d2i (Extension);
- if (Eku == NULL) {
- //
- // Fail to get Eku from extension.
- //
- goto Exit;
- }
-
- NumExtensions = sk_ASN1_OBJECT_num (Eku);
-
- //
- // Now loop through the extensions, looking for the specified Eku.
- //
- for (Index = 0; Index < NumExtensions; Index++) {
- Asn1InCert = sk_ASN1_OBJECT_value (Eku, (INT32)Index);
- if (Asn1InCert == NULL) {
- //
- // Fail to get ASN object from Eku.
- //
- goto Exit;
- }
-
- if (Asn1InCert->length == Asn1ToFind->length &&
- CompareMem (Asn1InCert->data, Asn1ToFind->data, Asn1InCert->length) == 0) {
- //
- // Found Eku in certificate.
- //
- Status = EFI_SUCCESS;
- goto Exit;
- }
- }
-
-Exit:
-
- //
- // Release Resources
- //
- if (ClonedCert != NULL) {
- X509_free (ClonedCert);
- }
-
- if (Eku != NULL) {
- sk_ASN1_OBJECT_pop_free (Eku, ASN1_OBJECT_free);
- }
-
- return Status;
-}
-
-
-/**
- Determines if the specified EKUs are present in a signing certificate.
-
- @param[in] SignerCert The certificate to check.
- @param[in] RequiredEKUs The EKUs to look for.
- @param[in] RequiredEKUsSize The number of EKUs
- @param[in] RequireAllPresent If TRUE, then all the specified EKUs
- must be present in the certificate.
-
- @retval EFI_SUCCESS We successfully identified the signing type.
- @retval EFI_INVALID_PARAMETER A parameter was invalid.
- @retval EFI_NOT_FOUND One or more EKU's were not found in the signature.
-**/
-EFI_STATUS
-CheckEKUs(
- IN CONST X509 *SignerCert,
- IN CONST CHAR8 *RequiredEKUs[],
- IN CONST UINT32 RequiredEKUsSize,
- IN BOOLEAN RequireAllPresent
- )
-{
- EFI_STATUS Status;
- ASN1_OBJECT *Asn1ToFind;
- UINT32 NumEkusFound;
- UINT32 Index;
-
- Status = EFI_SUCCESS;
- Asn1ToFind = NULL;
- NumEkusFound = 0;
-
- if (SignerCert == NULL || RequiredEKUs == NULL || RequiredEKUsSize == 0) {
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- for (Index = 0; Index < RequiredEKUsSize; Index++) {
- //
- // Finding required EKU in cert.
- //
- if (Asn1ToFind != NULL) {
- ASN1_OBJECT_free(Asn1ToFind);
- Asn1ToFind = NULL;
- }
-
- Asn1ToFind = OBJ_txt2obj (RequiredEKUs[Index], 0);
- if (Asn1ToFind == NULL) {
- //
- // Fail to convert required EKU to ASN1.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
-
- Status = IsEkuInCertificate (SignerCert, Asn1ToFind);
- if (Status == EFI_SUCCESS) {
- NumEkusFound++;
- if (!RequireAllPresent) {
- //
- // Found at least one, so we are done.
- //
- goto Exit;
- }
- } else {
- //
- // Fail to find Eku in cert
- break;
- }
- }
-
-Exit:
-
- if (Asn1ToFind != NULL) {
- ASN1_OBJECT_free(Asn1ToFind);
- }
-
- if (RequireAllPresent &&
- NumEkusFound == RequiredEKUsSize) {
- //
- // Found all required EKUs in certificate.
- //
- Status = EFI_SUCCESS;
- }
-
- return Status;
-}
/**
This function receives a PKCS#7 formatted signature blob,
@@ -357,135 +54,62 @@ VerifyEKUsInPkcs7Signature (
IN BOOLEAN RequireAllPresent
)
{
- EFI_STATUS Status;
- PKCS7 *Pkcs7;
- STACK_OF(X509) *CertChain;
- INT32 SignatureType;
- INT32 NumberCertsInSignature;
- X509 *SignerCert;
- UINT8 *SignedData;
- UINT8 *Temp;
- UINTN SignedDataSize;
- BOOLEAN IsWrapped;
- BOOLEAN Ok;
+ BOOLEAN Status;
+ UINT8 *SignedData;
+ UINTN SignedDataSize;
+ BOOLEAN Wrapped;
+ INTN Ret;
+ mbedtls_pkcs7 Pkcs7;
+ mbedtls_x509_crt *Cert;
+ UINT8 *SingleCert;
- Status = EFI_SUCCESS;
- Pkcs7 = NULL;
- CertChain = NULL;
- SignatureType = 0;
- NumberCertsInSignature = 0;
- SignerCert = NULL;
- SignedData = NULL;
- SignedDataSize = 0;
- IsWrapped = FALSE;
- Ok = FALSE;
+ mbedtls_pkcs7_init(&Pkcs7);
//
- //Validate the input parameters.
+ // Check input parameter.
//
- if (Pkcs7Signature == NULL ||
- SignatureSize == 0 ||
- RequiredEKUs == NULL ||
- RequiredEKUsSize == 0) {
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
+ if ((RequiredEKUs == NULL) || (Pkcs7Signature == NULL))
+ {
+ return FALSE;
}
- if (RequiredEKUsSize == 1) {
- RequireAllPresent = TRUE;
- }
+ SignedData = NULL;
- //
- // Wrap the PKCS7 data if needed.
- //
- Ok = WrapPkcs7Data (Pkcs7Signature,
- SignatureSize,
- &IsWrapped,
- &SignedData,
- &SignedDataSize);
- if (!Ok) {
- //
- // Fail to Wrap the PKCS7 data.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
+ Status = WrapPkcs7Data (Pkcs7Signature, SignatureSize, &Wrapped, &SignedData, &SignedDataSize);
+ if (!Status || (SignedDataSize > INT_MAX)) {
+ goto _Exit;
}
- Temp = SignedData;
+ Status = FALSE;
//
- // Create the PKCS7 object.
+ // Retrieve PKCS#7 Data (DER encoding)
//
- Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (INT32)SignedDataSize);
- if (Pkcs7 == NULL) {
- //
- // Fail to read PKCS7 data.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
+ if (SignedDataSize > INT_MAX) {
+ goto _Exit;
}
- //
- // Get the certificate chain.
- //
- SignatureType = OBJ_obj2nid (Pkcs7->type);
- switch (SignatureType) {
- case NID_pkcs7_signed:
- if (Pkcs7->d.sign != NULL) {
- CertChain = Pkcs7->d.sign->cert;
- }
- break;
- case NID_pkcs7_signedAndEnveloped:
- if (Pkcs7->d.signed_and_enveloped != NULL) {
- CertChain = Pkcs7->d.signed_and_enveloped->cert;
- }
- break;
- default:
- break;
- }
+ Ret = mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSize);
//
- // Ensure we have a certificate stack
+ // The type of Pkcs7 must be signedData
//
- if (CertChain == NULL) {
- //
- // Fail to get the certificate stack from signature.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
+ if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
+ goto _Exit;
}
- //
- // Find out how many certificates were in the PKCS7 signature.
- //
- NumberCertsInSignature = sk_X509_num (CertChain);
- if (NumberCertsInSignature == 0) {
- //
- // Fail to find any certificates in signature.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
+ Cert = NULL;
+ SingleCert = NULL;
- //
- // Get the leaf signer.
- //
- Status = GetSignerCertificate (Pkcs7, &SignerCert);
- if (Status != EFI_SUCCESS || SignerCert == NULL) {
- //
- // Fail to get the end-entity leaf signer certificate.
- //
- Status = EFI_INVALID_PARAMETER;
- goto Exit;
- }
- Status = CheckEKUs (SignerCert, RequiredEKUs, RequiredEKUsSize, RequireAllPresent);
- if (Status != EFI_SUCCESS) {
- goto Exit;
+ Cert = &Pkcs7.signed_data.certs;
+ if (Cert == NULL) {
+ goto _Exit;
}
-Exit:
+
+_Exit:
//
// Release Resources
@@ -493,17 +117,11 @@ Exit:
// If the signature was not wrapped, then the call to WrapData() will allocate
// the data and add a header to it
//
- if (!IsWrapped && SignedData) {
- free (SignedData);
+ if (!Wrapped && SignedData) {
+ FreePool (SignedData);
}
- if (SignerCert != NULL) {
- X509_free (SignerCert);
- }
-
- if (Pkcs7 != NULL) {
- PKCS7_free (Pkcs7);
- }
+ mbedtls_pkcs7_free (&Pkcs7);
return Status;
}
diff --git a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
index b735fef49e..69d712b9c6 100644
--- a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
+++ b/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
@@ -108,6 +108,7 @@
mbedtls/library/x509_crl.c
mbedtls/library/x509_crt.c
mbedtls/library/x509_csr.c
+ mbedtls/library/pkcs7.c
[Packages]
MdePkg/MdePkg.dec
--
2.26.2.windows.1
next prev parent reply other threads:[~2023-03-17 9:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-17 9:00 [edk2-staging/OpenSSL11_EOL PATCH 0/7] Enable MbedTLS for CryptoPkg update Mar 17 Wenxing Hou
2023-03-17 9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 1/7] Update ReadmeMbedtls Wenxing Hou
2023-03-17 9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 2/7] Clear unnecessary API in DH Wenxing Hou
2023-03-17 9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 3/7] Make all BaseCryptLibMbedTls inf files consistent with BaseCryptLib Wenxing Hou
2023-03-17 9:00 ` Wenxing Hou [this message]
2023-03-17 9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 5/7] Update EC api based on MbedTlsLib for CryptoPkg Wenxing Hou
2023-03-17 9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 6/7] Update X509 " Wenxing Hou
2023-03-17 9:00 ` [edk2-staging/OpenSSL11_EOL PATCH 7/7] Clean SysCall api by adding platform_util.c Wenxing Hou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230317090053.1895-5-wenxing.hou@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox