• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params);
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, &params);
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