+}\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