1/* 2 * Copyright (c) 2024-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#include <cassert> 16#include <string> 17#include <unordered_map> 18#include <openssl/x509.h> 19#include <openssl/x509v3.h> 20#include <openssl/conf.h> 21 22#include "cert_tools.h" 23#include "openssl/ec.h" 24#include "openssl/obj_mac.h" 25#include "openssl/asn1.h" 26#include "signature_tools_log.h" 27#include "constant.h" 28 29namespace OHOS { 30namespace SignatureTools { 31 32static std::unordered_map<std::string, long> externDic{ 33 {"digitalSignature", X509v3_KU_DIGITAL_SIGNATURE}, 34 {"nonRepudiation", X509v3_KU_NON_REPUDIATION}, 35 {"keyEncipherment", X509v3_KU_KEY_ENCIPHERMENT}, 36 {"dataEncipherment", X509v3_KU_DATA_ENCIPHERMENT}, 37 {"keyAgreement", X509v3_KU_KEY_AGREEMENT}, 38 {"certificateSignature", X509v3_KU_KEY_CERT_SIGN}, 39 {"crlSignature", X509v3_KU_CRL_SIGN}, 40 {"encipherOnly", X509v3_KU_ENCIPHER_ONLY}, 41 {"decipherOnly", X509v3_KU_DECIPHER_ONLY}, 42 43}; 44 45static std::unordered_map<std::string, std::string> externKey{ 46 {"serverAuthentication", "1.3.6.1.5.5.7.3.1"}, 47 {"clientAuthentication", "1.3.6.1.5.5.7.3.2"}, 48 {"codeSignature", "1.3.6.1.5.5.7.3.3"}, 49 {"emailProtection", "1.3.6.1.5.5.7.3.4"}, 50 {"smartCardLogin", "1.3.6.1.5.5.7.3.5"}, 51 {"timestamp", "1.3.6.1.5.5.7.3.8"}, 52 {"ocspSignature", "1.3.6.1.5.5.7.3.9"}, 53 54}; 55 56bool CertTools::SaveCertTofile(const std::string& filename, X509* cert) 57{ 58 BIO* certBio = BIO_new_file(filename.data(), "w"); 59 if (!certBio) { 60 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 61 SIGNATURE_TOOLS_LOGE("BIO_new failed"); 62 return false; 63 } 64 65 if (PEM_write_bio_X509(certBio, cert) < 0) { 66 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 67 SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509 failed"); 68 BIO_free(certBio); 69 return false; 70 } 71 BIO_free(certBio); 72 return true; 73} 74 75static bool UpdateConstraint(Options* options) 76{ 77 if (options->count(Options::BASIC_CONSTRAINTS)) { 78 if (!CertTools::String2Bool(options, Options::BASIC_CONSTRAINTS)) { 79 return false; 80 } 81 } else { 82 (*options)[Options::BASIC_CONSTRAINTS] = DEFAULT_BASIC_CONSTRAINTS; 83 } 84 85 if (options->count(Options::BASIC_CONSTRAINTS_CRITICAL)) { 86 if (!CertTools::String2Bool(options, Options::BASIC_CONSTRAINTS_CRITICAL)) { 87 return false; 88 } 89 } else { 90 (*options)[Options::BASIC_CONSTRAINTS_CRITICAL] = DEFAULT_BASIC_CONSTRAINTS_CRITICAL; 91 } 92 93 if (options->count(Options::BASIC_CONSTRAINTS_CA)) { 94 if (!CertTools::String2Bool(options, Options::BASIC_CONSTRAINTS_CA)) { 95 return false; 96 } 97 } else { 98 (*options)[Options::BASIC_CONSTRAINTS_CA] = DEFAULT_BASIC_CONSTRAINTS_CA; 99 } 100 return true; 101} 102 103bool CertTools::SetBisicConstraints(Options* options, X509* cert) 104{ 105 if (!UpdateConstraint(options)) { 106 return false; 107 } 108 109 bool basicCon = options->GetBool(Options::BASIC_CONSTRAINTS); 110 if (basicCon) { 111 bool basicConstraintsCritical = options->GetBool(Options::BASIC_CONSTRAINTS_CRITICAL); 112 int critial = basicConstraintsCritical ? 1 : 0; 113 bool basicConstraintsCa = options->GetBool(Options::BASIC_CONSTRAINTS_CA); 114 std::string ContainCa = basicConstraintsCa ? "CA:TRUE" : "CA:FALSE"; 115 std::string constraints = ContainCa + "," + "pathlen:" + 116 std::to_string(options->GetInt(Options::BASIC_CONSTRAINTS_PATH_LEN)); 117 X509V3_CTX ctx; 118 X509V3_set_ctx_nodb(&ctx); 119 120 X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, constraints.c_str()); 121 if (!X509_EXTENSION_set_critical(ext, critial)) { 122 SIGNATURE_TOOLS_LOGE("failed to set critical for extKeyUsage "); 123 X509_EXTENSION_free(ext); 124 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 125 return false; 126 } 127 if (!X509_add_ext(cert, ext, -1)) { 128 SIGNATURE_TOOLS_LOGE("X509_add_ext failed"); 129 X509_EXTENSION_free(ext); 130 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 131 return false; 132 } 133 X509_EXTENSION_free(ext); 134 } 135 136 return true; 137} 138 139bool CertTools::SetBisicConstraintsPathLen(Options* options, X509* cert) 140{ 141 std::string setOptions = "CA:TRUE, pathlen:" + 142 std::to_string(options->GetInt(Options::BASIC_CONSTRAINTS_PATH_LEN)); 143 X509V3_CTX ctx; 144 X509V3_set_ctx_nodb(&ctx); 145 X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, setOptions.c_str()); 146 if (!X509_EXTENSION_set_critical(ext, 1)) { 147 SIGNATURE_TOOLS_LOGE("failed to set critical for extKeyUsage "); 148 X509_EXTENSION_free(ext); 149 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 150 return false; 151 } 152 if (!X509_add_ext(cert, ext, -1)) { 153 SIGNATURE_TOOLS_LOGE("X509_add_ext failed\n"); 154 X509_EXTENSION_free(ext); 155 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 156 return false; 157 } 158 X509_EXTENSION_free(ext); 159 return true; 160} 161 162bool CertTools::SignForSubCert(X509* cert, X509_REQ* subcsr, X509_REQ* rootcsr, EVP_PKEY* caPrikey, Options* options) 163{ 164 bool result = false; 165 std::string signAlg = options->GetString(Options::SIGN_ALG); 166 EVP_PKEY* pubKey = X509_REQ_get_pubkey(subcsr); 167 X509_NAME* issuerName = X509_REQ_get_subject_name(rootcsr); 168 X509_NAME* subjectName = X509_REQ_get_subject_name(subcsr); 169 if (pubKey == NULL) { 170 SIGNATURE_TOOLS_LOGE("X509_REQ_get_pubkey failed"); 171 goto err; 172 } 173 if (caPrikey == nullptr || rootcsr == nullptr || subcsr == nullptr) { 174 SIGNATURE_TOOLS_LOGE("Sign failed because of caPrikey, roocsr or subcsr is nullptr"); 175 goto err; 176 } 177 result = (!X509_set_pubkey(cert, pubKey)); 178 if (result) { 179 SIGNATURE_TOOLS_LOGE("X509_set_pubkey failed"); 180 goto err; 181 } 182 result = (!X509_set_issuer_name(cert, issuerName)); 183 if (result) { 184 SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed"); 185 goto err; 186 } 187 result = (!X509_set_subject_name(cert, subjectName)); 188 if (result) { 189 SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed"); 190 goto err; 191 } 192 result = (!SignCert(cert, caPrikey, signAlg)); 193 if (result) { 194 goto err; 195 } 196 EVP_PKEY_free(pubKey); 197 return true; 198err: 199 EVP_PKEY_free(pubKey); 200 X509_NAME_free(issuerName); 201 X509_NAME_free(subjectName); 202 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 203 return false; 204} 205 206X509* CertTools::SignCsrGenerateCert(X509_REQ* rootcsr, X509_REQ* subcsr, 207 EVP_PKEY* keyPair, Options* options) 208{ 209 bool result = false; 210 X509* cert = X509_new(); 211 int validity = options->GetInt(Options::VALIDITY); 212 result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || 213 !SetCertSerialNum(cert)); 214 if (result) { 215 goto err; 216 } 217 result = SetCertValidity(cert, validity); 218 if (!result) { 219 goto err; 220 } 221 result = (!SetBisicConstraintsPathLen(options, cert) || 222 !SetKeyIdentifierExt(cert) || 223 !SetAuthorizeKeyIdentifierExt(cert)|| 224 !SetKeyUsage(cert, options) || 225 !SignForSubCert(cert, subcsr, rootcsr, keyPair, options)); 226 if (result) { 227 goto err; 228 } 229 return cert; 230err: 231 X509_free(cert); 232 return nullptr; 233} 234 235bool CertTools::SetSubjectForCert(X509_REQ* certReq, X509* cert) 236{ 237 if (certReq == nullptr) { 238 SIGNATURE_TOOLS_LOGE("set subjcet failed because of certReq is nullptr"); 239 goto err; 240 } 241 242 if (X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq)) != 1) { 243 SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed"); 244 goto err; 245 } 246 247 if (X509_set_issuer_name(cert, X509_REQ_get_subject_name(certReq)) != 1) { 248 SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed"); 249 goto err; 250 } 251 return true; 252err: 253 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 254 return false; 255} 256 257X509* CertTools::GenerateRootCertificate(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options) 258{ 259 bool result = false; 260 X509* cert = X509_new(); 261 int validity = options->GetInt(Options::VALIDITY); 262 std::string signAlg = options->GetString(Options::SIGN_ALG); 263 result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || 264 !SetCertSerialNum(cert)); 265 if (result) { 266 goto err; 267 } 268 if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) { 269 goto err; 270 } 271 result = (!SetBisicConstraintsPathLen(options, cert) || 272 !SetSubjectForCert(certReq, cert) || 273 !SetCertPublickKey(cert, certReq) || 274 !SetKeyIdentifierExt(cert) || 275 !SetKeyUsage(cert, options)); 276 if (result) { 277 goto err; 278 } 279 result = (!SignCert(cert, keyPair, signAlg)); 280 if (result) { 281 goto err; 282 } 283 return cert; 284err: 285 X509_free(cert); 286 return nullptr; 287} 288 289X509* CertTools::GenerateSubCert(EVP_PKEY* keyPair, X509_REQ* rootcsr, Options* options) 290{ 291 std::unique_ptr<LocalizationAdapter> adapter = std::make_unique< LocalizationAdapter>(options); 292 EVP_PKEY* subKey = nullptr; 293 X509_REQ* subcsr = nullptr; 294 X509* subCert = nullptr; 295 subKey = adapter->GetAliasKey(false); 296 if (subKey == nullptr) { 297 SIGNATURE_TOOLS_LOGE("failed to get the keypair"); 298 goto err; 299 } 300 subcsr = CertTools::GenerateCsr(subKey, options->GetString(Options::SIGN_ALG), 301 options->GetString(Options::SUBJECT)); 302 if (subcsr == nullptr) { 303 SIGNATURE_TOOLS_LOGE("failed to generate csr"); 304 goto err; 305 } 306 subCert = SignCsrGenerateCert(rootcsr, subcsr, keyPair, options); 307 if (subCert == nullptr) { 308 SIGNATURE_TOOLS_LOGE("failed to generate the subCert"); 309 goto err; 310 } 311 EVP_PKEY_free(subKey); 312 X509_REQ_free(subcsr); 313 return subCert; 314err: 315 EVP_PKEY_free(subKey); 316 X509_REQ_free(subcsr); 317 return nullptr; 318} 319 320bool CertTools::SetKeyUsage(X509* cert, Options* options) 321{ 322 std::string keyUsage = options->GetString(Options::KEY_USAGE); 323 ASN1_INTEGER* keyUsageInt = ASN1_INTEGER_new(); 324 long key = 0; 325 if (keyUsage.empty()) { 326 key = X509v3_KU_KEY_CERT_SIGN | X509v3_KU_CRL_SIGN; 327 if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key)) { 328 SIGNATURE_TOOLS_LOGE("failed to set asn1_integer"); 329 ASN1_INTEGER_free(keyUsageInt); 330 return false; 331 } 332 if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, 0, X509V3_ADD_DEFAULT)) { 333 SIGNATURE_TOOLS_LOGE("failed to add ext"); 334 ASN1_INTEGER_free(keyUsageInt); 335 return false; 336 } 337 } else { 338 bool keyUsageCritical = options->GetBool(Options::KEY_USAGE_CRITICAL); 339 int crit = keyUsageCritical > 0 ? 1 : 0; 340 std::vector<std::string> vecs = StringUtils::SplitString(keyUsage.c_str(), ','); 341 for (auto &vec : vecs) { 342 key |= externDic[vec]; 343 } 344 if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key)) { 345 SIGNATURE_TOOLS_LOGE("failed to set asn1_integer"); 346 ASN1_INTEGER_free(keyUsageInt); 347 return false; 348 } 349 if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, crit, X509V3_ADD_DEFAULT)) { 350 SIGNATURE_TOOLS_LOGE("failed to add ext"); 351 ASN1_INTEGER_free(keyUsageInt); 352 return false; 353 } 354 } 355 ASN1_INTEGER_free(keyUsageInt); 356 return true; 357} 358 359bool CertTools::SetkeyUsageExt(X509* cert, Options* options) 360{ 361 X509_EXTENSION* ext = nullptr; 362 bool keyUsageCritical = options->GetBool(Options::KEY_USAGE_CRITICAL); 363 int crit = keyUsageCritical ? 1 : 0; 364 if (!options->GetString(Options::EXT_KEY_USAGE).empty()) { 365 ext = X509V3_EXT_conf(NULL, NULL, NID_EXT_KEYUSAGE_CONST.c_str(), 366 externKey[options->GetString(Options::EXT_KEY_USAGE)].c_str()); 367 if (!X509_EXTENSION_set_critical(ext, crit)) { 368 SIGNATURE_TOOLS_LOGE("failed to set critical for extKeyUsage "); 369 X509_EXTENSION_free(ext); 370 return false; 371 } 372 if (!X509_add_ext(cert, ext, -1)) { 373 SIGNATURE_TOOLS_LOGE("failed to add extension"); 374 X509_EXTENSION_free(ext); 375 return false; 376 } 377 } 378 X509_EXTENSION_free(ext); 379 return true; 380} 381 382bool CertTools::SetExpandedInformation(X509* cert, Options* options) 383{ 384 bool result = false; 385 result = (!SetKeyUsage(cert, options) || 386 !SetkeyUsageExt(cert, options)); 387 if (result) { 388 SIGNATURE_TOOLS_LOGE("Failed to set expanded information "); 389 return false; 390 } 391 return true; 392} 393 394bool CertTools::SetPubkeyAndSignCert(X509* cert, X509_REQ* issuercsr, 395 X509_REQ* certReq, EVP_PKEY* keyPair, Options* options) 396{ 397 if (!X509_set_issuer_name(cert, X509_REQ_get_subject_name(issuercsr))) { 398 SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed"); 399 goto err; 400 } 401 402 if (!X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq))) { 403 SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed"); 404 goto err; 405 } 406 if ((options->GetString(Options::SIGN_ALG)) == SIGN_ALG_SHA256) { 407 if (!X509_sign(cert, keyPair, EVP_sha256())) { 408 SIGNATURE_TOOLS_LOGE("X509_sign failed"); 409 goto err; 410 } 411 } else { 412 if (!X509_sign(cert, keyPair, EVP_sha384())) { 413 SIGNATURE_TOOLS_LOGE("X509_sign failed"); 414 goto err; 415 } 416 } 417 return true; 418err: 419 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 420 return false; 421} 422 423X509* CertTools::GenerateCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options) 424{ 425 int validity = 0; 426 bool result = false; 427 X509_REQ* issuercsr = CertTools::GenerateCsr(keyPair, options->GetString(Options::SIGN_ALG), 428 options->GetString(Options::ISSUER)); 429 if (issuercsr == nullptr) { 430 SIGNATURE_TOOLS_LOGE("failed to generate the issuercsr"); 431 return nullptr; 432 } 433 434 X509* cert = X509_new(); 435 result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || 436 !SetCertSerialNum(cert) || 437 !SetKeyIdentifierExt(cert)); 438 if (result) { 439 goto err; 440 } 441 validity = options->GetInt(Options::VALIDITY); 442 if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) { 443 goto err; 444 } 445 446 result = (!SetBisicConstraints(options, cert) || 447 !SetCertPublickKey(cert, certReq) || 448 !SetExpandedInformation(cert, options) || 449 !SetPubkeyAndSignCert(cert, issuercsr, certReq, keyPair, options)); 450 if (result) { 451 goto err; 452 } 453 X509_REQ_free(issuercsr); 454 return cert; 455err: 456 X509_free(cert); 457 X509_REQ_free(issuercsr); 458 return nullptr; 459} 460 461X509_REQ* CertTools::GenerateCsr(EVP_PKEY* evpPkey, std::string signAlgorithm, std::string subject) 462{ 463 X509_NAME* name = nullptr; 464 X509_REQ* req = X509_REQ_new(); 465 466 if (!X509_REQ_set_pubkey(req, evpPkey)) { 467 SIGNATURE_TOOLS_LOGE("X509_REQ_set_pubkey failed"); 468 goto err; 469 } 470 471 name = BuildDN(subject, req); 472 if (!name) { 473 SIGNATURE_TOOLS_LOGE("failed to add subject into cert"); 474 goto err; 475 } 476 477 if (signAlgorithm == SIGN_ALG_SHA256) { 478 if (!X509_REQ_sign(req, evpPkey, EVP_sha256())) { 479 SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed"); 480 goto err; 481 } 482 } else if (signAlgorithm == SIGN_ALG_SHA384) { 483 if (!X509_REQ_sign(req, evpPkey, EVP_sha384())) { 484 SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed"); 485 goto err; 486 } 487 } else { 488 PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, 489 "Sign algorithm format error! Please check again."); 490 goto err; 491 } 492 return req; 493err: 494 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 495 X509_REQ_free(req); 496 return nullptr; 497} 498 499std::string CertTools::CsrToString(X509_REQ* csr) 500{ 501 BIO* csrBio = BIO_new(BIO_s_mem()); 502 if (!csrBio) { 503 return ""; 504 } 505 if (!PEM_write_bio_X509_REQ(csrBio, csr)) { 506 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 507 SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509_REQ error"); 508 BIO_free(csrBio); 509 return ""; 510 } 511 BUF_MEM* data = nullptr; 512 BIO_get_mem_ptr(csrBio, &data); 513 if (!data) { 514 BIO_free(csrBio); 515 return ""; 516 } 517 if (!data->data) { 518 BIO_free(csrBio); 519 return ""; 520 } 521 std::string csrStr(data->data, data->length); 522 BIO_free(csrBio); 523 return csrStr; 524} 525 526X509* CertTools::ReadfileToX509(const std::string& filename) 527{ 528 BIO* certBio = BIO_new_file(filename.c_str(), "rb"); 529 if (!certBio) { 530 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 531 SIGNATURE_TOOLS_LOGE("BIO_new_file failed"); 532 BIO_free(certBio); 533 return nullptr; 534 } 535 536 X509* cert = X509_new(); 537 if (!PEM_read_bio_X509(certBio, &cert, NULL, NULL)) { 538 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 539 SIGNATURE_TOOLS_LOGE("PEM_read_bio_X509 failed"); 540 X509_free(cert); 541 BIO_free(certBio); 542 return nullptr; 543 } 544 BIO_free(certBio); 545 546 return cert; 547} 548 549bool CertTools::SetCertVersion(X509* cert, int versionNum) 550{ 551 if (!X509_set_version(cert, versionNum)) { 552 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 553 SIGNATURE_TOOLS_LOGE("set x509 cert version failed"); 554 return false; 555 } 556 return true; 557} 558 559bool CertTools::SetCertSerialNum(X509* cert) 560{ 561 BN_CTX* ctx = BN_CTX_new(); 562 BIGNUM* bignum = BN_new(); 563 uint8_t serialNumberValue[RANDOM_SERIAL_NUMBER_LENGTH] = {0}; 564 if (!SerialNumberBuilder(serialNumberValue, sizeof(serialNumberValue))) { 565 goto err; 566 } 567 if (!BN_bin2bn(serialNumberValue, sizeof(serialNumberValue), bignum)) { 568 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 569 goto err; 570 } 571 if (BN_is_negative(bignum)) { 572 BN_set_negative(bignum, 0); // Replace negative numbers with positive ones 573 } 574 if (!BN_to_ASN1_INTEGER(bignum, X509_get_serialNumber(cert))) { 575 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 576 goto err; 577 } 578 BN_CTX_free(ctx); 579 BN_free(bignum); 580 return true; 581err: 582 SIGNATURE_TOOLS_LOGE("set x509 cert serial number failed"); 583 BN_CTX_free(ctx); 584 BN_free(bignum); 585 return false; 586} 587 588bool CertTools::SetCertIssuerName(X509* cert, X509_NAME* issuer) 589{ 590 if (!X509_set_issuer_name(cert, issuer)) { 591 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 592 SIGNATURE_TOOLS_LOGE("set x509 cert issuer name failed"); 593 return false; 594 } 595 return true; 596} 597 598bool CertTools::SetCertSubjectName(X509* cert, X509_REQ* subjectCsr) 599{ 600 X509_NAME* subject = nullptr; 601 if (!(subject = X509_REQ_get_subject_name(subjectCsr))) { 602 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 603 SIGNATURE_TOOLS_LOGE("get X509 cert subject name failed"); 604 return false; 605 } 606 if (!X509_set_subject_name(cert, subject)) { 607 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 608 SIGNATURE_TOOLS_LOGE("set X509 cert subject name failed"); 609 return false; 610 } 611 return true; 612} 613 614bool CertTools::SetCertValidityStartAndEnd(X509* cert, long vilidityStart, long vilidityEnd) 615{ 616 if (!X509_gmtime_adj(X509_getm_notBefore(cert), vilidityStart)) { 617 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 618 SIGNATURE_TOOLS_LOGE("set cert vilidity start time failed"); 619 return false; 620 } 621 if (!X509_gmtime_adj(X509_getm_notAfter(cert), vilidityEnd)) { 622 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 623 SIGNATURE_TOOLS_LOGE("set cert vilidity end time failed"); 624 return false; 625 } 626 return true; 627} 628 629bool CertTools::SetCertPublickKey(X509* cert, X509_REQ* subjectCsr) 630{ 631 EVP_PKEY* publicKey = X509_REQ_get_pubkey(subjectCsr); 632 if (!publicKey) { 633 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 634 SIGNATURE_TOOLS_LOGE("get the pubkey from csr failed"); 635 return false; 636 } 637 if (!X509_set_pubkey(cert, publicKey)) { 638 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 639 EVP_PKEY_free(publicKey); 640 SIGNATURE_TOOLS_LOGE("set public key to cert failed"); 641 return false; 642 } 643 EVP_PKEY_free(publicKey); 644 return true; 645} 646 647bool CertTools::SetBasicExt(X509* cert) 648{ 649 X509_EXTENSION* basicExtension = X509V3_EXT_conf(NULL, NULL, NID_BASIC_CONST.c_str(), 650 DEFAULT_BASIC_EXTENSION.c_str()); 651 if (!X509_add_ext(cert, basicExtension, -1)) { 652 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 653 SIGNATURE_TOOLS_LOGE("set basicExtension information failed"); 654 X509_EXTENSION_free(basicExtension); 655 return false; 656 } 657 X509_EXTENSION_free(basicExtension); 658 return true; 659} 660 661bool CertTools::SetkeyUsageExt(X509* cert) 662{ 663 X509_EXTENSION* keyUsageExtension = X509V3_EXT_conf(NULL, NULL, NID_KEYUSAGE_CONST.c_str(), 664 DEFAULT_KEYUSAGE_EXTENSION.c_str()); 665 if (!X509_add_ext(cert, keyUsageExtension, -1)) { 666 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 667 SIGNATURE_TOOLS_LOGE("set keyUsageExtension information failed"); 668 X509_EXTENSION_free(keyUsageExtension); 669 return false; 670 } 671 X509_EXTENSION_free(keyUsageExtension); 672 return true; 673} 674 675bool CertTools::SetKeyUsageEndExt(X509* cert) 676{ 677 X509_EXTENSION* keyUsageEndExtension = X509V3_EXT_conf(NULL, NULL, NID_EXT_KEYUSAGE_CONST.c_str(), 678 DEFAULT_EXTEND_KEYUSAGE.c_str()); 679 if (!X509_add_ext(cert, keyUsageEndExtension, -1)) { 680 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 681 SIGNATURE_TOOLS_LOGE("set keyUsageEndExtension information failed"); 682 X509_EXTENSION_free(keyUsageEndExtension); 683 return false; 684 } 685 X509_EXTENSION_free(keyUsageEndExtension); 686 return true; 687} 688 689bool CertTools::SetKeyIdentifierExt(X509* cert) 690{ 691 unsigned char digest[SHA256_DIGEST_LENGTH] = {0}; 692 unsigned int digestLen = 0; 693 if (X509_pubkey_digest(cert, EVP_sha256(), digest, &digestLen) != 1) { 694 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 695 SIGNATURE_TOOLS_LOGE("digest x509 cert public key failed"); 696 return false; 697 } 698 ASN1_OCTET_STRING* pubKeyDigestData = ASN1_OCTET_STRING_new(); 699 if (!ASN1_OCTET_STRING_set(pubKeyDigestData, digest, digestLen)) { 700 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 701 SIGNATURE_TOOLS_LOGE("set ANS1 pubKeyDigestData failed"); 702 ASN1_OCTET_STRING_free(pubKeyDigestData); 703 return false; 704 } 705 706 X509_EXTENSION* subKeyIdentifierExtension = nullptr; 707 /* function OBJ_nid2obj(NID_subject_key_identifier) return value is a global variable, so should not free it */ 708 subKeyIdentifierExtension = X509_EXTENSION_create_by_OBJ(NULL, OBJ_nid2obj(NID_subject_key_identifier), 709 0, pubKeyDigestData); 710 if (!X509_add_ext(cert, subKeyIdentifierExtension, -1)) { 711 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 712 SIGNATURE_TOOLS_LOGE("set subKeyIdentifierExtension information failed"); 713 ASN1_OCTET_STRING_free(pubKeyDigestData); 714 X509_EXTENSION_free(subKeyIdentifierExtension); 715 return false; 716 } 717 ASN1_OCTET_STRING_free(pubKeyDigestData); 718 X509_EXTENSION_free(subKeyIdentifierExtension); 719 return true; 720} 721 722bool CertTools::SetAuthorizeKeyIdentifierExt(X509* cert) 723{ 724 unsigned char key_id[] = { 0x73, 0x3a, 0x81, 0x87, 0x8f, 0x95, 0xc1, 0x94, 725 0xcf, 0xef, 0xab, 0x6f, 0x7f, 0x01, 0x52, 0x86, 726 0xa3, 0xc2, 0x01, 0xc2 }; 727 unsigned int key_id_len = sizeof(key_id); 728 X509_EXTENSION* ext = nullptr; 729 AUTHORITY_KEYID* akid = AUTHORITY_KEYID_new(); 730 akid->keyid = ASN1_OCTET_STRING_new(); 731 if (!ASN1_OCTET_STRING_set(akid->keyid, key_id, key_id_len)) { 732 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 733 SIGNATURE_TOOLS_LOGE("set ANS1 pubKeyDigestData failed"); 734 AUTHORITY_KEYID_free(akid); 735 return false; 736 } 737 ext = X509V3_EXT_i2d(NID_authority_key_identifier, 1, akid); 738 if (!X509_add_ext(cert, ext, -1)) { 739 SIGNATURE_TOOLS_LOGE("Failed to add AKI extension to certificate"); 740 X509_EXTENSION_free(ext); 741 AUTHORITY_KEYID_free(akid); 742 return false; 743 } 744 745 X509_EXTENSION_free(ext); 746 AUTHORITY_KEYID_free(akid); 747 return true; 748} 749 750bool CertTools::SetSignCapacityExt(X509* cert, const char signCapacity[], int capacityLen) 751{ 752 ASN1_OCTET_STRING* certSignCapacityData = ASN1_OCTET_STRING_new(); 753 if (!ASN1_OCTET_STRING_set(certSignCapacityData, (const unsigned char*)signCapacity, capacityLen)) { 754 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 755 SIGNATURE_TOOLS_LOGE("failed to set pubkey digst into ASN1 object"); 756 ASN1_OCTET_STRING_free(certSignCapacityData); 757 return false; 758 } 759 // generate user-define Nid 760 ASN1_OBJECT* nid = OBJ_txt2obj(X509_EXT_OID.c_str(), 1); 761 X509_EXTENSION* certSignCapacityExt = X509_EXTENSION_create_by_OBJ(NULL, nid, 0, certSignCapacityData); 762 763 if (!X509_add_ext(cert, certSignCapacityExt, -1)) { 764 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 765 SIGNATURE_TOOLS_LOGE("set certSignCapacityExt information failed"); 766 ASN1_OBJECT_free(nid); 767 X509_EXTENSION_free(certSignCapacityExt); 768 ASN1_OCTET_STRING_free(certSignCapacityData); 769 return false; 770 } 771 ASN1_OBJECT_free(nid); 772 X509_EXTENSION_free(certSignCapacityExt); 773 ASN1_OCTET_STRING_free(certSignCapacityData); 774 return true; 775} 776 777bool CertTools::SignCert(X509* cert, EVP_PKEY* privateKey, std::string signAlg) 778{ 779 const EVP_MD* alg = nullptr; 780 if (signAlg == SIGN_ALG_SHA256) { 781 /* in openssl this func return value is stack variable, so we not need to release it */ 782 alg = EVP_sha256(); 783 } 784 if (signAlg == SIGN_ALG_SHA384) { 785 alg = EVP_sha384(); 786 } 787 if (!X509_sign(cert, privateKey, alg)) { 788 VerifyHapOpensslUtils::GetOpensslErrorMessage(); 789 SIGNATURE_TOOLS_LOGE("sign X509 cert failed"); 790 return false; 791 } 792 return true; 793} 794 795bool CertTools::SetCertValidity(X509* cert, int validity) 796{ 797 if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) { 798 return false; 799 } 800 return true; 801} 802 803bool CertTools::SerialNumberBuilder(uint8_t* serialNum, int length) 804{ 805 if (RAND_bytes(serialNum, length) != 1) { // this function is thread safity 806 SIGNATURE_TOOLS_LOGE("serial number build failed"); 807 return false; 808 } 809 return true; 810} 811 812X509* CertTools::GenerateEndCert(X509_REQ* csr, EVP_PKEY* issuerKeyPair, 813 LocalizationAdapter& adapter, 814 const char signCapacity[], int capacityLen) 815{ 816 X509* cert = X509_new(); // in this function, should not release X509cert memory 817 X509_REQ* issuerReq = nullptr; 818 bool result = false; 819 issuerReq = X509_REQ_new(); 820 std::string issuerStr = adapter.options->GetString(adapter.options->ISSUER); 821 int validity = adapter.options->GetInt(adapter.options->VALIDITY); 822 std::string signAlg = adapter.options->GetString(adapter.options->SIGN_ALG); 823 824 result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || !SetCertSerialNum(cert)); 825 if (result) { 826 goto err; 827 } 828 result = (!SetCertIssuerName(cert, BuildDN(issuerStr, issuerReq)) || !SetCertSubjectName(cert, csr)); 829 if (result) { 830 goto err; 831 } 832 result = (!SetCertValidity(cert, validity) || !SetCertPublickKey(cert, csr)); 833 if (result) { 834 goto err; 835 } 836 result = (!SetBasicExt(cert) || !SetkeyUsageExt(cert) || !SetKeyUsageEndExt(cert)); 837 if (result) { 838 goto err; 839 } 840 result = (!SetKeyIdentifierExt(cert) || !SetSignCapacityExt(cert, signCapacity, capacityLen)); 841 if (result) { 842 goto err; 843 } 844 if (!SignCert(cert, issuerKeyPair, signAlg)) { 845 goto err; 846 } 847 848 adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {}); 849 return cert; // return x509 assets 850err: 851 adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {cert}); 852 return nullptr; 853} 854 855bool CertTools::String2Bool(Options* options, const std::string& option) 856{ 857 std::string val = options->GetString(option); 858 if (val == "1" || val == "true" || val == "TRUE") { 859 (*options)[option] = true; 860 } else if (val == "0" || val == "false" || val == "FALSE") { 861 (*options)[option] = false; 862 } else { 863 PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, 864 val + "is not valid value for " + "-" + option); 865 return false; 866 } 867 return true; 868} 869} // namespace SignatureTools 870} // namespace OHOS 871 872