1 /*
2 * Copyright (c) 2023-2024 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 "x509_cert_chain.h"
17
18 #include <securec.h>
19
20 #include "cf_blob.h"
21 #include "cf_log.h"
22 #include "cf_memory.h"
23 #include "cf_result.h"
24 #include "config.h"
25 #include "utils.h"
26 #include "x509_cert_chain_openssl.h"
27 #include "x509_cert_chain_spi.h"
28 #include "x509_certificate.h"
29
30 typedef CfResult (*CertChainSpiCreateByEncFunc)(const CfEncodingBlob *, HcfX509CertChainSpi **);
31 typedef CfResult (*CertChainSpiCreateByArrFunc)(const HcfX509CertificateArray *, HcfX509CertChainSpi **);
32 typedef CfResult (*CertChainSpiCreateByParamsFunc)(const HcfX509CertChainBuildParameters *, HcfX509CertChainSpi **);
33 typedef CfResult (*CreateTrustAnchorWithKeyStoreFunc)(const CfBlob *, const CfBlob *, HcfX509TrustAnchorArray **);
34
35 typedef struct {
36 HcfCertChain base;
37 HcfX509CertChainSpi *spiObj;
38 } CertChainImpl;
39
40 typedef struct {
41 HcfX509CertChainBuildResult base;
42 } CertChainBuildResultImpl;
43
44 typedef struct {
45 CertChainSpiCreateByEncFunc createByEncFunc;
46 CertChainSpiCreateByArrFunc createByArrFunc;
47 CertChainSpiCreateByParamsFunc createByParamsFunc;
48 CreateTrustAnchorWithKeyStoreFunc createTrustAnchorFunc;
49 } HcfCertChainFuncSet;
50
51 typedef struct {
52 char *certType;
53 HcfCertChainFuncSet funcSet;
54 } HcfCertChainAbility;
55
56 static const HcfCertChainAbility X509_CERT_CHAIN_ABILITY_SET[] = { { "X509",
57 { HcfX509CertChainByEncSpiCreate, HcfX509CertChainByArrSpiCreate, HcfX509CertChainByParamsSpiCreate,
58 HcfX509CreateTrustAnchorWithKeyStoreFunc } } };
59
FindAbility(const char * certType)60 static const HcfCertChainFuncSet *FindAbility(const char *certType)
61 {
62 if (certType == NULL) {
63 LOGE("CertType is null!");
64 return NULL;
65 }
66 for (uint32_t i = 0; i < sizeof(X509_CERT_CHAIN_ABILITY_SET) / sizeof(HcfCertChainAbility); i++) {
67 if (strcmp(X509_CERT_CHAIN_ABILITY_SET[i].certType, certType) == 0) {
68 return &(X509_CERT_CHAIN_ABILITY_SET[i].funcSet);
69 }
70 }
71 LOGE("Cert not support! [cert]: %s", certType);
72 return NULL;
73 }
74
GetCertChainClass(void)75 static const char *GetCertChainClass(void)
76 {
77 return "HcfCertChain";
78 }
79
DestroyCertChain(CfObjectBase * self)80 static void DestroyCertChain(CfObjectBase *self)
81 {
82 if (self == NULL) {
83 LOGE("Invalid input parameter.");
84 return;
85 }
86 if (!CfIsClassMatch(self, GetCertChainClass())) {
87 LOGE("Class is not match.");
88 return;
89 }
90 CertChainImpl *impl = (CertChainImpl *)self;
91 CfObjDestroy(impl->spiObj);
92 CfFree(impl);
93 }
94
GetCertList(HcfCertChain * self,HcfX509CertificateArray * out)95 static CfResult GetCertList(HcfCertChain *self, HcfX509CertificateArray *out)
96 {
97 if ((self == NULL) || (out == NULL)) {
98 LOGE("Invalid input parameter.");
99 return CF_INVALID_PARAMS;
100 }
101 if (!CfIsClassMatch((CfObjectBase *)self, GetCertChainClass())) {
102 LOGE("Class is not match.");
103 return CF_INVALID_PARAMS;
104 }
105
106 return ((CertChainImpl *)self)->spiObj->engineGetCertList(((CertChainImpl *)self)->spiObj, out);
107 }
108
ToString(HcfCertChain * self,CfBlob * out)109 static CfResult ToString(HcfCertChain *self, CfBlob *out)
110 {
111 if ((self == NULL) || (out == NULL)) {
112 LOGE("Invalid input parameter.");
113 return CF_INVALID_PARAMS;
114 }
115 if (!CfIsClassMatch((CfObjectBase *)self, GetCertChainClass())) {
116 LOGE("Class is not match.");
117 return CF_INVALID_PARAMS;
118 }
119
120 return ((CertChainImpl *)self)->spiObj->engineToString(((CertChainImpl *)self)->spiObj, out);
121 }
122
HashCode(HcfCertChain * self,CfBlob * out)123 static CfResult HashCode(HcfCertChain *self, CfBlob *out)
124 {
125 if ((self == NULL) || (out == NULL)) {
126 LOGE("Invalid input parameter.");
127 return CF_INVALID_PARAMS;
128 }
129 if (!CfIsClassMatch((CfObjectBase *)self, GetCertChainClass())) {
130 LOGE("Class is not match.");
131 return CF_INVALID_PARAMS;
132 }
133
134 return ((CertChainImpl *)self)->spiObj->engineHashCode(((CertChainImpl *)self)->spiObj, out);
135 }
136
Validate(HcfCertChain * self,const HcfX509CertChainValidateParams * params,HcfX509CertChainValidateResult * result)137 static CfResult Validate(
138 HcfCertChain *self, const HcfX509CertChainValidateParams *params, HcfX509CertChainValidateResult *result)
139 {
140 if ((self == NULL) || (params == NULL) || (result == NULL)) {
141 LOGE("Invalid input parameter.");
142 return CF_INVALID_PARAMS;
143 }
144 if (!CfIsClassMatch((CfObjectBase *)self, GetCertChainClass())) {
145 LOGE("Class is not match.");
146 return CF_INVALID_PARAMS;
147 }
148
149 return ((CertChainImpl *)self)->spiObj->engineValidate(((CertChainImpl *)self)->spiObj, params, result);
150 }
151
HcfCertChainCreate(const CfEncodingBlob * inStream,const HcfX509CertificateArray * inCerts,HcfCertChain ** returnObj)152 CfResult HcfCertChainCreate(
153 const CfEncodingBlob *inStream, const HcfX509CertificateArray *inCerts, HcfCertChain **returnObj)
154 {
155 if ((inStream == NULL && inCerts == NULL) || (inStream != NULL && inCerts != NULL) || returnObj == NULL) {
156 LOGE("invalid param!");
157 return CF_INVALID_PARAMS;
158 }
159
160 const HcfCertChainFuncSet *func = FindAbility("X509");
161 if (func == NULL) {
162 LOGE("Func is null!");
163 return CF_NOT_SUPPORT;
164 }
165
166 HcfX509CertChainSpi *spiObj = NULL;
167 CfResult res = CF_SUCCESS;
168 if (inStream != NULL) {
169 res = func->createByEncFunc(inStream, &spiObj);
170 } else {
171 res = func->createByArrFunc(inCerts, &spiObj);
172 }
173 if (res != CF_SUCCESS) {
174 LOGE("Failed to create certChain spi object!");
175 return res;
176 }
177 CertChainImpl *impl = (CertChainImpl *)CfMalloc(sizeof(CertChainImpl), 0);
178 if (impl == NULL) {
179 LOGE("Failed to allocate return memory!");
180 CfObjDestroy(spiObj);
181 return CF_ERR_MALLOC;
182 }
183 impl->base.base.destroy = DestroyCertChain;
184 impl->base.base.getClass = GetCertChainClass;
185 impl->base.getCertList = GetCertList;
186 impl->base.validate = Validate;
187 impl->base.toString = ToString;
188 impl->base.hashCode = HashCode;
189 impl->spiObj = spiObj;
190
191 *returnObj = (HcfCertChain *)impl;
192 return CF_SUCCESS;
193 }
194
HcfCertChainBuildResultCreate(const HcfX509CertChainBuildParameters * inParams,HcfX509CertChainBuildResult ** returnObj)195 CfResult HcfCertChainBuildResultCreate(
196 const HcfX509CertChainBuildParameters *inParams, HcfX509CertChainBuildResult **returnObj)
197 {
198 if (inParams == NULL || returnObj == NULL) {
199 LOGE("Invalid param!");
200 return CF_INVALID_PARAMS;
201 }
202
203 const HcfCertChainFuncSet *func = FindAbility("X509");
204 if ((func == NULL) || (func->createByParamsFunc == NULL)) {
205 LOGE("Func is null!");
206 return CF_NOT_SUPPORT;
207 }
208 HcfX509CertChainSpi *spiObj = NULL;
209 CfResult res = CF_SUCCESS;
210 res = func->createByParamsFunc(inParams, &spiObj);
211 if (res != CF_SUCCESS) {
212 LOGE("Failed to create certChainBuildResult spi object!");
213 return res;
214 }
215
216 CertChainBuildResultImpl *impl = (CertChainBuildResultImpl *)CfMalloc(sizeof(CertChainBuildResultImpl), 0);
217 if (impl == NULL) {
218 LOGE("Failed to allocate CertChainBuildResultImpl return memory!");
219 CfObjDestroy(spiObj);
220 return CF_ERR_MALLOC;
221 }
222
223 CertChainImpl *implCertChain = (CertChainImpl *)CfMalloc(sizeof(CertChainImpl), 0);
224 if (implCertChain == NULL) {
225 LOGE("Failed to allocate CertChainImpl return memory!");
226 CfObjDestroy(spiObj);
227 CfFree(impl);
228 return CF_ERR_MALLOC;
229 }
230
231 implCertChain->base.base.destroy = DestroyCertChain;
232 implCertChain->base.base.getClass = GetCertChainClass;
233 implCertChain->base.getCertList = GetCertList;
234 implCertChain->base.validate = Validate;
235 implCertChain->spiObj = spiObj;
236 impl->base.base.destroy = DestroyCertChain;
237 impl->base.base.getClass = GetCertChainClass;
238 impl->base.certChain = (HcfCertChain *)implCertChain;
239
240 *returnObj = (HcfX509CertChainBuildResult *)impl;
241 return CF_SUCCESS;
242 }
243
HcfCreateTrustAnchorWithKeyStore(const CfBlob * keyStore,const CfBlob * pwd,HcfX509TrustAnchorArray ** trustAnchorArray)244 CfResult HcfCreateTrustAnchorWithKeyStore(
245 const CfBlob *keyStore, const CfBlob *pwd, HcfX509TrustAnchorArray **trustAnchorArray)
246 {
247 if (keyStore == NULL || pwd == NULL || trustAnchorArray == NULL) {
248 LOGE("invalid param!");
249 return CF_INVALID_PARAMS;
250 }
251
252 const HcfCertChainFuncSet *func = FindAbility("X509");
253 if (func == NULL) {
254 LOGE("Func is null!");
255 return CF_NOT_SUPPORT;
256 }
257
258 return func->createTrustAnchorFunc(keyStore, pwd, trustAnchorArray);
259 }
260