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.l...@intel.com>
---
 CryptoPkg/Include/Library/BaseCryptLib.h           |  33 ++++++-
 .../Library/BaseCryptLib/Pk/CryptPkcs7Verify.c     | 109 ++++++++++++++++++++-
 .../Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c |  31 +++++-
 .../Pk/CryptPkcs7VerifyNull.c                      |  31 +++++-
 4 files changed, 199 insertions(+), 5 deletions(-)

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h 
b/CryptoPkg/Include/Library/BaseCryptLib.h
index bc36ac7..364fa3c 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -4,7 +4,7 @@
   primitives (Hash Serials, HMAC, RSA, Diffie-Hellman, etc) for UEFI security
   functionality enabling.
 
-Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2015, 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
@@ -2054,6 +2054,35 @@ Pkcs7Verify (
   );
 
 /**
+  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
+  );
+
+/**
   Verifies the validility of a PE/COFF Authenticode Signature as described in 
"Windows
   Authenticode Portable Executable Signature Format".
 
@@ -2333,4 +2362,4 @@ RandomBytes (
   IN   UINTN  Size
   );
 
-#endif // __BASE_CRYPT_LIB_H__
\ No newline at end of file
+#endif // __BASE_CRYPT_LIB_H__
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c 
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
index a1bab8a..b8cfa42 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
@@ -680,4 +680,111 @@ _Exit:
   }
 
   return Status;
-}
\ No newline at end of file
+}
+
+/**
+  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;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c 
b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c
index 9a4c77a..567965d 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyNull.c
@@ -2,7 +2,7 @@
   PKCS#7 SignedData Verification Wrapper Implementation which does not provide
   real capabilities.
 
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2015, 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
@@ -98,3 +98,32 @@ Pkcs7Verify (
   ASSERT (FALSE);
   return FALSE;
 }
+
+/**
+  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 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
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git 
a/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptPkcs7VerifyNull.c 
b/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptPkcs7VerifyNull.c
index 9a4c77a..567965d 100644
--- 
a/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptPkcs7VerifyNull.c
+++ 
b/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptPkcs7VerifyNull.c
@@ -2,7 +2,7 @@
   PKCS#7 SignedData Verification Wrapper Implementation which does not provide
   real capabilities.
 
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2015, 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
@@ -98,3 +98,32 @@ Pkcs7Verify (
   ASSERT (FALSE);
   return FALSE;
 }
+
+/**
+  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 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
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
-- 
1.9.5.msysgit.1


------------------------------------------------------------------------------
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to