Skip certificates that cannot be added to the CryptoAPI store

Also stop the Mbed TLS chain walk at an empty entry, as get_ca_certs()
does, and note that get_peer_certs() results share the session's
lifetime like get_peer_cert()'s.
This commit is contained in:
yhirose committed 2026-10-02 15:55:09 -04:00
1 parent 75cc18b966
commit 39489ee376
1 file changed
+9 -7
+9 -7
View File
@@ -5120,7 +5120,8 @@ bool is_peer_closed(session_t session, socket_t sock);
// Certificate verification // Certificate verification
cert_t get_peer_cert(const_session_t session); cert_t get_peer_cert(const_session_t session);
// The certificates the peer sent, leaf first. Free each with free_cert(). // The certificates the peer sent, leaf first. Free each with free_cert(), and
// do not use them after free_session(), as with get_peer_cert().
size_t get_peer_certs(const_session_t session, std::vector<cert_t> &certs); size_t get_peer_certs(const_session_t session, std::vector<cert_t> &certs);
void free_cert(cert_t cert); void free_cert(cert_t cert);
bool verify_hostname(cert_t cert, const char *hostname); bool verify_hostname(cert_t cert, const char *hostname);
@@ -10733,10 +10734,11 @@ inline bool verify_cert_with_windows_schannel(
}); });
for (auto cert : peer_certs) { for (auto cert : peer_certs) {
std::vector<unsigned char> der; std::vector<unsigned char> der;
tls::get_cert_der(cert, der); if (store && tls::get_cert_der(cert, der)) {
CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, der.data(), CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, der.data(),
static_cast<DWORD>(der.size()), static_cast<DWORD>(der.size()),
CERT_STORE_ADD_USE_EXISTING, nullptr); CERT_STORE_ADD_USE_EXISTING, nullptr);
}
} }
// Setup chain parameters // Setup chain parameters
@@ -20910,8 +20912,8 @@ inline size_t get_peer_certs(const_session_t session,
certs.clear(); certs.clear();
// Mbed TLS parses the whole received chain into a list headed by the peer // Mbed TLS parses the whole received chain into a list headed by the peer
// certificate, owned by the session like get_peer_cert()'s result // certificate, owned by the session like get_peer_cert()'s result
for (auto crt = static_cast<mbedtls_x509_crt *>(get_peer_cert(session)); crt; for (auto crt = static_cast<mbedtls_x509_crt *>(get_peer_cert(session));
crt = crt->next) { crt && crt->raw.len > 0; crt = crt->next) {
certs.push_back(static_cast<cert_t>(crt)); certs.push_back(static_cast<cert_t>(crt));
} }
return certs.size(); return certs.size();