• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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