Loading src/crypto/tls.cpp +21 −3 Original line number Diff line number Diff line Loading @@ -5033,13 +5033,31 @@ namespace netplus { return true; } // PEM / DER cert file (auto-detected inside loadFromFile / loadAllFromPem) if (ext == ".pem") { // PEM / DER cert file — detect by content, not by extension. A PEM // bundle (leaf + intermediate CAs) is commonly shipped as .crt/.cer // (fullchain.crt, server.cer, ...), not just .pem; dispatching on // extension silently truncated those to the leaf certificate only, // since loadFromFile() (the non-".pem" branch) parses just the // first PEM block and never touches `chain`. Clients that don't // chase the missing intermediate via AIA then reject the handshake // with a fatal certificate_unknown alert. bool looksLikePem = false; { std::ifstream probe(certPath, std::ios::binary); if (probe.is_open()) { char head[11]; probe.read(head, sizeof(head)); looksLikePem = (probe.gcount() == static_cast<std::streamsize>(sizeof(head)) && std::memcmp(head, "-----BEGIN ", sizeof(head)) == 0); } } if (looksLikePem) { // PEM may contain multiple certs (chain) if (!cert.loadAllFromPem(certPath, chain)) return false; } else { // .crt, .cer, .der, or any other extension // DER: a single certificate, no chain possible in this format if (!cert.loadFromFile(certPath)) return false; } Loading Loading
src/crypto/tls.cpp +21 −3 Original line number Diff line number Diff line Loading @@ -5033,13 +5033,31 @@ namespace netplus { return true; } // PEM / DER cert file (auto-detected inside loadFromFile / loadAllFromPem) if (ext == ".pem") { // PEM / DER cert file — detect by content, not by extension. A PEM // bundle (leaf + intermediate CAs) is commonly shipped as .crt/.cer // (fullchain.crt, server.cer, ...), not just .pem; dispatching on // extension silently truncated those to the leaf certificate only, // since loadFromFile() (the non-".pem" branch) parses just the // first PEM block and never touches `chain`. Clients that don't // chase the missing intermediate via AIA then reject the handshake // with a fatal certificate_unknown alert. bool looksLikePem = false; { std::ifstream probe(certPath, std::ios::binary); if (probe.is_open()) { char head[11]; probe.read(head, sizeof(head)); looksLikePem = (probe.gcount() == static_cast<std::streamsize>(sizeof(head)) && std::memcmp(head, "-----BEGIN ", sizeof(head)) == 0); } } if (looksLikePem) { // PEM may contain multiple certs (chain) if (!cert.loadAllFromPem(certPath, chain)) return false; } else { // .crt, .cer, .der, or any other extension // DER: a single certificate, no chain possible in this format if (!cert.loadFromFile(certPath)) return false; } Loading