| 395 | } |
| 396 | |
| 397 | static int |
| 398 | shadow_cert_generator(TSCont contp, TSEvent /* event ATS_UNUSED */, void * /* edata ATS_UNUSED */) |
| 399 | { |
| 400 | const char *servername = reinterpret_cast<const char *>(TSContDataGet(contp)); |
| 401 | std::string commonName(servername); |
| 402 | |
| 403 | std::queue<void *> localQ; |
| 404 | SSL_CTX *ref_ctx; |
| 405 | scoped_SSL_CTX ctx; |
| 406 | scoped_X509_REQ req; |
| 407 | scoped_X509 cert; |
| 408 | |
| 409 | /// Calculate hash and path, try certs on disk first |
| 410 | unsigned char digest[MD5_DIGEST_LENGTH]; |
| 411 | MD5(reinterpret_cast<unsigned char const *>(commonName.data()), commonName.length(), digest); |
| 412 | char md5String[5]; |
| 413 | snprintf(md5String, sizeof(md5String), "%02hhx%02hhx", digest[0], digest[1]); |
| 414 | std::string path = store_path + "/" + std::string(md5String, 3); |
| 415 | std::string cert_filename = path + '/' + commonName + ".crt"; |
| 416 | |
| 417 | struct stat st; |
| 418 | FILE *fp = nullptr; |
| 419 | /// If directory doesn't exist, create one |
| 420 | if (stat(path.c_str(), &st) == -1) { |
| 421 | mkdir(path.c_str(), 0755); |
| 422 | } else { |
| 423 | /// Try open the file if directory exists |
| 424 | fp = fopen(cert_filename.c_str(), "rt"); |
| 425 | } |
| 426 | Dbg(dbg_ctl, "%s: cert file is expected at %s", __func__, cert_filename.c_str()); |
| 427 | /// If cert file exists and is readable |
| 428 | if (fp != nullptr) { |
| 429 | cert.reset(PEM_read_X509(fp, nullptr, nullptr, nullptr)); |
| 430 | fclose(fp); |
| 431 | |
| 432 | if (cert == nullptr) { |
| 433 | /// Problem with cert file / openssl read |
| 434 | TSError("[%s] %s: failed o load certificate from '%s'", PLUGIN_NAME, __func__, cert_filename.c_str()); |
| 435 | } else { |
| 436 | Dbg(dbg_ctl, "%s: loaded certificate from '%s'", __func__, cert_filename.c_str()); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | /// No valid certs available from disk, create one and write to file |
| 441 | if (cert == nullptr) { |
| 442 | if (!sign_enabled) { |
| 443 | Dbg(dbg_ctl, "%s: no certs found and dynamic generation disabled; marked as wontdo", __func__); |
| 444 | // There won't be certs available. Mark this servername as wontdo |
| 445 | // Pass on as if plugin doesn't exist |
| 446 | ssl_list->setup_data_ctx(commonName, localQ, nullptr, nullptr, true); |
| 447 | while (!localQ.empty()) { |
| 448 | // Dbg(dbg_ctl, "\tClearing the queue size %lu", localQ.size()); |
| 449 | TSVConn ssl_vc = reinterpret_cast<TSVConn>(localQ.front()); |
| 450 | localQ.pop(); |
| 451 | TSVConnReenable(ssl_vc); |
| 452 | } |
| 453 | TSContDestroy(contp); |
| 454 | return TS_SUCCESS; |
nothing calls this directly
no test coverage detected