Loading src/crypto/tls.cpp +53 −4 Original line number Diff line number Diff line Loading @@ -4393,12 +4393,53 @@ namespace netplus { } // ---- CertificateBundle::loadFromFile ---- // Auto-detect format by file extension: // Auto-detect format: // Inline PEM → certPath/keyPath start with "-----BEGIN" // .p12/.pfx → PKCS#12 (certPath only) // everything else → PEM or DER with auto-detection // everything else → PEM or DER file with auto-detection bool tls::CertificateBundle::loadFromFile(const std::string& certPath, const std::string& keyPath, const std::string& password) { // --- Inline PEM data: certPath contains PEM text, not a file path --- if (certPath.size() > 11 && certPath.compare(0, 11, "-----BEGIN ") == 0) { // Parse certificate(s) — first cert is the leaf, rest form the chain const std::string beginMarker = "-----BEGIN CERTIFICATE-----"; const std::string endMarker = "-----END CERTIFICATE-----"; bool first = true; size_t pos = 0; while (pos < certPath.size()) { auto b = certPath.find(beginMarker, pos); if (b == std::string::npos) break; auto e = certPath.find(endMarker, b); if (e == std::string::npos) break; e += endMarker.size(); std::string block = certPath.substr(b, e - b); auto der = cert.pemCertToDer(block); if (der.empty()) { pos = e; continue; } if (first) { if (!cert.loadFromBuffer(std::move(der))) return false; first = false; } else { chain.push_back(std::move(der)); } pos = e; } if (first) return false; // no cert loaded // Key: use keyPath if given, otherwise look for key in certPath const std::string& keySource = keyPath.empty() ? certPath : keyPath; std::vector<uint8_t> keyData(keySource.begin(), keySource.end()); privateKeyDer = keyData; rsa_key = netplus::rsa(keyData); // auto-detects PEM vs DER return true; } // Helper: get lowercase extension auto getExt = [](const std::string& path) -> std::string { auto dot = path.rfind('.'); Loading Loading @@ -4442,7 +4483,15 @@ namespace netplus { // Load private key std::string kp = keyPath.empty() ? certPath : keyPath; std::string kext = getExt(kp); // Key path may also be inline PEM data if (kp.size() > 11 && kp.compare(0, 11, "-----BEGIN ") == 0) { std::vector<uint8_t> keyData(kp.begin(), kp.end()); privateKeyDer = keyData; rsa_key = netplus::rsa(keyData); return true; } std::ifstream keyFile(kp, std::ios::binary | std::ios::ate); if (!keyFile.is_open()) return false; Loading src/crypto/tls.h +4 −2 Original line number Diff line number Diff line Loading @@ -115,9 +115,11 @@ namespace netplus { netplus::rsa rsa_key; // Pre-loaded RSA private key std::vector<std::vector<uint8_t>> chain; // CA chain certs in DER (per-SNI) // Load cert+key from file(s), auto-detecting format by extension: // Load cert+key from file(s) or inline PEM data. // Auto-detects: // Inline PEM → certPath/keyPath contain "-----BEGIN" PEM data // .p12/.pfx → PKCS#12 (certPath only, password required) // .pem/.crt/.cer/.der/.key → PEM or DER (certPath + keyPath) // .pem/.crt/.cer/.der/.key → PEM or DER file (certPath + keyPath) bool loadFromFile(const std::string& certPath, const std::string& keyPath = "", const std::string& password = ""); Loading Loading
src/crypto/tls.cpp +53 −4 Original line number Diff line number Diff line Loading @@ -4393,12 +4393,53 @@ namespace netplus { } // ---- CertificateBundle::loadFromFile ---- // Auto-detect format by file extension: // Auto-detect format: // Inline PEM → certPath/keyPath start with "-----BEGIN" // .p12/.pfx → PKCS#12 (certPath only) // everything else → PEM or DER with auto-detection // everything else → PEM or DER file with auto-detection bool tls::CertificateBundle::loadFromFile(const std::string& certPath, const std::string& keyPath, const std::string& password) { // --- Inline PEM data: certPath contains PEM text, not a file path --- if (certPath.size() > 11 && certPath.compare(0, 11, "-----BEGIN ") == 0) { // Parse certificate(s) — first cert is the leaf, rest form the chain const std::string beginMarker = "-----BEGIN CERTIFICATE-----"; const std::string endMarker = "-----END CERTIFICATE-----"; bool first = true; size_t pos = 0; while (pos < certPath.size()) { auto b = certPath.find(beginMarker, pos); if (b == std::string::npos) break; auto e = certPath.find(endMarker, b); if (e == std::string::npos) break; e += endMarker.size(); std::string block = certPath.substr(b, e - b); auto der = cert.pemCertToDer(block); if (der.empty()) { pos = e; continue; } if (first) { if (!cert.loadFromBuffer(std::move(der))) return false; first = false; } else { chain.push_back(std::move(der)); } pos = e; } if (first) return false; // no cert loaded // Key: use keyPath if given, otherwise look for key in certPath const std::string& keySource = keyPath.empty() ? certPath : keyPath; std::vector<uint8_t> keyData(keySource.begin(), keySource.end()); privateKeyDer = keyData; rsa_key = netplus::rsa(keyData); // auto-detects PEM vs DER return true; } // Helper: get lowercase extension auto getExt = [](const std::string& path) -> std::string { auto dot = path.rfind('.'); Loading Loading @@ -4442,7 +4483,15 @@ namespace netplus { // Load private key std::string kp = keyPath.empty() ? certPath : keyPath; std::string kext = getExt(kp); // Key path may also be inline PEM data if (kp.size() > 11 && kp.compare(0, 11, "-----BEGIN ") == 0) { std::vector<uint8_t> keyData(kp.begin(), kp.end()); privateKeyDer = keyData; rsa_key = netplus::rsa(keyData); return true; } std::ifstream keyFile(kp, std::ios::binary | std::ios::ate); if (!keyFile.is_open()) return false; Loading
src/crypto/tls.h +4 −2 Original line number Diff line number Diff line Loading @@ -115,9 +115,11 @@ namespace netplus { netplus::rsa rsa_key; // Pre-loaded RSA private key std::vector<std::vector<uint8_t>> chain; // CA chain certs in DER (per-SNI) // Load cert+key from file(s), auto-detecting format by extension: // Load cert+key from file(s) or inline PEM data. // Auto-detects: // Inline PEM → certPath/keyPath contain "-----BEGIN" PEM data // .p12/.pfx → PKCS#12 (certPath only, password required) // .pem/.crt/.cer/.der/.key → PEM or DER (certPath + keyPath) // .pem/.crt/.cer/.der/.key → PEM or DER file (certPath + keyPath) bool loadFromFile(const std::string& certPath, const std::string& keyPath = "", const std::string& password = ""); Loading