LLVMFuzzerTestOneInput:
   25|  1.12k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   26|  1.12k|    std::string pem(reinterpret_cast<const char*>(data), size);
   27|  1.12k|    try {
   28|  1.12k|        auto cert = phosphor::certs::parseCert(pem);
   29|  1.12k|        if (cert) {
  ------------------
  |  Branch (29:13): [True: 106, False: 1.01k]
  ------------------
   30|       |            // Validate start date
   31|    106|            phosphor::certs::validateCertificateStartDate(*cert);
   32|       |
   33|       |            // Validate in SSL context
   34|    106|            phosphor::certs::validateCertificateInSSLContext(*cert);
   35|       |
   36|       |            // Validate against an empty store.
   37|       |            // Since validateCertificateAgainstStore allows trust chain errors,
   38|       |            // this should not throw for typical untrusted certs, but will
   39|       |            // exercise the verification logic.
   40|    106|            std::unique_ptr<X509_STORE, decltype(&::X509_STORE_free)> x509Store(
   41|    106|                X509_STORE_new(), &X509_STORE_free);
   42|    106|            if (x509Store) {
  ------------------
  |  Branch (42:17): [True: 30, False: 76]
  ------------------
   43|     30|                phosphor::certs::validateCertificateAgainstStore(*x509Store, *cert);
   44|     30|            }
   45|    106|        }
   46|  1.12k|    } catch (const std::exception& e) {
   47|       |        // Catch expected exceptions to prevent the fuzzer from treating them as crashes.
   48|  1.09k|    } catch (...) {
   49|       |        // Catch any other unexpected exceptions.
   50|      0|    }
   51|  1.12k|    return 0;
   52|  1.12k|}

_ZN3lg27detailsorITpTkNS0_9log_flagsEJNS0_15flag_signed_valENS0_17flag_unsigned_valENS0_8flag_strEETpTkNS0_9log_flagsEJNS0_13flag_floatingEEEEDaNS0_8log_flagIJDpT_EEENS6_IJDpT0_EEE:
   31|  1.11k|{
   32|  1.11k|    return details::log_flag<As..., Bs...>{};
   33|  1.11k|}
_ZN3lg27detailsorITpTkNS0_9log_flagsEJNS0_15flag_signed_valENS0_17flag_unsigned_valEETpTkNS0_9log_flagsEJNS0_8flag_strEEEEDaNS0_8log_flagIJDpT_EEENS5_IJDpT0_EEE:
   31|  1.11k|{
   32|  1.11k|    return details::log_flag<As..., Bs...>{};
   33|  1.11k|}
_ZN3lg27detailsorITpTkNS0_9log_flagsEJNS0_15flag_signed_valEETpTkNS0_9log_flagsEJNS0_17flag_unsigned_valEEEEDaNS0_8log_flagIJDpT_EEENS4_IJDpT0_EEE:
   31|  1.11k|{
   32|  1.11k|    return details::log_flag<As..., Bs...>{};
   33|  1.11k|}
_ZN3lg27detailsorITpTkNS0_9log_flagsEJNS0_8flag_hexEETpTkNS0_9log_flagsEJNS0_8flag_binEEEEDaNS0_8log_flagIJDpT_EEENS4_IJDpT0_EEE:
   31|     65|{
   32|     65|    return details::log_flag<As..., Bs...>{};
   33|     65|}
_ZN3lg27detailsorITpTkNS0_9log_flagsEJNS0_8flag_hexENS0_8flag_binEETpTkNS0_9log_flagsEJNS0_8flag_decEEEEDaNS0_8log_flagIJDpT_EEENS5_IJDpT0_EEE:
   31|     35|{
   32|     35|    return details::log_flag<As..., Bs...>{};
   33|     35|}

