• 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/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