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 = ¶m->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