_ZN3lg27details6do_logENS_5levelERKNSt3__115source_locationEPKcz:
  248|  1.12k|{
  249|  1.12k|    using namespace std::string_literals;
  250|       |
  251|  1.12k|    std::vector<std::string> strings{static_locs};
  252|       |
  253|  1.12k|    std::string message{m};
  254|       |
  255|       |    // Assign all the static fields.
  256|  1.12k|    strings[pos_fmtmsg] = "LOG2_FMTMSG="s + m;
  257|  1.12k|    strings[pos_prio] = "PRIORITY="s + std::to_string(static_cast<uint64_t>(l));
  258|  1.12k|    strings[pos_file] = "CODE_FILE="s + s.file_name();
  259|  1.12k|    strings[pos_line] = "CODE_LINE="s + std::to_string(s.line());
  260|  1.12k|    strings[pos_func] = "CODE_FUNC="s + s.function_name();
  261|       |
  262|       |    // Handle all the va_list args.
  263|  1.12k|    std::va_list args;
  264|  1.12k|    va_start(args, m);
  265|  2.23k|    while (true)
  ------------------
  |  Branch (265:12): [True: 2.23k, Folded]
  ------------------
  266|  2.23k|    {
  267|       |        // Get the header out.
  268|  2.23k|        auto h_ptr = va_arg(args, const char*);
  269|  2.23k|        if (h_ptr == nullptr)
  ------------------
  |  Branch (269:13): [True: 1.12k, False: 1.11k]
  ------------------
  270|  1.12k|        {
  271|  1.12k|            break;
  272|  1.12k|        }
  273|  1.11k|        std::string h{h_ptr};
  274|       |
  275|       |        // Get the format flag.
  276|  1.11k|        auto f = va_arg(args, uint64_t);
  277|       |
  278|       |        // Handle the value depending on which type format flag it has.
  279|  1.11k|        std::string value = {};
  280|  1.11k|        switch (f & (signed_val | unsigned_val | str | floating).value)
  ------------------
  |  Branch (280:17): [True: 1.11k, False: 0]
  ------------------
  281|  1.11k|        {
  282|     30|            case signed_val.value:
  ------------------
  |  Branch (282:13): [True: 30, False: 1.08k]
  ------------------
  283|     30|            {
  284|     30|                auto v = va_arg(args, int64_t);
  285|     30|                value = value_to_string(f, v);
  286|     30|                break;
  287|      0|            }
  288|       |
  289|     35|            case unsigned_val.value:
  ------------------
  |  Branch (289:13): [True: 35, False: 1.07k]
  ------------------
  290|     35|            {
  291|     35|                auto v = va_arg(args, uint64_t);
  292|     35|                value = value_to_string(f, v);
  293|     35|                break;
  294|      0|            }
  295|       |
  296|  1.04k|            case str.value:
  ------------------
  |  Branch (296:13): [True: 1.04k, False: 65]
  ------------------
  297|  1.04k|            {
  298|  1.04k|                value = va_arg(args, const char*);
  299|  1.04k|                break;
  300|      0|            }
  301|       |
  302|      0|            case floating.value:
  ------------------
  |  Branch (302:13): [True: 0, False: 1.11k]
  ------------------
  303|      0|            {
  304|      0|                auto v = va_arg(args, double);
  305|      0|                value = value_to_string(f, v);
  306|      0|                break;
  307|      0|            }
  308|  1.11k|        }
  309|       |
  310|       |        // Create the field for this value.
  311|  1.11k|        strings.emplace_back(h + '=' + value);
  312|       |
  313|       |        // Check for {HEADER} in the message and replace with value.
  314|  1.11k|        auto h_brace = '{' + h + '}';
  315|  1.11k|        if (auto start = message.find(h_brace); start != std::string::npos)
  ------------------
  |  Branch (315:49): [True: 1.11k, False: 0]
  ------------------
  316|  1.11k|        {
  317|  1.11k|            message.replace(start, h_brace.size(), value);
  318|  1.11k|        }
  319|  1.11k|    }
  320|  1.12k|    va_end(args);
  321|       |
  322|       |    // Add the final message into the strings array.
  323|  1.12k|    strings[pos_msg] = "MESSAGE="s + message.data();
  324|       |
  325|       |    // Transform strings -> iovec.
  326|  1.12k|    std::vector<iovec> iov{};
  327|  1.12k|    std::ranges::transform(strings, std::back_inserter(iov), [](auto& s) {
  328|  1.12k|        return iovec{s.data(), s.length()};
  329|  1.12k|    });
  330|       |
  331|       |    // Output the iovec.
  332|  1.12k|    if (send_debug_to_journal || l != level::debug)
  ------------------
  |  Branch (332:9): [True: 0, False: 1.12k]
  |  Branch (332:34): [True: 1.12k, False: 0]
  ------------------
  333|  1.12k|    {
  334|  1.12k|        sd_journal_sendv(iov.data(), strings.size());
  335|  1.12k|    }
  336|  1.12k|    extra_output_method(l, s, message);
  337|  1.12k|}
