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