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
56static mbedtls_x509_crt g_rootCaG2Cert;
57static bool g_rootCertLoaded;
58static 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
74static mbedtls_x509_crt g_debugModeRootCert;
75static bool g_debugModeEnabled;
76static 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";
91static mbedtls_x509_crt g_ohosRootCert;
92static 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 */
110static 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
117static 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
143static 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
148static 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
153static 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
180static 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
192static 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 */
216static 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
227static 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 */
246static 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
262static 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
271static 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
291static 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
300static 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
308static 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
324static 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
334static 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
361static void *Pkcs7Calloc(size_t nmemb, size_t size)
362{
363    return calloc(nmemb, size);
364}
365
366static void Pkcs7Free(void *ptr)
367{
368    free(ptr);
369}
370
371static 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
430static 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
445static 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
481static 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
498static 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
525static 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
565static 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
581static 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
633static bool IsSigedDataOid(const Pkcs7 *pkcs7)
634{
635    return !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->contentTypeOid);
636}
637
638static 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
651static 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
660static 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
673static 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
690static 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
699static void FreeSignedDataCrl(Pkcs7 *pkcs7)
700{
701    mbedtls_x509_crl_free(&pkcs7->signedData.crl);
702    return;
703}
704
705static 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
715static 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
727static 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
747static 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
766static 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
801static 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 */
832static 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 */
851static 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
864int32_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
915static 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
932static void UnLoadRootCert(void)
933{
934    if (g_rootCertLoaded) {
935        mbedtls_x509_crt_free(&g_rootCaG2Cert);
936        g_rootCertLoaded = false;
937    }
938}
939
940static 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}
953static int32_t UnLoadDebugModeRootCert(void)
954{
955    mbedtls_x509_crt_free(&g_debugModeRootCert);
956    return PKCS7_SUCC;
957}
958
959static 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
972static void UnLoadSelfSignedCert(void)
973{
974    mbedtls_x509_crt_free(&g_ohosRootCert);
975}
976static 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
984static 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
1003static 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
1021static 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
1039int32_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
1088int32_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
1102int32_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
1116static 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
1126static 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
1150static 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
1160void 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
1172SignersResovedInfo *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;
1210OUT:
1211    PKCS7_FreeAllSignersResolvedInfo(sri);
1212    return NULL;
1213}
1214
1215int32_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
1264int32_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
1275int32_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
1294int32_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
1308static 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
1329int32_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;
1382EXIT:
1383    return rc;
1384}
1385
1386void 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