lg2_logger.cpp:_ZN3lg27detailsL17noop_extra_outputENS_5levelERKNSt3__115source_locationERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  135|  1.12k|{}
lg2_logger.cpp:_ZN3lg27detailsL15value_to_stringEml:
  106|     30|{
  107|       |    // If hex or bin was requested just use the unsigned formatting
  108|       |    // rules. (What should a negative binary number look like otherwise?)
  109|     30|    if (f & (hex | bin).value)
  ------------------
  |  Branch (109:9): [True: 0, False: 30]
  ------------------
  110|      0|    {
  111|      0|        return value_to_string(f, static_cast<uint64_t>(v));
  112|      0|    }
  113|     30|    return std::to_string(v);
  114|     30|}
lg2_logger.cpp:_ZN3lg27detailsL15value_to_stringEmm:
   23|     35|{
   24|     35|    switch (f & (hex | bin | dec).value)
   25|     35|    {
   26|       |        // For binary, use bitset<>::to_string.
   27|       |        // Treat values without a field-length format flag as 64 bit.
   28|      0|        case bin.value:
  ------------------
  |  Branch (28:9): [True: 0, False: 35]
  ------------------
   29|      0|        {
   30|      0|            switch (f & (field8 | field16 | field32 | field64).value)
   31|      0|            {
   32|      0|                case field8.value:
  ------------------
  |  Branch (32:17): [True: 0, False: 0]
  ------------------
   33|      0|                {
   34|      0|                    return "0b" + std::bitset<8>(v).to_string();
   35|      0|                }
   36|      0|                case field16.value:
  ------------------
  |  Branch (36:17): [True: 0, False: 0]
  ------------------
   37|      0|                {
   38|      0|                    return "0b" + std::bitset<16>(v).to_string();
   39|      0|                }
   40|      0|                case field32.value:
  ------------------
  |  Branch (40:17): [True: 0, False: 0]
  ------------------
   41|      0|                {
   42|      0|                    return "0b" + std::bitset<32>(v).to_string();
   43|      0|                }
   44|      0|                case field64.value:
  ------------------
  |  Branch (44:17): [True: 0, False: 0]
  ------------------
   45|      0|                default:
  ------------------
  |  Branch (45:17): [True: 0, False: 0]
  ------------------
   46|      0|                {
   47|      0|                    return "0b" + std::bitset<64>(v).to_string();
   48|      0|                }
   49|      0|            }
   50|      0|        }
   51|       |
   52|       |        // For hex, use the appropriate sprintf.
   53|      0|        case hex.value:
  ------------------
  |  Branch (53:9): [True: 0, False: 35]
  ------------------
   54|      0|        {
   55|      0|            char value[19];
   56|      0|            const char* format = nullptr;
   57|       |
   58|      0|            switch (f & (field8 | field16 | field32 | field64).value)
   59|      0|            {
   60|      0|                case field8.value:
  ------------------
  |  Branch (60:17): [True: 0, False: 0]
  ------------------
   61|      0|                {
   62|      0|                    format = "0x%02" PRIx64;
   63|      0|                    break;
   64|      0|                }
   65|       |
   66|      0|                case field16.value:
  ------------------
  |  Branch (66:17): [True: 0, False: 0]
  ------------------
   67|      0|                {
   68|      0|                    format = "0x%04" PRIx64;
   69|      0|                    break;
   70|      0|                }
   71|       |
   72|      0|                case field32.value:
  ------------------
  |  Branch (72:17): [True: 0, False: 0]
  ------------------
   73|      0|                {
   74|      0|                    format = "0x%08" PRIx64;
   75|      0|                    break;
   76|      0|                }
   77|       |
   78|      0|                case field64.value:
  ------------------
  |  Branch (78:17): [True: 0, False: 0]
  ------------------
   79|      0|                {
   80|      0|                    format = "0x%016" PRIx64;
   81|      0|                    break;
   82|      0|                }
   83|       |
   84|      0|                default:
  ------------------
  |  Branch (84:17): [True: 0, False: 0]
  ------------------
   85|      0|                {
   86|      0|                    format = "0x%" PRIx64;
   87|      0|                    break;
   88|      0|                }
   89|      0|            }
   90|       |
   91|      0|            snprintf(value, sizeof(value), format, v);
   92|      0|            return value;
   93|      0|        }
   94|       |
   95|       |        // For dec, use the simple to_string.
   96|      0|        case dec.value:
  ------------------
  |  Branch (96:9): [True: 0, False: 35]
  ------------------
   97|     35|        default:
  ------------------
  |  Branch (97:9): [True: 35, False: 0]
  ------------------
   98|     35|        {
   99|     35|            return std::to_string(v);
  100|      0|        }
  101|     35|    }
  102|     35|}
