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