Skip to content

Commit f682156

Browse files
committed
Curl_rand: fixed and moved to rand.c
Now Curl_rand() is made to fail if it cannot get the necessary random level. Changed the proto of Curl_rand() slightly to provide a number of ints at once. Moved out from vtls, since it isn't a TLS function and vtls provides Curl_ssl_random() for this to use. Discussion: https://curl.haxx.se/mail/lib-2016-11/0119.html
1 parent 050aa80 commit f682156

File tree

10 files changed

+211
-98
lines changed

10 files changed

+211
-98
lines changed

lib/Makefile.inc

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
5151
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
5252
openldap.c curl_gethostname.c gopher.c idn_win32.c \
5353
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
54-
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c \
54+
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
5555
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
5656
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c
5757

@@ -72,7 +72,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
7272
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
7373
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
7474
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
75-
curl_printf.h system_win32.h
75+
curl_printf.h system_win32.h rand.h
7676

7777
LIB_RCFILES = libcurl.rc
7878

lib/Makefile.vc6

+1
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ X_OBJS= \
602602
$(DIROBJ)\pop3.obj \
603603
$(DIROBJ)\progress.obj \
604604
$(DIROBJ)\strcase.obj \
605+
$(DIROBJ)\rand.obj \
605606
$(DIROBJ)\rtsp.obj \
606607
$(DIROBJ)\schannel.obj \
607608
$(DIROBJ)\security.obj \

lib/formdata.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "strcase.h"
3737
#include "sendf.h"
3838
#include "strdup.h"
39+
#include "rand.h"
3940
/* The last 3 #include files should be in this order */
4041
#include "curl_printf.h"
4142
#include "curl_memory.h"
@@ -1569,8 +1570,12 @@ static char *formboundary(struct Curl_easy *data)
15691570
{
15701571
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
15711572
combinations */
1572-
return aprintf("------------------------%08x%08x",
1573-
Curl_rand(data), Curl_rand(data));
1573+
unsigned int rnd[2];
1574+
CURLcode result = Curl_rand(data, &rnd[0], 2);
1575+
if(result)
1576+
return NULL;
1577+
1578+
return aprintf("------------------------%08x%08x", rnd[0], rnd[1]);
15741579
}
15751580

15761581
#else /* CURL_DISABLE_HTTP */

lib/rand.c

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/***************************************************************************
2+
* _ _ ____ _
3+
* Project ___| | | | _ \| |
4+
* / __| | | | |_) | |
5+
* | (__| |_| | _ <| |___
6+
* \___|\___/|_| \_\_____|
7+
*
8+
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
9+
*
10+
* This software is licensed as described in the file COPYING, which
11+
* you should have received as part of this distribution. The terms
12+
* are also available at https://curl.haxx.se/docs/copyright.html.
13+
*
14+
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15+
* copies of the Software, and permit persons to whom the Software is
16+
* furnished to do so, under the terms of the COPYING file.
17+
*
18+
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19+
* KIND, either express or implied.
20+
*
21+
***************************************************************************/
22+
23+
#include "curl_setup.h"
24+
25+
#include <fcntl.h>
26+
27+
#include <curl/curl.h>
28+
#include "vtls/vtls.h"
29+
#include "sendf.h"
30+
#include "rand.h"
31+
32+
/* The last 3 #include files should be in this order */
33+
#include "curl_printf.h"
34+
#include "curl_memory.h"
35+
#include "memdebug.h"
36+
37+
static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
38+
{
39+
unsigned int r;
40+
CURLcode result = CURLE_OK;
41+
static unsigned int randseed;
42+
static bool seeded = FALSE;
43+
44+
#ifdef CURLDEBUG
45+
char *force_entropy = getenv("CURL_ENTROPY");
46+
if(force_entropy) {
47+
if(!seeded) {
48+
size_t elen = strlen(force_entropy);
49+
size_t clen = sizeof(randseed);
50+
size_t min = elen < clen ? elen : clen;
51+
memcpy((char *)&randseed, force_entropy, min);
52+
seeded = TRUE;
53+
}
54+
else
55+
randseed++;
56+
*rnd = randseed;
57+
return CURLE_OK;
58+
}
59+
#endif
60+
61+
/* data may be NULL! */
62+
result = Curl_ssl_random(data, (unsigned char *)&rnd, sizeof(rnd));
63+
if(result != CURLE_NOT_BUILT_IN)
64+
/* only if there is no random funtion in the TLS backend do the non crypto
65+
version, otherwise return result */
66+
return result;
67+
68+
/* ---- non-cryptographic version following ---- */
69+
70+
#ifdef RANDOM_FILE
71+
if(!seeded) {
72+
/* if there's a random file to read a seed from, use it */
73+
int fd = open(RANDOM_FILE, O_RDONLY);
74+
if(fd > -1) {
75+
/* read random data into the randseed variable */
76+
ssize_t nread = read(fd, &randseed, sizeof(randseed));
77+
if(nread == sizeof(randseed))
78+
seeded = TRUE;
79+
close(fd);
80+
}
81+
}
82+
#endif
83+
84+
if(!seeded) {
85+
struct timeval now = curlx_tvnow();
86+
infof(data, "WARNING: Using weak random seed\n");
87+
randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
88+
randseed = randseed * 1103515245 + 12345;
89+
randseed = randseed * 1103515245 + 12345;
90+
randseed = randseed * 1103515245 + 12345;
91+
seeded = TRUE;
92+
}
93+
94+
/* Return an unsigned 32-bit pseudo-random number. */
95+
r = randseed = randseed * 1103515245 + 12345;
96+
*rnd = (r << 16) | ((r >> 16) & 0xFFFF);
97+
return CURLE_OK;
98+
}
99+
100+
/*
101+
* Curl_rand() stores 'num' number of random unsigned integers in the buffer
102+
* 'rndptr' points to.
103+
*
104+
* If libcurl is built without TLS support or with a TLS backend that lacks a
105+
* proper random API (Gskit, PolarSSL or mbedTLS), this function will use
106+
* "weak" random.
107+
*
108+
* When built *with* TLS support and a backend that offers strong random, it
109+
* will return error if it cannot provide strong random values.
110+
*
111+
* NOTE: 'data' may be passed in as NULL when coming from external API without
112+
* easy handle!
113+
*
114+
*/
115+
116+
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rndptr, int num)
117+
{
118+
CURLcode result;
119+
int i;
120+
121+
assert(num > 0);
122+
123+
for(i = 0; i < num; i++) {
124+
result = randit(data, rndptr++);
125+
if(result)
126+
return result;
127+
}
128+
return result;
129+
}

