• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <openssl/x509.h>
17 #include <openssl/pem.h>
18 #include <openssl/err.h>
19 #include <openssl/sha.h>
20 #include <openssl/evp.h>
21 
22 #include "cf_log.h"
23 #include "cf_memory.h"
24 #include "attestation_common.h"
25 #include "attestation_cert_ext.h"
26 #include "attestation_cert_verify.h"
27 #include "attestation_cert_ext_legacy.h"
28 
29 static const char *ROOT_CA = "-----BEGIN CERTIFICATE-----\n"
30 "MIIFZDCCA0ygAwIBAgIIYsLLTehAXpYwDQYJKoZIhvcNAQELBQAwUDELMAkGA1UE\n"
31 "BhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEbMBkG\n"
32 "A1UEAwwSSHVhd2VpIENCRyBSb290IENBMB4XDTE3MDgyMTEwNTYyN1oXDTQyMDgx\n"
33 "NTEwNTYyN1owUDELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE\n"
34 "CwwKSHVhd2VpIENCRzEbMBkGA1UEAwwSSHVhd2VpIENCRyBSb290IENBMIICIjAN\n"
35 "BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1OyKm3Ig/6eibB7Uz2o93UqGk2M7\n"
36 "84WdfF8mvffvu218d61G5M3Px54E3kefUTk5Ky1ywHvw7Rp9KDuYv7ktaHkk+yr5\n"
37 "9Ihseu3a7iM/C6SnMSGt+LfB/Bcob9Abw95EigXQ4yQddX9hbNrin3AwZw8wMjEI\n"
38 "SYYDo5GuYDL0NbAiYg2Y5GpfYIqRzoi6GqDz+evLrsl20kJeCEPgJZN4Jg00Iq9k\n"
39 "++EKOZ5Jc/Zx22ZUgKpdwKABkvzshEgG6WWUPB+gosOiLv++inu/9blDpEzQZhjZ\n"
40 "9WVHpURHDK1YlCvubVAMhDpnbqNHZ0AxlPletdoyugrH/OLKl5inhMXNj3Re7Hl8\n"
41 "WsBWLUKp6sXFf0dvSFzqnr2jkhicS+K2IYZnjghC9cOBRO8fnkonh0EBt0evjUIK\n"
42 "r5ClbCKioBX8JU+d4ldtWOpp2FlxeFTLreDJ5ZBU4//bQpTwYMt7gwMK+MO5Wtok\n"
43 "Ux3UF98Z6GdUgbl6nBjBe82c7oIQXhHGHPnURQO7DDPgyVnNOnTPIkmiHJh/e3vk\n"
44 "VhiZNHFCCLTip6GoJVrLxwb9i4q+d0thw4doxVJ5NB9OfDMV64/ybJgpf7m3Ld2y\n"
45 "E0gsf1prrRlDFDXjlYyqqpf1l9Y0u3ctXo7UpXMgbyDEpUQhq3a7txZQO/17luTD\n"
46 "oA6Tz1ADavvBwHkCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\n"
47 "MAMBAf8wHQYDVR0OBBYEFKrE03lH6G4ja+/wqWwicz16GWmhMA0GCSqGSIb3DQEB\n"
48 "CwUAA4ICAQC1d3TMB+VHZdGrWJbfaBShFNiCTN/MceSHOpzBn6JumQP4N7mxCOwd\n"
49 "RSsGKQxV2NPH7LTXWNhUvUw5Sek96FWx/+Oa7jsj3WNAVtmS3zKpCQ5iGb08WIRO\n"
50 "cFnx3oUQ5rcO8r/lUk7Q2cN0E+rF4xsdQrH9k2cd3kAXZXBjfxfKPJTdPy1XnZR/\n"
51 "h8H5EwEK5DWjSzK1wKd3G/Fxdm3E23pcr4FZgdYdOlFSiqW2TJ3Qe6lF4GOKOOyd\n"
52 "WHkpu54ieTsqoYcuMKnKMjT2SLNNgv9Gu5ipaG8Olz6g9C7Htp943lmK/1Vtnhgg\n"
53 "pL3rDTsFX/+ehk7OtxuNzRMD9lXUtEfok7f8XB0dcL4ZjnEhDmp5QZqC1kMubHQt\n"
54 "QnTauEiv0YkSGOwJAUZpK1PIff5GgxXYfaHfBC6Op4q02ppl5Q3URl7XIjYLjvs9\n"
55 "t4S9xPe8tb6416V2fe1dZ62vOXMMKHkZjVihh+IceYpJYHuyfKoYJyahLOQXZykG\n"
56 "K5iPAEEtq3HPfMVF43RKHOwfhrAH5KwelUA/0EkcR4Gzth1MKEqojdnYNemkkSy7\n"
57 "aNPPT4LEm5R7sV6vG1CjwbgvQrWCgc4nMb8ngdfnVF7Ydqjqi9SAqUzIk4+Uf0ZY\n"
58 "+6RY5IcHdCaiPaWIE1xURQ8B0DRUURsQwXdjZhgLN/DKJpCl5aCCxg==\n"
59 "-----END CERTIFICATE-----";
60 
61 static const char *ROOT_G2_CA = "-----BEGIN CERTIFICATE-----\n"
62 "MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC\n"
63 "Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE\n"
64 "AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx\n"
65 "NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE\n"
66 "CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw\n"
67 "EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs\n"
68 "GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB\n"
69 "wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T\n"
70 "AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI\n"
71 "zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn\n"
72 "BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h\n"
73 "FTjgDHctXJlC5L7+ZDY=\n"
74 "-----END CERTIFICATE-----";
75 
76 static const char *EQUIPMENT_ROOT_CA = "-----BEGIN CERTIFICATE-----\n"
77 "MIICEDCCAZagAwIBAgIDM4vWMAoGCCqGSM49BAMDME8xCzAJBgNVBAYTAkNOMRMw\n"
78 "EQYDVQQKEwpIdWF3ZWkgQ0JHMSswKQYDVQQDEyJIdWF3ZWkgQ0JHIEVDQyBFcXVp\n"
79 "cG1lbnQgUm9vdCBDQSAzMCAXDTI0MDQxMzA0MjAwN1oYDzIwNzQwNDEzMDQyMDA3\n"
80 "WjBPMQswCQYDVQQGEwJDTjETMBEGA1UEChMKSHVhd2VpIENCRzErMCkGA1UEAxMi\n"
81 "SHVhd2VpIENCRyBFQ0MgRXF1aXBtZW50IFJvb3QgQ0EgMzB2MBAGByqGSM49AgEG\n"
82 "BSuBBAAiA2IABIqIk8IWZQaD80A5w8IxUN5HYs6coMCoA2uMffx8PQhoRE+OqsFM\n"
83 "g4AkdZmIqSjD0UMVNgN90gwTWYsjFRtztang3bujaQfABwb2PoLwd8bvdZaD8eq6\n"
84 "uYMBqgbEEeb23aNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w\n"
85 "HQYDVR0OBBYEFCnkWR/rJwU1EGXzxZPD1X2pTWhFMAoGCCqGSM49BAMDA2gAMGUC\n"
86 "MH+QnarOVBE2RtbqVMMTKBlKMc/sas/CZuawZazpdEhNKZIfe/9cODWMpV0/NpKJ\n"
87 "/QIxAKNJ6Wb0ir3VGYpCfXLAGgCcJU5G/DHorT+7eF6T8Bg4t2Di1XGT9HIaZ2W+\n"
88 "OSPInA==\n"
89 "-----END CERTIFICATE-----";
90 
91 struct HcfAttestCertVerifyParam {
92     bool checkTime;
93     STACK_OF(X509) *trustedCerts;
94     const HmAttestationSnInfo *snInfos;
95 };
96 #define SUB_CA_SUBJECT_INFO_LEN 3
97 
98 #define DEVICE_SECURITY_LEVEL_MIN 0
99 #define DEVICE_SECURITY_LEVEL_MAX 5
100 
101 #define MAX_CERT_NUM 20
102 
103 #define MAX_CERT_CHAIN_NUM 5
104 #define MIN_CERT_CHAIN_NUM 2
105 
106 #define MAX_CERT_DATA_NUM (10 * 1024 * 1024)
107 
108 typedef enum {
109     HM_ATTEST_TYPE_LEGACY = 0, // RSA cert
110     HM_ATTEST_TYPE_STANDARD = 1, // EC cert
111     HM_ATTEST_TYPE_UNKNOWN = 0xFF,
112 } HmAttestType;
113 
114 struct HmAttestationInfo {
115     HmAttestType type;
116     union {
117         void *data;
118         AttestationRecord *attestationRecord;
119         LegacyKeyDescription *legacyKeyDescription;
120     };
121     DeviceCertSecureLevel *attestationDevSecLevel;
122     DeviceActivationCertExt *deviveActiveCertExt;
123     STACK_OF(X509) *trustedChain;
124     bool hasParseExtension;
125 };
126 
AddtrustedCertsToStore(STACK_OF (X509)* trustedCerts,X509_STORE * store)127 static CfResult AddtrustedCertsToStore(STACK_OF(X509) *trustedCerts, X509_STORE *store)
128 {
129     int i;
130     for (i = 0; i < sk_X509_num(trustedCerts); i++) {
131         X509 *ca = sk_X509_value(trustedCerts, i);
132         if (ca == NULL) {
133             LOGE("cert is NULL\n");
134             return CF_ERR_CRYPTO_OPERATION;
135         }
136 
137         if (X509_STORE_add_cert(store, ca) != 1) {
138             LOGE("X509_STORE_add_cert failed\n");
139             return CF_ERR_CRYPTO_OPERATION;
140         }
141     }
142     return CF_SUCCESS;
143 }
144 
145 typedef struct {
146     int32_t errCode;
147     CfResult ret;
148 } X509VerifyErrCodeMap;
149 
150 static const X509VerifyErrCodeMap X509_VERIFY_ERR_MAP[] = {
151     {X509_V_ERR_CERT_SIGNATURE_FAILURE, CF_ERR_CERT_SIGNATURE_FAILURE},
152     {X509_V_ERR_CERT_NOT_YET_VALID, CF_ERR_CERT_NOT_YET_VALID},
153     {X509_V_ERR_CERT_HAS_EXPIRED, CF_ERR_CERT_HAS_EXPIRED},
154     {X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, CF_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY},
155     {X509_V_ERR_KEYUSAGE_NO_CERTSIGN, CF_ERR_KEYUSAGE_NO_CERTSIGN},
156     {X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, CF_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE},
157 };
158 
ParseX509VerifyErrCode(X509_STORE_CTX * ctx)159 static CfResult ParseX509VerifyErrCode(X509_STORE_CTX *ctx)
160 {
161     int32_t errCode = X509_STORE_CTX_get_error(ctx);
162     LOGE("X509_verify_cert failed: %{public}s\n", X509_verify_cert_error_string(errCode));
163     size_t i;
164     for (i = 0; i < sizeof(X509_VERIFY_ERR_MAP) / sizeof(X509_VERIFY_ERR_MAP[0]); i++) {
165         if (X509_VERIFY_ERR_MAP[i].errCode == errCode) {
166             return X509_VERIFY_ERR_MAP[i].ret;
167         }
168     }
169     return CF_ERR_CRYPTO_OPERATION;
170 }
171 
VerifyCerts(STACK_OF (X509)* certs,STACK_OF (X509)* trustedCerts,const HcfAttestCertVerifyParam * param,STACK_OF (X509)** chain)172 static CfResult VerifyCerts(STACK_OF(X509) *certs, STACK_OF(X509) *trustedCerts, const HcfAttestCertVerifyParam *param,
173     STACK_OF(X509) **chain)
174 {
175     X509_STORE *store = NULL;
176     X509_STORE_CTX *ctx = NULL;
177     X509 *cert = NULL;
178     CfResult ret = CF_ERR_CRYPTO_OPERATION;
179 
180     store = X509_STORE_new();
181     if (store == NULL) {
182         LOGE("X509_STORE_new failed\n");
183         return CF_ERR_CRYPTO_OPERATION;
184     }
185 
186     ret = AddtrustedCertsToStore(trustedCerts, store);
187     if (ret != CF_SUCCESS) {
188         LOGE("AddtrustedCertsToStore failed\n");
189         goto exit;
190     }
191 
192     ctx = X509_STORE_CTX_new();
193     if (ctx == NULL) {
194         LOGE("X509_STORE_CTX_new failed\n");
195         goto exit;
196     }
197 
198     cert = sk_X509_value(certs, 0);
199     if (cert == NULL) {
200         LOGE("cert is NULL\n");
201         goto exit;
202     }
203 
204     if (X509_STORE_CTX_init(ctx, store, cert, certs) != 1) {
205         LOGE("X509_STORE_CTX_init failed\n");
206         goto exit;
207     }
208 
209     if (param != NULL && param->checkTime == false) {
210         (void)X509_STORE_set_flags(store, X509_V_FLAG_NO_CHECK_TIME);
211     }
212 
213     if (X509_verify_cert(ctx) != 1) {
214         ret = ParseX509VerifyErrCode(ctx);
215         goto exit;
216     }
217 
218     *chain = X509_STORE_CTX_get1_chain(ctx);
219     ret = CF_SUCCESS;
220 exit:
221     X509_STORE_free(store);
222     X509_STORE_CTX_free(ctx);
223     return ret;
224 }
225 
GetX509NameByNid(X509_NAME * name,int nid,char ** buf)226 static CfResult GetX509NameByNid(X509_NAME *name, int nid, char **buf)
227 {
228     CfResult ret = X509_NAME_get_text_by_NID(name, nid, NULL, 0);
229     if (ret <= 0) {
230         LOGE("X509 name not exist %{public}s\n", OBJ_nid2sn(nid));
231         return CF_ERR_EXTENSION_NOT_EXIST;
232     }
233 
234     int len = ret + 1;
235     char *out = (char *)CfMalloc(len, 0);
236     if (out == NULL) {
237         LOGE("Malloc failed\n");
238         return CF_ERR_MALLOC;
239     }
240     ret = X509_NAME_get_text_by_NID(name, nid, out, len);
241     if (ret <= 0) {
242         LOGE("X509_NAME_get_text_by_NID failed\n");
243         CfFree(out);
244         out = NULL;
245         return CF_ERR_CRYPTO_OPERATION;
246     }
247     *buf = out;
248     return CF_SUCCESS;
249 }
250 
CheckSnItem(char * snPatternItem,char * item)251 static CfResult CheckSnItem(char *snPatternItem, char *item)
252 {
253     if (snPatternItem == NULL) {
254         return CF_SUCCESS;
255     }
256 
257     if (item == NULL) {
258         return CF_ERR_PARAMETER_CHECK;
259     }
260 
261     if (strcmp(snPatternItem, item) != 0) {
262         return CF_ERR_PARAMETER_CHECK;
263     }
264     return CF_SUCCESS;
265 }
266 
CheckSn(const CertSnInfo * snPattern,const CertSnInfo * sn)267 static CfResult CheckSn(const CertSnInfo *snPattern, const CertSnInfo *sn)
268 {
269     if (snPattern->cn == NULL || sn->cn == NULL) {
270         LOGE("snPattern->cn or sn->cn is NULL\n");
271         return CF_ERR_PARAMETER_CHECK;
272     }
273 
274     if (strncmp(snPattern->cn, sn->cn, strlen(snPattern->cn)) != 0) {
275         LOGI("cn is not equal\n");
276         return CF_ERR_PARAMETER_CHECK;
277     }
278 
279     if (CheckSnItem(snPattern->o, sn->o) != CF_SUCCESS) {
280         LOGI("o is not equal\n");
281         return CF_ERR_PARAMETER_CHECK;
282     }
283 
284     if (CheckSnItem(snPattern->c, sn->c) != CF_SUCCESS) {
285         LOGI("c is not equal\n");
286         return CF_ERR_PARAMETER_CHECK;
287     }
288 
289     if (CheckSnItem(snPattern->ou, sn->ou) != CF_SUCCESS) {
290         LOGI("ou is not equal\n");
291         return CF_ERR_PARAMETER_CHECK;
292     }
293 
294     return CF_SUCCESS;
295 }
296 
FreeSnInfo(CertSnInfo * sn)297 static void FreeSnInfo(CertSnInfo *sn)
298 {
299     CfFree(sn->cn);
300     sn->cn = NULL;
301     CfFree(sn->c);
302     sn->c = NULL;
303     CfFree(sn->ou);
304     sn->ou = NULL;
305     CfFree(sn->o);
306     sn->o = NULL;
307 }
308 
GetCertSn(X509 * cert,CertSnInfo * sn)309 static CfResult GetCertSn(X509 *cert, CertSnInfo *sn)
310 {
311     X509_NAME *name = X509_get_subject_name(cert);
312     if (name == NULL) {
313         LOGE("subject name is NULL\n");
314         return CF_ERR_CRYPTO_OPERATION;
315     }
316     CfResult ret = GetX509NameByNid(name, NID_commonName, &sn->cn);
317     if (ret != CF_SUCCESS) { // CN must exist
318         LOGE("Get X509 name cn failed, ret = %{public}d\n", ret);
319         goto exit;
320     }
321 
322     ret = GetX509NameByNid(name, NID_countryName, &sn->c);
323     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
324         LOGE("Get X509 name c failed, ret = %{public}d\n", ret);
325         goto exit;
326     }
327 
328     ret = GetX509NameByNid(name, NID_organizationalUnitName, &sn->ou);
329     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
330         LOGE("Get X509 name ou failed, ret = %{public}d\n", ret);
331         goto exit;
332     }
333 
334     ret = GetX509NameByNid(name, NID_organizationName, &sn->o);
335     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
336         LOGE("Get X509 name o failed, ret = %{public}d\n", ret);
337         goto exit;
338     }
339     return CF_SUCCESS;
340 exit:
341     FreeSnInfo(sn);
342     return ret;
343 }
344 
VerifySubCa(X509 * subCa,const HcfAttestCertVerifyParam * param)345 static CfResult VerifySubCa(X509 *subCa, const HcfAttestCertVerifyParam *param)
346 {
347     if (param == NULL || param->snInfos == NULL || param->snInfos->num == 0) {
348         LOGE("snInfos is NULL\n");
349         return CF_SUCCESS;
350     }
351 
352     CertSnInfo snInfo = {0};
353     CfResult ret = GetCertSn(subCa, &snInfo);
354     if (ret != CF_SUCCESS) {
355         LOGE("GetCertSn failed, ret = %{public}d\n", ret);
356         return ret;
357     }
358 
359     uint32_t i;
360     for (i = 0; i < param->snInfos->num; i++) {
361         CertSnInfo *snPattern = &param->snInfos->certSnInfos[i];
362         if (CheckSn(snPattern, &snInfo) == CF_SUCCESS) {
363             FreeSnInfo(&snInfo);
364             return CF_SUCCESS;
365         }
366     }
367     FreeSnInfo(&snInfo);
368     return CF_ERR_PARAMETER_CHECK;
369 }
370 
CreateTrustedCerts(const HcfAttestCertVerifyParam * param,STACK_OF (X509)** trustedCerts)371 static CfResult CreateTrustedCerts(const HcfAttestCertVerifyParam *param, STACK_OF(X509) **trustedCerts)
372 {
373     if (param != NULL && param->trustedCerts != NULL) {
374         *trustedCerts = X509_chain_up_ref(param->trustedCerts);
375         if (*trustedCerts == NULL) {
376             return CF_ERR_CRYPTO_OPERATION;
377         }
378         return CF_SUCCESS;
379     }
380 
381     STACK_OF(X509) *certs = sk_X509_new_null();
382     if (certs == NULL) {
383         return CF_ERR_CRYPTO_OPERATION;
384     }
385 
386     const char *rootCa[] = {ROOT_CA, ROOT_G2_CA, EQUIPMENT_ROOT_CA};
387     uint32_t rootCaNum = sizeof(rootCa) / sizeof(rootCa[0]);
388     uint32_t i;
389     ERR_clear_error();
390     for (i = 0; i < rootCaNum; i++) {
391         BIO *bio = BIO_new_mem_buf(rootCa[i], -1);
392         if (bio == NULL) {
393             break;
394         }
395         X509 *cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
396         if (cert == NULL) {
397             BIO_free(bio);
398             break;
399         }
400         if (sk_X509_push(certs, cert) <= 0) {
401             BIO_free(bio);
402             X509_free(cert);
403             break;
404         }
405         BIO_free(bio);
406     }
407     // Record the error
408     ProcessOpensslError(CF_ERR_CRYPTO_OPERATION);
409     if ((uint32_t)sk_X509_num(certs) != rootCaNum) {
410         sk_X509_pop_free(certs, X509_free);
411         return CF_ERR_PARAMETER_CHECK;
412     }
413 
414     *trustedCerts = certs;
415     return CF_SUCCESS;
416 }
417 
ReadX509FromData(const CfEncodingBlob * encodingBlob,STACK_OF (X509)** certs)418 static CfResult ReadX509FromData(const CfEncodingBlob *encodingBlob, STACK_OF(X509) **certs)
419 {
420     BIO *bio = BIO_new_mem_buf(encodingBlob->data, encodingBlob->len);
421     if (bio == NULL) {
422         return CF_ERR_CRYPTO_OPERATION;
423     }
424     STACK_OF(X509) *tmp = sk_X509_new_null();
425     if (tmp == NULL) {
426         BIO_free(bio);
427         return CF_ERR_CRYPTO_OPERATION;
428     }
429 
430     CfResult ret = CF_SUCCESS;
431     uint32_t certNum = 0;
432 
433     ERR_clear_error();
434     X509 *cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
435     while (cert != NULL) {
436         if (sk_X509_push(tmp, cert) <= 0) {
437             X509_free(cert);
438             ret = CF_ERR_CRYPTO_OPERATION;
439             break;
440         }
441         certNum++;
442         if (certNum > MAX_CERT_NUM) {
443             ret = CF_ERR_PARAMETER_CHECK;
444             break;
445         }
446         cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
447     }
448     // Record the error
449     ProcessOpensslError(CF_ERR_CRYPTO_OPERATION);
450     BIO_free(bio);
451     if (ret != CF_SUCCESS) {
452         sk_X509_pop_free(tmp, X509_free);
453         return ret;
454     }
455     if (sk_X509_num(tmp) == 0) {
456         sk_X509_pop_free(tmp, X509_free);
457         return CF_ERR_PARAMETER_CHECK;
458     }
459     *certs = tmp;
460     return ret;
461 }
462 
CreateCerts(const CfEncodingBlob * encodingBlob,STACK_OF (X509)** certs)463 static CfResult CreateCerts(const CfEncodingBlob *encodingBlob, STACK_OF(X509) **certs)
464 {
465     STACK_OF(X509) *tmp = NULL;
466     if (encodingBlob->len > MAX_CERT_DATA_NUM) {
467         LOGE("cert data is too large, len = %{public}zu\n", encodingBlob->len);
468         return CF_ERR_PARAMETER_CHECK;
469     }
470     CfResult ret = ReadX509FromData(encodingBlob, &tmp);
471     if (ret != CF_SUCCESS) {
472         LOGE("ReadX509FromData failed, ret = %{public}d\n", ret);
473         return ret;
474     }
475 
476     if (sk_X509_num(tmp) < MIN_CERT_CHAIN_NUM || sk_X509_num(tmp) > MAX_CERT_CHAIN_NUM) {
477         sk_X509_pop_free(tmp, X509_free);
478         return CF_ERR_PARAMETER_CHECK;
479     }
480 
481     *certs = tmp;
482     return CF_SUCCESS;
483 }
484 
CalculateSha256(CfBlob * data1,CfBlob * data2,uint8_t * buf,uint32_t len)485 static CfResult CalculateSha256(CfBlob *data1, CfBlob *data2, uint8_t *buf, uint32_t len)
486 {
487     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
488     if (ctx == NULL) {
489         return CF_ERR_CRYPTO_OPERATION;
490     }
491 
492     if (EVP_DigestInit(ctx, EVP_sha256()) != 1 ||
493         EVP_DigestUpdate(ctx, data1->data, data1->size) != 1 ||
494         EVP_DigestUpdate(ctx, data2->data, data2->size) != 1 ||
495         EVP_DigestFinal(ctx, buf, &len)!= 1) {
496         EVP_MD_CTX_free(ctx);
497         return CF_ERR_CRYPTO_OPERATION;
498     }
499 
500     EVP_MD_CTX_free(ctx);
501     return CF_SUCCESS;
502 }
503 
Uint8ArrayCmp(uint8_t * data1,uint32_t len1,uint8_t * data2,uint32_t len2)504 static bool Uint8ArrayCmp(uint8_t *data1, uint32_t len1, uint8_t *data2, uint32_t len2)
505 {
506     if (len1 != len2) {
507         return false;
508     }
509 
510     if (memcmp(data1, data2, len1) != 0) {
511         return false;
512     }
513     return true;
514 }
515 
AttestInfoFree(HmAttestationInfo * info)516 void AttestInfoFree(HmAttestationInfo *info)
517 {
518     if (info == NULL) {
519         return;
520     }
521 
522     if (info->type == HM_ATTEST_TYPE_STANDARD) {
523         FreeHmAttestationRecord(info->attestationRecord);
524         info->attestationRecord = NULL;
525     }
526     if (info->type == HM_ATTEST_TYPE_LEGACY) {
527         FreeHmKeyDescription(info->legacyKeyDescription);
528         info->legacyKeyDescription = NULL;
529     }
530 
531     if (info->trustedChain != NULL) {
532         sk_X509_pop_free(info->trustedChain, X509_free);
533     }
534 
535     FreeAttestationDevSecLevel(info->attestationDevSecLevel);
536     info->attestationDevSecLevel = NULL;
537     FreeDeviveActiveCertExt(info->deviveActiveCertExt);
538     info->deviveActiveCertExt = NULL;
539     CfFree(info);
540 }
541 
ParseAttestationCert(X509 * cert,HmAttestationInfo * info)542 static CfResult ParseAttestationCert(X509 *cert, HmAttestationInfo *info)
543 {
544     AttestationRecord *attestationRecord = NULL;
545     CfResult ret = GetHmAttestationRecord(cert, &attestationRecord);
546     if (ret == CF_SUCCESS) {
547         info->type = HM_ATTEST_TYPE_STANDARD;
548         info->attestationRecord = attestationRecord;
549         return CF_SUCCESS;
550     }
551 
552     if (ret != CF_ERR_EXTENSION_NOT_EXIST) {
553         LOGE("GetHmAttestationRecord failed, ret = %{public}d\n", ret);
554         return ret;
555     }
556 
557     LegacyKeyDescription *desc = NULL;
558     ret = GetHmKeyDescription(cert, &desc);
559     if (ret == CF_SUCCESS) {
560         info->type = HM_ATTEST_TYPE_LEGACY;
561         info->legacyKeyDescription = desc;
562         return CF_SUCCESS;
563     }
564 
565     if (ret != CF_ERR_EXTENSION_NOT_EXIST) {
566         LOGE("GetHmKeyDescription failed, ret = %{public}d\n", ret);
567         return ret;
568     }
569 
570     return ret;
571 }
572 
ParseDeviceCert(X509 * deviceCert,HmAttestationInfo * info)573 static CfResult ParseDeviceCert(X509 *deviceCert, HmAttestationInfo *info)
574 {
575     DeviceCertSecureLevel *level = NULL;
576     AttestationRecord *devActRecord = NULL;
577     CfResult ret = GetDeviceCertSecureLevel(deviceCert, &level);
578     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
579         LOGE("GetDeviceCertSecureLevel failed, ret = %{public}d\n", ret);
580         return ret;
581     }
582 
583     if (ret == CF_SUCCESS) {
584         int version = -1;
585         int secLevel = -1;
586         ret = GetDeviceSecureLevel(level, &version, &secLevel);
587         if (version != 0 && version != 1) {
588             LOGE("version is invalid, version = %{public}d\n", version);
589             ret = CF_ERR_INVALID_EXTENSION;
590             goto exit;
591         }
592 
593         if (secLevel < DEVICE_SECURITY_LEVEL_MIN || secLevel > DEVICE_SECURITY_LEVEL_MAX) {
594             LOGE("secLevel is invalid, secLevel = %{public}d\n", secLevel);
595             ret = CF_ERR_INVALID_EXTENSION;
596             goto exit;
597         }
598     }
599 
600     ret = GetDeviceActivationCertExt(deviceCert, &devActRecord);
601     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
602         LOGE("GetDeviceActivationCertExt failed, ret = %{public}d\n", ret);
603         goto exit;
604     }
605 
606     info->attestationDevSecLevel = level;
607     info->deviveActiveCertExt = devActRecord;
608     return CF_SUCCESS;
609 exit:
610     FreeAttestationDevSecLevel(level);
611     return ret;
612 }
613 
CheckCertsOrder(STACK_OF (X509)* certs,STACK_OF (X509)* chain)614 static CfResult CheckCertsOrder(STACK_OF(X509) *certs, STACK_OF(X509) *chain)
615 {
616     int num1 = sk_X509_num(certs);
617     int num2 = sk_X509_num(chain);
618     if (num2 < MIN_CERT_CHAIN_NUM) {
619         LOGE("Incorrect number of chain, num2 = %{public}d\n", num2);
620         return CF_ERR_PARAMETER_CHECK;
621     }
622 
623     if (num1 != num2 && (num1 + 1) != num2) {
624         LOGE("Incorrect number of chain, num1 = %{public}d, num2 = %{public}d\n", num1, num2);
625         return CF_ERR_PARAMETER_CHECK;
626     }
627 
628     int i;
629     for (i = 0; i < num1; i++) {
630         if (X509_cmp(sk_X509_value(certs, i), sk_X509_value(chain, i)) != 0) {
631             LOGE("Wrong certificate order\n");
632             return CF_ERR_PARAMETER_CHECK;
633         }
634     }
635     return CF_SUCCESS;
636 }
637 
VerifyAttestCerts(const CfEncodingBlob * encodingBlob,const HcfAttestCertVerifyParam * param,STACK_OF (X509)** out)638 static CfResult VerifyAttestCerts(const CfEncodingBlob *encodingBlob, const HcfAttestCertVerifyParam *param,
639     STACK_OF(X509) **out)
640 {
641     STACK_OF(X509) *certs = NULL;
642     STACK_OF(X509) *trustedCerts = NULL;
643     STACK_OF(X509) *chain = NULL;
644     CfResult ret = CreateCerts(encodingBlob, &certs);
645     if (ret != CF_SUCCESS) {
646         LOGE("CreateCerts failed, ret = %{public}d\n", ret);
647         goto exit;
648     }
649     ret = CreateTrustedCerts(param, &trustedCerts);
650     if (ret != CF_SUCCESS) {
651         LOGE("CreateTrustedCerts failed, ret = %{public}d\n", ret);
652         goto exit;
653     }
654     ret = VerifyCerts(certs, trustedCerts, param, &chain);
655     if (ret != CF_SUCCESS) {
656         LOGE("VerifyCerts failed, ret = %{public}d\n", ret);
657         goto exit;
658     }
659     ret = CheckCertsOrder(certs, chain);
660     if (ret != CF_SUCCESS) {
661         LOGE("VerifyCerts failed, ret = %{public}d\n", ret);
662         goto exit;
663     }
664     *out = chain;
665     chain = NULL;
666 exit:
667     sk_X509_pop_free(certs, X509_free);
668     sk_X509_pop_free(trustedCerts, X509_free);
669     if (chain != NULL) {
670         sk_X509_pop_free(chain, X509_free);
671     }
672     return ret;
673 }
674 
AttestCertVerify(const CfEncodingBlob * encodingBlob,const HcfAttestCertVerifyParam * param,HmAttestationInfo ** info)675 CfResult AttestCertVerify(const CfEncodingBlob *encodingBlob, const HcfAttestCertVerifyParam *param,
676     HmAttestationInfo **info)
677 {
678     if (encodingBlob == NULL || info == NULL) {
679         return CF_NULL_POINTER;
680     }
681 
682     STACK_OF(X509) *chain = NULL;
683     X509 *trustSubCa = NULL;
684     HmAttestationInfo *tmp = NULL;
685 
686     CfResult ret = VerifyAttestCerts(encodingBlob, param, &chain);
687     if (ret != CF_SUCCESS) {
688         LOGE("AttestCertVerify failed, ret = %{public}d\n", ret);
689         goto exit;
690     }
691 
692     trustSubCa = sk_X509_value(chain, sk_X509_num(chain) - MIN_CERT_CHAIN_NUM);
693     ret = VerifySubCa(trustSubCa, param);
694     if (ret != CF_SUCCESS) {
695         LOGE("VerifyCerts failed, ret = %{public}d\n", ret);
696         goto exit;
697     }
698 
699     tmp = (HmAttestationInfo *)CfMalloc(sizeof(HmAttestationInfo), 0);
700     if (tmp == NULL) {
701         LOGE("Malloc failed\n");
702         ret = CF_ERR_MALLOC;
703         goto exit;
704     }
705 
706     tmp->type = HM_ATTEST_TYPE_UNKNOWN;
707     tmp->hasParseExtension = false;
708     tmp->trustedChain = chain;
709     *info = tmp;
710     tmp = NULL;
711     chain = NULL;
712     ret = CF_SUCCESS;
713 exit:
714     ProcessOpensslError(ret);
715     AttestInfoFree(tmp);
716     tmp = NULL;
717     if (chain != NULL) {
718         sk_X509_pop_free(chain, X509_free);
719     }
720     return ret;
721 }
722 
AttestCertParseExtension(HmAttestationInfo * info)723 CfResult AttestCertParseExtension(HmAttestationInfo *info)
724 {
725     if (info == NULL) {
726         return CF_NULL_POINTER;
727     }
728     if (info->hasParseExtension == true) {
729         return CF_SUCCESS;
730     }
731 
732     if (info->trustedChain == NULL || sk_X509_num(info->trustedChain) < MIN_CERT_CHAIN_NUM) {
733         return CF_ERR_PARAMETER_CHECK;
734     }
735 
736     info->hasParseExtension = true;
737 
738     CfResult ret = ParseAttestationCert(sk_X509_value(info->trustedChain, 0), info);
739     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
740         LOGE("ParseAttestationCert failed, ret = %{public}d\n", ret);
741         ProcessOpensslError(ret);
742         return ret;
743     }
744 
745     ret = ParseDeviceCert(sk_X509_value(info->trustedChain, 1), info);
746     if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
747         LOGE("ParseDeviceCert failed, ret = %{public}d\n", ret);
748         ProcessOpensslError(ret);
749         return ret;
750     }
751     if (ret == CF_ERR_EXTENSION_NOT_EXIST) {
752         ret = CF_SUCCESS;
753     }
754     return CF_SUCCESS;
755 }
756 
AttestCheckBoundedWithUdId(HmAttestationInfo * info)757 CfResult AttestCheckBoundedWithUdId(HmAttestationInfo *info)
758 {
759     if (info == NULL) {
760         return CF_NULL_POINTER;
761     }
762 
763     if (info->type != HM_ATTEST_TYPE_STANDARD) {
764         return CF_ERR_EXTENSION_NOT_EXIST;
765     }
766 
767     if (info->deviveActiveCertExt == NULL || info->data == NULL) {
768         return CF_ERR_EXTENSION_NOT_EXIST;
769     }
770 
771     HmAttestationCertExt deviceId1 = {0};
772     HmAttestationCertExt nonce = {0};
773     HmAttestationCertExt udid = {0};
774 
775     CfResult ret = GetAttestCertExt(info->deviveActiveCertExt, DEVICE_ACTIVATION_DEVICE_ID1, &deviceId1);
776     if (ret != CF_SUCCESS) {
777         LOGE("Get deviceId1 failed, ret = %{public}d\n", ret);
778         return ret;
779     }
780 
781     ret = GetAttestCertExt(info->attestationRecord, ATTESTATION_NONCE, &nonce);
782     if (ret != CF_SUCCESS) {
783         LOGE("Get nonce failed when check deviceId1, ret = %{public}d\n", ret);
784         return ret;
785     }
786 
787     ret = GetAttestCertExt(info->attestationRecord, ATTESTATION_UDID, &udid);
788     if (ret != CF_SUCCESS) {
789         LOGE("Get udid failed, ret = %{public}d\n", ret);
790         return ret;
791     }
792 
793     uint8_t nonceUdidHash[SHA256_DIGEST_LENGTH] = {0};
794     ret = CalculateSha256(&udid.blob, &nonce.blob, nonceUdidHash, sizeof(nonceUdidHash));
795     if (ret != CF_SUCCESS) {
796         ProcessOpensslError(ret);
797         LOGE("CalculateSha256 udid failed, ret = %{public}d\n", ret);
798         return ret;
799     }
800 
801     if (Uint8ArrayCmp(deviceId1.blob.data, deviceId1.blob.size, nonceUdidHash, SHA256_DIGEST_LENGTH) == false) {
802         LOGE("deviceId1 is not equal to udid+nonce sha256\n");
803         return CF_ERR_INVALID_EXTENSION;
804     }
805 
806     return CF_SUCCESS;
807 }
808 
AttestCheckBoundedWithSocid(HmAttestationInfo * info)809 CfResult AttestCheckBoundedWithSocid(HmAttestationInfo *info)
810 {
811     if (info == NULL) {
812         return CF_NULL_POINTER;
813     }
814 
815     if (info->type != HM_ATTEST_TYPE_STANDARD) {
816         return CF_ERR_EXTENSION_NOT_EXIST;
817     }
818 
819     if (info->deviveActiveCertExt == NULL || info->data == NULL) {
820         return CF_ERR_EXTENSION_NOT_EXIST;
821     }
822 
823     HmAttestationCertExt deviceId2 = {0};
824     HmAttestationCertExt nonce = {0};
825     HmAttestationCertExt socId = {0};
826 
827     CfResult ret = GetAttestCertExt(info->deviveActiveCertExt, DEVICE_ACTIVATION_DEVICE_ID2, &deviceId2);
828     if (ret != CF_SUCCESS) {
829         LOGE("Get deviceId2 failed, ret = %{public}d\n", ret);
830         return ret;
831     }
832 
833     ret = GetAttestCertExt(info->attestationRecord, ATTESTATION_NONCE, &nonce);
834     if (ret != CF_SUCCESS) {
835         LOGE("Get nonce failed when check deviceId2, ret = %{public}d\n", ret);
836         return ret;
837     }
838 
839     ret = GetAttestCertExt(info->attestationRecord, ATTESTATION_SOCID, &socId);
840     if (ret != CF_SUCCESS) {
841         LOGE("Get socid failed, ret = %{public}d\n", ret);
842         return ret;
843     }
844 
845     uint8_t nonceSocidHash[SHA256_DIGEST_LENGTH] = {0};
846     ret = CalculateSha256(&socId.blob, &nonce.blob, nonceSocidHash, sizeof(nonceSocidHash));
847     if (ret != CF_SUCCESS) {
848         ProcessOpensslError(ret);
849         LOGE("CalculateSha256 socid failed, ret = %{public}d\n", ret);
850         return ret;
851     }
852 
853     if (Uint8ArrayCmp(deviceId2.blob.data, deviceId2.blob.size, nonceSocidHash, SHA256_DIGEST_LENGTH) == false) {
854         LOGE("deviceId2 is not equal to socId+nonce sha256\n");
855         return CF_ERR_INVALID_EXTENSION;
856     }
857 
858     return CF_SUCCESS;
859 }
860 
AttestGetCertExtension(HmAttestationInfo * info,HmAttestationCertExtType type,HmAttestationCertExt * ext)861 CfResult AttestGetCertExtension(HmAttestationInfo *info, HmAttestationCertExtType type, HmAttestationCertExt *ext)
862 {
863     if (info == NULL || ext == NULL) {
864         return CF_NULL_POINTER;
865     }
866     if (info->hasParseExtension == false) {
867         return CF_ERR_SHOULD_NOT_CALL;
868     }
869 
870     if (type == DEVICE_ACTIVATION_DEVICE_ID1 || type == DEVICE_ACTIVATION_DEVICE_ID2) {
871         return GetAttestCertExt(info->deviveActiveCertExt, type, ext);
872     }
873 
874     if (type >= ATTESTATION_KEY_PURPOSE && type < ATTESTATION_CERT_EXT_TYPE_MAX) {
875         if (info->type != HM_ATTEST_TYPE_STANDARD) {
876             return CF_ERR_EXTENSION_NOT_EXIST;
877         }
878         return GetAttestCertExt(info->attestationRecord, type, ext);
879     }
880 
881     if (type >= LEGACY_VERSION && type < KM_TAG_TYPE_MAX) {
882         if (info->type != HM_ATTEST_TYPE_LEGACY) {
883             return CF_ERR_EXTENSION_NOT_EXIST;
884         }
885         return GetKeyDescriptionExt(info->legacyKeyDescription, type, ext);
886     }
887     return CF_ERR_PARAMETER_CHECK;
888 }
889 
AttestCreateVerifyParam(HcfAttestCertVerifyParam ** param)890 CfResult AttestCreateVerifyParam(HcfAttestCertVerifyParam **param)
891 {
892     if (param == NULL) {
893         return CF_NULL_POINTER;
894     }
895     *param = (HcfAttestCertVerifyParam *)CfMalloc(sizeof(HcfAttestCertVerifyParam), 0);
896     if (*param == NULL) {
897         LOGE("Malloc failed\n");
898         return CF_ERR_MALLOC;
899     }
900     (*param)->checkTime = true;
901     return CF_SUCCESS;
902 }
903 
AttestSetVerifyParamCheckTime(HcfAttestCertVerifyParam * param,bool checkTime)904 CfResult AttestSetVerifyParamCheckTime(HcfAttestCertVerifyParam *param, bool checkTime)
905 {
906     if (param == NULL) {
907         return CF_NULL_POINTER;
908     }
909     param->checkTime = checkTime;
910     return CF_SUCCESS;
911 }
912 
AttestSetVerifyParamRootCa(HcfAttestCertVerifyParam * param,const CfEncodingBlob * rootCa)913 CfResult AttestSetVerifyParamRootCa(HcfAttestCertVerifyParam *param, const CfEncodingBlob *rootCa)
914 {
915     if (param == NULL || rootCa == NULL) {
916         return CF_NULL_POINTER;
917     }
918     if (param->trustedCerts != NULL) {
919         return CF_ERR_SHOULD_NOT_CALL;
920     }
921     if (rootCa->data == NULL || rootCa->len == 0) {
922         return CF_ERR_PARAMETER_CHECK;
923     }
924     STACK_OF(X509) *cas = NULL;
925     CfResult ret = ReadX509FromData(rootCa, &cas);
926     if (ret != CF_SUCCESS) {
927         LOGE("ReadX509FromData failed, ret = %{public}d\n", ret);
928         return ret;
929     }
930 
931     param->trustedCerts = cas;
932     return ret;
933 }
934 
AttestSetVerifyParamSnInfos(HcfAttestCertVerifyParam * param,const HmAttestationSnInfo * snInfos)935 CfResult AttestSetVerifyParamSnInfos(HcfAttestCertVerifyParam *param, const HmAttestationSnInfo *snInfos)
936 {
937     if (param == NULL || snInfos == NULL) {
938         return CF_NULL_POINTER;
939     }
940 
941     if (param->snInfos != NULL) {
942         return CF_ERR_SHOULD_NOT_CALL;
943     }
944 
945     param->snInfos = snInfos;
946     return CF_SUCCESS;
947 }
948 
AttestFreeVerifyParam(HcfAttestCertVerifyParam * param)949 void AttestFreeVerifyParam(HcfAttestCertVerifyParam *param)
950 {
951     if (param == NULL) {
952         return;
953     }
954     if (param->trustedCerts != NULL) {
955         sk_X509_pop_free(param->trustedCerts, X509_free);
956     }
957     CfFree(param);
958 }
959