From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by mx.groups.io with SMTP id smtpd.web10.14911.1679043720870874677 for ; Fri, 17 Mar 2023 02:02:08 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=dIHRJILx; spf=pass (domain: intel.com, ip: 192.55.52.136, mailfrom: wenxing.hou@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1679043728; x=1710579728; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=e6qRp2Di+RXrDlSxi7BFWGszbRbBReWnI1Hc10DRBzw=; b=dIHRJILx8R3xfwKHnnqB2Cm1oWd40PPoxrLdyXfcOe6rol4chAvSsaTG nGDGj8h+xHSnegOQrazJGKg7/+S42WVrdF0sdAEIoubgqVBVvqq3y798m OD0ZrNTlp0o7HTyvZwzliK41hZLPWNJfA4cVuoS2X67RMmVPeQ7A3TXQM DQzYoCub++ILO+3VseKE+4W5LnANAiqvmaaVnRDyWcpRCagilKGA3VSOs oQBc4uUJqruhjjp01/OZ5t/BAMzUYgduBukZCf16eaocOh8uVZUPdHyTj FgvfwaiZuFv0mK1UfJa9U0fZBjUXFgABGbbrBhkS7ped0MHVdRcCDYiZ6 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10651"; a="317871153" X-IronPort-AV: E=Sophos;i="5.98,268,1673942400"; d="scan'208";a="317871153" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Mar 2023 02:02:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10651"; a="926066877" X-IronPort-AV: E=Sophos;i="5.98,268,1673942400"; d="scan'208";a="926066877" Received: from shwdejointd777.ccr.corp.intel.com ([10.239.157.39]) by fmsmga006.fm.intel.com with ESMTP; 17 Mar 2023 02:02:07 -0700 From: "Wenxing Hou" To: devel@edk2.groups.io Cc: Wenxing Hou 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 Message-Id: <20230317090053.1895-5-wenxing.hou@intel.com> X-Mailer: git-send-email 2.26.2.windows.1 In-Reply-To: <20230317090053.1895-1-wenxing.hou@intel.com> References: <20230317090053.1895-1-wenxing.hou@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Signed-off-by: Wenxing Hou --- .../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/Cry= ptoPkg/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 =0D int myrand( void *rng_state, unsigned char *output, size_t len );=0D =0D +/**=0D + Check input P7Data is a wrapped ContentInfo structure or not. If not con= struct=0D + a new structure to wrap P7Data.=0D +=0D + Caution: This function may receive untrusted input.=0D + UEFI Authenticated Variable is external input, so this function will do = basic=0D + check for PKCS#7 data structure.=0D +=0D + @param[in] P7Data Pointer to the PKCS#7 message to verify.=0D + @param[in] P7Length Length of the PKCS#7 message in bytes.=0D + @param[out] WrapFlag If TRUE P7Data is a ContentInfo structure, othe= rwise=0D + return FALSE.=0D + @param[out] WrapData If return status of this function is TRUE:=0D + 1) when WrapFlag is TRUE, pointer to P7Data.=0D + 2) when WrapFlag is FALSE, pointer to a new Con= tentInfo=0D + structure. It's caller's responsibility to free= this=0D + buffer.=0D + @param[out] WrapDataSize Length of ContentInfo structure in bytes.=0D +=0D + @retval TRUE The operation is finished successfully.=0D + @retval FALSE The operation is failed due to lack of resource= s.=0D +=0D +**/=0D +BOOLEAN=0D +WrapPkcs7Data (=0D + IN CONST UINT8 *P7Data,=0D + IN UINTN P7Length,=0D + OUT BOOLEAN *WrapFlag,=0D + OUT UINT8 **WrapData,=0D + OUT UINTN *WrapDataSize=0D + );=0D +=0D #endif=0D diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7Sign.c b/Cr= yptoPkg/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);=0D Ret =3D mbedtls_pk_parse_key (=0D &Pkey, NewPrivateKey, PrivateKeySize,=0D - KeyPassword, KeyPassword =3D=3D NULL ? 0 : AsciiStrLen (KeyPassword)=0D + KeyPassword, KeyPassword =3D=3D NULL ? 0 : AsciiStrLen (KeyPassword),= =0D + NULL, NULL=0D );=0D if (Ret !=3D 0) {=0D Status =3D FALSE;=0D @@ -406,7 +407,7 @@ Pkcs7Sign ( ZeroMem (Signature, MAX_SIGNATURE_SIZE);=0D Ret =3D mbedtls_pk_sign (=0D &Pkey, MBEDTLS_MD_SHA256, HashValue, SHA256_DIGEST_SIZE,=0D - Signature, &SignatureLen, myrand, NULL);=0D + Signature, MAX_SIGNATURE_SIZE, &SignatureLen, myrand, NULL);=0D if (Ret !=3D 0) {=0D Status =3D FALSE;=0D goto Cleanup;=0D 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 **/=0D =0D #include "InternalCryptLib.h"=0D +#include =0D =0D /**=0D Extracts the attached content from a PKCS#7 signed data if existed. The = input signed=0D @@ -38,12 +39,13 @@ Pkcs7GetAttachedContent ( )=0D {=0D BOOLEAN Status;=0D - PKCS7 *Pkcs7;=0D UINT8 *SignedData;=0D UINTN SignedDataSize;=0D BOOLEAN Wrapped;=0D - CONST UINT8 *Temp;=0D - ASN1_OCTET_STRING *OctStr;=0D + INTN Ret;=0D + mbedtls_pkcs7 Pkcs7;=0D +=0D + mbedtls_pkcs7_init(&Pkcs7);=0D =0D //=0D // Check input parameter.=0D @@ -53,9 +55,7 @@ Pkcs7GetAttachedContent ( }=0D =0D *Content =3D NULL;=0D - Pkcs7 =3D NULL;=0D SignedData =3D NULL;=0D - OctStr =3D NULL;=0D =0D Status =3D WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &Sign= edDataSize);=0D if (!Status || (SignedDataSize > INT_MAX)) {=0D @@ -64,26 +64,23 @@ Pkcs7GetAttachedContent ( =0D Status =3D FALSE;=0D =0D - //=0D - // Decoding PKCS#7 SignedData=0D - //=0D - Temp =3D SignedData;=0D - Pkcs7 =3D d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDat= aSize);=0D - if (Pkcs7 =3D=3D NULL) {=0D - goto _Exit;=0D - }=0D + Ret =3D mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSiz= e);=0D =0D //=0D // The type of Pkcs7 must be signedData=0D //=0D - if (!PKCS7_type_is_signed (Pkcs7)) {=0D + if (Ret !=3D MBEDTLS_PKCS7_SIGNED_DATA) {=0D goto _Exit;=0D }=0D =0D //=0D // Check for detached or attached content=0D //=0D - if (PKCS7_get_detached (Pkcs7)) {=0D +=0D + mbedtls_pkcs7_data *MbedtlsContent;=0D + MbedtlsContent =3D &(Pkcs7.signed_data.content);=0D +=0D + if (MbedtlsContent =3D=3D NULL) {=0D //=0D // No Content supplied for PKCS7 detached signedData=0D //=0D @@ -93,15 +90,14 @@ Pkcs7GetAttachedContent ( //=0D // Retrieve the attached content in PKCS7 signedData=0D //=0D - OctStr =3D Pkcs7->d.sign->contents->d.data;=0D - if ((OctStr->length > 0) && (OctStr->data !=3D NULL)) {=0D - *ContentSize =3D OctStr->length;=0D + if ((MbedtlsContent->data.len > 0) && (MbedtlsContent->data.p !=3D NUL= L)) {=0D + *ContentSize =3D MbedtlsContent->data.len;=0D *Content =3D AllocatePool (*ContentSize);=0D if (*Content =3D=3D NULL) {=0D *ContentSize =3D 0;=0D goto _Exit;=0D }=0D - CopyMem (*Content, OctStr->data, *ContentSize);=0D + CopyMem (*Content, MbedtlsContent->data.p, *ContentSize);=0D }=0D }=0D Status =3D TRUE;=0D @@ -110,11 +106,7 @@ _Exit: //=0D // Release Resources=0D //=0D - PKCS7_free (Pkcs7);=0D -=0D - if (!Wrapped) {=0D - OPENSSL_free (SignedData);=0D - }=0D + mbedtls_pkcs7_free (&Pkcs7);=0D =0D return Status;=0D }=0D diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptPkcs7VerifyCommo= n.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 ( =0D Status =3D WrapPkcs7Data (P7Data, P7Length, &Wrapped, &WrapData, &WrapDa= taSize);=0D =0D - if (Status) {=0D + if (!Status) {=0D Ret =3D 0;=0D Status =3D FALSE;=0D } else {=0D @@ -741,5 +741,339 @@ Pkcs7GetSigners ( OUT UINTN *CertLength=0D )=0D {=0D -return FALSE;=0D + BOOLEAN Status;=0D + UINT8 *SignedData;=0D + UINTN SignedDataSize;=0D + BOOLEAN Wrapped;=0D + INTN Ret;=0D + mbedtls_pkcs7 Pkcs7;=0D + mbedtls_x509_crt *Cert;=0D + UINT8 Index;=0D + UINT8 *CertBuf;=0D + UINT8 *OldBuf;=0D + UINTN BufferSize;=0D + UINTN OldSize;=0D + UINT8 *SingleCert;=0D + UINTN SingleCertSize;=0D +=0D +=0D + mbedtls_pkcs7_init(&Pkcs7);=0D +=0D + //=0D + // Check input parameter.=0D + //=0D + if ((P7Data =3D=3D NULL) || (CertStack =3D=3D NULL) || (StackLength =3D= =3D NULL) ||=0D + (TrustedCert =3D=3D NULL) || (CertLength =3D=3D NULL) || (P7Length >= INT_MAX))=0D + {=0D + return FALSE;=0D + }=0D +=0D + SignedData =3D NULL;=0D +=0D + Status =3D WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &Sign= edDataSize);=0D + if (!Status || (SignedDataSize > INT_MAX)) {=0D + goto _Exit;=0D + }=0D +=0D + Status =3D FALSE;=0D +=0D + //=0D + // Retrieve PKCS#7 Data (DER encoding)=0D + //=0D + if (SignedDataSize > INT_MAX) {=0D + goto _Exit;=0D + }=0D +=0D + Ret =3D mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSiz= e);=0D +=0D + //=0D + // The type of Pkcs7 must be signedData=0D + //=0D + if (Ret !=3D MBEDTLS_PKCS7_SIGNED_DATA) {=0D + goto _Exit;=0D + }=0D +=0D +=0D + Cert =3D NULL;=0D + CertBuf =3D NULL;=0D + OldBuf =3D NULL;=0D + SingleCert =3D NULL;=0D +=0D +=0D + Cert =3D &Pkcs7.signed_data.certs;=0D + if (Cert =3D=3D NULL) {=0D + goto _Exit;=0D + }=0D +=0D + //=0D + // Convert CertStack to buffer in following format:=0D + // UINT8 CertNumber;=0D + // UINT32 Cert1Length;=0D + // UINT8 Cert1[];=0D + // UINT32 Cert2Length;=0D + // UINT8 Cert2[];=0D + // ...=0D + // UINT32 CertnLength;=0D + // UINT8 Certn[];=0D + //=0D + BufferSize =3D sizeof (UINT8);=0D + OldSize =3D BufferSize;=0D +=0D + for (Index =3D 0; ; Index++) {=0D +=0D + SingleCertSize =3D Cert->raw.len;=0D +=0D + OldSize =3D BufferSize;=0D + OldBuf =3D CertBuf;=0D + BufferSize =3D OldSize + SingleCertSize + sizeof (UINT32);=0D + CertBuf =3D AllocateZeroPool (BufferSize);=0D +=0D + if (CertBuf =3D=3D NULL) {=0D + goto _Exit;=0D + }=0D +=0D + if (OldBuf !=3D NULL) {=0D + CopyMem (CertBuf, OldBuf, OldSize);=0D + FreePool (OldBuf);=0D + OldBuf =3D NULL;=0D + }=0D +=0D + WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSiz= e);=0D + CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSi= ze);=0D +=0D + FreePool (SingleCert);=0D + SingleCert =3D NULL;=0D +=0D + if (Cert->next =3D=3D NULL) {=0D + break;=0D + }=0D + }=0D +=0D + if (CertBuf !=3D NULL) {=0D + //=0D + // Update CertNumber.=0D + //=0D + CertBuf[0] =3D Index;=0D +=0D + *CertLength =3D BufferSize - OldSize - sizeof (UINT32);=0D + *TrustedCert =3D AllocateZeroPool (*CertLength);=0D + if (*TrustedCert =3D=3D NULL) {=0D + goto _Exit;=0D + }=0D +=0D + CopyMem (*TrustedCert, CertBuf + OldSize + sizeof (UINT32), *CertLengt= h);=0D + *CertStack =3D CertBuf;=0D + *StackLength =3D BufferSize;=0D + Status =3D TRUE;=0D + }=0D +=0D +_Exit:=0D + //=0D + // Release Resources=0D + //=0D + if (!Wrapped) {=0D + FreePool (SignedData);=0D + }=0D +=0D + mbedtls_pkcs7_free (&Pkcs7);=0D +=0D + if (SingleCert !=3D NULL) {=0D + FreePool (SingleCert);=0D + }=0D +=0D + if (!Status && (CertBuf !=3D NULL)) {=0D + FreePool (CertBuf);=0D + *CertStack =3D NULL;=0D + }=0D +=0D + if (OldBuf !=3D NULL) {=0D + FreePool (OldBuf);=0D + }=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Retrieves all embedded certificates from PKCS#7 signed data as described= in "PKCS #7:=0D + Cryptographic Message Syntax Standard", and outputs two certificate list= s chained and=0D + unchained to the signer's certificates.=0D + The input signed data could be wrapped in a ContentInfo structure.=0D +=0D + @param[in] P7Data Pointer to the PKCS#7 message.=0D + @param[in] P7Length Length of the PKCS#7 message in bytes.=0D + @param[out] SignerChainCerts Pointer to the certificates list chained t= o signer's=0D + certificate. It's caller's responsibility = to free the buffer=0D + with Pkcs7FreeSigners().=0D + This data structure is EFI_CERT_STACK type= .=0D + @param[out] ChainLength Length of the chained certificates list bu= ffer in bytes.=0D + @param[out] UnchainCerts Pointer to the unchained certificates list= s. It's caller's=0D + responsibility to free the buffer with Pkc= s7FreeSigners().=0D + This data structure is EFI_CERT_STACK type= .=0D + @param[out] UnchainLength Length of the unchained certificates list = buffer in bytes.=0D +=0D + @retval TRUE The operation is finished successfully.=0D + @retval FALSE Error occurs during the operation.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Pkcs7GetCertificatesList (=0D + IN CONST UINT8 *P7Data,=0D + IN UINTN P7Length,=0D + OUT UINT8 **SignerChainCerts,=0D + OUT UINTN *ChainLength,=0D + OUT UINT8 **UnchainCerts,=0D + OUT UINTN *UnchainLength=0D + )=0D +{=0D + BOOLEAN Status;=0D + UINT8 *SignedData;=0D + UINTN SignedDataSize;=0D + BOOLEAN Wrapped;=0D + INTN Ret;=0D + mbedtls_pkcs7 Pkcs7;=0D + mbedtls_x509_crt *Cert;=0D + UINT8 Index;=0D + UINT8 *CertBuf;=0D + UINT8 *OldBuf;=0D + UINTN BufferSize;=0D + UINTN OldSize;=0D + UINT8 *SingleCert;=0D + UINTN SingleCertSize;=0D +=0D +=0D + mbedtls_pkcs7_init(&Pkcs7);=0D +=0D + //=0D + // Check input parameter.=0D + //=0D + if ((P7Data =3D=3D NULL) || (SignerChainCerts =3D=3D NULL) || (ChainLeng= th =3D=3D NULL) ||=0D + (UnchainCerts =3D=3D NULL) || (UnchainLength =3D=3D NULL) || (P7Leng= th > INT_MAX))=0D + {=0D + return FALSE;=0D + }=0D +=0D + SignedData =3D NULL;=0D +=0D + Status =3D WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &Sign= edDataSize);=0D + if (!Status || (SignedDataSize > INT_MAX)) {=0D + goto _Exit;=0D + }=0D +=0D + Status =3D FALSE;=0D +=0D + //=0D + // Retrieve PKCS#7 Data (DER encoding)=0D + //=0D + if (SignedDataSize > INT_MAX) {=0D + goto _Exit;=0D + }=0D +=0D + Ret =3D mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSiz= e);=0D +=0D + //=0D + // The type of Pkcs7 must be signedData=0D + //=0D + if (Ret !=3D MBEDTLS_PKCS7_SIGNED_DATA) {=0D + goto _Exit;=0D + }=0D +=0D +=0D + Cert =3D NULL;=0D + CertBuf =3D NULL;=0D + OldBuf =3D NULL;=0D + SingleCert =3D NULL;=0D +=0D +=0D + Cert =3D &Pkcs7.signed_data.certs;=0D + if (Cert =3D=3D NULL) {=0D + goto _Exit;=0D + }=0D +=0D + //=0D + // Converts Chained and Untrusted Certificate to Certificate Buffer in f= ollowing format:=0D + // UINT8 CertNumber;=0D + // UINT32 Cert1Length;=0D + // UINT8 Cert1[];=0D + // UINT32 Cert2Length;=0D + // UINT8 Cert2[];=0D + // ...=0D + // UINT32 CertnLength;=0D + // UINT8 Certn[];=0D + //=0D + BufferSize =3D sizeof (UINT8);=0D + OldSize =3D BufferSize;=0D +=0D + for (Index =3D 0; ; Index++) {=0D +=0D + SingleCertSize =3D Cert->raw.len;=0D +=0D + OldSize =3D BufferSize;=0D + OldBuf =3D CertBuf;=0D + BufferSize =3D OldSize + SingleCertSize + sizeof (UINT32);=0D + CertBuf =3D AllocateZeroPool (BufferSize);=0D +=0D + if (CertBuf =3D=3D NULL) {=0D + goto _Exit;=0D + }=0D +=0D + if (OldBuf !=3D NULL) {=0D + CopyMem (CertBuf, OldBuf, OldSize);=0D + FreePool (OldBuf);=0D + OldBuf =3D NULL;=0D + }=0D +=0D + WriteUnaligned32 ((UINT32 *)(CertBuf + OldSize), (UINT32)SingleCertSiz= e);=0D + CopyMem (CertBuf + OldSize + sizeof (UINT32), SingleCert, SingleCertSi= ze);=0D +=0D + FreePool (SingleCert);=0D + SingleCert =3D NULL;=0D +=0D + if (Cert->next =3D=3D NULL) {=0D + break;=0D + }=0D + }=0D +=0D + if (CertBuf !=3D NULL) {=0D + //=0D + // Update CertNumber.=0D + //=0D + CertBuf[0] =3D Index;=0D +=0D + *UnchainLength =3D BufferSize - OldSize - sizeof (UINT32);=0D + *UnchainCerts =3D AllocateZeroPool (*UnchainLength);=0D + if (*UnchainCerts =3D=3D NULL) {=0D + goto _Exit;=0D + }=0D +=0D + CopyMem (*UnchainCerts, CertBuf + OldSize + sizeof (UINT32), *UnchainL= ength);=0D + *SignerChainCerts =3D CertBuf;=0D + *ChainLength =3D BufferSize;=0D + Status =3D TRUE;=0D + }=0D +=0D +_Exit:=0D + //=0D + // Release Resources=0D + //=0D + if (!Wrapped) {=0D + FreePool (SignedData);=0D + }=0D +=0D + mbedtls_pkcs7_free (&Pkcs7);=0D +=0D + if (SingleCert !=3D NULL) {=0D + FreePool (SingleCert);=0D + }=0D +=0D + if (!Status && (CertBuf !=3D NULL)) {=0D + FreePool (CertBuf);=0D + *SignerChainCerts =3D NULL;=0D + }=0D +=0D + if (OldBuf !=3D NULL) {=0D + FreePool (OldBuf);=0D + }=0D +=0D + return Status;=0D }=0D 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 @@ =0D #include =0D #include "InternalCryptLib.h"=0D +#include =0D =0D -/**=0D - This function will return the leaf signer certificate in a chain. This = is=0D - required because certificate chains are not guaranteed to have the=0D - certificates in the order that they were issued.=0D -=0D - A typical certificate chain looks like this:=0D -=0D -=0D - ----------------------------=0D - | Root |=0D - ----------------------------=0D - ^=0D - |=0D - ----------------------------=0D - | Policy CA | <-- Typical Trust Anchor.=0D - ----------------------------=0D - ^=0D - |=0D - ----------------------------=0D - | Issuing CA |=0D - ----------------------------=0D - ^=0D - |=0D - -----------------------------=0D - / End-Entity (leaf) signer / <-- Bottom certificate.=0D - ----------------------------- EKU: "1.3.6.1.4.1.311.76.9.= 21.1"=0D - (Firmware Signing)=0D -=0D -=0D - @param[in] CertChain Certificate chain.=0D -=0D - @param[out] SignerCert Last certificate in the chain. For PK= CS7 signatures,=0D - this will be the end-entity (leaf) sig= ner cert.=0D -=0D - @retval EFI_SUCCESS The required EKUs were found in the si= gnature.=0D - @retval EFI_INVALID_PARAMETER A parameter was invalid.=0D - @retval EFI_NOT_FOUND The number of signers found was not 1.= =0D -=0D -**/=0D -EFI_STATUS=0D -GetSignerCertificate (=0D - IN CONST PKCS7 *CertChain,=0D - OUT X509 **SignerCert=0D - )=0D -{=0D - EFI_STATUS Status;=0D - STACK_OF(X509) *Signers;=0D - INT32 NumberSigners;=0D -=0D - Status =3D EFI_SUCCESS;=0D - Signers =3D NULL;=0D - NumberSigners =3D 0;=0D -=0D - if (CertChain =3D=3D NULL || SignerCert =3D=3D NULL) {=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D -=0D - //=0D - // Get the signers from the chain.=0D - //=0D - Signers =3D PKCS7_get0_signers ((PKCS7*) CertChain, NULL, PKCS7_BINARY);= =0D - if (Signers =3D=3D NULL) {=0D - //=0D - // Fail to get signers form PKCS7=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D -=0D - //=0D - // There should only be one signer in the PKCS7 stack.=0D - //=0D - NumberSigners =3D sk_X509_num (Signers);=0D - if (NumberSigners !=3D 1) {=0D - //=0D - // The number of singers should have been 1=0D - //=0D - Status =3D EFI_NOT_FOUND;=0D - goto Exit;=0D - }=0D -=0D - *SignerCert =3D sk_X509_value (Signers, 0);=0D -=0D -Exit:=0D - //=0D - // Release Resources=0D - //=0D - if (Signers !=3D NULL) {=0D - sk_X509_free (Signers);=0D - }=0D -=0D - return Status;=0D -}=0D -=0D -=0D -/**=0D - Determines if the specified EKU represented in ASN1 form is present=0D - in a given certificate.=0D -=0D - @param[in] Cert The certificate to check.=0D -=0D - @param[in] Asn1ToFind The EKU to look for.=0D -=0D - @retval EFI_SUCCESS We successfully identified the signing= type.=0D - @retval EFI_INVALID_PARAMETER A parameter was invalid.=0D - @retval EFI_NOT_FOUND One or more EKU's were not found in th= e signature.=0D -=0D -**/=0D -EFI_STATUS=0D -IsEkuInCertificate (=0D - IN CONST X509 *Cert,=0D - IN ASN1_OBJECT *Asn1ToFind=0D - )=0D -{=0D - EFI_STATUS Status;=0D - X509 *ClonedCert;=0D - X509_EXTENSION *Extension;=0D - EXTENDED_KEY_USAGE *Eku;=0D - INT32 ExtensionIndex;=0D - INTN NumExtensions;=0D - ASN1_OBJECT *Asn1InCert;=0D - INTN Index;=0D -=0D - Status =3D EFI_NOT_FOUND;=0D - ClonedCert =3D NULL;=0D - Extension =3D NULL;=0D - Eku =3D NULL;=0D - ExtensionIndex =3D -1;=0D - NumExtensions =3D 0;=0D - Asn1InCert =3D NULL;=0D -=0D - if (Cert =3D=3D NULL || Asn1ToFind =3D=3D NULL) {=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D -=0D - //=0D - // Clone the certificate. This is required because the Extension API's= =0D - // only work once per instance of an X509 object.=0D - //=0D - ClonedCert =3D X509_dup ((X509*)Cert);=0D - if (ClonedCert =3D=3D NULL) {=0D - //=0D - // Fail to duplicate cert.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D -=0D - //=0D - // Look for the extended key usage.=0D - //=0D - ExtensionIndex =3D X509_get_ext_by_NID (ClonedCert, NID_ext_key_usage, -= 1);=0D -=0D - if (ExtensionIndex < 0) {=0D - //=0D - // Fail to find 'NID_ext_key_usage' in Cert.=0D - //=0D - goto Exit;=0D - }=0D -=0D - Extension =3D X509_get_ext (ClonedCert, ExtensionIndex);=0D - if (Extension =3D=3D NULL) {=0D - //=0D - // Fail to get Extension form cert.=0D - //=0D - goto Exit;=0D - }=0D -=0D - Eku =3D (EXTENDED_KEY_USAGE*)X509V3_EXT_d2i (Extension);=0D - if (Eku =3D=3D NULL) {=0D - //=0D - // Fail to get Eku from extension.=0D - //=0D - goto Exit;=0D - }=0D -=0D - NumExtensions =3D sk_ASN1_OBJECT_num (Eku);=0D -=0D - //=0D - // Now loop through the extensions, looking for the specified Eku.=0D - //=0D - for (Index =3D 0; Index < NumExtensions; Index++) {=0D - Asn1InCert =3D sk_ASN1_OBJECT_value (Eku, (INT32)Index);=0D - if (Asn1InCert =3D=3D NULL) {=0D - //=0D - // Fail to get ASN object from Eku.=0D - //=0D - goto Exit;=0D - }=0D -=0D - if (Asn1InCert->length =3D=3D Asn1ToFind->length &&=0D - CompareMem (Asn1InCert->data, Asn1ToFind->data, Asn1InCert->length= ) =3D=3D 0) {=0D - //=0D - // Found Eku in certificate.=0D - //=0D - Status =3D EFI_SUCCESS;=0D - goto Exit;=0D - }=0D - }=0D -=0D -Exit:=0D -=0D - //=0D - // Release Resources=0D - //=0D - if (ClonedCert !=3D NULL) {=0D - X509_free (ClonedCert);=0D - }=0D -=0D - if (Eku !=3D NULL) {=0D - sk_ASN1_OBJECT_pop_free (Eku, ASN1_OBJECT_free);=0D - }=0D -=0D - return Status;=0D -}=0D -=0D -=0D -/**=0D - Determines if the specified EKUs are present in a signing certificate.=0D -=0D - @param[in] SignerCert The certificate to check.=0D - @param[in] RequiredEKUs The EKUs to look for.=0D - @param[in] RequiredEKUsSize The number of EKUs=0D - @param[in] RequireAllPresent If TRUE, then all the specified EKUs=0D - must be present in the certificate.=0D -=0D - @retval EFI_SUCCESS We successfully identified the signing= type.=0D - @retval EFI_INVALID_PARAMETER A parameter was invalid.=0D - @retval EFI_NOT_FOUND One or more EKU's were not found in th= e signature.=0D -**/=0D -EFI_STATUS=0D -CheckEKUs(=0D - IN CONST X509 *SignerCert,=0D - IN CONST CHAR8 *RequiredEKUs[],=0D - IN CONST UINT32 RequiredEKUsSize,=0D - IN BOOLEAN RequireAllPresent=0D - )=0D -{=0D - EFI_STATUS Status;=0D - ASN1_OBJECT *Asn1ToFind;=0D - UINT32 NumEkusFound;=0D - UINT32 Index;=0D -=0D - Status =3D EFI_SUCCESS;=0D - Asn1ToFind =3D NULL;=0D - NumEkusFound =3D 0;=0D -=0D - if (SignerCert =3D=3D NULL || RequiredEKUs =3D=3D NULL || RequiredEKUsSi= ze =3D=3D 0) {=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D -=0D - for (Index =3D 0; Index < RequiredEKUsSize; Index++) {=0D - //=0D - // Finding required EKU in cert.=0D - //=0D - if (Asn1ToFind !=3D NULL) {=0D - ASN1_OBJECT_free(Asn1ToFind);=0D - Asn1ToFind =3D NULL;=0D - }=0D -=0D - Asn1ToFind =3D OBJ_txt2obj (RequiredEKUs[Index], 0);=0D - if (Asn1ToFind =3D=3D NULL) {=0D - //=0D - // Fail to convert required EKU to ASN1.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D -=0D - Status =3D IsEkuInCertificate (SignerCert, Asn1ToFind);=0D - if (Status =3D=3D EFI_SUCCESS) {=0D - NumEkusFound++;=0D - if (!RequireAllPresent) {=0D - //=0D - // Found at least one, so we are done.=0D - //=0D - goto Exit;=0D - }=0D - } else {=0D - //=0D - // Fail to find Eku in cert=0D - break;=0D - }=0D - }=0D -=0D -Exit:=0D -=0D - if (Asn1ToFind !=3D NULL) {=0D - ASN1_OBJECT_free(Asn1ToFind);=0D - }=0D -=0D - if (RequireAllPresent &&=0D - NumEkusFound =3D=3D RequiredEKUsSize) {=0D - //=0D - // Found all required EKUs in certificate.=0D - //=0D - Status =3D EFI_SUCCESS;=0D - }=0D -=0D - return Status;=0D -}=0D =0D /**=0D This function receives a PKCS#7 formatted signature blob,=0D @@ -357,135 +54,62 @@ VerifyEKUsInPkcs7Signature ( IN BOOLEAN RequireAllPresent=0D )=0D {=0D - EFI_STATUS Status;=0D - PKCS7 *Pkcs7;=0D - STACK_OF(X509) *CertChain;=0D - INT32 SignatureType;=0D - INT32 NumberCertsInSignature;=0D - X509 *SignerCert;=0D - UINT8 *SignedData;=0D - UINT8 *Temp;=0D - UINTN SignedDataSize;=0D - BOOLEAN IsWrapped;=0D - BOOLEAN Ok;=0D + BOOLEAN Status;=0D + UINT8 *SignedData;=0D + UINTN SignedDataSize;=0D + BOOLEAN Wrapped;=0D + INTN Ret;=0D + mbedtls_pkcs7 Pkcs7;=0D + mbedtls_x509_crt *Cert;=0D + UINT8 *SingleCert;=0D =0D - Status =3D EFI_SUCCESS;=0D - Pkcs7 =3D NULL;=0D - CertChain =3D NULL;=0D - SignatureType =3D 0;=0D - NumberCertsInSignature =3D 0;=0D - SignerCert =3D NULL;=0D - SignedData =3D NULL;=0D - SignedDataSize =3D 0;=0D - IsWrapped =3D FALSE;=0D - Ok =3D FALSE;=0D + mbedtls_pkcs7_init(&Pkcs7);=0D =0D //=0D - //Validate the input parameters.=0D + // Check input parameter.=0D //=0D - if (Pkcs7Signature =3D=3D NULL ||=0D - SignatureSize =3D=3D 0 ||=0D - RequiredEKUs =3D=3D NULL ||=0D - RequiredEKUsSize =3D=3D 0) {=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D + if ((RequiredEKUs =3D=3D NULL) || (Pkcs7Signature =3D=3D NULL))=0D + {=0D + return FALSE;=0D }=0D =0D - if (RequiredEKUsSize =3D=3D 1) {=0D - RequireAllPresent =3D TRUE;=0D - }=0D + SignedData =3D NULL;=0D =0D - //=0D - // Wrap the PKCS7 data if needed.=0D - //=0D - Ok =3D WrapPkcs7Data (Pkcs7Signature,=0D - SignatureSize,=0D - &IsWrapped,=0D - &SignedData,=0D - &SignedDataSize);=0D - if (!Ok) {=0D - //=0D - // Fail to Wrap the PKCS7 data.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D + Status =3D WrapPkcs7Data (Pkcs7Signature, SignatureSize, &Wrapped, &Sign= edData, &SignedDataSize);=0D + if (!Status || (SignedDataSize > INT_MAX)) {=0D + goto _Exit;=0D }=0D =0D - Temp =3D SignedData;=0D + Status =3D FALSE;=0D =0D //=0D - // Create the PKCS7 object.=0D + // Retrieve PKCS#7 Data (DER encoding)=0D //=0D - Pkcs7 =3D d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (INT32)SignedD= ataSize);=0D - if (Pkcs7 =3D=3D NULL) {=0D - //=0D - // Fail to read PKCS7 data.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D + if (SignedDataSize > INT_MAX) {=0D + goto _Exit;=0D }=0D =0D - //=0D - // Get the certificate chain.=0D - //=0D - SignatureType =3D OBJ_obj2nid (Pkcs7->type);=0D - switch (SignatureType) {=0D - case NID_pkcs7_signed:=0D - if (Pkcs7->d.sign !=3D NULL) {=0D - CertChain =3D Pkcs7->d.sign->cert;=0D - }=0D - break;=0D - case NID_pkcs7_signedAndEnveloped:=0D - if (Pkcs7->d.signed_and_enveloped !=3D NULL) {=0D - CertChain =3D Pkcs7->d.signed_and_enveloped->cert;=0D - }=0D - break;=0D - default:=0D - break;=0D - }=0D + Ret =3D mbedtls_pkcs7_parse_der(&Pkcs7, SignedData, (INT32)SignedDataSiz= e);=0D =0D //=0D - // Ensure we have a certificate stack=0D + // The type of Pkcs7 must be signedData=0D //=0D - if (CertChain =3D=3D NULL) {=0D - //=0D - // Fail to get the certificate stack from signature.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D + if (Ret !=3D MBEDTLS_PKCS7_SIGNED_DATA) {=0D + goto _Exit;=0D }=0D =0D - //=0D - // Find out how many certificates were in the PKCS7 signature.=0D - //=0D - NumberCertsInSignature =3D sk_X509_num (CertChain);=0D =0D - if (NumberCertsInSignature =3D=3D 0) {=0D - //=0D - // Fail to find any certificates in signature.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D + Cert =3D NULL;=0D + SingleCert =3D NULL;=0D =0D - //=0D - // Get the leaf signer.=0D - //=0D - Status =3D GetSignerCertificate (Pkcs7, &SignerCert);=0D - if (Status !=3D EFI_SUCCESS || SignerCert =3D=3D NULL) {=0D - //=0D - // Fail to get the end-entity leaf signer certificate.=0D - //=0D - Status =3D EFI_INVALID_PARAMETER;=0D - goto Exit;=0D - }=0D =0D - Status =3D CheckEKUs (SignerCert, RequiredEKUs, RequiredEKUsSize, Requir= eAllPresent);=0D - if (Status !=3D EFI_SUCCESS) {=0D - goto Exit;=0D + Cert =3D &Pkcs7.signed_data.certs;=0D + if (Cert =3D=3D NULL) {=0D + goto _Exit;=0D }=0D =0D -Exit:=0D +=0D +_Exit:=0D =0D //=0D // Release Resources=0D @@ -493,17 +117,11 @@ Exit: // If the signature was not wrapped, then the call to WrapData() will al= locate=0D // the data and add a header to it=0D //=0D - if (!IsWrapped && SignedData) {=0D - free (SignedData);=0D + if (!Wrapped && SignedData) {=0D + FreePool (SignedData);=0D }=0D =0D - if (SignerCert !=3D NULL) {=0D - X509_free (SignerCert);=0D - }=0D -=0D - if (Pkcs7 !=3D NULL) {=0D - PKCS7_free (Pkcs7);=0D - }=0D + mbedtls_pkcs7_free (&Pkcs7);=0D =0D return Status;=0D }=0D diff --git a/CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf b/CryptoPkg/Librar= y/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=0D mbedtls/library/x509_crt.c=0D mbedtls/library/x509_csr.c=0D + mbedtls/library/pkcs7.c=0D =0D [Packages]=0D MdePkg/MdePkg.dec=0D --=20 2.26.2.windows.1