]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7VerifyBase.c
CryptoPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptPkcs7VerifyBase.c
1 /** @file
2 Non-runtime specific implementation of PKCS#7 SignedData Verification Wrapper.
3
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "InternalCryptLib.h"
10
11 #include <openssl/objects.h>
12 #include <openssl/x509.h>
13 #include <openssl/x509v3.h>
14 #include <openssl/pkcs7.h>
15
16 /**
17 Extracts the attached content from a PKCS#7 signed data if existed. The input signed
18 data could be wrapped in a ContentInfo structure.
19
20 If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,
21 then return FALSE. If the P7Data is not correctly formatted, then return FALSE.
22
23 Caution: This function may receive untrusted input. So this function will do
24 basic check for PKCS#7 data structure.
25
26 @param[in] P7Data Pointer to the PKCS#7 signed data to process.
27 @param[in] P7Length Length of the PKCS#7 signed data in bytes.
28 @param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
29 It's caller's responsibility to free the buffer with FreePool().
30 @param[out] ContentSize The size of the extracted content in bytes.
31
32 @retval TRUE The P7Data was correctly formatted for processing.
33 @retval FALSE The P7Data was not correctly formatted for processing.
34
35 **/
36 BOOLEAN
37 EFIAPI
38 Pkcs7GetAttachedContent (
39 IN CONST UINT8 *P7Data,
40 IN UINTN P7Length,
41 OUT VOID **Content,
42 OUT UINTN *ContentSize
43 )
44 {
45 BOOLEAN Status;
46 PKCS7 *Pkcs7;
47 UINT8 *SignedData;
48 UINTN SignedDataSize;
49 BOOLEAN Wrapped;
50 CONST UINT8 *Temp;
51 ASN1_OCTET_STRING *OctStr;
52
53 //
54 // Check input parameter.
55 //
56 if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {
57 return FALSE;
58 }
59
60 *Content = NULL;
61 Pkcs7 = NULL;
62 SignedData = NULL;
63 OctStr = NULL;
64
65 Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
66 if (!Status || (SignedDataSize > INT_MAX)) {
67 goto _Exit;
68 }
69
70 Status = FALSE;
71
72 //
73 // Decoding PKCS#7 SignedData
74 //
75 Temp = SignedData;
76 Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **)&Temp, (int)SignedDataSize);
77 if (Pkcs7 == NULL) {
78 goto _Exit;
79 }
80
81 //
82 // The type of Pkcs7 must be signedData
83 //
84 if (!PKCS7_type_is_signed (Pkcs7)) {
85 goto _Exit;
86 }
87
88 //
89 // Check for detached or attached content
90 //
91 if (PKCS7_get_detached (Pkcs7)) {
92 //
93 // No Content supplied for PKCS7 detached signedData
94 //
95 *Content = NULL;
96 *ContentSize = 0;
97 } else {
98 //
99 // Retrieve the attached content in PKCS7 signedData
100 //
101 OctStr = Pkcs7->d.sign->contents->d.data;
102 if ((OctStr->length > 0) && (OctStr->data != NULL)) {
103 *ContentSize = OctStr->length;
104 *Content = AllocatePool (*ContentSize);
105 if (*Content == NULL) {
106 *ContentSize = 0;
107 goto _Exit;
108 }
109 CopyMem (*Content, OctStr->data, *ContentSize);
110 }
111 }
112 Status = TRUE;
113
114 _Exit:
115 //
116 // Release Resources
117 //
118 PKCS7_free (Pkcs7);
119
120 if (!Wrapped) {
121 OPENSSL_free (SignedData);
122 }
123
124 return Status;
125 }