lib/rand.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef HEADER_CURL_RAND_H
2+
#define HEADER_CURL_RAND_H
3+
/***************************************************************************
4+
* _ _ ____ _
5+
* Project ___| | | | _ \| |
6+
* / __| | | | |_) | |
7+
* | (__| |_| | _ <| |___
8+
* \___|\___/|_| \_\_____|
9+
*
10+
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
11+
*
12+
* This software is licensed as described in the file COPYING, which
13+
* you should have received as part of this distribution. The terms
14+
* are also available at https://curl.haxx.se/docs/copyright.html.
15+
*
16+
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
17+
* copies of the Software, and permit persons to whom the Software is
18+
* furnished to do so, under the terms of the COPYING file.
19+
*
20+
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21+
* KIND, either express or implied.
22+
*
23+
***************************************************************************/
24+
25+
/*
26+
* Curl_rand() stores 'num' number of random unsigned integers in the buffer
27+
* 'rnd' points to.
28+
*
29+
* If libcurl is built without TLS support or with a TLS backend that lacks a
30+
* proper random API (Gskit, PolarSSL or mbedTLS), this function will use
31+
* "weak" random.
32+
*
33+
* When built *with* TLS support and a backend that offers strong random, it
34+
* will return error if it cannot provide strong random values.
35+
*
36+
* NOTE: 'data' may be passed in as NULL when coming from external API without
37+
* easy handle!
38+
*
39+
*/
40+
CURLcode Curl_rand(struct Curl_easy *data, unsigned int *rnd, int num);
41+
42+
#endif /* HEADER_CURL_RAND_H */

lib/vauth/digest.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "strcase.h"
4141
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
4242
#include "curl_printf.h"
43+
#include "rand.h"
4344

4445
/* The last #include files should be: */
4546
#include "curl_memory.h"
@@ -387,10 +388,9 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
387388
return CURLE_BAD_CONTENT_ENCODING;
388389

389390
/* Generate 16 bytes of random data */
390-
entropy[0] = Curl_rand(data);
391-
entropy[1] = Curl_rand(data);
392-
entropy[2] = Curl_rand(data);
393-
entropy[3] = Curl_rand(data);
391+
result = Curl_rand(data, &entropy[0], 4);
392+
if(result)
393+
return result;
394394

395395
/* Convert the random data into a 32 byte hex string */
396396
snprintf(cnonce, sizeof(cnonce), "%08x%08x%08x%08x",
@@ -684,9 +684,12 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
684684
digest->nc = 1;
685685

686686
if(!digest->cnonce) {
687+
unsigned int rnd[4];
688+
result = Curl_rand(data, &rnd[0], 4);
689+
if(result)
690+
return result;
687691
snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
688-
Curl_rand(data), Curl_rand(data),
689-
Curl_rand(data), Curl_rand(data));
692+
rnd[0], rnd[1], rnd[2], rnd[3]);
690693

691694
result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
692695
&cnonce, &cnonce_sz);

lib/vauth/ntlm.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#include "curl_gethostname.h"
4242
#include "curl_multibyte.h"
4343
#include "warnless.h"
44-
44+
#include "rand.h"
4545
#include "vtls/vtls.h"
4646

4747
#ifdef USE_NSS
@@ -558,8 +558,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
558558
unsigned int entropy[2];
559559
unsigned char ntlmv2hash[0x18];
560560

561-
entropy[0] = Curl_rand(data);
562-
entropy[1] = Curl_rand(data);
561+
result = Curl_rand(data, &entropy[0], 2);
562+
if(result)
563+
return result;
563564

564565
result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
565566
if(result)
@@ -598,8 +599,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
598599
unsigned int entropy[2];
599600

600601
/* Need to create 8 bytes random data */
601-
entropy[0] = Curl_rand(data);
602-
entropy[1] = Curl_rand(data);
602+
result = Curl_rand(data, &entropy[0], 2);
603+
if(result)
604+
return result;
603605

604606
/* 8 bytes random data as challenge in lmresp */
605607
memcpy(lmresp, entropy, 8);

lib/vtls/gskit.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* | (__| |_| | _ <| |___
88
* \___|\___/|_| \_\_____|
99
*
10-
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
10+
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
1111
*
1212
* This software is licensed as described in the file COPYING, which
1313
* you should have received as part of this distribution. The terms
@@ -64,7 +64,7 @@ int Curl_gskit_check_cxn(struct connectdata *cxn);
6464
#define curlssl_version Curl_gskit_version
6565
#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
6666
#define curlssl_data_pending(x,y) 0
67-
#define curlssl_random(x,y,z) -1
67+
#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN)
6868

6969
#endif /* USE_GSKIT */
7070

0 commit comments

Comments
 (0)