1 /*
2 * Copyright (C) 2022 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_certificate.h"
17
18 #include <securec.h>
19
20 #include "config.h"
21 #include "fwk_class.h"
22 #include "x509_certificate_openssl.h"
23 #include "log.h"
24 #include "memory.h"
25 #include "utils.h"
26
27 typedef HcfResult (*HcfX509CertificateSpiCreateFunc)(const HcfEncodingBlob *, HcfX509CertificateSpi **);
28
29 typedef struct {
30 HcfX509CertificateSpiCreateFunc createFunc;
31 } HcfX509CertificateFuncSet;
32
33 typedef struct {
34 char *certType;
35 HcfX509CertificateFuncSet funcSet;
36 } HcfCCertFactoryAbility;
37
GetX509CertificateClass(void)38 static const char *GetX509CertificateClass(void)
39 {
40 return HCF_X509_CERTIFICATE_CLASS;
41 }
42
43 static const HcfCCertFactoryAbility X509_CERTIFICATE_ABILITY_SET[] = {
44 { "X509", { OpensslX509CertSpiCreate, } }
45 };
46
FindAbility(const char * certType)47 static const HcfX509CertificateFuncSet *FindAbility(const char *certType)
48 {
49 if (certType == NULL) {
50 LOGE("CertType is null!");
51 return NULL;
52 }
53 for (uint32_t i = 0; i < sizeof(X509_CERTIFICATE_ABILITY_SET) / sizeof(HcfCCertFactoryAbility); i++) {
54 if (strcmp(X509_CERTIFICATE_ABILITY_SET[i].certType, certType) == 0) {
55 return &(X509_CERTIFICATE_ABILITY_SET[i].funcSet);
56 }
57 }
58 LOGE("Cert not support! [cert]: %s", certType);
59 return NULL;
60 }
61
DestroyX509Certificate(HcfObjectBase * self)62 static void DestroyX509Certificate(HcfObjectBase *self)
63 {
64 if (self == NULL) {
65 LOGE("Invalid input parameter.");
66 return;
67 }
68 if (!IsClassMatch(self, GetX509CertificateClass())) {
69 LOGE("Class is not match.");
70 return;
71 }
72 HcfX509CertificateImpl *impl = (HcfX509CertificateImpl *)self;
73 HcfObjDestroy(impl->spiObj);
74 HcfFree(impl);
75 }
76
Verify(HcfCertificate * self,HcfPubKey * key)77 static HcfResult Verify(HcfCertificate *self, HcfPubKey *key)
78 {
79 if ((self == NULL) || (key == NULL)) {
80 LOGE("Invalid input parameter.");
81 return HCF_INVALID_PARAMS;
82 }
83 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
84 LOGE("Class is not match.");
85 return HCF_INVALID_PARAMS;
86 }
87 return ((HcfX509CertificateImpl *)self)->spiObj->engineVerify(
88 ((HcfX509CertificateImpl *)self)->spiObj, key);
89 }
90
GetEncoded(HcfCertificate * self,HcfEncodingBlob * encodedByte)91 static HcfResult GetEncoded(HcfCertificate *self, HcfEncodingBlob *encodedByte)
92 {
93 if ((self == NULL) || (encodedByte == NULL)) {
94 LOGE("Invalid input parameter.");
95 return HCF_INVALID_PARAMS;
96 }
97 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
98 LOGE("Class is not match.");
99 return HCF_INVALID_PARAMS;
100 }
101 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetEncoded(
102 ((HcfX509CertificateImpl *)self)->spiObj, encodedByte);
103 }
104
GetPublicKey(HcfCertificate * self,HcfPubKey ** keyOut)105 static HcfResult GetPublicKey(HcfCertificate *self, HcfPubKey **keyOut)
106 {
107 if ((self == NULL) || (keyOut == NULL)) {
108 LOGE("Invalid input parameter.");
109 return HCF_INVALID_PARAMS;
110 }
111 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
112 LOGE("Class is not match.");
113 return HCF_INVALID_PARAMS;
114 }
115 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetPublicKey(
116 ((HcfX509CertificateImpl *)self)->spiObj, keyOut);
117 }
118
CheckValidityWithDate(HcfX509Certificate * self,const char * date)119 static HcfResult CheckValidityWithDate(HcfX509Certificate *self, const char *date)
120 {
121 if ((self == NULL) || (date == NULL)) {
122 LOGE("Invalid input parameter.");
123 return HCF_INVALID_PARAMS;
124 }
125 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
126 LOGE("Class is not match.");
127 return HCF_INVALID_PARAMS;
128 }
129 return ((HcfX509CertificateImpl *)self)->spiObj->engineCheckValidityWithDate(
130 ((HcfX509CertificateImpl *)self)->spiObj, date);
131 }
132
GetVersion(HcfX509Certificate * self)133 static long GetVersion(HcfX509Certificate *self)
134 {
135 if (self == NULL) {
136 LOGE("Invalid input parameter.");
137 return INVALID_VERSION;
138 }
139 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
140 LOGE("Class is not match.");
141 return INVALID_VERSION;
142 }
143 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetVersion(
144 ((HcfX509CertificateImpl *)self)->spiObj);
145 }
146
GetSerialNumber(HcfX509Certificate * self)147 static long GetSerialNumber(HcfX509Certificate *self)
148 {
149 if (self == NULL) {
150 LOGE("Invalid input parameter.");
151 return INVALID_SERIAL_NUMBER;
152 }
153 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
154 LOGE("Class is not match.");
155 return INVALID_SERIAL_NUMBER;
156 }
157 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSerialNumber(
158 ((HcfX509CertificateImpl *)self)->spiObj);
159 }
160
GetIssuerName(HcfX509Certificate * self,HcfBlob * out)161 static HcfResult GetIssuerName(HcfX509Certificate *self, HcfBlob *out)
162 {
163 if ((self == NULL) || (out == NULL)) {
164 LOGE("Invalid input parameter.");
165 return HCF_INVALID_PARAMS;
166 }
167 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
168 LOGE("Class is not match.");
169 return HCF_INVALID_PARAMS;
170 }
171 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetIssuerName(
172 ((HcfX509CertificateImpl *)self)->spiObj, out);
173 }
174
GetSubjectName(HcfX509Certificate * self,HcfBlob * out)175 static HcfResult GetSubjectName(HcfX509Certificate *self, HcfBlob *out)
176 {
177 if ((self == NULL) || (out == NULL)) {
178 LOGE("Invalid input parameter.");
179 return HCF_INVALID_PARAMS;
180 }
181 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
182 LOGE("Class is not match.");
183 return HCF_INVALID_PARAMS;
184 }
185 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSubjectName(
186 ((HcfX509CertificateImpl *)self)->spiObj, out);
187 }
188
GetNotBeforeTime(HcfX509Certificate * self,HcfBlob * outDate)189 static HcfResult GetNotBeforeTime(HcfX509Certificate *self, HcfBlob *outDate)
190 {
191 if ((self == NULL) || (outDate == NULL)) {
192 LOGE("Invalid input parameter.");
193 return HCF_INVALID_PARAMS;
194 }
195 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
196 LOGE("Class is not match.");
197 return HCF_INVALID_PARAMS;
198 }
199 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetNotBeforeTime(
200 ((HcfX509CertificateImpl *)self)->spiObj, outDate);
201 }
202
GetNotAfterTime(HcfX509Certificate * self,HcfBlob * outDate)203 static HcfResult GetNotAfterTime(HcfX509Certificate *self, HcfBlob *outDate)
204 {
205 if ((self == NULL) || (outDate == NULL)) {
206 LOGE("Invalid input parameter.");
207 return HCF_INVALID_PARAMS;
208 }
209 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
210 LOGE("Class is not match.");
211 return HCF_INVALID_PARAMS;
212 }
213 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetNotAfterTime(
214 ((HcfX509CertificateImpl *)self)->spiObj, outDate);
215 }
216
GetSignature(HcfX509Certificate * self,HcfBlob * sigOut)217 static HcfResult GetSignature(HcfX509Certificate *self, HcfBlob *sigOut)
218 {
219 if ((self == NULL) || (sigOut == NULL)) {
220 LOGE("Invalid input parameter.");
221 return HCF_INVALID_PARAMS;
222 }
223 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
224 LOGE("Class is not match.");
225 return HCF_INVALID_PARAMS;
226 }
227 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignature(
228 ((HcfX509CertificateImpl *)self)->spiObj, sigOut);
229 }
230
GetSignatureAlgName(HcfX509Certificate * self,HcfBlob * outName)231 static HcfResult GetSignatureAlgName(HcfX509Certificate *self, HcfBlob *outName)
232 {
233 if ((self == NULL) || (outName == NULL)) {
234 LOGE("Invalid input parameter.");
235 return HCF_INVALID_PARAMS;
236 }
237 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
238 LOGE("Class is not match.");
239 return HCF_INVALID_PARAMS;
240 }
241 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignatureAlgName(
242 ((HcfX509CertificateImpl *)self)->spiObj, outName);
243 }
244
GetSignatureAlgOid(HcfX509Certificate * self,HcfBlob * out)245 static HcfResult GetSignatureAlgOid(HcfX509Certificate *self, HcfBlob *out)
246 {
247 if ((self == NULL) || (out == NULL)) {
248 LOGE("Invalid input parameter.");
249 return HCF_INVALID_PARAMS;
250 }
251 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
252 LOGE("Class is not match.");
253 return HCF_INVALID_PARAMS;
254 }
255 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignatureAlgOid(
256 ((HcfX509CertificateImpl *)self)->spiObj, out);
257 }
258
GetSignatureAlgParams(HcfX509Certificate * self,HcfBlob * sigAlgParamsOut)259 static HcfResult GetSignatureAlgParams(HcfX509Certificate *self, HcfBlob *sigAlgParamsOut)
260 {
261 if ((self == NULL) || (sigAlgParamsOut == NULL)) {
262 LOGE("Invalid input parameter.");
263 return HCF_INVALID_PARAMS;
264 }
265 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
266 LOGE("Class is not match.");
267 return HCF_INVALID_PARAMS;
268 }
269 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSignatureAlgParams(
270 ((HcfX509CertificateImpl *)self)->spiObj, sigAlgParamsOut);
271 }
272
GetKeyUsage(HcfX509Certificate * self,HcfBlob * boolArr)273 static HcfResult GetKeyUsage(HcfX509Certificate *self, HcfBlob *boolArr)
274 {
275 if ((self == NULL) || (boolArr == NULL)) {
276 LOGE("Invalid input parameter.");
277 return HCF_INVALID_PARAMS;
278 }
279 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
280 LOGE("Class is not match.");
281 return HCF_INVALID_PARAMS;
282 }
283 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetKeyUsage(
284 ((HcfX509CertificateImpl *)self)->spiObj, boolArr);
285 }
286
GetExtKeyUsage(HcfX509Certificate * self,HcfArray * keyUsageOut)287 static HcfResult GetExtKeyUsage(HcfX509Certificate *self, HcfArray *keyUsageOut)
288 {
289 if ((self == NULL) || (keyUsageOut == NULL)) {
290 LOGE("Invalid input parameter.");
291 return HCF_INVALID_PARAMS;
292 }
293 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
294 LOGE("Class is not match.");
295 return HCF_INVALID_PARAMS;
296 }
297 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetExtKeyUsage(
298 ((HcfX509CertificateImpl *)self)->spiObj, keyUsageOut);
299 }
300
GetBasicConstraints(HcfX509Certificate * self)301 static int32_t GetBasicConstraints(HcfX509Certificate *self)
302 {
303 if (self == NULL) {
304 LOGE("Invalid input parameter.");
305 return INVALID_CONSTRAINTS_LEN;
306 }
307 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
308 LOGE("Class is not match.");
309 return INVALID_CONSTRAINTS_LEN;
310 }
311 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetBasicConstraints(
312 ((HcfX509CertificateImpl *)self)->spiObj);
313 }
314
GetSubjectAltNames(HcfX509Certificate * self,HcfArray * outName)315 static HcfResult GetSubjectAltNames(HcfX509Certificate *self, HcfArray *outName)
316 {
317 if ((self == NULL) || (outName == NULL)) {
318 LOGE("Invalid input parameter.");
319 return HCF_INVALID_PARAMS;
320 }
321 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
322 LOGE("Class is not match.");
323 return HCF_INVALID_PARAMS;
324 }
325 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetSubjectAltNames(
326 ((HcfX509CertificateImpl *)self)->spiObj, outName);
327 }
328
GetIssuerAltNames(HcfX509Certificate * self,HcfArray * outName)329 static HcfResult GetIssuerAltNames(HcfX509Certificate *self, HcfArray *outName)
330 {
331 if ((self == NULL) || (outName == NULL)) {
332 LOGE("Invalid input parameter.");
333 return HCF_INVALID_PARAMS;
334 }
335 if (!IsClassMatch((HcfObjectBase *)self, GetX509CertificateClass())) {
336 LOGE("Class is not match.");
337 return HCF_INVALID_PARAMS;
338 }
339 return ((HcfX509CertificateImpl *)self)->spiObj->engineGetIssuerAltNames(
340 ((HcfX509CertificateImpl *)self)->spiObj, outName);
341 }
342
HcfX509CertificateCreate(const HcfEncodingBlob * inStream,HcfX509Certificate ** returnObj)343 HcfResult HcfX509CertificateCreate(const HcfEncodingBlob *inStream, HcfX509Certificate **returnObj)
344 {
345 if ((inStream == NULL) || (inStream->len > HCF_MAX_BUFFER_LEN) || (returnObj == NULL)) {
346 return HCF_INVALID_PARAMS;
347 }
348 const HcfX509CertificateFuncSet *funcSet = FindAbility("X509");
349 if (funcSet == NULL) {
350 return HCF_NOT_SUPPORT;
351 }
352 HcfX509CertificateSpi *spiObj = NULL;
353 HcfResult res = funcSet->createFunc(inStream, &spiObj);
354 if (res != HCF_SUCCESS) {
355 LOGE("Failed to create spi object!");
356 return res;
357 }
358 HcfX509CertificateImpl *x509CertImpl = (HcfX509CertificateImpl *)HcfMalloc(sizeof(HcfX509CertificateImpl), 0);
359 if (x509CertImpl == NULL) {
360 LOGE("Failed to allocate x509CertImpl memory!");
361 return HCF_ERR_MALLOC;
362 }
363 x509CertImpl->base.base.base.getClass = GetX509CertificateClass;
364 x509CertImpl->base.base.base.destroy = DestroyX509Certificate;
365 x509CertImpl->base.base.verify = Verify;
366 x509CertImpl->base.base.getEncoded = GetEncoded;
367 x509CertImpl->base.base.getPublicKey = GetPublicKey;
368 x509CertImpl->base.checkValidityWithDate = CheckValidityWithDate;
369 x509CertImpl->base.getVersion = GetVersion;
370 x509CertImpl->base.getSerialNumber = GetSerialNumber;
371 x509CertImpl->base.getIssuerName = GetIssuerName;
372 x509CertImpl->base.getSubjectName = GetSubjectName;
373 x509CertImpl->base.getNotBeforeTime = GetNotBeforeTime;
374 x509CertImpl->base.getNotAfterTime = GetNotAfterTime;
375 x509CertImpl->base.getSignature = GetSignature;
376 x509CertImpl->base.getSignatureAlgName = GetSignatureAlgName;
377 x509CertImpl->base.getSignatureAlgOid = GetSignatureAlgOid;
378 x509CertImpl->base.getSignatureAlgParams = GetSignatureAlgParams;
379 x509CertImpl->base.getKeyUsage = GetKeyUsage;
380 x509CertImpl->base.getExtKeyUsage = GetExtKeyUsage;
381 x509CertImpl->base.getBasicConstraints = GetBasicConstraints;
382 x509CertImpl->base.getSubjectAltNames = GetSubjectAltNames;
383 x509CertImpl->base.getIssuerAltNames = GetIssuerAltNames;
384
385 x509CertImpl->spiObj = spiObj;
386 *returnObj = (HcfX509Certificate *)x509CertImpl;
387 return HCF_SUCCESS;
388 }