diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/formdata.c | 39 | ||||
| -rw-r--r-- | lib/rand.c | 61 | ||||
| -rw-r--r-- | lib/rand.h | 12 | ||||
| -rw-r--r-- | lib/vauth/digest.c | 15 | ||||
| -rw-r--r-- | lib/vauth/ntlm.c | 14 | 
5 files changed, 87 insertions, 54 deletions
| diff --git a/lib/formdata.c b/lib/formdata.c index 90fbd1143..4c3cf203c 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -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 */ diff --git a/lib/rand.c b/lib/rand.c index 8a1408425..a61a070ee 100644 --- a/lib/rand.c +++ b/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;  } diff --git a/lib/rand.h b/lib/rand.h index 0f8986120..c6fae3553 100644 --- a/lib/rand.h +++ b/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 */ diff --git a/lib/vauth/digest.c b/lib/vauth/digest.c index 268474c78..185098ed6 100644 --- a/lib/vauth/digest.c +++ b/lib/vauth/digest.c @@ -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); diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c index d02eec491..42196455f 100644 --- a/lib/vauth/ntlm.c +++ b/lib/vauth/ntlm.c @@ -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; | 
