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, ¶ms); 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, ¶ms); 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