blob: 5802fdc1b2850ffa1cf82e33d325f93d0b5194c5 [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 ||
Paul Bakkerff60ee62010-03-16 21:09:09 +000093 ( ssl->timeout != 0 && t - ssl->session->start > ssl->timeout ) )
Paul Bakker5121ce52009-01-03 21:22:43 +000094 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;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000277
278 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
279 {
280 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
281 return( ret );
282 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 }
284
285 SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
286 ssl->resume ? "a" : "no" ) );
287
288 SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d", i ) );
289 SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
290
291 i = 0;
292 while( 1 )
293 {
294 if( ssl->ciphers[i] == 0 )
295 {
296 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000297 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 }
299
300 if( ssl->ciphers[i++] == ssl->session->cipher )
301 break;
302 }
303
304 if( buf[41 + n] != SSL_COMPRESS_NULL )
305 {
306 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000307 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308 }
309
310 /* TODO: Process extensions */
311
312 SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
313
314 return( 0 );
315}
316
317static int ssl_parse_server_key_exchange( ssl_context *ssl )
318{
319 int ret, n;
320 unsigned char *p, *end;
321 unsigned char hash[36];
322 md5_context md5;
323 sha1_context sha1;
324
325 SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
326
327 if( ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +0000328 ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
329 ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA)
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 {
331 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
332 ssl->state++;
333 return( 0 );
334 }
335
Paul Bakker40e46942009-01-03 21:51:57 +0000336#if !defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000338 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339#else
340 if( ( ret = ssl_read_record( ssl ) ) != 0 )
341 {
342 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
343 return( ret );
344 }
345
346 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
347 {
348 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000349 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350 }
351
352 if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
353 {
354 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000355 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 }
357
358 /*
359 * Ephemeral DH parameters:
360 *
361 * struct {
362 * opaque dh_p<1..2^16-1>;
363 * opaque dh_g<1..2^16-1>;
364 * opaque dh_Ys<1..2^16-1>;
365 * } ServerDHParams;
366 */
367 p = ssl->in_msg + 4;
368 end = ssl->in_msg + ssl->in_hslen;
369
370 if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
371 {
372 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000373 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000374 }
375
376 if( (int)( end - p ) != ssl->peer_cert->rsa.len )
377 {
378 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000379 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000380 }
381
382 if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
383 {
384 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000385 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000386 }
387
388 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P );
389 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G );
390 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
391
392 /*
393 * digitally-signed struct {
394 * opaque md5_hash[16];
395 * opaque sha_hash[20];
396 * };
397 *
398 * md5_hash
399 * MD5(ClientHello.random + ServerHello.random
400 * + ServerParams);
401 * sha_hash
402 * SHA(ClientHello.random + ServerHello.random
403 * + ServerParams);
404 */
405 n = ssl->in_hslen - ( end - p ) - 6;
406
407 md5_starts( &md5 );
408 md5_update( &md5, ssl->randbytes, 64 );
409 md5_update( &md5, ssl->in_msg + 4, n );
410 md5_finish( &md5, hash );
411
412 sha1_starts( &sha1 );
413 sha1_update( &sha1, ssl->randbytes, 64 );
414 sha1_update( &sha1, ssl->in_msg + 4, n );
415 sha1_finish( &sha1, hash + 16 );
416
417 SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
418
419 if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
Paul Bakkerfc22c442009-07-19 20:36:27 +0000420 SIG_RSA_RAW, 36, hash, p ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 {
422 SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
423 return( ret );
424 }
425
426 ssl->state++;
427
428 SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
429
430 return( 0 );
431#endif
432}
433
434static int ssl_parse_certificate_request( ssl_context *ssl )
435{
436 int ret;
437
438 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
439
440 /*
441 * 0 . 0 handshake type
442 * 1 . 3 handshake length
443 * 4 . 5 SSL version
444 * 6 . 6 cert type count
445 * 7 .. n-1 cert types
446 * n .. n+1 length of all DNs
447 * n+2 .. n+3 length of DN 1
448 * n+4 .. ... Distinguished Name #1
449 * ... .. ... length of DN 2, etc.
450 */
451 if( ( ret = ssl_read_record( ssl ) ) != 0 )
452 {
453 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
454 return( ret );
455 }
456
457 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
458 {
459 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000460 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461 }
462
463 ssl->client_auth = 0;
464 ssl->state++;
465
466 if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
467 ssl->client_auth++;
468
469 SSL_DEBUG_MSG( 3, ( "got %s certificate request",
470 ssl->client_auth ? "a" : "no" ) );
471
472 SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
473
474 return( 0 );
475}
476
477static int ssl_parse_server_hello_done( ssl_context *ssl )
478{
479 int ret;
480
481 SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
482
483 if( ssl->client_auth != 0 )
484 {
485 if( ( ret = ssl_read_record( ssl ) ) != 0 )
486 {
487 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
488 return( ret );
489 }
490
491 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
492 {
493 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000494 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 }
496 }
497
498 if( ssl->in_hslen != 4 ||
499 ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
500 {
501 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000502 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000503 }
504
505 ssl->state++;
506
507 SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
508
509 return( 0 );
510}
511
512static int ssl_write_client_key_exchange( ssl_context *ssl )
513{
514 int ret, i, n;
515
516 SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
517
518 if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +0000519 ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
520 ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 {
Paul Bakker40e46942009-01-03 21:51:57 +0000522#if !defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000524 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000525#else
526 /*
527 * DHM key exchange -- send G^X mod P
528 */
529 n = ssl->dhm_ctx.len;
530
531 ssl->out_msg[4] = (unsigned char)( n >> 8 );
532 ssl->out_msg[5] = (unsigned char)( n );
533 i = 6;
534
535 ret = dhm_make_public( &ssl->dhm_ctx, 256,
536 &ssl->out_msg[i], n,
537 ssl->f_rng, ssl->p_rng );
538 if( ret != 0 )
539 {
540 SSL_DEBUG_RET( 1, "dhm_make_public", ret );
541 return( ret );
542 }
543
544 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X );
545 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
546
547 ssl->pmslen = ssl->dhm_ctx.len;
548
549 if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
550 ssl->premaster,
551 &ssl->pmslen ) ) != 0 )
552 {
553 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
554 return( ret );
555 }
556
557 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K );
558#endif
559 }
560 else
561 {
562 /*
563 * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
564 */
565 ssl->premaster[0] = (unsigned char) ssl->max_major_ver;
566 ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
567 ssl->pmslen = 48;
568
569 for( i = 2; i < ssl->pmslen; i++ )
570 ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
571
572 i = 4;
573 n = ssl->peer_cert->rsa.len;
574
575 if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
576 {
577 i += 2;
578 ssl->out_msg[4] = (unsigned char)( n >> 8 );
579 ssl->out_msg[5] = (unsigned char)( n );
580 }
581
582 ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa, RSA_PUBLIC,
583 ssl->pmslen, ssl->premaster,
584 ssl->out_msg + i );
585 if( ret != 0 )
586 {
587 SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
588 return( ret );
589 }
590 }
591
Paul Bakkerff60ee62010-03-16 21:09:09 +0000592 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
593 {
594 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
595 return( ret );
596 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 ssl->out_msglen = i + n;
599 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
600 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
601
602 ssl->state++;
603
604 if( ( ret = ssl_write_record( ssl ) ) != 0 )
605 {
606 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
607 return( ret );
608 }
609
610 SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
611
612 return( 0 );
613}
614
615static int ssl_write_certificate_verify( ssl_context *ssl )
616{
617 int ret, n;
618 unsigned char hash[36];
619
620 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
621
622 if( ssl->client_auth == 0 )
623 {
624 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
625 ssl->state++;
626 return( 0 );
627 }
628
629 if( ssl->rsa_key == NULL )
630 {
631 SSL_DEBUG_MSG( 1, ( "got no private key" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000632 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 }
634
635 /*
636 * Make an RSA signature of the handshake digests
637 */
638 ssl_calc_verify( ssl, hash );
639
640 n = ssl->rsa_key->len;
641 ssl->out_msg[4] = (unsigned char)( n >> 8 );
642 ssl->out_msg[5] = (unsigned char)( n );
643
Paul Bakkerfc22c442009-07-19 20:36:27 +0000644 if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW,
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 36, hash, ssl->out_msg + 6 ) ) != 0 )
646 {
647 SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret );
648 return( ret );
649 }
650
651 ssl->out_msglen = 6 + n;
652 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
653 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
654
655 ssl->state++;
656
657 if( ( ret = ssl_write_record( ssl ) ) != 0 )
658 {
659 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
660 return( ret );
661 }
662
663 SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
664
665 return( 0 );
666}
667
668/*
669 * SSL handshake -- client side
670 */
671int ssl_handshake_client( ssl_context *ssl )
672{
673 int ret = 0;
674
675 SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
676
677 while( ssl->state != SSL_HANDSHAKE_OVER )
678 {
679 SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
680
681 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
682 break;
683
684 switch( ssl->state )
685 {
686 case SSL_HELLO_REQUEST:
687 ssl->state = SSL_CLIENT_HELLO;
688 break;
689
690 /*
691 * ==> ClientHello
692 */
693 case SSL_CLIENT_HELLO:
694 ret = ssl_write_client_hello( ssl );
695 break;
696
697 /*
698 * <== ServerHello
699 * Certificate
700 * ( ServerKeyExchange )
701 * ( CertificateRequest )
702 * ServerHelloDone
703 */
704 case SSL_SERVER_HELLO:
705 ret = ssl_parse_server_hello( ssl );
706 break;
707
708 case SSL_SERVER_CERTIFICATE:
709 ret = ssl_parse_certificate( ssl );
710 break;
711
712 case SSL_SERVER_KEY_EXCHANGE:
713 ret = ssl_parse_server_key_exchange( ssl );
714 break;
715
716 case SSL_CERTIFICATE_REQUEST:
717 ret = ssl_parse_certificate_request( ssl );
718 break;
719
720 case SSL_SERVER_HELLO_DONE:
721 ret = ssl_parse_server_hello_done( ssl );
722 break;
723
724 /*
725 * ==> ( Certificate/Alert )
726 * ClientKeyExchange
727 * ( CertificateVerify )
728 * ChangeCipherSpec
729 * Finished
730 */
731 case SSL_CLIENT_CERTIFICATE:
732 ret = ssl_write_certificate( ssl );
733 break;
734
735 case SSL_CLIENT_KEY_EXCHANGE:
736 ret = ssl_write_client_key_exchange( ssl );
737 break;
738
739 case SSL_CERTIFICATE_VERIFY:
740 ret = ssl_write_certificate_verify( ssl );
741 break;
742
743 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
744 ret = ssl_write_change_cipher_spec( ssl );
745 break;
746
747 case SSL_CLIENT_FINISHED:
748 ret = ssl_write_finished( ssl );
749 break;
750
751 /*
752 * <== ChangeCipherSpec
753 * Finished
754 */
755 case SSL_SERVER_CHANGE_CIPHER_SPEC:
756 ret = ssl_parse_change_cipher_spec( ssl );
757 break;
758
759 case SSL_SERVER_FINISHED:
760 ret = ssl_parse_finished( ssl );
761 break;
762
763 case SSL_FLUSH_BUFFERS:
764 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
765 ssl->state = SSL_HANDSHAKE_OVER;
766 break;
767
768 default:
769 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000770 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000771 }
772
773 if( ret != 0 )
774 break;
775 }
776
777 SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
778
779 return( ret );
780}
781
782#endif