1 /*
2 * Copyright (c) 2020-2022 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 #include "mbedtls_pkcs7.h"
17 #include <ctype.h>
18 #include <stdbool.h>
19 #include <string.h>
20 #include "app_common.h"
21 #include "mbedtls/platform.h" // for mbedtls_calloc
22 #include "securec.h"
23
24 #define VERIFY_BUF_LEN 512
25 #define MAX_SIG_SIZE 1024
26
27 #ifndef MBEDTLS_OID_PKCS7
28 #define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07"
29 #endif
30
31 #ifndef MBEDTLS_OID_PKCS7_DATA
32 #define MBEDTLS_OID_PKCS7_DATA MBEDTLS_OID_PKCS7 "\x01"
33 #endif
34
35 #ifndef MBEDTLS_OID_PKCS7_SIGNED_DATA
36 #define MBEDTLS_OID_PKCS7_SIGNED_DATA MBEDTLS_OID_PKCS7 "\x02"
37 #endif
38
39 #ifndef MBEDTLS_OID_PKCS9_MSG_DIGEST
40 #define MBEDTLS_OID_PKCS9_MSG_DIGEST MBEDTLS_OID_PKCS9 "\x04"
41 #endif
42
43 #define PKCS7_SIGNED_DATA_VERSION 1
44 #define PEM_FORMAT_SINGED_DATA 1
45 #define DER_FORMAT_SINGED_DATA 2
46
47 #define PKCS7_ERR_RETURN_WITH_LOG(rc) \
48 do { \
49 if ((rc) != PKCS7_SUCC) \
50 { \
51 LOG_ERROR("%s:%u, error occurred, ret:%d", __FUNCTION__, __LINE__, (rc)); \
52 return rc; \
53 } \
54 } while (0)
55
56 static mbedtls_x509_crt g_rootCaG2Cert;
57 static bool g_rootCertLoaded;
58 static const unsigned char ROOT_CA_G2_CERT_IN_PEM[] =
59 "-----BEGIN CERTIFICATE-----\r\n"
60 "MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC\r\n"
61 "Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE\r\n"
62 "AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx\r\n"
63 "NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE\r\n"
64 "CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw\r\n"
65 "EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs\r\n"
66 "GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB\r\n"
67 "wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T\r\n"
68 "AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI\r\n"
69 "zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn\r\n"
70 "BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h\r\n"
71 "FTjgDHctXJlC5L7+ZDY=\r\n"
72 "-----END CERTIFICATE-----\r\n";
73
74 static mbedtls_x509_crt g_debugModeRootCert;
75 static bool g_debugModeEnabled;
76 static const unsigned char DEBUG_MODE_ROOT_CERT_IN_PEM[] =
77 "-----BEGIN CERTIFICATE-----\r\n"
78 "MIICJTCCAaugAwIBAgIIb/9KnVieVTgwCgYIKoZIzj0EAwMwWDELMAkGA1UEBhMC\r\n"
79 "Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEjMCEGA1UE\r\n"
80 "AwwaSHVhd2VpIENCRyBSb290IENBIEcyIFRlc3QwHhcNMjAwMzEyMTI0NDAwWhcN\r\n"
81 "NDkwMzEyMTI0NDAwWjBYMQswCQYDVQQGEwJDTjEPMA0GA1UECgwGSHVhd2VpMRMw\r\n"
82 "EQYDVQQLDApIdWF3ZWkgQ0JHMSMwIQYDVQQDDBpIdWF3ZWkgQ0JHIFJvb3QgQ0Eg\r\n"
83 "RzIgVGVzdDB2MBAGByqGSM49AgEGBSuBBAAiA2IABLS4fgvaYKKfyMZW/4nNTsSv\r\n"
84 "xqVxqOEDfLySZK/fSEN0IDQj0sK/qK5hvnf0OxWhwI49P3dKGmQ+cSujXvy0me2D\r\n"
85 "JTjY127XYZJrvJwwMkrT/vMrZC5kSOEJbt1qAgSmiaNCMEAwDgYDVR0PAQH/BAQD\r\n"
86 "AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGldwFjx9Tzm/QpA8R1gc9wc\r\n"
87 "eMbFMAoGCCqGSM49BAMDA2gAMGUCMQCCUDRaglmycUGrHmF+L8owKJhbqOUqbwuX\r\n"
88 "7XL/vJcp3HeHjiXu7XZmYQ+QAvHPhU0CMCiwWFbDl8ETw4VK25QbwhL/QiUfiRfC\r\n"
89 "J6LzteOvjLTEV5iebQMz/nS1j7/oj3Rsqg==\r\n"
90 "-----END CERTIFICATE-----\r\n";
91 static mbedtls_x509_crt g_ohosRootCert;
92 static const unsigned char OHOS_ROOT_CERT_IN_PEM[] =
93 "-----BEGIN CERTIFICATE-----\r\n"
94 "MIICRDCCAcmgAwIBAgIED+E4izAMBggqhkjOPQQDAwUAMGgxCzAJBgNVBAYTAkNO\r\n"
95 "MRQwEgYDVQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVh\r\n"
96 "bTEoMCYGA1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTAeFw0y\r\n"
97 "MTAyMDIxMjE0MThaFw00OTEyMzExMjE0MThaMGgxCzAJBgNVBAYTAkNOMRQwEgYD\r\n"
98 "VQQKEwtPcGVuSGFybW9ueTEZMBcGA1UECxMQT3Blbkhhcm1vbnkgVGVhbTEoMCYG\r\n"
99 "A1UEAxMfT3Blbkhhcm1vbnkgQXBwbGljYXRpb24gUm9vdCBDQTB2MBAGByqGSM49\r\n"
100 "AgEGBSuBBAAiA2IABE023XmRaw2DnO8NSsb+KG/uY0FtS3u5LQucdr3qWVnRW5ui\r\n"
101 "QIL6ttNZBEeLTUeYcJZCpayg9Llf+1SmDA7dY4iP2EcRo4UN3rilovtfFfsmH4ty\r\n"
102 "3SApHVFzWUl+NwdH8KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\r\n"
103 "AQYwHQYDVR0OBBYEFBc6EKGrGXzlAE+s0Zgnsphadw7NMAwGCCqGSM49BAMDBQAD\r\n"
104 "ZwAwZAIwd1p3JzHN93eoPped1li0j64npgqNzwy4OrkehYAqNXpcpaEcLZ7UxW8E\r\n"
105 "I2lZJ3SbAjAkqySHb12sIwdSFKSN9KCMMEo/eUT5dUXlcKR2nZz0MJdxT5F51qcX\r\n"
106 "1CumzkcYhgU=\r\n"
107 "-----END CERTIFICATE-----\r\n";
108
109 /* valid digest alg now: sha256 sha384 sha512 */
InvalidDigestAlg(const mbedtls_asn1_buf * alg)110 static bool InvalidDigestAlg(const mbedtls_asn1_buf *alg)
111 {
112 return MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA256, alg) &&
113 MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA384, alg) &&
114 MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA512, alg);
115 }
116
GetContentInfoType(unsigned char ** p,const unsigned char * end,mbedtls_asn1_buf * contentType,bool * hasContent)117 static int32_t GetContentInfoType(unsigned char **p, const unsigned char *end,
118 mbedtls_asn1_buf *contentType, bool *hasContent)
119 {
120 size_t seqLen = 0;
121 size_t len = 0;
122 int32_t rc;
123
124 rc = mbedtls_asn1_get_tag(p, end, &seqLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
125 if (rc) {
126 return rc;
127 }
128 unsigned char *start = *p;
129 end = start + seqLen;
130 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OID);
131 if (rc) {
132 return rc;
133 }
134 contentType->tag = MBEDTLS_ASN1_OID;
135 contentType->len = len;
136 contentType->p = *p;
137 *hasContent = (seqLen != len + (*p - start));
138 *p += len; // pass the oid info to the real content location.
139
140 return PKCS7_SUCC;
141 }
142
GetContentLenOfContentInfo(unsigned char ** p,const unsigned char * end,size_t * len)143 static int32_t GetContentLenOfContentInfo(unsigned char **p, const unsigned char *end, size_t *len)
144 {
145 return mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
146 }
147
ParseSignerVersion(unsigned char ** p,const unsigned char * end,SignerInfo * signer)148 static int32_t ParseSignerVersion(unsigned char **p, const unsigned char *end, SignerInfo *signer)
149 {
150 return mbedtls_asn1_get_int(p, end, &signer->version);
151 }
152
ParseSignerIssuerAndSerialNum(unsigned char ** p,const unsigned char * end,SignerInfo * signer)153 static int32_t ParseSignerIssuerAndSerialNum(unsigned char **p, const unsigned char *end, SignerInfo *signer)
154 {
155 int32_t rc;
156 size_t len;
157
158 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
159 if (rc) {
160 return rc;
161 }
162
163 signer->issuerRaw.p = *p;
164 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
165 if (rc) {
166 return rc;
167 }
168 /* parse issuer name */
169 rc = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
170 if (rc) {
171 return rc;
172 }
173 signer->issuerRaw.len = *p - signer->issuerRaw.p; /* not include the serial. */
174
175 rc = mbedtls_x509_get_serial(p, end, &signer->serial);
176
177 return rc;
178 }
179
ParseSignerDigestAlg(unsigned char ** p,const unsigned char * end,SignerInfo * signer)180 static int32_t ParseSignerDigestAlg(unsigned char **p, const unsigned char *end, SignerInfo *signer)
181 {
182 int32_t rc = mbedtls_asn1_get_alg_null(p, end, &signer->digestAlgId);
183 if (rc) {
184 return rc;
185 }
186 if (InvalidDigestAlg(&signer->digestAlgId)) {
187 return PKCS7_INVALID_DIGEST_ALG;
188 }
189 return PKCS7_SUCC;
190 }
191
ParseSignerAuthAttr(unsigned char ** p,const unsigned char * end,SignerInfo * signer)192 static int32_t ParseSignerAuthAttr(unsigned char **p, const unsigned char *end, SignerInfo *signer)
193 {
194 int32_t rc;
195 size_t len = 0;
196 unsigned char *raw = *p;
197
198 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
199 if (rc) {
200 return PKCS7_SUCC; /* because this is optional item */
201 }
202 signer->authAttr.tag = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC;
203 signer->authAttr.p = *p;
204 signer->authAttr.len = len;
205 size_t tlLen = *p - raw;
206 *p += len;
207
208 signer->authAttrRaw.p = raw;
209 signer->authAttrRaw.len = len + tlLen;
210 return PKCS7_SUCC;
211 }
212
213 /*
214 * check if enc alg is rsa/ecdsa 256/384/512
215 */
InvalidDigestEncAlg(const mbedtls_x509_buf * alg)216 static bool InvalidDigestEncAlg(const mbedtls_x509_buf *alg)
217 {
218 return MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS1_SHA256, alg) &&
219 MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS1_SHA384, alg) &&
220 MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS1_SHA512, alg) &&
221 MBEDTLS_OID_CMP(MBEDTLS_OID_ECDSA_SHA256, alg) &&
222 MBEDTLS_OID_CMP(MBEDTLS_OID_ECDSA_SHA384, alg) &&
223 MBEDTLS_OID_CMP(MBEDTLS_OID_ECDSA_SHA512, alg) &&
224 MBEDTLS_OID_CMP(MBEDTLS_OID_RSASSA_PSS, alg);
225 }
226
ParseSignerEncAlg(unsigned char ** p,const unsigned char * end,SignerInfo * signer)227 static int32_t ParseSignerEncAlg(unsigned char **p, const unsigned char *end, SignerInfo *signer)
228 {
229 int32_t rc;
230 mbedtls_asn1_buf params = {0};
231 /* params not be used now */
232 rc = mbedtls_asn1_get_alg(p, end, &signer->digestEncAlgId, ¶ms);
233 if (rc) {
234 return rc;
235 }
236 if (InvalidDigestEncAlg(&signer->digestEncAlgId)) {
237 return PKCS7_INVALID_SIGNING_ALG;
238 }
239 return PKCS7_SUCC;
240 }
241
242 /*
243 * encryptedDigest EncryptedDigest,
244 * EncryptedDigest ::= OCTET STRING
245 */
ParseSignerSignature(unsigned char ** p,const unsigned char * end,SignerInfo * signer)246 static int32_t ParseSignerSignature(unsigned char **p, const unsigned char *end, SignerInfo *signer)
247 {
248 int32_t rc;
249 size_t len = 0;
250
251 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
252 if (rc) {
253 return rc;
254 }
255 signer->signature.tag = MBEDTLS_ASN1_OCTET_STRING;
256 signer->signature.len = len;
257 signer->signature.p = *p;
258 *p += len;
259 return PKCS7_SUCC;
260 }
261
GetSignerSignature(const SignerInfo * signer,unsigned char ** sig,size_t * sigLen)262 static int32_t GetSignerSignature(const SignerInfo *signer, unsigned char **sig, size_t *sigLen)
263 {
264 size_t len = signer->signature.len;
265 unsigned char *buf = signer->signature.p;
266 *sig = buf;
267 *sigLen = len;
268 return PKCS7_SUCC;
269 }
270
ParseSignerUnAuthAttr(unsigned char ** p,const unsigned char * end,SignerInfo * signer)271 static int32_t ParseSignerUnAuthAttr(unsigned char **p, const unsigned char *end, SignerInfo *signer)
272 {
273 int32_t rc;
274 size_t len = 0;
275
276 /* the optional unauth attr is not exist */
277 if (end - *p < 1) {
278 return PKCS7_SUCC;
279 }
280 rc = mbedtls_asn1_get_tag(p, end, &len, (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) + 1);
281 if (rc) {
282 return rc;
283 }
284 signer->unAuthAttr.tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) + 1;
285 signer->unAuthAttr.len = len;
286 signer->unAuthAttr.p = *p;
287 *p += len;
288 return PKCS7_SUCC;
289 }
290
SerialCmp(const mbedtls_x509_buf * a,const mbedtls_x509_buf * b)291 static int32_t SerialCmp(const mbedtls_x509_buf *a, const mbedtls_x509_buf *b)
292 {
293 if (a->len == b->len && memcmp(a->p, b->p, a->len) == 0) {
294 return 0;
295 }
296 return -1;
297 }
298
299 #define DIFF_NUM 32
IsLegitString(int32_t tag)300 static bool IsLegitString(int32_t tag)
301 {
302 if (tag == MBEDTLS_ASN1_UTF8_STRING || tag == MBEDTLS_ASN1_PRINTABLE_STRING) {
303 return true;
304 }
305 return false;
306 }
307
CompareX509String(const mbedtls_x509_buf * first,const mbedtls_x509_buf * second)308 static int32_t CompareX509String(const mbedtls_x509_buf *first, const mbedtls_x509_buf *second)
309 {
310 if (IsLegitString(first->tag) && IsLegitString(second->tag)) {
311 for (int32_t i = 0; i < first->len; i++) {
312 if (first->p[i] == second->p[i] ||
313 ((islower(first->p[i]) != 0) && (first->p[i] - DIFF_NUM == second->p[i])) ||
314 ((isupper(first->p[i]) != 0) && (first->p[i] + DIFF_NUM == second->p[i]))) {
315 continue;
316 }
317 return -1;
318 }
319 return 0;
320 }
321 return -1;
322 }
323
GetDeps(const mbedtls_x509_name * nameList)324 static int32_t GetDeps(const mbedtls_x509_name *nameList)
325 {
326 int32_t deps = 0;
327 while (nameList != NULL) {
328 nameList = nameList->next;
329 deps++;
330 }
331 return deps;
332 }
333
CompareX509NameList(const mbedtls_x509_name * first,const mbedtls_x509_name * second)334 static int32_t CompareX509NameList(const mbedtls_x509_name *first, const mbedtls_x509_name *second)
335 {
336 if (first == NULL || second == NULL) {
337 return -1;
338 }
339 int32_t firstDeps = GetDeps(first);
340 int32_t secondDeps = GetDeps(second);
341 if (firstDeps != secondDeps) {
342 return -1;
343 }
344 for (int32_t i = 0; i < firstDeps; i++) {
345 if (first->oid.tag != second->oid.tag ||
346 first->oid.len != second->oid.len ||
347 memcmp(first->oid.p, second->oid.p, second->oid.len) != 0 ||
348 first->MBEDTLS_PRIVATE(next_merged) != second->MBEDTLS_PRIVATE(next_merged) ||
349 first->val.len != second->val.len) {
350 return -1;
351 }
352 if (CompareX509String(&first->val, &second->val) != 0) {
353 return -1;
354 }
355 first = first->next;
356 second = second->next;
357 }
358 return 0;
359 }
360
Pkcs7Calloc(size_t nmemb,size_t size)361 static void *Pkcs7Calloc(size_t nmemb, size_t size)
362 {
363 return calloc(nmemb, size);
364 }
365
Pkcs7Free(void * ptr)366 static void Pkcs7Free(void *ptr)
367 {
368 free(ptr);
369 }
370
ParseSignedDataSignerInfos(unsigned char ** p,const unsigned char * end,SignerInfo * signers)371 static int32_t ParseSignedDataSignerInfos(unsigned char **p, const unsigned char *end, SignerInfo *signers)
372 {
373 int32_t rc;
374 size_t len = 0;
375
376 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET);
377 if (rc || len == 0) {
378 return PKCS7_HAS_NO_SIGNER_INFO;
379 }
380 end = *p + len; // update end to the SET end.
381
382 while (*p < end) {
383 size_t oneSignerLen;
384 unsigned char *oneSignerEnd = NULL;
385 /* parse one signer info */
386 rc = mbedtls_asn1_get_tag(p, end, &oneSignerLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
387 PKCS7_ERR_RETURN_WITH_LOG(rc);
388
389 oneSignerEnd = *p + oneSignerLen;
390 /* parse version */
391 rc = ParseSignerVersion(p, oneSignerEnd, signers);
392 PKCS7_ERR_RETURN_WITH_LOG(rc);
393
394 /* parse issuerAndSerialNum */
395 rc = ParseSignerIssuerAndSerialNum(p, oneSignerEnd, signers);
396 PKCS7_ERR_RETURN_WITH_LOG(rc);
397
398 /* parse digestAlgorithm */
399 rc = ParseSignerDigestAlg(p, oneSignerEnd, signers);
400 PKCS7_ERR_RETURN_WITH_LOG(rc);
401
402 /* parse authenticatedAttributes */
403 rc = ParseSignerAuthAttr(p, oneSignerEnd, signers);
404 PKCS7_ERR_RETURN_WITH_LOG(rc);
405
406 /* parse digestEncryptionAlgorithm */
407 rc = ParseSignerEncAlg(p, oneSignerEnd, signers);
408 PKCS7_ERR_RETURN_WITH_LOG(rc);
409
410 /* parse encryptedDigest */
411 rc = ParseSignerSignature(p, oneSignerEnd, signers);
412 PKCS7_ERR_RETURN_WITH_LOG(rc);
413
414 /* parse unauthenticatedAttributes */
415 rc = ParseSignerUnAuthAttr(p, oneSignerEnd, signers);
416 PKCS7_ERR_RETURN_WITH_LOG(rc);
417
418 if (*p < end) {
419 signers->next = Pkcs7Calloc(1, sizeof(*signers));
420 if (signers->next == NULL) {
421 /* release resource in main entry. */
422 return PKCS7_MEMORY_EXHAUST;
423 }
424 signers = signers->next;
425 }
426 }
427 return rc;
428 }
429
ParseSignedDataVersion(unsigned char ** p,const unsigned char * end,int32_t * ver)430 static int32_t ParseSignedDataVersion(unsigned char **p, const unsigned char *end, int32_t *ver)
431 {
432 int32_t rc = mbedtls_asn1_get_int(p, end, ver);
433 if (rc) {
434 return rc;
435 }
436
437 if (*ver != PKCS7_SIGNED_DATA_VERSION) {
438 LOG_ERROR("Invalid version : %d\n", *ver);
439 return PKCS7_INVALID_VERSION;
440 }
441 LOG_INFO("Parse signed data version success\n");
442 return PKCS7_SUCC;
443 }
444
ParseSignedDataDigestAlgs(unsigned char ** p,const unsigned char * end,DigestAlgId * algIds)445 static int32_t ParseSignedDataDigestAlgs(unsigned char **p, const unsigned char *end, DigestAlgId *algIds)
446 {
447 int32_t rc;
448 size_t len = 0;
449
450 /* parse SET OF header */
451 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET);
452 if (rc) {
453 return rc;
454 }
455 end = *p + len;
456
457 /* parse SET OF 's digest alg content */
458 DigestAlgId *id = algIds;
459 while (*p < end) {
460 mbedtls_asn1_buf params = {0};
461 /* alg param is supported, but not be used now */
462 rc = mbedtls_asn1_get_alg(p, end, &id->algBuf, ¶ms);
463 if (rc) {
464 return rc;
465 }
466 if (InvalidDigestAlg(&id->algBuf)) {
467 return PKCS7_INVALID_DIGEST_ALG;
468 }
469 if (*p < end) {
470 id->next = Pkcs7Calloc(1, sizeof(DigestAlgId));
471 if (id->next == NULL) {
472 /* resource will be released in parse main entry */
473 return PKCS7_MEMORY_EXHAUST;
474 }
475 id = id->next;
476 }
477 }
478 return PKCS7_SUCC;
479 }
480
DlogContentInfo(const Content * content)481 static void DlogContentInfo(const Content *content)
482 {
483 int32_t len = content->data.len;
484 if (len <= 0) {
485 return;
486 }
487 char *info = Pkcs7Calloc(len + 1, sizeof(char));
488 if (info == NULL) {
489 return;
490 }
491 if (strncpy_s(info, len + 1, (char *)content->data.p, len) != EOK) {
492 Pkcs7Free(info);
493 return;
494 }
495 Pkcs7Free(info);
496 }
497
ParseSignedDataContentInfo(unsigned char ** p,const unsigned char * end,Content * content)498 static int32_t ParseSignedDataContentInfo(unsigned char **p, const unsigned char *end, Content *content)
499 {
500 int32_t rc;
501 size_t len = 0;
502 bool hasContent = false;
503
504 rc = GetContentInfoType(p, end, &content->oid, &hasContent);
505 if (rc) {
506 return rc;
507 }
508
509 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content->oid) || !hasContent) {
510 LOG_ERROR("Invalid content type or has no real content");
511 return PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
512 }
513 rc = GetContentLenOfContentInfo(p, end, &len);
514 if (rc) {
515 return rc;
516 }
517 content->data.tag = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC; // has no use
518 content->data.p = *p;
519 content->data.len = len;
520 DlogContentInfo(content);
521 *p += len;
522 return PKCS7_SUCC;
523 }
524
ParseSignedDataCerts(unsigned char ** p,const unsigned char * end,mbedtls_x509_crt ** certs)525 static int32_t ParseSignedDataCerts(unsigned char **p, const unsigned char *end, mbedtls_x509_crt **certs)
526 {
527 int32_t rc;
528 size_t len = 0;
529
530 rc = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
531 if (rc) {
532 LOG_ERROR("Has no certificates in signed data.");
533 return PKCS7_SUCC;
534 }
535 *certs = mbedtls_calloc(1, sizeof(**certs));
536 if (*certs == NULL) {
537 return PKCS7_MEMORY_EXHAUST;
538 }
539 mbedtls_x509_crt_init(*certs);
540
541 unsigned char *certsEnd = *p + len;
542 int32_t cnt = 0;
543 while (*p < certsEnd) {
544 /* scan every cert */
545 size_t oneCertLen;
546 unsigned char *seqBegin = *p;
547 rc = mbedtls_asn1_get_tag(p, end, &oneCertLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
548 if (rc) {
549 return rc;
550 }
551 if (oneCertLen + (*p - seqBegin) > (certsEnd - seqBegin)) {
552 return PKCS7_PARSING_ERROR;
553 }
554 rc = mbedtls_x509_crt_parse(*certs, seqBegin, oneCertLen + (*p - seqBegin));
555 if (rc) {
556 return rc;
557 }
558 *p += oneCertLen;
559 cnt++;
560 }
561 LOG_INFO("Parse signed data certs success");
562 return rc;
563 }
564
ParseSignedDataCrl(unsigned char ** p,const unsigned char * end,mbedtls_x509_crl * crl)565 static int32_t ParseSignedDataCrl(unsigned char **p, const unsigned char *end, mbedtls_x509_crl *crl)
566 {
567 int32_t rc;
568 size_t len = 0;
569
570 rc = mbedtls_asn1_get_tag(p, end, &len, (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) + 1);
571 if (rc) {
572 LOG_INFO("Has no crl in signed data.");
573 return PKCS7_SUCC;
574 }
575 mbedtls_x509_crl_init(crl);
576 rc = mbedtls_x509_crl_parse(crl, *p, len);
577 *p += len;
578 return rc;
579 }
580
ParseSignedData(unsigned char * buf,size_t bufLen,SignedData * signedData)581 static int32_t ParseSignedData(unsigned char *buf, size_t bufLen, SignedData *signedData)
582 {
583 unsigned char *p = buf;
584 unsigned char *end = buf + bufLen;
585 size_t len = 0;
586 int32_t rc;
587
588 /* parse SignedData sequence header */
589 rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
590 if (rc) {
591 return rc;
592 }
593
594 /* parse version of signed data */
595 rc = ParseSignedDataVersion(&p, end, &signedData->version);
596 if (rc) {
597 return rc;
598 }
599
600 /* parse digestAlgorithms */
601 rc = ParseSignedDataDigestAlgs(&p, end, &signedData->digestAlgIds);
602 if (rc) {
603 return rc;
604 }
605
606 /* parse contentInfo */
607 rc = ParseSignedDataContentInfo(&p, end, &signedData->content);
608 if (rc) {
609 return rc;
610 }
611
612 if (p >= end) {
613 return PKCS7_PARSING_ERROR;
614 }
615 /* parse certificates (optional) */
616 rc = ParseSignedDataCerts(&p, end, &signedData->certs);
617 if (rc) {
618 return rc;
619 }
620
621 /* parse crls (optional) */
622 rc = ParseSignedDataCrl(&p, end, &signedData->crl);
623 if (rc) {
624 return rc;
625 }
626
627 /* parse signerInfos */
628 rc = ParseSignedDataSignerInfos(&p, end, &signedData->signers);
629 LOG_INFO("ParseSignedData %d", rc);
630 return rc;
631 }
632
IsSigedDataOid(const Pkcs7 * pkcs7)633 static bool IsSigedDataOid(const Pkcs7 *pkcs7)
634 {
635 return !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->contentTypeOid);
636 }
637
FreeSignedDataDigestAlgs(Pkcs7 * pkcs7)638 static void FreeSignedDataDigestAlgs(Pkcs7 *pkcs7)
639 {
640 DigestAlgId *alg = pkcs7->signedData.digestAlgIds.next;
641 DigestAlgId *next = NULL;
642
643 while (alg != NULL) {
644 next = alg->next;
645 Pkcs7Free(alg);
646 alg = next;
647 }
648 pkcs7->signedData.digestAlgIds.next = NULL;
649 }
650
FreeSignerCerts(SignerInfo * signer)651 static void FreeSignerCerts(SignerInfo *signer)
652 {
653 if (signer->certPath.crt != NULL) {
654 mbedtls_x509_crt_free(signer->certPath.crt);
655 mbedtls_free(signer->certPath.crt);
656 signer->certPath.crt = NULL;
657 }
658 }
659
FreeSignerIssuer(SignerInfo * signer)660 static void FreeSignerIssuer(SignerInfo *signer)
661 {
662 mbedtls_x509_name *name_cur = NULL;
663 mbedtls_x509_name *name_prv = NULL;
664 name_cur = signer->issuer.next;
665 while (name_cur != NULL) {
666 name_prv = name_cur;
667 name_cur = name_cur->next;
668 mbedtls_free(name_prv);
669 }
670 signer->issuer.next = NULL;
671 }
672
FreeSignersInfo(Pkcs7 * pkcs7)673 static void FreeSignersInfo(Pkcs7 *pkcs7)
674 {
675 SignerInfo *signer = pkcs7->signedData.signers.next;
676 SignerInfo *next = NULL;
677
678 while (signer != NULL) {
679 next = signer->next;
680 FreeSignerCerts(signer);
681 FreeSignerIssuer(signer);
682 Pkcs7Free(signer);
683 signer = next;
684 }
685 pkcs7->signedData.signers.next = NULL;
686 FreeSignerCerts(&pkcs7->signedData.signers);
687 FreeSignerIssuer(&pkcs7->signedData.signers);
688 }
689
FreeSignedDataCerts(Pkcs7 * pkcs7)690 static void FreeSignedDataCerts(Pkcs7 *pkcs7)
691 {
692 if (pkcs7->signedData.certs != NULL) {
693 mbedtls_x509_crt_free(pkcs7->signedData.certs);
694 mbedtls_free(pkcs7->signedData.certs);
695 pkcs7->signedData.certs = NULL;
696 }
697 }
698
FreeSignedDataCrl(Pkcs7 * pkcs7)699 static void FreeSignedDataCrl(Pkcs7 *pkcs7)
700 {
701 mbedtls_x509_crl_free(&pkcs7->signedData.crl);
702 return;
703 }
704
GetCertsNumOfSignedData(const mbedtls_x509_crt * crts)705 static int32_t GetCertsNumOfSignedData(const mbedtls_x509_crt *crts)
706 {
707 int32_t cnt = 0;
708 while (crts != NULL) {
709 crts = crts->next;
710 cnt++;
711 }
712 return cnt;
713 }
714
FindSuperCert(mbedtls_x509_crt * cur,mbedtls_x509_crt * certsList)715 static mbedtls_x509_crt *FindSuperCert(mbedtls_x509_crt *cur, mbedtls_x509_crt *certsList)
716 {
717 /* current level's subject is next level issuer */
718 while (certsList != NULL) {
719 if (CompareX509NameList(&cur->issuer, &certsList->subject) == 0) {
720 break;
721 }
722 certsList = certsList->next;
723 }
724 return certsList;
725 }
726
DelCertOfSignedData(SignedData * signedData,mbedtls_x509_crt * crt)727 static void DelCertOfSignedData(SignedData *signedData, mbedtls_x509_crt *crt)
728 {
729 mbedtls_x509_crt *head = signedData->certs;
730 if (crt == head) {
731 signedData->certs = crt->next;
732 crt->next = NULL;
733 } else {
734 mbedtls_x509_crt *prev = head;
735 while (head != NULL) {
736 if (head == crt) {
737 prev->next = crt->next;
738 crt->next = NULL;
739 break;
740 }
741 prev = head;
742 head = head->next;
743 }
744 }
745 }
746
AddCertToSignerCertPath(SignerInfo * signer,mbedtls_x509_crt * crt)747 static void AddCertToSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *crt)
748 {
749 mbedtls_x509_crt *prev = signer->certPath.crt;
750 mbedtls_x509_crt *cur = prev;
751 if (prev == NULL) {
752 signer->certPath.crt = crt;
753 crt->next = NULL;
754 } else {
755 while (cur != NULL) {
756 prev = cur;
757 cur = cur->next;
758 }
759 prev->next = crt;
760 crt->next = NULL;
761 }
762
763 signer->certPath.depth++;
764 }
765
BuildSignerCertPath(SignerInfo * signer,mbedtls_x509_crt * lowerCrt,SignedData * signeData)766 static int32_t BuildSignerCertPath(SignerInfo *signer, mbedtls_x509_crt *lowerCrt, SignedData *signeData)
767 {
768 int32_t scanCnt = 0;
769 int32_t rc = PKCS7_SUCC;
770 if (!g_rootCertLoaded) {
771 return PKCS7_ROOT_CA_NOT_VALID;
772 }
773 signer->rootCert = &g_rootCaG2Cert;
774
775 mbedtls_x509_crt *certs = signeData->certs;
776 /* From the root ca cert, to found the signer secondary ca , and use secondary cert to
777 * find the next level ca cert */
778 mbedtls_x509_crt *cur = lowerCrt;
779 mbedtls_x509_crt *next = NULL;
780 int32_t certsCnt = GetCertsNumOfSignedData(certs);
781 DelCertOfSignedData(signeData, cur);
782 AddCertToSignerCertPath(signer, cur);
783 while (true) {
784 next = FindSuperCert(cur, signeData->certs);
785 if (next == NULL) {
786 break;
787 } else {
788 DelCertOfSignedData(signeData, next);
789 AddCertToSignerCertPath(signer, next);
790 }
791 scanCnt++;
792 if (scanCnt > certsCnt) {
793 rc = PKCS7_BUILD_CERT_PATH_FAIL;
794 break;
795 }
796 cur = next;
797 }
798 return rc;
799 }
800
ConstructSignerCerts(SignedData * signedData)801 static int32_t ConstructSignerCerts(SignedData *signedData)
802 {
803 /* scan all of the signers , and filter the signer's certs by serial and name */
804 SignerInfo *signer = &signedData->signers;
805 while (signer != NULL) {
806 mbedtls_x509_buf *signerSerial = &signer->serial;
807 mbedtls_x509_name *signerIssuer = &signer->issuer;
808 mbedtls_x509_crt *cert = signedData->certs;
809 LOG_INFO("To filter one signer's cert");
810 while (cert != NULL) {
811 if (SerialCmp(signerSerial, &cert->serial) == 0 &&
812 CompareX509NameList(signerIssuer, &cert->issuer) == 0) {
813 LOG_INFO("Found signer's low level cert");
814 break;
815 }
816 cert = cert->next;
817 }
818 if (cert == NULL) {
819 LOG_ERROR("Could not found signer's lowest cert");
820 return PKCS7_INVALID_VALUE;
821 }
822 int32_t rc = BuildSignerCertPath(signer, cert, signedData);
823 if (rc != 0) {
824 return rc;
825 }
826 signer = signer->next;
827 }
828 return 0;
829 }
830
831 /* get signer digest alg */
GetSignerDigestAlg(const SignerInfo * signer,mbedtls_md_type_t * algType)832 static int32_t GetSignerDigestAlg(const SignerInfo *signer, mbedtls_md_type_t *algType)
833 {
834 const mbedtls_x509_buf *alg = &signer->digestAlgId;
835 if (!MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA256, alg)) {
836 *algType = MBEDTLS_MD_SHA256;
837 return PKCS7_SUCC;
838 }
839 if (!MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA384, alg)) {
840 *algType = MBEDTLS_MD_SHA384;
841 return PKCS7_SUCC;
842 }
843 if (!MBEDTLS_OID_CMP(MBEDTLS_OID_DIGEST_ALG_SHA512, alg)) {
844 *algType = MBEDTLS_MD_SHA512;
845 return PKCS7_SUCC;
846 }
847 return PKCS7_INVALID_DIGEST_ALG;
848 }
849
850 /* get signer pubkey of sign from signer cert */
GetSignerPubKeyOfSignature(const SignerInfo * signer,mbedtls_pk_context ** pk)851 static int32_t GetSignerPubKeyOfSignature(const SignerInfo *signer, mbedtls_pk_context **pk)
852 {
853 /* signer cert_path first cert is the lowest cert. yet is the signature cert */
854 if (signer == NULL || pk == NULL) {
855 return PKCS7_INVALID_PARAM;
856 }
857 if (signer->certPath.crt != NULL) {
858 *pk = &signer->certPath.crt->pk;
859 return PKCS7_SUCC;
860 }
861 return PKCS7_INVALID_VALUE;
862 }
863
PKCS7_VerifySignerSignature(const Pkcs7 * pkcs7,PKCS7_CalcDigest calcDigest)864 int32_t PKCS7_VerifySignerSignature(const Pkcs7 *pkcs7, PKCS7_CalcDigest calcDigest)
865 {
866 int32_t rc;
867 if (pkcs7 == NULL || calcDigest == NULL) {
868 return PKCS7_INVALID_PARAM;
869 }
870 const SignerInfo *signer = &pkcs7->signedData.signers;
871 unsigned char *sig = NULL;
872 size_t sigLen;
873 while (signer != NULL) {
874 rc = GetSignerSignature(signer, &sig, &sigLen);
875 if (rc) {
876 return rc;
877 }
878 LOG_INFO("get signer signature len : %zu", sigLen);
879
880 mbedtls_pk_context *pk = NULL;
881 rc = GetSignerPubKeyOfSignature(signer, &pk);
882 if (rc) {
883 return rc;
884 }
885 mbedtls_md_type_t digAlg;
886 rc = GetSignerDigestAlg(signer, &digAlg);
887 if (rc) {
888 return rc;
889 }
890 unsigned char hash[MAX_HASH_SIZE];
891 (void)memset_s(hash, MAX_HASH_SIZE, 0, MAX_HASH_SIZE);
892 size_t hashLen = 0;
893 rc = calcDigest(pkcs7, signer, digAlg, hash, &hashLen);
894 if (rc) {
895 LOG_ERROR("Calculate content hash failed by calling callback");
896 return rc;
897 }
898 /* if is rsassa-pss, need to set padding version to V21, RFC3447 */
899 if (!MBEDTLS_OID_CMP(MBEDTLS_OID_RSASSA_PSS, &signer->digestEncAlgId)) {
900 mbedtls_rsa_set_padding(pk->MBEDTLS_PRIVATE(pk_ctx), MBEDTLS_RSA_PKCS_V21, (mbedtls_md_type_t)0);
901 }
902 rc = mbedtls_pk_verify(pk, digAlg, hash, hashLen, sig, sigLen);
903 (void)memset_s(hash, MAX_HASH_SIZE, 0, MAX_HASH_SIZE);
904 if (rc) {
905 LOG_ERROR("Verify signature failed, returned -0x%04x", rc);
906 return rc;
907 } else {
908 LOG_INFO("Verify signer signature success\n");
909 }
910 signer = signer->next;
911 }
912 return rc;
913 }
914
LoadRootCert(void)915 static int32_t LoadRootCert(void)
916 {
917 int32_t rc = 0;
918 if (!g_rootCertLoaded) {
919 mbedtls_x509_crt_init(&g_rootCaG2Cert);
920 rc = mbedtls_x509_crt_parse(&g_rootCaG2Cert, ROOT_CA_G2_CERT_IN_PEM, sizeof(ROOT_CA_G2_CERT_IN_PEM));
921 if (rc) {
922 LOG_ERROR("load root ca failed");
923 return rc;
924 } else {
925 LOG_INFO("load root ca success");
926 }
927 g_rootCertLoaded = true;
928 }
929 return rc;
930 }
931
UnLoadRootCert(void)932 static void UnLoadRootCert(void)
933 {
934 if (g_rootCertLoaded) {
935 mbedtls_x509_crt_free(&g_rootCaG2Cert);
936 g_rootCertLoaded = false;
937 }
938 }
939
LoadDebugModeRootCert(void)940 static int32_t LoadDebugModeRootCert(void)
941 {
942 mbedtls_x509_crt_init(&g_debugModeRootCert);
943 int32_t rc = mbedtls_x509_crt_parse(&g_debugModeRootCert, DEBUG_MODE_ROOT_CERT_IN_PEM,
944 sizeof(DEBUG_MODE_ROOT_CERT_IN_PEM));
945 if (rc) {
946 LOG_ERROR("load debug mode root ca failed %d", rc);
947 return rc;
948 } else {
949 LOG_INFO("load debug mode root ca success");
950 }
951 return rc;
952 }
UnLoadDebugModeRootCert(void)953 static int32_t UnLoadDebugModeRootCert(void)
954 {
955 mbedtls_x509_crt_free(&g_debugModeRootCert);
956 return PKCS7_SUCC;
957 }
958
LoadSelfSignedCert(void)959 static int32_t LoadSelfSignedCert(void)
960 {
961 mbedtls_x509_crt_init(&g_ohosRootCert);
962 int32_t rc = mbedtls_x509_crt_parse(&g_ohosRootCert, OHOS_ROOT_CERT_IN_PEM, sizeof(OHOS_ROOT_CERT_IN_PEM));
963 if (rc) {
964 LOG_ERROR("load self signed ca failed %d", rc);
965 return rc;
966 } else {
967 LOG_INFO("load self signed root ca success");
968 }
969 return rc;
970 }
971
UnLoadSelfSignedCert(void)972 static void UnLoadSelfSignedCert(void)
973 {
974 mbedtls_x509_crt_free(&g_ohosRootCert);
975 }
DLogCrtVerifyInfo(uint32_t flags)976 static void DLogCrtVerifyInfo(uint32_t flags)
977 {
978 char vrfyBuf[VERIFY_BUF_LEN];
979 (void)memset_s(vrfyBuf, VERIFY_BUF_LEN, 0, VERIFY_BUF_LEN);
980 mbedtls_x509_crt_verify_info(vrfyBuf, sizeof(vrfyBuf), " ! ", flags);
981 LOG_DEBUG("%s", vrfyBuf);
982 }
983
IsRevoked(const mbedtls_x509_crt * crt,const mbedtls_x509_crl * crl)984 static int32_t IsRevoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl)
985 {
986 mbedtls_x509_crl_entry *cur = (mbedtls_x509_crl_entry *)(&crl->entry);
987 while (cur != NULL) {
988 if (cur->serial.len == 0) {
989 return PKCS7_SUCC;
990 }
991 if (crt->serial.len != cur->serial.len) {
992 cur = cur->next;
993 continue;
994 }
995 if (memcmp(crt->serial.p, cur->serial.p, cur->serial.len) == 0) {
996 return PKCS7_IS_REVOKED;
997 }
998 cur = cur->next;
999 }
1000 return PKCS7_SUCC;
1001 }
1002
VerifyCrl(const mbedtls_x509_crt * crt,const mbedtls_x509_crl * crl)1003 static int32_t VerifyCrl(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl)
1004 {
1005 const mbedtls_x509_crl *crlList = crl;
1006 while (crlList != NULL) {
1007 if (crlList->version == 0 ||
1008 CompareX509NameList(&crlList->issuer, &crt->issuer) != 0) {
1009 crlList = crlList->next;
1010 continue;
1011 }
1012 LOG_INFO("find crl");
1013 if (IsRevoked(crt, crlList)) {
1014 return PKCS7_IS_REVOKED;
1015 }
1016 crlList = crlList->next;
1017 }
1018 return PKCS7_SUCC;
1019 }
1020
VerifyClicert(mbedtls_x509_crt * clicert,mbedtls_x509_crt * rootCert,const Pkcs7 * pkcs7)1021 static int32_t VerifyClicert(mbedtls_x509_crt *clicert, mbedtls_x509_crt *rootCert, const Pkcs7 *pkcs7)
1022 {
1023 uint32_t flags;
1024 int32_t rc = mbedtls_x509_crt_verify(clicert, rootCert,
1025 (mbedtls_x509_crl *)&pkcs7->signedData.crl, NULL, &flags, NULL, NULL);
1026 if (rc) {
1027 DLogCrtVerifyInfo(flags);
1028 } else {
1029 LOG_INFO("Verify signers cert chain root cert success");
1030 if (VerifyCrl(clicert, (mbedtls_x509_crl *)&pkcs7->signedData.crl) != PKCS7_SUCC) {
1031 LOG_ERROR("cert crl verify failed");
1032 return PKCS7_IS_REVOKED;
1033 }
1034 return PKCS7_SUCC;
1035 }
1036 return rc;
1037 }
1038
PKCS7_VerifyCertsChain(const Pkcs7 * pkcs7)1039 int32_t PKCS7_VerifyCertsChain(const Pkcs7 *pkcs7)
1040 {
1041 if (pkcs7 == NULL) {
1042 return PKCS7_INVALID_PARAM;
1043 }
1044 int32_t cnt = 0;
1045 const SignerInfo *signer = &pkcs7->signedData.signers;
1046 while (signer != NULL) {
1047 mbedtls_x509_crt *clicert = signer->certPath.crt;
1048 if (clicert == NULL) {
1049 LOG_ERROR("Signer has no certs");
1050 return PKCS7_HAS_NO_SIGNER_CRT;
1051 }
1052 int32_t rc;
1053 cnt++;
1054 LOG_INFO("signer : %d", cnt);
1055 if (g_debugModeEnabled) {
1056 rc = VerifyClicert(clicert, &g_debugModeRootCert, pkcs7);
1057 LOG_DEBUG("Verify inner: %d", rc);
1058 if (rc == PKCS7_SUCC) {
1059 signer = signer->next;
1060 continue;
1061 }
1062 if (rc == PKCS7_IS_REVOKED) {
1063 return PKCS7_IS_REVOKED;
1064 }
1065 }
1066 rc = VerifyClicert(clicert, signer->rootCert, pkcs7);
1067 LOG_DEBUG("Verify : %d", rc);
1068 if (rc == PKCS7_SUCC) {
1069 signer = signer->next;
1070 continue;
1071 }
1072 if (rc == PKCS7_IS_REVOKED) {
1073 return PKCS7_IS_REVOKED;
1074 }
1075 #ifndef OHOS_SIGN_HAPS_BY_SERVER
1076 rc = VerifyClicert(clicert, &g_ohosRootCert, pkcs7);
1077 LOG_DEBUG("Verify self : %d", rc);
1078 if (rc == PKCS7_SUCC) {
1079 signer = signer->next;
1080 continue;
1081 }
1082 #endif
1083 return rc;
1084 }
1085 return PKCS7_SUCC;
1086 }
1087
PKCS7_GetSignerSignningCertSubject(const SignerInfo * signer,char * subject,size_t subjectLen)1088 int32_t PKCS7_GetSignerSignningCertSubject(const SignerInfo *signer, char *subject, size_t subjectLen)
1089 {
1090 int32_t rc;
1091 if (signer == NULL || subject == NULL) {
1092 return PKCS7_INVALID_PARAM;
1093 }
1094 const mbedtls_x509_crt *crt = signer->certPath.crt;
1095 rc = mbedtls_x509_dn_gets(subject, subjectLen, &crt->subject);
1096 if (rc < 0) {
1097 return rc;
1098 }
1099 return PKCS7_SUCC;
1100 }
1101
PKCS7_GetSignerSignningCertIssuer(const SignerInfo * signer,char * issuer,size_t issuerLen)1102 int32_t PKCS7_GetSignerSignningCertIssuer(const SignerInfo *signer, char *issuer, size_t issuerLen)
1103 {
1104 int32_t rc;
1105 if (signer == NULL || issuer == NULL) {
1106 return PKCS7_INVALID_PARAM;
1107 }
1108 const mbedtls_x509_crt *crt = signer->certPath.crt;
1109 rc = mbedtls_x509_dn_gets(issuer, issuerLen, &crt->issuer);
1110 if (rc < 0) {
1111 return rc;
1112 }
1113 return PKCS7_SUCC;
1114 }
1115
GetSignersCnt(const SignerInfo * signers)1116 static size_t GetSignersCnt(const SignerInfo *signers)
1117 {
1118 size_t cnt = 0;
1119 while (signers != NULL) {
1120 cnt++;
1121 signers = signers->next;
1122 }
1123 return cnt;
1124 }
1125
IsIncludeRoot(const SignerInfo * signer)1126 static bool IsIncludeRoot(const SignerInfo *signer)
1127 {
1128 mbedtls_x509_crt *pre = signer->certPath.crt;
1129 mbedtls_x509_crt *cur = pre;
1130 int32_t i = 0;
1131 while (i < signer->certPath.depth && cur != NULL) {
1132 pre = cur;
1133 cur = cur->next;
1134 i++;
1135 }
1136
1137 if (pre == NULL) {
1138 return false;
1139 }
1140
1141 /* root cert is a self-sign cert */
1142 if (CompareX509NameList(&pre->issuer, &pre->subject) == 0) {
1143 LOG_INFO("Include root cert");
1144 return true;
1145 }
1146 LOG_INFO("Not include root cert");
1147 return false;
1148 }
1149
GetSignerSignningCertDepth(const SignerInfo * signer)1150 static int32_t GetSignerSignningCertDepth(const SignerInfo *signer)
1151 {
1152 if (IsIncludeRoot(signer)) {
1153 return signer->certPath.depth;
1154 }
1155
1156 /* root cert is not included in signer->certPath, add 1 for root cert */
1157 return signer->certPath.depth + 1;
1158 }
1159
PKCS7_FreeAllSignersResolvedInfo(SignersResovedInfo * sri)1160 void PKCS7_FreeAllSignersResolvedInfo(SignersResovedInfo *sri)
1161 {
1162 if (sri == NULL) {
1163 return;
1164 }
1165 if (sri->signers != NULL) {
1166 Pkcs7Free(sri->signers);
1167 sri->signers = NULL;
1168 }
1169 Pkcs7Free(sri);
1170 }
1171
PKCS7_GetAllSignersResolvedInfo(const Pkcs7 * pkcs7)1172 SignersResovedInfo *PKCS7_GetAllSignersResolvedInfo(const Pkcs7 *pkcs7)
1173 {
1174 SignersResovedInfo *sri = NULL;
1175 if (pkcs7 == NULL) {
1176 return NULL;
1177 }
1178 size_t signersCnt = GetSignersCnt(&pkcs7->signedData.signers);
1179 if (signersCnt == 0) {
1180 return NULL;
1181 }
1182 sri = Pkcs7Calloc(1, sizeof(*sri));
1183 if (sri == NULL) {
1184 return NULL;
1185 }
1186 sri->nrOfSigners = signersCnt;
1187 sri->signers = Pkcs7Calloc(signersCnt, sizeof(SignerResovledInfo));
1188 if (sri->signers == NULL) {
1189 Pkcs7Free(sri);
1190 return NULL;
1191 }
1192 int32_t rc;
1193 const SignerInfo *signer = &pkcs7->signedData.signers;
1194 int32_t idx = 0;
1195 while (signer != NULL && idx < signersCnt) {
1196 rc = PKCS7_GetSignerSignningCertSubject(signer, sri->signers[idx].subject, sizeof(sri->signers[idx].subject));
1197 if (rc) {
1198 goto OUT;
1199 }
1200 rc = PKCS7_GetSignerSignningCertIssuer(signer, sri->signers[idx].issuer, sizeof(sri->signers[idx].issuer));
1201 if (rc) {
1202 goto OUT;
1203 }
1204 sri->signers[idx].depth = GetSignerSignningCertDepth(signer);
1205
1206 signer = signer->next;
1207 idx++;
1208 }
1209 return sri;
1210 OUT:
1211 PKCS7_FreeAllSignersResolvedInfo(sri);
1212 return NULL;
1213 }
1214
PKCS7_GetDigestInSignerAuthAttr(const SignerInfo * signer,unsigned char ** dig,size_t * digLen)1215 int32_t PKCS7_GetDigestInSignerAuthAttr(const SignerInfo *signer, unsigned char **dig, size_t *digLen)
1216 {
1217 if (signer == NULL || dig == NULL || digLen == NULL) {
1218 return PKCS7_INVALID_VALUE;
1219 }
1220 unsigned char *p = signer->authAttr.p;
1221 if (p == NULL) {
1222 return PKCS7_HAS_NO_AUTH_ATTR_IN_SIGNER;
1223 }
1224 unsigned char *end = p + signer->authAttr.len;
1225 size_t tmpLen = 0;
1226
1227 /* SET OF SEQUENCE */
1228 while (p < end) {
1229 size_t seqLen;
1230 unsigned char *seqEnd = NULL;
1231 int32_t rc = mbedtls_asn1_get_tag(&p, end, &seqLen, MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED);
1232 if (rc) {
1233 return rc;
1234 }
1235 seqEnd = p + seqLen;
1236 /* SEQUENCE : OID and SET */
1237 size_t oidLen;
1238 rc = mbedtls_asn1_get_tag(&p, seqEnd, &oidLen, MBEDTLS_ASN1_OID);
1239 if (rc) {
1240 return rc;
1241 }
1242 if (oidLen == MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS9_MSG_DIGEST) &&
1243 memcmp(p, MBEDTLS_OID_PKCS9_MSG_DIGEST, MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS9_MSG_DIGEST)) == 0) {
1244 p += oidLen;
1245 rc = mbedtls_asn1_get_tag(&p, seqEnd, &tmpLen, MBEDTLS_ASN1_SET | MBEDTLS_ASN1_CONSTRUCTED);
1246 if (rc) {
1247 return rc;
1248 }
1249 /* we just resolve one now. */
1250 rc = mbedtls_asn1_get_tag(&p, seqEnd, &tmpLen, MBEDTLS_ASN1_OCTET_STRING);
1251 if (rc) {
1252 return rc;
1253 }
1254 *dig = p;
1255 *digLen = tmpLen;
1256 return PKCS7_SUCC;
1257 } else {
1258 p = seqEnd;
1259 }
1260 }
1261 return PKCS7_INVALID_VALUE;
1262 }
1263
PKCS7_GetSignerAuthAttr(const SignerInfo * signer,unsigned char ** data,size_t * dataLen)1264 int32_t PKCS7_GetSignerAuthAttr(const SignerInfo *signer, unsigned char **data, size_t *dataLen)
1265 {
1266 if (signer == NULL || signer->authAttrRaw.p == NULL || data == NULL || dataLen == NULL) {
1267 return PKCS7_INVALID_VALUE;
1268 }
1269 *dataLen = signer->authAttrRaw.len;
1270 *data = signer->authAttrRaw.p;
1271 *(unsigned char *)signer->authAttrRaw.p = MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET;
1272 return PKCS7_SUCC;
1273 }
1274
PKCS7_GetContentData(const Pkcs7 * pkcs7,unsigned char ** data,size_t * dataLen)1275 int32_t PKCS7_GetContentData(const Pkcs7 *pkcs7, unsigned char **data, size_t *dataLen)
1276 {
1277 if (pkcs7 == NULL || data == NULL || dataLen == NULL) {
1278 return PKCS7_INVALID_PARAM;
1279 }
1280
1281 unsigned char *p = pkcs7->signedData.content.data.p;
1282 size_t len = pkcs7->signedData.content.data.len;
1283 unsigned char *end = p + len;
1284 size_t octetLen;
1285 int32_t rc = mbedtls_asn1_get_tag(&p, end, &octetLen, MBEDTLS_ASN1_OCTET_STRING);
1286 if (rc != 0) {
1287 return rc;
1288 }
1289 *data = p;
1290 *dataLen = octetLen;
1291 return PKCS7_SUCC;
1292 }
1293
PKCS7_EnableDebugMode(bool mode)1294 int32_t PKCS7_EnableDebugMode(bool mode)
1295 {
1296 if (g_debugModeEnabled == mode) {
1297 return PKCS7_SUCC;
1298 }
1299 int32_t rc = ((mode == true) ? LoadDebugModeRootCert() : UnLoadDebugModeRootCert());
1300 if (rc) {
1301 return rc;
1302 }
1303 g_debugModeEnabled = mode;
1304 return PKCS7_SUCC;
1305 }
1306
1307 #ifdef PARSE_PEM_FORMAT_SIGNED_DATA
ParsePemFormatSignedData(const unsigned char * buf,size_t bufLen,mbedtls_pem_context * pem,char * format)1308 static int32_t ParsePemFormatSignedData(const unsigned char *buf, size_t bufLen, mbedtls_pem_context *pem, char *format)
1309 {
1310 if (bufLen != 0 && strstr((const char *)buf, "-----BEGIN PKCS7-----") != NULL) {
1311 int32_t ret;
1312 size_t useLen = 0;
1313 mbedtls_pem_init(pem);
1314 ret = mbedtls_pem_read_buffer(pem, "-----BEGIN PKCS7-----", "-----END PKCS7-----",
1315 buf, NULL, 0, &useLen);
1316 if (ret == 0 && useLen == bufLen) {
1317 *format = PEM_FORMAT_SINGED_DATA;
1318 return PKCS7_SUCC;
1319 }
1320 mbedtls_pem_free(pem);
1321 } else {
1322 *format = DER_FORMAT_SINGED_DATA;
1323 return PKCS7_SUCC; // DER format
1324 }
1325 return PKCS7_INVALID_PARAM;
1326 }
1327 #endif
1328
PKCS7_ParseSignedData(const unsigned char * buf,size_t bufLen,Pkcs7 * pkcs7)1329 int32_t PKCS7_ParseSignedData(const unsigned char *buf, size_t bufLen, Pkcs7 *pkcs7)
1330 {
1331 int32_t rc;
1332 size_t len = 0;
1333 bool hasContent = false;
1334 unsigned char *start = NULL;
1335 unsigned char *end = NULL;
1336 if (buf == NULL || bufLen == 0 || pkcs7 == NULL) {
1337 return PKCS7_INVALID_PARAM;
1338 }
1339 (void)memset_s(pkcs7, sizeof(*pkcs7), 0, sizeof(*pkcs7));
1340 start = (unsigned char *)buf;
1341 #ifdef PARSE_PEM_FORMAT_SIGNED_DATA
1342 char format = 0;
1343 rc = ParsePemFormatSignedData(buf, bufLen, &pkcs7->pem, &format);
1344 if (rc) {
1345 goto EXIT;
1346 }
1347 if (format == PEM_FORMAT_SINGED_DATA) {
1348 start = pkcs7->pem.MBEDTLS_PRIVATE(buf);
1349 bufLen = pkcs7->pem.MBEDTLS_PRIVATE(buflen);
1350 }
1351 #endif
1352 end = start + bufLen;
1353 /* loaded the root ca cert */
1354 rc = LoadRootCert();
1355 P_ERR_GOTO_WTTH_LOG(rc);
1356 #ifndef OHOS_SIGN_HAPS_BY_SERVER
1357 rc = LoadSelfSignedCert();
1358 P_ERR_GOTO_WTTH_LOG(rc);
1359 #endif
1360 LOG_INFO("Begin to parse pkcs#7 signed data");
1361 /* parse the ContentInfo total head */
1362 rc = GetContentInfoType(&start, end, &(pkcs7->contentTypeOid), &hasContent);
1363 P_ERR_GOTO_WTTH_LOG(rc);
1364 if (!IsSigedDataOid(pkcs7) || !hasContent) {
1365 rc = PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
1366 LOG_ERROR("Input data is not pkcs#7 signed data format or has no content info");
1367 goto EXIT;
1368 }
1369 rc = GetContentLenOfContentInfo(&start, end, &len);
1370 P_ERR_GOTO_WTTH_LOG(rc);
1371 if (start + len > end) {
1372 rc = PKCS7_INVALID_CONTENT_TYPE_OR_NO_CONTENT;
1373 LOG_ERROR("The length of input data is invalid");
1374 goto EXIT;
1375 }
1376 rc = ParseSignedData(start, len, &(pkcs7->signedData));
1377 P_ERR_GOTO_WTTH_LOG(rc);
1378 LOG_INFO("Parse pkcs#7 signed data success");
1379 rc = ConstructSignerCerts(&pkcs7->signedData);
1380 P_ERR_GOTO_WTTH_LOG(rc);
1381 return rc;
1382 EXIT:
1383 return rc;
1384 }
1385
PKCS7_FreeRes(Pkcs7 * pkcs7)1386 void PKCS7_FreeRes(Pkcs7 *pkcs7)
1387 {
1388 if (pkcs7 == NULL) {
1389 return;
1390 }
1391 FreeSignedDataDigestAlgs(pkcs7);
1392 FreeSignersInfo(pkcs7);
1393 FreeSignedDataCerts(pkcs7);
1394 FreeSignedDataCrl(pkcs7);
1395 UnLoadRootCert();
1396 #ifndef OHOS_SIGN_HAPS_BY_SERVER
1397 UnLoadSelfSignedCert();
1398 #endif
1399 }
1400