lg2_logger.cpp:_ZZN3lg27details6do_logENS_5levelERKNSt3__115source_locationEPKczENK3$_0clINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEDaRT_:
  327|  7.85k|    std::ranges::transform(strings, std::back_inserter(iov), [](auto& s) {
  328|  7.85k|        return iovec{s.data(), s.length()};
  329|  7.85k|    });

_ZN9sdbusplus6server11transaction7details11TransactionC2Ev:
   25|      1|    Transaction() : time(std::time(nullptr)), thread(std::this_thread::get_id())
   26|      1|    {}

_ZN9sdbusplus6server11transaction6get_idEv:
   18|  1.09k|{
   19|       |    // If the transaction id has not been initialized, generate one.
   20|  1.09k|    if (!details::id)
  ------------------
  |  Branch (20:9): [True: 1, False: 1.09k]
  ------------------
   21|      1|    {
   22|      1|        details::Transaction t;
   23|      1|        details::id = std::hash<details::Transaction>{}(t);
   24|      1|    }
   25|  1.09k|    return details::id;
   26|  1.09k|}
_ZNKSt3__14hashIN9sdbusplus6server11transaction7details11TransactionEEclERKS5_:
   90|      1|{
   91|      1|    auto hash1 = std::hash<std::time_t>{}(t.time);
   92|      1|    auto hash2 = std::hash<std::thread::id>{}(t.thread);
   93|       |
   94|       |    // boost::hash_combine() algorithm.
   95|      1|    return static_cast<size_t>(
   96|      1|        hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2)));
   97|      1|}

_ZN8phosphor5certs28validateCertificateStartDateER7x509_st:
  124|    106|{
  125|    106|    int days = 0;
  126|    106|    int secs = 0;
  127|       |
  128|    106|    ASN1TimePtr epoch(ASN1_TIME_new(), ASN1_STRING_free);
  129|       |    // Set time to 00:00am GMT, Jan 1 1970; format: YYYYMMDDHHMMSSZ
  130|    106|    ASN1_TIME_set_string(epoch.get(), "19700101000000Z");
  131|       |
  132|    106|    ASN1_TIME* notBefore = X509_get_notBefore(&cert);
  133|    106|    ASN1_TIME_diff(&days, &secs, epoch.get(), notBefore);
  134|       |
  135|    106|    if (days < 0 || secs < 0)
  ------------------
  |  Branch (135:9): [True: 18, False: 88]
  |  Branch (135:21): [True: 23, False: 65]
  ------------------
  136|     41|    {
  137|     41|        lg2::error("Certificate valid date starts before the Unix Epoch");
  138|     41|        elog<InvalidCertificate>(
  139|     41|            Reason("NotBefore should after 19700101000000Z"));
  140|     41|    }
  141|    106|}
