Skip to content

Commit

Permalink
misc: better random strings
Browse files Browse the repository at this point in the history
Generate alphanumerical random strings.

Prior this change curl used to create random hex strings. This was
mostly okay, but having alphanumerical random strings is better: The
strings have more entropy in the same space.

The MIME multipart boundary used to be mere 64-bits of randomness due
to being 16 hex chars. With these changes the boundary is 22
alphanumerical chars, or little over 130 bits of randomness.

Closes curl#11838
  • Loading branch information
Harry Sintonen authored and bagder committed Sep 16, 2023
1 parent f88cc65 commit 3aa3cc9
Show file tree
Hide file tree
Showing 53 changed files with 213 additions and 151 deletions.
2 changes: 1 addition & 1 deletion lib/fopen.c
Expand Up @@ -64,7 +64,7 @@ CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
fclose(*fh);
*fh = NULL;

result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix));
result = Curl_rand_alnum(data, randsuffix, sizeof(randsuffix));
if(result)
goto fail;

Expand Down
6 changes: 3 additions & 3 deletions lib/mime.c
Expand Up @@ -1289,9 +1289,9 @@ curl_mime *curl_mime_init(struct Curl_easy *easy)
mime->lastpart = NULL;

memset(mime->boundary, '-', MIME_BOUNDARY_DASHES);
if(Curl_rand_hex(easy,
(unsigned char *) &mime->boundary[MIME_BOUNDARY_DASHES],
MIME_RAND_BOUNDARY_CHARS + 1)) {
if(Curl_rand_alnum(easy,
(unsigned char *) &mime->boundary[MIME_BOUNDARY_DASHES],
MIME_RAND_BOUNDARY_CHARS + 1)) {
/* failed to get random separator, bail out */
free(mime);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion lib/mime.h
Expand Up @@ -27,7 +27,7 @@
#include "curl_setup.h"

#define MIME_BOUNDARY_DASHES 24 /* leading boundary dashes */
#define MIME_RAND_BOUNDARY_CHARS 16 /* Nb. of random boundary chars. */
#define MIME_RAND_BOUNDARY_CHARS 22 /* Nb. of random boundary chars. */
#define MAX_ENCODED_LINE_LENGTH 76 /* Maximum encoded line length. */
#define ENCODING_BUFFER_SIZE 256 /* Encoding temp buffers size. */

Expand Down
4 changes: 2 additions & 2 deletions lib/mqtt.c
Expand Up @@ -295,8 +295,8 @@ static CURLcode mqtt_connect(struct Curl_easy *data)
/* set initial values for the CONNECT packet */
pos = init_connpack(packet, remain, remain_pos);

result = Curl_rand_hex(data, (unsigned char *)&client_id[clen],
MQTT_CLIENTID_LEN - clen + 1);
result = Curl_rand_alnum(data, (unsigned char *)&client_id[clen],
MQTT_CLIENTID_LEN - clen + 1);
/* add client id */
rc = add_client_id(client_id, strlen(client_id), packet, pos + 1);
if(rc) {
Expand Down
35 changes: 35 additions & 0 deletions lib/rand.c
Expand Up @@ -24,6 +24,8 @@

#include "curl_setup.h"

#include <limits.h>

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
Expand Down Expand Up @@ -267,3 +269,36 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,

return result;
}

/*
* Curl_rand_alnum() fills the 'rnd' buffer with a given 'num' size with random
* alphanumerical chars PLUS a null-terminating byte.
*/

static const char alnum[26 + 26 + 10] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

CURLcode Curl_rand_alnum(struct Curl_easy *data, unsigned char *rnd,
size_t num)
{
CURLcode result = CURLE_OK;
const int alnumspace = sizeof(alnum);
unsigned int r;
DEBUGASSERT(num > 1);

num--; /* save one for null-termination */

while(num) {
do {
result = randit(data, &r);
if(result)
return result;
} while(r >= (UINT_MAX - UINT_MAX % alnumspace));

*rnd++ = alnum[r % alnumspace];
num--;
}
*rnd = 0;

return result;
}
7 changes: 7 additions & 0 deletions lib/rand.h
Expand Up @@ -34,6 +34,13 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
size_t num);

/*
* Curl_rand_alnum() fills the 'rnd' buffer with a given 'num' size with random
* alphanumerical chars PLUS a null-terminating byte.
*/
CURLcode Curl_rand_alnum(struct Curl_easy *data, unsigned char *rnd,
size_t num);

#ifdef WIN32
/* Random generator shared between the Schannel vtls and Curl_rand*()
functions */
Expand Down
4 changes: 2 additions & 2 deletions tests/data/test1053
Expand Up @@ -81,7 +81,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 410
Content-Length: 434
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763

------------------------------9ef8d6205763
Expand All @@ -105,7 +105,7 @@ POST /we/want/data/%TESTNUMBER0002.txt?coolsite=yes HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 410
Content-Length: 434
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763

------------------------------9ef8d6205763
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1133
Expand Up @@ -50,7 +50,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1264
Content-Length: 1324
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32

------------------------------24e78000bd32
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1158
Expand Up @@ -53,7 +53,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 958
Content-Length: 1006
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32

------------------------------24e78000bd32
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1186
Expand Up @@ -53,7 +53,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 954
Content-Length: 1002
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32

------------------------------24e78000bd32
Expand Down
4 changes: 2 additions & 2 deletions tests/data/test1187
Expand Up @@ -38,8 +38,8 @@ smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-fr
# Verify data after the test has been "shot"
<verify>
<strippart>
s/^--------------------------[a-z0-9]*/------------------------------/
s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
s/^--------------------------[A-Za-z0-9]*/------------------------------/
s/boundary=------------------------[A-Za-z0-9]*/boundary=----------------------------/
</strippart>
<protocol>
EHLO %TESTNUMBER
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1189
Expand Up @@ -50,7 +50,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1186
Content-Length: 1240
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32

------------------------------24e78000bd32
Expand Down
6 changes: 3 additions & 3 deletions tests/data/test1293
Expand Up @@ -47,15 +47,15 @@ http://0 http://%HOSTIP:%HTTPPORT/%TESTNUMBER -F=
# Verify data after the test has been "shot"
<verify>
<strippart>
s/^--------------------------[a-z0-9]*/------------------------------/
s/boundary=------------------------[a-z0-9]*/boundary=----------------------------/
s/^--------------------------[A-Za-z0-9]*/------------------------------/
s/boundary=------------------------[A-Za-z0-9]*/boundary=----------------------------/
</strippart>
<protocol>
POST /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 126
Content-Length: 138
Content-Type: multipart/form-data; boundary=----------------------------

------------------------------
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1315
Expand Up @@ -50,7 +50,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 797
Content-Length: 845
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763

------------------------------9ef8d6205763
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1404
Expand Up @@ -54,7 +54,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 882
Content-Length: 930
Content-Type: multipart/form-data; boundary=----------------------------9ef8d6205763

------------------------------9ef8d6205763
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test158
Expand Up @@ -42,7 +42,7 @@ POST /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 145
Content-Length: 157
Content-Type: multipart/form-data; boundary=----------------------------4f12fcdaa3bc

------------------------------4f12fcdaa3bc
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test163
Expand Up @@ -56,7 +56,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 304
Content-Length: 322
Content-Type: multipart/form-data; boundary=----------------------------c2d1767eb6ac

------------------------------c2d1767eb6ac
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test166
Expand Up @@ -48,7 +48,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 223
Content-Length: 235
Content-Type: multipart/form-data; boundary=----------------------------b0b3d6d23991

------------------------------b0b3d6d23991
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test173
Expand Up @@ -56,7 +56,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 360
Content-Length: 378
Content-Type: multipart/form-data; boundary=----------------------------5dbea401cd8c

------------------------------5dbea401cd8c
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test186
Expand Up @@ -46,7 +46,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 320
Content-Length: 338
Content-Type: multipart/form-data; boundary=----------------------------212d9006ceb5

------------------------------212d9006ceb5
Expand Down
6 changes: 3 additions & 3 deletions tests/data/test1972
Expand Up @@ -67,13 +67,13 @@ Host: exam.ple.com:9000
Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=eaee0f1c5984ad5d81c8bc7805f28c7b83b35322de654b2ace18cb8cf6d5a9cb
X-Amz-Date: 19700101T000000Z
x-amz-content-sha256: UNSIGNED-PAYLOAD
Content-Length: 142
Content-Length: 154

--------------------------3433323135333231
--------------------------qrstuvwxyz0123456789AB
Content-Disposition: attachment; name="foo"

bar
--------------------------3433323135333231--
--------------------------qrstuvwxyz0123456789AB--
</protocol>
</verify>
</testcase>
4 changes: 2 additions & 2 deletions tests/data/test2073
Expand Up @@ -52,7 +52,7 @@ POST /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 189
Content-Length: 201

Content-Disposition: form-data; name="name"; filename="a.pdf"
Content-Type: application/pdf
Expand All @@ -62,7 +62,7 @@ POST /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 184
Content-Length: 196

Content-Disposition: form-data; name="name"; filename="b.jpg"
Content-Type: image/jpeg
Expand Down
4 changes: 2 additions & 2 deletions tests/data/test258
Expand Up @@ -86,7 +86,7 @@ Host: remotehost:54321
User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 409
Content-Length: 433
Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

------------------------------7c633d5c27ce
Expand All @@ -112,7 +112,7 @@ Proxy-Authorization: Digest username="uuuser", realm="many secrets", nonce="911"
User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 409
Content-Length: 433
Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

------------------------------7c633d5c27ce
Expand Down
4 changes: 2 additions & 2 deletions tests/data/test259
Expand Up @@ -83,7 +83,7 @@ User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Expect: 100-continue
Content-Length: 409
Content-Length: 433
Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

------------------------------7c633d5c27ce
Expand All @@ -110,7 +110,7 @@ User-Agent: curl/%VERSION
Accept: */*
Proxy-Connection: Keep-Alive
Expect: 100-continue
Content-Length: 409
Content-Length: 433
Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

------------------------------7c633d5c27ce
Expand Down
6 changes: 3 additions & 3 deletions tests/data/test277
Expand Up @@ -37,15 +37,15 @@ http://%HOSTIP:%HTTPPORT/want/%TESTNUMBER -F name=daniel -H "Content-Type: text/
# Verify data after the test has been "shot"
<verify>
<strippart>
s/^--------------------------[a-z0-9]*/--------------------------/
s/boundary=------------------------[a-z0-9]*/boundary=------------------------/
s/^--------------------------[A-Za-z0-9]*/--------------------------/
s/boundary=------------------------[A-Za-z0-9]*/boundary=------------------------/
</strippart>
<protocol>
POST /want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 146
Content-Length: 158
Content-Type: text/info; boundary=------------------------

--------------------------
Expand Down
12 changes: 6 additions & 6 deletions tests/data/test304
Expand Up @@ -49,24 +49,24 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPSPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1386
Content-Type: multipart/form-data; boundary=----------------------------c3b2ef7f0bb8
Content-Length: 1410
Content-Type: multipart/form-data; boundary=----------------------------qrstuvwxyz0123456789AB

------------------------------c3b2ef7f0bb8
------------------------------qrstuvwxyz0123456789AB
Content-Disposition: form-data; name="name"

daniel
------------------------------c3b2ef7f0bb8
------------------------------qrstuvwxyz0123456789AB
Content-Disposition: form-data; name="tool"

curl
------------------------------c3b2ef7f0bb8
------------------------------qrstuvwxyz0123456789AB
Content-Disposition: form-data; name="file"; filename="test%TESTNUMBER.txt"
Content-Type: text/plain

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

------------------------------c3b2ef7f0bb8--
------------------------------qrstuvwxyz0123456789AB--
</protocol>
</verify>
</testcase>
2 changes: 1 addition & 1 deletion tests/data/test39
Expand Up @@ -50,7 +50,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 1180
Content-Length: 1234
Content-Type: multipart/form-data; boundary=----------------------------24e78000bd32

------------------------------24e78000bd32
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test44
Expand Up @@ -50,7 +50,7 @@ POST /we/want/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
Content-Length: 408
Content-Length: 432
Content-Type: multipart/form-data; boundary=----------------------------7c633d5c27ce

------------------------------7c633d5c27ce
Expand Down

0 comments on commit 3aa3cc9

Please sign in to comment.