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