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 <string.h>
17 #include <stdbool.h>
18 #include "openssl/err.h"
19 #include "cf_log.h"
20 #include "attestation_common.h"
21
CmpObjOid(ASN1_OBJECT * obj,const uint8_t * oid,uint32_t oidLen)22 bool CmpObjOid(ASN1_OBJECT *obj, const uint8_t *oid, uint32_t oidLen)
23 {
24 if (obj == NULL || oid == NULL || oidLen == 0) {
25 return false;
26 }
27
28 if (OBJ_length(obj) != oidLen) {
29 return false;
30 }
31
32 if (memcmp(OBJ_get0_data(obj), oid, oidLen) != 0) {
33 return false;
34 }
35 return true;
36 }
37
FindCertExt(const X509 * cert,const uint8_t * oid,uint32_t oidLen,X509_EXTENSION ** extension)38 CfResult FindCertExt(const X509 *cert, const uint8_t *oid, uint32_t oidLen, X509_EXTENSION **extension)
39 {
40 if (cert == NULL || oid == NULL || oidLen == 0 || extension == NULL) {
41 return CF_NULL_POINTER;
42 }
43 const X509_EXTENSIONS *extensions = X509_get0_extensions(cert);
44 if (extensions == NULL) {
45 return CF_ERR_EXTENSION_NOT_EXIST;
46 }
47
48 int extCount = sk_X509_EXTENSION_num(extensions);
49 if (extCount <= 0) {
50 return CF_ERR_EXTENSION_NOT_EXIST;
51 }
52
53 X509_EXTENSION *tmp = NULL;
54 int i;
55 for (i = 0; i < extCount; i++) {
56 tmp = sk_X509_EXTENSION_value(extensions, i);
57 if (tmp == NULL) {
58 continue;
59 }
60 if (CmpObjOid(X509_EXTENSION_get_object(tmp), oid, oidLen) == true) { // OBJ_create() is not thread safe
61 *extension = tmp;
62 return CF_SUCCESS;
63 }
64 }
65
66 return CF_ERR_EXTENSION_NOT_EXIST;
67 }
68
GetOctectOrUtf8Data(ASN1_TYPE * v,CfBlob * out)69 CfResult GetOctectOrUtf8Data(ASN1_TYPE *v, CfBlob *out)
70 {
71 if (v == NULL) {
72 return CF_ERR_EXTENSION_NOT_EXIST;
73 }
74
75 if (ASN1_TYPE_get(v) == V_ASN1_OCTET_STRING) {
76 out->size = (uint32_t)ASN1_STRING_length(v->value.octet_string);
77 out->data = (uint8_t *)ASN1_STRING_get0_data(v->value.octet_string);
78 } else if (ASN1_TYPE_get(v) == V_ASN1_UTF8STRING) {
79 out->size = (uint32_t)ASN1_STRING_length(v->value.utf8string);
80 out->data = (uint8_t *)ASN1_STRING_get0_data(v->value.utf8string);
81 } else {
82 return CF_ERR_INVALID_EXTENSION;
83 }
84 return CF_SUCCESS;
85 }
86
87 #define MAX_OPENSSL_ERROR_DEPTH 16
88 #define MAX_OPENSSL_ERROR_LEN 256
ProcessOpensslError(CfResult ret)89 void ProcessOpensslError(CfResult ret)
90 {
91 if (ret != CF_ERR_CRYPTO_OPERATION) {
92 return;
93 }
94 char errStr[MAX_OPENSSL_ERROR_LEN] = { 0 };
95 unsigned long errCode = ERR_get_error();
96 uint32_t depth = MAX_OPENSSL_ERROR_DEPTH;
97 while (errCode != 0 && depth > 0) {
98 ERR_error_string_n(errCode, errStr, MAX_OPENSSL_ERROR_LEN);
99 LOGE("Call openssl failed, error code = %{public}lu, error string = %{public}s", errCode, errStr);
100 errCode = ERR_get_error();
101 depth--;
102 }
103 }
104