CryptoPkg: Add one new API for PKCS7 Verification Protocol Support

This patch adds one new API (Pkcs7GetAttachedContent) to support
PKCS7 Verification Protocol defined in UEFI 2.5.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Qin Long <qin.long@intel.com>
Reviewed-by: Chao Zhang <chao.b.zhang@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17669 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Qin Long
2015-06-19 02:44:20 +00:00
committed by qlong
parent bfc2fc9e90
commit afeb55e4a6
4 changed files with 199 additions and 5 deletions

View File

@@ -680,4 +680,111 @@ _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 responsiblity to free the buffer.
@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;
*Content = NULL;
Pkcs7 = NULL;
SignedData = NULL;
OctStr = NULL;
//
// Check input parameter.
//
if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {
return FALSE;
}
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 = malloc (*ContentSize);
CopyMem (*Content, OctStr->data, *ContentSize);
}
}
Status = TRUE;
_Exit:
//
// Release Resources
//
PKCS7_free (Pkcs7);
if (!Wrapped) {
OPENSSL_free (SignedData);
}
return Status;
}