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, >ype);
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