• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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_certificate_openssl.h"
17 
18 #include <securec.h>
19 #include <openssl/x509.h>
20 #include <openssl/x509v3.h>
21 #include <openssl/evp.h>
22 #include <openssl/pem.h>
23 
24 #include "config.h"
25 #include "log.h"
26 #include "memory.h"
27 #include "result.h"
28 #include "utils.h"
29 #include "x509_certificate.h"
30 #include "openssl_class.h"
31 #include "openssl_common.h"
32 
33 #define X509_CERT_PUBLIC_KEY_OPENSSL_CLASS "X509CertPublicKeyOpensslClass"
34 #define OID_STR_MAX_LEN 128
35 #define CHAR_TO_BIT_LEN 8
36 #define MAX_DATE_STR_LEN 128
37 #define FLAG_BIT_LEFT_NUM 0x07
38 
39 typedef struct {
40     HcfPubKey base;
41     EVP_PKEY *pubKey;
42 } X509PubKeyOpensslImpl;
43 
DeepCopyDataToOut(const char * data,uint32_t len,HcfBlob * out)44 static HcfResult DeepCopyDataToOut(const char *data, uint32_t len, HcfBlob *out)
45 {
46     out->data = (uint8_t *)HcfMalloc(len, 0);
47     if (out->data == NULL) {
48         LOGE("Failed to malloc for sig algorithm params!");
49         return HCF_ERR_MALLOC;
50     }
51     (void)memcpy_s(out->data, len, data, len);
52     out->len = len;
53     return HCF_SUCCESS;
54 }
55 
GetX509CertClass(void)56 static const char *GetX509CertClass(void)
57 {
58     return X509_CERT_OPENSSL_CLASS;
59 }
60 
DestroyX509Openssl(HcfObjectBase * self)61 static void DestroyX509Openssl(HcfObjectBase *self)
62 {
63     if (self == NULL) {
64         return;
65     }
66     if (!IsClassMatch(self, GetX509CertClass())) {
67         LOGE("Input wrong class type!");
68         return;
69     }
70     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
71     X509_free(realCert->x509);
72     realCert->x509 = NULL;
73     HcfFree(realCert);
74 }
75 
GetX509CertPubKeyClass(void)76 static const char *GetX509CertPubKeyClass(void)
77 {
78     return X509_CERT_PUBLIC_KEY_OPENSSL_CLASS;
79 }
80 
DestroyX509PubKeyOpenssl(HcfObjectBase * self)81 static void DestroyX509PubKeyOpenssl(HcfObjectBase *self)
82 {
83     if (self == NULL) {
84         return;
85     }
86     if (!IsClassMatch(self, GetX509CertPubKeyClass())) {
87         LOGE("Input wrong class type!");
88         return;
89     }
90     X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
91     if (impl->pubKey != NULL) {
92         EVP_PKEY_free(impl->pubKey);
93         impl->pubKey = NULL;
94     }
95     HcfFree(impl);
96 }
97 
GetPubKeyAlgorithm(HcfKey * self)98 static const char *GetPubKeyAlgorithm(HcfKey *self)
99 {
100     (void)self;
101     LOGD("Not supported!");
102     return NULL;
103 }
104 
105 
GetPubKeyEncoded(HcfKey * self,HcfBlob * returnBlob)106 static HcfResult GetPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob)
107 {
108     (void)self;
109     (void)returnBlob;
110     LOGD("Not supported!");
111     return HCF_NOT_SUPPORT;
112 }
113 
GetPubKeyFormat(HcfKey * self)114 static const char *GetPubKeyFormat(HcfKey *self)
115 {
116     (void)self;
117     LOGD("Not supported!");
118     return NULL;
119 }
120 
VerifyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey * key)121 static HcfResult VerifyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey *key)
122 {
123     if ((self == NULL) || (key == NULL)) {
124         LOGE("The input data is null!");
125         return HCF_INVALID_PARAMS;
126     }
127     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass()) ||
128         (!IsClassMatch((HcfObjectBase *)key, GetX509CertPubKeyClass()))) {
129         LOGE("Input wrong class type!");
130         return HCF_INVALID_PARAMS;
131     }
132     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
133     X509 *x509 = realCert->x509;
134     X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)key;
135     EVP_PKEY *pubKey = keyImpl->pubKey;
136     if (X509_verify(x509, pubKey) != HCF_OPENSSL_SUCCESS) {
137         LOGE("Failed to verify x509 cert's signature.");
138         HcfPrintOpensslError();
139         return HCF_ERR_CRYPTO_OPERATION;
140     }
141     return HCF_SUCCESS;
142 }
143 
GetEncodedX509Openssl(HcfX509CertificateSpi * self,HcfEncodingBlob * encodedByte)144 static HcfResult GetEncodedX509Openssl(HcfX509CertificateSpi *self, HcfEncodingBlob *encodedByte)
145 {
146     if ((self == NULL) || (encodedByte == NULL)) {
147         LOGE("The input data is null!");
148         return HCF_INVALID_PARAMS;
149     }
150     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
151         LOGE("Input wrong class type!");
152         return HCF_INVALID_PARAMS;
153     }
154     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
155     X509 *x509 = realCert->x509;
156     int32_t length = i2d_X509(x509, NULL);
157     if ((length <= 0) || (x509 == NULL)) {
158         LOGE("Failed to convert internal x509 to der format!");
159         HcfPrintOpensslError();
160         return HCF_ERR_CRYPTO_OPERATION;
161     }
162     unsigned char *der = NULL;
163     (void)i2d_X509(x509, &der);
164     encodedByte->data = (uint8_t *)HcfMalloc(length, 0);
165     if (encodedByte->data == NULL) {
166         LOGE("Failed to malloc for x509 der data!");
167         OPENSSL_free(der);
168         return HCF_ERR_MALLOC;
169     }
170     (void)memcpy_s(encodedByte->data, length, der, length);
171     OPENSSL_free(der);
172     encodedByte->len = length;
173     encodedByte->encodingFormat = HCF_FORMAT_DER;
174     return HCF_SUCCESS;
175 }
176 
GetPublicKeyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey ** keyOut)177 static HcfResult GetPublicKeyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey **keyOut)
178 {
179     if ((self == NULL) || (keyOut == NULL)) {
180         LOGE("The input data is null!");
181         return HCF_INVALID_PARAMS;
182     }
183     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
184         LOGE("Input wrong class type!");
185         return HCF_INVALID_PARAMS;
186     }
187     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
188     X509 *x509 = realCert->x509;
189     EVP_PKEY *pubKey = X509_get_pubkey(x509);
190     if (pubKey == NULL) {
191         LOGE("Failed to get publick key from x509 cert.");
192         HcfPrintOpensslError();
193         return HCF_ERR_CRYPTO_OPERATION;
194     }
195     X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)HcfMalloc(sizeof(X509PubKeyOpensslImpl), 0);
196     if (keyImpl == NULL) {
197         LOGE("Failed to malloc for public key obj!");
198         EVP_PKEY_free(pubKey);
199         return HCF_ERR_MALLOC;
200     }
201     keyImpl->pubKey = pubKey;
202     keyImpl->base.base.base.destroy = DestroyX509PubKeyOpenssl;
203     keyImpl->base.base.base.getClass = GetX509CertPubKeyClass;
204     keyImpl->base.base.getEncoded = GetPubKeyEncoded;
205     keyImpl->base.base.getAlgorithm = GetPubKeyAlgorithm;
206     keyImpl->base.base.getFormat = GetPubKeyFormat;
207     *keyOut = (HcfPubKey *)keyImpl;
208     return HCF_SUCCESS;
209 }
210 
CompareDateWithCertTime(const X509 * x509,const ASN1_TIME * inputDate)211 static HcfResult CompareDateWithCertTime(const X509 *x509, const ASN1_TIME *inputDate)
212 {
213     ASN1_TIME *startDate = X509_get_notBefore(x509);
214     ASN1_TIME *expirationDate = X509_get_notAfter(x509);
215     if ((startDate == NULL) || (expirationDate == NULL)) {
216         LOGE("Date is null in x509 cert!");
217         HcfPrintOpensslError();
218         return HCF_ERR_CRYPTO_OPERATION;
219     }
220     HcfResult res = HCF_SUCCESS;
221     /* 0: equal in ASN1_TIME_compare, -1: a < b, 1: a > b, -2: error. */
222     if (ASN1_TIME_compare(inputDate, startDate) < 0) {
223         LOGE("Date is not validate in x509 cert!");
224         res = HCF_ERR_CERT_NOT_YET_VALID;
225     } else if (ASN1_TIME_compare(expirationDate, inputDate) < 0) {
226         LOGE("Date is expired in x509 cert!");
227         res = HCF_ERR_CERT_HAS_EXPIRED;
228     }
229     return res;
230 }
231 
CheckValidityWithDateX509Openssl(HcfX509CertificateSpi * self,const char * date)232 static HcfResult CheckValidityWithDateX509Openssl(HcfX509CertificateSpi *self, const char *date)
233 {
234     if ((self == NULL) || (date == NULL)) {
235         LOGE("The input data is null!");
236         return HCF_INVALID_PARAMS;
237     }
238     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
239         LOGE("Input wrong class type!");
240         return HCF_INVALID_PARAMS;
241     }
242     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
243     X509 *x509 = realCert->x509;
244     ASN1_TIME *asn1InputDate = ASN1_TIME_new();
245     if (asn1InputDate == NULL) {
246         LOGE("Failed to malloc for asn1 time.");
247         return HCF_ERR_MALLOC;
248     }
249     if (ASN1_TIME_set_string(asn1InputDate, date) != HCF_OPENSSL_SUCCESS) {
250         LOGE("Failed to set time for asn1 time.");
251         HcfPrintOpensslError();
252         ASN1_TIME_free(asn1InputDate);
253         return HCF_ERR_CRYPTO_OPERATION;
254     }
255     HcfResult res = CompareDateWithCertTime(x509, asn1InputDate);
256     ASN1_TIME_free(asn1InputDate);
257     return res;
258 }
259 
GetVersionX509Openssl(HcfX509CertificateSpi * self)260 static long GetVersionX509Openssl(HcfX509CertificateSpi *self)
261 {
262     if (self == NULL) {
263         LOGE("The input data is null!");
264         return INVALID_VERSION;
265     }
266     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
267         LOGE("Input wrong class type!");
268         return INVALID_VERSION;
269     }
270     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
271     X509 *x509 = realCert->x509;
272     return X509_get_version(x509) + 1;
273 }
274 
GetSerialNumberX509Openssl(HcfX509CertificateSpi * self)275 static long GetSerialNumberX509Openssl(HcfX509CertificateSpi *self)
276 {
277     if (self == NULL) {
278         LOGE("The input data is null!");
279         return INVALID_SERIAL_NUMBER;
280     }
281     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
282         LOGE("Input wrong class type!");
283         return INVALID_SERIAL_NUMBER;
284     }
285     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
286     X509 *x509 = realCert->x509;
287     const ASN1_INTEGER *serial = X509_get0_serialNumber(x509);
288     if (serial == NULL) {
289         LOGE("Failed to get serial number!");
290         return INVALID_SERIAL_NUMBER;
291     }
292     return ASN1_INTEGER_get(serial);
293 }
294 
GetIssuerDNX509Openssl(HcfX509CertificateSpi * self,HcfBlob * out)295 static HcfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, HcfBlob *out)
296 {
297     if ((self == NULL) || (out == NULL)) {
298         LOGE("[Get issuerDN openssl] The input data is null!");
299         return HCF_INVALID_PARAMS;
300     }
301     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
302         LOGE("Input wrong class type!");
303         return HCF_INVALID_PARAMS;
304     }
305     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
306     X509 *x509 = realCert->x509;
307     X509_NAME *issuerName = X509_get_issuer_name(x509);
308     if (issuerName == NULL) {
309         LOGE("Failed to get x509 issuerName in openssl!");
310         HcfPrintOpensslError();
311         return HCF_ERR_CRYPTO_OPERATION;
312     }
313     char *issuer = (char *)HcfMalloc(HCF_MAX_STR_LEN + 1, 0);
314     if (issuer == NULL) {
315         LOGE("Failed to malloc for issuer buffer!");
316         return HCF_ERR_MALLOC;
317     }
318 
319     HcfResult res = HCF_SUCCESS;
320     do {
321         X509_NAME_oneline(issuerName, issuer, HCF_MAX_STR_LEN);
322         size_t length = strlen(issuer) + 1;
323         if (length == 1) {
324             LOGE("Failed to get oneline issuerName in openssl!");
325             res = HCF_ERR_CRYPTO_OPERATION;
326             HcfPrintOpensslError();
327             break;
328         }
329         res = DeepCopyDataToOut(issuer, length, out);
330     } while (0);
331     HcfFree(issuer);
332     return res;
333 }
334 
GetSubjectDNX509Openssl(HcfX509CertificateSpi * self,HcfBlob * out)335 static HcfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, HcfBlob *out)
336 {
337     if ((self == NULL) || (out == NULL)) {
338         LOGE("[Get subjectDN openssl]The input data is null!");
339         return HCF_INVALID_PARAMS;
340     }
341     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
342         LOGE("Input wrong class type!");
343         return HCF_INVALID_PARAMS;
344     }
345     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
346     X509 *x509 = realCert->x509;
347     X509_NAME *subjectName = X509_get_subject_name(x509);
348     if (subjectName == NULL) {
349         LOGE("Failed to get x509 subjectName in openssl!");
350         HcfPrintOpensslError();
351         return HCF_ERR_CRYPTO_OPERATION;
352     }
353     char *subject = (char *)HcfMalloc(HCF_MAX_STR_LEN + 1, 0);
354     if (subject == NULL) {
355         LOGE("Failed to malloc for subject buffer!");
356         return HCF_ERR_MALLOC;
357     }
358 
359     HcfResult res = HCF_SUCCESS;
360     do {
361         X509_NAME_oneline(subjectName, subject, HCF_MAX_STR_LEN);
362         size_t length = strlen(subject) + 1;
363         if (length == 1) {
364             LOGE("Failed to get oneline subjectName in openssl!");
365             HcfPrintOpensslError();
366             res = HCF_ERR_CRYPTO_OPERATION;
367             break;
368         }
369         res = DeepCopyDataToOut(subject, length, out);
370     } while (0);
371     HcfFree(subject);
372     return res;
373 }
374 
GetNotBeforeX509Openssl(HcfX509CertificateSpi * self,HcfBlob * outDate)375 static HcfResult GetNotBeforeX509Openssl(HcfX509CertificateSpi *self, HcfBlob *outDate)
376 {
377     if ((self == NULL) || (outDate == NULL)) {
378         LOGE("Get not before, input is null!");
379         return HCF_INVALID_PARAMS;
380     }
381     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
382         LOGE("Get not before, input wrong class type!");
383         return HCF_INVALID_PARAMS;
384     }
385     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
386     X509 *x509 = realCert->x509;
387     ASN1_TIME *notBeforeDate = X509_get_notBefore(x509);
388     if (notBeforeDate == NULL) {
389         LOGE("NotBeforeDate is null in x509 cert!");
390         HcfPrintOpensslError();
391         return HCF_ERR_CRYPTO_OPERATION;
392     }
393     if (ASN1_TIME_normalize(notBeforeDate) != HCF_OPENSSL_SUCCESS) {
394         LOGE("Failed to normalize notBeforeDate!");
395         HcfPrintOpensslError();
396         return HCF_ERR_CRYPTO_OPERATION;
397     }
398     const char *date = (const char *)(notBeforeDate->data);
399     if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
400         LOGE("Failed to get notBeforeDate data!");
401         return HCF_ERR_CRYPTO_OPERATION;
402     }
403     uint32_t length = strlen(date) + 1;
404     return DeepCopyDataToOut(date, length, outDate);
405 }
406 
GetNotAfterX509Openssl(HcfX509CertificateSpi * self,HcfBlob * outDate)407 static HcfResult GetNotAfterX509Openssl(HcfX509CertificateSpi *self, HcfBlob *outDate)
408 {
409     if ((self == NULL) || (outDate == NULL)) {
410         LOGE("Get not after, input data is null!");
411         return HCF_INVALID_PARAMS;
412     }
413     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
414         LOGE("Get not after, input wrong class type!");
415         return HCF_INVALID_PARAMS;
416     }
417     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
418     X509 *x509 = realCert->x509;
419     ASN1_TIME *notAfterDate = X509_get_notAfter(x509);
420     if (notAfterDate == NULL) {
421         LOGE("NotAfterDate is null in x509 cert!");
422         HcfPrintOpensslError();
423         return HCF_ERR_CRYPTO_OPERATION;
424     }
425     if (ASN1_TIME_normalize(notAfterDate) != HCF_OPENSSL_SUCCESS) {
426         LOGE("Failed to normalize notAfterDate!");
427         HcfPrintOpensslError();
428         return HCF_ERR_CRYPTO_OPERATION;
429     }
430     const char *date = (const char *)(notAfterDate->data);
431     if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
432         LOGE("Failed to get notAfterDate data!");
433         return HCF_ERR_CRYPTO_OPERATION;
434     }
435     uint32_t length = strlen(date) + 1;
436     return DeepCopyDataToOut(date, length, outDate);
437 }
438 
GetSignatureX509Openssl(HcfX509CertificateSpi * self,HcfBlob * sigOut)439 static HcfResult GetSignatureX509Openssl(HcfX509CertificateSpi *self, HcfBlob *sigOut)
440 {
441     if ((self == NULL) || (sigOut == NULL)) {
442         LOGE("The input data is null!");
443         return HCF_INVALID_PARAMS;
444     }
445     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
446         LOGE("Input wrong class type!");
447         return HCF_INVALID_PARAMS;
448     }
449     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
450     X509 *x509 = realCert->x509;
451     const ASN1_BIT_STRING *signature;
452     X509_get0_signature(&signature, NULL, x509);
453     if ((signature == NULL) || (signature->length == 0) || (signature->length > HCF_MAX_BUFFER_LEN)) {
454         LOGE("Failed to get x509 signature in openssl!");
455         HcfPrintOpensslError();
456         return HCF_ERR_CRYPTO_OPERATION;
457     }
458     sigOut->data = (uint8_t *)HcfMalloc(signature->length, 0);
459     if (sigOut->data == NULL) {
460         LOGE("Failed to malloc for signature data!");
461         return HCF_ERR_MALLOC;
462     }
463     (void)memcpy_s(sigOut->data, signature->length, signature->data, signature->length);
464     sigOut->len = signature->length;
465     return HCF_SUCCESS;
466 }
467 
GetSigAlgNameX509Openssl(HcfX509CertificateSpi * self,HcfBlob * outName)468 static HcfResult GetSigAlgNameX509Openssl(HcfX509CertificateSpi *self, HcfBlob *outName)
469 {
470     if ((self == NULL) || (outName == NULL)) {
471         LOGE("[GetSigAlgName openssl] The input data is null!");
472         return HCF_INVALID_PARAMS;
473     }
474     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
475         LOGE("[GetSigAlgName openssl] Input wrong class type!");
476         return HCF_INVALID_PARAMS;
477     }
478     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
479     X509 *x509 = realCert->x509;
480     const X509_ALGOR *alg;
481     X509_get0_signature(NULL, &alg, x509);
482     const ASN1_OBJECT *oidObj;
483     X509_ALGOR_get0(&oidObj, NULL, NULL, alg);
484     char oidStr[OID_STR_MAX_LEN] = { 0 };
485     int32_t resLen = OBJ_obj2txt(oidStr, OID_STR_MAX_LEN, oidObj, 1);
486     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
487         LOGE("Failed to convert x509 object to text!");
488         HcfPrintOpensslError();
489         return HCF_ERR_CRYPTO_OPERATION;
490     }
491     const char *algName = GetAlgorithmName(oidStr);
492     if (algName == NULL) {
493         return HCF_ERR_CRYPTO_OPERATION;
494     }
495     uint32_t len = strlen(algName) + 1;
496     return DeepCopyDataToOut(algName, len, outName);
497 }
498 
GetSigAlgOidX509Openssl(HcfX509CertificateSpi * self,HcfBlob * out)499 static HcfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, HcfBlob *out)
500 {
501     if ((self == NULL) || (out == NULL)) {
502         LOGE("[GetSigAlgOID openssl] The input data is null!");
503         return HCF_INVALID_PARAMS;
504     }
505     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
506         LOGE("[GetSigAlgOID openssl] Input wrong class type!");
507         return HCF_INVALID_PARAMS;
508     }
509     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
510     X509 *x509 = realCert->x509;
511     const X509_ALGOR *alg;
512     X509_get0_signature(NULL, &alg, x509);
513     const ASN1_OBJECT *oid;
514     X509_ALGOR_get0(&oid, NULL, NULL, alg);
515     char algOid[OID_STR_MAX_LEN] = { 0 };
516     int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, oid, 1);
517     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
518         LOGE("Failed to convert x509 object to text!");
519         HcfPrintOpensslError();
520         return HCF_ERR_CRYPTO_OPERATION;
521     }
522     uint32_t len = strlen(algOid) + 1;
523     return DeepCopyDataToOut(algOid, len, out);
524 }
525 
GetSigAlgParamsX509Openssl(HcfX509CertificateSpi * self,HcfBlob * sigAlgParamsOut)526 static HcfResult GetSigAlgParamsX509Openssl(HcfX509CertificateSpi *self, HcfBlob *sigAlgParamsOut)
527 {
528     if ((self == NULL) || (sigAlgParamsOut == NULL)) {
529         LOGE("[GetSigAlgParams openssl] The input data is null!");
530         return HCF_INVALID_PARAMS;
531     }
532     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
533         LOGE("[GetSigAlgParams openssl] Input wrong class type!");
534         return HCF_INVALID_PARAMS;
535     }
536     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
537     X509 *x509 = realCert->x509;
538     const X509_ALGOR *alg;
539     X509_get0_signature(NULL, &alg, x509);
540     int32_t paramType = 0;
541     const void *paramValue = NULL;
542     X509_ALGOR_get0(NULL, &paramType, &paramValue, alg);
543     if (paramType == V_ASN1_UNDEF) {
544         LOGE("get_X509_ALGOR_parameter, no parameters!");
545         return HCF_NOT_SUPPORT;
546     }
547     ASN1_TYPE *param = ASN1_TYPE_new();
548     if (param == NULL) {
549         LOGE("Failed to malloc for asn1 type data!");
550         return HCF_ERR_MALLOC;
551     }
552     if (ASN1_TYPE_set1(param, paramType, paramValue) != HCF_OPENSSL_SUCCESS) {
553         LOGE("Failed to set asn1 type in openssl!");
554         HcfPrintOpensslError();
555         ASN1_TYPE_free(param);
556         return HCF_ERR_CRYPTO_OPERATION;
557     }
558     unsigned char *out = NULL;
559     int32_t len = i2d_ASN1_TYPE(param, NULL);
560     if (len <= 0) {
561         LOGE("Failed to convert ASN1_TYPE!");
562         HcfPrintOpensslError();
563         ASN1_TYPE_free(param);
564         return HCF_ERR_CRYPTO_OPERATION;
565     }
566     (void)i2d_ASN1_TYPE(param, &out);
567     ASN1_TYPE_free(param);
568     HcfResult res = DeepCopyDataToOut((const char *)out, len, sigAlgParamsOut);
569     OPENSSL_free(out);
570     return res;
571 }
572 
ConvertAsn1String2BoolArray(const ASN1_BIT_STRING * string,HcfBlob * boolArr)573 static HcfResult ConvertAsn1String2BoolArray(const ASN1_BIT_STRING *string, HcfBlob *boolArr)
574 {
575     uint32_t length = ASN1_STRING_length(string) * CHAR_TO_BIT_LEN;
576     if (string->flags & ASN1_STRING_FLAG_BITS_LEFT) {
577         length -= string->flags & FLAG_BIT_LEFT_NUM;
578     }
579     boolArr->data = (uint8_t *)HcfMalloc(length, 0);
580     if (boolArr->data == NULL) {
581         LOGE("Failed to malloc for bit array data!");
582         return HCF_ERR_MALLOC;
583     }
584     for (uint32_t i = 0; i < length; i++) {
585         boolArr->data[i] = ASN1_BIT_STRING_get_bit(string, i);
586     }
587     boolArr->len = length;
588     return HCF_SUCCESS;
589 }
590 
GetKeyUsageX509Openssl(HcfX509CertificateSpi * self,HcfBlob * boolArr)591 static HcfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, HcfBlob *boolArr)
592 {
593     if ((self == NULL) || (boolArr == NULL)) {
594         LOGE("[GetKeyUsage openssl] The input data is null!");
595         return HCF_INVALID_PARAMS;
596     }
597     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
598         LOGE("Input wrong class type!");
599         return HCF_INVALID_PARAMS;
600     }
601     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
602     X509 *x509 = realCert->x509;
603 
604     ASN1_BIT_STRING *keyUsage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
605     if ((keyUsage == NULL) || (keyUsage->length <= 0)|| (keyUsage->length >= HCF_MAX_STR_LEN)) {
606         LOGE("Failed to get x509 keyUsage in openssl!");
607         HcfPrintOpensslError();
608         return HCF_ERR_CRYPTO_OPERATION;
609     }
610     HcfResult res = ConvertAsn1String2BoolArray(keyUsage, boolArr);
611     ASN1_BIT_STRING_free(keyUsage);
612     return res;
613 }
614 
DeepCopyExtendedKeyUsage(const STACK_OF (ASN1_OBJECT)* extUsage,int32_t i,HcfArray * keyUsageOut)615 static HcfResult DeepCopyExtendedKeyUsage(const STACK_OF(ASN1_OBJECT) *extUsage,
616     int32_t i, HcfArray *keyUsageOut)
617 {
618     char usage[OID_STR_MAX_LEN] = { 0 };
619     int32_t resLen = OBJ_obj2txt(usage, OID_STR_MAX_LEN, sk_ASN1_OBJECT_value(extUsage, i), 1);
620     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
621         LOGE("Failed to convert x509 object to text!");
622         HcfPrintOpensslError();
623         return HCF_ERR_CRYPTO_OPERATION;
624     }
625     uint32_t len = strlen(usage) + 1;
626     keyUsageOut->data[i].data = (uint8_t *)HcfMalloc(len, 0);
627     if (keyUsageOut->data[i].data == NULL) {
628         LOGE("Failed to malloc for key usage!");
629         return HCF_ERR_MALLOC;
630     }
631     (void)memcpy_s(keyUsageOut->data[i].data, len, usage, len);
632     keyUsageOut->data[i].len = len;
633     return HCF_SUCCESS;
634 }
635 
GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi * self,HcfArray * keyUsageOut)636 static HcfResult GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi *self, HcfArray *keyUsageOut)
637 {
638     if ((self == NULL) || (keyUsageOut == NULL)) {
639         LOGE("The input data is null!");
640         return HCF_INVALID_PARAMS;
641     }
642     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
643         LOGE("Input wrong class type!");
644         return HCF_INVALID_PARAMS;
645     }
646     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
647     X509 *x509 = realCert->x509;
648     STACK_OF(ASN1_OBJECT) *extUsage = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL);
649     if (extUsage == NULL) {
650         LOGE("Failed to get x509 extended keyUsage in openssl!");
651         return HCF_ERR_CRYPTO_OPERATION;
652     }
653     HcfResult res = HCF_SUCCESS;
654     do {
655         int32_t size = sk_ASN1_OBJECT_num(extUsage);
656         if (size <= 0) {
657             LOGE("The extended key usage size in openssl is invalid!");
658             HcfPrintOpensslError();
659             res = HCF_ERR_CRYPTO_OPERATION;
660             break;
661         }
662         int32_t blobSize = sizeof(HcfBlob) * size;
663         keyUsageOut->data = (HcfBlob *)HcfMalloc(blobSize, 0);
664         if (keyUsageOut->data == NULL) {
665             LOGE("Failed to malloc for keyUsageOut array!");
666             res = HCF_ERR_MALLOC;
667             break;
668         }
669         keyUsageOut->count = size;
670         for (int32_t i = 0; i < size; ++i) {
671             res = DeepCopyExtendedKeyUsage(extUsage, i, keyUsageOut);
672             if (res != HCF_SUCCESS) {
673                 LOGE("Falied to copy extended key usage!");
674                 break;
675             }
676         }
677     } while (0);
678     if (res != HCF_SUCCESS) {
679         HcfArrayDataClearAndFree(keyUsageOut);
680     }
681     sk_ASN1_OBJECT_pop_free(extUsage, ASN1_OBJECT_free);
682     return res;
683 }
684 
GetBasicConstraintsX509Openssl(HcfX509CertificateSpi * self)685 static int32_t GetBasicConstraintsX509Openssl(HcfX509CertificateSpi *self)
686 {
687     if (self == NULL) {
688         LOGE("The input data is null!");
689         return INVALID_CONSTRAINTS_LEN;
690     }
691     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
692         LOGE("Input wrong class type!");
693         return INVALID_CONSTRAINTS_LEN;
694     }
695     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
696     X509 *x509 = realCert->x509;
697     BASIC_CONSTRAINTS *constraints = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x509, NID_basic_constraints, NULL, NULL);
698     if (constraints == NULL) {
699         LOGE("Failed to get basic constraints in openssl!");
700         return INVALID_CONSTRAINTS_LEN;
701     }
702     /* Path len is only valid for CA cert. */
703     if (!constraints->ca) {
704         LOGI("The cert in not a CA!");
705         return INVALID_CONSTRAINTS_LEN;
706     }
707     if ((constraints->pathlen == NULL) || (constraints->pathlen->type == V_ASN1_NEG_INTEGER)) {
708         LOGE("The cert path len is negative in openssl!");
709         return INVALID_CONSTRAINTS_LEN;
710     }
711     long pathLen = ASN1_INTEGER_get(constraints->pathlen);
712     if ((pathLen < 0) || (pathLen > INT_MAX)) {
713         LOGE("Get the overflow path length in openssl!");
714         return INVALID_CONSTRAINTS_LEN;
715     }
716     return (int32_t)pathLen;
717 }
718 
DeepCopyAlternativeNames(const STACK_OF (GENERAL_NAME)* altNames,int32_t i,HcfArray * outName)719 static HcfResult DeepCopyAlternativeNames(const STACK_OF(GENERAL_NAME) *altNames, int32_t i, HcfArray *outName)
720 {
721     GENERAL_NAME *general = sk_GENERAL_NAME_value(altNames, i);
722     int32_t generalType = 0;
723     ASN1_STRING *ans1Str = GENERAL_NAME_get0_value(general, &generalType);
724     const char *str = (const char *)ASN1_STRING_get0_data(ans1Str);
725     if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
726         LOGE("Failed to get x509 altNames string in openssl!");
727         HcfPrintOpensslError();
728         return HCF_ERR_CRYPTO_OPERATION;
729     }
730     uint32_t nameLen = strlen(str) + 1;
731     outName->data[i].data = (uint8_t *)HcfMalloc(nameLen, 0);
732     if (outName->data[i].data == NULL) {
733         LOGE("Failed to malloc for outName!");
734         return HCF_ERR_MALLOC;
735     }
736     (void)memcpy_s(outName->data[i].data, nameLen, str, nameLen);
737     outName->data[i].len = nameLen;
738     return HCF_SUCCESS;
739 }
740 
GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi * self,HcfArray * outName)741 static HcfResult GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi *self, HcfArray *outName)
742 {
743     if ((self == NULL) || (outName == NULL)) {
744         LOGE("[GetSubjectAltNames openssl] The input data is null!");
745         return HCF_INVALID_PARAMS;
746     }
747     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
748         LOGE("Input wrong class type!");
749         return HCF_INVALID_PARAMS;
750     }
751     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
752     X509 *x509 = realCert->x509;
753     STACK_OF(GENERAL_NAME) *subjectAltName = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
754     if (subjectAltName == NULL) {
755         LOGE("Failed to get subjectAltName in openssl!");
756         HcfPrintOpensslError();
757         return HCF_ERR_CRYPTO_OPERATION;
758     }
759     HcfResult res = HCF_SUCCESS;
760     do {
761         int32_t size = sk_GENERAL_NAME_num(subjectAltName);
762         if (size <= 0) {
763             LOGE("The subjectAltName number in openssl is invalid!");
764             HcfPrintOpensslError();
765             res = HCF_ERR_CRYPTO_OPERATION;
766             break;
767         }
768         int32_t blobSize = sizeof(HcfBlob) * size;
769         outName->data = (HcfBlob *)HcfMalloc(blobSize, 0);
770         if (outName->data == NULL) {
771             LOGE("Failed to malloc for subjectAltName array!");
772             res = HCF_ERR_MALLOC;
773             break;
774         }
775         outName->count = size;
776         for (int32_t i = 0; i < size; ++i) {
777             res = DeepCopyAlternativeNames(subjectAltName, i, outName);
778             if (res != HCF_SUCCESS) {
779                 LOGE("Falied to copy subjectAltName!");
780                 break;
781             }
782         }
783     } while (0);
784     if (res != HCF_SUCCESS) {
785         HcfArrayDataClearAndFree(outName);
786     }
787     GENERAL_NAMES_free(subjectAltName);
788     return res;
789 }
790 
GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi * self,HcfArray * outName)791 static HcfResult GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi *self, HcfArray *outName)
792 {
793     if ((self == NULL) || (outName == NULL)) {
794         LOGE("[GetIssuerAltNames openssl] The input data is null!");
795         return HCF_INVALID_PARAMS;
796     }
797     if (!IsClassMatch((HcfObjectBase *)self, GetX509CertClass())) {
798         LOGE("Input wrong class type!");
799         return HCF_INVALID_PARAMS;
800     }
801     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
802     X509 *x509 = realCert->x509;
803     STACK_OF(GENERAL_NAME) *issuerAltName = X509_get_ext_d2i(x509, NID_issuer_alt_name, NULL, NULL);
804     if (issuerAltName == NULL) {
805         LOGE("Failed to get issuerAltName in openssl!");
806         HcfPrintOpensslError();
807         return HCF_ERR_CRYPTO_OPERATION;
808     }
809     HcfResult res = HCF_SUCCESS;
810     do {
811         int32_t size = sk_GENERAL_NAME_num(issuerAltName);
812         if (size <= 0) {
813             LOGE("The issuerAltName number in openssl is invalid!");
814             HcfPrintOpensslError();
815             res = HCF_ERR_CRYPTO_OPERATION;
816             break;
817         }
818         int32_t blobSize = sizeof(HcfBlob) * size;
819         outName->data = (HcfBlob *)HcfMalloc(blobSize, 0);
820         if (outName->data == NULL) {
821             LOGE("Failed to malloc for issuerAltName array!");
822             res = HCF_ERR_MALLOC;
823             break;
824         }
825         outName->count = size;
826         for (int32_t i = 0; i < size; ++i) {
827             res = DeepCopyAlternativeNames(issuerAltName, i, outName);
828             if (res != HCF_SUCCESS) {
829                 LOGE("Falied to copy issuerAltName!");
830                 break;
831             }
832         }
833     } while (0);
834     if (res != HCF_SUCCESS) {
835         HcfArrayDataClearAndFree(outName);
836     }
837     GENERAL_NAMES_free(issuerAltName);
838     return res;
839 }
840 
CreateX509CertInner(const HcfEncodingBlob * encodingBlob)841 static X509 *CreateX509CertInner(const HcfEncodingBlob *encodingBlob)
842 {
843     X509 *x509 = NULL;
844     BIO *bio = BIO_new_mem_buf(encodingBlob->data, encodingBlob->len);
845     if (bio == NULL) {
846         LOGE("Openssl bio new buf failed.");
847         return NULL;
848     }
849     LOGD("The input cert format is: %d.", encodingBlob->encodingFormat);
850     if (encodingBlob->encodingFormat == HCF_FORMAT_DER) {
851         x509 = d2i_X509_bio(bio, NULL);
852     } else if (encodingBlob->encodingFormat == HCF_FORMAT_PEM) {
853         x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
854     }
855     BIO_free(bio);
856     return x509;
857 }
858 
OpensslX509CertSpiCreate(const HcfEncodingBlob * inStream,HcfX509CertificateSpi ** spi)859 HcfResult OpensslX509CertSpiCreate(const HcfEncodingBlob *inStream, HcfX509CertificateSpi **spi)
860 {
861     if ((inStream == NULL) || (inStream->data == NULL) || (spi == NULL)) {
862         LOGE("The input data blob is null!");
863         return HCF_INVALID_PARAMS;
864     }
865     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)HcfMalloc(sizeof(HcfOpensslX509Cert), 0);
866     if (realCert == NULL) {
867         LOGE("Failed to malloc for x509 instance!");
868         return HCF_ERR_MALLOC;
869     }
870     realCert->x509 = CreateX509CertInner(inStream);
871     if (realCert->x509 == NULL) {
872         HcfFree(realCert);
873         LOGE("Failed to create x509 cert from input data!");
874         return HCF_INVALID_PARAMS;
875     }
876     realCert->base.base.getClass = GetX509CertClass;
877     realCert->base.base.destroy = DestroyX509Openssl;
878     realCert->base.engineVerify = VerifyX509Openssl;
879     realCert->base.engineGetEncoded = GetEncodedX509Openssl;
880     realCert->base.engineGetPublicKey = GetPublicKeyX509Openssl;
881     realCert->base.engineCheckValidityWithDate = CheckValidityWithDateX509Openssl;
882     realCert->base.engineGetVersion = GetVersionX509Openssl;
883     realCert->base.engineGetSerialNumber = GetSerialNumberX509Openssl;
884     realCert->base.engineGetIssuerName = GetIssuerDNX509Openssl;
885     realCert->base.engineGetSubjectName = GetSubjectDNX509Openssl;
886     realCert->base.engineGetNotBeforeTime = GetNotBeforeX509Openssl;
887     realCert->base.engineGetNotAfterTime = GetNotAfterX509Openssl;
888     realCert->base.engineGetSignature = GetSignatureX509Openssl;
889     realCert->base.engineGetSignatureAlgName = GetSigAlgNameX509Openssl;
890     realCert->base.engineGetSignatureAlgOid = GetSigAlgOidX509Openssl;
891     realCert->base.engineGetSignatureAlgParams = GetSigAlgParamsX509Openssl;
892     realCert->base.engineGetKeyUsage = GetKeyUsageX509Openssl;
893     realCert->base.engineGetExtKeyUsage = GetExtendedKeyUsageX509Openssl;
894     realCert->base.engineGetBasicConstraints = GetBasicConstraintsX509Openssl;
895     realCert->base.engineGetSubjectAltNames = GetSubjectAltNamesX509Openssl;
896     realCert->base.engineGetIssuerAltNames = GetIssuerAltNamesX509Openssl;
897     *spi = (HcfX509CertificateSpi *)realCert;
898     return HCF_SUCCESS;
899 }
900