blob: ba1d287abf4227bc7fe34dc2179257d057ac4983 [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;
Paul Bakker2e11f7d2010-07-25 14:24:53 +000051 ssl->max_minor_ver = SSL_MINOR_VERSION_2;
Paul Bakker5121ce52009-01-03 21:22:43 +000052
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
Paul Bakker2e11f7d2010-07-25 14:24:53 +0000211 if( buf[5] > ssl->max_minor_ver )
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 {
213 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000214 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 }
216
217 ssl->minor_ver = buf[5];
218
219 t = ( (time_t) buf[6] << 24 )
220 | ( (time_t) buf[7] << 16 )
221 | ( (time_t) buf[8] << 8 )
222 | ( (time_t) buf[9] );
223
224 memcpy( ssl->randbytes + 32, buf + 6, 32 );
225
226 n = buf[38];
227
228 SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
229 SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
230
231 /*
232 * 38 . 38 session id length
233 * 39 . 38+n session id
234 * 39+n . 40+n chosen cipher
235 * 41+n . 41+n chosen compression alg.
236 * 42+n . 43+n extensions length
237 * 44+n . 44+n+m extensions
238 */
239 if( n < 0 || n > 32 || ssl->in_hslen > 42 + n )
240 {
241 ext_len = ( ( buf[42 + n] << 8 )
242 | ( buf[43 + n] ) ) + 2;
243 }
244 else
245 {
246 ext_len = 0;
247 }
248
249 if( n < 0 || n > 32 || ssl->in_hslen != 42 + n + ext_len )
250 {
251 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000252 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 }
254
255 i = ( buf[39 + n] << 8 ) | buf[40 + n];
256
257 SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
258 SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
259
260 /*
261 * Check if the session can be resumed
262 */
263 if( ssl->resume == 0 || n == 0 ||
264 ssl->session->cipher != i ||
265 ssl->session->length != n ||
266 memcmp( ssl->session->id, buf + 39, n ) != 0 )
267 {
268 ssl->state++;
269 ssl->resume = 0;
270 ssl->session->start = time( NULL );
271 ssl->session->cipher = i;
272 ssl->session->length = n;
273 memcpy( ssl->session->id, buf + 39, n );
274 }
275 else
276 {
277 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
Paul Bakkerff60ee62010-03-16 21:09:09 +0000278
279 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
280 {
281 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
282 return( ret );
283 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 }
285
286 SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
287 ssl->resume ? "a" : "no" ) );
288
289 SSL_DEBUG_MSG( 3, ( "server hello, chosen cipher: %d", i ) );
290 SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
291
292 i = 0;
293 while( 1 )
294 {
295 if( ssl->ciphers[i] == 0 )
296 {
297 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000298 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 }
300
301 if( ssl->ciphers[i++] == ssl->session->cipher )
302 break;
303 }
304
305 if( buf[41 + n] != SSL_COMPRESS_NULL )
306 {
307 SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000308 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309 }
310
311 /* TODO: Process extensions */
312
313 SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
314
315 return( 0 );
316}
317
318static int ssl_parse_server_key_exchange( ssl_context *ssl )
319{
320 int ret, n;
321 unsigned char *p, *end;
322 unsigned char hash[36];
323 md5_context md5;
324 sha1_context sha1;
325
326 SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
327
328 if( ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
Paul Bakker77a43582010-06-15 21:32:46 +0000329 ssl->session->cipher != SSL_EDH_RSA_AES_128_SHA &&
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +0000330 ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
Paul Bakker77a43582010-06-15 21:32:46 +0000331 ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_128_SHA &&
332 ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA)
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 {
334 SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
335 ssl->state++;
336 return( 0 );
337 }
338
Paul Bakker40e46942009-01-03 21:51:57 +0000339#if !defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000341 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342#else
343 if( ( ret = ssl_read_record( ssl ) ) != 0 )
344 {
345 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
346 return( ret );
347 }
348
349 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
350 {
351 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000352 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353 }
354
355 if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
356 {
357 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000358 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000359 }
360
361 /*
362 * Ephemeral DH parameters:
363 *
364 * struct {
365 * opaque dh_p<1..2^16-1>;
366 * opaque dh_g<1..2^16-1>;
367 * opaque dh_Ys<1..2^16-1>;
368 * } ServerDHParams;
369 */
370 p = ssl->in_msg + 4;
371 end = ssl->in_msg + ssl->in_hslen;
372
373 if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
374 {
375 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000376 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000377 }
378
379 if( (int)( end - p ) != ssl->peer_cert->rsa.len )
380 {
381 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000382 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 }
384
385 if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256 )
386 {
387 SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000388 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 }
390
391 SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P );
392 SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G );
393 SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
394
395 /*
396 * digitally-signed struct {
397 * opaque md5_hash[16];
398 * opaque sha_hash[20];
399 * };
400 *
401 * md5_hash
402 * MD5(ClientHello.random + ServerHello.random
403 * + ServerParams);
404 * sha_hash
405 * SHA(ClientHello.random + ServerHello.random
406 * + ServerParams);
407 */
408 n = ssl->in_hslen - ( end - p ) - 6;
409
410 md5_starts( &md5 );
411 md5_update( &md5, ssl->randbytes, 64 );
412 md5_update( &md5, ssl->in_msg + 4, n );
413 md5_finish( &md5, hash );
414
415 sha1_starts( &sha1 );
416 sha1_update( &sha1, ssl->randbytes, 64 );
417 sha1_update( &sha1, ssl->in_msg + 4, n );
418 sha1_finish( &sha1, hash + 16 );
419
420 SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
421
422 if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
Paul Bakkerfc22c442009-07-19 20:36:27 +0000423 SIG_RSA_RAW, 36, hash, p ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 {
425 SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
426 return( ret );
427 }
428
429 ssl->state++;
430
431 SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
432
433 return( 0 );
434#endif
435}
436
437static int ssl_parse_certificate_request( ssl_context *ssl )
438{
439 int ret;
440
441 SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
442
443 /*
444 * 0 . 0 handshake type
445 * 1 . 3 handshake length
446 * 4 . 5 SSL version
447 * 6 . 6 cert type count
448 * 7 .. n-1 cert types
449 * n .. n+1 length of all DNs
450 * n+2 .. n+3 length of DN 1
451 * n+4 .. ... Distinguished Name #1
452 * ... .. ... length of DN 2, etc.
453 */
454 if( ( ret = ssl_read_record( ssl ) ) != 0 )
455 {
456 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
457 return( ret );
458 }
459
460 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
461 {
462 SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000463 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 }
465
466 ssl->client_auth = 0;
467 ssl->state++;
468
469 if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
470 ssl->client_auth++;
471
472 SSL_DEBUG_MSG( 3, ( "got %s certificate request",
473 ssl->client_auth ? "a" : "no" ) );
474
475 SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
476
477 return( 0 );
478}
479
480static int ssl_parse_server_hello_done( ssl_context *ssl )
481{
482 int ret;
483
484 SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
485
486 if( ssl->client_auth != 0 )
487 {
488 if( ( ret = ssl_read_record( ssl ) ) != 0 )
489 {
490 SSL_DEBUG_RET( 1, "ssl_read_record", ret );
491 return( ret );
492 }
493
494 if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
495 {
496 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000497 return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 }
499 }
500
501 if( ssl->in_hslen != 4 ||
502 ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
503 {
504 SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000505 return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 }
507
508 ssl->state++;
509
510 SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
511
512 return( 0 );
513}
514
515static int ssl_write_client_key_exchange( ssl_context *ssl )
516{
517 int ret, i, n;
518
519 SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
520
521 if( ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
Paul Bakker77a43582010-06-15 21:32:46 +0000522 ssl->session->cipher == SSL_EDH_RSA_AES_128_SHA ||
Paul Bakkerb5ef0ba2009-01-11 20:25:36 +0000523 ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
Paul Bakker77a43582010-06-15 21:32:46 +0000524 ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_128_SHA ||
525 ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
Paul Bakker5121ce52009-01-03 21:22:43 +0000526 {
Paul Bakker40e46942009-01-03 21:51:57 +0000527#if !defined(POLARSSL_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000529 return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000530#else
531 /*
532 * DHM key exchange -- send G^X mod P
533 */
534 n = ssl->dhm_ctx.len;
535
536 ssl->out_msg[4] = (unsigned char)( n >> 8 );
537 ssl->out_msg[5] = (unsigned char)( n );
538 i = 6;
539
540 ret = dhm_make_public( &ssl->dhm_ctx, 256,
541 &ssl->out_msg[i], n,
542 ssl->f_rng, ssl->p_rng );
543 if( ret != 0 )
544 {
545 SSL_DEBUG_RET( 1, "dhm_make_public", ret );
546 return( ret );
547 }
548
549 SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X );
550 SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
551
552 ssl->pmslen = ssl->dhm_ctx.len;
553
554 if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
555 ssl->premaster,
556 &ssl->pmslen ) ) != 0 )
557 {
558 SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
559 return( ret );
560 }
561
562 SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K );
563#endif
564 }
565 else
566 {
567 /*
568 * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
569 */
570 ssl->premaster[0] = (unsigned char) ssl->max_major_ver;
571 ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
572 ssl->pmslen = 48;
573
574 for( i = 2; i < ssl->pmslen; i++ )
575 ssl->premaster[i] = (unsigned char) ssl->f_rng( ssl->p_rng );
576
577 i = 4;
578 n = ssl->peer_cert->rsa.len;
579
580 if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
581 {
582 i += 2;
583 ssl->out_msg[4] = (unsigned char)( n >> 8 );
584 ssl->out_msg[5] = (unsigned char)( n );
585 }
586
587 ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa, RSA_PUBLIC,
588 ssl->pmslen, ssl->premaster,
589 ssl->out_msg + i );
590 if( ret != 0 )
591 {
592 SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
593 return( ret );
594 }
595 }
596
Paul Bakkerff60ee62010-03-16 21:09:09 +0000597 if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
598 {
599 SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
600 return( ret );
601 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
603 ssl->out_msglen = i + n;
604 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
605 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
606
607 ssl->state++;
608
609 if( ( ret = ssl_write_record( ssl ) ) != 0 )
610 {
611 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
612 return( ret );
613 }
614
615 SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
616
617 return( 0 );
618}
619
620static int ssl_write_certificate_verify( ssl_context *ssl )
621{
622 int ret, n;
623 unsigned char hash[36];
624
625 SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
626
627 if( ssl->client_auth == 0 )
628 {
629 SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
630 ssl->state++;
631 return( 0 );
632 }
633
634 if( ssl->rsa_key == NULL )
635 {
636 SSL_DEBUG_MSG( 1, ( "got no private key" ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000637 return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 }
639
640 /*
641 * Make an RSA signature of the handshake digests
642 */
643 ssl_calc_verify( ssl, hash );
644
645 n = ssl->rsa_key->len;
646 ssl->out_msg[4] = (unsigned char)( n >> 8 );
647 ssl->out_msg[5] = (unsigned char)( n );
648
Paul Bakkerfc22c442009-07-19 20:36:27 +0000649 if( ( ret = rsa_pkcs1_sign( ssl->rsa_key, RSA_PRIVATE, SIG_RSA_RAW,
Paul Bakker5121ce52009-01-03 21:22:43 +0000650 36, hash, ssl->out_msg + 6 ) ) != 0 )
651 {
652 SSL_DEBUG_RET( 1, "rsa_pkcs1_sign", ret );
653 return( ret );
654 }
655
656 ssl->out_msglen = 6 + n;
657 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
658 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
659
660 ssl->state++;
661
662 if( ( ret = ssl_write_record( ssl ) ) != 0 )
663 {
664 SSL_DEBUG_RET( 1, "ssl_write_record", ret );
665 return( ret );
666 }
667
668 SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
669
670 return( 0 );
671}
672
673/*
674 * SSL handshake -- client side
675 */
676int ssl_handshake_client( ssl_context *ssl )
677{
678 int ret = 0;
679
680 SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
681
682 while( ssl->state != SSL_HANDSHAKE_OVER )
683 {
684 SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
685
686 if( ( ret = ssl_flush_output( ssl ) ) != 0 )
687 break;
688
689 switch( ssl->state )
690 {
691 case SSL_HELLO_REQUEST:
692 ssl->state = SSL_CLIENT_HELLO;
693 break;
694
695 /*
696 * ==> ClientHello
697 */
698 case SSL_CLIENT_HELLO:
699 ret = ssl_write_client_hello( ssl );
700 break;
701
702 /*
703 * <== ServerHello
704 * Certificate
705 * ( ServerKeyExchange )
706 * ( CertificateRequest )
707 * ServerHelloDone
708 */
709 case SSL_SERVER_HELLO:
710 ret = ssl_parse_server_hello( ssl );
711 break;
712
713 case SSL_SERVER_CERTIFICATE:
714 ret = ssl_parse_certificate( ssl );
715 break;
716
717 case SSL_SERVER_KEY_EXCHANGE:
718 ret = ssl_parse_server_key_exchange( ssl );
719 break;
720
721 case SSL_CERTIFICATE_REQUEST:
722 ret = ssl_parse_certificate_request( ssl );
723 break;
724
725 case SSL_SERVER_HELLO_DONE:
726 ret = ssl_parse_server_hello_done( ssl );
727 break;
728
729 /*
730 * ==> ( Certificate/Alert )
731 * ClientKeyExchange
732 * ( CertificateVerify )
733 * ChangeCipherSpec
734 * Finished
735 */
736 case SSL_CLIENT_CERTIFICATE:
737 ret = ssl_write_certificate( ssl );
738 break;
739
740 case SSL_CLIENT_KEY_EXCHANGE:
741 ret = ssl_write_client_key_exchange( ssl );
742 break;
743
744 case SSL_CERTIFICATE_VERIFY:
745 ret = ssl_write_certificate_verify( ssl );
746 break;
747
748 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
749 ret = ssl_write_change_cipher_spec( ssl );
750 break;
751
752 case SSL_CLIENT_FINISHED:
753 ret = ssl_write_finished( ssl );
754 break;
755
756 /*
757 * <== ChangeCipherSpec
758 * Finished
759 */
760 case SSL_SERVER_CHANGE_CIPHER_SPEC:
761 ret = ssl_parse_change_cipher_spec( ssl );
762 break;
763
764 case SSL_SERVER_FINISHED:
765 ret = ssl_parse_finished( ssl );
766 break;
767
768 case SSL_FLUSH_BUFFERS:
769 SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
770 ssl->state = SSL_HANDSHAKE_OVER;
771 break;
772
773 default:
774 SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
Paul Bakker40e46942009-01-03 21:51:57 +0000775 return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 }
777
778 if( ret != 0 )
779 break;
780 }
781
782 SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
783
784 return( ret );
785}
786
787#endif