]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Avoid unbounded allocations in pkcs11_mbedtls.c
authorMax Fillinger <maximilian.fillinger@sentyron.com>
Mon, 2 Mar 2026 14:20:39 +0000 (15:20 +0100)
committerGert Doering <gert@greenie.muc.de>
Mon, 2 Mar 2026 21:49:11 +0000 (22:49 +0100)
The PKCS#11 provider can crash OpenVPN by making it try to allocate
2^64 bytes for a certificate. To avoid this, set a maximum size for
certificates. If the size is exceeded, don't try to allocate memory and
instead exit pkcs11_get_x509_cert with an error.

The chosen maximum size is 100.000 bytes which is twice the size of
a SLH-DSA (aka SPHINCS+) signature.

Found-by: ZeroPath (https://zeropath.com/)
Reported-by: Joshua Rogers <contact@joshua.hu>
Github: closes OpenVPN/openvpn-private-issues#42

Change-Id: I53d47e4a0d33c380ee95e0e33aecad3db3197940
Signed-off-by: Max Fillinger <maximilian.fillinger@sentyron.com>
Acked-by: Arne Schwabe <arne-openvpn@rfc2549.org>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1549
Message-Id: <20260302142045.5954-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg35807.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 0a8e80aaf9c96718903251a828bc3e8055014160)

src/openvpn/pkcs11_mbedtls.c

index 66aefacde75e959303652139146c790181b47bd8..bf9d953098c6bff308ad16ff568eb6ebed9d4bf3 100644 (file)
 static bool
 pkcs11_get_x509_cert(pkcs11h_certificate_t pkcs11_cert, mbedtls_x509_crt *cert)
 {
+    /* We set a maximum size for certificates so that the PKCS provider cannot crash OpenVPN by
+     * making it try to allocate 2^64 bytes. The maximum of 100.000 bytes is picked as a round
+     * number that easily accomodates the currently standardized quantum-safe signature algorithms.
+     * It is twice the size of a SLH-DSA (aka SPHINCS+) signature plus public key.
+     *
+     * However, there are additional digital signature schemes currently on the NIST on-ramp
+     * (e.g., some parameter settings for LESS) that have even larger public keys or signatures, so
+     * if those ever see use on smartcards, we will need to increase this number. */
+    const size_t max_cert_size = 100000;
+
     unsigned char *cert_blob = NULL;
     size_t cert_blob_size = 0;
     bool ret = false;
@@ -52,6 +62,12 @@ pkcs11_get_x509_cert(pkcs11h_certificate_t pkcs11_cert, mbedtls_x509_crt *cert)
         goto cleanup;
     }
 
+    if (cert_blob_size > max_cert_size)
+    {
+        msg(M_WARN, "PKCS#11: Certificate too large: %lu bytes, maximum is %lu", cert_blob_size, max_cert_size);
+        goto cleanup;
+    }
+
     check_malloc_return((cert_blob = calloc(1, cert_blob_size)));
     if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, cert_blob, &cert_blob_size) != CKR_OK)
     {