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