1 /*
2 * Copyright (c) 2022-2023 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 "hks_verifier.h"
17
18 #include <openssl/asn1.h>
19 #include <openssl/bio.h>
20 #include <openssl/crypto.h>
21 #include <openssl/evp.h>
22 #include <openssl/obj_mac.h>
23 #include <openssl/ossl_typ.h>
24 #include <openssl/pem.h>
25 #include <openssl/x509.h>
26 #include <stddef.h>
27
28 #include "hks_log.h"
29 #include "hks_mem.h"
30 #include "hks_param.h"
31 #include "hks_template.h"
32 #include "hks_type.h"
33 #include "securec.h"
34
35 #define OPENSSL_SUCCESS 1
36 #define OPENSSL_ERROR 0
37 #define KEY_DESCRIPTION_OID "1.3.6.1.4.1.2011.2.376.1.3"
38
39 #define TLV_VERSION_NEED_SIZE 3
40
41 #define ASN_1_TAG_TYPE_SEQ 0x30
42 #define ASN_1_MIN_VAL_1_EXTRA_LEN_BYTE 0x80
43 #define ASN_1_TAG_TYPE_1_BYTE_LEN 0x81
44 #define ASN_1_TAG_TYPE_2_BYTE_LEN 0x82
45 #define ASN_1_MIN_HEADER_LEN 0x3
46 #define APPLICATION_ID_RAW_OID_LEN 16
47 #define APPLICATION_ID_HEADER_LEN 2
48
49 struct HksCertInfo {
50 uint8_t *data;
51 size_t length;
52 enum HksCertFormat format;
53 X509 *x509;
54 };
55
56 #define HKS_ASN1_DECODE_BYTE(ptr, value) \
57 do { \
58 (value) = (uint32_t)((ptr)[0]); \
59 (ptr)++; \
60 } while (0)
61
62 #define HKS_ASN1_DECODE_TWO_BYTE(ptr, value) \
63 do { \
64 (value) = (uint32_t)((ptr)[0] & 0xff) << 8; \
65 (ptr)++; \
66 (value) |= (uint32_t)((ptr)[0] & 0xff); \
67 (ptr)++; \
68 } while (0)
69
70 static uint8_t g_challengeOid[] = {
71 0x06, 0x0d, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x01, 0x04
72 };
73 static uint8_t g_udidOid[] = {
74 0x06, 0x0e, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x02, 0x04, 0x0a
75 };
76 static uint8_t g_snOid[] = {
77 0x06, 0x0e, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x02, 0x04, 0x03
78 };
79 static uint8_t g_secInfoOid[] = {
80 0x06, 0x0e, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x02, 0x02, 0x05
81 };
82 static uint8_t g_versionInfoOid[] = {
83 0x06, 0x0e, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x02, 0x02, 0x04
84 };
85 static uint8_t g_deviceIdOid[] = {
86 0x06, 0x0e, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x02, 0x04, 0x05
87 };
88 static uint8_t g_appIdOid[] = {
89 0x06, 0x0d, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8f, 0x5b, 0x02, 0x82, 0x78, 0x02, 0x01, 0x03
90 };
91
92 static const struct HksParam g_oidParams[] = {
93 {
94 .tag = HKS_TAG_ATTESTATION_CHALLENGE,
95 .blob = {
96 .size = sizeof(g_challengeOid),
97 .data = g_challengeOid
98 }
99 }, {
100 .tag = HKS_TAG_ATTESTATION_ID_UDID,
101 .blob = {
102 .size = sizeof(g_udidOid),
103 .data = g_udidOid
104 }
105 }, {
106 .tag = HKS_TAG_ATTESTATION_ID_SERIAL,
107 .blob = {
108 .size = sizeof(g_snOid),
109 .data = g_snOid
110 }
111 }, {
112 .tag = HKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO,
113 .blob = {
114 .size = sizeof(g_secInfoOid),
115 .data = g_secInfoOid
116 }
117 }, {
118 .tag = HKS_TAG_ATTESTATION_ID_VERSION_INFO,
119 .blob = {
120 .size = sizeof(g_versionInfoOid),
121 .data = g_versionInfoOid
122 }
123 }, {
124 .tag = HKS_TAG_ATTESTATION_ID_DEVICE,
125 .blob = {
126 .size = sizeof(g_deviceIdOid),
127 .data = g_deviceIdOid
128 }
129 }, {
130 .tag = HKS_TAG_ATTESTATION_APPLICATION_ID,
131 .blob = {
132 .size = sizeof(g_appIdOid),
133 .data = g_appIdOid
134 }
135 },
136 };
137
CopyBlobBuffer(const uint8_t * buffer,uint32_t len,struct HksBlob * blob)138 static int32_t CopyBlobBuffer(const uint8_t *buffer, uint32_t len, struct HksBlob *blob)
139 {
140 if ((blob->data == NULL) || (blob->size < len)) {
141 HKS_LOG_E("construct paramSet out blob: invalid blob");
142 return HKS_ERROR_INVALID_ARGUMENT;
143 }
144 if (memcpy_s(blob->data, blob->size, buffer, len) != EOK) {
145 HKS_LOG_E("construct paramSet out blob buffer failed");
146 return HKS_ERROR_INSUFFICIENT_MEMORY;
147 }
148 blob->size = len;
149 return HKS_SUCCESS;
150 }
151
GetX509FormatCert(const struct HksCertInfo * cert)152 static X509 *GetX509FormatCert(const struct HksCertInfo *cert)
153 {
154 X509 *x509 = NULL;
155
156 BIO *bio = BIO_new_mem_buf(cert->data, cert->length);
157 HKS_IF_NULL_RETURN(bio, x509)
158
159 if (cert->format == HKS_CERT_DER) {
160 x509 = d2i_X509_bio(bio, NULL);
161 } else if (cert->format == HKS_CERT_PEM) {
162 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
163 }
164
165 BIO_free(bio);
166 return x509;
167 }
168
TranslateToX509Format(struct HksCertInfo * certs,uint32_t certNum)169 static int32_t TranslateToX509Format(struct HksCertInfo *certs, uint32_t certNum)
170 {
171 for (uint32_t i = 0; i < certNum; ++i) {
172 X509 *x509 = GetX509FormatCert(&certs[i]);
173 /* if failed, x509 need to be freed by caller function */
174 HKS_IF_NULL_LOGE_RETURN(x509, HKS_ERROR_VERIFICATION_FAILED, "load cert chain to x509 failed")
175
176 certs[i].x509 = x509;
177 }
178 return HKS_SUCCESS;
179 }
180
VerifySignature(const struct HksCertInfo * cert,const struct HksCertInfo * issuerCert)181 static int32_t VerifySignature(const struct HksCertInfo *cert, const struct HksCertInfo *issuerCert)
182 {
183 EVP_PKEY *pubKey = X509_get_pubkey(issuerCert->x509);
184 HKS_IF_NULL_LOGE_RETURN(pubKey, HKS_ERROR_VERIFICATION_FAILED, "get public key from device cert failed")
185
186 int32_t resOpenssl = X509_verify(cert->x509, pubKey);
187 if (resOpenssl != OPENSSL_SUCCESS) {
188 HKS_LOG_E("verify signature failed");
189 }
190
191 EVP_PKEY_free(pubKey);
192 return (resOpenssl == OPENSSL_SUCCESS) ? HKS_SUCCESS : HKS_ERROR_VERIFICATION_FAILED;
193 }
194
VerifyCertChain(const struct HksCertInfo * certs,uint32_t certNum)195 static int32_t VerifyCertChain(const struct HksCertInfo *certs, uint32_t certNum)
196 {
197 int32_t ret = HKS_ERROR_VERIFICATION_FAILED;
198 X509_STORE *store = X509_STORE_new();
199 X509_STORE_CTX *verifyCtx = X509_STORE_CTX_new();
200 if ((store == NULL) || (verifyCtx == NULL)) {
201 HKS_LOG_E("verify cert chain init failed");
202 goto EXIT;
203 }
204
205 for (uint32_t i = certNum - 1; i > 1; i--) { /* add root ca cert and device ca cert */
206 if (X509_STORE_add_cert(store, certs[i].x509) != OPENSSL_SUCCESS) {
207 HKS_LOG_E("add cert to store failed");
208 goto EXIT;
209 }
210 }
211
212 int32_t resOpenssl = X509_STORE_CTX_init(verifyCtx, store, certs[1].x509, NULL); /* cert 1: add device cert */
213 if (resOpenssl != OPENSSL_SUCCESS) {
214 HKS_LOG_E("init verify ctx failed");
215 goto EXIT;
216 }
217
218 resOpenssl = X509_verify_cert(verifyCtx);
219 if (resOpenssl != OPENSSL_SUCCESS) {
220 HKS_LOG_E("verify cert failed");
221 goto EXIT;
222 }
223
224 ret = VerifySignature(&certs[certNum - 1], &certs[certNum - 1]); /* root ca cert need to be verified by itself */
225 HKS_IF_NOT_SUCC_LOGE(ret, "verify root cert failed")
226
227 EXIT:
228 if (verifyCtx != NULL) {
229 X509_STORE_CTX_free(verifyCtx);
230 }
231 if (store != NULL) {
232 X509_STORE_free(store);
233 }
234 return ret;
235 }
236
VerifyAttestationCertChain(struct HksCertInfo * certs,uint32_t certNum)237 static int32_t VerifyAttestationCertChain(struct HksCertInfo *certs, uint32_t certNum)
238 {
239 int32_t ret = TranslateToX509Format(certs, certNum);
240 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "translate to x509 format failed")
241
242 ret = VerifyCertChain(certs, certNum);
243 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "verify attestation cert chain verify cert chain failed")
244
245 /* use device cert's pubkey to verify the attestation cert */
246 ret = VerifySignature(&certs[0], &certs[1]); /* 0:attestation cert, 1:device cert */
247 HKS_IF_NOT_SUCC_LOGE(ret, "verify attestation cert chain signature failed")
248
249 return ret;
250 }
251
EncodeTlvAndGetLength(uint8_t ** buf,uint32_t * outLength,uint32_t inLen)252 static int32_t EncodeTlvAndGetLength(uint8_t **buf, uint32_t *outLength, uint32_t inLen)
253 {
254 uint32_t length = 0; /* length of the payload */
255
256 uint32_t tmp;
257 HKS_ASN1_DECODE_BYTE(*buf, tmp); /* get type */
258 if ((*buf)[0] < ASN_1_MIN_VAL_1_EXTRA_LEN_BYTE) {
259 /* Current byte tells the length */
260 HKS_ASN1_DECODE_BYTE(*buf, length);
261 } else {
262 /* now bit 8 is set */
263 uint32_t b;
264 HKS_ASN1_DECODE_BYTE(*buf, b);
265
266 switch (b) {
267 case ASN_1_TAG_TYPE_1_BYTE_LEN: /* 1 byte length */
268 HKS_ASN1_DECODE_BYTE(*buf, length);
269 break;
270 case ASN_1_TAG_TYPE_2_BYTE_LEN: /* 2 byte length */
271 if (inLen < (ASN_1_MIN_HEADER_LEN + 1)) {
272 HKS_LOG_E("invalid data to decode two bytes");
273 return HKS_ERROR_INVALID_ARGUMENT;
274 }
275 HKS_ASN1_DECODE_TWO_BYTE(*buf, length);
276 break;
277 default:
278 HKS_LOG_E("Object length does not make sense");
279 return HKS_ERROR_INVALID_ARGUMENT;
280 }
281 }
282 *outLength = length;
283 return HKS_SUCCESS;
284 }
285
ExtractTlvLength(const uint8_t * in,uint32_t inLen,uint32_t * headSize,uint32_t * outLen)286 static int32_t ExtractTlvLength(const uint8_t *in, uint32_t inLen, uint32_t *headSize, uint32_t *outLen)
287 {
288 if ((in == NULL) || (inLen < ASN_1_MIN_HEADER_LEN) || (outLen == NULL)) {
289 HKS_LOG_E("invalid tlv data");
290 return HKS_ERROR_INVALID_ARGUMENT;
291 }
292
293 uint8_t *buf = (uint8_t *)in;
294 uint32_t length = 0; /* length of the payload */
295
296 int32_t ret = EncodeTlvAndGetLength(&buf, &length, inLen);
297 HKS_IF_NOT_SUCC_RETURN(ret, ret)
298
299 *headSize = buf - in;
300 if (*headSize > inLen) {
301 HKS_LOG_E("the data is too small, extract failed");
302 return HKS_ERROR_BUFFER_TOO_SMALL;
303 }
304 /* Check that tag length can fit into buffer */
305 if (length > (inLen - *headSize)) {
306 HKS_LOG_E("data buffer is not big enough to hold %" LOG_PUBLIC "u bytes.", length);
307 return HKS_ERROR_INVALID_ARGUMENT;
308 }
309 *outLen = length;
310 return HKS_SUCCESS;
311 }
312
ExtractTlvData(const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)313 static int32_t ExtractTlvData(const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
314 {
315 if ((in == NULL) || (inLen < ASN_1_MIN_HEADER_LEN) || (out == NULL) || (outLen == NULL)) {
316 HKS_LOG_E("invalid tlv data");
317 return HKS_ERROR_INVALID_ARGUMENT;
318 }
319
320 uint8_t *buf = (uint8_t *)in;
321 uint32_t length = 0; /* length of the payload */
322
323 int32_t ret = EncodeTlvAndGetLength(&buf, &length, inLen);
324 HKS_IF_NOT_SUCC_RETURN(ret, ret)
325
326 uint32_t headSize = buf - in;
327 if (headSize > inLen) {
328 HKS_LOG_E("the data is too small, extract failed");
329 return HKS_ERROR_BUFFER_TOO_SMALL;
330 }
331 /* Check that tag length can fit into buffer */
332 if (length > (inLen - headSize)) {
333 HKS_LOG_E("data buffer is not big enough to hold %" LOG_PUBLIC "u bytes.", length);
334 return HKS_ERROR_INVALID_ARGUMENT;
335 }
336 if (memcpy_s(out, *outLen, buf, length) != EOK) {
337 HKS_LOG_E("extract tlv data memcpy_s failed");
338 return HKS_ERROR_INSUFFICIENT_MEMORY;
339 }
340 *outLen = length;
341 return HKS_SUCCESS;
342 }
343
ExtractTlvDataAndHeadSize(const uint8_t * in,uint32_t inLen,uint8_t ** out,uint32_t * outLen,uint32_t * size)344 static int32_t ExtractTlvDataAndHeadSize(const uint8_t *in, uint32_t inLen,
345 uint8_t **out, uint32_t *outLen, uint32_t *size)
346 {
347 uint32_t headOffset = 0;
348 int32_t ret = ExtractTlvLength(in, inLen, &headOffset, outLen);
349 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ExtractTlvLength fail!")
350 if (size != NULL) {
351 *size = headOffset;
352 }
353
354 *out = (uint8_t *)HksMalloc(*outLen);
355 HKS_IF_NULL_LOGE_RETURN(*out, HKS_ERROR_MALLOC_FAIL, "malloc fail!")
356
357 ret = ExtractTlvData(in, inLen, *out, outLen);
358 if (ret != HKS_SUCCESS) {
359 HKS_FREE(*out);
360 HKS_LOG_E("ExtractTlvData fail!");
361 }
362 return ret;
363 }
364
GetObjByOid(int32_t nid,const char * oid,const char * sn,const char * ln)365 static ASN1_OBJECT *GetObjByOid(int32_t nid, const char *oid, const char *sn, const char *ln)
366 {
367 int32_t len;
368 ASN1_OBJECT *obj = NULL;
369 uint8_t *buf = NULL;
370 do {
371 len = a2d_ASN1_OBJECT(NULL, 0, oid, -1);
372 if (len <= 0) {
373 HKS_LOG_E("get a2d_ASN1_OBJECT fail, len1 = %" LOG_PUBLIC "d", len);
374 return NULL;
375 }
376
377 buf = (uint8_t *)HksMalloc(len);
378 HKS_IF_NULL_LOGE_RETURN(buf, NULL, "openssl malloc fail")
379
380 len = a2d_ASN1_OBJECT(buf, len, oid, -1);
381 if (len <= 0) {
382 HKS_LOG_E("get a2d_ASN1_OBJECT fail, len2 = %" LOG_PUBLIC "d", len);
383 break;
384 }
385
386 obj = ASN1_OBJECT_create(nid, buf, len, sn, ln);
387 HKS_IF_NULL_LOGE_BREAK(obj, "ASN1_OBJECT_create fail")
388 } while (0);
389 HKS_FREE(buf);
390 return obj;
391 }
392
GetKeyDescriptionSeqValue(const struct HksCertInfo * cert,uint8_t ** data,uint32_t * len)393 static int32_t GetKeyDescriptionSeqValue(const struct HksCertInfo *cert, uint8_t **data, uint32_t *len)
394 {
395 int32_t ret = HKS_ERROR_VERIFICATION_FAILED;
396 ASN1_OBJECT *obj = GetObjByOid(NID_undef, KEY_DESCRIPTION_OID, "KeyDescription", "KEY DESCRIPTION OID");
397 HKS_IF_NULL_LOGE_RETURN(obj, ret, "get obj by oid failed")
398
399 int32_t idx = X509_get_ext_by_OBJ(cert->x509, obj, -1);
400 if (idx < 0) {
401 HKS_LOG_E("get ext idx by Obj failed");
402 goto EXIT;
403 }
404
405 X509_EXTENSION *ext = X509_get_ext(cert->x509, idx);
406 if (ext == NULL) {
407 HKS_LOG_E("X509 get ext by idx failed");
408 goto EXIT;
409 }
410
411 ASN1_OCTET_STRING *octetStr = X509_EXTENSION_get_data(ext);
412 if (octetStr == NULL) {
413 HKS_LOG_E("X509 extension get data by ext failed");
414 goto EXIT;
415 }
416
417 // gain the Extension data of attest cert
418 ret = ExtractTlvDataAndHeadSize(octetStr->data, octetStr->length, data, len, NULL);
419 if (ret != HKS_SUCCESS) {
420 HKS_LOG_E("gain the extension data failed");
421 goto EXIT;
422 }
423
424 if (*len >= MAX_ATTEST_EXTENSION_BUF_LEN) {
425 (void)memset_s(*data, *len, 0, *len);
426 HKS_FREE(*data);
427 HKS_LOG_E("the length of extension data is too long");
428 ret = HKS_ERROR_INSUFFICIENT_MEMORY;
429 }
430
431 EXIT:
432 ASN1_OBJECT_free(obj);
433 return ret;
434 }
435
ConstructParamSetOut(enum HksTag tag,uint8_t * data,uint32_t len,struct HksParamSet * paramSetOut)436 static int32_t ConstructParamSetOut(enum HksTag tag, uint8_t *data, uint32_t len, struct HksParamSet *paramSetOut)
437 {
438 int32_t ret;
439 for (uint32_t i = 0; i < paramSetOut->paramsCnt; i++) {
440 if ((paramSetOut->params[i].tag == tag) && (GetTagType(tag) == HKS_TAG_TYPE_BYTES)) {
441 if (tag == HKS_TAG_ATTESTATION_APPLICATION_ID) {
442 // APPLICATION_ID_RAW_OID_LEN + APPLICATION_ID_HEADER_LEN + sizeof(appId)
443 uint32_t appIdOffsetSize = APPLICATION_ID_RAW_OID_LEN + APPLICATION_ID_HEADER_LEN;
444 ret = CopyBlobBuffer(data + appIdOffsetSize, len - appIdOffsetSize, &(paramSetOut->params[i].blob));
445 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "CopyBlobBuffer failed")
446 } else {
447 ret = CopyBlobBuffer(data, len, &(paramSetOut->params[i].blob));
448 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "CopyBlobBuffer failed")
449 }
450 return HKS_SUCCESS;
451 }
452 }
453 return HKS_SUCCESS;
454 }
455
GetClaimDataParamSet(uint8_t * data,uint32_t len,struct HksParamSet * paramSetOut)456 static int32_t GetClaimDataParamSet(uint8_t *data, uint32_t len, struct HksParamSet *paramSetOut)
457 {
458 for (uint32_t i = 0; i < sizeof(g_oidParams) / sizeof(g_oidParams[0]); i++) {
459 uint32_t offset = TLV_VERSION_NEED_SIZE;
460 uint8_t *claimData = NULL;
461 uint32_t claimSize = 0;
462 uint32_t headSize = 0;
463
464 if ((offset > len) || ((len - offset) < g_oidParams[i].blob.size)) {
465 HKS_LOG_E("input param invalid, fail");
466 return HKS_ERROR_INVALID_ARGUMENT;
467 }
468
469 if (HksMemCmp(g_oidParams[i].blob.data, data + offset, g_oidParams[i].blob.size) == 0) {
470 offset += g_oidParams[i].blob.size;
471 int32_t ret = ExtractTlvDataAndHeadSize(data + offset, len - offset, &claimData, &claimSize, &headSize);
472 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "get cliam count fail")
473
474 if (claimSize >= MAX_ATTEST_CLAIM_BUF_LEN) {
475 HKS_LOG_E("the length of claim is too long");
476 HKS_FREE(claimData);
477 return HKS_ERROR_INSUFFICIENT_MEMORY;
478 }
479
480 ret = ConstructParamSetOut(g_oidParams[i].tag, claimData, claimSize, paramSetOut);
481 if (ret != HKS_SUCCESS) {
482 HKS_LOG_E("ConstructParamSetOut fail");
483 HKS_FREE(claimData);
484 return HKS_ERROR_INVALID_ARGUMENT;
485 }
486 HKS_FREE(claimData);
487 return HKS_SUCCESS;
488 }
489 }
490
491 return HKS_SUCCESS;
492 }
493
FillAttestExtendParamSet(uint8_t * data,uint32_t length,uint8_t version,struct HksParamSet * paramSetOut)494 static int32_t FillAttestExtendParamSet(uint8_t *data, uint32_t length,
495 uint8_t version, struct HksParamSet *paramSetOut)
496 {
497 if ((data == NULL) || (length < ASN_1_MIN_HEADER_LEN)) {
498 HKS_LOG_E("invalid argument data");
499 return HKS_ERROR_INVALID_ARGUMENT;
500 }
501 int32_t ret;
502 uint32_t headSize;
503 uint32_t leftSize = length;
504 uint8_t *tmp = data;
505
506 for (headSize = 0; leftSize >= ASN_1_MIN_HEADER_LEN;) {
507 uint8_t *value = NULL;
508 uint32_t valueLength;
509 ret = ExtractTlvDataAndHeadSize(tmp, leftSize, &value, &valueLength, &headSize);
510 if (ret != HKS_SUCCESS || valueLength > (leftSize - headSize)
511 || leftSize < ASN_1_MIN_HEADER_LEN) {
512 HKS_FREE(value);
513 HKS_LOG_E("get claim count fail, the length of claim or the value of leftSize can be wrong, too");
514 return HKS_ERROR_INVALID_ARGUMENT;
515 }
516
517 if (valueLength >= MAX_ATTEST_CLAIM_BUF_LEN) {
518 HKS_LOG_E("the length of claim is too long");
519 HKS_FREE(value);
520 return HKS_ERROR_INSUFFICIENT_MEMORY;
521 }
522
523 ret = GetClaimDataParamSet(value, valueLength, paramSetOut);
524 if (ret != HKS_SUCCESS) {
525 HKS_LOG_E("GetClaimDataParamSet failed, ret = %" LOG_PUBLIC "d", ret);
526 HKS_FREE(value);
527 return ret;
528 }
529 HKS_FREE(value);
530 tmp += (valueLength + headSize);
531 leftSize -= (valueLength + headSize);
532 }
533 return HKS_SUCCESS;
534 }
535
FillAttestExtendInfo(uint8_t * data,uint32_t length,struct HksParamSet * paramSetOut)536 static int32_t FillAttestExtendInfo(uint8_t *data, uint32_t length, struct HksParamSet *paramSetOut)
537 {
538 if ((data == NULL) || (length < ASN_1_MIN_HEADER_LEN) || (length <= TLV_VERSION_NEED_SIZE)) {
539 HKS_LOG_E("invalid argument data");
540 return HKS_ERROR_INVALID_ARGUMENT;
541 }
542
543 uint8_t *version = NULL;
544 uint32_t len;
545 int32_t ret = ExtractTlvDataAndHeadSize(data, length, &version, &len, NULL);
546 if (ret != HKS_SUCCESS || len != sizeof(uint8_t)) {
547 HKS_FREE(version);
548 HKS_LOG_E("get version fail or length is not equal to sizeof(uint8_t)");
549 return HKS_ERROR_INVALID_ARGUMENT;
550 }
551
552 ret = FillAttestExtendParamSet(data + TLV_VERSION_NEED_SIZE, length - TLV_VERSION_NEED_SIZE,
553 *version, paramSetOut);
554 HKS_IF_NOT_SUCC_LOGE(ret, "fill attest extend paramSet fail")
555
556 HKS_FREE(version);
557 return ret;
558 }
559
GetParamSetOutInfo(const struct HksCertInfo * certs,struct HksParamSet * paramSetOut)560 static int32_t GetParamSetOutInfo(const struct HksCertInfo *certs, struct HksParamSet *paramSetOut)
561 {
562 uint8_t *keyDescription = NULL;
563 uint32_t keyDescLen;
564
565 int32_t ret = GetKeyDescriptionSeqValue(&certs[0], &keyDescription, &keyDescLen);
566 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "GetKeyDescriptionSeqValue failed")
567
568 ret = FillAttestExtendInfo(keyDescription, keyDescLen, paramSetOut);
569 HKS_IF_NOT_SUCC_LOGE(ret, "fill attest extend info fail")
570
571 (void)memset_s(keyDescription, keyDescLen, 0, keyDescLen);
572 HKS_FREE(keyDescription);
573 return ret;
574 }
575
InitCertChainInfo(const struct HksCertChain * certChain,struct HksCertInfo ** certs)576 static int32_t InitCertChainInfo(const struct HksCertChain *certChain, struct HksCertInfo **certs)
577 {
578 int32_t ret = HKS_SUCCESS;
579
580 uint32_t certsInfoLen = sizeof(struct HksCertInfo) * certChain->certsCount; /* only 4 cert */
581 struct HksCertInfo *certsInfo = (struct HksCertInfo *)HksMalloc(certsInfoLen);
582 HKS_IF_NULL_RETURN(certsInfo, HKS_ERROR_MALLOC_FAIL)
583
584 (void)memset_s(certsInfo, certsInfoLen, 0, certsInfoLen);
585
586 for (uint32_t i = 0; i < certChain->certsCount; ++i) {
587 struct HksCertInfo *cert = &(certsInfo[i]);
588 cert->data = certChain->certs[i].data;
589 cert->length = certChain->certs[i].size;
590
591 if (cert->data[0] == '-') {
592 cert->format = HKS_CERT_PEM;
593 } else if (cert->data[0] == ASN_1_TAG_TYPE_SEQ) {
594 cert->format = HKS_CERT_DER;
595 } else {
596 HKS_LOG_E("validate cert chain invalid cert format");
597 ret = HKS_ERROR_VERIFICATION_FAILED;
598 break;
599 }
600 }
601
602 if (ret != HKS_SUCCESS) {
603 HKS_FREE(certsInfo);
604 return ret;
605 }
606 *certs = certsInfo;
607 return HKS_SUCCESS;
608 }
609
FreeCertChainInfo(struct HksCertInfo ** certs,uint32_t certNum)610 static void FreeCertChainInfo(struct HksCertInfo **certs, uint32_t certNum)
611 {
612 if (*certs != NULL) {
613 for (uint32_t i = 0; i < certNum; ++i) {
614 if ((*certs)[i].x509 != NULL) {
615 X509_free((*certs)[i].x509);
616 }
617 }
618 HKS_FREE(*certs);
619 }
620 }
621
CheckCertChainParams(const struct HksCertChain * certChain)622 static int32_t CheckCertChainParams(const struct HksCertChain *certChain)
623 {
624 /* certChain has been checked not null */
625 if ((certChain->certs == NULL) || (certChain->certsCount != HKS_DEFAULT_CERT_CHAIN_CNT)) {
626 HKS_LOG_E("validate cert chain chain invalid certChain or count");
627 return HKS_ERROR_INVALID_ARGUMENT;
628 }
629
630 for (uint32_t i = 0; i < certChain->certsCount; ++i) {
631 if (CheckBlob(&certChain->certs[i]) != HKS_SUCCESS) {
632 HKS_LOG_E("certChain entry[%" LOG_PUBLIC "u] invalid", i);
633 return HKS_ERROR_INVALID_ARGUMENT;
634 }
635 }
636 return HKS_SUCCESS;
637 }
638
CheckValidateCertChainParams(const struct HksCertChain * certChain,struct HksParamSet * paramSetOut)639 static int32_t CheckValidateCertChainParams(const struct HksCertChain *certChain, struct HksParamSet *paramSetOut)
640 {
641 int32_t ret = CheckCertChainParams(certChain);
642 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "certChain invalid, ret = %" LOG_PUBLIC "d", ret)
643
644 /* paramSetOut has been checked not null */
645 ret = HksCheckParamSet(paramSetOut, paramSetOut->paramSetSize);
646 HKS_IF_NOT_SUCC_LOGE(ret, "paramSetOut invalid, ret = %" LOG_PUBLIC "d", ret)
647 return ret;
648 }
649
HksClientValidateCertChain(const struct HksCertChain * certChain,struct HksParamSet * paramSetOut)650 int32_t HksClientValidateCertChain(const struct HksCertChain *certChain, struct HksParamSet *paramSetOut)
651 {
652 int32_t ret = CheckValidateCertChainParams(certChain, paramSetOut);
653 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "certChain params check failed, ret = %" LOG_PUBLIC "d", ret)
654
655 struct HksCertInfo *certsInfo = NULL;
656 ret = InitCertChainInfo(certChain, &certsInfo);
657 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get cert chain info failed")
658 ret = VerifyAttestationCertChain(certsInfo, certChain->certsCount);
659 if (ret != HKS_SUCCESS) {
660 FreeCertChainInfo(&certsInfo, certChain->certsCount);
661 HKS_LOG_E("VerifyAttestationCertChain failed, ret = %" LOG_PUBLIC "d", ret);
662 return ret;
663 }
664
665 ret = GetParamSetOutInfo(certsInfo, paramSetOut);
666 HKS_IF_NOT_SUCC_LOGE(ret, "VerifyAttestationCertChain failed, ret = %" LOG_PUBLIC "d", ret)
667
668 FreeCertChainInfo(&certsInfo, certChain->certsCount);
669 return ret;
670 }
671