_ZN8phosphor5certs31validateCertificateAgainstStoreER13x509_store_stR7x509_st:
  144|     30|{
  145|     30|    int errCode = X509_V_OK;
  146|     30|    X509StoreCtxPtr storeCtx(X509_STORE_CTX_new(), ::X509_STORE_CTX_free);
  147|     30|    if (!storeCtx)
  ------------------
  |  Branch (147:9): [True: 0, False: 30]
  ------------------
  148|      0|    {
  149|      0|        lg2::error("Error occurred during X509_STORE_CTX_new call");
  150|      0|        elog<InternalFailure>();
  151|      0|    }
  152|       |
  153|     30|    errCode = X509_STORE_CTX_init(storeCtx.get(), &x509Store, &cert, nullptr);
  154|     30|    if (errCode != 1)
  ------------------
  |  Branch (154:9): [True: 0, False: 30]
  ------------------
  155|      0|    {
  156|      0|        lg2::error("Error occurred during X509_STORE_CTX_init call");
  157|      0|        elog<InternalFailure>();
  158|      0|    }
  159|       |
  160|       |    // Set time to current time.
  161|     30|    auto locTime = time(nullptr);
  162|       |
  163|     30|    X509_STORE_CTX_set_time(storeCtx.get(), X509_V_FLAG_USE_CHECK_TIME,
  164|     30|                            locTime);
  165|       |
  166|     30|    errCode = X509_verify_cert(storeCtx.get());
  167|     30|    if (errCode == 1)
  ------------------
  |  Branch (167:9): [True: 0, False: 30]
  ------------------
  168|      0|    {
  169|      0|        errCode = X509_V_OK;
  170|      0|    }
  171|     30|    else if (errCode == 0)
  ------------------
  |  Branch (171:14): [True: 30, False: 0]
  ------------------
  172|     30|    {
  173|     30|        errCode = X509_STORE_CTX_get_error(storeCtx.get());
  174|     30|        lg2::info(
  175|     30|            "Error occurred during X509_verify_cert call, checking for known "
  176|     30|            "error, ERRCODE:{ERRCODE}, ERROR_STR:{ERROR_STR}",
  177|     30|            "ERRCODE", errCode, "ERROR_STR",
  178|     30|            X509_verify_cert_error_string(errCode));
  179|     30|    }
  180|      0|    else
  181|      0|    {
  182|      0|        lg2::error("Error occurred during X509_verify_cert call");
  183|      0|        elog<InternalFailure>();
  184|      0|    }
  185|       |
  186|       |    // Allow certificate upload, for "certificate is not yet valid" and
  187|       |    // trust chain related errors.
  188|       |    // If ALLOW_EXPIRED is defined, allow expired certificate so that it
  189|       |    // could be replaced
  190|     30|    bool isOK = (errCode == X509_V_OK) ||
  ------------------
  |  Branch (190:17): [True: 0, False: 30]
  ------------------
  191|     30|                (errCode == X509_V_ERR_CERT_NOT_YET_VALID) ||
  ------------------
  |  Branch (191:17): [True: 0, False: 30]
  ------------------
  192|     30|                isTrustChainError(errCode) ||
  ------------------
  |  Branch (192:17): [True: 30, False: 0]
  ------------------
  193|      0|                (allowExpired && errCode == X509_V_ERR_CERT_HAS_EXPIRED);
  ------------------
  |  Branch (193:18): [True: 0, Folded]
  |  Branch (193:34): [True: 0, False: 0]
  ------------------
  194|       |
  195|     30|    if (!isOK)
  ------------------
  |  Branch (195:9): [True: 0, False: 30]
  ------------------
  196|      0|    {
  197|      0|        if (errCode == X509_V_ERR_CERT_HAS_EXPIRED)
  ------------------
  |  Branch (197:13): [True: 0, False: 0]
  ------------------
  198|      0|        {
  199|      0|            lg2::error("Expired certificate ");
  200|      0|            elog<InvalidCertificate>(Reason("Expired Certificate"));
  201|      0|        }
  202|       |        // Logging general error here.
  203|      0|        lg2::error(
  204|      0|            "Certificate validation failed, ERRCODE:{ERRCODE}, ERROR_STR:{ERROR_STR}",
  205|      0|            "ERRCODE", errCode, "ERROR_STR",
  206|      0|            X509_verify_cert_error_string(errCode));
  207|      0|        elog<InvalidCertificate>(Reason("Certificate validation failed"));
  208|      0|    }
  209|     30|}
