• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MBEDTLS_PKCS7_H
17 #define MBEDTLS_PKCS7_H
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <mbedtls/asn1.h>
21 #include <mbedtls/x509.h>
22 #include <mbedtls/x509_crt.h>
23 #include <mbedtls/x509_crl.h>
24 #include <mbedtls/pem.h>
25 #include <mbedtls/oid.h>
26 
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif
31 #endif
32 
33 /*
34  * if the pkcs7 format is pem, add this define in this header file
35  * or in build env
36  * #define PARSE_PEM_FORMAT_SIGNED_DATA 1
37  */
38 #define MAX_SIGNER_NAME_LEN 512
39 
40 typedef enum {
41     PKCS7_SUCC = 0,
42     PKCS7_PARSING_ERROR,
43     PKCS7_INVALID_PARAM,
44     PKCS7_INVALID_VALUE,
45     PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT,
46     PKCS7_CERTIFICATE_NOT_FOUND,
47     PKCS7_INVALID_VERSION,
48     PKCS7_INVALID_DIGEST_ALG,
49     PKCS7_INVALID_SIGNING_ALG,
50     PKCS7_MEMORY_EXHAUST,
51     PKCS7_ROOT_CA_NOT_VALID,
52     PKCS7_BUILD_CERT_PATH_FAIL,
53     PKCS7_HAS_NO_AUTH_ATTR_IN_SIGNER,
54     PKCS7_HAS_NO_SIGNER_INFO,
55     PKCS7_HAS_NO_SIGNER_CRT,
56     PKCS7_IS_REVOKED,
57     PKCS7_VERIFY_FAIL,
58 } PKCS7_RetCode;
59 
60 typedef struct {
61     char issuer[MAX_SIGNER_NAME_LEN];
62     char subject[MAX_SIGNER_NAME_LEN];
63     int32_t depth;
64 } SignerResovledInfo;
65 
66 typedef struct {
67     SignerResovledInfo *signers;
68     int32_t nrOfSigners;
69 } SignersResovedInfo;
70 
71 /*
72  * The structure bellow used the mbedtls open source structure which definition is kernel-like style,
73  * We do not redefine it to Camel style
74  *
75  * the PKCS7 signer's cert path header
76  * depth is the signer's cert path depth
77  * crt is the certs list header, the lower ca cert is at front
78  */
79 typedef struct {
80     int32_t depth;
81     mbedtls_x509_crt *crt;
82 } SignerCertPath;
83 
84 /*
85  * PKCS7 signer info structure, as defined in PKCS7
86  * rootCert is not defined in PKCS7, this is the signer's root cert preinstall in system
87  * certPath is for cert chain verify
88  * next is point to the next signer info, as PKCS7 definination, maybe there are multi signer
89  */
90 typedef struct tagSignerInfo {
91     int32_t version;
92     mbedtls_x509_buf serial;
93     mbedtls_x509_name issuer;
94     mbedtls_x509_crt *rootCert;
95     mbedtls_x509_buf issuerRaw;
96     mbedtls_x509_buf digestAlgId;
97     mbedtls_x509_buf authAttr;
98     mbedtls_x509_buf authAttrRaw;
99     mbedtls_x509_buf digestEncAlgId;
100     mbedtls_x509_buf signature;
101     mbedtls_x509_buf unAuthAttr;
102     SignerCertPath certPath;
103     struct tagSignerInfo *next;
104 } SignerInfo;
105 
106 /*
107  * PKCS7 signed data content info
108  */
109 typedef struct tagContent {
110     mbedtls_asn1_buf oid;
111     mbedtls_asn1_buf data;
112 } Content;
113 
114 /*
115  * PKCS7 signed data digest algorithm identifiers
116  */
117 typedef struct tagDigestAlgId {
118     mbedtls_asn1_buf algBuf;
119     struct tagDigestAlgId *next;
120 } DigestAlgId;
121 
122 /*
123  * PKCS7 signed-data structure
124  */
125 typedef struct {
126     int32_t version;
127     DigestAlgId digestAlgIds;
128     Content content;
129     mbedtls_x509_crt *certs;
130     mbedtls_x509_crl crl;
131     SignerInfo signers;
132 } SignedData;
133 
134 /*
135  * PKCS7 signed data total structure header
136  * contentTypeOid must be the pkcs7 signed-data oid 1.2.840.113549.1.7.2
137  */
138 typedef struct {
139     mbedtls_asn1_buf contentTypeOid;
140     SignedData signedData;
141 #ifdef PARSE_PEM_FORMAT_SIGNED_DATA
142     mbedtls_pem_context pem;
143 #endif
144 } Pkcs7;
145 
146 /*******************************************************************************
147  * Function    : PKCS7_ParseSignedData
148  * Description : parse the pkcs7 signed data, store the resolved data to pkcs7
149  * Input       : buf     - pkcs7 signed data
150  *               bufLen  - pkcs7 signed data length
151  * Output      : pkcs7   - resolved pkcs7 data, caller provide this arg, malloc
152  *                         from heap memory or use stack memory, if malloced
153  *                         from heap memory, caller must freed the memory after
154  *                         called PKCS7_FreeRes
155  * Return      : 0 on success, others on fail
156  * Note        : need to call PKCS7_FreeRes to free the resource when success
157  *               parse and use, no need to call PKCS7_FreeRes when parse failed
158  *******************************************************************************/
159 int32_t PKCS7_ParseSignedData(const unsigned char *buf, size_t bufLen, Pkcs7 *pkcs7);
160 
161 /*******************************************************************************
162  * Function    : PKCS7_VerifyCertsChain
163  * Description : Verify all signer's cert chain
164  * Input       : pkcs7 -- the pkcs7 signed data header.
165  * Return      : 0 on success, others on fail
166  *******************************************************************************/
167 int32_t PKCS7_VerifyCertsChain(const Pkcs7 *pkcs7);
168 
169 /*******************************************************************************
170  * Function    : PKCS7_FreeRes
171  * Description : free the resource of resolved pkcs7 data
172  * Input       : pkcs7   - resolved pkcs7 data
173  * Return      : 0 on success, others on fail
174  * Note        : need to call PKCS7_FreeRes to free the resource when success
175  *               parse and use, no need to call PKCS7_FreeRes when parse failed
176  *******************************************************************************/
177 void PKCS7_FreeRes(Pkcs7 *pkcs7);
178 
179 /*******************************************************************************
180  * Function    : PKCS7_CalcDigest
181  * Description : is a callback defined by upper layer user, calculate the
182  *               digest for final verify the signed data signature.
183  * Input       : pkcs7   - pkcs7 signed data header
184  *               signer  - pkcs7 signer info
185  *               algType - digest algorithm type, defined in mbedtls, exp:
186  *                         MBEDTLS_MD_SHA256/MBEDTLS_MD_SHA512
187  * Output      : hash    - the calcuated digest hash
188  *               hashLen - the length of calculated digest hash
189  * Return      : 0 on success, others on fail
190  *******************************************************************************/
191 typedef int32_t (*PKCS7_CalcDigest)(const Pkcs7 *pkcs7, const SignerInfo *signer,
192     mbedtls_md_type_t algType, unsigned char *hash, size_t *hashLen);
193 
194 /*******************************************************************************
195  * Function    : PKCS7_GetContentData
196  * Description : get the content data of PKCS#7 signed-data content
197  * Input       : pkcs7   - pkcs7 signed data header
198  * Output      : data    - pointer to the content data
199  *                         user need not to free this var
200  *               dataLen - the content data length
201  * Return      : 0 on success, others on fail
202  *******************************************************************************/
203 int32_t PKCS7_GetContentData(const Pkcs7 *pkcs7, unsigned char **data, size_t *dataLen);
204 
205 /*******************************************************************************
206  * Function    : PKCS7_GetDigestInSignerAuthAttr
207  * Description : get the digest which stored in signer's auth attribute.
208  * Input       : signer  - pkcs7 signer info
209  * Output      : dig     - pointer to the digest stored in signer's auth attribute
210  *                         user need not to free this var
211  *               digLen  - digest length
212  * Return      : 0 on success, others on fail
213  *******************************************************************************/
214 int32_t PKCS7_GetDigestInSignerAuthAttr(const SignerInfo *signer, unsigned char **dig, size_t *digLen);
215 
216 /*******************************************************************************
217  * Function    : PKCS7_GetSignerAuthAttr
218  * Description : get the signer's auth attribute content, which maybe signed by
219  *               signer, so upper layer can call this to get to-be-signed data,
220  *               then calculate digest of it for signature verification
221  * Input       : signer  - pkcs7 signer info
222  * Output      : data    - pointer to signer's auth attribute start location
223  *                         user need not to free this var
224  *               dataLen - signer auth attribute data length
225  * Return      : 0 on success, others on fail
226  *******************************************************************************/
227 int32_t PKCS7_GetSignerAuthAttr(const SignerInfo *signer, unsigned char **data, size_t *dataLen);
228 
229 /*******************************************************************************
230  * Function    : PKCS7_VerifySignerSignature
231  * Description : Verify all of signer's signature
232  * Input       : pkcs7   - pkcs7 signed data header
233  *               calcDigest - callback function for upper layer user to calculate
234  *                            the digest of signature
235  * Output      : NA
236  * Return      : 0 on success, others on fail
237  *******************************************************************************/
238 int32_t PKCS7_VerifySignerSignature(const Pkcs7 *pkcs7, PKCS7_CalcDigest calcDigest);
239 
240 /*******************************************************************************
241  * Function    : PKCS7_GetAllSignersResolvedInfo
242  * Description : Get all signer's associate info, now including subject/issuer/
243  *               cert depth, used it for trustlist match.
244  * Input       : pkcs7   - pkcs7 signed data header
245  * Output      : the structure of associate signer's info
246  * Return      : non-NULL on success, and user need to call
247  *               PKCS7_FreeAllSignersResolvedInfo to free resource
248  *******************************************************************************/
249 SignersResovedInfo *PKCS7_GetAllSignersResolvedInfo(const Pkcs7 *pkcs7);
250 
251 /*******************************************************************************
252  * Function    : PKCS7_FreeAllSignersResolvedInfo
253  * Description : Free the signer associate info.
254  * Input       : sri    - signer associate info
255  * Output      : NA
256  * Return      : void
257  *******************************************************************************/
258 void PKCS7_FreeAllSignersResolvedInfo(SignersResovedInfo *sri);
259 
260 /*******************************************************************************
261  * Function    : PKCS7_EnableDebugMode
262  * Description : Enable or disable debug mode, so it can install the app that
263  *               signed by the test cert's private key.
264  * Input       : mode    - true:enable, false:disable
265  * Output      : NA
266  * Return      : 0 on success, others on error
267  *******************************************************************************/
268 int32_t PKCS7_EnableDebugMode(bool mode);
269 
270 #ifdef __cplusplus
271 #if __cplusplus
272 }
273 #endif
274 #endif
275 #endif // MBEDTLS_PKCS7_H
276