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