1 /*
2 * Copyright (c) 2023 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
23 #include "certificate_openssl_common.h"
24 #include "cf_log.h"
25 #include "cf_memory.h"
26 #include "config.h"
27 #include "utils.h"
28 #include "x509_crl.h"
29 #include "x509_crl_entry.h"
30 #include "x509_crl_openssl.h"
31
32 #define OPENSSL_ERROR_SERIAL_NUMBER (-1)
33
34 typedef struct {
35 HcfX509CrlEntry base;
36 X509_REVOKED *rev;
37 CfBlob *certIssuer;
38 } HcfX509CRLEntryOpensslImpl;
39
GetClass(void)40 static const char *GetClass(void)
41 {
42 return "HcfX509CRLEntryOpensslImpl.HcfX509CrlEntry";
43 }
44
GetSelfRev(const HcfX509CrlEntry * self)45 static X509_REVOKED *GetSelfRev(const HcfX509CrlEntry *self)
46 {
47 if (!IsClassMatch((CfObjectBase *)self, GetClass())) {
48 LOGE("Input wrong class type!");
49 return NULL;
50 }
51 return ((HcfX509CRLEntryOpensslImpl *)self)->rev;
52 }
53
GetEncoded(HcfX509CrlEntry * self,CfEncodingBlob * encodedOut)54 static CfResult GetEncoded(HcfX509CrlEntry *self, CfEncodingBlob *encodedOut)
55 {
56 if ((self == NULL) || (encodedOut == NULL)) {
57 LOGE("Invalid Paramas for calling GetEncoded!");
58 return CF_INVALID_PARAMS;
59 }
60 X509_REVOKED *rev = GetSelfRev(self);
61 if (rev == NULL) {
62 LOGE("Rev is null!");
63 return CF_INVALID_PARAMS;
64 }
65 unsigned char *out = NULL;
66 int32_t length = i2d_X509_REVOKED(rev, &out);
67 if (length <= 0) {
68 LOGE("Do i2d_X509_REVOKED fail!");
69 CfPrintOpensslError();
70 return CF_ERR_CRYPTO_OPERATION;
71 }
72 encodedOut->data = (uint8_t *)HcfMalloc(length, 0);
73 if (encodedOut->data == NULL) {
74 LOGE("Failed to malloc for encodedOut!");
75 OPENSSL_free(out);
76 return CF_ERR_MALLOC;
77 }
78 (void)memcpy_s(encodedOut->data, length, out, length);
79 encodedOut->len = length;
80 encodedOut->encodingFormat = CF_FORMAT_DER;
81 OPENSSL_free(out);
82 return CF_SUCCESS;
83 }
84
GetSerialNumber(HcfX509CrlEntry * self,CfBlob * out)85 static CfResult GetSerialNumber(HcfX509CrlEntry *self, CfBlob *out)
86 {
87 if (self == NULL) {
88 LOGE("Invalid Paramas for calling GetSerialNumber!");
89 return CF_INVALID_PARAMS;
90 }
91 X509_REVOKED *rev = GetSelfRev(self);
92 if (rev == NULL) {
93 LOGE("Rev is null!");
94 return CF_INVALID_PARAMS;
95 }
96 const ASN1_INTEGER *serialNumber = X509_REVOKED_get0_serialNumber(rev);
97 if (serialNumber == NULL) {
98 LOGE("Get serial number fail!");
99 CfPrintOpensslError();
100 return CF_ERR_CRYPTO_OPERATION;
101 }
102
103 unsigned char *serialNumBytes = NULL;
104 int serialNumLen = i2d_ASN1_INTEGER((ASN1_INTEGER *)serialNumber, &serialNumBytes);
105 if (serialNumLen <= SERIAL_NUMBER_HEDER_SIZE) {
106 CfPrintOpensslError();
107 LOGE("get serial num len failed!");
108 return CF_ERR_CRYPTO_OPERATION;
109 }
110
111 out->data = (uint8_t *)HcfMalloc(serialNumLen - SERIAL_NUMBER_HEDER_SIZE, 0);
112 if (out->data == NULL) {
113 OPENSSL_free(&serialNumBytes);
114 LOGE("Failed to malloc serial num");
115 return CF_ERR_MALLOC;
116 }
117 out->size = (uint32_t)(serialNumLen - SERIAL_NUMBER_HEDER_SIZE);
118 (void)memcpy_s(out->data, out->size, serialNumBytes + SERIAL_NUMBER_HEDER_SIZE, out->size);
119 OPENSSL_free(serialNumBytes);
120 return CF_SUCCESS;
121 }
122
GetCertIssuer(HcfX509CrlEntry * self,CfBlob * encodedOut)123 static CfResult GetCertIssuer(HcfX509CrlEntry *self, CfBlob *encodedOut)
124 {
125 if ((self == NULL) || (encodedOut == NULL)) {
126 LOGE("Invalid Paramas for calling GetCertIssuer!");
127 return CF_INVALID_PARAMS;
128 }
129 if (!IsClassMatch((CfObjectBase *)self, GetClass())) {
130 LOGE("Input wrong class type!");
131 return CF_INVALID_PARAMS;
132 }
133 CfBlob *certIssuer = ((HcfX509CRLEntryOpensslImpl *)self)->certIssuer;
134 if (!IsBlobValid(certIssuer)) {
135 LOGE("Get certIssuer fail! No certIssuer in CRL entry.");
136 return CF_NOT_SUPPORT;
137 }
138 uint32_t length = certIssuer->size;
139 encodedOut->data = (uint8_t *)HcfMalloc(length, 0);
140 if (encodedOut->data == NULL) {
141 LOGE("Failed to malloc for encodedOut!");
142 return CF_ERR_MALLOC;
143 }
144 (void)memcpy_s(encodedOut->data, length, certIssuer->data, length);
145 encodedOut->size = length;
146 return CF_SUCCESS;
147 }
148
GetRevocationDate(HcfX509CrlEntry * self,CfBlob * out)149 static CfResult GetRevocationDate(HcfX509CrlEntry *self, CfBlob *out)
150 {
151 if ((self == NULL) || (out == NULL)) {
152 LOGE("invalid Paramas for calling GetRevocationDate!");
153 return CF_INVALID_PARAMS;
154 }
155 X509_REVOKED *rev = GetSelfRev(self);
156 if (rev == NULL) {
157 LOGE("Rev is null!");
158 return CF_INVALID_PARAMS;
159 }
160 const ASN1_TIME *time = X509_REVOKED_get0_revocationDate(rev);
161 if (time == NULL) {
162 LOGE("Get revocation date fail!");
163 CfPrintOpensslError();
164 return CF_ERR_CRYPTO_OPERATION;
165 }
166 const char *revTime = (const char *)(time->data);
167 if ((revTime == NULL) || (strlen(revTime) > HCF_MAX_STR_LEN)) {
168 LOGE("Get revocation date from ASN1_TIME fail!");
169 return CF_ERR_CRYPTO_OPERATION;
170 }
171 uint32_t length = strlen(revTime) + 1;
172 out->data = (uint8_t *)HcfMalloc(length, 0);
173 if (out->data == NULL) {
174 LOGE("Failed to malloc for revTime!");
175 return CF_ERR_MALLOC;
176 }
177 (void)memcpy_s(out->data, length, revTime, length);
178 out->size = length;
179 return CF_SUCCESS;
180 }
181
GetExtensions(HcfX509CrlEntry * self,CfBlob * outBlob)182 static CfResult GetExtensions(HcfX509CrlEntry *self, CfBlob *outBlob)
183 {
184 if ((self == NULL) || (outBlob == NULL)) {
185 LOGE("Invalid Paramas!");
186 return CF_INVALID_PARAMS;
187 }
188
189 X509_REVOKED *rev = GetSelfRev(self);
190 if (rev == NULL) {
191 LOGE("Rev is null!");
192 return CF_INVALID_PARAMS;
193 }
194
195 X509_EXTENSIONS *exts = (X509_EXTENSIONS *)X509_REVOKED_get0_extensions(rev);
196 CfResult ret = CopyExtensionsToBlob(exts, outBlob);
197 if (ret != CF_SUCCESS) {
198 CfPrintOpensslError();
199 }
200 return ret;
201 }
202
HasExtensions(HcfX509CrlEntry * self,bool * out)203 static CfResult HasExtensions(HcfX509CrlEntry *self, bool *out)
204 {
205 if (self == NULL || out == NULL) {
206 LOGE("Invalid Paramas!");
207 return CF_INVALID_PARAMS;
208 }
209
210 X509_REVOKED *rev = GetSelfRev(self);
211 if (rev == NULL) {
212 LOGE("Rev is null!");
213 return CF_INVALID_PARAMS;
214 }
215
216 X509_EXTENSIONS *exts = (X509_EXTENSIONS *)X509_REVOKED_get0_extensions(rev);
217 if (exts == NULL) {
218 *out = false;
219 } else {
220 *out = (sk_X509_EXTENSION_num(exts) > 0);
221 }
222
223 return CF_SUCCESS;
224 }
225
DeepCopyCertIssuer(HcfX509CRLEntryOpensslImpl * returnCRLEntry,CfBlob * certIssuer)226 static CfResult DeepCopyCertIssuer(HcfX509CRLEntryOpensslImpl *returnCRLEntry, CfBlob *certIssuer)
227 {
228 returnCRLEntry->certIssuer = (CfBlob *)HcfMalloc(sizeof(CfBlob), 0);
229 if (returnCRLEntry->certIssuer == NULL) {
230 LOGE("Failed to malloc certIssuer!");
231 return CF_ERR_MALLOC;
232 }
233 size_t len = certIssuer->size;
234 returnCRLEntry->certIssuer->size = len;
235 returnCRLEntry->certIssuer->data = (uint8_t *)HcfMalloc(len, 0);
236 if (returnCRLEntry->certIssuer->data == NULL) {
237 LOGE("Failed to malloc certIssuer data!");
238 return CF_ERR_MALLOC;
239 }
240 (void)memcpy_s(returnCRLEntry->certIssuer->data, len, certIssuer->data, len);
241 return CF_SUCCESS;
242 }
243
Destroy(CfObjectBase * self)244 static void Destroy(CfObjectBase *self)
245 {
246 if (self == NULL) {
247 LOGE("Invalid Paramas!");
248 return;
249 }
250 if (!IsClassMatch((CfObjectBase *)self, GetClass())) {
251 LOGE("Input wrong class type!");
252 return;
253 }
254 HcfX509CRLEntryOpensslImpl *realCrlEntry = (HcfX509CRLEntryOpensslImpl *)self;
255 if (realCrlEntry->rev != NULL) {
256 X509_REVOKED_free(realCrlEntry->rev);
257 realCrlEntry->rev = NULL;
258 }
259 if (realCrlEntry->certIssuer != NULL) {
260 CfFree(realCrlEntry->certIssuer->data);
261 realCrlEntry->certIssuer->data = NULL;
262 CfFree(realCrlEntry->certIssuer);
263 realCrlEntry->certIssuer = NULL;
264 }
265 CfFree(realCrlEntry);
266 }
267
HcfCX509CRLEntryCreate(X509_REVOKED * rev,HcfX509CrlEntry ** crlEntryOut,CfBlob * certIssuer)268 CfResult HcfCX509CRLEntryCreate(X509_REVOKED *rev, HcfX509CrlEntry **crlEntryOut, CfBlob *certIssuer)
269 {
270 if ((rev == NULL) || (crlEntryOut == NULL) || certIssuer == NULL) {
271 LOGE("Invalid Paramas!");
272 return CF_INVALID_PARAMS;
273 }
274 HcfX509CRLEntryOpensslImpl *returnCRLEntry = (HcfX509CRLEntryOpensslImpl *)HcfMalloc(
275 sizeof(HcfX509CRLEntryOpensslImpl), 0);
276 if (returnCRLEntry == NULL) {
277 LOGE("Failed to malloc for x509 entry instance!");
278 return CF_ERR_MALLOC;
279 }
280
281 X509_REVOKED *tmp = X509_REVOKED_dup(rev);
282 if (tmp == NULL) {
283 CfFree(returnCRLEntry);
284 LOGE("Failed to dup x509 revoked");
285 return CF_ERR_MALLOC;
286 }
287 returnCRLEntry->rev = tmp;
288 returnCRLEntry->certIssuer = NULL;
289 returnCRLEntry->base.base.getClass = GetClass;
290 returnCRLEntry->base.base.destroy = Destroy;
291 returnCRLEntry->base.getEncoded = GetEncoded;
292 returnCRLEntry->base.getSerialNumber = GetSerialNumber;
293 returnCRLEntry->base.getCertIssuer = GetCertIssuer;
294 returnCRLEntry->base.getRevocationDate = GetRevocationDate;
295 returnCRLEntry->base.getExtensions = GetExtensions;
296 returnCRLEntry->base.hasExtensions = HasExtensions;
297 if (DeepCopyCertIssuer(returnCRLEntry, certIssuer) != CF_SUCCESS) {
298 LOGI("No cert issuer find or deep copy cert issuer fail!");
299 }
300 *crlEntryOut = (HcfX509CrlEntry *)returnCRLEntry;
301 return CF_SUCCESS;
302 }
303