• 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_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 "cf_log.h"
26 #include "cf_memory.h"
27 #include "cf_result.h"
28 #include "result.h"
29 #include "utils.h"
30 #include "x509_certificate.h"
31 #include "certificate_openssl_class.h"
32 #include "certificate_openssl_common.h"
33 
34 #define X509_CERT_PUBLIC_KEY_OPENSSL_CLASS "X509CertPublicKeyOpensslClass"
35 #define OID_STR_MAX_LEN 128
36 #define CHAR_TO_BIT_LEN 8
37 #define MAX_DATE_STR_LEN 128
38 #define FLAG_BIT_LEFT_NUM 0x07
39 
40 typedef struct {
41     HcfPubKey base;
42     EVP_PKEY *pubKey;
43 } X509PubKeyOpensslImpl;
44 
45 static CfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
46 static CfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
47 static CfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfBlob *boolArr);
48 static CfResult GetSerialNumberX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
49 static CfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
50 static CfResult GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
51 
DeepCopyDataToOut(const char * data,uint32_t len,CfBlob * out)52 static CfResult DeepCopyDataToOut(const char *data, uint32_t len, CfBlob *out)
53 {
54     out->data = (uint8_t *)HcfMalloc(len, 0);
55     if (out->data == NULL) {
56         LOGE("Failed to malloc for sig algorithm params!");
57         return CF_ERR_MALLOC;
58     }
59     (void)memcpy_s(out->data, len, data, len);
60     out->size = len;
61     return CF_SUCCESS;
62 }
63 
GetX509CertClass(void)64 static const char *GetX509CertClass(void)
65 {
66     return X509_CERT_OPENSSL_CLASS;
67 }
68 
DestroyX509Openssl(CfObjectBase * self)69 static void DestroyX509Openssl(CfObjectBase *self)
70 {
71     if (self == NULL) {
72         return;
73     }
74     if (!IsClassMatch(self, GetX509CertClass())) {
75         LOGE("Input wrong class type!");
76         return;
77     }
78     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
79     X509_free(realCert->x509);
80     realCert->x509 = NULL;
81     CfFree(realCert);
82 }
83 
GetX509CertPubKeyClass(void)84 static const char *GetX509CertPubKeyClass(void)
85 {
86     return X509_CERT_PUBLIC_KEY_OPENSSL_CLASS;
87 }
88 
DestroyX509PubKeyOpenssl(HcfObjectBase * self)89 static void DestroyX509PubKeyOpenssl(HcfObjectBase *self)
90 {
91     if (self == NULL) {
92         return;
93     }
94     if (!IsPubKeyClassMatch(self, GetX509CertPubKeyClass())) {
95         LOGE("Input wrong class type!");
96         return;
97     }
98     X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
99     if (impl->pubKey != NULL) {
100         EVP_PKEY_free(impl->pubKey);
101         impl->pubKey = NULL;
102     }
103     CfFree(impl);
104 }
105 
GetPubKeyAlgorithm(HcfKey * self)106 static const char *GetPubKeyAlgorithm(HcfKey *self)
107 {
108     (void)self;
109     LOGD("Not supported!");
110     return NULL;
111 }
112 
GetPubKeyEncoded(HcfKey * self,HcfBlob * returnBlob)113 static HcfResult GetPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob)
114 {
115     if (self == NULL || returnBlob == NULL) {
116         LOGE("Input params is invalid.");
117         return HCF_INVALID_PARAMS;
118     }
119     if (!IsPubKeyClassMatch((HcfObjectBase *)self, GetX509CertPubKeyClass())) {
120         LOGE("Input wrong class type!");
121         return HCF_INVALID_PARAMS;
122     }
123     X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
124 
125     unsigned char *pkBytes = NULL;
126     int32_t pkLen = i2d_PUBKEY(impl->pubKey, &pkBytes);
127     if (pkLen <= 0) {
128         CfPrintOpensslError();
129         LOGE("Failed to convert internal pubkey to der format!");
130         return HCF_ERR_CRYPTO_OPERATION;
131     }
132 
133     returnBlob->data = (uint8_t *)HcfMalloc(pkLen, 0);
134     if (returnBlob->data == NULL) {
135         LOGE("Failed to malloc for sig algorithm params!");
136         OPENSSL_free(pkBytes);
137         return HCF_ERR_MALLOC;
138     }
139     (void)memcpy_s(returnBlob->data, pkLen, pkBytes, pkLen);
140     returnBlob->len = (size_t)pkLen;
141 
142     OPENSSL_free(pkBytes);
143     return HCF_SUCCESS;
144 }
145 
GetPubKeyFormat(HcfKey * self)146 static const char *GetPubKeyFormat(HcfKey *self)
147 {
148     (void)self;
149     LOGD("Not supported!");
150     return NULL;
151 }
152 
VerifyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey * key)153 static CfResult VerifyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey *key)
154 {
155     if ((self == NULL) || (key == NULL)) {
156         LOGE("The input data is null!");
157         return CF_INVALID_PARAMS;
158     }
159     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass()) ||
160         (!IsPubKeyClassMatch((HcfObjectBase *)key, GetX509CertPubKeyClass()))) {
161         LOGE("Input wrong class type!");
162         return CF_INVALID_PARAMS;
163     }
164     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
165     X509 *x509 = realCert->x509;
166     X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)key;
167     EVP_PKEY *pubKey = keyImpl->pubKey;
168     if (X509_verify(x509, pubKey) != CF_OPENSSL_SUCCESS) {
169         LOGE("Failed to verify x509 cert's signature.");
170         CfPrintOpensslError();
171         return CF_ERR_CRYPTO_OPERATION;
172     }
173     return CF_SUCCESS;
174 }
175 
GetEncodedX509Openssl(HcfX509CertificateSpi * self,CfEncodingBlob * encodedByte)176 static CfResult GetEncodedX509Openssl(HcfX509CertificateSpi *self, CfEncodingBlob *encodedByte)
177 {
178     if ((self == NULL) || (encodedByte == NULL)) {
179         LOGE("The input data is null!");
180         return CF_INVALID_PARAMS;
181     }
182     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
183         LOGE("Input wrong class type!");
184         return CF_INVALID_PARAMS;
185     }
186     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
187     X509 *x509 = realCert->x509;
188     int32_t length = i2d_X509(x509, NULL);
189     if ((length <= 0) || (x509 == NULL)) {
190         LOGE("Failed to convert internal x509 to der format!");
191         CfPrintOpensslError();
192         return CF_ERR_CRYPTO_OPERATION;
193     }
194     unsigned char *der = NULL;
195     (void)i2d_X509(x509, &der);
196     encodedByte->data = (uint8_t *)HcfMalloc(length, 0);
197     if (encodedByte->data == NULL) {
198         LOGE("Failed to malloc for x509 der data!");
199         OPENSSL_free(der);
200         return CF_ERR_MALLOC;
201     }
202     (void)memcpy_s(encodedByte->data, length, der, length);
203     OPENSSL_free(der);
204     encodedByte->len = length;
205     encodedByte->encodingFormat = CF_FORMAT_DER;
206     return CF_SUCCESS;
207 }
208 
GetPublicKeyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey ** keyOut)209 static CfResult GetPublicKeyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey **keyOut)
210 {
211     if ((self == NULL) || (keyOut == NULL)) {
212         LOGE("The input data is null!");
213         return CF_INVALID_PARAMS;
214     }
215     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
216         LOGE("Input wrong class type!");
217         return CF_INVALID_PARAMS;
218     }
219     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
220     X509 *x509 = realCert->x509;
221     EVP_PKEY *pubKey = X509_get_pubkey(x509);
222     if (pubKey == NULL) {
223         LOGE("Failed to get publick key from x509 cert.");
224         CfPrintOpensslError();
225         return CF_ERR_CRYPTO_OPERATION;
226     }
227     X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)HcfMalloc(sizeof(X509PubKeyOpensslImpl), 0);
228     if (keyImpl == NULL) {
229         LOGE("Failed to malloc for public key obj!");
230         EVP_PKEY_free(pubKey);
231         return CF_ERR_MALLOC;
232     }
233     keyImpl->pubKey = pubKey;
234     keyImpl->base.base.base.destroy = DestroyX509PubKeyOpenssl;
235     keyImpl->base.base.base.getClass = GetX509CertPubKeyClass;
236     keyImpl->base.base.getEncoded = GetPubKeyEncoded;
237     keyImpl->base.base.getAlgorithm = GetPubKeyAlgorithm;
238     keyImpl->base.base.getFormat = GetPubKeyFormat;
239     *keyOut = (HcfPubKey *)keyImpl;
240     return CF_SUCCESS;
241 }
242 
CompareCertBlobX509Openssl(HcfX509CertificateSpi * self,HcfCertificate * x509Cert,bool * out)243 static CfResult CompareCertBlobX509Openssl(HcfX509CertificateSpi *self, HcfCertificate *x509Cert, bool *out)
244 {
245     CfResult res = CF_SUCCESS;
246     CfEncodingBlob encodedBlobSelf = { NULL, 0, CF_FORMAT_DER };
247     CfEncodingBlob encodedBlobParam = { NULL, 0, CF_FORMAT_DER };
248     if (x509Cert != NULL) {
249         res = x509Cert->getEncoded(x509Cert, &encodedBlobParam);
250         if (res != CF_SUCCESS) {
251             LOGE("x509Cert getEncoded failed!");
252             return res;
253         }
254         res = GetEncodedX509Openssl(self, &encodedBlobSelf);
255         if (res != CF_SUCCESS) {
256             LOGE("x509Cert GetEncodedX509Openssl failed!");
257             CfFree(encodedBlobParam.data);
258             return res;
259         }
260         if ((encodedBlobSelf.len != encodedBlobParam.len) ||
261             (memcmp(encodedBlobSelf.data, encodedBlobParam.data, encodedBlobSelf.len) != 0)) {
262             *out = false;
263         }
264 
265         CfFree(encodedBlobParam.data);
266         CfFree(encodedBlobSelf.data);
267     }
268 
269     return res;
270 }
271 
CompareNameObjectX509Openssl(HcfX509CertificateSpi * self,const CfBlob * blobObj,X509NameType nameType,bool * out)272 static CfResult CompareNameObjectX509Openssl(
273     HcfX509CertificateSpi *self, const CfBlob *blobObj, X509NameType nameType, bool *out)
274 {
275     CfResult res = CF_SUCCESS;
276     if (blobObj != NULL) {
277         HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
278         X509 *x509 = realCert->x509;
279         res = CompareNameObject(x509, blobObj, nameType, out);
280     }
281     return res;
282 }
283 
CheckValidityWithDateX509Openssl(HcfX509CertificateSpi * self,const char * date)284 static CfResult CheckValidityWithDateX509Openssl(HcfX509CertificateSpi *self, const char *date)
285 {
286     if ((self == NULL) || (date == NULL)) {
287         LOGE("The input data is null!");
288         return CF_INVALID_PARAMS;
289     }
290     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
291         LOGE("Input wrong class type!");
292         return CF_INVALID_PARAMS;
293     }
294     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
295     X509 *x509 = realCert->x509;
296     ASN1_TIME *asn1InputDate = ASN1_TIME_new();
297     if (asn1InputDate == NULL) {
298         LOGE("Failed to malloc for asn1 time.");
299         return CF_ERR_MALLOC;
300     }
301     if (ASN1_TIME_set_string(asn1InputDate, date) != CF_OPENSSL_SUCCESS) {
302         LOGE("Failed to set time for asn1 time.");
303         CfPrintOpensslError();
304         ASN1_TIME_free(asn1InputDate);
305         return CF_ERR_CRYPTO_OPERATION;
306     }
307     CfResult res = CompareDateWithCertTime(x509, asn1InputDate);
308     ASN1_TIME_free(asn1InputDate);
309     return res;
310 }
311 
CompareKeyUsageX509Openssl(HcfX509CertificateSpi * self,const CfBlob * keyUsage,bool * out)312 static CfResult CompareKeyUsageX509Openssl(HcfX509CertificateSpi *self, const CfBlob *keyUsage, bool *out)
313 {
314     if (keyUsage == NULL) {
315         return CF_SUCCESS;
316     }
317     if (keyUsage->size == 0 || keyUsage->data == NULL) {
318         LOGE("invalid param!");
319         return CF_INVALID_PARAMS;
320     }
321     CfBlob cfBlobDataSelf = { 0 };
322     CfResult res = GetKeyUsageX509Openssl(self, &cfBlobDataSelf);
323     if ((res != CF_SUCCESS) && (res != CF_ERR_CRYPTO_OPERATION)) {
324         LOGE("x509Cert GetKeyUsageX509Openssl failed!");
325         return res;
326     }
327     /*
328      * Check If the position of the true value in both arrays is the same.
329      * When two array is in different length, it is considered as match success if the values of the over size part are
330      * false.
331      */
332     uint32_t index = 0;
333     for (; index < keyUsage->size && index < cfBlobDataSelf.size; ++index) {
334         if ((keyUsage->data[index] & 0x01) != (cfBlobDataSelf.data[index] & 0x01)) {
335             *out = false;
336             break;
337         }
338     }
339     if (!(*out)) {
340         CfFree(cfBlobDataSelf.data);
341         return CF_SUCCESS;
342     }
343     for (; index < cfBlobDataSelf.size; ++index) {
344         if (cfBlobDataSelf.data[index] != 0) {
345             *out = false;
346             break;
347         }
348     }
349     for (; index < keyUsage->size; ++index) {
350         if (keyUsage->data[index] != 0) {
351             *out = false;
352             break;
353         }
354     }
355     CfFree(cfBlobDataSelf.data);
356     return CF_SUCCESS;
357 }
358 
CompareSerialNumberX509Openssl(HcfX509CertificateSpi * self,const CfBlob * serialNumber,bool * out)359 static CfResult CompareSerialNumberX509Openssl(HcfX509CertificateSpi *self, const CfBlob *serialNumber, bool *out)
360 {
361     CfResult res = CF_SUCCESS;
362     CfBlob cfBlobDataSelf = { 0 };
363 
364     if (serialNumber != NULL) {
365         if (serialNumber->size == 0 || serialNumber->data == NULL) {
366             LOGE("invalid param!");
367             return CF_INVALID_PARAMS;
368         }
369 
370         res = GetSerialNumberX509Openssl(self, &cfBlobDataSelf);
371         if (res != CF_SUCCESS) {
372             LOGE("x509Cert GetSerialNumberX509Openssl failed!");
373             return res;
374         }
375         do {
376             if (cfBlobDataSelf.size != serialNumber->size) {
377                 *out = false;
378                 break;
379             }
380             int ret = 0;
381             res = CompareBigNum(&cfBlobDataSelf, serialNumber, &ret);
382             if (res != CF_SUCCESS) {
383                 LOGE("x509Cert CompareBigNum failed!");
384                 break;
385             }
386             if (ret != 0) {
387                 *out = false;
388                 break;
389             }
390         } while (0);
391 
392         CfFree(cfBlobDataSelf.data);
393     }
394 
395     return res;
396 }
397 
GetCertPubKey(HcfX509CertificateSpi * self,CfBlob * outBlob)398 static CfResult GetCertPubKey(HcfX509CertificateSpi *self, CfBlob *outBlob)
399 {
400     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
401     X509 *x509 = realCert->x509;
402     EVP_PKEY *pubKey = X509_get_pubkey(x509);
403     if (pubKey == NULL) {
404         CfPrintOpensslError();
405         LOGE("the x509 cert data is error!");
406         return CF_ERR_CRYPTO_OPERATION;
407     }
408 
409     unsigned char *pubKeyBytes = NULL;
410     int32_t pubKeyLen = i2d_PUBKEY(pubKey, &pubKeyBytes);
411     if (pubKeyLen <= 0) {
412         EVP_PKEY_free(pubKey);
413         CfPrintOpensslError();
414         LOGE("Failed to convert internal pubkey to der format!");
415         return CF_ERR_CRYPTO_OPERATION;
416     }
417 
418     int32_t ret = DeepCopyDataToBlob(pubKeyBytes, (uint32_t)pubKeyLen, outBlob);
419     EVP_PKEY_free(pubKey);
420     OPENSSL_free(pubKeyBytes);
421     return ret;
422 }
423 
ComparePublicKeyX509Openssl(HcfX509CertificateSpi * self,const CfBlob * pubKey,bool * out)424 static CfResult ComparePublicKeyX509Openssl(HcfX509CertificateSpi *self, const CfBlob *pubKey, bool *out)
425 {
426     CfResult res = CF_SUCCESS;
427     CfBlob cfBlobDataSelf = { 0, NULL };
428 
429     if (pubKey != NULL) {
430         if (pubKey->size == 0 || pubKey->data == NULL) {
431             LOGE("invalid param!");
432             return CF_INVALID_PARAMS;
433         }
434         res = GetCertPubKey(self, &cfBlobDataSelf);
435         if (res != CF_SUCCESS) {
436             LOGE("x509Cert GetCertPubKey failed!");
437             return CF_ERR_CRYPTO_OPERATION;
438         }
439 
440         if (cfBlobDataSelf.size != pubKey->size) {
441             *out = false;
442             CfBlobDataFree(&cfBlobDataSelf);
443             return res;
444         }
445         if (memcmp(cfBlobDataSelf.data, pubKey->data, cfBlobDataSelf.size) != 0) {
446             *out = false;
447         }
448         CfBlobDataFree(&cfBlobDataSelf);
449     }
450 
451     return res;
452 }
453 
ComparePublicKeyAlgOidX509Openssl(HcfX509CertificateSpi * self,const CfBlob * publicKeyAlgOid,bool * out)454 static CfResult ComparePublicKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, const CfBlob *publicKeyAlgOid, bool *out)
455 {
456     CfResult res = CF_SUCCESS;
457     CfBlob cfBlobDataSelf = { 0 };
458 
459     if (publicKeyAlgOid != NULL) {
460         if (!CfBlobIsStr(publicKeyAlgOid)) {
461             LOGE("publicKeyAlgOid is not string!");
462             return CF_INVALID_PARAMS;
463         }
464         res = GetSubjectPubKeyAlgOidX509Openssl(self, &cfBlobDataSelf);
465         if (res != CF_SUCCESS) {
466             LOGE("x509Cert ComparePublicKeyAlgOidX509Openssl failed!");
467             return res;
468         }
469 
470         if (cfBlobDataSelf.size != publicKeyAlgOid->size ||
471             strncmp((const char *)cfBlobDataSelf.data, (const char *)publicKeyAlgOid->data, cfBlobDataSelf.size) != 0) {
472             *out = false;
473         }
474         CfFree(cfBlobDataSelf.data);
475     }
476 
477     return res;
478 }
479 
GetVersionX509Openssl(HcfX509CertificateSpi * self)480 static long GetVersionX509Openssl(HcfX509CertificateSpi *self)
481 {
482     if (self == NULL) {
483         LOGE("The input data is null!");
484         return INVALID_VERSION;
485     }
486     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
487         LOGE("Input wrong class type!");
488         return INVALID_VERSION;
489     }
490     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
491     X509 *x509 = realCert->x509;
492     return X509_get_version(x509) + 1;
493 }
494 
GetSerialNumberX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)495 static CfResult GetSerialNumberX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
496 {
497     if ((self == NULL) || (out == NULL)) {
498         LOGE("The input data is null!");
499         return CF_INVALID_PARAMS;
500     }
501     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
502         LOGE("Input wrong class type!");
503         return CF_INVALID_PARAMS;
504     }
505 
506     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
507     X509 *x509 = realCert->x509;
508     const ASN1_INTEGER *serial = X509_get0_serialNumber(x509);
509     if (serial == NULL) {
510         LOGE("Failed to get serial number!");
511         return CF_ERR_CRYPTO_OPERATION;
512     }
513 
514     unsigned char *serialNumBytes = NULL;
515     int serialNumLen = i2d_ASN1_INTEGER((ASN1_INTEGER *)serial, &serialNumBytes);
516     if (serialNumLen <= SERIAL_NUMBER_HEDER_SIZE) {
517         CfPrintOpensslError();
518         LOGE("Failed to get serialNumLen!");
519         return CF_ERR_CRYPTO_OPERATION;
520     }
521 
522     CfResult ret = DeepCopyDataToOut((const char *)(serialNumBytes + SERIAL_NUMBER_HEDER_SIZE),
523         (uint32_t)(serialNumLen - SERIAL_NUMBER_HEDER_SIZE), out);
524     OPENSSL_free(serialNumBytes);
525     return ret;
526 }
527 
GetIssuerDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)528 static CfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
529 {
530     if ((self == NULL) || (out == NULL)) {
531         LOGE("[Get issuerDN openssl] The input data is null!");
532         return CF_INVALID_PARAMS;
533     }
534     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
535         LOGE("Input wrong class type!");
536         return CF_INVALID_PARAMS;
537     }
538     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
539     X509 *x509 = realCert->x509;
540     X509_NAME *issuerName = X509_get_issuer_name(x509);
541     if (issuerName == NULL) {
542         LOGE("Failed to get x509 issuerName in openssl!");
543         CfPrintOpensslError();
544         return CF_ERR_CRYPTO_OPERATION;
545     }
546     char *issuer = (char *)HcfMalloc(HCF_MAX_STR_LEN + 1, 0);
547     if (issuer == NULL) {
548         LOGE("Failed to malloc for issuer buffer!");
549         return CF_ERR_MALLOC;
550     }
551 
552     CfResult res = CF_SUCCESS;
553     do {
554         X509_NAME_oneline(issuerName, issuer, HCF_MAX_STR_LEN);
555         size_t length = strlen(issuer) + 1;
556         if (length == 1) {
557             LOGE("Failed to get oneline issuerName in openssl!");
558             res = CF_ERR_CRYPTO_OPERATION;
559             CfPrintOpensslError();
560             break;
561         }
562         res = DeepCopyDataToOut(issuer, length, out);
563     } while (0);
564     CfFree(issuer);
565     return res;
566 }
567 
GetSubjectDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)568 static CfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
569 {
570     if ((self == NULL) || (out == NULL)) {
571         LOGE("[Get subjectDN openssl]The input data is null!");
572         return CF_INVALID_PARAMS;
573     }
574     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
575         LOGE("Input wrong class type!");
576         return CF_INVALID_PARAMS;
577     }
578     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
579     X509 *x509 = realCert->x509;
580     X509_NAME *subjectName = X509_get_subject_name(x509);
581     if (subjectName == NULL) {
582         LOGE("Failed to get x509 subjectName in openssl!");
583         CfPrintOpensslError();
584         return CF_ERR_CRYPTO_OPERATION;
585     }
586     char *subject = (char *)HcfMalloc(HCF_MAX_STR_LEN + 1, 0);
587     if (subject == NULL) {
588         LOGE("Failed to malloc for subject buffer!");
589         return CF_ERR_MALLOC;
590     }
591 
592     CfResult res = CF_SUCCESS;
593     do {
594         X509_NAME_oneline(subjectName, subject, HCF_MAX_STR_LEN);
595         size_t length = strlen(subject) + 1;
596         if (length == 1) {
597             LOGE("Failed to get oneline subjectName in openssl!");
598             CfPrintOpensslError();
599             res = CF_ERR_CRYPTO_OPERATION;
600             break;
601         }
602         res = DeepCopyDataToOut(subject, length, out);
603     } while (0);
604     CfFree(subject);
605     return res;
606 }
607 
GetNotBeforeX509Openssl(HcfX509CertificateSpi * self,CfBlob * outDate)608 static CfResult GetNotBeforeX509Openssl(HcfX509CertificateSpi *self, CfBlob *outDate)
609 {
610     if ((self == NULL) || (outDate == NULL)) {
611         LOGE("Get not before, input is null!");
612         return CF_INVALID_PARAMS;
613     }
614     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
615         LOGE("Get not before, input wrong class type!");
616         return CF_INVALID_PARAMS;
617     }
618     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
619     X509 *x509 = realCert->x509;
620     ASN1_TIME *notBeforeDate = X509_get_notBefore(x509);
621     if (notBeforeDate == NULL) {
622         LOGE("NotBeforeDate is null in x509 cert!");
623         CfPrintOpensslError();
624         return CF_ERR_CRYPTO_OPERATION;
625     }
626     if (ASN1_TIME_normalize(notBeforeDate) != CF_OPENSSL_SUCCESS) {
627         LOGE("Failed to normalize notBeforeDate!");
628         CfPrintOpensslError();
629         return CF_ERR_CRYPTO_OPERATION;
630     }
631     const char *date = (const char *)(notBeforeDate->data);
632     if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
633         LOGE("Failed to get notBeforeDate data!");
634         return CF_ERR_CRYPTO_OPERATION;
635     }
636     uint32_t length = strlen(date) + 1;
637     return DeepCopyDataToOut(date, length, outDate);
638 }
639 
GetNotAfterX509Openssl(HcfX509CertificateSpi * self,CfBlob * outDate)640 static CfResult GetNotAfterX509Openssl(HcfX509CertificateSpi *self, CfBlob *outDate)
641 {
642     if ((self == NULL) || (outDate == NULL)) {
643         LOGE("Get not after, input data is null!");
644         return CF_INVALID_PARAMS;
645     }
646     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
647         LOGE("Get not after, input wrong class type!");
648         return CF_INVALID_PARAMS;
649     }
650     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
651     X509 *x509 = realCert->x509;
652     ASN1_TIME *notAfterDate = X509_get_notAfter(x509);
653     if (notAfterDate == NULL) {
654         LOGE("NotAfterDate is null in x509 cert!");
655         CfPrintOpensslError();
656         return CF_ERR_CRYPTO_OPERATION;
657     }
658     if (ASN1_TIME_normalize(notAfterDate) != CF_OPENSSL_SUCCESS) {
659         LOGE("Failed to normalize notAfterDate!");
660         CfPrintOpensslError();
661         return CF_ERR_CRYPTO_OPERATION;
662     }
663     const char *date = (const char *)(notAfterDate->data);
664     if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
665         LOGE("Failed to get notAfterDate data!");
666         return CF_ERR_CRYPTO_OPERATION;
667     }
668     uint32_t length = strlen(date) + 1;
669     return DeepCopyDataToOut(date, length, outDate);
670 }
671 
GetSignatureX509Openssl(HcfX509CertificateSpi * self,CfBlob * sigOut)672 static CfResult GetSignatureX509Openssl(HcfX509CertificateSpi *self, CfBlob *sigOut)
673 {
674     if ((self == NULL) || (sigOut == NULL)) {
675         LOGE("The input data is null!");
676         return CF_INVALID_PARAMS;
677     }
678     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
679         LOGE("Input wrong class type!");
680         return CF_INVALID_PARAMS;
681     }
682     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
683     X509 *x509 = realCert->x509;
684     const ASN1_BIT_STRING *signature;
685     X509_get0_signature(&signature, NULL, x509);
686     if ((signature == NULL) || (signature->length == 0) || (signature->length > HCF_MAX_BUFFER_LEN)) {
687         LOGE("Failed to get x509 signature in openssl!");
688         CfPrintOpensslError();
689         return CF_ERR_CRYPTO_OPERATION;
690     }
691     sigOut->data = (uint8_t *)HcfMalloc(signature->length, 0);
692     if (sigOut->data == NULL) {
693         LOGE("Failed to malloc for signature data!");
694         return CF_ERR_MALLOC;
695     }
696     (void)memcpy_s(sigOut->data, signature->length, signature->data, signature->length);
697     sigOut->size = signature->length;
698     return CF_SUCCESS;
699 }
700 
GetSigAlgNameX509Openssl(HcfX509CertificateSpi * self,CfBlob * outName)701 static CfResult GetSigAlgNameX509Openssl(HcfX509CertificateSpi *self, CfBlob *outName)
702 {
703     if ((self == NULL) || (outName == NULL)) {
704         LOGE("[GetSigAlgName openssl] The input data is null!");
705         return CF_INVALID_PARAMS;
706     }
707     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
708         LOGE("[GetSigAlgName openssl] Input wrong class type!");
709         return CF_INVALID_PARAMS;
710     }
711     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
712     X509 *x509 = realCert->x509;
713     const X509_ALGOR *alg;
714     X509_get0_signature(NULL, &alg, x509);
715     const ASN1_OBJECT *oidObj;
716     X509_ALGOR_get0(&oidObj, NULL, NULL, alg);
717     char oidStr[OID_STR_MAX_LEN] = { 0 };
718     int32_t resLen = OBJ_obj2txt(oidStr, OID_STR_MAX_LEN, oidObj, 1);
719     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
720         LOGE("Failed to convert x509 object to text!");
721         CfPrintOpensslError();
722         return CF_ERR_CRYPTO_OPERATION;
723     }
724     const char *algName = GetAlgorithmName(oidStr);
725     if (algName == NULL) {
726         return CF_ERR_CRYPTO_OPERATION;
727     }
728     uint32_t len = strlen(algName) + 1;
729     return DeepCopyDataToOut(algName, len, outName);
730 }
731 
GetSigAlgOidX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)732 static CfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
733 {
734     if ((self == NULL) || (out == NULL)) {
735         LOGE("[GetSigAlgOID openssl] The input data is null!");
736         return CF_INVALID_PARAMS;
737     }
738     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
739         LOGE("[GetSigAlgOID openssl] Input wrong class type!");
740         return CF_INVALID_PARAMS;
741     }
742     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
743     X509 *x509 = realCert->x509;
744     const X509_ALGOR *alg;
745     X509_get0_signature(NULL, &alg, x509);
746     const ASN1_OBJECT *oid;
747     X509_ALGOR_get0(&oid, NULL, NULL, alg);
748     char algOid[OID_STR_MAX_LEN] = { 0 };
749     int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, oid, 1);
750     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
751         LOGE("Failed to convert x509 object to text!");
752         CfPrintOpensslError();
753         return CF_ERR_CRYPTO_OPERATION;
754     }
755     uint32_t len = strlen(algOid) + 1;
756     return DeepCopyDataToOut(algOid, len, out);
757 }
758 
GetSigAlgParamsX509Openssl(HcfX509CertificateSpi * self,CfBlob * sigAlgParamsOut)759 static CfResult GetSigAlgParamsX509Openssl(HcfX509CertificateSpi *self, CfBlob *sigAlgParamsOut)
760 {
761     if ((self == NULL) || (sigAlgParamsOut == NULL)) {
762         LOGE("[GetSigAlgParams openssl] The input data is null!");
763         return CF_INVALID_PARAMS;
764     }
765     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
766         LOGE("[GetSigAlgParams openssl] Input wrong class type!");
767         return CF_INVALID_PARAMS;
768     }
769     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
770     X509 *x509 = realCert->x509;
771     const X509_ALGOR *alg;
772     X509_get0_signature(NULL, &alg, x509);
773     int32_t paramType = 0;
774     const void *paramValue = NULL;
775     X509_ALGOR_get0(NULL, &paramType, &paramValue, alg);
776     if (paramType == V_ASN1_UNDEF) {
777         LOGE("get_X509_ALGOR_parameter, no parameters!");
778         return CF_NOT_SUPPORT;
779     }
780     ASN1_TYPE *param = ASN1_TYPE_new();
781     if (param == NULL) {
782         LOGE("Failed to malloc for asn1 type data!");
783         return CF_ERR_MALLOC;
784     }
785     if (ASN1_TYPE_set1(param, paramType, paramValue) != CF_OPENSSL_SUCCESS) {
786         LOGE("Failed to set asn1 type in openssl!");
787         CfPrintOpensslError();
788         ASN1_TYPE_free(param);
789         return CF_ERR_CRYPTO_OPERATION;
790     }
791     unsigned char *out = NULL;
792     int32_t len = i2d_ASN1_TYPE(param, NULL);
793     if (len <= 0) {
794         LOGE("Failed to convert ASN1_TYPE!");
795         CfPrintOpensslError();
796         ASN1_TYPE_free(param);
797         return CF_ERR_CRYPTO_OPERATION;
798     }
799     (void)i2d_ASN1_TYPE(param, &out);
800     ASN1_TYPE_free(param);
801     CfResult res = DeepCopyDataToOut((const char *)out, len, sigAlgParamsOut);
802     OPENSSL_free(out);
803     return res;
804 }
805 
ConvertAsn1String2BoolArray(const ASN1_BIT_STRING * string,CfBlob * boolArr)806 static CfResult ConvertAsn1String2BoolArray(const ASN1_BIT_STRING *string, CfBlob *boolArr)
807 {
808     uint32_t length = ASN1_STRING_length(string) * CHAR_TO_BIT_LEN;
809     if (string->flags & ASN1_STRING_FLAG_BITS_LEFT) {
810         length -= string->flags & FLAG_BIT_LEFT_NUM;
811     }
812     boolArr->data = (uint8_t *)HcfMalloc(length, 0);
813     if (boolArr->data == NULL) {
814         LOGE("Failed to malloc for bit array data!");
815         return CF_ERR_MALLOC;
816     }
817     for (uint32_t i = 0; i < length; i++) {
818         boolArr->data[i] = ASN1_BIT_STRING_get_bit(string, i);
819     }
820     boolArr->size = length;
821     return CF_SUCCESS;
822 }
823 
GetKeyUsageX509Openssl(HcfX509CertificateSpi * self,CfBlob * boolArr)824 static CfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfBlob *boolArr)
825 {
826     if ((self == NULL) || (boolArr == NULL)) {
827         LOGE("[GetKeyUsage openssl] The input data is null!");
828         return CF_INVALID_PARAMS;
829     }
830     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
831         LOGE("Input wrong class type!");
832         return CF_INVALID_PARAMS;
833     }
834     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
835     X509 *x509 = realCert->x509;
836 
837     ASN1_BIT_STRING *keyUsage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
838     if ((keyUsage == NULL) || (keyUsage->length <= 0)|| (keyUsage->length >= HCF_MAX_STR_LEN)) {
839         LOGE("Failed to get x509 keyUsage in openssl!");
840         CfPrintOpensslError();
841         return CF_ERR_CRYPTO_OPERATION;
842     }
843     CfResult res = ConvertAsn1String2BoolArray(keyUsage, boolArr);
844     ASN1_BIT_STRING_free(keyUsage);
845     return res;
846 }
847 
DeepCopyExtendedKeyUsage(const STACK_OF (ASN1_OBJECT)* extUsage,int32_t i,CfArray * keyUsageOut)848 static CfResult DeepCopyExtendedKeyUsage(const STACK_OF(ASN1_OBJECT) *extUsage,
849     int32_t i, CfArray *keyUsageOut)
850 {
851     char usage[OID_STR_MAX_LEN] = { 0 };
852     int32_t resLen = OBJ_obj2txt(usage, OID_STR_MAX_LEN, sk_ASN1_OBJECT_value(extUsage, i), 1);
853     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
854         LOGE("Failed to convert x509 object to text!");
855         CfPrintOpensslError();
856         return CF_ERR_CRYPTO_OPERATION;
857     }
858     uint32_t len = strlen(usage) + 1;
859     keyUsageOut->data[i].data = (uint8_t *)HcfMalloc(len, 0);
860     if (keyUsageOut->data[i].data == NULL) {
861         LOGE("Failed to malloc for key usage!");
862         return CF_ERR_MALLOC;
863     }
864     (void)memcpy_s(keyUsageOut->data[i].data, len, usage, len);
865     keyUsageOut->data[i].size = len;
866     return CF_SUCCESS;
867 }
868 
GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi * self,CfArray * keyUsageOut)869 static CfResult GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfArray *keyUsageOut)
870 {
871     if ((self == NULL) || (keyUsageOut == NULL)) {
872         LOGE("The input data is null!");
873         return CF_INVALID_PARAMS;
874     }
875     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
876         LOGE("Input wrong class type!");
877         return CF_INVALID_PARAMS;
878     }
879     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
880     X509 *x509 = realCert->x509;
881     STACK_OF(ASN1_OBJECT) *extUsage = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL);
882     if (extUsage == NULL) {
883         LOGE("Failed to get x509 extended keyUsage in openssl!");
884         return CF_ERR_CRYPTO_OPERATION;
885     }
886     CfResult res = CF_SUCCESS;
887     do {
888         int32_t size = sk_ASN1_OBJECT_num(extUsage);
889         if (size <= 0) {
890             LOGE("The extended key usage size in openssl is invalid!");
891             CfPrintOpensslError();
892             res = CF_ERR_CRYPTO_OPERATION;
893             break;
894         }
895         int32_t blobSize = sizeof(CfBlob) * size;
896         keyUsageOut->data = (CfBlob *)HcfMalloc(blobSize, 0);
897         if (keyUsageOut->data == NULL) {
898             LOGE("Failed to malloc for keyUsageOut array!");
899             res = CF_ERR_MALLOC;
900             break;
901         }
902         keyUsageOut->count = (uint32_t)size;
903         for (int32_t i = 0; i < size; ++i) {
904             res = DeepCopyExtendedKeyUsage(extUsage, i, keyUsageOut);
905             if (res != CF_SUCCESS) {
906                 LOGE("Falied to copy extended key usage!");
907                 break;
908             }
909         }
910     } while (0);
911     if (res != CF_SUCCESS) {
912         CfArrayDataClearAndFree(keyUsageOut);
913     }
914     sk_ASN1_OBJECT_pop_free(extUsage, ASN1_OBJECT_free);
915     return res;
916 }
917 
GetBasicConstraintsX509Openssl(HcfX509CertificateSpi * self)918 static int32_t GetBasicConstraintsX509Openssl(HcfX509CertificateSpi *self)
919 {
920     if (self == NULL) {
921         LOGE("The input data is null!");
922         return INVALID_CONSTRAINTS_LEN;
923     }
924     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
925         LOGE("Input wrong class type!");
926         return INVALID_CONSTRAINTS_LEN;
927     }
928     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
929     X509 *x509 = realCert->x509;
930     BASIC_CONSTRAINTS *constraints = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x509, NID_basic_constraints, NULL, NULL);
931     if (constraints == NULL) {
932         LOGE("Failed to get basic constraints in openssl!");
933         return INVALID_CONSTRAINTS_LEN;
934     }
935     /* Path len is only valid for CA cert. */
936     if (!constraints->ca) {
937         BASIC_CONSTRAINTS_free(constraints);
938         LOGI("The cert in not a CA!");
939         return INVALID_CONSTRAINTS_LEN;
940     }
941     if ((constraints->pathlen == NULL) || (constraints->pathlen->type == V_ASN1_NEG_INTEGER)) {
942         BASIC_CONSTRAINTS_free(constraints);
943         LOGE("The cert path len is negative in openssl!");
944         return INVALID_CONSTRAINTS_LEN;
945     }
946     long pathLen = ASN1_INTEGER_get(constraints->pathlen);
947     if ((pathLen < 0) || (pathLen > INT_MAX)) {
948         BASIC_CONSTRAINTS_free(constraints);
949         LOGE("Get the overflow path length in openssl!");
950         return INVALID_CONSTRAINTS_LEN;
951     }
952     BASIC_CONSTRAINTS_free(constraints);
953     return (int32_t)pathLen;
954 }
955 
DeepCopyAlternativeNames(const STACK_OF (GENERAL_NAME)* altNames,int32_t i,CfArray * outName)956 static CfResult DeepCopyAlternativeNames(const STACK_OF(GENERAL_NAME) *altNames, int32_t i, CfArray *outName)
957 {
958     GENERAL_NAME *general = sk_GENERAL_NAME_value(altNames, i);
959     int32_t generalType = 0;
960     ASN1_STRING *ans1Str = GENERAL_NAME_get0_value(general, &generalType);
961     const char *str = (const char *)ASN1_STRING_get0_data(ans1Str);
962     if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
963         LOGE("Failed to get x509 altNames string in openssl!");
964         CfPrintOpensslError();
965         return CF_ERR_CRYPTO_OPERATION;
966     }
967     uint32_t nameLen = strlen(str) + 1;
968     outName->data[i].data = (uint8_t *)HcfMalloc(nameLen, 0);
969     if (outName->data[i].data == NULL) {
970         LOGE("Failed to malloc for outName!");
971         return CF_ERR_MALLOC;
972     }
973     (void)memcpy_s(outName->data[i].data, nameLen, str, nameLen);
974     outName->data[i].size = nameLen;
975     return CF_SUCCESS;
976 }
977 
GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi * self,CfArray * outName)978 static CfResult GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi *self, CfArray *outName)
979 {
980     if ((self == NULL) || (outName == NULL)) {
981         LOGE("[GetSubjectAltNames openssl] The input data is null!");
982         return CF_INVALID_PARAMS;
983     }
984     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
985         LOGE("Input wrong class type!");
986         return CF_INVALID_PARAMS;
987     }
988     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
989     X509 *x509 = realCert->x509;
990     STACK_OF(GENERAL_NAME) *subjectAltName = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
991     if (subjectAltName == NULL) {
992         LOGE("Failed to get subjectAltName in openssl!");
993         CfPrintOpensslError();
994         return CF_ERR_CRYPTO_OPERATION;
995     }
996     CfResult res = CF_SUCCESS;
997     do {
998         int32_t size = sk_GENERAL_NAME_num(subjectAltName);
999         if (size <= 0) {
1000             LOGE("The subjectAltName number in openssl is invalid!");
1001             CfPrintOpensslError();
1002             res = CF_ERR_CRYPTO_OPERATION;
1003             break;
1004         }
1005         int32_t blobSize = sizeof(CfBlob) * size;
1006         outName->data = (CfBlob *)HcfMalloc(blobSize, 0);
1007         if (outName->data == NULL) {
1008             LOGE("Failed to malloc for subjectAltName array!");
1009             res = CF_ERR_MALLOC;
1010             break;
1011         }
1012         outName->count = (uint32_t)size;
1013         for (int32_t i = 0; i < size; ++i) {
1014             res = DeepCopyAlternativeNames(subjectAltName, i, outName);
1015             if (res != CF_SUCCESS) {
1016                 LOGE("Falied to copy subjectAltName!");
1017                 break;
1018             }
1019         }
1020     } while (0);
1021     if (res != CF_SUCCESS) {
1022         CfArrayDataClearAndFree(outName);
1023     }
1024     GENERAL_NAMES_free(subjectAltName);
1025     return res;
1026 }
1027 
GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi * self,CfArray * outName)1028 static CfResult GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi *self, CfArray *outName)
1029 {
1030     if ((self == NULL) || (outName == NULL)) {
1031         LOGE("[GetIssuerAltNames openssl] The input data is null!");
1032         return CF_INVALID_PARAMS;
1033     }
1034     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1035         LOGE("Input wrong class type!");
1036         return CF_INVALID_PARAMS;
1037     }
1038     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1039     X509 *x509 = realCert->x509;
1040     STACK_OF(GENERAL_NAME) *issuerAltName = X509_get_ext_d2i(x509, NID_issuer_alt_name, NULL, NULL);
1041     if (issuerAltName == NULL) {
1042         LOGE("Failed to get issuerAltName in openssl!");
1043         CfPrintOpensslError();
1044         return CF_ERR_CRYPTO_OPERATION;
1045     }
1046     CfResult res = CF_SUCCESS;
1047     do {
1048         int32_t size = sk_GENERAL_NAME_num(issuerAltName);
1049         if (size <= 0) {
1050             LOGE("The issuerAltName number in openssl is invalid!");
1051             CfPrintOpensslError();
1052             res = CF_ERR_CRYPTO_OPERATION;
1053             break;
1054         }
1055         int32_t blobSize = sizeof(CfBlob) * size;
1056         outName->data = (CfBlob *)HcfMalloc(blobSize, 0);
1057         if (outName->data == NULL) {
1058             LOGE("Failed to malloc for issuerAltName array!");
1059             res = CF_ERR_MALLOC;
1060             break;
1061         }
1062         outName->count = (uint32_t)size;
1063         for (int32_t i = 0; i < size; ++i) {
1064             res = DeepCopyAlternativeNames(issuerAltName, i, outName);
1065             if (res != CF_SUCCESS) {
1066                 LOGE("Falied to copy issuerAltName!");
1067                 break;
1068             }
1069         }
1070     } while (0);
1071     if (res != CF_SUCCESS) {
1072         CfArrayDataClearAndFree(outName);
1073     }
1074     GENERAL_NAMES_free(issuerAltName);
1075     return res;
1076 }
1077 
MatchPart1(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1078 static CfResult MatchPart1(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1079 {
1080     CfResult res = CF_SUCCESS;
1081     *out = true;
1082 
1083     // x509Cert
1084     res = CompareCertBlobX509Openssl(self, matchParams->x509Cert, out);
1085     if (res != CF_SUCCESS || (*out == false)) {
1086         LOGE("Failed to CompareCertBlob!");
1087         return res;
1088     }
1089     // subject
1090     res = CompareNameObjectX509Openssl(self, matchParams->subject, NAME_TYPE_SUBECT, out);
1091     if (res != CF_SUCCESS || (*out == false)) {
1092         LOGE("Failed to CompareSubject!");
1093         return res;
1094     }
1095     // validDate
1096     if (matchParams->validDate != NULL) {
1097         if (!CfBlobIsStr(matchParams->validDate)) {
1098             LOGE("Invalid param!");
1099             return CF_INVALID_PARAMS;
1100         }
1101         res = CheckValidityWithDateX509Openssl(self, (const char *)matchParams->validDate->data);
1102         if ((res == CF_ERR_CERT_NOT_YET_VALID) || (res == CF_ERR_CERT_HAS_EXPIRED)) {
1103             *out = false;
1104             return CF_SUCCESS;
1105         }
1106         if (res != CF_SUCCESS) {
1107             LOGE("Failed to CheckValidityWithDate!");
1108             return res;
1109         }
1110     }
1111     // issuer
1112     res = CompareNameObjectX509Openssl(self, matchParams->issuer, NAME_TYPE_ISSUER, out);
1113     if (res != CF_SUCCESS || (*out == false)) {
1114         LOGE("Failed to CompareIssuer!");
1115         return res;
1116     }
1117     return res;
1118 }
1119 
MatchPart2(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1120 static CfResult MatchPart2(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1121 {
1122     CfResult res = CF_SUCCESS;
1123     *out = true;
1124 
1125     // keyUsage
1126     res = CompareKeyUsageX509Openssl(self, matchParams->keyUsage, out);
1127     if (res != CF_SUCCESS || (*out == false)) {
1128         LOGE("Failed to CompareKeyUsage!");
1129         return res;
1130     }
1131     // serialNumber
1132     res = CompareSerialNumberX509Openssl(self, matchParams->serialNumber, out);
1133     if (res != CF_SUCCESS || (*out == false)) {
1134         LOGE("Failed to CompareSerialNumber!");
1135         return res;
1136     }
1137     // publicKey
1138     res = ComparePublicKeyX509Openssl(self, matchParams->publicKey, out);
1139     if (res != CF_SUCCESS || (*out == false)) {
1140         LOGE("Failed to ComparePublicKey!");
1141         return res;
1142     }
1143     // publicKeyAlgID
1144     res = ComparePublicKeyAlgOidX509Openssl(self, matchParams->publicKeyAlgID, out);
1145     if (res != CF_SUCCESS || (*out == false)) {
1146         LOGE("Failed to ComparePublicKeyAlgOid!");
1147         return res;
1148     }
1149 
1150     return CF_SUCCESS;
1151 }
1152 
MatchX509Openssl(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1153 static CfResult MatchX509Openssl(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1154 {
1155     LOGI("enter MatchX509Openssl!");
1156     if ((self == NULL) || (matchParams == NULL) || (out == NULL)) {
1157         LOGE("[GetIssuerAltNames openssl] The input data is null!");
1158         return CF_INVALID_PARAMS;
1159     }
1160     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1161         LOGE("Input wrong class type!");
1162         return CF_INVALID_PARAMS;
1163     }
1164     CfResult res = CF_SUCCESS;
1165     *out = true;
1166     res = MatchPart1(self, matchParams, out);
1167     if (res != CF_SUCCESS || (*out == false)) {
1168         LOGE("Failed to Match Part1!");
1169         return res;
1170     }
1171 
1172     res = MatchPart2(self, matchParams, out);
1173     if (res != CF_SUCCESS || (*out == false)) {
1174         LOGE("Failed to Match Part2!");
1175         return res;
1176     }
1177     return CF_SUCCESS;
1178 }
1179 
DeepCopyURIs(ASN1_STRING * uri,uint32_t index,CfArray * outURI)1180 static CfResult DeepCopyURIs(ASN1_STRING *uri, uint32_t index, CfArray *outURI)
1181 {
1182     if (index >= outURI->count) { /* exceed the maximum memory capacity. */
1183         LOGE("exceed the maximum memory capacity, uriCount = %u, malloc count = %u", index, outURI->count);
1184         return CF_ERR_CRYPTO_OPERATION;
1185     }
1186 
1187     const char *str = (const char *)ASN1_STRING_get0_data(uri);
1188     if ((str == NULL) || (strlen(str) > HCF_MAX_STR_LEN)) {
1189         LOGE("Failed to get CRL DP URI string in openssl!");
1190         return CF_ERR_CRYPTO_OPERATION;
1191     }
1192 
1193     uint32_t uriLen = strlen(str) + 1;
1194     outURI->data[index].data = (uint8_t *)HcfMalloc(uriLen, 0);
1195     if (outURI->data[index].data == NULL) {
1196         LOGE("Failed to malloc for outURI[%u]!", index);
1197         return CF_ERR_MALLOC;
1198     }
1199     (void)memcpy_s(outURI->data[index].data, uriLen, str, uriLen);
1200     outURI->data[index].size = uriLen;
1201     return CF_SUCCESS;
1202 }
1203 
GetDpURIFromGenName(GENERAL_NAME * genName,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)1204 static CfResult GetDpURIFromGenName(GENERAL_NAME *genName, bool isFormatOutURI, uint32_t *uriCount, CfArray *outURI)
1205 {
1206     int type = 0;
1207     ASN1_STRING *uri = GENERAL_NAME_get0_value(genName, &type);
1208     if (uri == NULL) {
1209         LOGE("get uri asn1 string failed");
1210         return CF_ERR_CRYPTO_OPERATION;
1211     }
1212 
1213     if (type != GEN_URI) {
1214         LOGI("not URI type, type is %d", type);
1215         return CF_SUCCESS;
1216     }
1217 
1218     if (isFormatOutURI) {
1219         CfResult ret = DeepCopyURIs(uri, *uriCount, outURI);
1220         if (ret != CF_SUCCESS) {
1221             LOGE("copy URI[%u] failed", *uriCount);
1222             return ret;
1223         }
1224     }
1225     *uriCount += 1;
1226     return CF_SUCCESS;
1227 }
1228 
GetDpURIFromGenNames(GENERAL_NAMES * genNames,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)1229 static CfResult GetDpURIFromGenNames(GENERAL_NAMES *genNames, bool isFormatOutURI, uint32_t *uriCount,
1230     CfArray *outURI)
1231 {
1232     CfResult ret = CF_SUCCESS;
1233     int genNameNum = sk_GENERAL_NAME_num(genNames);
1234     for (int i = 0; i < genNameNum; ++i) {
1235         GENERAL_NAME *genName = sk_GENERAL_NAME_value(genNames, i);
1236         if (genName == NULL) {
1237             LOGE("get gen name failed!");
1238             ret = CF_ERR_CRYPTO_OPERATION;
1239             break;
1240         }
1241 
1242         ret = GetDpURIFromGenName(genName, isFormatOutURI, uriCount, outURI);
1243         if (ret != CF_SUCCESS) {
1244             LOGE("get gen name failed!");
1245             break;
1246         }
1247     }
1248     return ret;
1249 }
1250 
GetDpURI(STACK_OF (DIST_POINT)* crlDp,int32_t dpNumber,bool isFormatOutURI,uint32_t * uriCount,CfArray * outURI)1251 static CfResult GetDpURI(STACK_OF(DIST_POINT) *crlDp, int32_t dpNumber, bool isFormatOutURI,
1252     uint32_t *uriCount, CfArray *outURI)
1253 {
1254     CfResult ret = CF_SUCCESS;
1255     for (int i = 0; i < dpNumber; ++i) {
1256         DIST_POINT *dp = sk_DIST_POINT_value(crlDp, i);
1257         if (dp == NULL) {
1258             LOGE("get distribution point failed!");
1259             ret = CF_ERR_CRYPTO_OPERATION;
1260             break;
1261         }
1262 
1263         if (dp->distpoint == NULL || dp->distpoint->type != 0) {
1264             LOGI("not fullnames, continue!");
1265             continue;
1266         }
1267 
1268         ret = GetDpURIFromGenNames(dp->distpoint->name.fullname, isFormatOutURI, uriCount, outURI);
1269         if (ret != CF_SUCCESS) {
1270             LOGE("get dp uri from general names failed");
1271             break;
1272         }
1273     }
1274     if (ret == CF_SUCCESS && isFormatOutURI) {
1275         outURI->count = *uriCount;
1276     }
1277     return ret;
1278 }
1279 
GetCRLDpURI(STACK_OF (DIST_POINT)* crlDp,CfArray * outURI)1280 static CfResult GetCRLDpURI(STACK_OF(DIST_POINT) *crlDp, CfArray *outURI)
1281 {
1282     /* 1. get CRL distribution point URI count */
1283     int32_t dpNumber = sk_DIST_POINT_num(crlDp);
1284     uint32_t uriCount = 0;
1285     CfResult ret = GetDpURI(crlDp, dpNumber, false, &uriCount, outURI);
1286     if (ret != CF_SUCCESS) {
1287         LOGE("get dp URI count failed, ret = %d", ret);
1288         return ret;
1289     }
1290     if (uriCount == 0) {
1291         LOGE("CRL DP URI not exist");
1292         return CF_NOT_EXIST;
1293     }
1294     if (uriCount > CF_MAX_URI_COUNT) {
1295         LOGE("uriCount[%u] exceed max count", uriCount);
1296         return CF_ERR_CRYPTO_OPERATION;
1297     }
1298     LOGI("get uriCount success, uriCount = %u", uriCount);
1299 
1300     /* 2. malloc outArray buffer */
1301     uint32_t blobSize = sizeof(CfBlob) * uriCount;
1302     outURI->data = (CfBlob *)HcfMalloc(blobSize, 0);
1303     if (outURI->data == NULL) {
1304         LOGE("Failed to malloc for outURI array!");
1305         return CF_ERR_MALLOC;
1306     }
1307     outURI->count = uriCount;
1308 
1309     /* 2. copy CRL distribution point URIs */
1310     uriCount = 0;
1311     ret = GetDpURI(crlDp, dpNumber, true, &uriCount, outURI);
1312     if (ret != CF_SUCCESS) {
1313         LOGE("get dp URI format failed, ret = %d", ret);
1314         CfArrayDataClearAndFree(outURI);
1315         return ret;
1316     }
1317 
1318     LOGI("get CRL dp URI success, count = %u", outURI->count);
1319     return ret;
1320 }
1321 
GetCRLDistributionPointsURIX509Openssl(HcfX509CertificateSpi * self,CfArray * outURI)1322 static CfResult GetCRLDistributionPointsURIX509Openssl(HcfX509CertificateSpi *self, CfArray *outURI)
1323 {
1324     if ((self == NULL) || (outURI == NULL)) {
1325         LOGE("[GetCRLDistributionPointsURI openssl] The input data is null!");
1326         return CF_INVALID_PARAMS;
1327     }
1328     if (!IsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1329         LOGE("[GetCRLDistributionPointsURI openssl] Input wrong class type!");
1330         return CF_INVALID_PARAMS;
1331     }
1332 
1333     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1334     X509 *x509 = realCert->x509;
1335     STACK_OF(DIST_POINT) *crlDp = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL);
1336     if (crlDp == NULL) {
1337         LOGE("Failed to get crl distribution point in openssl!");
1338         CfPrintOpensslError();
1339         return CF_NOT_EXIST;
1340     }
1341 
1342     CfResult ret = GetCRLDpURI(crlDp, outURI);
1343     sk_DIST_POINT_pop_free(crlDp, DIST_POINT_free);
1344     return ret;
1345 }
1346 
GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)1347 static CfResult GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
1348 {
1349     CfResult res = CF_SUCCESS;
1350     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1351     X509 *x509 = realCert->x509;
1352     EVP_PKEY *pubkey = X509_get_pubkey(x509);
1353     if (NULL == pubkey) {
1354         LOGE("Failed to get public key from x509 cert.");
1355         CfPrintOpensslError();
1356         return CF_ERR_CRYPTO_OPERATION;
1357     }
1358     int nId = EVP_PKEY_get_base_id(pubkey);
1359     ASN1_OBJECT *obj = OBJ_nid2obj(nId);
1360     if (NULL == obj) {
1361         LOGE("Failed to get algObj from pubkey.");
1362         CfPrintOpensslError();
1363         EVP_PKEY_free(pubkey);
1364         return CF_ERR_CRYPTO_OPERATION;
1365     }
1366 
1367     char algOid[OID_STR_MAX_LEN] = { 0 };
1368     int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, obj, 1);
1369     if ((resLen < 0) || (resLen >= OID_STR_MAX_LEN)) {
1370         LOGE("Failed to convert x509 object to text!");
1371         CfPrintOpensslError();
1372         EVP_PKEY_free(pubkey);
1373         ASN1_OBJECT_free(obj);
1374         return CF_ERR_CRYPTO_OPERATION;
1375     }
1376     uint32_t len = strlen(algOid) + 1;
1377     res = DeepCopyDataToOut(algOid, len, out);
1378     EVP_PKEY_free(pubkey);
1379     ASN1_OBJECT_free(obj);
1380     return res;
1381 }
1382 
CreateX509CertInner(const CfEncodingBlob * encodingBlob)1383 static X509 *CreateX509CertInner(const CfEncodingBlob *encodingBlob)
1384 {
1385     X509 *x509 = NULL;
1386     BIO *bio = BIO_new_mem_buf(encodingBlob->data, encodingBlob->len);
1387     if (bio == NULL) {
1388         LOGE("Openssl bio new buf failed.");
1389         return NULL;
1390     }
1391     LOGD("The input cert format is: %d.", encodingBlob->encodingFormat);
1392     if (encodingBlob->encodingFormat == CF_FORMAT_DER) {
1393         x509 = d2i_X509_bio(bio, NULL);
1394     } else if (encodingBlob->encodingFormat == CF_FORMAT_PEM) {
1395         x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
1396     }
1397     BIO_free(bio);
1398     return x509;
1399 }
1400 
OpensslX509CertSpiCreate(const CfEncodingBlob * inStream,HcfX509CertificateSpi ** spi)1401 CfResult OpensslX509CertSpiCreate(const CfEncodingBlob *inStream, HcfX509CertificateSpi **spi)
1402 {
1403     if ((inStream == NULL) || (inStream->data == NULL) || (spi == NULL)) {
1404         LOGE("The input data blob is null!");
1405         return CF_INVALID_PARAMS;
1406     }
1407     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)HcfMalloc(sizeof(HcfOpensslX509Cert), 0);
1408     if (realCert == NULL) {
1409         LOGE("Failed to malloc for x509 instance!");
1410         return CF_ERR_MALLOC;
1411     }
1412     realCert->x509 = CreateX509CertInner(inStream);
1413     if (realCert->x509 == NULL) {
1414         CfFree(realCert);
1415         LOGE("Failed to create x509 cert from input data!");
1416         return CF_INVALID_PARAMS;
1417     }
1418     realCert->base.base.getClass = GetX509CertClass;
1419     realCert->base.base.destroy = DestroyX509Openssl;
1420     realCert->base.engineVerify = VerifyX509Openssl;
1421     realCert->base.engineGetEncoded = GetEncodedX509Openssl;
1422     realCert->base.engineGetPublicKey = GetPublicKeyX509Openssl;
1423     realCert->base.engineCheckValidityWithDate = CheckValidityWithDateX509Openssl;
1424     realCert->base.engineGetVersion = GetVersionX509Openssl;
1425     realCert->base.engineGetSerialNumber = GetSerialNumberX509Openssl;
1426     realCert->base.engineGetIssuerName = GetIssuerDNX509Openssl;
1427     realCert->base.engineGetSubjectName = GetSubjectDNX509Openssl;
1428     realCert->base.engineGetNotBeforeTime = GetNotBeforeX509Openssl;
1429     realCert->base.engineGetNotAfterTime = GetNotAfterX509Openssl;
1430     realCert->base.engineGetSignature = GetSignatureX509Openssl;
1431     realCert->base.engineGetSignatureAlgName = GetSigAlgNameX509Openssl;
1432     realCert->base.engineGetSignatureAlgOid = GetSigAlgOidX509Openssl;
1433     realCert->base.engineGetSignatureAlgParams = GetSigAlgParamsX509Openssl;
1434     realCert->base.engineGetKeyUsage = GetKeyUsageX509Openssl;
1435     realCert->base.engineGetExtKeyUsage = GetExtendedKeyUsageX509Openssl;
1436     realCert->base.engineGetBasicConstraints = GetBasicConstraintsX509Openssl;
1437     realCert->base.engineGetSubjectAltNames = GetSubjectAltNamesX509Openssl;
1438     realCert->base.engineGetIssuerAltNames = GetIssuerAltNamesX509Openssl;
1439     realCert->base.engineGetCRLDistributionPointsURI = GetCRLDistributionPointsURIX509Openssl;
1440     realCert->base.engineMatch = MatchX509Openssl;
1441 
1442     *spi = (HcfX509CertificateSpi *)realCert;
1443     return CF_SUCCESS;
1444 }
1445