CryptoPkg/BaseCryptLib: split CryptPkcs7Verify.c on behalf of runtime

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1493

Pkcs7GetAttachedContent() implementation in current CryptPkcs7Verify.c
is actually shared by RuntimeCryptLib.inf, SmmCryptLib.inf and
BaseCryptLib.inf, which are not correct since there's no use scenario
for runtime and AllocatePool() used in this method can only be called
in boot time.

This patch fix this issue by splitting file CryptPkcs7Verify.c into 3 parts.

  CryptPkcs7VerifyCommon.c  (shared among Base, SMM, Runtime)
  CryptPkcs7VerifyBase.c    (shared between Base, SMM)
  CryptPkcs7VerifyRuntime.c (for Runtime only)

CryptPkcs7VerifyBase.c will have original implementation of
Pkcs7GetAttachedContent() as CryptPkcs7Verify.c. CryptPkcs7VerifyRuntime.c
provide a NULL version of Pkcs7GetAttachedContent().

No functionality and interface change is involved in this patch.

Cc: Ting Ye <ting.ye@intel.com>
Cc: Qin Long <qin.long@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Ting Ye <ting.ye@intel.com>
This commit is contained in:
Jian J Wang 2019-01-28 15:34:47 +08:00
parent 37bf678761
commit cc01b26e05
8 changed files with 220 additions and 119 deletions

View File

@ -6,7 +6,7 @@
# This external input must be validated carefully to avoid security issues such as
# buffer overflow or integer overflow.
#
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@ -49,7 +49,8 @@
Pk/CryptRsaExt.c
Pk/CryptPkcs5Pbkdf2.c
Pk/CryptPkcs7Sign.c
Pk/CryptPkcs7Verify.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptDh.c
Pk/CryptX509.c
Pk/CryptAuthenticode.c

View File

@ -33,4 +33,36 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define OBJ_length(o) ((o)->length)
#endif
/**
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

View File

@ -56,7 +56,8 @@
Pk/CryptRsaExtNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7Verify.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptDhNull.c
Pk/CryptX509Null.c

View File

@ -0,0 +1,131 @@
/** @file
Non-runtime specific implementation of PKCS#7 SignedData Verification Wrapper.
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "InternalCryptLib.h"
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs7.h>
/**
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
data could be wrapped in a ContentInfo structure.
If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,
then return FALSE. If the P7Data is not correctly formatted, then return FALSE.
Caution: This function may receive untrusted input. So this function will do
basic check for PKCS#7 data structure.
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
It's caller's responsibility to free the buffer with FreePool().
@param[out] ContentSize The size of the extracted content in bytes.
@retval TRUE The P7Data was correctly formatted for processing.
@retval FALSE The P7Data was not correctly formatted for processing.
**/
BOOLEAN
EFIAPI
Pkcs7GetAttachedContent (
IN CONST UINT8 *P7Data,
IN UINTN P7Length,
OUT VOID **Content,
OUT UINTN *ContentSize
)
{
BOOLEAN Status;
PKCS7 *Pkcs7;
UINT8 *SignedData;
UINTN SignedDataSize;
BOOLEAN Wrapped;
CONST UINT8 *Temp;
ASN1_OCTET_STRING *OctStr;
//
// Check input parameter.
//
if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {
return FALSE;
}
*Content = NULL;
Pkcs7 = NULL;
SignedData = NULL;
OctStr = NULL;
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
if (!Status || (SignedDataSize > INT_MAX)) {
goto _Exit;
}
Status = FALSE;
//
// Decoding PKCS#7 SignedData
//
Temp = SignedData;
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
if (Pkcs7 == NULL) {
goto _Exit;
}
//
// The type of Pkcs7 must be signedData
//
if (!PKCS7_type_is_signed (Pkcs7)) {
goto _Exit;
}
//
// Check for detached or attached content
//
if (PKCS7_get_detached (Pkcs7)) {
//
// No Content supplied for PKCS7 detached signedData
//
*Content = NULL;
*ContentSize = 0;
} else {
//
// Retrieve the attached content in PKCS7 signedData
//
OctStr = Pkcs7->d.sign->contents->d.data;
if ((OctStr->length > 0) && (OctStr->data != NULL)) {
*ContentSize = OctStr->length;
*Content = AllocatePool (*ContentSize);
if (*Content == NULL) {
*ContentSize = 0;
goto _Exit;
}
CopyMem (*Content, OctStr->data, *ContentSize);
}
}
Status = TRUE;
_Exit:
//
// Release Resources
//
PKCS7_free (Pkcs7);
if (!Wrapped) {
OPENSSL_free (SignedData);
}
return Status;
}

