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/asn1t.h"
18 #include "cf_log.h"
19 #include "cf_memory.h"
20 #include "cf_result.h"
21 #include "attestation_common.h"
22 #include "attestation_cert_ext.h"
23 #include "hm_attestation_cert_ext_type.h"
24
25 #define MAX_ATTESTATION_CLAIM_NUM 128
26
27 #define ID_HM_PKI 0x2B, 0x06, 0x01, 0x04, 0x1, 0x8F, 0x5B, 0x02, 0x82, 0x78
28
29 #define ID_HM_PKI_CERT_EXT ID_HM_PKI, 0x01
30 #define ID_HM_DEVICE_SECURITY_LEVEL_EXTENSION ID_HM_PKI_CERT_EXT, 0x01
31 #define ID_HM_ATTESTATION_EXTENSION ID_HM_PKI_CERT_EXT, 0x03
32 #define ID_HM_DEVICE_ACTIVATION_EXTENSION ID_HM_PKI_CERT_EXT, 0x05
33 #define ID_HM_DEVICE_ACTIVATION_DEVICE_ID1 ID_HM_DEVICE_ACTIVATION_EXTENSION, 0x01
34 #define ID_HM_DEVICE_ACTIVATION_DEVICE_ID2 ID_HM_DEVICE_ACTIVATION_EXTENSION, 0x02
35 #define ID_HM_ATTESTATION_BASE ID_HM_PKI, 0x02
36 #define ID_KEY_PROPERTIES ID_HM_ATTESTATION_BASE, 0x01
37 #define ID_SYSTEM_PROPERTIES ID_HM_ATTESTATION_BASE, 0x02
38
39 // ID_KEY_PROPERTIES
40 #define ID_KEY_PROPERTY_KEY_PURPOSE ID_KEY_PROPERTIES, 0x01
41 #define ID_KEY_PROPERTY_KEY_ID ID_KEY_PROPERTIES, 0x02
42 #define ID_KEY_PROPERTY_APP_ID ID_KEY_PROPERTIES, 0x03
43
44 #define ID_KEY_PROPERTY_APP_ID_HAP_ID ID_KEY_PROPERTY_APP_ID, 0x01
45 #define ID_KEY_PROPERTY_APP_ID_SA_ID ID_KEY_PROPERTY_APP_ID, 0x02
46
47 #define ID_KEY_PROPERTY_APP_ID_UNIFIED_ID ID_KEY_PROPERTY_APP_ID, 0x03
48
49 #define ID_KEY_PROPERTY_CHALLENGE ID_KEY_PROPERTIES, 0x04
50 #define ID_KEY_PROPERTY_KEY_FLAG ID_KEY_PROPERTIES, 0x05
51 #define ID_KEY_PROPERTY_DIGEST ID_KEY_PROPERTIES, 0x08
52 #define ID_KEY_PROPERTY_SIGN_PADDING ID_KEY_PROPERTIES, 0x09
53 #define ID_KEY_PROPERTY_ENC_PADDING ID_KEY_PROPERTIES, 0x0A
54 #define ID_KEY_PROPERTY_SIGN_TYPE ID_KEY_PROPERTIES, 0x0B
55
56 // ID_SYSTEM_PROPERTIES
57 #define ID_SYSTEM_PROPERTIES_OS ID_SYSTEM_PROPERTIES, 0x02
58 #define ID_SYSTEM_PROPERTIES_OS_VERSION_INFO ID_SYSTEM_PROPERTIES_OS, 0x04
59 #define ID_SYSTEM_PROPERTIES_OS_SEC_LEVEL_INFO ID_SYSTEM_PROPERTIES_OS, 0x05
60 #define ID_SYSTEM_PROPERTIES_OS_KEY_MANAGER_TA_ID ID_SYSTEM_PROPERTIES_OS, 0x06
61 #define ID_SYSTEM_PROPERTIES_OS_PURPOSE ID_SYSTEM_PROPERTIES_OS, 0x07
62 #define ID_SYSTEM_PROPERTIES_OS_ID_PADDING_FLAG ID_SYSTEM_PROPERTIES_OS, 0x08
63 #define ID_SYSTEM_PROPERTIES_OS_NONCE ID_SYSTEM_PROPERTIES_OS, 0x09
64
65 #define ID_PRIVACY_PROPERTIES ID_SYSTEM_PROPERTIES, 0x04
66 #define ID_PRIVACY_PROPERTIES_IMEI ID_PRIVACY_PROPERTIES, 0x01
67 #define ID_PRIVACY_PROPERTIES_MEID ID_PRIVACY_PROPERTIES, 0x02
68 #define ID_PRIVACY_PROPERTIES_SERIAL ID_PRIVACY_PROPERTIES, 0x03
69 #define ID_PRIVACY_PROPERTIES_BRAND ID_PRIVACY_PROPERTIES, 0x04
70 #define ID_PRIVACY_PROPERTIES_DEVICE ID_PRIVACY_PROPERTIES, 0x05
71 #define ID_PRIVACY_PROPERTIES_PRODUCT ID_PRIVACY_PROPERTIES, 0x06
72 #define ID_PRIVACY_PROPERTIES_MANUFACTURER ID_PRIVACY_PROPERTIES, 0x07
73 #define ID_PRIVACY_PROPERTIES_MODEL ID_PRIVACY_PROPERTIES, 0x08
74 #define ID_PRIVACY_PROPERTIES_SOCID ID_PRIVACY_PROPERTIES, 0x09
75 #define ID_PRIVACY_PROPERTIES_UDID ID_PRIVACY_PROPERTIES, 0x0A
76
77 #define DECLARE_OID(name, id) \
78 static const uint8_t name##_OID[] = {id}
79
80 DECLARE_OID(DEVICE_SECURITY_LEVEL, ID_HM_DEVICE_SECURITY_LEVEL_EXTENSION);
81 DECLARE_OID(DEVICE_ACTIVATION_EXT, ID_HM_DEVICE_ACTIVATION_EXTENSION);
82 DECLARE_OID(DEVICE_ACTIVATION_DEVICE_ID1, ID_HM_DEVICE_ACTIVATION_DEVICE_ID1);
83 DECLARE_OID(DEVICE_ACTIVATION_DEVICE_ID2, ID_HM_DEVICE_ACTIVATION_DEVICE_ID2);
84 DECLARE_OID(ATTESTATION_EXT, ID_HM_ATTESTATION_EXTENSION);
85 DECLARE_OID(ATTESTATION_NONCE, ID_SYSTEM_PROPERTIES_OS_NONCE);
86 DECLARE_OID(ATTESTATION_IMEI, ID_PRIVACY_PROPERTIES_IMEI);
87 DECLARE_OID(ATTESTATION_MEID, ID_PRIVACY_PROPERTIES_MEID);
88 DECLARE_OID(ATTESTATION_SERIAL, ID_PRIVACY_PROPERTIES_SERIAL);
89 DECLARE_OID(ATTESTATION_MODEL, ID_PRIVACY_PROPERTIES_MODEL);
90 DECLARE_OID(ATTESTATION_SOCID, ID_PRIVACY_PROPERTIES_SOCID);
91 DECLARE_OID(ATTESTATION_UDID, ID_PRIVACY_PROPERTIES_UDID);
92 DECLARE_OID(ATTESTATION_KEY_PURPOSE, ID_KEY_PROPERTY_KEY_PURPOSE);
93 DECLARE_OID(ATTESTATION_APP_ID, ID_KEY_PROPERTY_APP_ID);
94 DECLARE_OID(ATTESTATION_APP_ID_HAP_ID, ID_KEY_PROPERTY_APP_ID_HAP_ID);
95 DECLARE_OID(ATTESTATION_APP_ID_SA_ID, ID_KEY_PROPERTY_APP_ID_SA_ID);
96 DECLARE_OID(ATTESTATION_APP_ID_UNIFIED_ID, ID_KEY_PROPERTY_APP_ID_UNIFIED_ID);
97 DECLARE_OID(ATTESTATION_CHALLENGE, ID_KEY_PROPERTY_CHALLENGE);
98 DECLARE_OID(ATTESTATION_KEY_FLAG, ID_KEY_PROPERTY_KEY_FLAG);
99 DECLARE_OID(ATTESTATION_DIGEST, ID_KEY_PROPERTY_DIGEST);
100 DECLARE_OID(ATTESTATION_SIGN_PADDING, ID_KEY_PROPERTY_SIGN_PADDING);
101 DECLARE_OID(ATTESTATION_ENC_PADDING, ID_KEY_PROPERTY_ENC_PADDING);
102 DECLARE_OID(ATTESTATION_SIGN_TYPE, ID_KEY_PROPERTY_SIGN_TYPE);
103 DECLARE_OID(ATTESTATION_VERSION_INFO, ID_SYSTEM_PROPERTIES_OS_VERSION_INFO);
104 DECLARE_OID(ATTESTATION_KEY_MANAGER_TA_ID, ID_SYSTEM_PROPERTIES_OS_KEY_MANAGER_TA_ID);
105 DECLARE_OID(ATTESTATION_PURPOSE, ID_SYSTEM_PROPERTIES_OS_PURPOSE);
106 DECLARE_OID(ATTESTATION_ID_PADDING_FLAG, ID_SYSTEM_PROPERTIES_OS_ID_PADDING_FLAG);
107
108 typedef struct {
109 const uint8_t *oid;
110 uint32_t oidLen;
111 } AttestationExtOid;
112
113 static const AttestationExtOid ATTESTATION_EXT_OIDS[] = {
114 {DEVICE_ACTIVATION_DEVICE_ID1_OID, sizeof(DEVICE_ACTIVATION_DEVICE_ID1_OID)}, // DEVICE_ACTIVATION_DEVICE_ID1 0
115 {DEVICE_ACTIVATION_DEVICE_ID2_OID, sizeof(DEVICE_ACTIVATION_DEVICE_ID2_OID)}, // DEVICE_ACTIVATION_DEVICE_ID2 1
116 {ATTESTATION_KEY_PURPOSE_OID, sizeof(ATTESTATION_KEY_PURPOSE_OID)}, // ATTESTATION_KEY_PURPOSE 2
117 {ATTESTATION_APP_ID_HAP_ID_OID, sizeof(ATTESTATION_APP_ID_HAP_ID_OID)}, // ATTESTATION_APP_ID_HAP_ID 3
118 {ATTESTATION_APP_ID_SA_ID_OID, sizeof(ATTESTATION_APP_ID_SA_ID_OID)}, // ATTESTATION_APP_ID_SA_ID 4
119 {ATTESTATION_APP_ID_UNIFIED_ID_OID, sizeof(ATTESTATION_APP_ID_UNIFIED_ID_OID)}, // ATTESTATION_APP_ID_UNIFIED_ID 5
120 {ATTESTATION_CHALLENGE_OID, sizeof(ATTESTATION_CHALLENGE_OID)}, // ATTESTATION_CHALLENGE 6
121 {ATTESTATION_KEY_FLAG_OID, sizeof(ATTESTATION_KEY_FLAG_OID)}, // ATTESTATION_KEY_FLAG 7
122 {ATTESTATION_DIGEST_OID, sizeof(ATTESTATION_DIGEST_OID)}, // ATTESTATION_DIGEST 8
123 {ATTESTATION_SIGN_PADDING_OID, sizeof(ATTESTATION_SIGN_PADDING_OID)}, // ATTESTATION_SIGN_PADDING 9
124 {ATTESTATION_ENC_PADDING_OID, sizeof(ATTESTATION_ENC_PADDING_OID)}, // ATTESTATION_ENC_PADDING 10
125 {ATTESTATION_SIGN_TYPE_OID, sizeof(ATTESTATION_SIGN_TYPE_OID)}, // ATTESTATION_SIGN_TYPE 11
126 {ATTESTATION_VERSION_INFO_OID, sizeof(ATTESTATION_VERSION_INFO_OID)}, // ATTESTATION_VERSION_INFO 12
127 {ATTESTATION_KEY_MANAGER_TA_ID_OID, sizeof(ATTESTATION_KEY_MANAGER_TA_ID_OID)}, // ATTESTATION_KEY_MANAGER_TA_ID 13
128 {ATTESTATION_PURPOSE_OID, sizeof(ATTESTATION_PURPOSE_OID)}, // ATTESTATION_PURPOSE 14
129 {ATTESTATION_ID_PADDING_FLAG_OID, sizeof(ATTESTATION_ID_PADDING_FLAG_OID)}, // ATTESTATION_ID_PADDING_FLAG 15
130 {ATTESTATION_NONCE_OID, sizeof(ATTESTATION_NONCE_OID)}, // ATTESTATION_NONCE 16
131 {ATTESTATION_IMEI_OID, sizeof(ATTESTATION_IMEI_OID)}, // ATTESTATION_IMEI 17
132 {ATTESTATION_MEID_OID, sizeof(ATTESTATION_MEID_OID)}, // ATTESTATION_MEID 18
133 {ATTESTATION_SERIAL_OID, sizeof(ATTESTATION_SERIAL_OID)}, // ATTESTATION_SERIAL 19
134 {ATTESTATION_MODEL_OID, sizeof(ATTESTATION_MODEL_OID)}, // ATTESTATION_MODEL 20
135 {ATTESTATION_SOCID_OID, sizeof(ATTESTATION_SOCID_OID)}, // ATTESTATION_SOCID 21
136 {ATTESTATION_UDID_OID, sizeof(ATTESTATION_UDID_OID)}, // ATTESTATION_UDID 22
137 };
138
139 typedef struct {
140 ASN1_INTEGER *securityLevel;
141 ASN1_OBJECT *attestType;
142 ASN1_TYPE *value;
143 } HmAttestationClaim;
144
145 typedef struct {
146 ASN1_OBJECT *type;
147 ASN1_OCTET_STRING *value;
148 } HmApplicationIdType;
149
150 ASN1_SEQUENCE(HmApplicationIdType) = {
151 ASN1_SIMPLE(HmApplicationIdType, type, ASN1_OBJECT),
152 ASN1_SIMPLE(HmApplicationIdType, value, ASN1_OCTET_STRING),
153 } ASN1_SEQUENCE_END(HmApplicationIdType)
154 IMPLEMENT_ASN1_FUNCTIONS(HmApplicationIdType)
155
156 ASN1_SEQUENCE(HmAttestationClaim) = {
157 ASN1_SIMPLE(HmAttestationClaim, securityLevel, ASN1_INTEGER),
158 ASN1_SIMPLE(HmAttestationClaim, attestType, ASN1_OBJECT),
159 ASN1_SIMPLE(HmAttestationClaim, value, ASN1_ANY),
160 } ASN1_SEQUENCE_END(HmAttestationClaim)
161
162 IMPLEMENT_ASN1_FUNCTIONS(HmAttestationClaim)
163
164 struct AttestationRecord {
165 int64_t version;
166 uint32_t claimNum;
167 HmAttestationClaim **claims;
168 HmApplicationIdType *appId;
169 };
170
HmAttestationClaimfree(HmAttestationClaim ** claims,uint32_t count)171 static void HmAttestationClaimfree(HmAttestationClaim **claims, uint32_t count)
172 {
173 if (claims == NULL) {
174 return;
175 }
176
177 uint32_t i;
178 for (i = 0; i < count; i++) {
179 HmAttestationClaim *claim = claims[i];
180 if (claim != NULL) {
181 HmAttestationClaim_free(claim);
182 }
183 }
184 CfFree(claims);
185 }
186
FreeHmAttestationRecord(AttestationRecord * record)187 void FreeHmAttestationRecord(AttestationRecord *record)
188 {
189 if (record == NULL) {
190 return;
191 }
192
193 HmAttestationClaimfree(record->claims, record->claimNum);
194 record->claims = NULL;
195 HmApplicationIdType_free(record->appId);
196 CfFree(record);
197 }
198
Asn1typeGetInteger(ASN1_TYPE * asn1Type,int64_t * value)199 static CfResult Asn1typeGetInteger(ASN1_TYPE *asn1Type, int64_t *value)
200 {
201 if (asn1Type == NULL || asn1Type->type != V_ASN1_INTEGER || asn1Type->value.integer == NULL) {
202 return CF_ERR_INVALID_EXTENSION;
203 }
204
205 int64_t v = 0;
206 CfResult ret = ASN1_INTEGER_get_int64(&v, asn1Type->value.integer);
207 if (ret != 1) {
208 return CF_ERR_CRYPTO_OPERATION;
209 }
210
211 *value = v;
212 return CF_SUCCESS;
213 }
214
215 struct DeviceCertSecureLevel {
216 int64_t version;
217 int64_t secLevel;
218 };
219
220 typedef struct {
221 ASN1_INTEGER *version;
222 ASN1_ENUMERATED *level;
223 } HmDeviceSecurityLevel;
224
225 ASN1_SEQUENCE(HmDeviceSecurityLevel) = {
226 ASN1_SIMPLE(HmDeviceSecurityLevel, version, ASN1_INTEGER),
227 ASN1_SIMPLE(HmDeviceSecurityLevel, level, ASN1_ENUMERATED),
228 } ASN1_SEQUENCE_END(HmDeviceSecurityLevel)
229
230 IMPLEMENT_ASN1_FUNCTIONS(HmDeviceSecurityLevel)
231
232 CfResult GetDeviceCertSecureLevel(const X509 *cert, DeviceCertSecureLevel **devSecLevel)
233 {
234 if (cert == NULL || devSecLevel == NULL) {
235 return CF_NULL_POINTER;
236 }
237 X509_EXTENSION *extension = NULL;
238 CfResult ret = FindCertExt(cert, DEVICE_SECURITY_LEVEL_OID, sizeof(DEVICE_SECURITY_LEVEL_OID), &extension);
239 if (ret != CF_SUCCESS) {
240 LOGE("device security level extention is not exist, ret = %{public}d\n", ret);
241 return ret;
242 }
243
244 ASN1_OCTET_STRING *extValue = X509_EXTENSION_get_data(extension);
245 if (extValue == NULL) {
246 LOGE("X509_EXTENSION_get_data failed\n");
247 return CF_ERR_CRYPTO_OPERATION;
248 }
249
250 int dataLen = ASN1_STRING_length(extValue);
251 const unsigned char *data = ASN1_STRING_get0_data(extValue);
252 HmDeviceSecurityLevel *tmp = NULL;
253 tmp = d2i_HmDeviceSecurityLevel(NULL, &data, dataLen);
254 if (tmp == NULL) {
255 LOGE("d2i_HmDeviceSecurityLevel failed\n");
256 return CF_ERR_INVALID_EXTENSION;
257 }
258
259 int64_t v = 0;
260 int64_t s = 0;
261 if (ASN1_INTEGER_get_int64(&v, tmp->version) != 1) {
262 LOGE("ASN1_INTEGER_get_int64 version failed\n");
263 HmDeviceSecurityLevel_free(tmp);
264 return CF_ERR_CRYPTO_OPERATION;
265 }
266 if (ASN1_ENUMERATED_get_int64(&s, tmp->level) != 1) {
267 LOGE("ASN1_INTEGER_get_int64 level failed\n");
268 HmDeviceSecurityLevel_free(tmp);
269 return CF_ERR_CRYPTO_OPERATION;
270 }
271 HmDeviceSecurityLevel_free(tmp);
272 *devSecLevel = (DeviceCertSecureLevel *)CfMalloc(sizeof(DeviceCertSecureLevel), 0);
273 if (*devSecLevel == NULL) {
274 LOGE("malloc failed\n");
275 return CF_ERR_MALLOC;
276 }
277 (*devSecLevel)->version = v;
278 (*devSecLevel)->secLevel = s;
279 return CF_SUCCESS;
280 }
281
FindClaim(AttestationRecord * record,const uint8_t * oid,uint32_t oidLen,HmAttestationClaim ** claim)282 static CfResult FindClaim(AttestationRecord *record, const uint8_t *oid, uint32_t oidLen, HmAttestationClaim **claim)
283 {
284 if (record == NULL || record->claimNum == 0) {
285 return CF_ERR_EXTENSION_NOT_EXIST;
286 }
287 uint32_t i;
288 HmAttestationClaim *tmp = NULL;
289 for (i = 0; i < record->claimNum; i++) {
290 tmp = record->claims[i];
291 if (CmpObjOid(tmp->attestType, oid, oidLen) == true) {
292 *claim = tmp;
293 return CF_SUCCESS;
294 }
295 }
296 return CF_ERR_EXTENSION_NOT_EXIST;
297 }
298
GetOctetStringItem(AttestationRecord * record,const uint8_t * oid,uint32_t oidLen,CfBlob * out)299 static CfResult GetOctetStringItem(AttestationRecord *record, const uint8_t *oid, uint32_t oidLen, CfBlob *out)
300 {
301 HmAttestationClaim *claim = NULL;
302 CfResult ret = FindClaim(record, oid, oidLen, &claim);
303 if (ret != CF_SUCCESS) {
304 return ret;
305 }
306
307 if (ASN1_TYPE_get(claim->value) != V_ASN1_OCTET_STRING) {
308 return CF_ERR_INVALID_EXTENSION;
309 }
310
311 ASN1_OCTET_STRING *octetString = claim->value->value.octet_string;
312 if (octetString == NULL) {
313 return CF_ERR_INVALID_EXTENSION;
314 }
315
316 out->size = (uint32_t)ASN1_STRING_length(octetString);
317 out->data = (uint8_t *)ASN1_STRING_get0_data(octetString);
318 return CF_SUCCESS;
319 }
320
GetOctetOrUtf8Item(AttestationRecord * record,const uint8_t * oid,uint32_t oidLen,CfBlob * out)321 static CfResult GetOctetOrUtf8Item(AttestationRecord *record, const uint8_t *oid, uint32_t oidLen, CfBlob *out)
322 {
323 HmAttestationClaim *claim = NULL;
324 CfResult ret = FindClaim(record, oid, oidLen, &claim);
325 if (ret != CF_SUCCESS) {
326 return ret;
327 }
328
329 return GetOctectOrUtf8Data(claim->value, out);
330 }
331
GetInt64Item(AttestationRecord * record,const uint8_t * oid,uint32_t oidLen,int64_t * out)332 static CfResult GetInt64Item(AttestationRecord *record, const uint8_t *oid, uint32_t oidLen, int64_t *out)
333 {
334 HmAttestationClaim *claim = NULL;
335 CfResult ret = FindClaim(record, oid, oidLen, &claim);
336 if (ret != CF_SUCCESS) {
337 return ret;
338 }
339
340 if (ASN1_TYPE_get(claim->value) != V_ASN1_INTEGER) {
341 return CF_ERR_INVALID_EXTENSION;
342 }
343
344 ret = ASN1_INTEGER_get_int64(out, claim->value->value.integer);
345 if (ret != 1) {
346 return CF_ERR_INVALID_EXTENSION;
347 }
348 return CF_SUCCESS;
349 }
350
GetBooleanItem(AttestationRecord * record,const uint8_t * oid,uint32_t oidLen,bool * out)351 static CfResult GetBooleanItem(AttestationRecord *record, const uint8_t *oid, uint32_t oidLen, bool *out)
352 {
353 HmAttestationClaim *claim = NULL;
354 CfResult ret = FindClaim(record, oid, oidLen, &claim);
355 if (ret != CF_SUCCESS) {
356 return ret;
357 }
358
359 if (ASN1_TYPE_get(claim->value) != V_ASN1_BOOLEAN) {
360 return CF_ERR_INVALID_EXTENSION;
361 }
362
363 if (claim->value->value.boolean == 0) {
364 *out = false;
365 } else {
366 *out = true;
367 }
368 return CF_SUCCESS;
369 }
370
Asn1typeParseHmAttestationClaim(ASN1_TYPE * asn1Type,HmAttestationClaim ** claim)371 static CfResult Asn1typeParseHmAttestationClaim(ASN1_TYPE *asn1Type, HmAttestationClaim **claim)
372 {
373 if (asn1Type == NULL || asn1Type->type != V_ASN1_SEQUENCE || asn1Type->value.sequence == NULL) {
374 return CF_ERR_INVALID_EXTENSION;
375 }
376
377 const unsigned char *p = asn1Type->value.sequence->data;
378 long len = asn1Type->value.sequence->length;
379
380 *claim = d2i_HmAttestationClaim(NULL, &p, len);
381 if (*claim == NULL) {
382 LOGE("d2i_HmAttestationClaim failed\n");
383 return CF_ERR_INVALID_EXTENSION;
384 }
385
386 return CF_SUCCESS;
387 }
388
ParseAttestationClaim(STACK_OF (ASN1_TYPE)* exts,int extCount,AttestationRecord * record)389 static CfResult ParseAttestationClaim(STACK_OF(ASN1_TYPE) *exts, int extCount, AttestationRecord *record)
390 {
391 ASN1_TYPE *asn1Type = NULL;
392 uint32_t count = 0;
393 int i;
394 CfResult ret;
395 HmAttestationClaim **claims = NULL;
396
397 if (extCount <= 1) {
398 record->claimNum = 0;
399 record->claims = NULL;
400 return CF_SUCCESS;
401 }
402 if ((extCount - 1) > MAX_ATTESTATION_CLAIM_NUM) {
403 LOGE("extCount = %{public}d, exceed max claim num = %{public}d\n", extCount, MAX_ATTESTATION_CLAIM_NUM);
404 return CF_ERR_INVALID_EXTENSION;
405 }
406
407 claims = (HmAttestationClaim **)CfMalloc(sizeof(HmAttestationClaim *) * (extCount - 1), 0);
408 if (claims == NULL) {
409 LOGE("Malloc failed\n");
410 return CF_ERR_MALLOC;
411 }
412
413 for (i = 1; i < extCount; i++) {
414 asn1Type = sk_ASN1_TYPE_value(exts, i);
415 HmAttestationClaim *t = NULL;
416 ret = Asn1typeParseHmAttestationClaim(asn1Type, &t);
417 if (ret != CF_SUCCESS) {
418 LOGE("Asn1typeParseHmAttestationClaim failed, ret = %{public}d\n", ret);
419 HmAttestationClaimfree(claims, count);
420 return ret;
421 }
422 claims[i - 1] = t;
423 count++;
424 }
425
426 record->claimNum = count;
427 record->claims = claims;
428 return CF_SUCCESS;
429 }
430
ParseAttestationExt(X509_EXTENSION * extension,AttestationRecord * record)431 static CfResult ParseAttestationExt(X509_EXTENSION *extension, AttestationRecord *record)
432 {
433 ASN1_OCTET_STRING *extValue = X509_EXTENSION_get_data(extension);
434 if (extValue == NULL) {
435 LOGE("X509_EXTENSION_get_data failed\n");
436 return CF_ERR_CRYPTO_OPERATION;
437 }
438
439 int extValueLen = ASN1_STRING_length(extValue);
440 const unsigned char *data = ASN1_STRING_get0_data(extValue);
441 if (extValueLen == 0 || data == NULL) {
442 LOGE("extValueLen = %{public}d\n", extValueLen);
443 return CF_ERR_EXTENSION_NOT_EXIST;
444 }
445 STACK_OF(ASN1_TYPE) *exts = d2i_ASN1_SEQUENCE_ANY(NULL, &data, extValueLen);
446 if (exts == NULL) {
447 LOGE("d2i_ASN1_SEQUENCE_ANY failed\n");
448 return CF_ERR_INVALID_EXTENSION;
449 }
450
451 CfResult ret;
452 int extCount = sk_ASN1_TYPE_num(exts);
453 if (extCount <= 0) {
454 LOGE("exts has no element\n");
455 ret = CF_ERR_EXTENSION_NOT_EXIST;
456 goto exit;
457 }
458
459 ret = Asn1typeGetInteger(sk_ASN1_TYPE_value(exts, 0), &record->version);
460 if (ret != CF_SUCCESS) {
461 LOGE("Asn1typeGetInteger record version failed, ret = %{public}d\n", ret);
462 goto exit;
463 }
464
465 ret = ParseAttestationClaim(exts, extCount, record);
466 if (ret != CF_SUCCESS) {
467 LOGE("ParseAttestationClaim failed, ret = %{public}d\n", ret);
468 goto exit;
469 }
470
471 exit:
472 sk_ASN1_TYPE_pop_free(exts, ASN1_TYPE_free);
473 return ret;
474 }
475
ParseAppId(AttestationRecord * record)476 static CfResult ParseAppId(AttestationRecord *record)
477 {
478 CfBlob blob = {0};
479 CfResult ret = GetOctetStringItem(record, ATTESTATION_APP_ID_OID, sizeof(ATTESTATION_APP_ID_OID), &blob);
480 if (ret != CF_SUCCESS) {
481 return ret;
482 }
483
484 HmApplicationIdType *appId = NULL;
485 const unsigned char *p = blob.data;
486 appId = d2i_HmApplicationIdType(NULL, &p, blob.size);
487 if (appId == NULL) {
488 LOGE("d2i_HmApplicationIdType failed\n");
489 return CF_ERR_INVALID_EXTENSION;
490 }
491
492 record->appId = appId;
493 return CF_SUCCESS;
494 }
495
GetHmAttestationRecord(const X509 * cert,AttestationRecord ** record)496 CfResult GetHmAttestationRecord(const X509 *cert, AttestationRecord **record)
497 {
498 if (cert == NULL || record == NULL) {
499 return CF_NULL_POINTER;
500 }
501 X509_EXTENSION *extension = NULL;
502 CfResult ret = FindCertExt(cert, ATTESTATION_EXT_OID, sizeof(ATTESTATION_EXT_OID), &extension);
503 if (ret != CF_SUCCESS) {
504 LOGE("attestation extention is not exist, ret = %{public}d\n", ret);
505 return ret;
506 }
507
508 AttestationRecord *tmp = (AttestationRecord *)CfMalloc(sizeof(AttestationRecord), 0);
509 if (tmp == NULL) {
510 LOGE("Malloc failed\n");
511 return CF_ERR_MALLOC;
512 }
513 ret = ParseAttestationExt(extension, tmp);
514 if (ret != CF_SUCCESS) {
515 CfFree(tmp);
516 tmp = NULL;
517 return ret;
518 }
519
520 ret = ParseAppId(tmp);
521 if (ret != CF_SUCCESS && ret != CF_ERR_EXTENSION_NOT_EXIST) {
522 FreeHmAttestationRecord(tmp);
523 tmp = NULL;
524 return ret;
525 }
526
527 *record = tmp;
528 return CF_SUCCESS;
529 }
530
GetDeviceActivationCertExt(const X509 * cert,DeviceActivationCertExt ** record)531 CfResult GetDeviceActivationCertExt(const X509 *cert, DeviceActivationCertExt **record)
532 {
533 if (cert == NULL || record == NULL) {
534 return CF_NULL_POINTER;
535 }
536 X509_EXTENSION *extension = NULL;
537 CfResult ret = FindCertExt(cert, DEVICE_ACTIVATION_EXT_OID, sizeof(DEVICE_ACTIVATION_EXT_OID), &extension);
538 if (ret != CF_SUCCESS) {
539 LOGE("Device activation cert extention is not exist, ret = %{public}d\n", ret);
540 return ret;
541 }
542
543 DeviceActivationCertExt *tmp = (DeviceActivationCertExt *)CfMalloc(sizeof(DeviceActivationCertExt), 0);
544 if (tmp == NULL) {
545 LOGE("Malloc failed\n");
546 return CF_ERR_MALLOC;
547 }
548 ret = ParseAttestationExt(extension, tmp);
549 if (ret != CF_SUCCESS) {
550 CfFree(tmp);
551 tmp = NULL;
552 return ret;
553 }
554 *record = tmp;
555 return CF_SUCCESS;
556 }
557
GetDeviceSecureLevel(DeviceCertSecureLevel * record,int * version,int * level)558 CfResult GetDeviceSecureLevel(DeviceCertSecureLevel *record, int *version, int *level)
559 {
560 if (record == NULL) {
561 return CF_ERR_EXTENSION_NOT_EXIST;
562 }
563 if (version != NULL) {
564 *version = record->version;
565 }
566 if (level != NULL) {
567 *level = record->secLevel;
568 }
569 return CF_SUCCESS;
570 }
571
FreeAttestationDevSecLevel(DeviceCertSecureLevel * record)572 void FreeAttestationDevSecLevel(DeviceCertSecureLevel *record)
573 {
574 if (record == NULL) {
575 return;
576 }
577
578 CfFree(record);
579 }
580
FreeDeviveActiveCertExt(DeviceActivationCertExt * record)581 void FreeDeviveActiveCertExt(DeviceActivationCertExt *record)
582 {
583 if (record == NULL) {
584 return;
585 }
586
587 HmAttestationClaimfree(record->claims, record->claimNum);
588 CfFree(record);
589 }
590
GetAppIdType(AttestationRecord * record,const uint8_t * oid,uint32_t oidLen,CfBlob * out)591 static CfResult GetAppIdType(AttestationRecord *record, const uint8_t *oid, uint32_t oidLen, CfBlob *out)
592 {
593 if (record == NULL || record->appId == NULL) {
594 return CF_ERR_EXTENSION_NOT_EXIST;
595 }
596
597 if (CmpObjOid(record->appId->type, oid, oidLen) != true) {
598 return CF_ERR_EXTENSION_NOT_EXIST;
599 }
600
601 out->size = (uint32_t)ASN1_STRING_length(record->appId->value);
602 out->data = (uint8_t *)ASN1_STRING_get0_data(record->appId->value);
603 return CF_SUCCESS;
604 }
605
GetAttestCertExt(AttestationRecord * record,HmAttestationCertExtType type,HmAttestationCertExt * ext)606 CfResult GetAttestCertExt(AttestationRecord *record, HmAttestationCertExtType type, HmAttestationCertExt *ext)
607 {
608 if (record == NULL) {
609 return CF_ERR_EXTENSION_NOT_EXIST;
610 }
611 if (type == ATTESTATION_VERSION) {
612 ext->int64Value = record->version;
613 return CF_SUCCESS;
614 }
615 const uint8_t *oid = ATTESTATION_EXT_OIDS[type].oid;
616 uint32_t oidLen = ATTESTATION_EXT_OIDS[type].oidLen;
617 switch (type) {
618 case ATTESTATION_ID_PADDING_FLAG:
619 return GetBooleanItem(record, oid, oidLen, &ext->boolValue);
620 case ATTESTATION_APP_ID_HAP_ID:
621 case ATTESTATION_APP_ID_SA_ID:
622 case ATTESTATION_APP_ID_UNIFIED_ID:
623 return GetAppIdType(record, oid, oidLen, &ext->blob);
624 case ATTESTATION_PURPOSE:
625 return GetInt64Item(record, oid, oidLen, &ext->int64Value);
626 case ATTESTATION_NONCE:
627 case ATTESTATION_IMEI:
628 case ATTESTATION_SERIAL:
629 case ATTESTATION_MEID:
630 case ATTESTATION_MODEL:
631 case ATTESTATION_SOCID:
632 case ATTESTATION_UDID:
633 return GetOctetOrUtf8Item(record, oid, oidLen, &ext->blob);
634 default:
635 return GetOctetStringItem(record, oid, oidLen, &ext->blob);
636 }
637 }
638