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