View File

@ -10,7 +10,7 @@
WrapPkcs7Data(), Pkcs7GetSigners(), Pkcs7Verify() will get UEFI Authenticated
Variable and will do basic check for data structure.
Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -914,113 +914,3 @@ _Exit:
return Status;
}
/**
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
data could be wrapped in a ContentInfo structure.
If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,
then return FALSE. If the P7Data is not correctly formatted, then return FALSE.
Caution: This function may receive untrusted input. So this function will do
basic check for PKCS#7 data structure.
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
It's caller's responsibility to free the buffer with FreePool().
@param[out] ContentSize The size of the extracted content in bytes.
@retval TRUE The P7Data was correctly formatted for processing.
@retval FALSE The P7Data was not correctly formatted for processing.
**/
BOOLEAN
EFIAPI
Pkcs7GetAttachedContent (
IN CONST UINT8 *P7Data,
IN UINTN P7Length,
OUT VOID **Content,
OUT UINTN *ContentSize
)
{
BOOLEAN Status;
PKCS7 *Pkcs7;
UINT8 *SignedData;
UINTN SignedDataSize;
BOOLEAN Wrapped;
CONST UINT8 *Temp;
ASN1_OCTET_STRING *OctStr;
//
// Check input parameter.
//
if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {
return FALSE;
}
*Content = NULL;
Pkcs7 = NULL;
SignedData = NULL;
OctStr = NULL;
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
if (!Status || (SignedDataSize > INT_MAX)) {
goto _Exit;
}
Status = FALSE;
//
// Decoding PKCS#7 SignedData
//
Temp = SignedData;
Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
if (Pkcs7 == NULL) {
goto _Exit;
}
//
// The type of Pkcs7 must be signedData
//
if (!PKCS7_type_is_signed (Pkcs7)) {
goto _Exit;
}
//
// Check for detached or attached content
//
if (PKCS7_get_detached (Pkcs7)) {
//
// No Content supplied for PKCS7 detached signedData
//
*Content = NULL;
*ContentSize = 0;
} else {
//
// Retrieve the attached content in PKCS7 signedData
//
OctStr = Pkcs7->d.sign->contents->d.data;
if ((OctStr->length > 0) && (OctStr->data != NULL)) {
*ContentSize = OctStr->length;
*Content = AllocatePool (*ContentSize);
if (*Content == NULL) {
*ContentSize = 0;
goto _Exit;
}
CopyMem (*Content, OctStr->data, *ContentSize);
}
}
Status = TRUE;
_Exit:
//
// Release Resources
//
PKCS7_free (Pkcs7);
if (!Wrapped) {
OPENSSL_free (SignedData);
}
return Status;
}

View File

@ -0,0 +1,45 @@
/** @file
Runtime specific implementation of PKCS#7 SignedData Verification Wrapper.
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "InternalCryptLib.h"
/**
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
data could be wrapped in a ContentInfo structure.
Return FALSE to indicate this interface is not supported.
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
It's caller's responsibility to free the buffer with FreePool().
@param[out] ContentSize The size of the extracted content in bytes.
@retval TRUE The P7Data was correctly formatted for processing.
@retval FALSE The P7Data was not correctly formatted for processing.
**/
BOOLEAN
EFIAPI
Pkcs7GetAttachedContent (
IN CONST UINT8 *P7Data,
IN UINTN P7Length,
OUT VOID **Content,
OUT UINTN *ContentSize
)
{
ASSERT (FALSE);
return FALSE;
}

View File

@ -11,7 +11,7 @@
# functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and
# authenticode signature verification functions are not supported in this instance.
#
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@ -54,7 +54,8 @@
Pk/CryptRsaExtNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7Verify.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyRuntime.c
Pk/CryptDhNull.c
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
@ -84,7 +85,6 @@
[LibraryClasses]
BaseLib
BaseMemoryLib
MemoryAllocationLib
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
DebugLib

View File

@ -11,7 +11,7 @@
# functions, PKCS#7 SignedData sign functions, Diffie-Hellman functions, and
# authenticode signature verification functions are not supported in this instance.
#
# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@ -54,7 +54,8 @@
Pk/CryptRsaExtNull.c
Pk/CryptPkcs5Pbkdf2.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7Verify.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptDhNull.c
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c