diff options
Diffstat (limited to 'src/lib/libssl/s23_clnt.c')
-rw-r--r-- | src/lib/libssl/s23_clnt.c | 225 |
1 files changed, 166 insertions, 59 deletions
diff --git a/src/lib/libssl/s23_clnt.c b/src/lib/libssl/s23_clnt.c index 779e94a35c..86356731ea 100644 --- a/src/lib/libssl/s23_clnt.c +++ b/src/lib/libssl/s23_clnt.c | |||
@@ -106,7 +106,7 @@ SSL_METHOD *SSLv23_client_method(void) | |||
106 | int ssl23_connect(SSL *s) | 106 | int ssl23_connect(SSL *s) |
107 | { | 107 | { |
108 | BUF_MEM *buf=NULL; | 108 | BUF_MEM *buf=NULL; |
109 | unsigned long Time=time(NULL); | 109 | unsigned long Time=(unsigned long)time(NULL); |
110 | void (*cb)(const SSL *ssl,int type,int val)=NULL; | 110 | void (*cb)(const SSL *ssl,int type,int val)=NULL; |
111 | int ret= -1; | 111 | int ret= -1; |
112 | int new_state,state; | 112 | int new_state,state; |
@@ -220,9 +220,28 @@ static int ssl23_client_hello(SSL *s) | |||
220 | { | 220 | { |
221 | unsigned char *buf; | 221 | unsigned char *buf; |
222 | unsigned char *p,*d; | 222 | unsigned char *p,*d; |
223 | int i,ch_len; | 223 | int i,j,ch_len; |
224 | unsigned long Time,l; | ||
225 | int ssl2_compat; | ||
226 | int version = 0, version_major, version_minor; | ||
227 | SSL_COMP *comp; | ||
224 | int ret; | 228 | int ret; |
225 | 229 | ||
230 | ssl2_compat = (s->options & SSL_OP_NO_SSLv2) ? 0 : 1; | ||
231 | |||
232 | if (!(s->options & SSL_OP_NO_TLSv1)) | ||
233 | { | ||
234 | version = TLS1_VERSION; | ||
235 | } | ||
236 | else if (!(s->options & SSL_OP_NO_SSLv3)) | ||
237 | { | ||
238 | version = SSL3_VERSION; | ||
239 | } | ||
240 | else if (!(s->options & SSL_OP_NO_SSLv2)) | ||
241 | { | ||
242 | version = SSL2_VERSION; | ||
243 | } | ||
244 | |||
226 | buf=(unsigned char *)s->init_buf->data; | 245 | buf=(unsigned char *)s->init_buf->data; |
227 | if (s->state == SSL23_ST_CW_CLNT_HELLO_A) | 246 | if (s->state == SSL23_ST_CW_CLNT_HELLO_A) |
228 | { | 247 | { |
@@ -235,19 +254,15 @@ static int ssl23_client_hello(SSL *s) | |||
235 | #endif | 254 | #endif |
236 | 255 | ||
237 | p=s->s3->client_random; | 256 | p=s->s3->client_random; |
238 | if(RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE) <= 0) | 257 | Time=(unsigned long)time(NULL); /* Time */ |
239 | return -1; | 258 | l2n(Time,p); |
240 | 259 | if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) | |
241 | /* Do the message type and length last */ | 260 | return -1; |
242 | d= &(buf[2]); | ||
243 | p=d+9; | ||
244 | 261 | ||
245 | *(d++)=SSL2_MT_CLIENT_HELLO; | 262 | if (version == TLS1_VERSION) |
246 | if (!(s->options & SSL_OP_NO_TLSv1)) | ||
247 | { | 263 | { |
248 | *(d++)=TLS1_VERSION_MAJOR; | 264 | version_major = TLS1_VERSION_MAJOR; |
249 | *(d++)=TLS1_VERSION_MINOR; | 265 | version_minor = TLS1_VERSION_MINOR; |
250 | s->client_version=TLS1_VERSION; | ||
251 | } | 266 | } |
252 | #ifdef OPENSSL_FIPS | 267 | #ifdef OPENSSL_FIPS |
253 | else if(FIPS_mode()) | 268 | else if(FIPS_mode()) |
@@ -257,17 +272,15 @@ static int ssl23_client_hello(SSL *s) | |||
257 | return -1; | 272 | return -1; |
258 | } | 273 | } |
259 | #endif | 274 | #endif |
260 | else if (!(s->options & SSL_OP_NO_SSLv3)) | 275 | else if (version == SSL3_VERSION) |
261 | { | 276 | { |
262 | *(d++)=SSL3_VERSION_MAJOR; | 277 | version_major = SSL3_VERSION_MAJOR; |
263 | *(d++)=SSL3_VERSION_MINOR; | 278 | version_minor = SSL3_VERSION_MINOR; |
264 | s->client_version=SSL3_VERSION; | ||
265 | } | 279 | } |
266 | else if (!(s->options & SSL_OP_NO_SSLv2)) | 280 | else if (version == SSL2_VERSION) |
267 | { | 281 | { |
268 | *(d++)=SSL2_VERSION_MAJOR; | 282 | version_major = SSL2_VERSION_MAJOR; |
269 | *(d++)=SSL2_VERSION_MINOR; | 283 | version_minor = SSL2_VERSION_MINOR; |
270 | s->client_version=SSL2_VERSION; | ||
271 | } | 284 | } |
272 | else | 285 | else |
273 | { | 286 | { |
@@ -275,59 +288,153 @@ static int ssl23_client_hello(SSL *s) | |||
275 | return(-1); | 288 | return(-1); |
276 | } | 289 | } |
277 | 290 | ||
278 | /* Ciphers supported */ | 291 | s->client_version = version; |
279 | i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p); | 292 | |
280 | if (i == 0) | 293 | if (ssl2_compat) |
281 | { | 294 | { |
282 | /* no ciphers */ | 295 | /* create SSL 2.0 compatible Client Hello */ |
283 | SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); | 296 | |
284 | return(-1); | 297 | /* two byte record header will be written last */ |
285 | } | 298 | d = &(buf[2]); |
286 | s2n(i,d); | 299 | p = d + 9; /* leave space for message type, version, individual length fields */ |
287 | p+=i; | ||
288 | 300 | ||
289 | /* put in the session-id, zero since there is no | 301 | *(d++) = SSL2_MT_CLIENT_HELLO; |
290 | * reuse. */ | 302 | *(d++) = version_major; |
303 | *(d++) = version_minor; | ||
304 | |||
305 | /* Ciphers supported */ | ||
306 | i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),p,0); | ||
307 | if (i == 0) | ||
308 | { | ||
309 | /* no ciphers */ | ||
310 | SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); | ||
311 | return -1; | ||
312 | } | ||
313 | s2n(i,d); | ||
314 | p+=i; | ||
315 | |||
316 | /* put in the session-id length (zero since there is no reuse) */ | ||
291 | #if 0 | 317 | #if 0 |
292 | s->session->session_id_length=0; | 318 | s->session->session_id_length=0; |
293 | #endif | 319 | #endif |
294 | s2n(0,d); | 320 | s2n(0,d); |
295 | 321 | ||
296 | if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) | 322 | if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) |
297 | ch_len=SSL2_CHALLENGE_LENGTH; | 323 | ch_len=SSL2_CHALLENGE_LENGTH; |
324 | else | ||
325 | ch_len=SSL2_MAX_CHALLENGE_LENGTH; | ||
326 | |||
327 | /* write out sslv2 challenge */ | ||
328 | if (SSL3_RANDOM_SIZE < ch_len) | ||
329 | i=SSL3_RANDOM_SIZE; | ||
330 | else | ||
331 | i=ch_len; | ||
332 | s2n(i,d); | ||
333 | memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE); | ||
334 | if (RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0) | ||
335 | return -1; | ||
336 | |||
337 | memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); | ||
338 | p+=i; | ||
339 | |||
340 | i= p- &(buf[2]); | ||
341 | buf[0]=((i>>8)&0xff)|0x80; | ||
342 | buf[1]=(i&0xff); | ||
343 | |||
344 | /* number of bytes to write */ | ||
345 | s->init_num=i+2; | ||
346 | s->init_off=0; | ||
347 | |||
348 | ssl3_finish_mac(s,&(buf[2]),i); | ||
349 | } | ||
298 | else | 350 | else |
299 | ch_len=SSL2_MAX_CHALLENGE_LENGTH; | 351 | { |
352 | /* create Client Hello in SSL 3.0/TLS 1.0 format */ | ||
300 | 353 | ||
301 | /* write out sslv2 challenge */ | 354 | /* do the record header (5 bytes) and handshake message header (4 bytes) last */ |
302 | if (SSL3_RANDOM_SIZE < ch_len) | 355 | d = p = &(buf[9]); |
303 | i=SSL3_RANDOM_SIZE; | 356 | |
304 | else | 357 | *(p++) = version_major; |
305 | i=ch_len; | 358 | *(p++) = version_minor; |
306 | s2n(i,d); | 359 | |
307 | memset(&(s->s3->client_random[0]),0,SSL3_RANDOM_SIZE); | 360 | /* Random stuff */ |
308 | if(RAND_pseudo_bytes(&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i) <= 0) | 361 | memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); |
309 | return -1; | 362 | p += SSL3_RANDOM_SIZE; |
363 | |||
364 | /* Session ID (zero since there is no reuse) */ | ||
365 | *(p++) = 0; | ||
366 | |||
367 | /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ | ||
368 | i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),ssl3_put_cipher_by_char); | ||
369 | if (i == 0) | ||
370 | { | ||
371 | SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); | ||
372 | return -1; | ||
373 | } | ||
374 | s2n(i,p); | ||
375 | p+=i; | ||
376 | |||
377 | /* COMPRESSION */ | ||
378 | if (s->ctx->comp_methods == NULL) | ||
379 | j=0; | ||
380 | else | ||
381 | j=sk_SSL_COMP_num(s->ctx->comp_methods); | ||
382 | *(p++)=1+j; | ||
383 | for (i=0; i<j; i++) | ||
384 | { | ||
385 | comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); | ||
386 | *(p++)=comp->id; | ||
387 | } | ||
388 | *(p++)=0; /* Add the NULL method */ | ||
389 | |||
390 | l = p-d; | ||
391 | *p = 42; | ||
310 | 392 | ||
311 | memcpy(p,&(s->s3->client_random[SSL3_RANDOM_SIZE-i]),i); | 393 | /* fill in 4-byte handshake header */ |
312 | p+=i; | 394 | d=&(buf[5]); |
395 | *(d++)=SSL3_MT_CLIENT_HELLO; | ||
396 | l2n3(l,d); | ||
313 | 397 | ||
314 | i= p- &(buf[2]); | 398 | l += 4; |
315 | buf[0]=((i>>8)&0xff)|0x80; | 399 | |
316 | buf[1]=(i&0xff); | 400 | if (l > SSL3_RT_MAX_PLAIN_LENGTH) |
401 | { | ||
402 | SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); | ||
403 | return -1; | ||
404 | } | ||
405 | |||
406 | /* fill in 5-byte record header */ | ||
407 | d=buf; | ||
408 | *(d++) = SSL3_RT_HANDSHAKE; | ||
409 | *(d++) = version_major; | ||
410 | *(d++) = version_minor; /* arguably we should send the *lowest* suported version here | ||
411 | * (indicating, e.g., TLS 1.0 in "SSL 3.0 format") */ | ||
412 | s2n((int)l,d); | ||
413 | |||
414 | /* number of bytes to write */ | ||
415 | s->init_num=p-buf; | ||
416 | s->init_off=0; | ||
417 | |||
418 | ssl3_finish_mac(s,&(buf[5]), s->init_num - 5); | ||
419 | } | ||
317 | 420 | ||
318 | s->state=SSL23_ST_CW_CLNT_HELLO_B; | 421 | s->state=SSL23_ST_CW_CLNT_HELLO_B; |
319 | /* number of bytes to write */ | ||
320 | s->init_num=i+2; | ||
321 | s->init_off=0; | 422 | s->init_off=0; |
322 | |||
323 | ssl3_finish_mac(s,&(buf[2]),i); | ||
324 | } | 423 | } |
325 | 424 | ||
326 | /* SSL3_ST_CW_CLNT_HELLO_B */ | 425 | /* SSL3_ST_CW_CLNT_HELLO_B */ |
327 | ret = ssl23_write_bytes(s); | 426 | ret = ssl23_write_bytes(s); |
328 | if (ret >= 2) | 427 | |
329 | if (s->msg_callback) | 428 | if ((ret >= 2) && s->msg_callback) |
330 | s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg); /* CLIENT-HELLO */ | 429 | { |
430 | /* Client Hello has been sent; tell msg_callback */ | ||
431 | |||
432 | if (ssl2_compat) | ||
433 | s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg); | ||
434 | else | ||
435 | s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data+5, ret-5, s, s->msg_callback_arg); | ||
436 | } | ||
437 | |||
331 | return ret; | 438 | return ret; |
332 | } | 439 | } |
333 | 440 | ||