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