• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "x509_certificate_openssl.h"
17 
18 #include <securec.h>
19 #include <openssl/asn1.h>
20 #include <openssl/bio.h>
21 #include <openssl/x509.h>
22 #include <openssl/x509v3.h>
23 #include <openssl/evp.h>
24 #include <openssl/pem.h>
25 
26 #include "config.h"
27 #include "cf_log.h"
28 #include "cf_memory.h"
29 #include "result.h"
30 #include "cf_result.h"
31 #include "utils.h"
32 #include "x509_certificate.h"
33 #include "certificate_openssl_class.h"
34 #include "certificate_openssl_common.h"
35 
36 #define X509_CERT_PUBLIC_KEY_OPENSSL_CLASS "X509CertPublicKeyOpensslClass"
37 
38 typedef struct {
39     HcfPubKey base;
40     EVP_PKEY *pubKey;
41 } X509PubKeyOpensslImpl;
42 
43 static CfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
44 static CfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
45 static CfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfBlob *boolArr);
46 static CfResult GetSerialNumberX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
47 static CfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
48 static CfResult GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out);
49 
GetX509CertClass(void)50 static const char *GetX509CertClass(void)
51 {
52     return X509_CERT_OPENSSL_CLASS;
53 }
54 
DestroyX509Openssl(CfObjectBase * self)55 static void DestroyX509Openssl(CfObjectBase *self)
56 {
57     if (self == NULL) {
58         return;
59     }
60     if (!CfIsClassMatch(self, GetX509CertClass())) {
61         LOGE("Input wrong class type!");
62         return;
63     }
64     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
65     X509_free(realCert->x509);
66     realCert->x509 = NULL;
67     CfFree(realCert);
68 }
69 
GetX509CertPubKeyClass(void)70 static const char *GetX509CertPubKeyClass(void)
71 {
72     return X509_CERT_PUBLIC_KEY_OPENSSL_CLASS;
73 }
74 
DestroyX509PubKeyOpenssl(HcfObjectBase * self)75 static void DestroyX509PubKeyOpenssl(HcfObjectBase *self)
76 {
77     if (self == NULL) {
78         return;
79     }
80     if (!CfIsPubKeyClassMatch(self, GetX509CertPubKeyClass())) {
81         LOGE("Input wrong class type!");
82         return;
83     }
84     X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
85     if (impl->pubKey != NULL) {
86         EVP_PKEY_free(impl->pubKey);
87         impl->pubKey = NULL;
88     }
89     CfFree(impl);
90 }
91 
GetPubKeyAlgorithm(HcfKey * self)92 static const char *GetPubKeyAlgorithm(HcfKey *self)
93 {
94     (void)self;
95     LOGD("Not supported!");
96     return NULL;
97 }
98 
GetPubKeyEncoded(HcfKey * self,HcfBlob * returnBlob)99 static HcfResult GetPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob)
100 {
101     if (self == NULL || returnBlob == NULL) {
102         LOGE("Input params is invalid.");
103         return HCF_INVALID_PARAMS;
104     }
105     if (!CfIsPubKeyClassMatch((HcfObjectBase *)self, GetX509CertPubKeyClass())) {
106         LOGE("Input wrong class type!");
107         return HCF_INVALID_PARAMS;
108     }
109     X509PubKeyOpensslImpl *impl = (X509PubKeyOpensslImpl *)self;
110 
111     unsigned char *pkBytes = NULL;
112     int32_t pkLen = i2d_PUBKEY(impl->pubKey, &pkBytes);
113     if (pkLen <= 0) {
114         CfPrintOpensslError();
115         LOGE("Failed to convert internal pubkey to der format!");
116         return HCF_ERR_CRYPTO_OPERATION;
117     }
118 
119     returnBlob->data = (uint8_t *)CfMalloc(pkLen, 0);
120     if (returnBlob->data == NULL) {
121         LOGE("Failed to malloc for sig algorithm params!");
122         OPENSSL_free(pkBytes);
123         return HCF_ERR_MALLOC;
124     }
125     (void)memcpy_s(returnBlob->data, pkLen, pkBytes, pkLen);
126     returnBlob->len = (size_t)pkLen;
127 
128     OPENSSL_free(pkBytes);
129     return HCF_SUCCESS;
130 }
131 
GetPubKeyFormat(HcfKey * self)132 static const char *GetPubKeyFormat(HcfKey *self)
133 {
134     (void)self;
135     LOGD("Not supported!");
136     return NULL;
137 }
138 
VerifyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey * key)139 static CfResult VerifyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey *key)
140 {
141     if ((self == NULL) || (key == NULL)) {
142         LOGE("The input data is null!");
143         return CF_INVALID_PARAMS;
144     }
145     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass()) ||
146         (!CfIsPubKeyClassMatch((HcfObjectBase *)key, GetX509CertPubKeyClass()))) {
147         LOGE("Input wrong class type!");
148         return CF_INVALID_PARAMS;
149     }
150     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
151     X509 *x509 = realCert->x509;
152 
153     X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)key;
154     EVP_PKEY *pubKey = keyImpl->pubKey;
155     if (X509_verify(x509, pubKey) != CF_OPENSSL_SUCCESS) {
156         LOGE("Failed to verify x509 cert's signature.");
157         CfPrintOpensslError();
158         return CF_ERR_CRYPTO_OPERATION;
159     }
160     return CF_SUCCESS;
161 }
162 
GetEncodedX509Openssl(HcfX509CertificateSpi * self,CfEncodingBlob * encodedByte)163 static CfResult GetEncodedX509Openssl(HcfX509CertificateSpi *self, CfEncodingBlob *encodedByte)
164 {
165     if ((self == NULL) || (encodedByte == NULL)) {
166         LOGE("The input data is null!");
167         return CF_INVALID_PARAMS;
168     }
169     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
170         LOGE("Input wrong class type!");
171         return CF_INVALID_PARAMS;
172     }
173     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
174     X509 *x509 = realCert->x509;
175 
176     unsigned char *der = NULL;
177     int32_t length = i2d_X509(x509, &der);
178     if (length <= 0 || der == NULL) {
179         LOGE("Failed to convert internal x509 to der format!");
180         CfPrintOpensslError();
181         return CF_ERR_CRYPTO_OPERATION;
182     }
183     encodedByte->data = (uint8_t *)CfMalloc(length, 0);
184     if (encodedByte->data == NULL) {
185         LOGE("Failed to malloc for x509 der data!");
186         OPENSSL_free(der);
187         return CF_ERR_MALLOC;
188     }
189     (void)memcpy_s(encodedByte->data, length, der, length);
190     OPENSSL_free(der);
191     encodedByte->len = length;
192     encodedByte->encodingFormat = CF_FORMAT_DER;
193     return CF_SUCCESS;
194 }
195 
GetPublicKeyX509Openssl(HcfX509CertificateSpi * self,HcfPubKey ** keyOut)196 static CfResult GetPublicKeyX509Openssl(HcfX509CertificateSpi *self, HcfPubKey **keyOut)
197 {
198     if ((self == NULL) || (keyOut == NULL)) {
199         LOGE("The input data is null!");
200         return CF_INVALID_PARAMS;
201     }
202     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
203         LOGE("Input wrong class type!");
204         return CF_INVALID_PARAMS;
205     }
206     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
207     X509 *x509 = realCert->x509;
208 
209     EVP_PKEY *pubKey = X509_get_pubkey(x509);
210     if (pubKey == NULL) {
211         LOGE("Failed to get publick key from x509 cert.");
212         CfPrintOpensslError();
213         return CF_ERR_CRYPTO_OPERATION;
214     }
215     X509PubKeyOpensslImpl *keyImpl = (X509PubKeyOpensslImpl *)CfMalloc(sizeof(X509PubKeyOpensslImpl), 0);
216     if (keyImpl == NULL) {
217         LOGE("Failed to malloc for public key obj!");
218         EVP_PKEY_free(pubKey);
219         return CF_ERR_MALLOC;
220     }
221     keyImpl->pubKey = pubKey;
222     keyImpl->base.base.base.destroy = DestroyX509PubKeyOpenssl;
223     keyImpl->base.base.base.getClass = GetX509CertPubKeyClass;
224     keyImpl->base.base.getEncoded = GetPubKeyEncoded;
225     keyImpl->base.base.getAlgorithm = GetPubKeyAlgorithm;
226     keyImpl->base.base.getFormat = GetPubKeyFormat;
227     *keyOut = (HcfPubKey *)keyImpl;
228     return CF_SUCCESS;
229 }
230 
CompareCertBlobX509Openssl(HcfX509CertificateSpi * self,HcfCertificate * x509Cert,bool * out)231 static CfResult CompareCertBlobX509Openssl(HcfX509CertificateSpi *self, HcfCertificate *x509Cert, bool *out)
232 {
233     CfResult res = CF_SUCCESS;
234     CfEncodingBlob encodedBlobSelf = { NULL, 0, CF_FORMAT_DER };
235     CfEncodingBlob encodedBlobParam = { NULL, 0, CF_FORMAT_DER };
236     if (x509Cert != NULL) {
237         res = x509Cert->getEncoded(x509Cert, &encodedBlobParam);
238         if (res != CF_SUCCESS) {
239             LOGE("x509Cert getEncoded failed!");
240             return res;
241         }
242         res = GetEncodedX509Openssl(self, &encodedBlobSelf);
243         if (res != CF_SUCCESS) {
244             LOGE("x509Cert GetEncodedX509Openssl failed!");
245             CfFree(encodedBlobParam.data);
246             encodedBlobParam.data = NULL;
247             return res;
248         }
249         if ((encodedBlobSelf.len != encodedBlobParam.len) ||
250             (memcmp(encodedBlobSelf.data, encodedBlobParam.data, encodedBlobSelf.len) != 0)) {
251             *out = false;
252         }
253 
254         CfFree(encodedBlobParam.data);
255         encodedBlobParam.data = NULL;
256         CfFree(encodedBlobSelf.data);
257         encodedBlobSelf.data = NULL;
258     }
259 
260     return res;
261 }
262 
GetAuKeyIdDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)263 static CfResult GetAuKeyIdDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
264 {
265     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
266     X509 *x509 = realCert->x509;
267     AUTHORITY_KEYID *akid = X509_get_ext_d2i(x509, NID_authority_key_identifier, NULL, NULL);
268     if (akid == NULL) {
269         LOGE("Failed to get authority key identifier!");
270         return CF_ERR_CRYPTO_OPERATION;
271     }
272 
273     unsigned char *akidBytes = NULL;
274     int32_t akidLen = i2d_AUTHORITY_KEYID(akid, &akidBytes);
275     if (akidLen <= 0) {
276         AUTHORITY_KEYID_free(akid);
277         CfPrintOpensslError();
278         LOGE("Failed to convert akid to der format!");
279         return CF_ERR_CRYPTO_OPERATION;
280     }
281     CfResult res = DeepCopyDataToBlob(akidBytes, (uint32_t)akidLen, out);
282     AUTHORITY_KEYID_free(akid);
283     OPENSSL_free(akidBytes);
284     return res;
285 }
286 
GetSubKeyIdDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)287 static CfResult GetSubKeyIdDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
288 {
289     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
290     X509 *x509 = realCert->x509;
291     ASN1_OCTET_STRING *skid = X509_get_ext_d2i(x509, NID_subject_key_identifier, NULL, NULL);
292     if (skid == NULL) {
293         LOGE("Failed to get subject key identifier!");
294         return CF_ERR_CRYPTO_OPERATION;
295     }
296     unsigned char *skidBytes = NULL;
297     int32_t nLen = i2d_ASN1_OCTET_STRING(skid, &skidBytes);
298     if (nLen <= 0) {
299         ASN1_OCTET_STRING_free(skid);
300         CfPrintOpensslError();
301         LOGE("Failed to convert subject key id to der format!");
302         return CF_ERR_CRYPTO_OPERATION;
303     }
304     CfResult res = DeepCopyDataToBlob(skidBytes, (uint32_t)nLen, out);
305     ASN1_OCTET_STRING_free(skid);
306     OPENSSL_free(skidBytes);
307     return res;
308 }
309 
ConvertName(const CfBlob * blobObj,CfBlob * cfBlobDataParam,X509NameType nameType)310 static CfResult ConvertName(const CfBlob *blobObj, CfBlob *cfBlobDataParam, X509NameType nameType)
311 {
312     switch (nameType) {
313         case NAME_TYPE_SUBJECT:
314         case NAME_TYPE_ISSUER:
315             return ConvertNameDerDataToString(blobObj->data, blobObj->size, cfBlobDataParam);
316         case NAME_TYPE_AUKEYID:
317         case NAME_TYPE_SUBKEYID:
318             return DeepCopyDataToBlob(blobObj->data, blobObj->size, cfBlobDataParam);
319         default:
320             return CF_INVALID_PARAMS;
321     }
322 }
323 
CompareNameObjectX509Openssl(HcfX509CertificateSpi * self,const CfBlob * blobObj,X509NameType nameType,bool * out)324 static CfResult CompareNameObjectX509Openssl(
325     HcfX509CertificateSpi *self, const CfBlob *blobObj, X509NameType nameType, bool *out)
326 {
327     CfResult res = CF_SUCCESS;
328     CfBlob cfBlobDataSelf = { 0 };
329     CfBlob cfBlobDataParam = { 0 };
330 
331     if (blobObj != NULL) {
332         res = ConvertName(blobObj, &cfBlobDataParam, nameType);
333         if (res != CF_SUCCESS) {
334             LOGE("Convert name der data to string failed!");
335             return res;
336         }
337 
338         switch (nameType) {
339             case NAME_TYPE_SUBJECT:
340                 res = GetSubjectDNX509Openssl(self, &cfBlobDataSelf);
341                 break;
342             case NAME_TYPE_ISSUER:
343                 res = GetIssuerDNX509Openssl(self, &cfBlobDataSelf);
344                 break;
345             case NAME_TYPE_AUKEYID:
346                 res = GetAuKeyIdDNX509Openssl(self, &cfBlobDataSelf);
347                 break;
348             case NAME_TYPE_SUBKEYID:
349                 res = GetSubKeyIdDNX509Openssl(self, &cfBlobDataSelf);
350                 break;
351             default:
352                 LOGE("Unknown nameType!");
353                 CfFree(cfBlobDataParam.data);
354                 cfBlobDataParam.data = NULL;
355                 return CF_INVALID_PARAMS;
356         }
357 
358         if (res != CF_SUCCESS) {
359             LOGE("X509Cert get param object failed!");
360             CfFree(cfBlobDataParam.data);
361             cfBlobDataParam.data = NULL;
362             return res;
363         }
364 
365         *out =
366             (cfBlobDataSelf.size == cfBlobDataParam.size) &&
367             (strncmp((const char *)cfBlobDataSelf.data, (const char *)cfBlobDataParam.data, cfBlobDataSelf.size) == 0);
368         CfFree(cfBlobDataSelf.data);
369         cfBlobDataSelf.data = NULL;
370         CfFree(cfBlobDataParam.data);
371         cfBlobDataParam.data = NULL;
372     }
373 
374     return res;
375 }
376 
CheckValidityWithDateX509Openssl(HcfX509CertificateSpi * self,const char * date)377 static CfResult CheckValidityWithDateX509Openssl(HcfX509CertificateSpi *self, const char *date)
378 {
379     if ((self == NULL) || (date == NULL)) {
380         LOGE("The input data is null!");
381         return CF_INVALID_PARAMS;
382     }
383     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
384         LOGE("Input wrong class type!");
385         return CF_INVALID_PARAMS;
386     }
387     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
388     X509 *x509 = realCert->x509;
389 
390     ASN1_TIME *asn1InputDate = ASN1_TIME_new();
391     if (asn1InputDate == NULL) {
392         LOGE("Failed to malloc for asn1 time.");
393         return CF_ERR_MALLOC;
394     }
395     if (ASN1_TIME_set_string(asn1InputDate, date) != CF_OPENSSL_SUCCESS) {
396         LOGE("Failed to set time for asn1 time.");
397         CfPrintOpensslError();
398         ASN1_TIME_free(asn1InputDate);
399         return CF_ERR_CRYPTO_OPERATION;
400     }
401     CfResult res = CompareDateWithCertTime(x509, asn1InputDate);
402     ASN1_TIME_free(asn1InputDate);
403     return res;
404 }
405 
CompareKeyUsageX509Openssl(HcfX509CertificateSpi * self,const CfBlob * keyUsage,bool * out)406 static CfResult CompareKeyUsageX509Openssl(HcfX509CertificateSpi *self, const CfBlob *keyUsage, bool *out)
407 {
408     if (keyUsage == NULL) {
409         return CF_SUCCESS;
410     }
411     if (keyUsage->size == 0 || keyUsage->data == NULL) {
412         LOGE("invalid param!");
413         return CF_INVALID_PARAMS;
414     }
415     CfBlob cfBlobDataSelf = { 0 };
416     CfResult res = GetKeyUsageX509Openssl(self, &cfBlobDataSelf);
417     if ((res != CF_SUCCESS) && (res != CF_ERR_CRYPTO_OPERATION)) {
418         LOGE("x509Cert GetKeyUsageX509Openssl failed!");
419         return res;
420     }
421     /*
422      * Check If the position of the true value in both arrays is the same.
423      * When two array is in different length, it is considered as match success if the values of the over size part are
424      * false.
425      */
426     uint32_t index = 0;
427     for (; index < keyUsage->size && index < cfBlobDataSelf.size; ++index) {
428         if ((keyUsage->data[index] & 0x01) != (cfBlobDataSelf.data[index] & 0x01)) {
429             *out = false;
430             break;
431         }
432     }
433     if (!(*out)) {
434         CfFree(cfBlobDataSelf.data);
435         cfBlobDataSelf.data = NULL;
436         return CF_SUCCESS;
437     }
438     for (; index < cfBlobDataSelf.size; ++index) {
439         if (cfBlobDataSelf.data[index] != 0) {
440             *out = false;
441             break;
442         }
443     }
444     for (; index < keyUsage->size; ++index) {
445         if (keyUsage->data[index] != 0) {
446             *out = false;
447             break;
448         }
449     }
450     CfFree(cfBlobDataSelf.data);
451     cfBlobDataSelf.data = NULL;
452     return CF_SUCCESS;
453 }
454 
CompareSerialNumberX509Openssl(HcfX509CertificateSpi * self,const CfBlob * serialNumber,bool * out)455 static CfResult CompareSerialNumberX509Openssl(HcfX509CertificateSpi *self, const CfBlob *serialNumber, bool *out)
456 {
457     CfResult res = CF_SUCCESS;
458     CfBlob cfBlobDataSelf = { 0 };
459 
460     if (serialNumber != NULL) {
461         if (serialNumber->size == 0 || serialNumber->data == NULL) {
462             LOGE("invalid param!");
463             return CF_INVALID_PARAMS;
464         }
465 
466         res = GetSerialNumberX509Openssl(self, &cfBlobDataSelf);
467         if (res != CF_SUCCESS) {
468             LOGE("x509Cert GetSerialNumberX509Openssl failed!");
469             return res;
470         }
471         do {
472             int ret = 0;
473             res = CompareBigNum(&cfBlobDataSelf, serialNumber, &ret);
474             if (res != CF_SUCCESS) {
475                 LOGE("x509Cert CompareBigNum failed!");
476                 break;
477             }
478             if (ret != 0) {
479                 *out = false;
480                 break;
481             }
482         } while (0);
483 
484         CfFree(cfBlobDataSelf.data);
485         cfBlobDataSelf.data = NULL;
486     }
487 
488     return res;
489 }
490 
GetCertPubKey(HcfX509CertificateSpi * self,CfBlob * outBlob)491 static CfResult GetCertPubKey(HcfX509CertificateSpi *self, CfBlob *outBlob)
492 {
493     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
494     X509 *x509 = realCert->x509;
495     EVP_PKEY *pubKey = X509_get_pubkey(x509);
496     if (pubKey == NULL) {
497         CfPrintOpensslError();
498         LOGE("the x509 cert data is error!");
499         return CF_ERR_CRYPTO_OPERATION;
500     }
501 
502     unsigned char *pubKeyBytes = NULL;
503     int32_t pubKeyLen = i2d_PUBKEY(pubKey, &pubKeyBytes);
504     if (pubKeyLen <= 0) {
505         EVP_PKEY_free(pubKey);
506         CfPrintOpensslError();
507         LOGE("Failed to convert internal pubkey to der format!");
508         return CF_ERR_CRYPTO_OPERATION;
509     }
510 
511     int32_t ret = DeepCopyDataToBlob(pubKeyBytes, (uint32_t)pubKeyLen, outBlob);
512     EVP_PKEY_free(pubKey);
513     OPENSSL_free(pubKeyBytes);
514     return ret;
515 }
516 
ComparePublicKeyX509Openssl(HcfX509CertificateSpi * self,const CfBlob * pubKey,bool * out)517 static CfResult ComparePublicKeyX509Openssl(HcfX509CertificateSpi *self, const CfBlob *pubKey, bool *out)
518 {
519     CfResult res = CF_SUCCESS;
520     CfBlob cfBlobDataSelf = { 0, NULL };
521 
522     if (pubKey != NULL) {
523         if (pubKey->size == 0 || pubKey->data == NULL) {
524             LOGE("invalid param!");
525             return CF_INVALID_PARAMS;
526         }
527         res = GetCertPubKey(self, &cfBlobDataSelf);
528         if (res != CF_SUCCESS) {
529             LOGE("x509Cert GetCertPubKey failed!");
530             return CF_ERR_CRYPTO_OPERATION;
531         }
532 
533         if (cfBlobDataSelf.size != pubKey->size) {
534             *out = false;
535             CfBlobDataFree(&cfBlobDataSelf);
536             return res;
537         }
538         if (memcmp(cfBlobDataSelf.data, pubKey->data, cfBlobDataSelf.size) != 0) {
539             *out = false;
540         }
541         CfBlobDataFree(&cfBlobDataSelf);
542     }
543 
544     return res;
545 }
546 
ComparePublicKeyAlgOidX509Openssl(HcfX509CertificateSpi * self,const CfBlob * publicKeyAlgOid,bool * out)547 static CfResult ComparePublicKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, const CfBlob *publicKeyAlgOid, bool *out)
548 {
549     CfResult res = CF_SUCCESS;
550     CfBlob cfBlobDataSelf = { 0 };
551 
552     if (publicKeyAlgOid != NULL) {
553         if (!CfBlobIsStr(publicKeyAlgOid)) {
554             LOGE("publicKeyAlgOid is not string!");
555             return CF_INVALID_PARAMS;
556         }
557         res = GetSubjectPubKeyAlgOidX509Openssl(self, &cfBlobDataSelf);
558         if (res != CF_SUCCESS) {
559             LOGE("x509Cert ComparePublicKeyAlgOidX509Openssl failed!");
560             return res;
561         }
562 
563         if (cfBlobDataSelf.size != publicKeyAlgOid->size ||
564             strncmp((const char *)cfBlobDataSelf.data, (const char *)publicKeyAlgOid->data, cfBlobDataSelf.size) != 0) {
565             *out = false;
566         }
567         CfFree(cfBlobDataSelf.data);
568         cfBlobDataSelf.data = NULL;
569     }
570 
571     return res;
572 }
573 
GetVersionX509Openssl(HcfX509CertificateSpi * self)574 static long GetVersionX509Openssl(HcfX509CertificateSpi *self)
575 {
576     if (self == NULL) {
577         LOGE("The input data is null!");
578         return INVALID_VERSION;
579     }
580     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
581         LOGE("Input wrong class type!");
582         return INVALID_VERSION;
583     }
584     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
585     X509 *x509 = realCert->x509;
586     if (x509 == NULL) {
587         LOGE("X509 cert is null!");
588         return INVALID_VERSION;
589     }
590     return X509_get_version(x509) + 1;
591 }
592 
GetSerialNumberX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)593 static CfResult GetSerialNumberX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
594 {
595     if ((self == NULL) || (out == NULL)) {
596         LOGE("The input data is null!");
597         return CF_INVALID_PARAMS;
598     }
599     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
600         LOGE("Input wrong class type!");
601         return CF_INVALID_PARAMS;
602     }
603 
604     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
605     X509 *x509 = realCert->x509;
606 
607     const ASN1_INTEGER *serial = X509_get0_serialNumber(x509);
608     if (serial == NULL) {
609         LOGE("Failed to get serial number!");
610         return CF_ERR_CRYPTO_OPERATION;
611     }
612 
613     unsigned char *serialNumBytes = NULL;
614     int serialNumLen = i2d_ASN1_INTEGER((ASN1_INTEGER *)serial, &serialNumBytes);
615     if (serialNumLen <= SERIAL_NUMBER_HEDER_SIZE) {
616         CfPrintOpensslError();
617         LOGE("Failed to get serialNumLen!");
618         return CF_ERR_CRYPTO_OPERATION;
619     }
620 
621     CfResult ret = DeepCopyDataToOut((const char *)(serialNumBytes + SERIAL_NUMBER_HEDER_SIZE),
622         (uint32_t)(serialNumLen - SERIAL_NUMBER_HEDER_SIZE), out);
623     OPENSSL_free(serialNumBytes);
624     return ret;
625 }
626 
GetIssuerDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)627 static CfResult GetIssuerDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
628 {
629     if ((self == NULL) || (out == NULL)) {
630         LOGE("[Get issuerDN openssl] The input data is null!");
631         return CF_INVALID_PARAMS;
632     }
633     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
634         LOGE("Input wrong class type!");
635         return CF_INVALID_PARAMS;
636     }
637     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
638     X509 *x509 = realCert->x509;
639 
640     X509_NAME *issuerName = X509_get_issuer_name(x509);
641     if (issuerName == NULL) {
642         LOGE("Failed to get x509 issuerName in openssl!");
643         CfPrintOpensslError();
644         return CF_ERR_CRYPTO_OPERATION;
645     }
646     char *issuer = (char *)CfMalloc(HCF_MAX_STR_LEN + 1, 0);
647     if (issuer == NULL) {
648         LOGE("Failed to malloc for issuer buffer!");
649         return CF_ERR_MALLOC;
650     }
651 
652     CfResult res = CF_SUCCESS;
653     do {
654         X509_NAME_oneline(issuerName, issuer, HCF_MAX_STR_LEN);
655         size_t length = strlen(issuer) + 1;
656         if (length == 1) {
657             LOGE("Failed to get oneline issuerName in openssl!");
658             res = CF_ERR_CRYPTO_OPERATION;
659             CfPrintOpensslError();
660             break;
661         }
662         res = DeepCopyDataToOut(issuer, length, out);
663     } while (0);
664     CfFree(issuer);
665     issuer = NULL;
666     return res;
667 }
668 
GetIssuerDNX509OpensslDer(HcfX509CertificateSpi * self,CfBlob * out)669 static CfResult GetIssuerDNX509OpensslDer(HcfX509CertificateSpi *self, CfBlob *out)
670 {
671     if ((self == NULL) || (out == NULL)) {
672         LOGE("[Get issuerDN openssl der] The input data is null!");
673         return CF_ERR_INTERNAL;
674     }
675     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
676         LOGE("Input wrong class type!");
677         return CF_ERR_INTERNAL;
678     }
679     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
680     X509 *x509 = realCert->x509;
681 
682     X509_NAME *issuerName = X509_get_issuer_name(x509);
683     if (issuerName == NULL) {
684         LOGE("Failed to get x509 issuerName in openssl!");
685         CfPrintOpensslError();
686         return CF_ERR_CRYPTO_OPERATION;
687     }
688 
689     int32_t size = i2d_X509_NAME(issuerName, &(out->data));
690     if (size <= 0) {
691         LOGE("Failed to get issuerName DER data!");
692         CfPrintOpensslError();
693         return CF_ERR_CRYPTO_OPERATION;
694     }
695     out->size = (uint32_t)size;
696     return CF_SUCCESS;
697 }
698 
GetIssuerDNX509OpensslEx(HcfX509CertificateSpi * self,CfEncodinigType encodingType,CfBlob * out)699 static CfResult GetIssuerDNX509OpensslEx(HcfX509CertificateSpi *self, CfEncodinigType encodingType, CfBlob *out)
700 {
701     if ((self == NULL) || (out == NULL)) {
702         LOGE("[Get issuerDN utf8 openssl] The input data is null!");
703         return CF_ERR_INTERNAL;
704     }
705     if (encodingType != CF_ENCODING_UTF8) {
706         LOGE("[Get issuerDN utf8 openssl] encodingType is not utf8!");
707         return CF_ERR_PARAMETER_CHECK;
708     }
709     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
710         LOGE("Input wrong class type!");
711         return CF_ERR_INTERNAL;
712     }
713     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
714     X509 *x509 = realCert->x509;
715 
716     X509_NAME *issuerName = X509_get_issuer_name(x509);
717     if (issuerName == NULL) {
718         LOGE("Failed to get x509 issuerName in openssl!");
719         CfPrintOpensslError();
720         return CF_ERR_CRYPTO_OPERATION;
721     }
722     BIO *bio = BIO_new(BIO_s_mem());
723     if (bio == NULL) {
724         LOGE("BIO new fail.");
725         CfPrintOpensslError();
726         return CF_ERR_CRYPTO_OPERATION;
727     }
728     CfResult res = CF_SUCCESS;
729     do {
730         int ret = X509_NAME_print_ex(bio, issuerName, 0, XN_FLAG_SEP_COMMA_PLUS | ASN1_STRFLGS_UTF8_CONVERT);
731         if (ret <= 0) {
732             LOGE("Failed to X509_NAME_print_ex in openssl!");
733             CfPrintOpensslError();
734             res = CF_ERR_CRYPTO_OPERATION;
735             break;
736         }
737         res = CopyMemFromBIO(bio, out);
738         if (res != CF_SUCCESS) {
739             LOGE("CopyMemFromBIO failed!");
740             break;
741         }
742     } while (0);
743     BIO_free(bio);
744     return res;
745 }
746 
GetSubjectDNX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)747 static CfResult GetSubjectDNX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
748 {
749     if ((self == NULL) || (out == NULL)) {
750         LOGE("[Get subjectDN openssl]The input data is null!");
751         return CF_INVALID_PARAMS;
752     }
753     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
754         LOGE("Input wrong class type!");
755         return CF_INVALID_PARAMS;
756     }
757     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
758     X509 *x509 = realCert->x509;
759 
760     X509_NAME *subjectName = X509_get_subject_name(x509);
761     if (subjectName == NULL) {
762         LOGE("Failed to get x509 subjectName in openssl!");
763         CfPrintOpensslError();
764         return CF_ERR_CRYPTO_OPERATION;
765     }
766     char *subject = (char *)CfMalloc(HCF_MAX_STR_LEN + 1, 0);
767     if (subject == NULL) {
768         LOGE("Failed to malloc for subject buffer!");
769         return CF_ERR_MALLOC;
770     }
771 
772     CfResult res = CF_SUCCESS;
773     do {
774         X509_NAME_oneline(subjectName, subject, HCF_MAX_STR_LEN);
775         size_t length = strlen(subject) + 1;
776         if (length == 1) {
777             LOGE("Failed to get oneline subjectName in openssl!");
778             CfPrintOpensslError();
779             res = CF_ERR_CRYPTO_OPERATION;
780             break;
781         }
782         res = DeepCopyDataToOut(subject, length, out);
783     } while (0);
784     CfFree(subject);
785     subject = NULL;
786     return res;
787 }
788 
GetSubjectDNX509OpensslDer(HcfX509CertificateSpi * self,CfBlob * out)789 static CfResult GetSubjectDNX509OpensslDer(HcfX509CertificateSpi *self, CfBlob *out)
790 {
791     if ((self == NULL) || (out == NULL)) {
792         LOGE("[Get subjectDN openssl]The input data is null!");
793         return CF_ERR_INTERNAL;
794     }
795     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
796         LOGE("Input wrong class type!");
797         return CF_ERR_INTERNAL;
798     }
799     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
800     X509 *x509 = realCert->x509;
801 
802     X509_NAME *subjectName = X509_get_subject_name(x509);
803     if (subjectName == NULL) {
804         LOGE("Failed to get x509 subjectName in openssl!");
805         CfPrintOpensslError();
806         return CF_ERR_CRYPTO_OPERATION;
807     }
808 
809     int32_t size = i2d_X509_NAME(subjectName, &(out->data));
810     if (size <= 0) {
811         LOGE("Failed to get subject DER data!");
812         CfPrintOpensslError();
813         return CF_ERR_CRYPTO_OPERATION;
814     }
815     out->size = (uint32_t)size;
816     return CF_SUCCESS;
817 }
818 
GetSubjectDNX509OpensslEx(HcfX509CertificateSpi * self,CfEncodinigType encodingType,CfBlob * out)819 static CfResult GetSubjectDNX509OpensslEx(HcfX509CertificateSpi *self, CfEncodinigType encodingType, CfBlob *out)
820 {
821     if ((self == NULL) || (out == NULL) || (encodingType != CF_ENCODING_UTF8)) {
822         LOGE("[Get utf8 subjectDN openssl]The input data is null or encodingType is not utf8!");
823         return CF_INVALID_PARAMS;
824     }
825     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
826         LOGE("Input wrong class type!");
827         return CF_INVALID_PARAMS;
828     }
829     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
830     X509 *x509 = realCert->x509;
831 
832     X509_NAME *subjectName = X509_get_subject_name(x509);
833     if (subjectName == NULL) {
834         LOGE("Failed to get x509 subjectName in openssl!");
835         CfPrintOpensslError();
836         return CF_ERR_CRYPTO_OPERATION;
837     }
838     CfResult res = CF_SUCCESS;
839     BIO *bio = BIO_new(BIO_s_mem());
840     if (bio == NULL) {
841         LOGE("BIO new fail.");
842         CfPrintOpensslError();
843         return CF_ERR_CRYPTO_OPERATION;
844     }
845     do {
846         int ret = X509_NAME_print_ex(bio, subjectName, 0, XN_FLAG_SEP_COMMA_PLUS | ASN1_STRFLGS_UTF8_CONVERT);
847         if (ret <= 0) {
848             LOGE("Failed to X509_NAME_print_ex in openssl!");
849             CfPrintOpensslError();
850             res = CF_ERR_CRYPTO_OPERATION;
851             break;
852         }
853         res = CopyMemFromBIO(bio, out);
854         if (res != CF_SUCCESS) {
855             LOGE("CopyMemFromBIO failed!");
856             break;
857         }
858     } while (0);
859     BIO_free(bio);
860     return res;
861 }
862 
GetNotBeforeX509Openssl(HcfX509CertificateSpi * self,CfBlob * outDate)863 static CfResult GetNotBeforeX509Openssl(HcfX509CertificateSpi *self, CfBlob *outDate)
864 {
865     if ((self == NULL) || (outDate == NULL)) {
866         LOGE("Get not before, input is null!");
867         return CF_INVALID_PARAMS;
868     }
869     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
870         LOGE("Get not before, input wrong class type!");
871         return CF_INVALID_PARAMS;
872     }
873     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
874     X509 *x509 = realCert->x509;
875 
876     ASN1_TIME *notBeforeDate = X509_get_notBefore(x509);
877     if (notBeforeDate == NULL) {
878         LOGE("NotBeforeDate is null in x509 cert!");
879         CfPrintOpensslError();
880         return CF_ERR_CRYPTO_OPERATION;
881     }
882     if (ASN1_TIME_normalize(notBeforeDate) != CF_OPENSSL_SUCCESS) {
883         LOGE("Failed to normalize notBeforeDate!");
884         CfPrintOpensslError();
885         return CF_ERR_CRYPTO_OPERATION;
886     }
887     const char *date = (const char *)(notBeforeDate->data);
888     if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
889         LOGE("Failed to get notBeforeDate data!");
890         return CF_ERR_CRYPTO_OPERATION;
891     }
892     uint32_t length = strlen(date) + 1;
893     return DeepCopyDataToOut(date, length, outDate);
894 }
895 
GetNotAfterX509Openssl(HcfX509CertificateSpi * self,CfBlob * outDate)896 static CfResult GetNotAfterX509Openssl(HcfX509CertificateSpi *self, CfBlob *outDate)
897 {
898     if ((self == NULL) || (outDate == NULL)) {
899         LOGE("Get not after, input data is null!");
900         return CF_INVALID_PARAMS;
901     }
902     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
903         LOGE("Get not after, input wrong class type!");
904         return CF_INVALID_PARAMS;
905     }
906     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
907     X509 *x509 = realCert->x509;
908 
909     ASN1_TIME *notAfterDate = X509_get_notAfter(x509);
910     if (notAfterDate == NULL) {
911         LOGE("NotAfterDate is null in x509 cert!");
912         CfPrintOpensslError();
913         return CF_ERR_CRYPTO_OPERATION;
914     }
915     if (ASN1_TIME_normalize(notAfterDate) != CF_OPENSSL_SUCCESS) {
916         LOGE("Failed to normalize notAfterDate!");
917         CfPrintOpensslError();
918         return CF_ERR_CRYPTO_OPERATION;
919     }
920     const char *date = (const char *)(notAfterDate->data);
921     if ((date == NULL) || (strlen(date) > HCF_MAX_STR_LEN)) {
922         LOGE("Failed to get notAfterDate data!");
923         return CF_ERR_CRYPTO_OPERATION;
924     }
925     uint32_t length = strlen(date) + 1;
926     return DeepCopyDataToOut(date, length, outDate);
927 }
928 
GetSignatureX509Openssl(HcfX509CertificateSpi * self,CfBlob * sigOut)929 static CfResult GetSignatureX509Openssl(HcfX509CertificateSpi *self, CfBlob *sigOut)
930 {
931     if ((self == NULL) || (sigOut == NULL)) {
932         LOGE("The input data is null!");
933         return CF_INVALID_PARAMS;
934     }
935     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
936         LOGE("Input wrong class type!");
937         return CF_INVALID_PARAMS;
938     }
939     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
940     X509 *x509 = realCert->x509;
941 
942     const ASN1_BIT_STRING *signature = NULL;
943     X509_get0_signature(&signature, NULL, x509);
944     if ((signature == NULL) || (signature->length == 0) || (signature->length > HCF_MAX_BUFFER_LEN)) {
945         LOGE("Failed to get x509 signature in openssl!");
946         CfPrintOpensslError();
947         return CF_ERR_CRYPTO_OPERATION;
948     }
949     sigOut->data = (uint8_t *)CfMalloc(signature->length, 0);
950     if (sigOut->data == NULL) {
951         LOGE("Failed to malloc for signature data!");
952         return CF_ERR_MALLOC;
953     }
954     (void)memcpy_s(sigOut->data, signature->length, signature->data, signature->length);
955     sigOut->size = signature->length;
956     return CF_SUCCESS;
957 }
958 
GetSigAlgNameX509Openssl(HcfX509CertificateSpi * self,CfBlob * outName)959 static CfResult GetSigAlgNameX509Openssl(HcfX509CertificateSpi *self, CfBlob *outName)
960 {
961     if ((self == NULL) || (outName == NULL)) {
962         LOGE("[GetSigAlgName openssl] The input data is null!");
963         return CF_INVALID_PARAMS;
964     }
965     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
966         LOGE("[GetSigAlgName openssl] Input wrong class type!");
967         return CF_INVALID_PARAMS;
968     }
969     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
970     X509 *x509 = realCert->x509;
971 
972     const X509_ALGOR *alg = NULL;
973     X509_get0_signature(NULL, &alg, x509);
974     const ASN1_OBJECT *oidObj = NULL;
975     X509_ALGOR_get0(&oidObj, NULL, NULL, alg);
976     char oidStr[OID_STR_MAX_LEN] = { 0 };
977     int32_t resLen = OBJ_obj2txt(oidStr, OID_STR_MAX_LEN, oidObj, 1);
978     if ((resLen <= 0) || (resLen >= OID_STR_MAX_LEN)) {
979         LOGE("Failed to convert x509 object to text!");
980         CfPrintOpensslError();
981         return CF_ERR_CRYPTO_OPERATION;
982     }
983     const char *algName = GetAlgorithmName(oidStr);
984     if (algName == NULL) {
985         return CF_ERR_CRYPTO_OPERATION;
986     }
987     uint32_t len = strlen(algName) + 1;
988     return DeepCopyDataToOut(algName, len, outName);
989 }
990 
GetSigAlgOidX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)991 static CfResult GetSigAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
992 {
993     if ((self == NULL) || (out == NULL)) {
994         LOGE("[GetSigAlgOID openssl] The input data is null!");
995         return CF_INVALID_PARAMS;
996     }
997     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
998         LOGE("[GetSigAlgOID openssl] Input wrong class type!");
999         return CF_INVALID_PARAMS;
1000     }
1001     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1002     X509 *x509 = realCert->x509;
1003 
1004     const X509_ALGOR *alg = NULL;
1005     X509_get0_signature(NULL, &alg, x509);
1006     const ASN1_OBJECT *oid = NULL;
1007     X509_ALGOR_get0(&oid, NULL, NULL, alg);
1008     char algOid[OID_STR_MAX_LEN] = { 0 };
1009     int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, oid, 1);
1010     if ((resLen <= 0) || (resLen >= OID_STR_MAX_LEN)) {
1011         LOGE("Failed to convert x509 object to text!");
1012         CfPrintOpensslError();
1013         return CF_ERR_CRYPTO_OPERATION;
1014     }
1015     uint32_t len = strlen(algOid) + 1;
1016     return DeepCopyDataToOut(algOid, len, out);
1017 }
1018 
GetSigAlgParamsX509Openssl(HcfX509CertificateSpi * self,CfBlob * sigAlgParamsOut)1019 static CfResult GetSigAlgParamsX509Openssl(HcfX509CertificateSpi *self, CfBlob *sigAlgParamsOut)
1020 {
1021     if ((self == NULL) || (sigAlgParamsOut == NULL)) {
1022         LOGE("[GetSigAlgParams openssl] The input data is null!");
1023         return CF_INVALID_PARAMS;
1024     }
1025     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1026         LOGE("[GetSigAlgParams openssl] Input wrong class type!");
1027         return CF_INVALID_PARAMS;
1028     }
1029     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1030     X509 *x509 = realCert->x509;
1031 
1032     const X509_ALGOR *alg = NULL;
1033     X509_get0_signature(NULL, &alg, x509);
1034     int32_t paramType = 0;
1035     const void *paramValue = NULL;
1036     X509_ALGOR_get0(NULL, &paramType, &paramValue, alg);
1037     if (paramType == V_ASN1_UNDEF) {
1038         LOGE("get_X509_ALGOR_parameter, no parameters!");
1039         return CF_NOT_SUPPORT;
1040     }
1041     ASN1_TYPE *param = ASN1_TYPE_new();
1042     if (param == NULL) {
1043         LOGE("Failed to malloc for asn1 type data!");
1044         return CF_ERR_MALLOC;
1045     }
1046     if (ASN1_TYPE_set1(param, paramType, paramValue) != CF_OPENSSL_SUCCESS) {
1047         LOGE("Failed to set asn1 type in openssl!");
1048         CfPrintOpensslError();
1049         ASN1_TYPE_free(param);
1050         return CF_ERR_CRYPTO_OPERATION;
1051     }
1052     unsigned char *out = NULL;
1053     int32_t len = i2d_ASN1_TYPE(param, &out);
1054     if (len <= 0 || out == NULL) {
1055         LOGE("Failed to convert ASN1_TYPE!");
1056         CfPrintOpensslError();
1057         ASN1_TYPE_free(param);
1058         return CF_ERR_CRYPTO_OPERATION;
1059     }
1060     ASN1_TYPE_free(param);
1061     CfResult res = DeepCopyDataToOut((const char *)out, len, sigAlgParamsOut);
1062     OPENSSL_free(out);
1063     return res;
1064 }
1065 
GetKeyUsageX509Openssl(HcfX509CertificateSpi * self,CfBlob * boolArr)1066 static CfResult GetKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfBlob *boolArr)
1067 {
1068     if ((self == NULL) || (boolArr == NULL)) {
1069         LOGE("[GetKeyUsage openssl] The input data is null!");
1070         return CF_INVALID_PARAMS;
1071     }
1072     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1073         LOGE("Input wrong class type!");
1074         return CF_INVALID_PARAMS;
1075     }
1076     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1077     X509 *x509 = realCert->x509;
1078 
1079     ASN1_BIT_STRING *keyUsage = (ASN1_BIT_STRING *)X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
1080     if ((keyUsage == NULL) || (keyUsage->length <= 0) || (keyUsage->length >= HCF_MAX_STR_LEN)) {
1081         if (keyUsage != NULL) {
1082             ASN1_BIT_STRING_free(keyUsage);
1083         }
1084         LOGE("Failed to get x509 keyUsage in openssl!");
1085         CfPrintOpensslError();
1086         return CF_ERR_CRYPTO_OPERATION;
1087     }
1088     CfResult res = CfConvertAsn1String2BoolArray(keyUsage, boolArr);
1089     ASN1_BIT_STRING_free(keyUsage);
1090     return res;
1091 }
1092 
GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi * self,CfArray * keyUsageOut)1093 static CfResult GetExtendedKeyUsageX509Openssl(HcfX509CertificateSpi *self, CfArray *keyUsageOut)
1094 {
1095     if ((self == NULL) || (keyUsageOut == NULL)) {
1096         LOGE("The input data is null!");
1097         return CF_INVALID_PARAMS;
1098     }
1099     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1100         LOGE("Input wrong class type!");
1101         return CF_INVALID_PARAMS;
1102     }
1103     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1104     X509 *x509 = realCert->x509;
1105     STACK_OF(ASN1_OBJECT) *extUsage = X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL);
1106     if (extUsage == NULL) {
1107         LOGE("Failed to get x509 extended keyUsage in openssl!");
1108         return CF_ERR_CRYPTO_OPERATION;
1109     }
1110     CfResult res = CF_SUCCESS;
1111     do {
1112         int32_t size = sk_ASN1_OBJECT_num(extUsage);
1113         if ((size <= 0) || ((size_t)size > INT32_MAX / sizeof(CfBlob))) {
1114             LOGE("The extended key usage size in openssl is invalid!");
1115             CfPrintOpensslError();
1116             res = CF_ERR_CRYPTO_OPERATION;
1117             break;
1118         }
1119         int32_t blobSize = sizeof(CfBlob) * size;
1120         keyUsageOut->data = (CfBlob *)CfMalloc(blobSize, 0);
1121         if (keyUsageOut->data == NULL) {
1122             LOGE("Failed to malloc for keyUsageOut array!");
1123             res = CF_ERR_MALLOC;
1124             break;
1125         }
1126         keyUsageOut->count = (uint32_t)size;
1127         for (int32_t i = 0; i < size; ++i) {
1128             res = CfDeepCopyExtendedKeyUsage(extUsage, i, keyUsageOut);
1129             if (res != CF_SUCCESS) {
1130                 LOGE("Falied to copy extended key usage!");
1131                 break;
1132             }
1133         }
1134     } while (0);
1135     if (res != CF_SUCCESS) {
1136         CfArrayDataClearAndFree(keyUsageOut);
1137     }
1138     sk_ASN1_OBJECT_pop_free(extUsage, ASN1_OBJECT_free);
1139     return res;
1140 }
1141 
GetBasicConstraintsX509Openssl(HcfX509CertificateSpi * self)1142 static int32_t GetBasicConstraintsX509Openssl(HcfX509CertificateSpi *self)
1143 {
1144     if (self == NULL) {
1145         LOGE("The input data is null!");
1146         return INVALID_CONSTRAINTS_LEN;
1147     }
1148     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1149         LOGE("Input wrong class type!");
1150         return INVALID_CONSTRAINTS_LEN;
1151     }
1152     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1153     X509 *x509 = realCert->x509;
1154     if (x509 == NULL) {
1155         LOGE("X509 cert is null!");
1156         return INVALID_CONSTRAINTS_LEN;
1157     }
1158     BASIC_CONSTRAINTS *constraints = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x509, NID_basic_constraints, NULL, NULL);
1159     if (constraints == NULL) {
1160         LOGE("Failed to get basic constraints in openssl!");
1161         return INVALID_CONSTRAINTS_LEN;
1162     }
1163     /* Path len is only valid for CA cert. */
1164     if (!constraints->ca) {
1165         BASIC_CONSTRAINTS_free(constraints);
1166         LOGI("The cert in not a CA!");
1167         return INVALID_CONSTRAINTS_LEN;
1168     }
1169     if ((constraints->pathlen == NULL) || (constraints->pathlen->type == V_ASN1_NEG_INTEGER)) {
1170         BASIC_CONSTRAINTS_free(constraints);
1171         LOGE("The cert path len is negative in openssl!");
1172         return INVALID_CONSTRAINTS_LEN;
1173     }
1174     long pathLen = ASN1_INTEGER_get(constraints->pathlen);
1175     if ((pathLen < 0) || (pathLen > INT_MAX)) {
1176         BASIC_CONSTRAINTS_free(constraints);
1177         LOGE("Get the overflow path length in openssl!");
1178         return INVALID_CONSTRAINTS_LEN;
1179     }
1180     BASIC_CONSTRAINTS_free(constraints);
1181     return (int32_t)pathLen;
1182 }
1183 
GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi * self,CfArray * outName)1184 static CfResult GetSubjectAltNamesX509Openssl(HcfX509CertificateSpi *self, CfArray *outName)
1185 {
1186     if ((self == NULL) || (outName == NULL)) {
1187         LOGE("[GetSubjectAltNames openssl] The input data is null!");
1188         return CF_INVALID_PARAMS;
1189     }
1190     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1191         LOGE("Input wrong class type!");
1192         return CF_INVALID_PARAMS;
1193     }
1194     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1195     X509 *x509 = realCert->x509;
1196     STACK_OF(GENERAL_NAME) *subjectAltName = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1197     if (subjectAltName == NULL) {
1198         LOGE("Failed to get subjectAltName in openssl!");
1199         CfPrintOpensslError();
1200         return CF_ERR_CRYPTO_OPERATION;
1201     }
1202     CfResult res = CF_SUCCESS;
1203     do {
1204         int32_t size = sk_GENERAL_NAME_num(subjectAltName);
1205         if ((size <= 0) || ((size_t)size > INT32_MAX / sizeof(CfBlob))) {
1206             LOGE("The subjectAltName number in openssl is invalid!");
1207             CfPrintOpensslError();
1208             res = CF_ERR_CRYPTO_OPERATION;
1209             break;
1210         }
1211         int32_t blobSize = sizeof(CfBlob) * size;
1212         outName->data = (CfBlob *)CfMalloc(blobSize, 0);
1213         if (outName->data == NULL) {
1214             LOGE("Failed to malloc for subjectAltName array!");
1215             res = CF_ERR_MALLOC;
1216             break;
1217         }
1218         outName->count = (uint32_t)size;
1219         for (int32_t i = 0; i < size; ++i) {
1220             res = CfDeepCopyAlternativeNames(subjectAltName, i, outName);
1221             if (res != CF_SUCCESS) {
1222                 LOGE("Falied to copy subjectAltName!");
1223                 break;
1224             }
1225         }
1226     } while (0);
1227     if (res != CF_SUCCESS) {
1228         CfArrayDataClearAndFree(outName);
1229     }
1230     GENERAL_NAMES_free(subjectAltName);
1231     return res;
1232 }
1233 
GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi * self,CfArray * outName)1234 static CfResult GetIssuerAltNamesX509Openssl(HcfX509CertificateSpi *self, CfArray *outName)
1235 {
1236     if ((self == NULL) || (outName == NULL)) {
1237         LOGE("[GetIssuerAltNames openssl] The input data is null!");
1238         return CF_INVALID_PARAMS;
1239     }
1240     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1241         LOGE("Input wrong class type!");
1242         return CF_INVALID_PARAMS;
1243     }
1244     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1245     X509 *x509 = realCert->x509;
1246     STACK_OF(GENERAL_NAME) *issuerAltName = X509_get_ext_d2i(x509, NID_issuer_alt_name, NULL, NULL);
1247     if (issuerAltName == NULL) {
1248         LOGE("Failed to get issuerAltName in openssl!");
1249         CfPrintOpensslError();
1250         return CF_ERR_CRYPTO_OPERATION;
1251     }
1252     CfResult res = CF_SUCCESS;
1253     do {
1254         int32_t size = sk_GENERAL_NAME_num(issuerAltName);
1255         if ((size <= 0) || ((size_t)size > INT32_MAX / sizeof(CfBlob))) {
1256             LOGE("The issuerAltName number in openssl is invalid!");
1257             CfPrintOpensslError();
1258             res = CF_ERR_CRYPTO_OPERATION;
1259             break;
1260         }
1261         int32_t blobSize = sizeof(CfBlob) * size;
1262         outName->data = (CfBlob *)CfMalloc(blobSize, 0);
1263         if (outName->data == NULL) {
1264             LOGE("Failed to malloc for issuerAltName array!");
1265             res = CF_ERR_MALLOC;
1266             break;
1267         }
1268         outName->count = (uint32_t)size;
1269         for (int32_t i = 0; i < size; ++i) {
1270             res = CfDeepCopyAlternativeNames(issuerAltName, i, outName);
1271             if (res != CF_SUCCESS) {
1272                 LOGE("Falied to copy issuerAltName!");
1273                 break;
1274             }
1275         }
1276     } while (0);
1277     if (res != CF_SUCCESS) {
1278         CfArrayDataClearAndFree(outName);
1279     }
1280     GENERAL_NAMES_free(issuerAltName);
1281     return res;
1282 }
1283 
ToStringX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)1284 static CfResult ToStringX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
1285 {
1286     if ((self == NULL) || (out == NULL)) {
1287         LOGE("The input data is null!");
1288         return CF_INVALID_PARAMS;
1289     }
1290     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1291         LOGE("Input wrong class type!");
1292         return CF_INVALID_PARAMS;
1293     }
1294     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1295     BIO *bio = BIO_new(BIO_s_mem());
1296     if (bio == NULL) {
1297         LOGE("BIO_new error");
1298         return CF_ERR_MALLOC;
1299     }
1300     int len = X509_print(bio, realCert->x509);
1301     if (len <= 0) {
1302         LOGE("X509_print error");
1303         BIO_free(bio);
1304         return CF_ERR_CRYPTO_OPERATION;
1305     }
1306     BUF_MEM *bufMem = NULL;
1307     if (BIO_get_mem_ptr(bio, &bufMem) > 0 && bufMem != NULL) {
1308         CfResult res = DeepCopyDataToOut(bufMem->data, bufMem->length, out);
1309         BIO_free(bio);
1310         return res;
1311     }
1312 
1313     BIO_free(bio);
1314     LOGE("BIO_get_mem_ptr error");
1315     return CF_ERR_CRYPTO_OPERATION;
1316 }
1317 
ToStringX509OpensslEx(HcfX509CertificateSpi * self,CfEncodinigType encodingType,CfBlob * out)1318 static CfResult ToStringX509OpensslEx(HcfX509CertificateSpi *self, CfEncodinigType encodingType, CfBlob *out)
1319 {
1320     if ((self == NULL) || (out == NULL)) {
1321         LOGE("The input data is null!");
1322         return CF_ERR_INTERNAL;
1323     }
1324     if (encodingType != CF_ENCODING_UTF8) {
1325         LOGE("encodingType is not utf8!");
1326         return CF_ERR_PARAMETER_CHECK;
1327     }
1328     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1329         LOGE("Input wrong class type!");
1330         return CF_ERR_INTERNAL;
1331     }
1332     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1333     BIO *bio = BIO_new(BIO_s_mem());
1334     if (bio == NULL) {
1335         LOGE("BIO_new error");
1336         return CF_ERR_MALLOC;
1337     }
1338     int ret = X509_print_ex(bio, realCert->x509, XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_UTF8_CONVERT, 0);
1339     if (ret <= 0) {
1340         LOGE("Failed to X509_print_ex in openssl!");
1341         CfPrintOpensslError();
1342         BIO_free(bio);
1343         return CF_ERR_CRYPTO_OPERATION;
1344     }
1345 
1346     BUF_MEM *bufMem = NULL;
1347     if (BIO_get_mem_ptr(bio, &bufMem) > 0 && bufMem != NULL) {
1348         CfResult res = DeepCopyDataToOut(bufMem->data, bufMem->length, out);
1349         BIO_free(bio);
1350         return res;
1351     }
1352     BIO_free(bio);
1353     return CF_ERR_CRYPTO_OPERATION;
1354 }
1355 
HashCodeX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)1356 static CfResult HashCodeX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
1357 {
1358     if ((self == NULL) || (out == NULL)) {
1359         LOGE("The input data is null!");
1360         return CF_INVALID_PARAMS;
1361     }
1362     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1363         LOGE("Input wrong class type!");
1364         return CF_INVALID_PARAMS;
1365     }
1366     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1367     X509 *x509 = realCert->x509;
1368 
1369     unsigned char *buf = NULL;
1370     int len = i2d_X509(x509, &buf);
1371     if (len < 0 || buf == NULL) {
1372         LOGE("i2d_X509 error");
1373         return CF_ERR_CRYPTO_OPERATION;
1374     }
1375 
1376     out->data = (uint8_t *)CfMalloc(SHA256_DIGEST_LENGTH, 0);
1377     if (out->data == NULL) {
1378         LOGE("CfMalloc error");
1379         OPENSSL_free(buf);
1380         return CF_ERR_MALLOC;
1381     }
1382     if (SHA256(buf, len, out->data) == NULL) {
1383         LOGE("Compute sha256 error");
1384         CfFree(out->data);
1385         out->data = NULL;
1386         OPENSSL_free(buf);
1387         return CF_ERR_CRYPTO_OPERATION;
1388     }
1389     out->size = SHA256_DIGEST_LENGTH;
1390     OPENSSL_free(buf);
1391     return CF_SUCCESS;
1392 }
1393 
GetExtensionsObjectX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)1394 static CfResult GetExtensionsObjectX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
1395 {
1396     if ((self == NULL) || (out == NULL)) {
1397         LOGE("The input data is null!");
1398         return CF_INVALID_PARAMS;
1399     }
1400     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1401         LOGE("Input wrong class type!");
1402         return CF_INVALID_PARAMS;
1403     }
1404     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1405     if (realCert->x509 == NULL) {
1406         LOGE("X509 cert is null!");
1407         return CF_INVALID_PARAMS;
1408     }
1409     unsigned char *extensions = NULL;
1410     int len = i2d_X509_EXTENSIONS(X509_get0_extensions(realCert->x509), &extensions);
1411     if (len <= 0 || extensions == NULL) {
1412         LOGE("i2d_X509_EXTENSIONS error");
1413         return CF_ERR_CRYPTO_OPERATION;
1414     }
1415 
1416     out->data = (uint8_t *)CfMalloc(len, 0);
1417     if (out->data == NULL) {
1418         LOGE("Failed to malloc for extensions data!");
1419         OPENSSL_free(extensions);
1420         return CF_ERR_MALLOC;
1421     }
1422     (void)memcpy_s(out->data, len, extensions, len);
1423     OPENSSL_free(extensions);
1424     out->size = len;
1425     return CF_SUCCESS;
1426 }
1427 
MatchPart1(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1428 static CfResult MatchPart1(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1429 {
1430     CfResult res = CF_SUCCESS;
1431     *out = true;
1432 
1433     // x509Cert
1434     res = CompareCertBlobX509Openssl(self, matchParams->x509Cert, out);
1435     if (res != CF_SUCCESS || (*out == false)) {
1436         LOGE("Failed to CompareCertBlob!");
1437         return res;
1438     }
1439     // subject
1440     res = CompareNameObjectX509Openssl(self, matchParams->subject, NAME_TYPE_SUBJECT, out);
1441     if (res != CF_SUCCESS || (*out == false)) {
1442         LOGE("Failed to CompareSubject!");
1443         return res;
1444     }
1445     // validDate
1446     if (matchParams->validDate != NULL) {
1447         if (!CfBlobIsStr(matchParams->validDate)) {
1448             LOGE("Invalid param!");
1449             return CF_INVALID_PARAMS;
1450         }
1451         res = CheckValidityWithDateX509Openssl(self, (const char *)matchParams->validDate->data);
1452         if ((res == CF_ERR_CERT_NOT_YET_VALID) || (res == CF_ERR_CERT_HAS_EXPIRED)) {
1453             *out = false;
1454             return CF_SUCCESS;
1455         }
1456         if (res != CF_SUCCESS) {
1457             LOGE("Failed to CheckValidityWithDate!");
1458             return res;
1459         }
1460     }
1461     // issuer
1462     res = CompareNameObjectX509Openssl(self, matchParams->issuer, NAME_TYPE_ISSUER, out);
1463     if (res != CF_SUCCESS || (*out == false)) {
1464         LOGE("Failed to CompareIssuer!");
1465         return res;
1466     }
1467     return res;
1468 }
1469 
MatchPart2(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1470 static CfResult MatchPart2(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1471 {
1472     CfResult res = CF_SUCCESS;
1473     *out = true;
1474 
1475     // keyUsage
1476     res = CompareKeyUsageX509Openssl(self, matchParams->keyUsage, out);
1477     if (res != CF_SUCCESS || (*out == false)) {
1478         LOGE("Failed to CompareKeyUsage!");
1479         return res;
1480     }
1481     // serialNumber
1482     res = CompareSerialNumberX509Openssl(self, matchParams->serialNumber, out);
1483     if (res != CF_SUCCESS || (*out == false)) {
1484         LOGE("Failed to CompareSerialNumber!");
1485         return res;
1486     }
1487     // publicKey
1488     res = ComparePublicKeyX509Openssl(self, matchParams->publicKey, out);
1489     if (res != CF_SUCCESS || (*out == false)) {
1490         LOGE("Failed to ComparePublicKey!");
1491         return res;
1492     }
1493     // publicKeyAlgID
1494     res = ComparePublicKeyAlgOidX509Openssl(self, matchParams->publicKeyAlgID, out);
1495     if (res != CF_SUCCESS || (*out == false)) {
1496         LOGE("Failed to ComparePublicKeyAlgOid!");
1497         return res;
1498     }
1499 
1500     return CF_SUCCESS;
1501 }
1502 
IsMatch(SubjectAlternaiveNameData * subAltName,SubAltNameArray * subArraySelf)1503 static bool IsMatch(SubjectAlternaiveNameData *subAltName, SubAltNameArray *subArraySelf)
1504 {
1505     if (subAltName == NULL || subArraySelf == NULL) {
1506         return false;
1507     }
1508     for (uint32_t j = 0; j < subArraySelf->count; j++) {
1509         if (subAltName->type == subArraySelf->data[j].type &&
1510             subAltName->name.size == subArraySelf->data[j].name.size &&
1511             memcmp(subAltName->name.data, subArraySelf->data[j].name.data, subAltName->name.size) == 0) {
1512             return true;
1513         }
1514     }
1515     return false;
1516 }
1517 
CompareSubAltNameMatch(const SubAltNameArray * subArrayInput,SubAltNameArray * subArraySelf,bool matchAll)1518 static bool CompareSubAltNameMatch(const SubAltNameArray *subArrayInput, SubAltNameArray *subArraySelf, bool matchAll)
1519 {
1520     if (matchAll) {
1521         if (subArrayInput->count != subArraySelf->count) {
1522             return false;
1523         }
1524         for (uint32_t i = 0; i < subArrayInput->count; i++) {
1525             if (!IsMatch(&subArrayInput->data[i], subArraySelf)) {
1526                 return false;
1527             }
1528         }
1529         return true;
1530     } else {
1531         for (uint32_t i = 0; i < subArrayInput->count; i++) {
1532             if (IsMatch(&subArrayInput->data[i], subArraySelf)) {
1533                 return true;
1534             }
1535         }
1536         return false;
1537     }
1538 }
1539 
DetailForMinPathLenConstraint(X509 * x509,int minPathLenConstraint)1540 static bool DetailForMinPathLenConstraint(X509 *x509, int minPathLenConstraint)
1541 {
1542     if (minPathLenConstraint == MIN_PATH_LEN_CONSTRAINT) {
1543         X509_EXTENSION *ext = X509_get_ext(x509, X509_get_ext_by_NID(x509, NID_basic_constraints, -1));
1544         if (ext == NULL) {
1545             // when minPathLenConstraint is -2 and get basic_constraints from cert failed is ok, return true.
1546             return true;
1547         }
1548         BASIC_CONSTRAINTS *bc = X509V3_EXT_d2i(ext);
1549         if (bc == NULL) {
1550             return false;
1551         }
1552         bool ca = (bc->ca != 0);
1553         BASIC_CONSTRAINTS_free(bc);
1554         if (!ca) {
1555             return true;
1556         }
1557         return false;
1558     } else if (minPathLenConstraint >= 0) {
1559         X509_EXTENSION *ext = X509_get_ext(x509, X509_get_ext_by_NID(x509, NID_basic_constraints, -1));
1560         if (ext == NULL) {
1561             return false;
1562         }
1563         BASIC_CONSTRAINTS *bc = X509V3_EXT_d2i(ext);
1564         if (bc == NULL) {
1565             return false;
1566         }
1567         bool ca = (bc->ca != 0);
1568         long pathLen = ASN1_INTEGER_get(bc->pathlen);
1569         BASIC_CONSTRAINTS_free(bc);
1570         if (ca && (pathLen >= minPathLenConstraint || pathLen == -1)) {
1571             return true;
1572         }
1573         return false;
1574     } else {
1575         return true;
1576     }
1577 }
1578 
CompareSubAltNameX509Openssl(HcfX509CertificateSpi * self,const SubAltNameArray * subAltNameArray,const bool matchAllSubAltNames,bool * out)1579 static CfResult CompareSubAltNameX509Openssl(
1580     HcfX509CertificateSpi *self, const SubAltNameArray *subAltNameArray, const bool matchAllSubAltNames, bool *out)
1581 {
1582     if (subAltNameArray == NULL) {
1583         LOGE("The input data is null!");
1584         return CF_SUCCESS;
1585     }
1586     *out = false;
1587     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1588     X509 *x509 = realCert->x509;
1589     STACK_OF(GENERAL_NAME) *altname = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1590     if (altname == NULL) {
1591         LOGE("Failed to get subject alternative name!");
1592         return CF_SUCCESS;
1593     }
1594     SubAltNameArray subAltNameArrayOut = { 0 };
1595     CfResult res = CF_SUCCESS;
1596     do {
1597         int32_t size = sk_GENERAL_NAME_num(altname);
1598         if (size <= 0) {
1599             LOGE("The altname in openssl is invalid!");
1600             res = CF_ERR_CRYPTO_OPERATION;
1601             break;
1602         }
1603         if ((size_t)size > INT32_MAX / sizeof(SubjectAlternaiveNameData)) {
1604             LOGE("Size is out of max!");
1605             res = CF_ERR_MALLOC;
1606             break;
1607         }
1608         int32_t blobSize = sizeof(SubjectAlternaiveNameData) * size;
1609         subAltNameArrayOut.data = (SubjectAlternaiveNameData *)CfMalloc(blobSize, 0);
1610         if (subAltNameArrayOut.data == NULL) {
1611             LOGE("Failed to malloc for subject alternative name array!");
1612             res = CF_ERR_MALLOC;
1613             break;
1614         }
1615         subAltNameArrayOut.count = (uint32_t)size;
1616         for (int32_t i = 0; i < size; ++i) {
1617             res = CfDeepCopySubAltName(altname, i, &subAltNameArrayOut);
1618             if (res != CF_SUCCESS) {
1619                 LOGE("Falied to copy subject alternative Name!");
1620                 break;
1621             }
1622         }
1623     } while (0);
1624     if (res == CF_SUCCESS && CompareSubAltNameMatch(subAltNameArray, &subAltNameArrayOut, matchAllSubAltNames)) {
1625         *out = true;
1626     }
1627     GENERAL_NAMES_free(altname);
1628     SubAltNameArrayDataClearAndFree(&subAltNameArrayOut);
1629     return res;
1630 }
1631 
ComparePathLenConstraintX509Openssl(HcfX509CertificateSpi * self,const int32_t minPath,bool * out)1632 static CfResult ComparePathLenConstraintX509Openssl(HcfX509CertificateSpi *self, const int32_t minPath, bool *out)
1633 {
1634     if (minPath < 0 && minPath != MIN_PATH_LEN_CONSTRAINT) {
1635         LOGE("The input minpath is invalid!");
1636         return CF_SUCCESS;
1637     }
1638     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1639     X509 *x509 = realCert->x509;
1640     if (!DetailForMinPathLenConstraint(x509, minPath)) {
1641         *out = false;
1642     }
1643     return CF_SUCCESS;
1644 }
1645 
CompareExtendKeyUsageX509Openssl(HcfX509CertificateSpi * self,const CfArray * extendKeyUsage,bool * out)1646 static CfResult CompareExtendKeyUsageX509Openssl(HcfX509CertificateSpi *self, const CfArray *extendKeyUsage, bool *out)
1647 {
1648     if (extendKeyUsage == NULL) {
1649         LOGE("The input data is null!");
1650         return CF_SUCCESS;
1651     }
1652     CfArray extendout = { 0 };
1653     CfResult res = GetExtendedKeyUsageX509Openssl(self, &extendout);
1654     if (res == CF_SUCCESS) {
1655         if (!CfArrayContains(extendKeyUsage, &extendout)) {
1656             *out = false;
1657         }
1658     }
1659     CfArrayDataClearAndFree(&extendout);
1660     return res;
1661 }
1662 
CompareNameConstraintsX509Openssl(HcfX509CertificateSpi * self,CfBlob * nameConstraints,bool * out)1663 static CfResult CompareNameConstraintsX509Openssl(HcfX509CertificateSpi *self, CfBlob *nameConstraints, bool *out)
1664 {
1665     if (nameConstraints == NULL) {
1666         LOGE("The input data is null!");
1667         return CF_SUCCESS;
1668     }
1669     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1670     X509 *x509 = realCert->x509;
1671     NAME_CONSTRAINTS *nc = X509_get_ext_d2i(x509, NID_name_constraints, NULL, NULL);
1672     if (nc == NULL || nc->permittedSubtrees == NULL || nc->excludedSubtrees == NULL) {
1673         if (nc != NULL) {
1674             NAME_CONSTRAINTS_free(nc);
1675         }
1676         LOGE("Failed to get name constraints!");
1677         *out = false;
1678         return CF_SUCCESS;
1679     }
1680 
1681     int i = 0;
1682     for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
1683         GENERAL_SUBTREE *tree = NULL;
1684         tree = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
1685         if (tree != NULL && CfCompareGN2Blob(tree->base, nameConstraints)) {
1686             NAME_CONSTRAINTS_free(nc);
1687             return CF_SUCCESS;
1688         }
1689     }
1690     for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
1691         GENERAL_SUBTREE *tree = NULL;
1692         tree = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
1693         if (tree != NULL && CfCompareGN2Blob(tree->base, nameConstraints) == true) {
1694             NAME_CONSTRAINTS_free(nc);
1695             return CF_SUCCESS;
1696         }
1697     }
1698     *out = false;
1699     NAME_CONSTRAINTS_free(nc);
1700     return CF_SUCCESS;
1701 }
1702 
CompareCertPolicesX509Openssl(HcfX509CertificateSpi * self,CfArray * certPolices,bool * out)1703 static CfResult CompareCertPolicesX509Openssl(HcfX509CertificateSpi *self, CfArray *certPolices, bool *out)
1704 {
1705     if (certPolices == NULL) {
1706         LOGE("The input data is null!");
1707         return CF_SUCCESS;
1708     }
1709     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1710     X509 *x509 = realCert->x509;
1711     CERTIFICATEPOLICIES *extCpols = X509_get_ext_d2i(x509, NID_certificate_policies, NULL, NULL);
1712     if (extCpols == NULL) {
1713         LOGE("Failed to get x509 cert polices in openssl!");
1714         *out = false;
1715         return CF_SUCCESS;
1716     }
1717     CfResult res = CF_SUCCESS;
1718     CfArray certPolicesOut = { NULL, 0 };
1719     do {
1720         int32_t size = sk_POLICYINFO_num(extCpols);
1721         if (size <= 0) {
1722             LOGE("The extended key usage size in openssl is invalid!");
1723             res = CF_ERR_CRYPTO_OPERATION;
1724             break;
1725         }
1726         if ((size_t)size > INT32_MAX / sizeof(CfBlob)) {
1727             LOGE("Size is out of max!");
1728             res = CF_ERR_MALLOC;
1729             break;
1730         }
1731         int32_t blobSize = sizeof(CfBlob) * size;
1732         certPolicesOut.data = (CfBlob *)CfMalloc(blobSize, 0);
1733         if (certPolicesOut.data == NULL) {
1734             LOGE("Failed to malloc for certPolicesOut array!");
1735             res = CF_ERR_MALLOC;
1736             break;
1737         }
1738         certPolicesOut.count = (uint32_t)size;
1739         for (int32_t i = 0; i < size; ++i) {
1740             res = CfDeepCopyCertPolices(extCpols, i, &certPolicesOut);
1741             if (res != CF_SUCCESS) {
1742                 LOGE("Falied to copy cert polices!");
1743                 break;
1744             }
1745         }
1746     } while (0);
1747     if (res == CF_SUCCESS && !CfArrayContains(certPolices, &certPolicesOut)) {
1748         *out = false;
1749     }
1750     CERTIFICATEPOLICIES_free(extCpols);
1751     CfArrayDataClearAndFree(&certPolicesOut);
1752     return res;
1753 }
1754 
ComparePrivateKeyValidX509Openssl(HcfX509CertificateSpi * self,CfBlob * privateKeyValid,bool * out)1755 static CfResult ComparePrivateKeyValidX509Openssl(HcfX509CertificateSpi *self, CfBlob *privateKeyValid, bool *out)
1756 {
1757     if (privateKeyValid == NULL) {
1758         LOGE("The input data is null!");
1759         return CF_SUCCESS;
1760     }
1761     *out = false;
1762     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1763     X509 *x509 = realCert->x509;
1764     PKEY_USAGE_PERIOD *pKeyValid = X509_get_ext_d2i(x509, NID_private_key_usage_period, NULL, NULL);
1765     if (pKeyValid == NULL || pKeyValid->notBefore == NULL || pKeyValid->notAfter == NULL) {
1766         if (pKeyValid != NULL) {
1767             PKEY_USAGE_PERIOD_free(pKeyValid);
1768         }
1769         LOGE("Failed to get x509 Private key valid in openssl!");
1770         return CF_SUCCESS;
1771     }
1772     char *notBefore = Asn1TimeToStr(pKeyValid->notBefore);
1773     char *notAfter = Asn1TimeToStr(pKeyValid->notAfter);
1774     PKEY_USAGE_PERIOD_free(pKeyValid);
1775     if (notBefore == NULL || notAfter == NULL) {
1776         LOGE("Get original data failed");
1777         CfFree(notBefore);
1778         notBefore = NULL;
1779         CfFree(notAfter);
1780         notAfter = NULL;
1781         return CF_SUCCESS;
1782     }
1783     if (privateKeyValid->size < DATETIME_LEN || strlen(notBefore) < DATETIME_LEN || strlen(notAfter) < DATETIME_LEN) {
1784         LOGE("Get private key valid date is not valid!");
1785         CfFree(notBefore);
1786         notBefore = NULL;
1787         CfFree(notAfter);
1788         notAfter = NULL;
1789         return CF_INVALID_PARAMS;
1790     }
1791     if (strncmp((const char *)privateKeyValid->data, (const char *)notBefore, DATETIME_LEN) >= 0 &&
1792         strncmp((const char *)privateKeyValid->data, (const char *)notAfter, DATETIME_LEN) <= 0) {
1793         *out = true;
1794     }
1795     CfFree(notBefore);
1796     notBefore = NULL;
1797     CfFree(notAfter);
1798     notAfter = NULL;
1799     return CF_SUCCESS;
1800 }
1801 
MatchPart3(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1802 static CfResult MatchPart3(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1803 {
1804     CfResult res = CF_SUCCESS;
1805     *out = true;
1806 
1807     // subjectAlternativeNames
1808     res = CompareSubAltNameX509Openssl(
1809         self, matchParams->subjectAlternativeNames, matchParams->matchAllSubjectAltNames, out);
1810     if (res != CF_SUCCESS || (*out == false)) {
1811         LOGE("Failed to compare subject alternative name!");
1812         return res;
1813     }
1814     // authorityKeyIdentifier
1815     res = CompareNameObjectX509Openssl(self, matchParams->authorityKeyIdentifier, NAME_TYPE_AUKEYID, out);
1816     if (res != CF_SUCCESS || (*out == false)) {
1817         LOGE("Failed to compare authority key identifier!");
1818         return res;
1819     }
1820     // minPathLenConstraint
1821     res = ComparePathLenConstraintX509Openssl(self, matchParams->minPathLenConstraint, out);
1822     if (res != CF_SUCCESS || (*out == false)) {
1823         LOGE("Failed to compare pathlen constraint!");
1824         return res;
1825     }
1826     // extendedKeyUsage Array<String>
1827     res = CompareExtendKeyUsageX509Openssl(self, matchParams->extendedKeyUsage, out);
1828     if (res != CF_SUCCESS || (*out == false)) {
1829         LOGE("Failed to compare extended key usage!");
1830         return res;
1831     }
1832     // nameConstraints
1833     res = CompareNameConstraintsX509Openssl(self, matchParams->nameConstraints, out);
1834     if (res != CF_SUCCESS || (*out == false)) {
1835         LOGE("Failed to compare name constraints!");
1836         return res;
1837     }
1838     // certPolicy Array<String>
1839     res = CompareCertPolicesX509Openssl(self, matchParams->certPolicy, out);
1840     if (res != CF_SUCCESS || (*out == false)) {
1841         LOGE("Failed to compare cert polices!");
1842         return res;
1843     }
1844     // privateKeyValid
1845     res = ComparePrivateKeyValidX509Openssl(self, matchParams->privateKeyValid, out);
1846     if (res != CF_SUCCESS || (*out == false)) {
1847         LOGE("Failed to compare private key valid!");
1848         return res;
1849     }
1850     // subjectKeyIdentifier
1851     res = CompareNameObjectX509Openssl(self, matchParams->subjectKeyIdentifier, NAME_TYPE_SUBKEYID, out);
1852     if (res != CF_SUCCESS || (*out == false)) {
1853         LOGE("Failed to compare subject key identifier!");
1854         return res;
1855     }
1856     return res;
1857 }
1858 
MatchX509Openssl(HcfX509CertificateSpi * self,const HcfX509CertMatchParams * matchParams,bool * out)1859 static CfResult MatchX509Openssl(HcfX509CertificateSpi *self, const HcfX509CertMatchParams *matchParams, bool *out)
1860 {
1861     if ((self == NULL) || (matchParams == NULL) || (out == NULL)) {
1862         LOGE("[GetIssuerAltNames openssl] The input data is null!");
1863         return CF_INVALID_PARAMS;
1864     }
1865     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1866         LOGE("Input wrong class type!");
1867         return CF_INVALID_PARAMS;
1868     }
1869     CfResult res = CF_SUCCESS;
1870     *out = true;
1871     res = MatchPart1(self, matchParams, out);
1872     if (res != CF_SUCCESS || (*out == false)) {
1873         LOGE("Failed to match part1!");
1874         return res;
1875     }
1876 
1877     res = MatchPart2(self, matchParams, out);
1878     if (res != CF_SUCCESS || (*out == false)) {
1879         LOGE("Failed to match part2!");
1880         return res;
1881     }
1882 
1883     res = MatchPart3(self, matchParams, out);
1884     if (res != CF_SUCCESS || (*out == false)) {
1885         LOGE("Failed to match part3!");
1886         return res;
1887     }
1888     return CF_SUCCESS;
1889 }
1890 
GetCRLDistributionPointsURIX509Openssl(HcfX509CertificateSpi * self,CfArray * outURI)1891 static CfResult GetCRLDistributionPointsURIX509Openssl(HcfX509CertificateSpi *self, CfArray *outURI)
1892 {
1893     if ((self == NULL) || (outURI == NULL)) {
1894         LOGE("[GetCRLDistributionPointsURI openssl] The input data is null!");
1895         return CF_INVALID_PARAMS;
1896     }
1897     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertClass())) {
1898         LOGE("[GetCRLDistributionPointsURI openssl] Input wrong class type!");
1899         return CF_INVALID_PARAMS;
1900     }
1901 
1902     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1903     X509 *x509 = realCert->x509;
1904 
1905     STACK_OF(DIST_POINT) *crlDp = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL);
1906     if (crlDp == NULL) {
1907         LOGE("Failed to get crl distribution point in openssl!");
1908         CfPrintOpensslError();
1909         return CF_NOT_EXIST;
1910     }
1911 
1912     CfResult ret = CfGetCRLDpURI(crlDp, outURI);
1913     sk_DIST_POINT_pop_free(crlDp, DIST_POINT_free);
1914     return ret;
1915 }
1916 
GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi * self,CfBlob * out)1917 static CfResult GetSubjectPubKeyAlgOidX509Openssl(HcfX509CertificateSpi *self, CfBlob *out)
1918 {
1919     CfResult res = CF_SUCCESS;
1920     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)self;
1921     X509 *x509 = realCert->x509;
1922     EVP_PKEY *pubkey = X509_get_pubkey(x509);
1923     if (NULL == pubkey) {
1924         LOGE("Failed to get public key from x509 cert.");
1925         CfPrintOpensslError();
1926         return CF_ERR_CRYPTO_OPERATION;
1927     }
1928     int nId = EVP_PKEY_get_base_id(pubkey);
1929     ASN1_OBJECT *obj = OBJ_nid2obj(nId);
1930     if (NULL == obj) {
1931         LOGE("Failed to get algObj from pubkey.");
1932         CfPrintOpensslError();
1933         EVP_PKEY_free(pubkey);
1934         return CF_ERR_CRYPTO_OPERATION;
1935     }
1936 
1937     char algOid[OID_STR_MAX_LEN] = { 0 };
1938     int32_t resLen = OBJ_obj2txt(algOid, OID_STR_MAX_LEN, obj, 1);
1939     if ((resLen <= 0) || (resLen >= OID_STR_MAX_LEN)) {
1940         LOGE("Failed to convert x509 object to text!");
1941         CfPrintOpensslError();
1942         EVP_PKEY_free(pubkey);
1943         ASN1_OBJECT_free(obj);
1944         return CF_ERR_CRYPTO_OPERATION;
1945     }
1946     uint32_t len = strlen(algOid) + 1;
1947     res = DeepCopyDataToOut(algOid, len, out);
1948     EVP_PKEY_free(pubkey);
1949     ASN1_OBJECT_free(obj);
1950     return res;
1951 }
1952 
CreateX509CertInner(const CfEncodingBlob * encodingBlob)1953 static X509 *CreateX509CertInner(const CfEncodingBlob *encodingBlob)
1954 {
1955     X509 *x509 = NULL;
1956     BIO *bio = BIO_new_mem_buf(encodingBlob->data, encodingBlob->len);
1957     if (bio == NULL) {
1958         LOGE("Openssl bio new buf failed.");
1959         return NULL;
1960     }
1961     if (encodingBlob->encodingFormat == CF_FORMAT_DER) {
1962         x509 = d2i_X509_bio(bio, NULL);
1963     } else if (encodingBlob->encodingFormat == CF_FORMAT_PEM) {
1964         x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
1965     }
1966     BIO_free(bio);
1967     return x509;
1968 }
1969 
OpensslX509CertSpiCreate(const CfEncodingBlob * inStream,HcfX509CertificateSpi ** spi)1970 CfResult OpensslX509CertSpiCreate(const CfEncodingBlob *inStream, HcfX509CertificateSpi **spi)
1971 {
1972     if ((inStream == NULL) || (inStream->data == NULL) || (spi == NULL)) {
1973         LOGE("The input data blob is null!");
1974         return CF_INVALID_PARAMS;
1975     }
1976     HcfOpensslX509Cert *realCert = (HcfOpensslX509Cert *)CfMalloc(sizeof(HcfOpensslX509Cert), 0);
1977     if (realCert == NULL) {
1978         LOGE("Failed to malloc for x509 instance!");
1979         return CF_ERR_MALLOC;
1980     }
1981     realCert->x509 = CreateX509CertInner(inStream);
1982     if (realCert->x509 == NULL) {
1983         CF_FREE_PTR(realCert);
1984         LOGE("Failed to create x509 cert from input data!");
1985         return CF_INVALID_PARAMS;
1986     }
1987     realCert->base.base.getClass = GetX509CertClass;
1988     realCert->base.base.destroy = DestroyX509Openssl;
1989     realCert->base.engineVerify = VerifyX509Openssl;
1990     realCert->base.engineGetEncoded = GetEncodedX509Openssl;
1991     realCert->base.engineGetPublicKey = GetPublicKeyX509Openssl;
1992     realCert->base.engineCheckValidityWithDate = CheckValidityWithDateX509Openssl;
1993     realCert->base.engineGetVersion = GetVersionX509Openssl;
1994     realCert->base.engineGetSerialNumber = GetSerialNumberX509Openssl;
1995     realCert->base.engineGetIssuerName = GetIssuerDNX509Openssl;
1996     realCert->base.engineGetIssuerNameDer = GetIssuerDNX509OpensslDer;
1997     realCert->base.engineGetIssuerNameEx = GetIssuerDNX509OpensslEx;
1998     realCert->base.engineGetSubjectName = GetSubjectDNX509Openssl;
1999     realCert->base.engineGetSubjectNameDer = GetSubjectDNX509OpensslDer;
2000     realCert->base.engineGetSubjectNameEx = GetSubjectDNX509OpensslEx;
2001     realCert->base.engineGetNotBeforeTime = GetNotBeforeX509Openssl;
2002     realCert->base.engineGetNotAfterTime = GetNotAfterX509Openssl;
2003     realCert->base.engineGetSignature = GetSignatureX509Openssl;
2004     realCert->base.engineGetSignatureAlgName = GetSigAlgNameX509Openssl;
2005     realCert->base.engineGetSignatureAlgOid = GetSigAlgOidX509Openssl;
2006     realCert->base.engineGetSignatureAlgParams = GetSigAlgParamsX509Openssl;
2007     realCert->base.engineGetKeyUsage = GetKeyUsageX509Openssl;
2008     realCert->base.engineGetExtKeyUsage = GetExtendedKeyUsageX509Openssl;
2009     realCert->base.engineGetBasicConstraints = GetBasicConstraintsX509Openssl;
2010     realCert->base.engineGetSubjectAltNames = GetSubjectAltNamesX509Openssl;
2011     realCert->base.engineGetIssuerAltNames = GetIssuerAltNamesX509Openssl;
2012     realCert->base.engineGetCRLDistributionPointsURI = GetCRLDistributionPointsURIX509Openssl;
2013     realCert->base.engineMatch = MatchX509Openssl;
2014     realCert->base.engineToString = ToStringX509Openssl;
2015     realCert->base.engineToStringEx = ToStringX509OpensslEx;
2016     realCert->base.engineHashCode = HashCodeX509Openssl;
2017     realCert->base.engineGetExtensionsObject = GetExtensionsObjectX509Openssl;
2018 
2019     *spi = (HcfX509CertificateSpi *)realCert;
2020     return CF_SUCCESS;
2021 }
2022