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_cert_chain_openssl.h"
17 #include "x509_cert_chain_openssl_ex.h"
18 
19 #include <openssl/crypto.h>
20 #include <openssl/err.h>
21 #include <openssl/evp.h>
22 #include <openssl/obj_mac.h>
23 #include <openssl/ocsp.h>
24 #include <openssl/ossl_typ.h>
25 #include <openssl/pem.h>
26 #include <openssl/pkcs12.h>
27 #include <openssl/ssl.h>
28 #include <openssl/x509.h>
29 #include <openssl/x509_vfy.h>
30 #include <openssl/x509v3.h>
31 #include <securec.h>
32 
33 #include "cert_crl_common.h"
34 #include "certificate_openssl_class.h"
35 #include "certificate_openssl_common.h"
36 #include "cf_blob.h"
37 #include "cf_log.h"
38 #include "cf_memory.h"
39 #include "cf_result.h"
40 #include "config.h"
41 #include "fwk_class.h"
42 #include "utils.h"
43 #include "x509_cert_chain_spi.h"
44 
45 #define MAX_CERT_NUM 256 /* max certs number of a certchain */
46 #define TIMET_NUM 6
47 #define TIMET_YEAR_START 1900
48 #define TIMET_YEAR_OFFSET 100 // start time year from 1900 + 100
49 #define HTTP_TIMEOUT 10
50 #define TRY_CONNECT_TIMES 3
51 #define OCSP_CONN_MILLISECOND 5000 // millisecond
52 #define OCSP_CONN_TIMEOUT (-1)     // timeout == 0 means no timeout, < 0 means exactly one try.
53 #define HTTP_PORT "80"
54 #define HTTPS_PORT "443"
55 
56 // helper functions
57 typedef struct {
58     int32_t errCode;
59     CfResult result;
60 } OpensslErrorToResult;
61 
62 typedef struct {
63     const EVP_MD *md;
64     X509 *subjectCert;
65     X509 *issuerCert;
66 } OcspCertIdInfo;
67 
68 typedef struct {
69     OCSP_REQUEST *req;
70     OCSP_RESPONSE *resp;
71     OcspCertIdInfo *certIdInfo;
72 } OcspLocalParam;
73 
74 typedef struct {
75     X509 *leafCert;
76     HcfRevocationCheckParam *revo;
77     char **host;
78     char **port;
79     char **path;
80     int *ssl;
81 } GetOcspUrlParams;
82 
83 static const OpensslErrorToResult ERROR_TO_RESULT_MAP[] = {
84     { X509_V_OK, CF_SUCCESS },
85     { X509_V_ERR_CERT_SIGNATURE_FAILURE, CF_ERR_CERT_SIGNATURE_FAILURE },
86     { X509_V_ERR_CERT_NOT_YET_VALID, CF_ERR_CERT_NOT_YET_VALID },
87     { X509_V_ERR_CERT_HAS_EXPIRED, CF_ERR_CERT_HAS_EXPIRED },
88     { X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, CF_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY },
89     { X509_V_ERR_KEYUSAGE_NO_CERTSIGN, CF_ERR_KEYUSAGE_NO_CERTSIGN },
90     { X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, CF_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE },
91 };
92 
ConvertOpensslErrorMsg(int32_t errCode)93 static CfResult ConvertOpensslErrorMsg(int32_t errCode)
94 {
95     for (uint32_t i = 0; i < sizeof(ERROR_TO_RESULT_MAP) / sizeof(OpensslErrorToResult); ++i) {
96         if (ERROR_TO_RESULT_MAP[i].errCode == errCode) {
97             return ERROR_TO_RESULT_MAP[i].result;
98         }
99     }
100     return CF_ERR_CRYPTO_OPERATION;
101 }
102 
DestroyX509CertChain(CfObjectBase * self)103 static void DestroyX509CertChain(CfObjectBase *self)
104 {
105     if (self == NULL || !CfIsClassMatch(self, GetX509CertChainClass())) {
106         LOGE("Invalid params!");
107         return;
108     }
109     HcfX509CertChainOpensslImpl *impl = (HcfX509CertChainOpensslImpl *)self;
110     if (impl->x509CertChain != NULL) {
111         sk_X509_pop_free(impl->x509CertChain, X509_free);
112         impl->x509CertChain = NULL;
113     }
114 
115     CfFree(impl);
116 }
117 
X509ToHcfX509Certificate(X509 * cert,HcfX509Certificate ** returnObj)118 static CfResult X509ToHcfX509Certificate(X509 *cert, HcfX509Certificate **returnObj)
119 {
120     if (cert == NULL) {
121         LOGE("The input params invalid.");
122         return CF_INVALID_PARAMS;
123     }
124 
125     int dataLength = 0;
126     uint8_t *certData = GetX509EncodedDataStream(cert, &dataLength);
127     if (certData == NULL) {
128         LOGE("Falied to get certificate data!");
129         return CF_ERR_CRYPTO_OPERATION;
130     }
131 
132     HcfX509Certificate *x509cert = NULL;
133     CfEncodingBlob encodingBlob = { certData, dataLength, CF_FORMAT_DER };
134     CfResult res = HcfX509CertificateCreate(&encodingBlob, &x509cert);
135     if (res != CF_SUCCESS) {
136         LOGE("HcfX509CertificateCreate fail, res : %d!", res);
137         CfFree(certData);
138         return CF_ERR_MALLOC;
139     }
140 
141     *returnObj = x509cert;
142     CfFree(certData);
143     return res;
144 }
145 
GetCertlist(HcfX509CertChainSpi * self,HcfX509CertificateArray * certsList)146 static CfResult GetCertlist(HcfX509CertChainSpi *self, HcfX509CertificateArray *certsList)
147 {
148     if ((self == NULL) || (certsList == NULL)) {
149         LOGE("[GetCertlist openssl] The input data is null!");
150         return CF_INVALID_PARAMS;
151     }
152     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
153         LOGE("[GetCertlist openssl] Input wrong class type!");
154         return CF_INVALID_PARAMS;
155     }
156 
157     CfResult res = CF_SUCCESS;
158     HcfX509CertChainOpensslImpl *certChain = (HcfX509CertChainOpensslImpl *)self;
159     STACK_OF(X509) *x509CertChain = certChain->x509CertChain;
160 
161     int32_t certsNum = sk_X509_num(x509CertChain);
162     if (certsNum <= 0) {
163         LOGE("sk X509 num : 0, failed!");
164         CfPrintOpensslError();
165         return CF_ERR_CRYPTO_OPERATION;
166     }
167     /* the list count has checked when create cert chain */
168     certsList->data = (HcfX509Certificate **)CfMalloc(certsNum * sizeof(HcfX509Certificate *), 0);
169     if (certsList->data == NULL) {
170         LOGE("malloc failed");
171         return CF_ERR_MALLOC;
172     }
173 
174     certsList->count = (uint32_t)certsNum;
175     for (int32_t i = 0; i < certsNum; ++i) {
176         X509 *cert = sk_X509_value(x509CertChain, i);
177         if (cert == NULL) {
178             LOGE("sk X509 value is null, failed!");
179             CfPrintOpensslError();
180             FreeCertArrayData(certsList);
181             return CF_ERR_CRYPTO_OPERATION;
182         }
183         HcfX509Certificate *x509Cert = NULL;
184         res = X509ToHcfX509Certificate(cert, &x509Cert);
185         if (res != CF_SUCCESS) {
186             LOGE("convert x509 to HcfX509Certificate failed!");
187             FreeCertArrayData(certsList);
188             return res;
189         }
190         certsList->data[i] = x509Cert;
191     }
192 
193     return res;
194 }
195 
CheckCertChainIsRevoked(const STACK_OF (X509_CRL)* crlStack,const STACK_OF (X509)* certChain)196 static CfResult CheckCertChainIsRevoked(const STACK_OF(X509_CRL) *crlStack, const STACK_OF(X509) *certChain)
197 {
198     int cerNum = sk_X509_num(certChain);
199     if (cerNum == 0) {
200         LOGE("sk X509 num : 0, failed!");
201         CfPrintOpensslError();
202         return CF_ERR_CRYPTO_OPERATION;
203     }
204 
205     int crlNum = sk_X509_CRL_num(crlStack); // allow crlNum : 0, no crl
206     for (int i = 0; i < crlNum; ++i) {
207         X509_CRL *crl = sk_X509_CRL_value(crlStack, i);
208         if (crl == NULL) {
209             LOGE("sk X509 CRL value is null, failed!");
210             CfPrintOpensslError();
211             return CF_ERR_CRYPTO_OPERATION;
212         }
213 
214         /* crl in certcrlcollection object is not null. */
215         for (int j = 0; j < cerNum; ++j) {
216             X509 *cert = sk_X509_value(certChain, j);
217             if (cert == NULL) {
218                 LOGE("sk X509 value is null, failed!");
219                 CfPrintOpensslError();
220                 return CF_ERR_CRYPTO_OPERATION;
221             }
222 
223             X509_REVOKED *rev = NULL;
224             int32_t res = X509_CRL_get0_by_cert(crl, &rev, cert);
225             if (res != 0) {
226                 LOGE("cert is revoked.");
227                 return CF_ERR_CRYPTO_OPERATION;
228             }
229         }
230     }
231 
232     return CF_SUCCESS;
233 }
234 
SetVerifyParams(X509_STORE * store,X509 * mostTrustCert)235 static CfResult SetVerifyParams(X509_STORE *store, X509 *mostTrustCert)
236 {
237     if (X509_STORE_add_cert(store, mostTrustCert) != CF_OPENSSL_SUCCESS) {
238         LOGE("add cert to store failed!");
239         CfPrintOpensslError();
240         return CF_ERR_CRYPTO_OPERATION;
241     }
242 
243     unsigned long flags = 0;
244     if (!CheckIsSelfSigned(mostTrustCert)) {
245         flags |= X509_V_FLAG_PARTIAL_CHAIN; // is not self signed
246         LOGI("SetVerifyFlag() is a partitial chain, not self signed!");
247     }
248 
249     /* date has verified before. */
250     flags |= X509_V_FLAG_NO_CHECK_TIME;
251     X509_STORE_set_flags(store, flags);
252 
253     return CF_SUCCESS;
254 }
255 
VerifyCertChain(X509 * mostTrustCert,STACK_OF (X509)* x509CertChain)256 static CfResult VerifyCertChain(X509 *mostTrustCert, STACK_OF(X509) *x509CertChain)
257 {
258     if (mostTrustCert == NULL || x509CertChain == NULL) {
259         LOGE("invalid params!");
260         return CF_INVALID_PARAMS;
261     }
262 
263     X509 *cert = sk_X509_value(x509CertChain, 0); // leaf cert
264     if (cert == NULL) {
265         CfPrintOpensslError();
266         return CF_ERR_CRYPTO_OPERATION;
267     }
268 
269     X509_STORE_CTX *ctx = X509_STORE_CTX_new();
270     if (ctx == NULL) {
271         CfPrintOpensslError();
272         return CF_ERR_CRYPTO_OPERATION;
273     }
274 
275     X509_STORE *store = X509_STORE_new();
276     if (store == NULL) {
277         LOGE("verify cert chain malloc failed!");
278         X509_STORE_CTX_free(ctx);
279         CfPrintOpensslError();
280         return CF_ERR_CRYPTO_OPERATION;
281     }
282 
283     CfResult res = SetVerifyParams(store, mostTrustCert);
284     if (res == CF_SUCCESS) {
285         if (X509_STORE_CTX_init(ctx, store, cert, x509CertChain) != CF_OPENSSL_SUCCESS) {
286             LOGE("init verify ctx failed!");
287             X509_STORE_CTX_free(ctx);
288             X509_STORE_free(store);
289             CfPrintOpensslError();
290             return CF_ERR_CRYPTO_OPERATION;
291         }
292 
293         if (X509_verify_cert(ctx) == CF_OPENSSL_SUCCESS) {
294             res = CF_SUCCESS;
295         } else {
296             int32_t errCode = X509_STORE_CTX_get_error(ctx);
297             const char *pChError = X509_verify_cert_error_string(errCode);
298             LOGE("Failed to verify cert, openssl openssl error code = %d, error msg:%s.", errCode, pChError);
299             res = ConvertOpensslErrorMsg(errCode);
300         }
301     }
302 
303     X509_STORE_CTX_free(ctx); // Cleanup: Free the allocated memory and release resources.
304     X509_STORE_free(store);
305     return res;
306 }
307 
ConvertByteArrayToPubKey(const uint8_t * pubKeyBytes,size_t len)308 static EVP_PKEY *ConvertByteArrayToPubKey(const uint8_t *pubKeyBytes, size_t len)
309 {
310     if (pubKeyBytes == NULL) {
311         LOGE("ConvertByteArrayToPubkey invalid params.");
312         return NULL;
313     }
314     EVP_PKEY *pubKey = d2i_PUBKEY(NULL, &pubKeyBytes, len); // pubkey DER format.
315     if (pubKey == NULL) {
316         LOGE("d2i_PUBKEY() failed!");
317         CfPrintOpensslError();
318         return NULL;
319     }
320 
321     return pubKey;
322 }
323 
CheckOthersInTrustAnchor(const HcfX509TrustAnchor * anchor,X509 * rootCert,bool * checkResult)324 static CfResult CheckOthersInTrustAnchor(const HcfX509TrustAnchor *anchor, X509 *rootCert, bool *checkResult)
325 {
326     *checkResult = false;
327     if (anchor->CAPubKey == NULL) {
328         return CF_SUCCESS;
329     }
330 
331     // 1. validate public key of the root CA.
332     EVP_PKEY *pubKey = ConvertByteArrayToPubKey(anchor->CAPubKey->data, anchor->CAPubKey->size);
333     if (pubKey == NULL) {
334         LOGE("ConvertByteArrayToPubKey failed!");
335         return CF_ERR_CRYPTO_OPERATION;
336     }
337     /* pubkey in trust anchor may be the pubkey of self or of its upper level cert. */
338     bool matchUpperPubKey = false;
339     if (CheckSelfPubkey(rootCert, pubKey) != CF_SUCCESS) {
340         matchUpperPubKey = (X509_verify(rootCert, pubKey) == CF_OPENSSL_SUCCESS);
341         if (!matchUpperPubKey) {
342             LOGE("verify pubkey in trust anchor failed!");
343             CfPrintOpensslError();
344             EVP_PKEY_free(pubKey);
345             return CF_SUCCESS;
346         }
347     }
348 
349     /* If pubkey is of self cert, the subject should be of self cert.
350      * If pubkey is of upper level cert, the subject should be of uppoer level cert (i.e. the issuer of self cert).
351      */
352     if (anchor->CASubject != NULL) {
353         // 2. compare subject name of root CA.
354         X509NameType nameType = NAME_TYPE_SUBJECT;
355         if (matchUpperPubKey) {
356             nameType = NAME_TYPE_ISSUER;
357         }
358         bool compareSubjectFlag = false;
359         CfResult res = CompareNameObject(rootCert, anchor->CASubject, nameType, &compareSubjectFlag);
360         if (res != CF_SUCCESS) {
361             LOGE("verify subject in trust anchor failed!");
362             EVP_PKEY_free(pubKey);
363             return res;
364         }
365         LOGI("verify subject in trust anchor result: %d", compareSubjectFlag);
366         *checkResult = compareSubjectFlag;
367     } else {
368         *checkResult = true;
369     }
370     EVP_PKEY_free(pubKey);
371     return CF_SUCCESS;
372 }
373 
GetTrustAnchor(const HcfX509TrustAnchor * trustAnchors,X509 * rootCert,X509 ** mostTrustCertOut)374 static CfResult GetTrustAnchor(const HcfX509TrustAnchor *trustAnchors, X509 *rootCert, X509 **mostTrustCertOut)
375 {
376     if (trustAnchors == NULL || rootCert == NULL || mostTrustCertOut == NULL) {
377         LOGE("GetTrustAnchorCert() invalid params!");
378         return CF_INVALID_PARAMS;
379     }
380 
381     if (trustAnchors->CACert != NULL) {
382         X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)trustAnchors->CACert);
383         if (cert == NULL) {
384             LOGE("GetTrustAnchorCert() cert is null.");
385             return CF_INVALID_PARAMS;
386         }
387 
388         X509_NAME *subjectName = X509_get_subject_name(cert);
389         if (subjectName == NULL) {
390             CfPrintOpensslError();
391             return CF_ERR_CRYPTO_OPERATION;
392         }
393         X509_NAME *subjectRoot = X509_get_subject_name(rootCert);
394         if (subjectRoot == NULL) {
395             CfPrintOpensslError();
396             return CF_ERR_CRYPTO_OPERATION;
397         }
398         EVP_PKEY *pubKey = X509_get_pubkey(cert); // validate public key of the trustAnchor CACert. X509_check_issued
399         if (pubKey == NULL) {
400             LOGE("X509_get_pubkey() failed!");
401             CfPrintOpensslError();
402             return CF_ERR_CRYPTO_OPERATION;
403         }
404         if (X509_verify(rootCert, pubKey) != CF_OPENSSL_SUCCESS && X509_NAME_cmp(subjectName, subjectRoot)) {
405             LOGE("X509_verify() failed!");
406             CfPrintOpensslError();
407             EVP_PKEY_free(pubKey);
408             return CF_SUCCESS; // continue to try next trustAnchor
409         }
410         EVP_PKEY_free(pubKey);
411         *mostTrustCertOut = cert;
412         return CF_SUCCESS;
413     }
414 
415     bool checkResult = false;
416     CfResult res = CheckOthersInTrustAnchor(trustAnchors, rootCert, &checkResult);
417     if (res != CF_SUCCESS) {
418         LOGE("CheckOthersInTrustAnchor failed.");
419         return res;
420     }
421 
422     if (checkResult) {
423         *mostTrustCertOut = rootCert;
424     }
425     return CF_SUCCESS;
426 }
427 
FreeTrustAnchorData(HcfX509TrustAnchor * trustAnchor)428 static void FreeTrustAnchorData(HcfX509TrustAnchor *trustAnchor)
429 {
430     if (trustAnchor == NULL) {
431         return;
432     }
433     CfBlobFree(&trustAnchor->CAPubKey);
434     CfBlobFree(&trustAnchor->CASubject);
435     CfObjDestroy(trustAnchor->CACert);
436     trustAnchor->CACert = NULL;
437 }
438 
CopyHcfX509TrustAnchor(const HcfX509TrustAnchor * inputAnchor,HcfX509TrustAnchor * outAnchor)439 static CfResult CopyHcfX509TrustAnchor(const HcfX509TrustAnchor *inputAnchor, HcfX509TrustAnchor *outAnchor)
440 {
441     HcfX509Certificate *CACert = inputAnchor->CACert;
442     CfBlob *CAPubKey = inputAnchor->CAPubKey;
443     CfBlob *CASubject = inputAnchor->CASubject;
444     CfBlob *nameConstraints = inputAnchor->nameConstraints;
445     CfResult res = CF_SUCCESS;
446     if (CACert != NULL) {
447         CfEncodingBlob encodedByte = { NULL, 0, CF_FORMAT_DER };
448         CACert->base.getEncoded((HcfCertificate *)CACert, &encodedByte);
449         res = HcfX509CertificateCreate(&encodedByte, &outAnchor->CACert);
450         if (res != CF_SUCCESS) {
451             LOGE("HcfX509CertificateCreate fail, res : %d!", res);
452             CfFree(encodedByte.data);
453             return CF_ERR_MALLOC;
454         }
455         CfFree(encodedByte.data);
456     }
457     if (CAPubKey != NULL) {
458         res = DeepCopyBlobToBlob(CAPubKey, &outAnchor->CAPubKey);
459         if (res != CF_SUCCESS) {
460             LOGE("DeepCopyDataToBlob failed");
461             CfObjDestroy(outAnchor->CACert);
462             return res;
463         }
464     }
465     if (CASubject != NULL) {
466         res = DeepCopyBlobToBlob(CASubject, &outAnchor->CASubject);
467         if (res != CF_SUCCESS) {
468             LOGE("DeepCopyDataToBlob failed");
469             CfObjDestroy(outAnchor->CACert);
470             CfBlobFree(&outAnchor->CAPubKey);
471             return res;
472         }
473     }
474     if (nameConstraints != NULL) {
475         res = DeepCopyBlobToBlob(nameConstraints, &outAnchor->nameConstraints);
476         if (res != CF_SUCCESS) {
477             LOGE("DeepCopyDataToBlob failed");
478             CfObjDestroy(outAnchor->CACert);
479             CfBlobFree(&outAnchor->CAPubKey);
480             CfBlobFree(&outAnchor->CASubject);
481             return res;
482         }
483     }
484 
485     return res;
486 }
487 
FillValidateResult(HcfX509TrustAnchor * inputAnchor,X509 * cert,HcfX509CertChainValidateResult * result)488 static CfResult FillValidateResult(HcfX509TrustAnchor *inputAnchor, X509 *cert, HcfX509CertChainValidateResult *result)
489 {
490     if (inputAnchor == NULL || cert == NULL) {
491         LOGE("FillValidateResult() invalidate params!");
492         return CF_INVALID_PARAMS;
493     }
494     CfResult res = CF_SUCCESS;
495     HcfX509TrustAnchor *validateTrustAnchors = (HcfX509TrustAnchor *)CfMalloc(sizeof(HcfX509TrustAnchor), 0);
496     if (validateTrustAnchors == NULL) {
497         LOGE("FillValidateResult() malloc failed");
498         return CF_ERR_MALLOC;
499     }
500     res = CopyHcfX509TrustAnchor(inputAnchor, validateTrustAnchors);
501     if (res != CF_SUCCESS) {
502         LOGE("CopyHcfX509TrustAnchor() failed!");
503         CfFree(validateTrustAnchors);
504         return res;
505     }
506 
507     result->trustAnchor = validateTrustAnchors;
508     HcfX509Certificate *entityCert = NULL;
509     res = X509ToHcfX509Certificate(cert, &entityCert);
510     if (res != CF_SUCCESS) {
511         LOGE("X509ToHcfX509Certificate() failed!");
512         FreeTrustAnchorData(result->trustAnchor);
513         CF_FREE_PTR(result->trustAnchor);
514         return res;
515     }
516 
517     result->entityCert = entityCert;
518     return res;
519 }
520 
ParseX509CRL(const CfEncodingBlob * inStream)521 static X509_CRL *ParseX509CRL(const CfEncodingBlob *inStream)
522 {
523     if ((inStream->data == NULL) || (inStream->len <= 0)) {
524         LOGE("Invalid params!");
525         return NULL;
526     }
527     BIO *bio = BIO_new_mem_buf(inStream->data, inStream->len);
528     if (bio == NULL) {
529         LOGE("bio get null!");
530         CfPrintOpensslError();
531         return NULL;
532     }
533     X509_CRL *crlOut = NULL;
534     switch (inStream->encodingFormat) {
535         case CF_FORMAT_DER:
536             crlOut = d2i_X509_CRL_bio(bio, NULL);
537             break;
538         case CF_FORMAT_PEM:
539             crlOut = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
540             break;
541         default:
542             LOGE("Not support format!");
543             break;
544     }
545     BIO_free_all(bio);
546     if (crlOut == NULL) {
547         LOGE("Parse X509 CRL fail!");
548         CfPrintOpensslError();
549         return NULL;
550     }
551     return crlOut;
552 }
553 
PushCrl2Stack(HcfX509CrlArray * crlArray,STACK_OF (X509_CRL)* outCrls)554 static CfResult PushCrl2Stack(HcfX509CrlArray *crlArray, STACK_OF(X509_CRL) *outCrls)
555 {
556     CfResult res = CF_SUCCESS;
557     HcfX509Crl *x509Crl = NULL;
558     X509_CRL *crl = NULL;
559     for (uint32_t i = 0; i < crlArray->count; i++) {
560         CfEncodingBlob encodedBlob = { 0 };
561         x509Crl = crlArray->data[i];
562         res = x509Crl->getEncoded(x509Crl, &encodedBlob);
563         if (res != CF_SUCCESS) {
564             LOGE("Failed to getEncoded of crl!");
565             return res;
566         }
567 
568         crl = ParseX509CRL(&encodedBlob);
569         CfFree(encodedBlob.data);
570         if (crl == NULL) {
571             LOGE("Failed to Parse x509 CRL!");
572             return CF_INVALID_PARAMS;
573         }
574         if (sk_X509_CRL_push(outCrls, crl) == 0) {
575             LOGE("sk_X509_CRL_push failed!");
576             X509_CRL_free(crl);
577             return CF_ERR_CRYPTO_OPERATION;
578         }
579     }
580     return res;
581 }
582 
GetX509Crls(const HcfCertCRLCollectionArray * certCRLCollections,STACK_OF (X509_CRL)* outCrls)583 static CfResult GetX509Crls(const HcfCertCRLCollectionArray *certCRLCollections, STACK_OF(X509_CRL) *outCrls)
584 {
585     if (certCRLCollections == NULL) { // certCRLCollection is not force params for verify certchain
586         LOGI("certcrlcollections is null!");
587         return CF_SUCCESS;
588     }
589 
590     CfResult res = CF_SUCCESS;
591     HcfX509CrlArray *crlArray = NULL;
592     HcfCertCrlCollection *crlCollection = NULL;
593     for (uint32_t i = 0; i < certCRLCollections->count; i++) {
594         crlCollection = certCRLCollections->data[i];
595         res = crlCollection->getCRLs(crlCollection, &crlArray);
596         if (res != CF_SUCCESS) {
597             LOGE("getCRLs() from CertCrlCollection failed!");
598             /* Warning: free outCrls in outside */
599             return res;
600         }
601         if (crlArray->count == 0) {
602             LOGI("crls array is empty.");
603             continue;
604         }
605         res = PushCrl2Stack(crlArray, outCrls);
606         if (res != CF_SUCCESS) {
607             LOGE("push crls to stack failed!");
608             /* Warning: free outCrls in outside */
609             return res;
610         }
611     }
612 
613     return res;
614 }
615 
ValidateCrlLocal(const HcfCertCRLCollectionArray * collectionArr,STACK_OF (X509)* x509CertChain)616 static CfResult ValidateCrlLocal(const HcfCertCRLCollectionArray *collectionArr, STACK_OF(X509) *x509CertChain)
617 {
618     STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
619     if (crlStack == NULL) {
620         LOGE("sk X509 CRL new null failed!");
621         CfPrintOpensslError();
622         return CF_ERR_CRYPTO_OPERATION;
623     }
624 
625     CfResult res = GetX509Crls(collectionArr, crlStack);
626     if (res != CF_SUCCESS) {
627         LOGE("GetX509Crls failed");
628         sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
629         return res;
630     }
631 
632     if (sk_X509_CRL_num(crlStack) == 0) {
633         LOGI("crls count is 0");
634         sk_X509_CRL_free(crlStack);
635         return CF_SUCCESS;
636     }
637     res = CheckCertChainIsRevoked(crlStack, x509CertChain);
638     sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
639     return res;
640 }
641 
ValidateNC(STACK_OF (X509)* x509CertChain,CfBlob * nameConstraints)642 static CfResult ValidateNC(STACK_OF(X509) *x509CertChain, CfBlob *nameConstraints)
643 {
644     if (nameConstraints == NULL) {
645         LOGI("NameConstraints from js is null!");
646         return CF_SUCCESS;
647     }
648 
649     const unsigned char *p = nameConstraints->data;
650     NAME_CONSTRAINTS *nc =
651         (NAME_CONSTRAINTS *)ASN1_item_d2i(NULL, &p, nameConstraints->size, ASN1_ITEM_rptr(NAME_CONSTRAINTS));
652     if (nc == NULL) {
653         LOGE("Get nameConstraints from js failed!");
654         return CF_INVALID_PARAMS;
655     }
656 
657     CfResult res = CF_SUCCESS;
658     for (int i = 0; i < sk_X509_num(x509CertChain); i++) {
659         X509 *cert = sk_X509_value(x509CertChain, i);
660         if (cert == NULL) {
661             LOGE("Get cert from stack to check nameConstraints failed!");
662             res = CF_INVALID_PARAMS;
663             break;
664         }
665         if (CheckIsLeafCert(cert) && !CheckIsSelfSigned(cert)) {
666             if (NAME_CONSTRAINTS_check(cert, nc) != X509_V_OK) {
667                 LOGE("Check nameConstraints failed!");
668                 res = CF_INVALID_PARAMS;
669                 break;
670             }
671         }
672     }
673 
674     NAME_CONSTRAINTS_free(nc);
675     return res;
676 }
677 
ValidateTrustAnchor(const HcfX509TrustAnchorArray * trustAnchorsArray,X509 * rootCert,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor ** trustAnchorResult)678 static CfResult ValidateTrustAnchor(const HcfX509TrustAnchorArray *trustAnchorsArray, X509 *rootCert,
679     STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor **trustAnchorResult)
680 {
681     CfResult res = CF_SUCCESS;
682     for (uint32_t i = 0; i < trustAnchorsArray->count; ++i) {
683         X509 *mostTrustAnchorCert = NULL;
684         HcfX509TrustAnchor *trustAnchor = trustAnchorsArray->data[i];
685         res = GetTrustAnchor(trustAnchor, rootCert, &mostTrustAnchorCert);
686         if (res != CF_SUCCESS) {
687             LOGE("Get trust anchor cert failed, try next trustAnchor.");
688             return res;
689         }
690         if (mostTrustAnchorCert == NULL) {
691             LOGE("most trust anchor cert is null.");
692             res = CF_INVALID_PARAMS; /* if validate trust anchor list failed, return the last error. */
693             continue;
694         }
695 
696         res = VerifyCertChain(mostTrustAnchorCert, x509CertChain);
697         if (res != CF_SUCCESS) { // verify the data & crl list of certchain
698             LOGI("verify one trustanchor failed, try next trustAnchor.");
699             continue;
700         }
701 
702         res = ValidateNC(x509CertChain, trustAnchor->nameConstraints);
703         if (res != CF_SUCCESS) {
704             LOGI("verify nameConstraints failed, try next trustAnchor.");
705             continue;
706         }
707         *trustAnchorResult = trustAnchor;
708         break;
709     }
710 
711     return res;
712 }
713 
GetDpUrl(DIST_POINT * dp)714 static const char *GetDpUrl(DIST_POINT *dp)
715 {
716     GENERAL_NAMES *gens = NULL;
717     GENERAL_NAME *gen = NULL;
718     ASN1_STRING *url = NULL;
719 
720     if (dp == NULL || dp->distpoint == NULL || dp->distpoint->type != 0) {
721         return NULL;
722     }
723     gens = dp->distpoint->name.fullname;
724     if (gens == NULL) {
725         return NULL;
726     }
727     for (int32_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
728         gen = sk_GENERAL_NAME_value(gens, i);
729         if (gen == NULL) {
730             continue;
731         }
732         int gtype;
733         url = GENERAL_NAME_get0_value(gen, &gtype);
734         if (url == NULL) {
735             continue;
736         }
737         if (gtype == GEN_URI && ASN1_STRING_length(url) > GEN_URI) {
738             const char *uptr = (const char *)ASN1_STRING_get0_data(url);
739             if (CfIsHttp(uptr)) {
740                 // can/should not use HTTPS here
741                 return uptr;
742             }
743         }
744     }
745     return NULL;
746 }
747 
LoadCrlDp(STACK_OF (DIST_POINT)* crldp)748 static X509_CRL *LoadCrlDp(STACK_OF(DIST_POINT) *crldp)
749 {
750     const char *urlptr = NULL;
751     for (int i = 0; i < sk_DIST_POINT_num(crldp); i++) {
752         DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
753         urlptr = GetDpUrl(dp);
754         if (urlptr != NULL) {
755             return X509_CRL_load_http(urlptr, NULL, NULL, HTTP_TIMEOUT);
756         }
757     }
758     return NULL;
759 }
760 
GetCrlFromCert(const HcfX509CertChainValidateParams * params,X509 * x509)761 static X509_CRL *GetCrlFromCert(const HcfX509CertChainValidateParams *params, X509 *x509)
762 {
763     STACK_OF(DIST_POINT) *crlStack = X509_get_ext_d2i(x509, NID_crl_distribution_points, NULL, NULL);
764     if (crlStack != NULL) {
765         X509_CRL *crl = LoadCrlDp(crlStack);
766         sk_DIST_POINT_pop_free(crlStack, DIST_POINT_free);
767         if (crl != NULL) {
768             return crl;
769         }
770     }
771 
772     if (params->revocationCheckParam->crlDownloadURI != NULL &&
773         params->revocationCheckParam->crlDownloadURI->data != NULL) {
774         char *url = (char *)params->revocationCheckParam->crlDownloadURI->data;
775         if (CfIsUrlValid(url)) {
776             return X509_CRL_load_http(url, NULL, NULL, HTTP_TIMEOUT);
777         }
778     }
779 
780     return NULL;
781 }
782 
ValidateCrlOnline(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain)783 static CfResult ValidateCrlOnline(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain)
784 {
785     X509 *x509 = sk_X509_value(x509CertChain, 0);
786     if (x509 == NULL) {
787         LOGE("Get leaf cert failed!");
788         return CF_INVALID_PARAMS;
789     }
790     X509_CRL *crl = GetCrlFromCert(params, x509);
791     if (crl == NULL) {
792         LOGE("Get crl online is null!");
793         return CF_ERR_CRYPTO_OPERATION;
794     }
795 
796     STACK_OF(X509_CRL) *crlStack = sk_X509_CRL_new_null();
797     if (crlStack == NULL) {
798         LOGE("Create crl stack failed!");
799         return CF_ERR_CRYPTO_OPERATION;
800     }
801     if (sk_X509_CRL_push(crlStack, crl) == 0) {
802         LOGE("Push crl stack failed!");
803         sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
804         return CF_ERR_CRYPTO_OPERATION;
805     }
806     if (CheckCertChainIsRevoked(crlStack, x509CertChain) != CF_SUCCESS) {
807         LOGE("Certchain is revoked, verify failed!");
808         sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
809         return CF_ERR_CRYPTO_OPERATION;
810     }
811 
812     sk_X509_CRL_pop_free(crlStack, X509_CRL_free);
813     return CF_SUCCESS;
814 }
815 
ContainsOption(HcfRevChkOpArray * options,HcfRevChkOption op)816 static bool ContainsOption(HcfRevChkOpArray *options, HcfRevChkOption op)
817 {
818     if (options == NULL || options->data == NULL) {
819         return false;
820     }
821 
822     for (uint32_t i = 0; i < options->count; i++) {
823         if (options->data[i] == op) {
824             return true;
825         }
826     }
827     return false;
828 }
829 
VerifyOcspSigner(OCSP_BASICRESP * bs,STACK_OF (X509)* certChain,X509 * cert)830 static CfResult VerifyOcspSigner(OCSP_BASICRESP *bs, STACK_OF(X509) *certChain, X509 *cert)
831 {
832     if (cert == NULL) {
833         LOGE("Input data cert is null!");
834         return CF_INVALID_PARAMS;
835     }
836     X509_STORE *store = X509_STORE_new();
837     if (store == NULL) {
838         LOGE("New x509 store failed!");
839         return CF_ERR_CRYPTO_OPERATION;
840     }
841     CfResult res = SetVerifyParams(store, cert);
842     if (res != CF_SUCCESS) {
843         LOGE("Set verify params failed!");
844         X509_STORE_free(store);
845         return res;
846     }
847 
848     if (OCSP_basic_verify(bs, certChain, store, 0) != 1) {
849         LOGE("OCSP basic verify failed!");
850         res = CF_ERR_CERT_SIGNATURE_FAILURE;
851     }
852     X509_STORE_free(store);
853 
854     return res;
855 }
856 
ParseResp(OCSP_BASICRESP * bs,OcspCertIdInfo * certIdInfo)857 static CfResult ParseResp(OCSP_BASICRESP *bs, OcspCertIdInfo *certIdInfo)
858 {
859     int ocspStatus;
860     ASN1_GENERALIZEDTIME *thisUpdate = NULL;
861     ASN1_GENERALIZEDTIME *nextUpdate = NULL;
862     CfResult res = CF_ERR_CRYPTO_OPERATION;
863 
864     OCSP_CERTID *certId = OCSP_cert_to_id(certIdInfo->md, certIdInfo->subjectCert, certIdInfo->issuerCert);
865     if (certId == NULL) {
866         LOGE("Unable to create certId.");
867         return CF_ERR_CRYPTO_OPERATION;
868     }
869 
870     if (OCSP_resp_find_status(bs, certId, &ocspStatus, NULL, NULL, &thisUpdate, &nextUpdate) == 1) {
871         switch (ocspStatus) {
872             case V_OCSP_CERTSTATUS_GOOD:
873                 LOGI("The OCSP status is [V_OCSP_CERTSTATUS_GOOD]!");
874                 res = CF_SUCCESS;
875                 break;
876             case V_OCSP_CERTSTATUS_REVOKED:
877                 LOGE("The OCSP status is [V_OCSP_CERTSTATUS_REVOKED]!");
878                 break;
879             case V_OCSP_CERTSTATUS_UNKNOWN:
880             default:
881                 LOGE("!The OCSP status is [UNKNOWN]!");
882                 break;
883         }
884     }
885     OCSP_CERTID_free(certId);
886     return res;
887 }
888 
ValidateOcspLocalGetTrustCert(STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params,HcfRevocationCheckParam * revo,X509 ** trustCert)889 static void ValidateOcspLocalGetTrustCert(STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchor,
890     const HcfX509CertChainValidateParams *params, HcfRevocationCheckParam *revo, X509 **trustCert)
891 {
892     if (revo->ocspResponderCert != NULL) {
893         *trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(params->revocationCheckParam->ocspResponderCert));
894     } else if (trustAnchor->CACert != NULL) {
895         *trustCert = GetX509FromHcfX509Certificate((HcfCertificate *)(trustAnchor->CACert));
896     } else {
897         *trustCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
898     }
899 }
900 
ValidateOcspLocal(OcspLocalParam localParam,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)901 static CfResult ValidateOcspLocal(OcspLocalParam localParam, STACK_OF(X509) *x509CertChain,
902     HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
903 {
904     int i;
905     X509 *trustCert = NULL;
906     OCSP_RESPONSE *rsp = NULL;
907     if (localParam.certIdInfo == NULL) {
908         LOGE("The input data is null!");
909         return CF_INVALID_PARAMS;
910     }
911     HcfRevocationCheckParam *revo = params->revocationCheckParam;
912     if (localParam.resp == NULL && revo->ocspResponses != NULL) {
913         const unsigned char *p = revo->ocspResponses->data;
914         rsp = d2i_OCSP_RESPONSE(NULL, &p, revo->ocspResponses->size);
915         localParam.resp = rsp;
916     }
917     if (localParam.resp == NULL) {
918         LOGE("The input data is null!");
919         return CF_ERR_CRYPTO_OPERATION;
920     }
921     if (OCSP_response_status(localParam.resp) != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
922         LOGE("The resp status is not success!");
923         OCSP_RESPONSE_free(rsp);
924         return CF_ERR_CRYPTO_OPERATION;
925     }
926     OCSP_BASICRESP *bs = OCSP_response_get1_basic(localParam.resp);
927     OCSP_RESPONSE_free(rsp);
928     if (bs == NULL) {
929         LOGE("Error parsing response!");
930         return CF_ERR_CRYPTO_OPERATION;
931     }
932     if (localParam.req != NULL && ((i = OCSP_check_nonce(localParam.req, bs)) <= 0)) {
933         if (i == -1) {
934             LOGW("No nonce in response!");
935         } else {
936             LOGE("Nonce Verify error!");
937             OCSP_BASICRESP_free(bs);
938             return CF_ERR_CRYPTO_OPERATION;
939         }
940     }
941 
942     ValidateOcspLocalGetTrustCert(x509CertChain, trustAnchor, params, revo, &trustCert);
943     CfResult res = VerifyOcspSigner(bs, x509CertChain, trustCert);
944     if (res != CF_SUCCESS) {
945         LOGE("VerifySinger failed!");
946         OCSP_BASICRESP_free(bs);
947         return res;
948     }
949     res = ParseResp(bs, localParam.certIdInfo);
950     OCSP_BASICRESP_free(bs);
951     return res;
952 }
953 
SendReqBioCustom(BIO * bio,const char * host,const char * path,OCSP_REQUEST * req)954 static OCSP_RESPONSE *SendReqBioCustom(BIO *bio, const char *host, const char *path, OCSP_REQUEST *req)
955 {
956     OCSP_RESPONSE *resp = NULL;
957     OCSP_REQ_CTX *ctx;
958 
959     ctx = OCSP_sendreq_new(bio, path, NULL, -1);
960     if (ctx == NULL) {
961         LOGE("Create ocsp req ctx failed!");
962         return NULL;
963     }
964     if (!OCSP_REQ_CTX_add1_header(ctx, "Accept", "application/ocsp-response")) {
965         OCSP_REQ_CTX_free(ctx);
966         return NULL;
967     }
968     if (!OCSP_REQ_CTX_add1_header(ctx, "Host", host)) {
969         OCSP_REQ_CTX_free(ctx);
970         return NULL;
971     }
972     if (!OCSP_REQ_CTX_set1_req(ctx, req)) {
973         OCSP_REQ_CTX_free(ctx);
974         return NULL;
975     }
976     int ret;
977     int tryNum = TRY_CONNECT_TIMES;
978     do {
979         ret = OCSP_sendreq_nbio(&resp, ctx);
980         tryNum--;
981     } while ((ret == -1) && BIO_should_retry(bio) && tryNum != 0);
982     OCSP_REQ_CTX_free(ctx);
983     if (ret) {
984         return resp;
985     }
986     return NULL;
987 }
988 
ConnectToServer(BIO * bio,int tryNum)989 static bool ConnectToServer(BIO *bio, int tryNum)
990 {
991     int ret = 0;
992     int num = tryNum;
993     do {
994         ret = BIO_do_connect_retry(bio, OCSP_CONN_TIMEOUT, OCSP_CONN_MILLISECOND);
995         if (ret == 1) {
996             break;
997         } else if (ret <= 0) {
998             LOGE("OCSP connecte service failed.");
999             CfPrintOpensslError();
1000             if (BIO_should_retry(bio)) {
1001                 LOGI("Try to connect service again, [%d]st.", num);
1002                 num--;
1003             } else {
1004                 break;
1005             }
1006         }
1007     } while (ret <= 0 && num != 0);
1008     return (ret == 1 ? true : false);
1009 }
1010 
GetOcspUrl(GetOcspUrlParams * params)1011 static CfResult GetOcspUrl(GetOcspUrlParams *params)
1012 {
1013     char *url = NULL;
1014 
1015     if (params->leafCert == NULL) {
1016         LOGE("The input param invalid.");
1017         return CF_INVALID_PARAMS;
1018     }
1019     STACK_OF(OPENSSL_STRING) *ocspList = X509_get1_ocsp(params->leafCert);
1020     if (ocspList != NULL && sk_OPENSSL_STRING_num(ocspList) > 0) {
1021         url = sk_OPENSSL_STRING_value(ocspList, 0);
1022     }
1023 
1024     if (url == NULL) {
1025         if (params->revo->ocspResponderURI == NULL || params->revo->ocspResponderURI->data == NULL) {
1026             LOGE("Unable to get url.");
1027             return CF_ERR_CRYPTO_OPERATION;
1028         }
1029     }
1030     char *urlValiable = (url == NULL) ? (char *)(params->revo->ocspResponderURI->data) : url;
1031     if (!CfIsUrlValid(urlValiable)) {
1032         LOGE("Invalid url.");
1033         return CF_INVALID_PARAMS;
1034     }
1035     if (!OCSP_parse_url(urlValiable, params->host, params->port, params->path, params->ssl)) {
1036         LOGE("Unable to parse url.");
1037         return CF_ERR_CRYPTO_OPERATION;
1038     }
1039     return CF_SUCCESS;
1040 }
1041 
SetRequestData(HcfRevocationCheckParam * revo,OCSP_REQUEST * req,OcspCertIdInfo * certIdInfo)1042 static CfResult SetRequestData(HcfRevocationCheckParam *revo, OCSP_REQUEST *req, OcspCertIdInfo *certIdInfo)
1043 {
1044     OCSP_CERTID *certId = OCSP_cert_to_id(certIdInfo->md, certIdInfo->subjectCert, certIdInfo->issuerCert);
1045     if (certId == NULL) {
1046         LOGE("Unable to create certId.");
1047         return CF_ERR_CRYPTO_OPERATION;
1048     }
1049 
1050     if (OCSP_request_add0_id(req, certId) == NULL) {
1051         LOGE("Unable to add certId to req.");
1052         OCSP_CERTID_free(certId);
1053         return CF_INVALID_PARAMS;
1054     }
1055 
1056     if (revo->ocspRequestExtension != NULL) {
1057         for (size_t i = 0; i < revo->ocspRequestExtension->count; i++) {
1058             const unsigned char *p = revo->ocspRequestExtension->data[i].data;
1059             X509_EXTENSION *ext = d2i_X509_EXTENSION(NULL, &p, revo->ocspRequestExtension->data[i].size);
1060             if (ext == NULL) {
1061                 return CF_INVALID_PARAMS;
1062             }
1063             if (!OCSP_REQUEST_add_ext(req, ext, -1)) {
1064                 X509_EXTENSION_free(ext);
1065                 return CF_ERR_CRYPTO_OPERATION;
1066             }
1067             X509_EXTENSION_free(ext);
1068             ext = NULL;
1069         }
1070     }
1071 
1072     return CF_SUCCESS;
1073 }
1074 
CreateConnectBio(char * host,char * port,int ssl)1075 static BIO *CreateConnectBio(char *host, char *port, int ssl)
1076 {
1077     BIO *bio = NULL;
1078     if (ssl == 1) {
1079         SSL_library_init();
1080         SSL_load_error_strings();
1081         OpenSSL_add_all_algorithms();
1082 
1083         SSL_CTX *sslCtx = SSL_CTX_new(TLS_client_method());
1084         if (sslCtx == NULL) {
1085             return NULL;
1086         }
1087         bio = BIO_new_ssl_connect(sslCtx);
1088         if (bio == NULL) {
1089             LOGE("bio is null.");
1090             SSL_CTX_free(sslCtx);
1091             return NULL;
1092         }
1093         if (BIO_set_conn_hostname(bio, host) != 1) {
1094             LOGE("Set host name failed.");
1095             BIO_free_all(bio);
1096             SSL_CTX_free(sslCtx);
1097             return NULL;
1098         }
1099     } else {
1100         bio = BIO_new_connect(host);
1101     }
1102 
1103     if (bio == NULL) {
1104         LOGE("Create connect bio failed.");
1105         return bio;
1106     }
1107 
1108     if (port != NULL) {
1109         if (BIO_set_conn_port(bio, port) != 1) {
1110             LOGE("Set port failed.");
1111             BIO_free_all(bio);
1112             return NULL;
1113         }
1114     } else if (ssl) {
1115         if (BIO_set_conn_port(bio, HTTPS_PORT) != 1) {
1116             LOGE("Set port failed.");
1117             BIO_free_all(bio);
1118             return NULL;
1119         }
1120     } else {
1121         if (BIO_set_conn_port(bio, HTTP_PORT) != 1) {
1122             LOGE("Set port failed.");
1123             BIO_free_all(bio);
1124             return NULL;
1125         }
1126     }
1127     return bio;
1128 }
1129 
ValidateOcspOnline(STACK_OF (X509)* x509CertChain,OcspCertIdInfo * certIdInfo,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)1130 static CfResult ValidateOcspOnline(STACK_OF(X509) *x509CertChain, OcspCertIdInfo *certIdInfo,
1131     HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
1132 {
1133     char *host = NULL;
1134     char *port = NULL;
1135     char *path = NULL;
1136     int ssl = 0;
1137 
1138     HcfRevocationCheckParam *revo = params->revocationCheckParam;
1139 
1140     CfResult res = GetOcspUrl(&(GetOcspUrlParams) { .leafCert = sk_X509_value(x509CertChain, 0),
1141         .revo = revo, .host = &host, .port = &port, .path = &path, .ssl = &ssl });
1142     if (res != CF_SUCCESS) {
1143         LOGE("Unable to get ocps url.");
1144         return res;
1145     }
1146 
1147     BIO *cbio = CreateConnectBio(host, port, ssl);
1148     if (cbio == NULL) {
1149         LOGE("Unable to create connection.");
1150         return CF_ERR_CRYPTO_OPERATION;
1151     }
1152     if (!ConnectToServer(cbio, TRY_CONNECT_TIMES)) {
1153         LOGE("Unable to connect service.");
1154         BIO_free_all(cbio);
1155         return CF_ERR_CRYPTO_OPERATION;
1156     }
1157     OCSP_REQUEST *req = OCSP_REQUEST_new();
1158     if (req == NULL) {
1159         LOGE("Unable to create req.");
1160         BIO_free_all(cbio);
1161         return CF_ERR_CRYPTO_OPERATION;
1162     }
1163     res = SetRequestData(revo, req, certIdInfo);
1164     if (res != CF_SUCCESS) {
1165         LOGE("Unable to set request data.");
1166         OCSP_REQUEST_free(req);
1167         BIO_free_all(cbio);
1168         return res;
1169     }
1170 
1171     /* Send OCSP request and wait for response */
1172     OCSP_RESPONSE *resp = SendReqBioCustom(cbio, host, path, req);
1173     if (resp == NULL) {
1174         LOGE("Unable to send request.");
1175         OCSP_REQUEST_free(req);
1176         BIO_free_all(cbio);
1177         return CF_ERR_CRYPTO_OPERATION;
1178     }
1179     res = ValidateOcspLocal(
1180         (OcspLocalParam) { .req = req, .resp = resp, .certIdInfo = certIdInfo }, x509CertChain, trustAnchor, params);
1181     OCSP_REQUEST_free(req);
1182     BIO_free_all(cbio);
1183     OCSP_RESPONSE_free(resp);
1184     return res;
1185 }
1186 
GetHashDigest(const CfBlob * ocspDigest)1187 static const EVP_MD *GetHashDigest(const CfBlob *ocspDigest)
1188 {
1189     if (ocspDigest == NULL || ocspDigest->data == NULL) {
1190         return EVP_sha256();
1191     }
1192     char *mdName = (char *)ocspDigest->data;
1193     if (strcmp(mdName, "SHA1") == 0) {
1194         return EVP_sha1();
1195     } else if (strcmp(mdName, "SHA224") == 0) {
1196         return EVP_sha224();
1197     } else if (strcmp(mdName, "SHA256") == 0) {
1198         return EVP_sha256();
1199     } else if (strcmp(mdName, "SHA384") == 0) {
1200         return EVP_sha384();
1201     } else if (strcmp(mdName, "SHA512") == 0) {
1202         return EVP_sha512();
1203     } else if (strcmp(mdName, "MD5") == 0) {
1204         return EVP_md5();
1205     }
1206     return EVP_sha256();
1207 }
1208 
GetCertIssuerFromChain(STACK_OF (X509)* x509CertChain,X509 * leafCert,X509 ** issuerCert)1209 static CfResult GetCertIssuerFromChain(STACK_OF(X509) *x509CertChain, X509 *leafCert, X509 **issuerCert)
1210 {
1211     X509_STORE *store = NULL;
1212     X509_STORE_CTX *storeCtx = NULL;
1213     CfResult ret = CF_SUCCESS;
1214 
1215     store = X509_STORE_new();
1216     if (store == NULL) {
1217         LOGE("Unable to create store.");
1218         return CF_ERR_MALLOC;
1219     }
1220 
1221     for (int i = 1; i < sk_X509_num(x509CertChain); i++) {
1222         X509 *tmpCert = sk_X509_value(x509CertChain, i);
1223         if (X509_STORE_add_cert(store, tmpCert) != 1) {
1224             LOGE("Add cert to store failed.");
1225             X509_STORE_free(store);
1226             return CF_ERR_CRYPTO_OPERATION;
1227         }
1228     }
1229 
1230     storeCtx = X509_STORE_CTX_new();
1231     if (storeCtx == NULL) {
1232         LOGE("Unable to create storeCtx.");
1233         X509_STORE_free(store);
1234         return CF_ERR_MALLOC;
1235     }
1236 
1237     if (X509_STORE_CTX_init(storeCtx, store, NULL, NULL) == 0) {
1238         LOGE("Unable to init STORE_CTX.");
1239         ret = CF_ERR_CRYPTO_OPERATION;
1240         goto end;
1241     }
1242 
1243     if (X509_STORE_CTX_get1_issuer(issuerCert, storeCtx, leafCert) == -1) {
1244         LOGE("Some other error occurred when getting issuer.");
1245         ret = CF_ERR_CRYPTO_OPERATION;
1246         goto end;
1247     }
1248 
1249 end:
1250     X509_STORE_free(store);
1251     X509_STORE_CTX_free(storeCtx);
1252     return ret;
1253 }
1254 
GetCertIdInfo(STACK_OF (X509)* x509CertChain,const CfBlob * ocspDigest,OcspCertIdInfo * certIdInfo)1255 static CfResult GetCertIdInfo(STACK_OF(X509) *x509CertChain, const CfBlob *ocspDigest, OcspCertIdInfo *certIdInfo)
1256 {
1257     X509 *issuerCert = NULL;
1258     X509 *leafCert = NULL;
1259     CfResult ret = CF_INVALID_PARAMS;
1260 
1261     leafCert = sk_X509_value(x509CertChain, 0);
1262     if (leafCert == NULL) {
1263         LOGE("Get the leaf cert is null.");
1264         return CF_INVALID_PARAMS;
1265     }
1266 
1267     ret = GetCertIssuerFromChain(x509CertChain, leafCert, &issuerCert);
1268     if (ret != CF_SUCCESS) {
1269         LOGE("Get cert issuer from chain failed.");
1270         return ret;
1271     }
1272 
1273     if (X509_up_ref(leafCert) != 1) {
1274         LOGE("Unable to up ref leaf cert.");
1275         X509_free(issuerCert);
1276         return CF_ERR_CRYPTO_OPERATION;
1277     }
1278 
1279     certIdInfo->md = GetHashDigest(ocspDigest);
1280     certIdInfo->subjectCert = leafCert;
1281     certIdInfo->issuerCert = issuerCert;
1282     return CF_SUCCESS;
1283 }
1284 
ValidateRevocationOnLine(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,OcspCertIdInfo * certIdInfo)1285 static CfResult ValidateRevocationOnLine(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1286     HcfX509TrustAnchor *trustAnchor, OcspCertIdInfo *certIdInfo)
1287 {
1288     CfResult res = CF_INVALID_PARAMS;
1289     if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) {
1290         if ((res = ValidateOcspOnline(x509CertChain, certIdInfo, trustAnchor, params)) == CF_SUCCESS) {
1291             return res;
1292         }
1293         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER)) {
1294             if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) {
1295                 return res;
1296             }
1297         }
1298         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) {
1299             if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1300                                          x509CertChain, trustAnchor, params)) == CF_SUCCESS) {
1301                 return res;
1302             }
1303             return ValidateCrlLocal(params->certCRLCollections, x509CertChain);
1304         }
1305     } else {
1306         if ((res = ValidateCrlOnline(params, x509CertChain)) == CF_SUCCESS) {
1307             return res;
1308         }
1309         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER)) {
1310             if ((res = ValidateOcspOnline(x509CertChain, certIdInfo, trustAnchor, params)) == CF_SUCCESS) {
1311                 return res;
1312             }
1313         }
1314         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_FALLBACK_LOCAL)) {
1315             if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) {
1316                 return res;
1317             }
1318             return ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1319                                                         x509CertChain, trustAnchor, params);
1320         }
1321     }
1322     return res;
1323 }
1324 
ValidateRevocationLocal(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,OcspCertIdInfo * certIdInfo)1325 static CfResult ValidateRevocationLocal(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1326     HcfX509TrustAnchor *trustAnchor, OcspCertIdInfo *certIdInfo)
1327 {
1328     CfResult res = CF_INVALID_PARAMS;
1329     if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_PREFER_OCSP)) {
1330         if ((res = ValidateOcspLocal((OcspLocalParam) { .req = NULL, .resp = NULL, .certIdInfo = certIdInfo },
1331                                      x509CertChain, trustAnchor, params)) == CF_SUCCESS) {
1332             return res;
1333         }
1334     } else {
1335         if ((res = ValidateCrlLocal(params->certCRLCollections, x509CertChain)) == CF_SUCCESS) {
1336             return res;
1337         }
1338     }
1339     return CF_INVALID_PARAMS;
1340 }
1341 
FreeCertIdInfo(OcspCertIdInfo * certIdInfo)1342 static void FreeCertIdInfo(OcspCertIdInfo *certIdInfo)
1343 {
1344     if (certIdInfo->subjectCert != NULL) {
1345         X509_free(certIdInfo->subjectCert);
1346     }
1347     if (certIdInfo->issuerCert != NULL) {
1348         X509_free(certIdInfo->issuerCert);
1349     }
1350 }
1351 
ValidateRevocation(STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor * trustAnchor,const HcfX509CertChainValidateParams * params)1352 static CfResult ValidateRevocation(
1353     STACK_OF(X509) *x509CertChain, HcfX509TrustAnchor *trustAnchor, const HcfX509CertChainValidateParams *params)
1354 {
1355     if (x509CertChain == NULL || params == NULL) {
1356         LOGE("The input data is null!");
1357         return CF_INVALID_PARAMS;
1358     }
1359 
1360     if (params->revocationCheckParam && params->revocationCheckParam->options) {
1361         CfResult res = CF_INVALID_PARAMS;
1362         OcspCertIdInfo certIdInfo = {0};
1363         res = GetCertIdInfo(x509CertChain, params->revocationCheckParam->ocspDigest, &certIdInfo);
1364         if (res != CF_SUCCESS) {
1365             LOGE("Get cert id info failed.");
1366             return res;
1367         }
1368         if (ContainsOption(params->revocationCheckParam->options, REVOCATION_CHECK_OPTION_ACCESS_NETWORK)) {
1369             res = ValidateRevocationOnLine(params, x509CertChain, trustAnchor, &certIdInfo);
1370             if (res != CF_SUCCESS) {
1371                 LOGE("Try to validate revocation online failed.");
1372             }
1373         } else {
1374             res = ValidateRevocationLocal(params, x509CertChain, trustAnchor, &certIdInfo);
1375             if (res != CF_SUCCESS) {
1376                 LOGE("Try to validate revocation local failed.");
1377             }
1378         }
1379         FreeCertIdInfo(&certIdInfo);
1380         return res;
1381     } else {
1382         return ValidateCrlLocal(params->certCRLCollections, x509CertChain);
1383     }
1384 }
1385 
ValidateDate(const STACK_OF (X509)* x509CertChain,CfBlob * date)1386 static CfResult ValidateDate(const STACK_OF(X509) *x509CertChain, CfBlob *date)
1387 {
1388     if (date == NULL) {
1389         LOGI("date is null");
1390         return CF_SUCCESS;
1391     }
1392     if (!CfBlobIsStr(date)) {
1393         LOGE("time format is invalid");
1394         return CF_INVALID_PARAMS;
1395     }
1396     ASN1_TIME *asn1InputDate = ASN1_TIME_new();
1397     if (asn1InputDate == NULL) {
1398         LOGE("Failed to malloc for asn1 time.");
1399         return CF_ERR_MALLOC;
1400     }
1401     if (ASN1_TIME_set_string(asn1InputDate, (const char *)date->data) != CF_OPENSSL_SUCCESS) {
1402         LOGE("Failed to set time for asn1 time.");
1403         CfPrintOpensslError();
1404         ASN1_TIME_free(asn1InputDate);
1405         return CF_INVALID_PARAMS;
1406     }
1407     CfResult res = CF_SUCCESS;
1408     int certsNum = sk_X509_num(x509CertChain);
1409     for (int i = 0; i < certsNum; ++i) {
1410         X509 *cert = sk_X509_value(x509CertChain, i);
1411         if (cert == NULL) {
1412             LOGE("sk X509 value is null, failed!");
1413             CfPrintOpensslError();
1414             ASN1_TIME_free(asn1InputDate);
1415             return CF_ERR_CRYPTO_OPERATION;
1416         }
1417         res = CompareDateWithCertTime(cert, asn1InputDate);
1418         if (res != CF_SUCCESS) {
1419             LOGE("check validate failed.");
1420             ASN1_TIME_free(asn1InputDate);
1421             return res;
1422         }
1423     }
1424     ASN1_TIME_free(asn1InputDate);
1425     return res;
1426 }
1427 
ValidatePolicy(const STACK_OF (X509)* x509CertChain,HcfValPolicyType policy,CfBlob * sslHostname)1428 static CfResult ValidatePolicy(const STACK_OF(X509) *x509CertChain, HcfValPolicyType policy, CfBlob *sslHostname)
1429 {
1430     CfResult res = CF_SUCCESS;
1431     switch (policy) {
1432         case VALIDATION_POLICY_TYPE_SSL:
1433             if (sslHostname == NULL) {
1434                 LOGE("The specified policy is SSL, but sslHostname is null!");
1435                 return CF_INVALID_PARAMS;
1436             }
1437             if (!X509_check_host(
1438                     sk_X509_value(x509CertChain, 0), (const char *)(sslHostname->data), sslHostname->size, 0, NULL)) {
1439                 LOGE("Validate SSL policy failed!");
1440                 return CF_ERR_CRYPTO_OPERATION;
1441             }
1442             break;
1443         case VALIDATION_POLICY_TYPE_X509:
1444             res = CF_SUCCESS;
1445             break;
1446         default:
1447             LOGE("Unknown policy type!");
1448             res = CF_INVALID_PARAMS;
1449             break;
1450     }
1451     return res;
1452 }
1453 
ValidateUseage(const STACK_OF (X509)* x509CertChain,HcfKuArray * keyUsage)1454 static CfResult ValidateUseage(const STACK_OF(X509) *x509CertChain, HcfKuArray *keyUsage)
1455 {
1456     CfResult res = CF_SUCCESS;
1457     if (keyUsage != NULL) {
1458         X509 *cert = sk_X509_value(x509CertChain, 0);
1459         if (cert == NULL) {
1460             return CF_INVALID_PARAMS;
1461         }
1462         uint32_t count = 0;
1463         for (size_t i = 0; i < keyUsage->count; i++) {
1464             HcfKeyUsageType kuType = keyUsage->data[i];
1465             uint32_t usageFlag = 0;
1466             switch (kuType) {
1467                 case KEYUSAGE_DIGITAL_SIGNATURE:
1468                     usageFlag = X509v3_KU_DIGITAL_SIGNATURE;
1469                     break;
1470                 case KEYUSAGE_NON_REPUDIATION:
1471                     usageFlag = X509v3_KU_NON_REPUDIATION;
1472                     break;
1473                 case KEYUSAGE_KEY_ENCIPHERMENT:
1474                     usageFlag = X509v3_KU_KEY_ENCIPHERMENT;
1475                     break;
1476                 case KEYUSAGE_DATA_ENCIPHERMENT:
1477                     usageFlag = X509v3_KU_DATA_ENCIPHERMENT;
1478                     break;
1479                 case KEYUSAGE_KEY_AGREEMENT:
1480                     usageFlag = X509v3_KU_KEY_AGREEMENT;
1481                     break;
1482                 case KEYUSAGE_KEY_CERT_SIGN:
1483                     usageFlag = X509v3_KU_KEY_CERT_SIGN;
1484                     break;
1485                 case KEYUSAGE_CRL_SIGN:
1486                     usageFlag = X509v3_KU_CRL_SIGN;
1487                     break;
1488                 case KEYUSAGE_ENCIPHER_ONLY:
1489                     usageFlag = X509v3_KU_ENCIPHER_ONLY;
1490                     break;
1491                 case KEYUSAGE_DECIPHER_ONLY:
1492                     usageFlag = X509v3_KU_DECIPHER_ONLY;
1493                     break;
1494                 default:
1495                     return CF_INVALID_PARAMS;
1496             }
1497             if ((X509_get_key_usage(cert) & usageFlag)) {
1498                 count++;
1499             }
1500         }
1501         res = (count == keyUsage->count) ? CF_SUCCESS : CF_ERR_CRYPTO_OPERATION;
1502     }
1503     return res;
1504 }
1505 
ValidateStrategies(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain)1506 static CfResult ValidateStrategies(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain)
1507 {
1508     CfResult res = ValidateDate(x509CertChain, params->date);
1509     if (res != CF_SUCCESS) {
1510         LOGE("Validate date failed.");
1511         return res;
1512     }
1513     res = ValidatePolicy(x509CertChain, params->policy, params->sslHostname);
1514     if (res != CF_SUCCESS) {
1515         LOGE("Validate policy failed.");
1516         return res;
1517     }
1518     res = ValidateUseage(x509CertChain, params->keyUsage);
1519     if (res != CF_SUCCESS) {
1520         LOGE("Validate usage failed.");
1521         return res;
1522     }
1523     return res;
1524 }
1525 
ValidateOther(const HcfX509CertChainValidateParams * params,STACK_OF (X509)* x509CertChain,HcfX509TrustAnchor ** trustAnchorResult)1526 static CfResult ValidateOther(const HcfX509CertChainValidateParams *params, STACK_OF(X509) *x509CertChain,
1527     HcfX509TrustAnchor **trustAnchorResult)
1528 {
1529     if (sk_X509_num(x509CertChain) < 1) {
1530         LOGE("No cert in the certchain!");
1531         return CF_INVALID_PARAMS;
1532     }
1533     X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
1534     if (rootCert == NULL) {
1535         LOGE("Sk X509 value failed!");
1536         CfPrintOpensslError();
1537         return CF_ERR_CRYPTO_OPERATION;
1538     }
1539 
1540     CfResult res = ValidateTrustAnchor(params->trustAnchors, rootCert, x509CertChain, trustAnchorResult);
1541     if (res != CF_SUCCESS) {
1542         LOGE("ValidateTrustAnchor failed!");
1543         return res;
1544     }
1545     res = ValidateRevocation(x509CertChain, *trustAnchorResult, params);
1546     if (res != CF_SUCCESS) {
1547         return res;
1548     }
1549     return res;
1550 }
1551 
Validate(HcfX509CertChainSpi * self,const HcfX509CertChainValidateParams * params,HcfX509CertChainValidateResult * result)1552 static CfResult Validate(
1553     HcfX509CertChainSpi *self, const HcfX509CertChainValidateParams *params, HcfX509CertChainValidateResult *result)
1554 {
1555     if ((self == NULL) || (params == NULL) || (params->trustAnchors == NULL) || (params->trustAnchors->data == NULL) ||
1556         (params->trustAnchors->count == 0) || (result == NULL)) {
1557         LOGE("The input data is null!");
1558         return CF_INVALID_PARAMS;
1559     }
1560     if (!CfIsClassMatch((CfObjectBase *)self, GetX509CertChainClass())) {
1561         LOGE("Input wrong class type!");
1562         return CF_INVALID_PARAMS;
1563     }
1564     if (!((HcfX509CertChainOpensslImpl *)self)->isOrder) {
1565         LOGE("MisOrder certs chain, verify failed!");
1566         return CF_INVALID_PARAMS;
1567     }
1568 
1569     STACK_OF(X509) *x509CertChain = ((HcfX509CertChainOpensslImpl *)self)->x509CertChain;
1570     /* when check time with X509_STORE_CTX_set_time, the noAfter of cert is exclusive, but in RFC5280, it is inclusive,
1571      * so check manually here.
1572      */
1573     CfResult res = ValidateStrategies(params, x509CertChain);
1574     if (res != CF_SUCCESS) {
1575         LOGE("Validate part1 failed!");
1576         return res;
1577     }
1578 
1579     HcfX509TrustAnchor *trustAnchorResult = NULL;
1580     res = ValidateOther(params, x509CertChain, &trustAnchorResult);
1581     if (res != CF_SUCCESS) {
1582         LOGE("Validate part2 failed!");
1583         return res;
1584     }
1585     X509 *entityCert = sk_X509_value(x509CertChain, 0);
1586     if (entityCert == NULL) {
1587         CfPrintOpensslError();
1588         return CF_ERR_CRYPTO_OPERATION;
1589     }
1590 
1591     return FillValidateResult(trustAnchorResult, entityCert, result);
1592 }
1593 
CreateX509CertChainPEM(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1594 static int32_t CreateX509CertChainPEM(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1595 {
1596     STACK_OF(X509) *certsChain = NULL;
1597     X509 *cert = NULL;
1598 
1599     BIO *bio = BIO_new_mem_buf(inData->data, inData->len);
1600     if (bio == NULL) {
1601         LOGE("BIO new mem buf failed!");
1602         CfPrintOpensslError();
1603         return CF_ERR_CRYPTO_OPERATION;
1604     }
1605 
1606     /* Create cert chain object */
1607     certsChain = sk_X509_new_null();
1608     if (certsChain == NULL) {
1609         BIO_free(bio);
1610         LOGE("Error creating certificate chain.");
1611         CfPrintOpensslError();
1612         return CF_ERR_CRYPTO_OPERATION;
1613     }
1614 
1615     /* Add cert to cert chain object */
1616     while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) && cert != NULL) {
1617         if (sk_X509_push(certsChain, cert) <= 0) {
1618             LOGE("Memory allocation failure!");
1619             X509_free(cert);
1620             BIO_free(bio);
1621             sk_X509_pop_free(certsChain, X509_free);
1622             return CF_ERR_CRYPTO_OPERATION;
1623         }
1624         LOGI("push cert to certsChain.");
1625     }
1626 
1627     if (sk_X509_num(certsChain) == 0) {
1628         LOGE("cert chain size = 0.");
1629         CfPrintOpensslError();
1630         BIO_free(bio);
1631         sk_X509_free(certsChain);
1632         return CF_ERR_CRYPTO_OPERATION;
1633     }
1634 
1635     *certchainObj = certsChain;
1636     BIO_free(bio);
1637     return CF_SUCCESS;
1638 }
1639 
1640 /*
1641  * create x509 certchain from DER format streams
1642  * input params: inData
1643  * output params: certchainObj
1644  */
CreateX509CertChainDER(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1645 static int32_t CreateX509CertChainDER(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1646 {
1647     STACK_OF(X509) *certsChain = NULL;
1648     X509 *cert = NULL;
1649     const unsigned char *p = inData->data; // DER data
1650     size_t length = inData->len;
1651 
1652     certsChain = sk_X509_new_null();
1653     if (certsChain == NULL) {
1654         LOGE("Error creating certificate chain.");
1655         return CF_ERR_MALLOC;
1656     }
1657 
1658     while (p < inData->data + length) {
1659         size_t lengthLeft = (inData->data + length - p);
1660         cert = d2i_X509(NULL, &p, lengthLeft);
1661         if (cert == NULL) {
1662             LOGE("Failed to parse certificate.");
1663             CfPrintOpensslError();
1664             sk_X509_pop_free(certsChain, X509_free);
1665             return CF_ERR_CRYPTO_OPERATION;
1666         }
1667         if (sk_X509_push(certsChain, cert) <= 0) {
1668             LOGE("Memory allocation failure!");
1669             X509_free(cert);
1670             sk_X509_pop_free(certsChain, X509_free);
1671             return CF_ERR_MALLOC;
1672         }
1673         LOGI("push cert to certsChain.");
1674     }
1675 
1676     if (sk_X509_num(certsChain) == 0) {
1677         sk_X509_free(certsChain);
1678         LOGE("sk_X509_num failed.");
1679         return CF_INVALID_PARAMS;
1680     }
1681     *certchainObj = certsChain;
1682     return CF_SUCCESS;
1683 }
1684 
1685 /*
1686  * create x509 certchain from pkcs#7 streams
1687  * input params: inData
1688  * output params: certchainObj
1689  */
CreateX509CertChainPKCS7(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1690 static CfResult CreateX509CertChainPKCS7(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1691 {
1692     size_t dataLength = inData->len;
1693     uint8_t *data = inData->data;
1694     BIO *bio = BIO_new_mem_buf(data, dataLength);
1695     if (bio == NULL) {
1696         LOGE("malloc failed");
1697         CfPrintOpensslError();
1698         return CF_ERR_MALLOC;
1699     }
1700 
1701     PKCS7 *pkcs7 = d2i_PKCS7_bio(bio, NULL); // DER format .p7b file
1702     if (pkcs7 == NULL) {
1703         LOGE("Failed to parse PKCS7 data.");
1704         BIO_free(bio);
1705         CfPrintOpensslError();
1706         return CF_ERR_CRYPTO_OPERATION;
1707     }
1708 
1709     /* Get cert chain from pkcs7 object */
1710     STACK_OF(X509) *oriCertsChain = NULL;
1711     int i = OBJ_obj2nid(pkcs7->type);
1712     if (i == NID_pkcs7_signed && pkcs7->d.sign != NULL) {
1713         oriCertsChain = pkcs7->d.sign->cert;
1714     } else if (i == NID_pkcs7_signedAndEnveloped && pkcs7->d.signed_and_enveloped != NULL) {
1715         oriCertsChain = pkcs7->d.signed_and_enveloped->cert;
1716     }
1717 
1718     if (oriCertsChain == NULL || sk_X509_num(oriCertsChain) == 0) {
1719         LOGE("Failed to get certchain object.");
1720         PKCS7_free(pkcs7);
1721         BIO_free(bio);
1722         return CF_ERR_CRYPTO_OPERATION;
1723     }
1724 
1725     /* Clone a cert chain object for free pkcs7 object */
1726     STACK_OF(X509) *certsChain = sk_X509_deep_copy(oriCertsChain, X509_dup, X509_free);
1727     if (certsChain == NULL) {
1728         PKCS7_free(pkcs7);
1729         BIO_free(bio);
1730         LOGE("deep clone cert chain failed.");
1731         CfPrintOpensslError();
1732         return CF_ERR_CRYPTO_OPERATION;
1733     }
1734     *certchainObj = certsChain;
1735     PKCS7_free(pkcs7);
1736     BIO_free(bio);
1737     return CF_SUCCESS;
1738 }
1739 
CreateX509CertChainInner(const CfEncodingBlob * inData,STACK_OF (X509)** certchainObj)1740 static int32_t CreateX509CertChainInner(const CfEncodingBlob *inData, STACK_OF(X509) **certchainObj)
1741 {
1742     int32_t ret = CF_SUCCESS;
1743     if (inData->encodingFormat == CF_FORMAT_PKCS7) {
1744         ret = CreateX509CertChainPKCS7(inData, certchainObj);
1745     } else if (inData->encodingFormat == CF_FORMAT_DER) {
1746         // create certchain from CF_FORMAT_DER
1747         ret = CreateX509CertChainDER(inData, certchainObj);
1748     } else if (inData->encodingFormat == CF_FORMAT_PEM) {
1749         // create certchain from CF_FORMAT_PEM
1750         ret = CreateX509CertChainPEM(inData, certchainObj);
1751     } else {
1752         LOGE("invalid input params");
1753         return CF_INVALID_PARAMS;
1754     }
1755 
1756     if (ret != CF_SUCCESS) {
1757         LOGE("error happened");
1758         return ret;
1759     }
1760 
1761     int num = sk_X509_num(*certchainObj);
1762     if (num > MAX_CERT_NUM || num == 0) {
1763         LOGE("certchain certs number :%d  invalid. create certChain failed! ", num);
1764         sk_X509_pop_free(*certchainObj, X509_free);
1765         *certchainObj = NULL;
1766         return CF_INVALID_PARAMS;
1767     }
1768 
1769     return CF_SUCCESS;
1770 }
1771 
HcfX509CertChainByEncSpiCreate(const CfEncodingBlob * inStream,HcfX509CertChainSpi ** spi)1772 CfResult HcfX509CertChainByEncSpiCreate(const CfEncodingBlob *inStream, HcfX509CertChainSpi **spi)
1773 {
1774     int32_t ret = CF_SUCCESS;
1775     if (inStream == NULL || inStream->data == NULL || inStream->len == 0 || spi == NULL) {
1776         LOGE("HcfX509CertChainByEncSpiCreate(), Invalid params!");
1777         return CF_INVALID_PARAMS;
1778     }
1779     HcfX509CertChainOpensslImpl *certChain =
1780         (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1781     if (certChain == NULL) {
1782         LOGE("Failed to allocate certChain spi object memory!");
1783         return CF_ERR_MALLOC;
1784     }
1785 
1786     ret = CreateX509CertChainInner(inStream, &(certChain->x509CertChain));
1787     if (ret != CF_SUCCESS || certChain->x509CertChain == NULL) {
1788         CfFree(certChain);
1789         LOGE("Failed to create x509 cert chain");
1790         return CF_INVALID_PARAMS;
1791     }
1792     bool isOrder = true;
1793     ret = IsOrderCertChain(certChain->x509CertChain, &isOrder);
1794     if (ret != CF_SUCCESS) {
1795         LOGE("cert chain isOrder failed!");
1796         sk_X509_pop_free(certChain->x509CertChain, X509_free);
1797         CfFree(certChain);
1798         return ret;
1799     }
1800 
1801     certChain->isOrder = isOrder;
1802     certChain->base.base.getClass = GetX509CertChainClass;
1803     certChain->base.base.destroy = DestroyX509CertChain;
1804     certChain->base.engineGetCertList = GetCertlist;
1805     certChain->base.engineValidate = Validate;
1806     certChain->base.engineToString = CfToString;
1807     certChain->base.engineHashCode = CfHashCode;
1808     *spi = (HcfX509CertChainSpi *)certChain;
1809     return CF_SUCCESS;
1810 }
1811 
GetCertsStack(const HcfX509CertificateArray * inCerts,STACK_OF (X509)* certsStack)1812 static CfResult GetCertsStack(const HcfX509CertificateArray *inCerts, STACK_OF(X509) *certsStack)
1813 {
1814     for (uint32_t i = 0; i < inCerts->count; ++i) {
1815         X509 *cert = GetX509FromHcfX509Certificate((HcfCertificate *)inCerts->data[i]);
1816         if (cert == NULL) {
1817             LOGE("GetX509Cert from encodedBlob failed!");
1818             return CF_INVALID_PARAMS;
1819         }
1820 
1821         X509 *certDup = X509_dup(cert);
1822         if (certDup == NULL) {
1823             LOGE("Memory allocation failure!");
1824             return CF_ERR_MALLOC;
1825         }
1826 
1827         if (sk_X509_push(certsStack, certDup) <= 0) {
1828             LOGE("Memory allocation failure!");
1829             X509_free(certDup);
1830             return CF_ERR_MALLOC;
1831         }
1832     }
1833 
1834     return CF_SUCCESS;
1835 }
1836 
HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray * inCerts,HcfX509CertChainSpi ** spi)1837 CfResult HcfX509CertChainByArrSpiCreate(const HcfX509CertificateArray *inCerts, HcfX509CertChainSpi **spi)
1838 {
1839     if (spi == NULL || inCerts == NULL || inCerts->data == NULL || inCerts->count == 0 ||
1840         inCerts->count > MAX_CERT_NUM) {
1841         LOGE("Invalid params, is null!");
1842         return CF_INVALID_PARAMS;
1843     }
1844 
1845     HcfX509CertChainOpensslImpl *certChain =
1846         (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
1847     if (certChain == NULL) {
1848         LOGE("Failed to allocate certChain spi object memory!");
1849         return CF_ERR_MALLOC;
1850     }
1851 
1852     STACK_OF(X509) *certsStack = sk_X509_new_null();
1853     if (certsStack == NULL) {
1854         LOGE("Error creating certificate chain.");
1855         CfFree(certChain);
1856         return CF_ERR_MALLOC;
1857     }
1858 
1859     CfResult res = GetCertsStack(inCerts, certsStack);
1860     if (res != CF_SUCCESS) {
1861         LOGE("Get Certs Stack failed!");
1862         sk_X509_pop_free(certsStack, X509_free);
1863         CfFree(certChain);
1864         return res;
1865     }
1866 
1867     bool isOrder = true;
1868     res = IsOrderCertChain(certsStack, &isOrder);
1869     if (res != CF_SUCCESS) {
1870         LOGE("cert chain isOrder failed!");
1871         sk_X509_pop_free(certsStack, X509_free);
1872         CfFree(certChain);
1873         return res;
1874     }
1875 
1876     certChain->isOrder = isOrder;
1877     certChain->x509CertChain = certsStack;
1878     certChain->base.base.getClass = GetX509CertChainClass;
1879     certChain->base.base.destroy = DestroyX509CertChain;
1880     certChain->base.engineGetCertList = GetCertlist;
1881     certChain->base.engineValidate = Validate;
1882     certChain->base.engineToString = CfToString;
1883     certChain->base.engineHashCode = CfHashCode;
1884     *spi = (HcfX509CertChainSpi *)certChain;
1885 
1886     return CF_SUCCESS;
1887 }
1888 
ValidatCertChainX509(STACK_OF (X509)* x509CertChain,HcfX509CertChainValidateParams params)1889 bool ValidatCertChainX509(STACK_OF(X509) * x509CertChain, HcfX509CertChainValidateParams params)
1890 {
1891     CfResult res = ValidateDate(x509CertChain, params.date);
1892     if (res != CF_SUCCESS) {
1893         return false;
1894     }
1895     X509 *rootCert = sk_X509_value(x509CertChain, sk_X509_num(x509CertChain) - 1);
1896     if (rootCert == NULL) {
1897         return false;
1898     }
1899     HcfX509TrustAnchor *trustAnchorResult = NULL;
1900     if (ValidateTrustAnchor(params.trustAnchors, rootCert, x509CertChain, &trustAnchorResult) != CF_SUCCESS) {
1901         return false;
1902     }
1903     if (ValidateCrlLocal(params.certCRLCollections, x509CertChain) != CF_SUCCESS) {
1904         return false;
1905     }
1906     return true;
1907 }
1908 
PopFreeCerts(STACK_OF (X509)* allCerts,STACK_OF (X509)* leafCerts)1909 static void PopFreeCerts(STACK_OF(X509) *allCerts, STACK_OF(X509) *leafCerts)
1910 {
1911     sk_X509_pop_free(allCerts, X509_free);
1912     sk_X509_pop_free(leafCerts, X509_free);
1913 }
1914 
PackCertChain(const HcfX509CertChainBuildParameters * inParams,STACK_OF (X509)* out)1915 static CfResult PackCertChain(const HcfX509CertChainBuildParameters *inParams, STACK_OF(X509) * out)
1916 {
1917     STACK_OF(X509) *allCerts = sk_X509_new_null();
1918     STACK_OF(X509) *leafCerts = sk_X509_new_null();
1919     if (allCerts == NULL || leafCerts == NULL) {
1920         sk_X509_free(allCerts);
1921         sk_X509_free(leafCerts);
1922         return CF_ERR_CRYPTO_OPERATION;
1923     }
1924     CfResult res = GetLeafCertsFromCertStack(inParams, allCerts, leafCerts);
1925     if (res != CF_SUCCESS) {
1926         PopFreeCerts(allCerts, leafCerts);
1927         return res;
1928     }
1929 
1930     int allCertsLen = sk_X509_num(allCerts);
1931     int leafCertsLen = sk_X509_num(leafCerts);
1932 
1933     for (int i = 0; i < leafCertsLen; i++) {
1934         X509 *leafCert = sk_X509_value(leafCerts, i);
1935         if (CheckIsSelfSigned(leafCert)) {
1936             sk_X509_push(out, X509_dup(leafCert));
1937             if (ValidatCertChainX509(out, inParams->validateParameters)) {
1938                 PopFreeCerts(allCerts, leafCerts);
1939                 return CF_SUCCESS;
1940             }
1941         } else {
1942             sk_X509_push(out, X509_dup(leafCert));
1943             X509_NAME *issuerName = X509_get_issuer_name(leafCert);
1944             X509 *ca = FindCertificateBySubject(allCerts, issuerName);
1945 
1946             int depth = 0;
1947             int maxdepth = inParams->maxlength < 0 ? allCertsLen : inParams->maxlength;
1948             while (ca && (depth < maxdepth)) {
1949                 sk_X509_push(out, X509_dup(ca));
1950                 issuerName = X509_get_issuer_name(ca);
1951                 ca = FindCertificateBySubject(allCerts, issuerName);
1952                 depth++;
1953             }
1954             if (ValidatCertChainX509(out, inParams->validateParameters)) {
1955                 PopFreeCerts(allCerts, leafCerts);
1956                 return CF_SUCCESS;
1957             }
1958         }
1959 
1960         while (sk_X509_num(out) > 0) {
1961             X509_free(sk_X509_pop(out));
1962         }
1963     }
1964     PopFreeCerts(allCerts, leafCerts);
1965     return CF_INVALID_PARAMS;
1966 }
1967 
HcfX509CertChainByParamsSpiCreate(const HcfX509CertChainBuildParameters * inParams,HcfX509CertChainSpi ** spi)1968 CfResult HcfX509CertChainByParamsSpiCreate(const HcfX509CertChainBuildParameters *inParams, HcfX509CertChainSpi **spi)
1969 {
1970     if (inParams == NULL || spi == NULL) {
1971         LOGE("Get certchain from js error, the input is null!");
1972         return CF_INVALID_PARAMS;
1973     }
1974 
1975     STACK_OF(X509) *certStack = sk_X509_new_null();
1976     if (certStack == NULL) {
1977         LOGE("Failed to new certificate stack.");
1978         return CF_ERR_MALLOC;
1979     }
1980 
1981     CfResult res = PackCertChain(inParams, certStack);
1982     if (res != CF_SUCCESS) {
1983         LOGE("Failed to pack certificate chain.");
1984         sk_X509_pop_free(certStack, X509_free);
1985         return res;
1986     }
1987 
1988     if (sk_X509_num(certStack) == 0) {
1989         sk_X509_free(certStack);
1990         LOGE("certs chain count = 0.");
1991         return CF_ERR_CERT_HAS_EXPIRED;
1992     }
1993 
1994     bool isOrder = true;
1995     res = IsOrderCertChain(certStack, &isOrder);
1996     if (res != CF_SUCCESS) {
1997         LOGE("cert chain isOrder failed!");
1998         sk_X509_pop_free(certStack, X509_free);
1999         return res;
2000     }
2001 
2002     HcfX509CertChainOpensslImpl *certChain =
2003         (HcfX509CertChainOpensslImpl *)CfMalloc(sizeof(HcfX509CertChainOpensslImpl), 0);
2004     if (certChain == NULL) {
2005         LOGE("Failed to allocate certChain spi object memory!");
2006         return CF_ERR_MALLOC;
2007     }
2008     certChain->isOrder = isOrder;
2009     certChain->x509CertChain = certStack;
2010     certChain->base.base.getClass = GetX509CertChainClass;
2011     certChain->base.base.destroy = DestroyX509CertChain;
2012     certChain->base.engineGetCertList = GetCertlist;
2013     certChain->base.engineValidate = Validate;
2014     *spi = (HcfX509CertChainSpi *)certChain;
2015 
2016     return res;
2017 }
2018 
ProcessP12Data(STACK_OF (X509)* ca,HcfX509TrustAnchorArray * result)2019 static void ProcessP12Data(STACK_OF(X509) *ca, HcfX509TrustAnchorArray *result)
2020 {
2021     for (int i = 0; i < sk_X509_num(ca); i++) {
2022         X509 *x509 = sk_X509_value(ca, i);
2023         // CACert
2024         if (X509ToHcfX509Certificate(x509, &(result->data[i]->CACert)) != CF_SUCCESS) {
2025             LOGD("Failed to get %d CACert!", i);
2026         }
2027 
2028         // CAPubKey
2029         if (GetPubKeyDataFromX509(x509, &(result->data[i]->CAPubKey)) != CF_SUCCESS) {
2030             LOGD("Failed to get %d CAPubKey!", i);
2031         }
2032 
2033         // CASubject
2034         if (GetSubjectNameFromX509(x509, &(result->data[i]->CASubject)) != CF_SUCCESS) {
2035             LOGD("Failed to get %d CASubject!", i);
2036         }
2037 
2038         // nameConstraints
2039         if (GetNameConstraintsFromX509(x509, &(result->data[i]->nameConstraints)) != CF_SUCCESS) {
2040             LOGD("Failed to get %d nameConstraints!", i);
2041         }
2042     }
2043 }
2044 
FreeHcfX509TrustAnchorArrayInner(HcfX509TrustAnchorArray * trustAnchorArray)2045 static void FreeHcfX509TrustAnchorArrayInner(HcfX509TrustAnchorArray *trustAnchorArray)
2046 {
2047     if (trustAnchorArray == NULL) {
2048         return;
2049     }
2050     if (trustAnchorArray->data != NULL) {
2051         for (uint32_t i = 0; i < trustAnchorArray->count; i++) {
2052             if (trustAnchorArray->data[i] != NULL) {
2053                 CfObjDestroy(trustAnchorArray->data[i]->CACert);
2054                 trustAnchorArray->data[i]->CACert = NULL;
2055                 CfBlobFree(&trustAnchorArray->data[i]->CAPubKey);
2056                 CfBlobFree(&trustAnchorArray->data[i]->CASubject);
2057                 CfBlobFree(&trustAnchorArray->data[i]->nameConstraints);
2058                 CfFree(trustAnchorArray->data[i]);
2059                 trustAnchorArray->data[i] = NULL;
2060             }
2061         }
2062         CfFree(trustAnchorArray->data);
2063     }
2064 }
2065 
STACK_OF(X509)2066 static STACK_OF(X509) *GetCaFromP12(const CfBlob *keyStore, const CfBlob *pwd)
2067 {
2068     X509 *cert = NULL;
2069     EVP_PKEY *pkey = NULL;
2070     STACK_OF(X509) *caStack = NULL;
2071     PKCS12 *p12 = NULL;
2072     const unsigned char *in = (const unsigned char *)(keyStore->data);
2073 
2074     p12 = d2i_PKCS12(NULL, &in, keyStore->size);
2075     if (p12 == NULL) {
2076         LOGE("Error convert pkcs12 data to inner struct!");
2077         CfPrintOpensslError();
2078         return NULL;
2079     }
2080 
2081     int ret = PKCS12_parse(p12, (const char *)pwd->data, &pkey, &cert, &caStack);
2082     PKCS12_free(p12);
2083     if (ret != 1) {
2084         LOGE("PKCS12_parse failed!");
2085         CfPrintOpensslError();
2086         return NULL;
2087     }
2088 
2089     EVP_PKEY_free(pkey);
2090     if (cert == NULL) {
2091         LOGE("P12 dose not have a cert!");
2092         sk_X509_pop_free(caStack, X509_free);
2093         return NULL;
2094     }
2095     X509_free(cert);
2096 
2097     if (caStack == NULL) {
2098         LOGE("P12 dose not have ca!");
2099     }
2100     return caStack;
2101 }
2102 
MallocTrustAnchorArray(int32_t count)2103 static HcfX509TrustAnchorArray *MallocTrustAnchorArray(int32_t count)
2104 {
2105     HcfX509TrustAnchorArray *anchor = (HcfX509TrustAnchorArray *)(CfMalloc(sizeof(HcfX509TrustAnchorArray), 0));
2106     if (anchor == NULL) {
2107         LOGE("Failed to allocate trustAnchorArray memory!");
2108         return NULL;
2109     }
2110 
2111     anchor->count = count;
2112     anchor->data = (HcfX509TrustAnchor **)(CfMalloc(anchor->count * sizeof(HcfX509TrustAnchor *), 0));
2113     if (anchor->data == NULL) {
2114         LOGE("Failed to allocate data memory!");
2115         CfFree(anchor);
2116         return NULL;
2117     }
2118 
2119     for (uint32_t i = 0; i < anchor->count; i++) {
2120         anchor->data[i] = (HcfX509TrustAnchor *)(CfMalloc(sizeof(HcfX509TrustAnchor), 0));
2121         if (anchor->data[i] == NULL) {
2122             LOGE("Failed to allocate data memory!");
2123             FreeHcfX509TrustAnchorArrayInner(anchor);
2124             CfFree(anchor);
2125             return NULL;
2126         }
2127     }
2128     return anchor;
2129 }
2130 
HcfX509CreateTrustAnchorWithKeyStoreFunc(const CfBlob * keyStore,const CfBlob * pwd,HcfX509TrustAnchorArray ** trustAnchorArray)2131 CfResult HcfX509CreateTrustAnchorWithKeyStoreFunc(
2132     const CfBlob *keyStore, const CfBlob *pwd, HcfX509TrustAnchorArray **trustAnchorArray)
2133 {
2134     if (keyStore == NULL || pwd == NULL || trustAnchorArray == NULL) {
2135         LOGE("Invalid params!");
2136         return CF_INVALID_PARAMS;
2137     }
2138 
2139     STACK_OF(X509) *ca = GetCaFromP12(keyStore, pwd);
2140     if (ca == NULL) {
2141         return CF_ERR_CRYPTO_OPERATION;
2142     }
2143 
2144     int32_t count = sk_X509_num(ca);
2145     if (count <= 0) {
2146         LOGE("P12 ca num is 0!");
2147         sk_X509_pop_free(ca, X509_free);
2148         return CF_ERR_CRYPTO_OPERATION;
2149     }
2150 
2151     HcfX509TrustAnchorArray *anchor = MallocTrustAnchorArray(count);
2152     if (anchor == NULL) {
2153         sk_X509_pop_free(ca, X509_free);
2154         return CF_ERR_MALLOC;
2155     }
2156 
2157     ProcessP12Data(ca, anchor);
2158     *trustAnchorArray = anchor;
2159     anchor = NULL;
2160     sk_X509_pop_free(ca, X509_free);
2161     return CF_SUCCESS;
2162 }
2163