]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Verify.c
CryptoPkg: Add one new API for PKCS7 Verification Protocol Support
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptPkcs7Verify.c
index a1bab8a0ce56ed3f908ce1da767121e094d5c6c9..b8cfa4286dd509fc644ea6b22b0b89fe9f02838f 100644 (file)
@@ -680,4 +680,111 @@ _Exit:
   }\r
 \r
   return Status;\r
-}
\ No newline at end of file
+}\r
+\r
+/**\r
+  Extracts the attached content from a PKCS#7 signed data if existed. The input signed\r
+  data could be wrapped in a ContentInfo structure.\r
+\r
+  If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,\r
+  then return FAlSE. If the P7Data is not correctly formatted, then return FALSE.\r
+\r
+  Caution: This function may receive untrusted input. So this function will do\r
+           basic check for PKCS#7 data structure.\r
+\r
+  @param[in]   P7Data       Pointer to the PKCS#7 signed data to process.\r
+  @param[in]   P7Length     Length of the PKCS#7 signed data in bytes.\r
+  @param[out]  Content      Pointer to the extracted content from the PKCS#7 signedData.\r
+                            It's caller's responsiblity to free the buffer.\r
+  @param[out]  ContentSize  The size of the extracted content in bytes.\r
+\r
+  @retval     TRUE          The P7Data was correctly formatted for processing.\r
+  @retval     FALSE         The P7Data was not correctly formatted for processing.\r
+\r
+*/\r
+BOOLEAN\r
+EFIAPI\r
+Pkcs7GetAttachedContent (\r
+  IN  CONST UINT8  *P7Data,\r
+  IN  UINTN        P7Length,\r
+  OUT VOID         **Content,\r
+  OUT UINTN        *ContentSize\r
+  )\r
+{\r
+  BOOLEAN            Status;\r
+  PKCS7              *Pkcs7;\r
+  UINT8              *SignedData;\r
+  UINTN              SignedDataSize;\r
+  BOOLEAN            Wrapped;\r
+  CONST UINT8        *Temp;\r
+  ASN1_OCTET_STRING  *OctStr;\r
+\r
+  *Content   = NULL;\r
+  Pkcs7      = NULL;\r
+  SignedData = NULL;\r
+  OctStr     = NULL;\r
+\r
+  //\r
+  // Check input parameter.\r
+  //\r
+  if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {\r
+    return FALSE;\r
+  }\r
+\r
+  Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);\r
+  if (!Status || (SignedDataSize > INT_MAX)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  Status = FALSE;\r
+\r
+  //\r
+  // Decoding PKCS#7 SignedData\r
+  //\r
+  Temp  = SignedData;\r
+  Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);\r
+  if (Pkcs7 == NULL) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // The type of Pkcs7 must be signedData\r
+  //\r
+  if (!PKCS7_type_is_signed (Pkcs7)) {\r
+    goto _Exit;\r
+  }\r
+\r
+  //\r
+  // Check for detached or attached content\r
+  //\r
+  if (PKCS7_get_detached (Pkcs7)) {\r
+    //\r
+    // No Content supplied for PKCS7 detached signedData\r
+    //\r
+    *Content     = NULL;\r
+    *ContentSize = 0;\r
+  } else {\r
+    //\r
+    // Retrieve the attached content in PKCS7 signedData\r
+    //\r
+    OctStr = Pkcs7->d.sign->contents->d.data;\r
+    if ((OctStr->length > 0) && (OctStr->data != NULL)) {\r
+      *ContentSize = OctStr->length;\r
+      *Content     = malloc (*ContentSize);\r
+      CopyMem (*Content, OctStr->data, *ContentSize);\r
+    }\r
+  }\r
+  Status = TRUE;\r
+\r
+_Exit:\r
+  //\r
+  // Release Resources\r
+  //\r
+  PKCS7_free (Pkcs7);\r
+\r
+  if (!Wrapped) {\r
+    OPENSSL_free (SignedData);\r
+  }\r
+\r
+  return Status;\r
+}\r