Skip to content

Commit 1f0a5d5

Browse files
Prevent premature hand off of GET response body
1 parent d8269c7 commit 1f0a5d5

File tree

1 file changed

+49
-4
lines changed

1 file changed

+49
-4
lines changed

osslsigncode.c

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,40 @@ static void check_authenticode_timestamp(BIO **resp)
903903
}
904904
}
905905

906+
/*
907+
* Read all remaining bytes from a BIO into a memory BIO.
908+
* Returns a memory BIO positioned at the start, or NULL on error.
909+
*
910+
* This is used for HTTP GET responses to ensure the full response
911+
* body is available to decoders that expect a seekable BIO.
912+
*/
913+
static BIO *bio_slurp_to_mem(BIO *in)
914+
{
915+
BIO *mem = BIO_new(BIO_s_mem());
916+
char buf[8192];
917+
int n;
918+
919+
if (!mem)
920+
return NULL;
921+
922+
ERR_clear_error();
923+
while ((n = BIO_read(in, buf, sizeof(buf))) > 0) {
924+
if (BIO_write(mem, buf, n) != n) {
925+
BIO_free(mem);
926+
return NULL;
927+
}
928+
}
929+
930+
/* n == 0: clean EOF. n < 0: treat as error unless retry is indicated. */
931+
if (n < 0 && !BIO_should_retry(in)) {
932+
BIO_free(mem);
933+
return NULL;
934+
}
935+
936+
(void)BIO_seek(mem, 0);
937+
return mem;
938+
}
939+
906940
/*
907941
* Get data from HTTP server.
908942
* [in] url: URL of the CRL distribution point or Time-Stamp Authority HTTP server
@@ -996,10 +1030,21 @@ static BIO *bio_get_http(char *url, BIO *req, char *proxy, int rfc3161, char *ca
9961030
SSL_CTX_free(ssl_ctx);
9971031

9981032
if (s_bio) {
999-
resp = socket_bio_read(s_bio, rctx, use_ssl);
1000-
BIO_free_all(s_bio);
1001-
if (resp && req && !rfc3161)
1002-
check_authenticode_timestamp(&resp);
1033+
if (!req) {
1034+
/*
1035+
* GET (CRLs): ensure we have the complete body in a seekable BIO.
1036+
* Some decoders may need to re-read the data, and partial reads
1037+
* can produce truncated DER that fails to parse.
1038+
*/
1039+
resp = bio_slurp_to_mem(s_bio);
1040+
BIO_free_all(s_bio);
1041+
} else {
1042+
/* POST: read response using the request context. */
1043+
resp = socket_bio_read(s_bio, rctx, use_ssl);
1044+
BIO_free_all(s_bio);
1045+
if (resp && !rfc3161)
1046+
check_authenticode_timestamp(&resp);
1047+
}
10031048
} else {
10041049
fprintf(stderr, "\nHTTP failure: Failed to get data from %s\n", url);
10051050
}

0 commit comments

Comments
 (0)