← Commit list

9c0ccd2739

x2018
x2018
2025-11-08
SUCCESS Duration: 143s

Subject

vtls: handle possible malicious certs_num from peer

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/vtls/gtls.c+17 -9
@@ -1618,19 +1618,27 @@ Curl_gtls_verifyserver(struct Curl_cfilter *cf,
}
if(data->set.ssl.certinfo && chain.certs) {
- unsigned int i;
-
- result = Curl_ssl_init_certinfo(data, (int)chain.num_certs);
- if(result)
+ if(chain.num_certs > MAX_ALLOWED_CERT_AMOUNT) {
+ failf(data, "%u certificates is more than allowed (%u)",
+ chain.num_certs, MAX_ALLOWED_CERT_AMOUNT);
+ result = CURLE_SSL_CONNECT_ERROR;
goto out;
+ }
+ else {
+ unsigned int i;
- for(i = 0; i < chain.num_certs; i++) {
- const char *beg = (const char *) chain.certs[i].data;
- const char *end = beg + chain.certs[i].size;
-
- result = Curl_extract_certinfo(data, (int)i, beg, end);
+ result = Curl_ssl_init_certinfo(data, (int)chain.num_certs);
if(result)
goto out;
+
+ for(i = 0; i < chain.num_certs; i++) {
+ const char *beg = (const char *) chain.certs[i].data;
+ const char *end = beg + chain.certs[i].size;
+
+ result = Curl_extract_certinfo(data, (int)i, beg, end);
+ if(result)
+ goto out;
+ }
}
}
lib/vtls/mbedtls.c+11 -2
@@ -475,10 +475,19 @@ mbed_extract_certinfo(struct Curl_easy *data, const mbedtls_x509_crt *crt)
{
CURLcode result;
const mbedtls_x509_crt *cur;
+ int cert_count = 0;
int i;
- for(i = 0, cur = crt; cur; ++i, cur = cur->next);
- result = Curl_ssl_init_certinfo(data, i);
+ for(cur = crt; cur && cert_count <= MAX_ALLOWED_CERT_AMOUNT; cur = cur->next)
+ cert_count++;
+
+ if(cert_count > MAX_ALLOWED_CERT_AMOUNT) {
+ infof(data, "Certificates is more than allowed (%u), skipping certinfo",
+ MAX_ALLOWED_CERT_AMOUNT);
+ return;
+ }
+
+ result = Curl_ssl_init_certinfo(data, cert_count);
for(i = 0, cur = crt; result == CURLE_OK && cur; ++i, cur = cur->next) {
const char *beg = (const char *) cur->raw.p;
lib/vtls/openssl.c+0 -2
@@ -349,8 +349,6 @@ static CURLcode X509V3_ext(struct Curl_easy *data,
return result;
}
-#define MAX_ALLOWED_CERT_AMOUNT 100
-
static CURLcode ossl_certchain(struct Curl_easy *data, SSL *ssl)
{
CURLcode result;
lib/vtls/rustls.c+6 -1
@@ -1211,8 +1211,13 @@ cr_connect(struct Curl_cfilter *cf,
if(data->set.ssl.certinfo) {
size_t num_certs = 0;
size_t i;
- while(rustls_connection_get_peer_certificate(rconn, (int)num_certs)) {
+ while(rustls_connection_get_peer_certificate(rconn, num_certs)) {
num_certs++;
+ if(num_certs > MAX_ALLOWED_CERT_AMOUNT) {
+ failf(data, "%zu certificates is more than allowed (%u)",
+ num_certs, MAX_ALLOWED_CERT_AMOUNT);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
}
result = Curl_ssl_init_certinfo(data, (int)num_certs);
if(result)
lib/vtls/schannel.c+8 -0
@@ -1478,6 +1478,8 @@ cert_counter_callback(const CERT_CONTEXT *ccert_context, bool reverse_order,
(void)reverse_order;
if(valid_cert_encoding(ccert_context))
(*(int *)certs_count)++;
+ if(*(int *)certs_count > MAX_ALLOWED_CERT_AMOUNT)
+ return FALSE;
return TRUE;
}
@@ -1623,6 +1625,12 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
}
traverse_cert_store(ccert_context, cert_counter_callback, &certs_count);
+ if(certs_count > MAX_ALLOWED_CERT_AMOUNT) {
+ failf(data, "%d certificates is more than allowed (%u)",
+ certs_count, MAX_ALLOWED_CERT_AMOUNT);
+ CertFreeCertificateContext(ccert_context);
+ return CURLE_SSL_CONNECT_ERROR;
+ }
result = Curl_ssl_init_certinfo(data, certs_count);
if(!result) {
lib/vtls/vtls.h+1 -0
@@ -165,6 +165,7 @@ void Curl_ssl_version(char *buffer, size_t size);
/* Certificate information list handling. */
#define CURL_X509_STR_MAX 100000
+#define MAX_ALLOWED_CERT_AMOUNT 100
void Curl_ssl_free_certinfo(struct Curl_easy *data);
CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num);
lib/vtls/wolfssl.c+6 -2
@@ -1512,9 +1512,13 @@ wssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
wolfSSL_set_bio(wssl->ssl, bio, bio);
}
#else /* USE_BIO_CHAIN */
+ curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
+ if(sockfd > INT_MAX) {
+ failf(data, "SSL: socket value too large");
+ return CURLE_SSL_CONNECT_ERROR;
+ }
/* pass the raw socket into the SSL layer */
- if(!wolfSSL_set_fd(wssl->ssl,
- (int)Curl_conn_cf_get_socket(cf, data))) {
+ if(!wolfSSL_set_fd(wssl->ssl, (int)sockfd)) {
failf(data, "SSL: wolfSSL_set_fd failed");
return CURLE_SSL_CONNECT_ERROR;
}