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