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_crl_entry_openssl.h"
17
18 #include "securec.h"
19
20 #include <openssl/bio.h>
21 #include <openssl/x509.h>
22 #include <openssl/x509v3.h>
23
24 #include "certificate_openssl_common.h"
25 #include "certificate_openssl_class.h"
26 #include "cf_log.h"
27 #include "cf_memory.h"
28 #include "config.h"
29 #include "utils.h"
30 #include "x509_crl.h"
31 #include "x509_crl_entry.h"
32 #include "x509_crl_openssl.h"
33
GetClass(void)34 static const char *GetClass(void)
35 {
36 return "HcfX509CRLEntryOpensslImpl.HcfX509CrlEntry";
37 }
38
GetSelfRev(const HcfX509CrlEntry * self)39 static X509_REVOKED *GetSelfRev(const HcfX509CrlEntry *self)
40 {
41 if (!CfIsClassMatch((CfObjectBase *)self, GetClass())) {
42 LOGE("Input wrong class type!");
43 return NULL;
44 }
45 return ((HcfX509CRLEntryOpensslImpl *)self)->rev;
46 }
47
GetEncoded(HcfX509CrlEntry * self,CfEncodingBlob * encodedOut)48 static CfResult GetEncoded(HcfX509CrlEntry *self, CfEncodingBlob *encodedOut)
49 {
50 if ((self == NULL) || (encodedOut == NULL)) {
51 LOGE("Invalid params for calling GetEncoded!");
52 return CF_INVALID_PARAMS;
53 }
54 X509_REVOKED *rev = GetSelfRev(self);
55 if (rev == NULL) {
56 LOGE("Rev is null!");
57 return CF_INVALID_PARAMS;
58 }
59 unsigned char *out = NULL;
60 int32_t length = i2d_X509_REVOKED(rev, &out);
61 if (length <= 0) {
62 LOGE("Do i2d_X509_REVOKED fail!");
63 CfPrintOpensslError();
64 return CF_ERR_CRYPTO_OPERATION;
65 }
66 encodedOut->data = (uint8_t *)CfMalloc(length, 0);
67 if (encodedOut->data == NULL) {
68 LOGE("Failed to malloc for encodedOut!");
69 OPENSSL_free(out);
70 return CF_ERR_MALLOC;
71 }
72 (void)memcpy_s(encodedOut->data, length, out, length);
73 encodedOut->len = length;
74 encodedOut->encodingFormat = CF_FORMAT_DER;
75 OPENSSL_free(out);
76 return CF_SUCCESS;
77 }
78
GetSerialNumber(HcfX509CrlEntry * self,CfBlob * out)79 static CfResult GetSerialNumber(HcfX509CrlEntry *self, CfBlob *out)
80 {
81 if (self == NULL) {
82 LOGE("Invalid params for calling GetSerialNumber!");
83 return CF_INVALID_PARAMS;
84 }
85 X509_REVOKED *rev = GetSelfRev(self);
86 if (rev == NULL) {
87 LOGE("Rev is null!");
88 return CF_INVALID_PARAMS;
89 }
90 const ASN1_INTEGER *serialNumber = X509_REVOKED_get0_serialNumber(rev);
91 if (serialNumber == NULL) {
92 LOGE("Get serial number fail!");
93 CfPrintOpensslError();
94 return CF_ERR_CRYPTO_OPERATION;
95 }
96
97 unsigned char *serialNumBytes = NULL;
98 int serialNumLen = i2d_ASN1_INTEGER((ASN1_INTEGER *)serialNumber, &serialNumBytes);
99 if (serialNumLen <= SERIAL_NUMBER_HEDER_SIZE) {
100 CfPrintOpensslError();
101 LOGE("get serial num len failed!");
102 return CF_ERR_CRYPTO_OPERATION;
103 }
104
105 out->data = (uint8_t *)CfMalloc(serialNumLen - SERIAL_NUMBER_HEDER_SIZE, 0);
106 if (out->data == NULL) {
107 OPENSSL_free(serialNumBytes);
108 LOGE("Failed to malloc serial num");
109 return CF_ERR_MALLOC;
110 }
111 out->size = (uint32_t)(serialNumLen - SERIAL_NUMBER_HEDER_SIZE);
112 (void)memcpy_s(out->data, out->size, serialNumBytes + SERIAL_NUMBER_HEDER_SIZE, out->size);
113 OPENSSL_free(serialNumBytes);
114 return CF_SUCCESS;
115 }
116
GetCertIssuer(HcfX509CrlEntry * self,CfBlob * encodedOut)117 static CfResult GetCertIssuer(HcfX509CrlEntry *self, CfBlob *encodedOut)
118 {
119 if ((self == NULL) || (encodedOut == NULL)) {
120 LOGE("Invalid params for calling GetCertIssuer!");
121 return CF_INVALID_PARAMS;
122 }
123 if (!CfIsClassMatch((CfObjectBase *)self, GetClass())) {
124 LOGE("Input wrong class type!");
125 return CF_INVALID_PARAMS;
126 }
127 CfBlob *certIssuer = ((HcfX509CRLEntryOpensslImpl *)self)->certIssuer;
128 if (!CfIsBlobValid(certIssuer)) {
129 LOGE("Get certIssuer fail! No certIssuer in CRL entry.");
130 return CF_NOT_SUPPORT;
131 }
132 uint32_t length = certIssuer->size;
133 encodedOut->data = (uint8_t *)CfMalloc(length, 0);
134 if (encodedOut->data == NULL) {
135 LOGE("Failed to malloc for encodedOut!");
136 return CF_ERR_MALLOC;
137 }
138 (void)memcpy_s(encodedOut->data, length, certIssuer->data, length);
139 encodedOut->size = length;
140 return CF_SUCCESS;
141 }
142
GetCertIssuerEx(HcfX509CrlEntry * self,CfEncodinigType encodingType,CfBlob * encodedOut)143 static CfResult GetCertIssuerEx(HcfX509CrlEntry *self, CfEncodinigType encodingType, CfBlob *encodedOut)
144 {
145 if ((self == NULL) || (encodedOut == NULL)) {
146 LOGE("Invalid params for calling GetCertIssuerEx!");
147 return CF_ERR_INTERNAL;
148 }
149 if (encodingType != CF_ENCODING_UTF8) {
150 LOGE("encodingType is not utf8!");
151 return CF_ERR_PARAMETER_CHECK;
152 }
153
154 if (!CfIsClassMatch((CfObjectBase *)self, GetClass())) {
155 LOGE("Input wrong class type!");
156 return CF_ERR_INTERNAL;
157 }
158 CfBlob *certIssuer = ((HcfX509CRLEntryOpensslImpl *)self)->certIssuerUtf8;
159 if (!CfIsBlobValid(certIssuer)) {
160 LOGE("Get certIssuer fail! No certIssuer in CRL entry.");
161 return CF_NOT_SUPPORT;
162 }
163 uint32_t length = certIssuer->size;
164 encodedOut->data = (uint8_t *)CfMalloc(length, 0);
165 if (encodedOut->data == NULL) {
166 LOGE("Failed to malloc for encodedOut!");
167 return CF_ERR_MALLOC;
168 }
169 (void)memcpy_s(encodedOut->data, length, certIssuer->data, length);
170 encodedOut->size = length;
171 return CF_SUCCESS;
172 }
173
GetCertIssuerDer(HcfX509CrlEntry * self,CfBlob * encodedOut)174 static CfResult GetCertIssuerDer(HcfX509CrlEntry *self, CfBlob *encodedOut)
175 {
176 if ((self == NULL) || (encodedOut == NULL)) {
177 LOGE("Invalid params for calling GetCertIssuerEx!");
178 return CF_ERR_INTERNAL;
179 }
180
181 if (!CfIsClassMatch((CfObjectBase *)self, GetClass())) {
182 LOGE("Input wrong class type!");
183 return CF_ERR_INTERNAL;
184 }
185 X509_CRL *crl = ((HcfX509CRLEntryOpensslImpl *)self)->crl;
186 X509_NAME *x509Name = X509_CRL_get_issuer(crl);
187 if (x509Name == NULL) {
188 LOGE("Failed to get issuer name!");
189 CfPrintOpensslError();
190 return CF_ERR_INTERNAL;
191 }
192
193 int32_t size = i2d_X509_NAME(x509Name, &(encodedOut->data));
194 if (size <= 0) {
195 LOGE("Failed to get subject DER data!");
196 CfPrintOpensslError();
197 return CF_ERR_CRYPTO_OPERATION;
198 }
199 encodedOut->size = (uint32_t)size;
200 return CF_SUCCESS;
201 }
202
GetRevocationDate(HcfX509CrlEntry * self,CfBlob * out)203 static CfResult GetRevocationDate(HcfX509CrlEntry *self, CfBlob *out)
204 {
205 if ((self == NULL) || (out == NULL)) {
206 LOGE("invalid params for calling GetRevocationDate!");
207 return CF_INVALID_PARAMS;
208 }
209 X509_REVOKED *rev = GetSelfRev(self);
210 if (rev == NULL) {
211 LOGE("Rev is null!");
212 return CF_INVALID_PARAMS;
213 }
214 const ASN1_TIME *time = X509_REVOKED_get0_revocationDate(rev);
215 if (time == NULL) {
216 LOGE("Get revocation date fail!");
217 CfPrintOpensslError();
218 return CF_ERR_CRYPTO_OPERATION;
219 }
220 const char *revTime = (const char *)(time->data);
221 if ((revTime == NULL) || (strlen(revTime) > HCF_MAX_STR_LEN)) {
222 LOGE("Get revocation date from ASN1_TIME fail!");
223 return CF_ERR_CRYPTO_OPERATION;
224 }
225 uint32_t length = strlen(revTime) + 1;
226 out->data = (uint8_t *)CfMalloc(length, 0);
227 if (out->data == NULL) {
228 LOGE("Failed to malloc for revTime!");
229 return CF_ERR_MALLOC;
230 }
231 (void)memcpy_s(out->data, length, revTime, length);
232 out->size = length;
233 return CF_SUCCESS;
234 }
235
GetExtensions(HcfX509CrlEntry * self,CfBlob * outBlob)236 static CfResult GetExtensions(HcfX509CrlEntry *self, CfBlob *outBlob)
237 {
238 if ((self == NULL) || (outBlob == NULL)) {
239 LOGE("Invalid params!");
240 return CF_INVALID_PARAMS;
241 }
242
243 X509_REVOKED *rev = GetSelfRev(self);
244 if (rev == NULL) {
245 LOGE("Rev is null!");
246 return CF_INVALID_PARAMS;
247 }
248
249 X509_EXTENSIONS *exts = (X509_EXTENSIONS *)X509_REVOKED_get0_extensions(rev);
250 CfResult ret = CopyExtensionsToBlob(exts, outBlob);
251 if (ret != CF_SUCCESS) {
252 CfPrintOpensslError();
253 }
254 return ret;
255 }
256
HasExtensions(HcfX509CrlEntry * self,bool * out)257 static CfResult HasExtensions(HcfX509CrlEntry *self, bool *out)
258 {
259 if (self == NULL || out == NULL) {
260 LOGE("Invalid params!");
261 return CF_INVALID_PARAMS;
262 }
263
264 X509_REVOKED *rev = GetSelfRev(self);
265 if (rev == NULL) {
266 LOGE("Rev is null!");
267 return CF_INVALID_PARAMS;
268 }
269
270 X509_EXTENSIONS *exts = (X509_EXTENSIONS *)X509_REVOKED_get0_extensions(rev);
271 if (exts == NULL) {
272 *out = false;
273 } else {
274 *out = (sk_X509_EXTENSION_num(exts) > 0);
275 }
276
277 return CF_SUCCESS;
278 }
279
ToString(HcfX509CrlEntry * self,CfBlob * outBlob)280 static CfResult ToString(HcfX509CrlEntry *self, CfBlob *outBlob)
281 {
282 if ((self == NULL) || (outBlob == NULL)) {
283 LOGE("Invalid params!");
284 return CF_INVALID_PARAMS;
285 }
286 X509_REVOKED *rev = GetSelfRev(self);
287 if (rev == NULL) {
288 LOGE("Rev is null!");
289 return CF_INVALID_PARAMS;
290 }
291
292 BIO *out = BIO_new(BIO_s_mem());
293 if (out == NULL) {
294 LOGE("BIO_new error");
295 return CF_ERR_MALLOC;
296 }
297 BIO_printf(out, " Serial Number: ");
298 i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(rev));
299 BIO_printf(out, "\n Revocation Date: ");
300 ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(rev));
301 BIO_printf(out, "\n");
302 int len = X509V3_extensions_print(out, "CRL entry extensions", X509_REVOKED_get0_extensions(rev), 0, 8);
303 if (len <= 0) {
304 LOGE("X509V3_extensions_print error");
305 BIO_free(out);
306 return CF_ERR_CRYPTO_OPERATION;
307 }
308 BUF_MEM *bufMem = NULL;
309 if (BIO_get_mem_ptr(out, &bufMem) > 0 && bufMem != NULL) {
310 CfResult res = DeepCopyDataToOut(bufMem->data, bufMem->length, outBlob);
311 BIO_free(out);
312 return res;
313 }
314 BIO_free(out);
315 LOGE("BIO_get_mem_ptr error");
316 return CF_ERR_CRYPTO_OPERATION;
317 }
318
HashCode(HcfX509CrlEntry * self,CfBlob * outBlob)319 static CfResult HashCode(HcfX509CrlEntry *self, CfBlob *outBlob)
320 {
321 if ((self == NULL) || (outBlob == NULL)) {
322 LOGE("Invalid params!");
323 return CF_INVALID_PARAMS;
324 }
325 X509_REVOKED *rev = GetSelfRev(self);
326 if (rev == NULL) {
327 LOGE("Rev is null!");
328 return CF_INVALID_PARAMS;
329 }
330
331 unsigned char *buf = NULL;
332 int len = i2d_X509_REVOKED(rev, &buf);
333 if (len < 0 || buf == NULL) {
334 LOGE("i2d_X509_REVOKED error");
335 return CF_ERR_CRYPTO_OPERATION;
336 }
337
338 outBlob->data = (uint8_t *)CfMalloc(SHA256_DIGEST_LENGTH, 0);
339 if (outBlob->data == NULL) {
340 LOGE("CfMalloc error");
341 OPENSSL_free(buf);
342 return CF_ERR_MALLOC;
343 }
344 if (SHA256(buf, len, (unsigned char *)outBlob->data) == NULL) {
345 LOGE("Compute sha256 error");
346 OPENSSL_free(buf);
347 CfFree(outBlob->data);
348 outBlob->data = NULL;
349 return CF_ERR_CRYPTO_OPERATION;
350 }
351 outBlob->size = SHA256_DIGEST_LENGTH;
352 OPENSSL_free(buf);
353 return CF_SUCCESS;
354 }
355
GetExtensionsObject(HcfX509CrlEntry * self,CfBlob * outBlob)356 static CfResult GetExtensionsObject(HcfX509CrlEntry *self, CfBlob *outBlob)
357 {
358 if ((self == NULL) || (outBlob == NULL)) {
359 LOGE("Invalid params!");
360 return CF_INVALID_PARAMS;
361 }
362
363 X509_REVOKED *rev = GetSelfRev(self);
364 if (rev == NULL) {
365 LOGE("Rev is null!");
366 return CF_INVALID_PARAMS;
367 }
368 int len = i2d_X509_EXTENSIONS(X509_REVOKED_get0_extensions(rev), &outBlob->data);
369 if (len < 0) {
370 LOGE("i2d_X509_EXTENSIONS error");
371 return CF_ERR_CRYPTO_OPERATION;
372 }
373 outBlob->size = len;
374 return CF_SUCCESS;
375 }
376
DeepCopyCertIssuer(HcfX509CRLEntryOpensslImpl * returnCRLEntry,CfBlob * certIssuer)377 static CfResult DeepCopyCertIssuer(HcfX509CRLEntryOpensslImpl *returnCRLEntry, CfBlob *certIssuer)
378 {
379 returnCRLEntry->certIssuer = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
380 if (returnCRLEntry->certIssuer == NULL) {
381 LOGE("Failed to malloc certIssuer!");
382 return CF_ERR_MALLOC;
383 }
384 returnCRLEntry->certIssuer->size = certIssuer->size;
385 returnCRLEntry->certIssuer->data = (uint8_t *)CfMalloc(certIssuer->size, 0);
386 if (returnCRLEntry->certIssuer->data == NULL) {
387 LOGE("Failed to malloc certIssuer data!");
388 CfBlobFree(&returnCRLEntry->certIssuer);
389 return CF_ERR_MALLOC;
390 }
391 (void)memcpy_s(returnCRLEntry->certIssuer->data, certIssuer->size, certIssuer->data, certIssuer->size);
392 return CF_SUCCESS;
393 }
394
DeepCopyCertIssuerUtf8(HcfX509CRLEntryOpensslImpl * returnCRLEntry,CfBlob * certIssuerUtf8)395 static CfResult DeepCopyCertIssuerUtf8(HcfX509CRLEntryOpensslImpl *returnCRLEntry, CfBlob *certIssuerUtf8)
396 {
397 returnCRLEntry->certIssuerUtf8 = (CfBlob *)CfMalloc(sizeof(CfBlob), 0);
398 if (returnCRLEntry->certIssuerUtf8 == NULL) {
399 LOGE("Failed to malloc certIssuerUtf8!");
400 return CF_ERR_MALLOC;
401 }
402 returnCRLEntry->certIssuerUtf8->size = certIssuerUtf8->size;
403 returnCRLEntry->certIssuerUtf8->data = (uint8_t *)CfMalloc(certIssuerUtf8->size, 0);
404 if (returnCRLEntry->certIssuerUtf8->data == NULL) {
405 LOGE("Failed to malloc certIssuerUtf8 data!");
406 CfBlobFree(&returnCRLEntry->certIssuerUtf8);
407 return CF_ERR_MALLOC;
408 }
409 (void)memcpy_s(returnCRLEntry->certIssuerUtf8->data, certIssuerUtf8->size, certIssuerUtf8->data,
410 certIssuerUtf8->size);
411 return CF_SUCCESS;
412 }
413
Destroy(CfObjectBase * self)414 static void Destroy(CfObjectBase *self)
415 {
416 if (self == NULL) {
417 LOGE("Invalid params!");
418 return;
419 }
420 if (!CfIsClassMatch((CfObjectBase *)self, GetClass())) {
421 LOGE("Input wrong class type!");
422 return;
423 }
424 HcfX509CRLEntryOpensslImpl *realCrlEntry = (HcfX509CRLEntryOpensslImpl *)self;
425 if (realCrlEntry->rev != NULL) {
426 X509_REVOKED_free(realCrlEntry->rev);
427 realCrlEntry->rev = NULL;
428 }
429 if (realCrlEntry->certIssuer != NULL) {
430 CfFree(realCrlEntry->certIssuer->data);
431 realCrlEntry->certIssuer->data = NULL;
432 CfFree(realCrlEntry->certIssuer);
433 realCrlEntry->certIssuer = NULL;
434 }
435 if (realCrlEntry->certIssuerUtf8 != NULL) {
436 CfFree(realCrlEntry->certIssuerUtf8->data);
437 realCrlEntry->certIssuerUtf8->data = NULL;
438 CfFree(realCrlEntry->certIssuerUtf8);
439 realCrlEntry->certIssuerUtf8 = NULL;
440 }
441 CfFree(realCrlEntry);
442 }
443
HcfCX509CRLEntryCreate(X509_REVOKED * rev,HcfX509CrlEntry ** crlEntryOut,CfBlob * certIssuer,CfBlob * certIssuerUtf8,X509_CRL * crl)444 CfResult HcfCX509CRLEntryCreate(X509_REVOKED *rev, HcfX509CrlEntry **crlEntryOut, CfBlob *certIssuer,
445 CfBlob *certIssuerUtf8, X509_CRL *crl)
446 {
447 if ((rev == NULL) || (crlEntryOut == NULL) || certIssuer == NULL) {
448 LOGE("Invalid params!");
449 return CF_INVALID_PARAMS;
450 }
451 HcfX509CRLEntryOpensslImpl *returnCRLEntry = (HcfX509CRLEntryOpensslImpl *)CfMalloc(
452 sizeof(HcfX509CRLEntryOpensslImpl), 0);
453 if (returnCRLEntry == NULL) {
454 LOGE("Failed to malloc for x509 entry instance!");
455 return CF_ERR_MALLOC;
456 }
457
458 X509_REVOKED *tmp = X509_REVOKED_dup(rev);
459 if (tmp == NULL) {
460 CfFree(returnCRLEntry);
461 returnCRLEntry = NULL;
462 LOGE("Failed to dup x509 revoked");
463 return CF_ERR_MALLOC;
464 }
465 returnCRLEntry->rev = tmp;
466 returnCRLEntry->certIssuer = NULL;
467 returnCRLEntry->certIssuerUtf8 = NULL;
468 returnCRLEntry->crl = crl;
469 returnCRLEntry->base.base.getClass = GetClass;
470 returnCRLEntry->base.base.destroy = Destroy;
471 returnCRLEntry->base.getEncoded = GetEncoded;
472 returnCRLEntry->base.getSerialNumber = GetSerialNumber;
473 returnCRLEntry->base.getCertIssuer = GetCertIssuer;
474 returnCRLEntry->base.getCertIssuerEx = GetCertIssuerEx;
475 returnCRLEntry->base.getCertIssuerDer = GetCertIssuerDer;
476 returnCRLEntry->base.getRevocationDate = GetRevocationDate;
477 returnCRLEntry->base.getExtensions = GetExtensions;
478 returnCRLEntry->base.hasExtensions = HasExtensions;
479 returnCRLEntry->base.toString = ToString;
480 returnCRLEntry->base.hashCode = HashCode;
481 returnCRLEntry->base.getExtensionsObject = GetExtensionsObject;
482 if (DeepCopyCertIssuer(returnCRLEntry, certIssuer) != CF_SUCCESS) {
483 LOGI("No cert issuer find or deep copy cert issuer fail!");
484 }
485 if (DeepCopyCertIssuerUtf8(returnCRLEntry, certIssuerUtf8) != CF_SUCCESS) {
486 LOGI("No cert utf8 issuer find or deep copy cert utf8 issuer fail!");
487 }
488 *crlEntryOut = (HcfX509CrlEntry *)returnCRLEntry;
489 return CF_SUCCESS;
490 }
491