mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 07:38:49 -05:00
rand: treat fake entropy the same regardless of endianness
When the random seed is purposely made predictable for testing purposes by using the CURL_ENTROPY environment variable, process that data in an endian agnostic way so the the initial random seed is the same regardless of endianness. - Change Curl_rand to write to a char array instead of int array. - Add Curl_rand_hex to write random hex characters to a buffer. Fixes #1315 Closes #1468 Co-authored-by: Daniel Stenberg Reported-by: Michael Kaufmann
This commit is contained in:
parent
9e9509e46a
commit
1cafede9f2
@ -48,7 +48,7 @@ static char *Curl_basename(char *path);
|
||||
#endif
|
||||
|
||||
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
|
||||
static char *formboundary(struct Curl_easy *data);
|
||||
static CURLcode formboundary(struct Curl_easy *data, char *buffer, size_t len);
|
||||
|
||||
/* What kind of Content-Type to use on un-specified files with unrecognized
|
||||
extensions. */
|
||||
@ -1159,20 +1159,19 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
struct FormData *firstform;
|
||||
struct curl_httppost *file;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
curl_off_t size = 0; /* support potentially ENORMOUS formposts */
|
||||
char *boundary;
|
||||
char *fileboundary = NULL;
|
||||
char fileboundary[42];
|
||||
struct curl_slist *curList;
|
||||
char boundary[42];
|
||||
|
||||
*finalform = NULL; /* default form is empty */
|
||||
|
||||
if(!post)
|
||||
return result; /* no input => no output! */
|
||||
|
||||
boundary = formboundary(data);
|
||||
if(!boundary)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = formboundary(data, boundary, sizeof(boundary));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Make the first line of the output */
|
||||
result = AddFormDataf(&form, NULL,
|
||||
@ -1182,7 +1181,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
boundary);
|
||||
|
||||
if(result) {
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
/* we DO NOT include that line in the total size of the POST, since it'll be
|
||||
@ -1225,10 +1223,8 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
/* If used, this is a link to more file names, we must then do
|
||||
the magic to include several files with the same field name */
|
||||
|
||||
free(fileboundary);
|
||||
fileboundary = formboundary(data);
|
||||
if(!fileboundary) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
result = formboundary(data, fileboundary, sizeof(fileboundary));
|
||||
if(result) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1379,16 +1375,10 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
||||
|
||||
if(result) {
|
||||
Curl_formclean(&firstform);
|
||||
free(fileboundary);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
|
||||
*sizep = size;
|
||||
|
||||
free(fileboundary);
|
||||
free(boundary);
|
||||
|
||||
*finalform = firstform;
|
||||
|
||||
return result;
|
||||
@ -1562,16 +1552,17 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
||||
* formboundary() creates a suitable boundary string and returns an allocated
|
||||
* one.
|
||||
*/
|
||||
static char *formboundary(struct Curl_easy *data)
|
||||
static CURLcode formboundary(struct Curl_easy *data,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
|
||||
combinations */
|
||||
unsigned int rnd[2];
|
||||
CURLcode result = Curl_rand(data, &rnd[0], 2);
|
||||
if(result)
|
||||
return NULL;
|
||||
DEBUGASSERT(buflen >= 41);
|
||||
|
||||
return aprintf("------------------------%08x%08x", rnd[0], rnd[1]);
|
||||
memset(buffer, '-', 24);
|
||||
Curl_rand_hex(data, (unsigned char *)&buffer[24], 17);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#else /* CURL_DISABLE_HTTP */
|
||||
|
61
lib/rand.c
61
lib/rand.c
@ -47,10 +47,12 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
|
||||
char *force_entropy = getenv("CURL_ENTROPY");
|
||||
if(force_entropy) {
|
||||
if(!seeded) {
|
||||
unsigned int seed = 0;
|
||||
size_t elen = strlen(force_entropy);
|
||||
size_t clen = sizeof(randseed);
|
||||
size_t clen = sizeof(seed);
|
||||
size_t min = elen < clen ? elen : clen;
|
||||
memcpy((char *)&randseed, force_entropy, min);
|
||||
memcpy((char *)&seed, force_entropy, min);
|
||||
randseed = ntohl(seed);
|
||||
seeded = TRUE;
|
||||
}
|
||||
else
|
||||
@ -115,18 +117,63 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
|
||||
*
|
||||
*/
|
||||
|
||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rndptr,
|
||||
unsigned int num)
|
||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
|
||||
{
|
||||
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
unsigned int i;
|
||||
|
||||
assert(num > 0);
|
||||
|
||||
for(i = 0; i < num; i++) {
|
||||
result = randit(data, rndptr++);
|
||||
while(num) {
|
||||
unsigned int r;
|
||||
size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int);
|
||||
|
||||
result = randit(data, &r);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
while(left) {
|
||||
*rnd++ = (unsigned char)(r & 0xFF);
|
||||
r >>= 8;
|
||||
--num;
|
||||
--left;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
|
||||
* hexadecimal digits PLUS a zero terminating byte. It must be an odd number
|
||||
* size.
|
||||
*/
|
||||
|
||||
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
|
||||
size_t num)
|
||||
{
|
||||
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
const char *hex = "0123456789abcdef";
|
||||
unsigned char buffer[128];
|
||||
unsigned char *bufp = buffer;
|
||||
DEBUGASSERT(num > 1);
|
||||
|
||||
if((num/2 >= sizeof(buffer)) || !(num&1))
|
||||
/* make sure it fits in the local buffer and that it is an odd number! */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
num--; /* save one for zero termination */
|
||||
|
||||
result = Curl_rand(data, buffer, num/2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
while(num) {
|
||||
*rnd++ = hex[(*bufp & 0xF0)>>4];
|
||||
*rnd++ = hex[*bufp & 0x0F];
|
||||
bufp++;
|
||||
num -= 2;
|
||||
}
|
||||
*rnd = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
12
lib/rand.h
12
lib/rand.h
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,7 +23,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Curl_rand() stores 'num' number of random unsigned integers in the buffer
|
||||
* Curl_rand() stores 'num' number of random unsigned characters in the buffer
|
||||
* 'rnd' points to.
|
||||
*
|
||||
* If libcurl is built without TLS support or with a TLS backend that lacks a
|
||||
@ -37,7 +37,11 @@
|
||||
* easy handle!
|
||||
*
|
||||
*/
|
||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rnd,
|
||||
unsigned int num);
|
||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
|
||||
|
||||
/* Same as above but outputs only random lowercase hex characters.
|
||||
Does NOT terminate.*/
|
||||
CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
|
||||
size_t num);
|
||||
|
||||
#endif /* HEADER_CURL_RAND_H */
|
||||
|
@ -360,7 +360,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
char qop_options[64];
|
||||
int qop_values;
|
||||
char cnonce[33];
|
||||
unsigned int entropy[4];
|
||||
char nonceCount[] = "00000001";
|
||||
char method[] = "AUTHENTICATE";
|
||||
char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
|
||||
@ -387,15 +386,11 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
||||
if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
/* Generate 16 bytes of random data */
|
||||
result = Curl_rand(data, &entropy[0], 4);
|
||||
/* Generate 32 random hex chars, 32 bytes + 1 zero termination */
|
||||
result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce));
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Convert the random data into a 32 byte hex string */
|
||||
snprintf(cnonce, sizeof(cnonce), "%08x%08x%08x%08x",
|
||||
entropy[0], entropy[1], entropy[2], entropy[3]);
|
||||
|
||||
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
|
||||
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
||||
if(!ctxt)
|
||||
@ -684,12 +679,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
||||
digest->nc = 1;
|
||||
|
||||
if(!digest->cnonce) {
|
||||
unsigned int rnd[4];
|
||||
result = Curl_rand(data, &rnd[0], 4);
|
||||
result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
|
||||
sizeof(cnoncebuf));
|
||||
if(result)
|
||||
return result;
|
||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
|
||||
rnd[0], rnd[1], rnd[2], rnd[3]);
|
||||
|
||||
result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
|
||||
&cnonce, &cnonce_sz);
|
||||
|
@ -555,10 +555,10 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
#if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2)
|
||||
if(ntlm->target_info_len) {
|
||||
unsigned char ntbuffer[0x18];
|
||||
unsigned int entropy[2];
|
||||
unsigned char entropy[8];
|
||||
unsigned char ntlmv2hash[0x18];
|
||||
|
||||
result = Curl_rand(data, &entropy[0], 2);
|
||||
result = Curl_rand(data, entropy, 8);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -572,15 +572,13 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
return result;
|
||||
|
||||
/* LMv2 response */
|
||||
result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
|
||||
(unsigned char *)&entropy[0],
|
||||
result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy,
|
||||
&ntlm->nonce[0], lmresp);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* NTLMv2 response */
|
||||
result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
|
||||
(unsigned char *)&entropy[0],
|
||||
result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy,
|
||||
ntlm, &ntlmv2resp, &ntresplen);
|
||||
if(result)
|
||||
return result;
|
||||
@ -596,10 +594,10 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
||||
unsigned char ntbuffer[0x18];
|
||||
unsigned char tmp[0x18];
|
||||
unsigned char md5sum[MD5_DIGEST_LENGTH];
|
||||
unsigned int entropy[2];
|
||||
unsigned char entropy[8];
|
||||
|
||||
/* Need to create 8 bytes random data */
|
||||
result = Curl_rand(data, &entropy[0], 2);
|
||||
result = Curl_rand(data, entropy, 8);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user