1 /*
2 * Copyright (c) 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 "cf_object_extension.h"
17
18 #include "securec.h"
19
20 #include "cf_ability.h"
21 #include "cf_log.h"
22 #include "cf_magic.h"
23 #include "cf_memory.h"
24 #include "cf_param.h"
25 #include "cf_param_parse.h"
26 #include "cf_result.h"
27
28 #include "cf_extension_adapter_ability_define.h"
29
30 typedef struct {
31 CfBase base;
32 CfExtensionAdapterAbilityFunc func;
33 CfBase *adapterRes;
34 } CfExtensionObjStruct;
35
CfExtensionCreate(const CfEncodingBlob * in,CfBase ** obj)36 int32_t CfExtensionCreate(const CfEncodingBlob *in, CfBase **obj)
37 {
38 if ((in == NULL) || (obj == NULL)) {
39 CF_LOG_E("param null");
40 return CF_NULL_POINTER;
41 }
42
43 CfExtensionAdapterAbilityFunc *func = (CfExtensionAdapterAbilityFunc *)GetAbility(
44 CF_ABILITY(CF_ABILITY_TYPE_ADAPTER, CF_OBJ_TYPE_EXTENSION));
45 if ((func == NULL) || (func->base.type != CF_MAGIC(CF_MAGIC_TYPE_ADAPTER_FUNC, CF_OBJ_TYPE_EXTENSION))) {
46 CF_LOG_E("invalid func type");
47 return CF_INVALID_PARAMS;
48 }
49
50 CfExtensionObjStruct *tmp = CfMalloc(sizeof(CfExtensionObjStruct), 0);
51 if (tmp == NULL) {
52 CF_LOG_E("malloc cert obj failed");
53 return CF_ERR_MALLOC;
54 }
55
56 tmp->base.type = CF_MAGIC(CF_MAGIC_TYPE_OBJ_RESOURCE, CF_OBJ_TYPE_EXTENSION);
57 int32_t ret = func->adapterCreate(in, &tmp->adapterRes);
58 if (ret != CF_SUCCESS) {
59 CF_LOG_E("cert adapter create failed");
60 CfFree(tmp);
61 return ret;
62 }
63 (void)memcpy_s(&tmp->func, sizeof(CfExtensionAdapterAbilityFunc), func, sizeof(CfExtensionAdapterAbilityFunc));
64
65 *obj = &(tmp->base);
66 return CF_SUCCESS;
67 }
68
CfExtGetItem(const CfExtensionObjStruct * obj,const CfParamSet * in,CfParamSet ** out)69 static int32_t CfExtGetItem(const CfExtensionObjStruct *obj, const CfParamSet *in, CfParamSet **out)
70 {
71 CfParam *tmpParam = NULL;
72 int32_t ret = CfGetParam(in, CF_TAG_PARAM0_INT32, &tmpParam);
73 if (ret != CF_SUCCESS) {
74 CF_LOG_E("ext get item failed, ret = %d", ret);
75 return ret;
76 }
77
78 CfBlob itemRes = { 0, NULL };
79 ret = obj->func.adapterGetItem(obj->adapterRes, (CfItemId)tmpParam->int32Param, &itemRes);
80 if (ret != CF_SUCCESS) {
81 CF_LOG_E("ext adapter get item failed, ret = %d", ret);
82 return ret;
83 }
84
85 CfParam params[] = {
86 { .tag = CF_TAG_RESULT_TYPE, .int32Param = CF_TAG_TYPE_BYTES },
87 { .tag = CF_TAG_RESULT_BYTES, .blob = itemRes },
88 };
89 ret = CfConstructParamSetOut(params, sizeof(params) / sizeof(CfParam), out);
90 CfFree(itemRes.data);
91 return ret;
92 }
93
CfExtGetOids(const CfExtensionObjStruct * obj,const CfParamSet * in,CfParamSet ** out)94 static int32_t CfExtGetOids(const CfExtensionObjStruct *obj, const CfParamSet *in, CfParamSet **out)
95 {
96 CfParam *oidTypeParam = NULL;
97 int32_t ret = CfGetParam(in, CF_TAG_PARAM0_INT32, &oidTypeParam);
98 if (ret != CF_SUCCESS) {
99 CF_LOG_E("get oid type failed, ret = %d", ret);
100 return ret;
101 }
102
103 CfBlobArray oids = { NULL, 0 };
104 ret = obj->func.adapterGetOids(obj->adapterRes, (CfExtensionOidType)oidTypeParam->int32Param, &oids);
105 if (ret != CF_SUCCESS) {
106 CF_LOG_E("adapter get oids failed, ret = %d", ret);
107 return ret;
108 }
109
110 ret = CfConstructArrayParamSetOut(&oids, out);
111 FreeCfBlobArray(oids.data, oids.count);
112 return ret;
113 }
114
CfExtGetEntry(const CfExtensionObjStruct * obj,const CfParamSet * in,CfParamSet ** out)115 static int32_t CfExtGetEntry(const CfExtensionObjStruct *obj, const CfParamSet *in, CfParamSet **out)
116 {
117 CfParam *entryTypeParam = NULL;
118 int32_t ret = CfGetParam(in, CF_TAG_PARAM0_INT32, &entryTypeParam);
119 if (ret != CF_SUCCESS) {
120 CF_LOG_E("get entry type failed, ret = %d", ret);
121 return ret;
122 }
123
124 CfParam *oidParam = NULL;
125 ret = CfGetParam(in, CF_TAG_PARAM1_BUFFER, &oidParam);
126 if (ret != CF_SUCCESS) {
127 CF_LOG_E("get oid failed, ret = %d", ret);
128 return ret;
129 }
130
131 CfBlob entryValue = { 0, NULL };
132 ret = obj->func.adapterGetEntry(obj->adapterRes, (CfExtensionEntryType)entryTypeParam->int32Param,
133 &oidParam->blob, &entryValue);
134 if (ret != CF_SUCCESS) {
135 CF_LOG_E("adapter get entry failed, ret = %d", ret);
136 return ret;
137 }
138
139 CfParam params[] = {
140 { .tag = CF_TAG_RESULT_TYPE, .int32Param = CF_TAG_TYPE_BYTES },
141 { .tag = CF_TAG_RESULT_BYTES, .blob = entryValue },
142 };
143 ret = CfConstructParamSetOut(params, sizeof(params) / sizeof(CfParam), out);
144 CfFree(entryValue.data);
145 return ret;
146 }
147
CfExtensionGet(const CfBase * obj,const CfParamSet * in,CfParamSet ** out)148 int32_t CfExtensionGet(const CfBase *obj, const CfParamSet *in, CfParamSet **out)
149 {
150 if ((obj == NULL) || (in == NULL) || (out == NULL)) {
151 CF_LOG_E("cfextensionget params is null");
152 return CF_NULL_POINTER;
153 }
154
155 CfExtensionObjStruct *tmp = (CfExtensionObjStruct *)obj;
156 if (tmp->base.type != CF_MAGIC(CF_MAGIC_TYPE_OBJ_RESOURCE, CF_OBJ_TYPE_EXTENSION)) {
157 CF_LOG_E("invalid resource type");
158 return CF_INVALID_PARAMS;
159 }
160
161 CfParam *tmpParam = NULL;
162 int32_t ret = CfGetParam(in, CF_TAG_GET_TYPE, &tmpParam);
163 if (ret != CF_SUCCESS) {
164 CF_LOG_E("get type failed, ret = %d", ret);
165 return ret;
166 }
167
168 switch (tmpParam->int32Param) {
169 case CF_GET_TYPE_EXT_ITEM:
170 return CfExtGetItem(tmp, in, out);
171 case CF_GET_TYPE_EXT_OIDS:
172 return CfExtGetOids(tmp, in, out);
173 case CF_GET_TYPE_EXT_ENTRY:
174 return CfExtGetEntry(tmp, in, out);
175 default:
176 CF_LOG_E("extension get type invalid, type = %d", tmpParam->int32Param);
177 return CF_NOT_SUPPORT;
178 }
179 }
180
CfExtensionCheck(const CfBase * obj,const CfParamSet * in,CfParamSet ** out)181 int32_t CfExtensionCheck(const CfBase *obj, const CfParamSet *in, CfParamSet **out)
182 {
183 if ((obj == NULL) || (in == NULL) || (out == NULL)) {
184 CF_LOG_E("cfextensioncheck params is null");
185 return CF_NULL_POINTER;
186 }
187
188 CfExtensionObjStruct *tmp = (CfExtensionObjStruct *)obj;
189 if (tmp->base.type != CF_MAGIC(CF_MAGIC_TYPE_OBJ_RESOURCE, CF_OBJ_TYPE_EXTENSION)) {
190 CF_LOG_E("invalid resource type");
191 return CF_INVALID_PARAMS;
192 }
193
194 CfParam *tmpParam = NULL;
195 int32_t ret = CfGetParam(in, CF_TAG_CHECK_TYPE, &tmpParam);
196 if (ret != CF_SUCCESS) {
197 CF_LOG_E("get check type failed, ret = %d", ret);
198 return ret;
199 }
200
201 if (tmpParam->int32Param == CF_CHECK_TYPE_EXT_CA) {
202 int32_t pathLen;
203 ret = tmp->func.adapterCheckCA(tmp->adapterRes, &pathLen);
204 if (ret != CF_SUCCESS) {
205 CF_LOG_E("adapter check ca failed");
206 return ret;
207 }
208
209 CfParam params[] = {
210 { .tag = CF_TAG_RESULT_TYPE, .int32Param = CF_TAG_TYPE_INT },
211 { .tag = CF_TAG_RESULT_INT, .int32Param = pathLen },
212 };
213 return CfConstructParamSetOut(params, sizeof(params) / sizeof(CfParam), out);
214 } else if (tmpParam->int32Param == CF_CHECK_TYPE_EXT_HAS_UN_SUPPORT) {
215 bool flag = false;
216 ret = tmp->func.adapterHasUnsupportedCriticalExtension(tmp->adapterRes, &flag);
217 if (ret != CF_SUCCESS) {
218 CF_LOG_E("adapter has unsupported critical extension failed");
219 return ret;
220 }
221 CfParam params[] = {
222 { .tag = CF_TAG_RESULT_TYPE, .int32Param = CF_TAG_TYPE_BOOL },
223 { .tag = CF_TAG_RESULT_BOOL, .boolParam = flag },
224 };
225 return CfConstructParamSetOut(params, sizeof(params) / sizeof(CfParam), out);
226 }
227
228 CF_LOG_E("extension check type invalid, type = %d", tmpParam->int32Param);
229 return CF_NOT_SUPPORT;
230 }
231
CfExtensionDestroy(CfBase ** obj)232 void CfExtensionDestroy(CfBase **obj)
233 {
234 if ((obj == NULL) || (*obj == NULL)) {
235 return;
236 }
237
238 CfExtensionObjStruct *tmp = (CfExtensionObjStruct *)*obj;
239 if (tmp->base.type != CF_MAGIC(CF_MAGIC_TYPE_OBJ_RESOURCE, CF_OBJ_TYPE_EXTENSION)) {
240 /* only extension objects can be destroyed */
241 CF_LOG_E("invalid resource type");
242 return;
243 }
244
245 tmp->func.adapterDestory(&tmp->adapterRes);
246 CfFree(tmp);
247 *obj = NULL;
248 return;
249 }