From 468dad47ec2b283df06fd97e7e22f3c2a7b3afc7 Mon Sep 17 00:00:00 2001 From: Per Allansson Date: Wed, 9 Sep 2026 07:18:09 +0200 Subject: [PATCH] wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio: avoid quadratic PEM marker scanning The PEM reader rescanned previously examined data after each byte read, causing quadratic scanning time for large PEM objects. Track the search position for BEGIN and END markers, retaining enough overlap to detect markers split across reads. Also check the buffer bound before reading the newline after the header. --- src/x509.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/x509.c b/src/x509.c index cf4d0815e6c..f54c089cfdd 100644 --- a/src/x509.c +++ b/src/x509.c @@ -14210,6 +14210,7 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type) const char* headerEnd = NULL; const char* footer = NULL; const char* footerEnd = NULL; + long searchPos = 0; #ifdef HAVE_CRL DerBuffer* der = NULL; #endif @@ -14252,7 +14253,12 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type) while (i < l && wolfSSL_BIO_read(bio, &pem[i], 1) == 1) { i++; if (!header) { - header = XSTRNSTR(pem, "-----BEGIN ", i); + header = XSTRNSTR(pem + searchPos, "-----BEGIN ", + (size_t)(i - searchPos)); + if (header == NULL) { + searchPos = i > (long)(XSTR_SIZEOF("-----BEGIN ") - 1) + ? i - (XSTR_SIZEOF("-----BEGIN ") - 1) : 0; + } } else if (!headerEnd) { headerEnd = XSTRNSTR(header + XSTR_SIZEOF("-----BEGIN "), @@ -14260,8 +14266,8 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type) i - (header + XSTR_SIZEOF("-----BEGIN ") - pem)); if (headerEnd) { headerEnd += XSTR_SIZEOF("-----"); - /* Read in the newline */ - if (wolfSSL_BIO_read(bio, &pem[i], 1) != 1) { + if (i >= l || + wolfSSL_BIO_read(bio, &pem[i], 1) != 1) { WOLFSSL_MSG("wolfSSL_BIO_read error"); goto err; } @@ -14270,11 +14276,16 @@ int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type) WOLFSSL_MSG("Missing newline after header"); goto err; } + searchPos = headerEnd - pem; } } else if (!footer) { - footer = XSTRNSTR(headerEnd, "-----END ", - i - (headerEnd - pem)); + footer = XSTRNSTR(pem + searchPos, "-----END ", + (size_t)(i - searchPos)); + if (footer == NULL) { + if (i > (long)(XSTR_SIZEOF("-----END ") - 1)) + searchPos = i - (XSTR_SIZEOF("-----END ") - 1); + } } else if (!footerEnd) { footerEnd = XSTRNSTR(footer + XSTR_SIZEOF("-----"),