mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 17:28:49 -10:00
net_socket_ssl_bear: decode PEM bodies by their compacted length
delete_linebreaks() compacts the certificate body in place but never terminated the compacted run, and the caller kept passing the span of the original line-wrapped body to unbase64(). Since unbase64() now insists on an exact 4-aligned length, every wrapped PEM certificate was rejected and the BearSSL trust store ended up empty; before that guard the stale tail bytes decoded as garbage instead. Strip CR as well as LF, NUL-terminate the compacted run, hand unbase64() its strlen(), and skip certificates it refuses rather than pushing a NULL blob into the X.509 decoder. Also stop scanning when a BEGIN marker has no matching END marker so a truncated bundle cannot drive strstr() past the buffer.
This commit is contained in:
1 parent
8766e7e473
commit
3a253df478
1 file changed
+23
-12
@@ -166,24 +166,26 @@ static bool append_cert_x509(void* x509, size_t len)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Compacts a PEM body in place, dropping every CR and LF, and
|
||||
* NUL-terminates the compacted run so strlen() yields the exact
|
||||
* number of base64 characters. The input is not needed by the
|
||||
* caller afterwards, so in-place rewriting is fine. */
|
||||
static char* delete_linebreaks(char* in)
|
||||
{
|
||||
char* iter_in;
|
||||
char* iter_out;
|
||||
while (*in == '\n')
|
||||
while (*in == '\n' || *in == '\r')
|
||||
in++;
|
||||
|
||||
iter_in = in;
|
||||
|
||||
while (*iter_in != '\n' && *iter_in != '\0')
|
||||
iter_in++;
|
||||
iter_out = iter_in;
|
||||
iter_in = in;
|
||||
iter_out = in;
|
||||
while (*iter_in != '\0')
|
||||
{
|
||||
while (*iter_in == '\n')
|
||||
iter_in++;
|
||||
*iter_out++ = *iter_in++;
|
||||
if (*iter_in != '\n' && *iter_in != '\r')
|
||||
*iter_out++ = *iter_in;
|
||||
iter_in++;
|
||||
}
|
||||
*iter_out = '\0';
|
||||
|
||||
return in;
|
||||
}
|
||||
@@ -204,13 +206,22 @@ static void append_certs_pem_x509(char * certs_pem)
|
||||
break;
|
||||
cert += STRLEN_CONST("-----BEGIN CERTIFICATE-----");
|
||||
cert_end = strstr(cert, "-----END CERTIFICATE-----");
|
||||
if (!cert_end)
|
||||
break;
|
||||
|
||||
*cert_end = '\0';
|
||||
cert = delete_linebreaks(cert);
|
||||
|
||||
cert_bin = unbase64(cert, cert_end-cert, &cert_bin_len);
|
||||
append_cert_x509(cert_bin, cert_bin_len);
|
||||
free(cert_bin);
|
||||
/* unbase64() requires an exact, 4-aligned length. The compacted
|
||||
* run is shorter than (cert_end - cert) by the number of line
|
||||
* breaks removed, so measure it rather than reusing the span of
|
||||
* the original wrapped body. */
|
||||
cert_bin = unbase64(cert, (int)strlen(cert), &cert_bin_len);
|
||||
if (cert_bin)
|
||||
{
|
||||
append_cert_x509(cert_bin, cert_bin_len);
|
||||
free(cert_bin);
|
||||
}
|
||||
|
||||
cert_end++; /* skip the NUL we just added */
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user