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
|
#endif
|
||||||
|
|
||||||
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
|
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
|
/* What kind of Content-Type to use on un-specified files with unrecognized
|
||||||
extensions. */
|
extensions. */
|
||||||
@ -1159,20 +1159,19 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
|||||||
struct FormData *firstform;
|
struct FormData *firstform;
|
||||||
struct curl_httppost *file;
|
struct curl_httppost *file;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
curl_off_t size = 0; /* support potentially ENORMOUS formposts */
|
curl_off_t size = 0; /* support potentially ENORMOUS formposts */
|
||||||
char *boundary;
|
char fileboundary[42];
|
||||||
char *fileboundary = NULL;
|
|
||||||
struct curl_slist *curList;
|
struct curl_slist *curList;
|
||||||
|
char boundary[42];
|
||||||
|
|
||||||
*finalform = NULL; /* default form is empty */
|
*finalform = NULL; /* default form is empty */
|
||||||
|
|
||||||
if(!post)
|
if(!post)
|
||||||
return result; /* no input => no output! */
|
return result; /* no input => no output! */
|
||||||
|
|
||||||
boundary = formboundary(data);
|
result = formboundary(data, boundary, sizeof(boundary));
|
||||||
if(!boundary)
|
if(result)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return result;
|
||||||
|
|
||||||
/* Make the first line of the output */
|
/* Make the first line of the output */
|
||||||
result = AddFormDataf(&form, NULL,
|
result = AddFormDataf(&form, NULL,
|
||||||
@ -1182,7 +1181,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
|||||||
boundary);
|
boundary);
|
||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
free(boundary);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* we DO NOT include that line in the total size of the POST, since it'll be
|
/* 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
|
/* 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 */
|
the magic to include several files with the same field name */
|
||||||
|
|
||||||
free(fileboundary);
|
result = formboundary(data, fileboundary, sizeof(fileboundary));
|
||||||
fileboundary = formboundary(data);
|
if(result) {
|
||||||
if(!fileboundary) {
|
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1379,16 +1375,10 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
|
|||||||
|
|
||||||
if(result) {
|
if(result) {
|
||||||
Curl_formclean(&firstform);
|
Curl_formclean(&firstform);
|
||||||
free(fileboundary);
|
|
||||||
free(boundary);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sizep = size;
|
*sizep = size;
|
||||||
|
|
||||||
free(fileboundary);
|
|
||||||
free(boundary);
|
|
||||||
|
|
||||||
*finalform = firstform;
|
*finalform = firstform;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -1562,16 +1552,17 @@ char *Curl_formpostheader(void *formp, size_t *len)
|
|||||||
* formboundary() creates a suitable boundary string and returns an allocated
|
* formboundary() creates a suitable boundary string and returns an allocated
|
||||||
* one.
|
* 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)
|
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
|
||||||
combinations */
|
combinations */
|
||||||
unsigned int rnd[2];
|
DEBUGASSERT(buflen >= 41);
|
||||||
CURLcode result = Curl_rand(data, &rnd[0], 2);
|
|
||||||
if(result)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
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 */
|
#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");
|
char *force_entropy = getenv("CURL_ENTROPY");
|
||||||
if(force_entropy) {
|
if(force_entropy) {
|
||||||
if(!seeded) {
|
if(!seeded) {
|
||||||
|
unsigned int seed = 0;
|
||||||
size_t elen = strlen(force_entropy);
|
size_t elen = strlen(force_entropy);
|
||||||
size_t clen = sizeof(randseed);
|
size_t clen = sizeof(seed);
|
||||||
size_t min = elen < clen ? elen : clen;
|
size_t min = elen < clen ? elen : clen;
|
||||||
memcpy((char *)&randseed, force_entropy, min);
|
memcpy((char *)&seed, force_entropy, min);
|
||||||
|
randseed = ntohl(seed);
|
||||||
seeded = TRUE;
|
seeded = TRUE;
|
||||||
}
|
}
|
||||||
else
|
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,
|
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
|
||||||
unsigned int num)
|
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
|
CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
assert(num > 0);
|
assert(num > 0);
|
||||||
|
|
||||||
for(i = 0; i < num; i++) {
|
while(num) {
|
||||||
result = randit(data, rndptr++);
|
unsigned int r;
|
||||||
|
size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int);
|
||||||
|
|
||||||
|
result = randit(data, &r);
|
||||||
if(result)
|
if(result)
|
||||||
return 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;
|
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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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.
|
* 'rnd' points to.
|
||||||
*
|
*
|
||||||
* If libcurl is built without TLS support or with a TLS backend that lacks a
|
* If libcurl is built without TLS support or with a TLS backend that lacks a
|
||||||
@ -37,7 +37,11 @@
|
|||||||
* easy handle!
|
* easy handle!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rnd,
|
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
|
||||||
unsigned int 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 */
|
#endif /* HEADER_CURL_RAND_H */
|
||||||
|
@ -360,7 +360,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
|
|||||||
char qop_options[64];
|
char qop_options[64];
|
||||||
int qop_values;
|
int qop_values;
|
||||||
char cnonce[33];
|
char cnonce[33];
|
||||||
unsigned int entropy[4];
|
|
||||||
char nonceCount[] = "00000001";
|
char nonceCount[] = "00000001";
|
||||||
char method[] = "AUTHENTICATE";
|
char method[] = "AUTHENTICATE";
|
||||||
char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
|
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))
|
if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
|
||||||
return CURLE_BAD_CONTENT_ENCODING;
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
/* Generate 16 bytes of random data */
|
/* Generate 32 random hex chars, 32 bytes + 1 zero termination */
|
||||||
result = Curl_rand(data, &entropy[0], 4);
|
result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce));
|
||||||
if(result)
|
if(result)
|
||||||
return 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 */
|
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
|
||||||
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
||||||
if(!ctxt)
|
if(!ctxt)
|
||||||
@ -684,12 +679,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
|
|||||||
digest->nc = 1;
|
digest->nc = 1;
|
||||||
|
|
||||||
if(!digest->cnonce) {
|
if(!digest->cnonce) {
|
||||||
unsigned int rnd[4];
|
result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
|
||||||
result = Curl_rand(data, &rnd[0], 4);
|
sizeof(cnoncebuf));
|
||||||
if(result)
|
if(result)
|
||||||
return 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),
|
result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
|
||||||
&cnonce, &cnonce_sz);
|
&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 defined(USE_NTRESPONSES) && defined(USE_NTLM_V2)
|
||||||
if(ntlm->target_info_len) {
|
if(ntlm->target_info_len) {
|
||||||
unsigned char ntbuffer[0x18];
|
unsigned char ntbuffer[0x18];
|
||||||
unsigned int entropy[2];
|
unsigned char entropy[8];
|
||||||
unsigned char ntlmv2hash[0x18];
|
unsigned char ntlmv2hash[0x18];
|
||||||
|
|
||||||
result = Curl_rand(data, &entropy[0], 2);
|
result = Curl_rand(data, entropy, 8);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -572,15 +572,13 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* LMv2 response */
|
/* LMv2 response */
|
||||||
result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
|
result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy,
|
||||||
(unsigned char *)&entropy[0],
|
|
||||||
&ntlm->nonce[0], lmresp);
|
&ntlm->nonce[0], lmresp);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* NTLMv2 response */
|
/* NTLMv2 response */
|
||||||
result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
|
result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy,
|
||||||
(unsigned char *)&entropy[0],
|
|
||||||
ntlm, &ntlmv2resp, &ntresplen);
|
ntlm, &ntlmv2resp, &ntresplen);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@ -596,10 +594,10 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||||||
unsigned char ntbuffer[0x18];
|
unsigned char ntbuffer[0x18];
|
||||||
unsigned char tmp[0x18];
|
unsigned char tmp[0x18];
|
||||||
unsigned char md5sum[MD5_DIGEST_LENGTH];
|
unsigned char md5sum[MD5_DIGEST_LENGTH];
|
||||||
unsigned int entropy[2];
|
unsigned char entropy[8];
|
||||||
|
|
||||||
/* Need to create 8 bytes random data */
|
/* Need to create 8 bytes random data */
|
||||||
result = Curl_rand(data, &entropy[0], 2);
|
result = Curl_rand(data, entropy, 8);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user