blob: 8e3bfc327c6537442dd80589683466bee9215781 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * SSLv3/TLSv1 client-side functions
3 *
Paul Bakker77b385e2009-07-28 17:23:11 +00004 * Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
5 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00006 *
Paul Bakker77b385e2009-07-28 17:23:11 +00007 * Joined copyright on original XySSL code with: Christophe Devine
Paul Bakker5121ce52009-01-03 21:22:43 +00008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
Paul Bakker40e46942009-01-03 21:51:57 +000024#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000025
Paul Bakker40e46942009-01-03 21:51:57 +000026#if defined(POLARSSL_SSL_CLI_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Paul Bakker40e46942009-01-03 21:51:57 +000028#include "polarssl/debug.h"
29#include "polarssl/ssl.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000030
31#include <string.h>
32#include <stdlib.h>
33#include <stdio.h>
34#include <time.h>
35
36static int ssl_write_client_hello( ssl_context *ssl )
37{
38 int ret, i, n;
39 unsigned char *buf;
40 unsigned char *p;
41 time_t t;
42
43 SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
44
45 ssl->major_ver = SSL_MAJOR_VERSION_3;
46 ssl->minor_ver = SSL_MINOR_VERSION_0;
47
48 ssl->max_major_ver = SSL_MAJOR_VERSION_3;
49 ssl->max_minor_ver = SSL_MINOR_VERSION_1;
50
51 /*
52 * 0 . 0 handshake type
53 * 1 . 3 handshake length
54 * 4 . 5 highest version supported
55 * 6 . 9 current UNIX time
56 * 10 . 37 random bytes
57 */
58 buf = ssl->out_msg;
59 p = buf + 4;
60
61 *p++ = (unsigned char) ssl->max_major_ver;
62 *p++ = (unsigned char) ssl->max_minor_ver;
63
64 SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
65 buf[4], buf[5] ) );
66
67 t = time( NULL );
68 *p++ = (unsigned char)( t >> 24 );
69 *p++ = (unsigned char)( t >> 16 );
70 *p++ = (unsigned char)( t >> 8 );
71 *p++ = (unsigned char)( t );
72
73 SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
74
75 for( i = 28; i > 0; i-- )
76 *p++ = (unsigned char) ssl->f_rng( ssl->p_rng );
77
78 memcpy( ssl->randbytes, buf + 6, 32 );
79
80 SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 );
81
82 /*
83 * 38 . 38 session id length
84 * 39 . 39+n session id
85 * 40+n . 41+n cipherlist length
86 * 42+n . .. cipherlist
87 * .. . .. compression alg. (0)
88 * .. . .. extensions (unused)
89 */
90 n = ssl->session->length;
91
92 if( n < 16 || n > 32 || ssl->resume == 0 ||
93 t - ssl->session->start > ssl->timeout )
94 n = 0;
95
96 *p++ = (unsigned char) n;
97
98 for( i = 0; i < n; i++ )
99 *p++ = ssl->session->id[i];
100
101 SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
102 SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
103
104 for( n = 0; ssl->ciphers[n] != 0; n++ );
105 *p++ = (unsigned char)( n >> 7 );
106 *p++ = (unsigned char)( n << 1 );
107
108 SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphers", n ) );
109
110 for( i = 0; i < n; i++ )
111 {
112 SSL_DEBUG_MSG( 3, ( "client hello, add cipher: %2d",
113 ssl->ciphers[i] ) );
114
115 *p++ = (unsigned char)( ssl->ciphers[i] >> 8 );
116 *p++ = (unsigned char)( ssl->ciphers[i] );
117 }
118
119 SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
120 SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", 0 ) );
121
122 *p++ = 1;
123 *p++ = SSL_COMPRESS_NULL;
124
125 if ( ssl->hostname != NULL )
126 {
127 SSL_DEBUG_MSG( 3, ( "client hello, server name extension: %s",
128 ssl->hostname ) );
129
130 *p++ = (unsigned char)( ( (ssl->hostname_len + 9) >> 8 ) & 0xFF );
131 *p++ = (unsigned char)( ( (ssl->hostname_len + 9) ) & 0xFF );
132
133 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
134 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME ) & 0xFF );
135
136 *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
137 *p++ = (unsigned char)( ( (ssl->hostname_len + 5) ) & 0xFF );
138
139 *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
140 *p++ = (unsigned char)( ( (ssl->hostname_len + 3) ) & 0xFF );
141
142 *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
143 *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
144 *p++ = (unsigned char)( ( ssl->hostname_len ) & 0xFF );
145
146 memcpy( p, ssl->hostname, ssl->hostname_len );
147
148 p += ssl->hostname_len;
149 }
150
151 ssl->out_msglen = p - buf;
152 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
153 ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
154
155 ssl->state++;
156
157 if( ( ret = ssl_write_record( ssl ) ) != 0 )
158 {
159 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
160 return( ret );
161 }
162
163 SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
164
165 return( 0 );
166}
167
168static int ssl_parse_server_hello( ssl_context *ssl )
169{
170 time_t t;
171 int ret, i, n;
172 int ext_len;
173 unsigned char *buf;
174
175 SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
176
177 /*
178 * 0 . 0 handshake type
179 * 1 . 3 handshake length
180 * 4 . 5 protocol version
181 * 6 . 9 UNIX time()
182 * 10 . 37 random bytes
183 */
184 buf = ssl->in_msg;
185
186 if( ( ret = ssl_read_record( ssl ) ) != 0 )
187 {
188 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
189 return( ret );
190 }
191
192 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
193 {
194 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000195 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 }
197
198 SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
199 buf[4], buf[5] ) );
200
201 if( ssl->in_hslen < 42 ||
202 buf[0] != SSL_HS_SERVER_HELLO ||
203 buf[4] != SSL_MAJOR_VERSION_3 )
204 {
205 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000206 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 }
208
209 if( buf[5] != SSL_MINOR_VERSION_0 &&
210 buf[5] != SSL_MINOR_VERSION_1 )
211 {
212 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000213 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 }
215
216 ssl->minor_ver = buf[5];
217
218 t = ( (time_t) buf[6] << 24 )
219 | ( (time_t) buf[7] << 16 )
220 | ( (time_t) buf[8] << 8 )
221 | ( (time_t) buf[9] );
222
223 memcpy( ssl->randbytes + 32, buf + 6, 32 );
224
225 n = buf[38];
226
227 SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
228 SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
229
230 /*
231 * 38 . 38 session id length
232 * 39 . 38+n session id
233 * 39+n . 40+n chosen cipher
234 * 41+n . 41+n chosen compression alg.
235 * 42+n . 43+n extensions length
236 * 44+n . 44+n+m extensions
237 */
238 if( n < 0 || n > 32 || ssl->in_hslen > 42 + n )
239 {
240 ext_len = ( ( buf[42 + n] << 8 )
241 | ( buf[43 + n] ) ) + 2;
242 }
243 else
244 {
245 ext_len = 0;
246 }
247
248 if( n < 0 || n > 32 || ssl->in_hslen != 42 + n + ext_len )
249 {
250 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000251 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 }
253
254 i = ( buf[39 + n] << 8 ) | buf[40 + n];
255
256 SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
257 SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
258
259 /*
260 * Check if the session can be resumed
261 */
262 if( ssl->resume == 0 || n == 0 ||
263 ssl->session->cipher != i ||
264 ssl->session->length != n ||
265 memcmp( ssl->session->id, buf + 39, n ) != 0 )
266 {
267 ssl->state++;
268 ssl->resume = 0;
269 ssl->session->start = time( NULL );
270 ssl->session->cipher = i;
271 ssl->session->length = n;
272 memcpy( ssl->session->id, buf + 39, n );
273 }
274 else
275 {
276 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
277 ssl_derive_keys( ssl );
278 }
279
280 SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
281 ssl->resume ? "a" : "no" ) );
282
283 SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d", i ) );
284 SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
285
286 i = 0;
287 while( 1 )
288 {
289 if( ssl->ciphers[i] == 0 )
290 {
291 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000292 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 }
294
295 if( ssl->ciphers[i++] == ssl->session->cipher )
296 break;
297 }
298
299 if( buf[41 + n] != SSL_COMPRESS_NULL )
300 {
301 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 }
304
305 /* TODO: Process extensions */
306
307 SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
308
309 return( 0 );
310}
311
312static int ssl_parse_server_key_exchange( ssl_context *ssl )
313{
314 int ret, n;
315 unsigned char *p, *end;
316 unsigned char hash[36];
317 md5_context md5;
318 sha1_context sha1;
319
320 SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
321
322 if( ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +0000323 ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
324 ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA)
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 {
326 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
327 ssl->state++;
328 return( 0 );
329 }
330
Paul Bakker40e46942009-01-03 21:51:57 +0000331#if !defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000332 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000333 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334#else
335 if( ( ret = ssl_read_record( ssl ) ) != 0 )
336 {
337 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
338 return( ret );
339 }
340
341 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
342 {
343 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000344 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345 }
346
347 if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
348 {
349 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000350 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351 }
352
353 /*
354 * Ephemeral DH parameters:
355 *
356 * struct {
357 * opaque dh_p<1..2^16-1>;
358 * opaque dh_g<1..2^16-1>;
359 * opaque dh_Ys<1..2^16-1>;
360 * } ServerDHParams;
361 */
362 p = ssl->in_msg + 4;
363 end = ssl->in_msg + ssl->in_hslen;
364
365 if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
366 {
367 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000368 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 }
370
371 if( (int)( end - p ) != ssl->peer_cert->rsa.len )
372 {
373 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000374 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375 }
376
377 if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
378 {
379 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000380 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000381 }
382
383 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P );
384 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G );
385 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
386
387 /*
388 * digitally-signed struct {
389 * opaque md5_hash[16];
390 * opaque sha_hash[20];
391 * };
392 *
393 * md5_hash
394 * MD5(ClientHello.random + ServerHello.random
395 * + ServerParams);
396 * sha_hash
397 * SHA(ClientHello.random + ServerHello.random
398 * + ServerParams);
399 */
400 n = ssl->in_hslen - ( end - p ) - 6;
401
402 md5_starts( &md5 );
403 md5_update( &md5, ssl->randbytes, 64 );
404 md5_update( &md5, ssl->in_msg + 4, n );
405 md5_finish( &md5, hash );
406
407 sha1_starts( &sha1 );
408 sha1_update( &sha1, ssl->randbytes, 64 );
409 sha1_update( &sha1, ssl->in_msg + 4, n );
410 sha1_finish( &sha1, hash + 16 );
411
412 SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
413
414 if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
Paul Bakkerfc22c442009-07-19 20:36:27 +0000415 SIG_RSA_RAW, 36, hash, p ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000416 {
417 SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
418 return( ret );
419 }
420
421 ssl->state++;
422
423 SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
424
425 return( 0 );
426#endif
427}
428
429static int ssl_parse_certificate_request( ssl_context *ssl )
430{
431 int ret;
432
433 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
434
435 /*
436 * 0 . 0 handshake type
437 * 1 . 3 handshake length
438 * 4 . 5 SSL version
439 * 6 . 6 cert type count
440 * 7 .. n-1 cert types
441 * n .. n+1 length of all DNs
442 * n+2 .. n+3 length of DN 1
443 * n+4 .. ... Distinguished Name #1
444 * ... .. ... length of DN 2, etc.
445 */
446 if( ( ret = ssl_read_record( ssl ) ) != 0 )
447 {
448 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
449 return( ret );
450 }
451
452 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
453 {
454 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000455 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 }
457
458 ssl->client_auth = 0;
459 ssl->state++;
460
461 if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
462 ssl->client_auth++;
463
464 SSL_DEBUG_MSG( 3, ( "got %s certificate request",
465 ssl->client_auth ? "a" : "no" ) );
466
467 SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
468
469 return( 0 );
470}
471
472static int ssl_parse_server_hello_done( ssl_context *ssl )
473{
474 int ret;
475
476 SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
477
478 if( ssl->client_auth != 0 )
479 {
480 if( ( ret = ssl_read_record( ssl ) ) != 0 )
481 {
482 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
483 return( ret );
484 }
485
486 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
487 {
488 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000489 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490 }
491 }
492
493 if( ssl->in_hslen != 4 ||
494 ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
495 {
496 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000497 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 }
499
500 ssl->state++;
501
502 SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
503
504 return( 0 );
505}
506
507static int ssl_write_client_key_exchange( ssl_context *ssl )
508{
509 int ret, i, n;
510
511 SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
512
513 if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +0000514 ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
515 ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 {
Paul Bakker40e46942009-01-03 21:51:57 +0000517#if !defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000519 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000520#else
521 /*
522 * DHM key exchange -- send G^X mod P
523 */
524 n = ssl->dhm_ctx.len;
525
526 ssl->out_msg[4] = (unsigned char)( n >> 8 );
527 ssl->out_msg[5] = (unsigned char)( n );
528 i = 6;
529
530 ret = dhm_make_public( &ssl->dhm_ctx, 256,
531 &ssl->out_msg[i], n,
532 ssl->f_rng, ssl->p_rng );
533 if( ret != 0 )
534 {
535 SSL_DEBUG_RET( 1, "dhm_make_public", ret );
536 return( ret );
537 }
538
539 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X );
540 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
541
542 ssl->pmslen = ssl->dhm_ctx.len;
543
544 if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
545 ssl->premaster,
546 &ssl->pmslen ) ) != 0 )
547 {
548 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
549 return( ret );
550 }
551
552 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K );
553#endif
554 }
555 else
556 {
557 /*
558 * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
559 */
560 ssl->premaster[0] = (unsigned char) ssl->max_major_ver;
561 ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
562 ssl->pmslen = 48;
563
564 for( i = 2; i < ssl->pmslen; i++ )
565 ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
566
567 i = 4;
568 n = ssl->peer_cert->rsa.len;
569
570 if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
571 {
572 i += 2;
573 ssl->out_msg[4] = (unsigned char)( n >> 8 );
574 ssl->out_msg[5] = (unsigned char)( n );
575 }
576
577 ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa, RSA_PUBLIC,
578 ssl->pmslen, ssl->premaster,
579 ssl->out_msg + i );
580 if( ret != 0 )
581 {
582 SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
583 return( ret );
584 }
585 }
586
587 ssl_derive_keys( ssl );
588
589 ssl->out_msglen = i + n;
590 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
591 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
592
593 ssl->state++;
594
595 if( ( ret = ssl_write_record( ssl ) ) != 0 )
596 {
597 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
598 return( ret );
599 }
600
601 SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
602
603 return( 0 );
604}
605
606static int ssl_write_certificate_verify( ssl_context *ssl )
607{
608 int ret, n;
609 unsigned char hash[36];
610
611 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
612
613 if( ssl->client_auth == 0 )
614 {
615 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
616 ssl->state++;
617 return( 0 );
618 }
619
620 if( ssl->rsa_key == NULL )
621 {
622 SSL_DEBUG_MSG( 1, ( "got no private key" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000623 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 }
625
626 /*
627 * Make an RSA signature of the handshake digests
628 */
629 ssl_calc_verify( ssl, hash );
630
631 n = ssl->rsa_key->len;
632 ssl->out_msg[4] = (unsigned char)( n >> 8 );
633 ssl->out_msg[5] = (unsigned char)( n );
634
Paul Bakkerfc22c442009-07-19 20:36:27 +0000635 if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW,
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 36, hash, ssl->out_msg + 6 ) ) != 0 )
637 {
638 SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret );
639 return( ret );
640 }
641
642 ssl->out_msglen = 6 + n;
643 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
644 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
645
646 ssl->state++;
647
648 if( ( ret = ssl_write_record( ssl ) ) != 0 )
649 {
650 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
651 return( ret );
652 }
653
654 SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
655
656 return( 0 );
657}
658
659/*
660 * SSL handshake -- client side
661 */
662int ssl_handshake_client( ssl_context *ssl )
663{
664 int ret = 0;
665
666 SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
667
668 while( ssl->state != SSL_HANDSHAKE_OVER )
669 {
670 SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
671
672 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
673 break;
674
675 switch( ssl->state )
676 {
677 case SSL_HELLO_REQUEST:
678 ssl->state = SSL_CLIENT_HELLO;
679 break;
680
681 /*
682 * ==> ClientHello
683 */
684 case SSL_CLIENT_HELLO:
685 ret = ssl_write_client_hello( ssl );
686 break;
687
688 /*
689 * <== ServerHello
690 * Certificate
691 * ( ServerKeyExchange )
692 * ( CertificateRequest )
693 * ServerHelloDone
694 */
695 case SSL_SERVER_HELLO:
696 ret = ssl_parse_server_hello( ssl );
697 break;
698
699 case SSL_SERVER_CERTIFICATE:
700 ret = ssl_parse_certificate( ssl );
701 break;
702
703 case SSL_SERVER_KEY_EXCHANGE:
704 ret = ssl_parse_server_key_exchange( ssl );
705 break;
706
707 case SSL_CERTIFICATE_REQUEST:
708 ret = ssl_parse_certificate_request( ssl );
709 break;
710
711 case SSL_SERVER_HELLO_DONE:
712 ret = ssl_parse_server_hello_done( ssl );
713 break;
714
715 /*
716 * ==> ( Certificate/Alert )
717 * ClientKeyExchange
718 * ( CertificateVerify )
719 * ChangeCipherSpec
720 * Finished
721 */
722 case SSL_CLIENT_CERTIFICATE:
723 ret = ssl_write_certificate( ssl );
724 break;
725
726 case SSL_CLIENT_KEY_EXCHANGE:
727 ret = ssl_write_client_key_exchange( ssl );
728 break;
729
730 case SSL_CERTIFICATE_VERIFY:
731 ret = ssl_write_certificate_verify( ssl );
732 break;
733
734 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
735 ret = ssl_write_change_cipher_spec( ssl );
736 break;
737
738 case SSL_CLIENT_FINISHED:
739 ret = ssl_write_finished( ssl );
740 break;
741
742 /*
743 * <== ChangeCipherSpec
744 * Finished
745 */
746 case SSL_SERVER_CHANGE_CIPHER_SPEC:
747 ret = ssl_parse_change_cipher_spec( ssl );
748 break;
749
750 case SSL_SERVER_FINISHED:
751 ret = ssl_parse_finished( ssl );
752 break;
753
754 case SSL_FLUSH_BUFFERS:
755 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
756 ssl->state = SSL_HANDSHAKE_OVER;
757 break;
758
759 default:
760 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000761 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 }
763
764 if( ret != 0 )
765 break;
766 }
767
768 SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
769
770 return( ret );
771}
772
773#endif