_ZN8phosphor5certs31validateCertificateInSSLContextER7x509_st:
  212|     65|{
  213|     65|    const SSL_METHOD* method = TLS_method();
  214|     65|    SSLCtxPtr ctx(SSL_CTX_new(method), SSL_CTX_free);
  215|     65|    if (SSL_CTX_use_certificate(ctx.get(), &cert) != 1)
  ------------------
  |  Branch (215:9): [True: 35, False: 30]
  ------------------
  216|     35|    {
  217|     35|        lg2::error("Certificate is not usable, ERRCODE:{ERRCODE}", "ERRCODE",
  218|     35|                   ERR_get_error());
  219|     35|        elog<InvalidCertificate>(Reason("Certificate is not usable"));
  220|     35|    }
  221|     65|}
_ZN8phosphor5certs9parseCertERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  237|  1.12k|{
  238|  1.12k|    if (pem.size() > INT_MAX)
  ------------------
  |  Branch (238:9): [True: 0, False: 1.12k]
  ------------------
  239|      0|    {
  240|      0|        lg2::error("Error occurred during parseCert: PEM is too long");
  241|      0|        elog<InvalidCertificate>(Reason("Invalid PEM: too long"));
  242|      0|    }
  243|  1.12k|    X509Ptr cert(X509_new(), ::X509_free);
  244|  1.12k|    if (!cert)
  ------------------
  |  Branch (244:9): [True: 0, False: 1.12k]
  ------------------
  245|      0|    {
  246|      0|        lg2::error("Error occurred during X509_new call, ERRCODE:{ERRCODE}",
  247|      0|                   "ERRCODE", ERR_get_error());
  248|      0|        elog<InternalFailure>();
  249|      0|    }
  250|       |
  251|  1.12k|    BIOMemPtr bioCert(BIO_new_mem_buf(pem.data(), static_cast<int>(pem.size())),
  252|  1.12k|                      ::BIO_free);
  253|  1.12k|    X509* x509 = cert.get();
  254|  1.12k|    if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr))
  ------------------
  |  Branch (254:9): [True: 1.01k, False: 106]
  ------------------
  255|  1.01k|    {
  256|  1.01k|        lg2::error("Error occurred during PEM_read_bio_X509 call, PEM:{PEM}",
  257|  1.01k|                   "PEM", pem);
  258|  1.01k|        elog<InternalFailure>();
  259|  1.01k|    }
  260|  1.12k|    return cert;
  261|  1.12k|}
x509_utils.cpp:_ZN8phosphor5certs12_GLOBAL__N_117isTrustChainErrorEi:
   47|     30|{
   48|     30|    return error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
  ------------------
  |  Branch (48:12): [True: 2, False: 28]
  ------------------
   49|     28|           error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
  ------------------
  |  Branch (49:12): [True: 0, False: 28]
  ------------------
   50|     28|           error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
  ------------------
  |  Branch (50:12): [True: 28, False: 0]
  ------------------
   51|      0|           error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT ||
  ------------------
  |  Branch (51:12): [True: 0, False: 0]
  ------------------
   52|      0|           error == X509_V_ERR_CERT_UNTRUSTED ||
  ------------------
  |  Branch (52:12): [True: 0, False: 0]
  ------------------
   53|      0|           error == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
  ------------------
  |  Branch (53:12): [True: 0, False: 0]
  ------------------
   54|     30|}

