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