PolarSSL v1.1.5
ssl_cli.c
Go to the documentation of this file.
1 /*
2  * SSLv3/TLSv1 client-side functions
3  *
4  * Copyright (C) 2006-2010, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * 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 
26 #include "polarssl/config.h"
27 
28 #if defined(POLARSSL_SSL_CLI_C)
29 
30 #include "polarssl/debug.h"
31 #include "polarssl/ssl.h"
32 
33 #if defined(POLARSSL_PKCS11_C)
34 #include "polarssl/pkcs11.h"
35 #endif /* defined(POLARSSL_PKCS11_C) */
36 
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <time.h>
40 
41 static int ssl_write_client_hello( ssl_context *ssl )
42 {
43  int ret;
44  size_t i, n;
45  unsigned char *buf;
46  unsigned char *p;
47  time_t t;
48 
49  SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
50 
53 
54  if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 )
55  {
58  }
59 
60  /*
61  * 0 . 0 handshake type
62  * 1 . 3 handshake length
63  * 4 . 5 highest version supported
64  * 6 . 9 current UNIX time
65  * 10 . 37 random bytes
66  */
67  buf = ssl->out_msg;
68  p = buf + 4;
69 
70  *p++ = (unsigned char) ssl->max_major_ver;
71  *p++ = (unsigned char) ssl->max_minor_ver;
72 
73  SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
74  buf[4], buf[5] ) );
75 
76  t = time( NULL );
77  *p++ = (unsigned char)( t >> 24 );
78  *p++ = (unsigned char)( t >> 16 );
79  *p++ = (unsigned char)( t >> 8 );
80  *p++ = (unsigned char)( t );
81 
82  SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
83 
84  if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 )
85  return( ret );
86 
87  p += 28;
88 
89  memcpy( ssl->randbytes, buf + 6, 32 );
90 
91  SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 );
92 
93  /*
94  * 38 . 38 session id length
95  * 39 . 39+n session id
96  * 40+n . 41+n ciphersuitelist length
97  * 42+n . .. ciphersuitelist
98  * .. . .. compression alg. (0)
99  * .. . .. extensions (unused)
100  */
101  n = ssl->session->length;
102 
103  if( n < 16 || n > 32 || ssl->resume == 0 ||
104  ( ssl->timeout != 0 && t - ssl->session->start > ssl->timeout ) )
105  n = 0;
106 
107  *p++ = (unsigned char) n;
108 
109  for( i = 0; i < n; i++ )
110  *p++ = ssl->session->id[i];
111 
112  SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
113  SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
114 
115  for( n = 0; ssl->ciphersuites[n] != 0; n++ );
116  *p++ = (unsigned char)( n >> 7 );
117  *p++ = (unsigned char)( n << 1 );
118 
119  SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) );
120 
121  for( i = 0; i < n; i++ )
122  {
123  SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d",
124  ssl->ciphersuites[i] ) );
125 
126  *p++ = (unsigned char)( ssl->ciphersuites[i] >> 8 );
127  *p++ = (unsigned char)( ssl->ciphersuites[i] );
128  }
129 
130  SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) );
131  SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", 0 ) );
132 
133  *p++ = 1;
134  *p++ = SSL_COMPRESS_NULL;
135 
136  if ( ssl->hostname != NULL )
137  {
138  SSL_DEBUG_MSG( 3, ( "client hello, server name extension: %s",
139  ssl->hostname ) );
140 
141  *p++ = (unsigned char)( ( (ssl->hostname_len + 9) >> 8 ) & 0xFF );
142  *p++ = (unsigned char)( ( (ssl->hostname_len + 9) ) & 0xFF );
143 
144  *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
145  *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME ) & 0xFF );
146 
147  *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF );
148  *p++ = (unsigned char)( ( (ssl->hostname_len + 5) ) & 0xFF );
149 
150  *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF );
151  *p++ = (unsigned char)( ( (ssl->hostname_len + 3) ) & 0xFF );
152 
153  *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
154  *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF );
155  *p++ = (unsigned char)( ( ssl->hostname_len ) & 0xFF );
156 
157  memcpy( p, ssl->hostname, ssl->hostname_len );
158 
159  p += ssl->hostname_len;
160  }
161 
162  ssl->out_msglen = p - buf;
164  ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
165 
166  ssl->state++;
167 
168  if( ( ret = ssl_write_record( ssl ) ) != 0 )
169  {
170  SSL_DEBUG_RET( 1, "ssl_write_record", ret );
171  return( ret );
172  }
173 
174  SSL_DEBUG_MSG( 2, ( "<= write client hello" ) );
175 
176  return( 0 );
177 }
178 
179 static int ssl_parse_server_hello( ssl_context *ssl )
180 {
181 #if defined(POLARSSL_DEBUG_MSG) && defined(POLARSSL_DEBUG_C)
182  time_t t;
183 #endif
184  int ret, i;
185  size_t n;
186  int ext_len;
187  unsigned char *buf;
188 
189  SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
190 
191  /*
192  * 0 . 0 handshake type
193  * 1 . 3 handshake length
194  * 4 . 5 protocol version
195  * 6 . 9 UNIX time()
196  * 10 . 37 random bytes
197  */
198  buf = ssl->in_msg;
199 
200  if( ( ret = ssl_read_record( ssl ) ) != 0 )
201  {
202  SSL_DEBUG_RET( 1, "ssl_read_record", ret );
203  return( ret );
204  }
205 
206  if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
207  {
208  SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
210  }
211 
212  SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
213  buf[4], buf[5] ) );
214 
215  if( ssl->in_hslen < 42 ||
216  buf[0] != SSL_HS_SERVER_HELLO ||
217  buf[4] != SSL_MAJOR_VERSION_3 )
218  {
219  SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
221  }
222 
223  if( buf[5] > ssl->max_minor_ver )
224  {
225  SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
227  }
228 
229  ssl->minor_ver = buf[5];
230 
231 #if defined(POLARSSL_DEBUG_MSG) && defined(POLARSSL_DEBUG_C)
232  t = ( (time_t) buf[6] << 24 )
233  | ( (time_t) buf[7] << 16 )
234  | ( (time_t) buf[8] << 8 )
235  | ( (time_t) buf[9] );
236 #endif
237 
238  memcpy( ssl->randbytes + 32, buf + 6, 32 );
239 
240  n = buf[38];
241 
242  SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
243  SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
244 
245  /*
246  * 38 . 38 session id length
247  * 39 . 38+n session id
248  * 39+n . 40+n chosen ciphersuite
249  * 41+n . 41+n chosen compression alg.
250  * 42+n . 43+n extensions length
251  * 44+n . 44+n+m extensions
252  */
253  if( n > 32 || ssl->in_hslen > 42 + n )
254  {
255  ext_len = ( ( buf[42 + n] << 8 )
256  | ( buf[43 + n] ) ) + 2;
257  }
258  else
259  {
260  ext_len = 0;
261  }
262 
263  if( n > 32 || ssl->in_hslen != 42 + n + ext_len )
264  {
265  SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
267  }
268 
269  i = ( buf[39 + n] << 8 ) | buf[40 + n];
270 
271  SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
272  SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
273 
274  /*
275  * Check if the session can be resumed
276  */
277  if( ssl->resume == 0 || n == 0 ||
278  ssl->session->ciphersuite != i ||
279  ssl->session->length != n ||
280  memcmp( ssl->session->id, buf + 39, n ) != 0 )
281  {
282  ssl->state++;
283  ssl->resume = 0;
284  ssl->session->start = time( NULL );
285  ssl->session->ciphersuite = i;
286  ssl->session->length = n;
287  memcpy( ssl->session->id, buf + 39, n );
288  }
289  else
290  {
292 
293  if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
294  {
295  SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
296  return( ret );
297  }
298  }
299 
300  SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
301  ssl->resume ? "a" : "no" ) );
302 
303  SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) );
304  SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) );
305 
306  i = 0;
307  while( 1 )
308  {
309  if( ssl->ciphersuites[i] == 0 )
310  {
311  SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
313  }
314 
315  if( ssl->ciphersuites[i++] == ssl->session->ciphersuite )
316  break;
317  }
318 
319  if( buf[41 + n] != SSL_COMPRESS_NULL )
320  {
321  SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
323  }
324 
325  /* TODO: Process extensions */
326 
327  SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) );
328 
329  return( 0 );
330 }
331 
332 static int ssl_parse_server_key_exchange( ssl_context *ssl )
333 {
334 #if defined(POLARSSL_DHM_C)
335  int ret;
336  size_t n;
337  unsigned char *p, *end;
338  unsigned char hash[36];
341 #endif
342 
343  SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
344 
350  {
351  SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
352  ssl->state++;
353  return( 0 );
354  }
355 
356 #if !defined(POLARSSL_DHM_C)
357  SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
359 #else
360  if( ( ret = ssl_read_record( ssl ) ) != 0 )
361  {
362  SSL_DEBUG_RET( 1, "ssl_read_record", ret );
363  return( ret );
364  }
365 
366  if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
367  {
368  SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
370  }
371 
372  if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
373  {
374  SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
376  }
377 
378  /*
379  * Ephemeral DH parameters:
380  *
381  * struct {
382  * opaque dh_p<1..2^16-1>;
383  * opaque dh_g<1..2^16-1>;
384  * opaque dh_Ys<1..2^16-1>;
385  * } ServerDHParams;
386  */
387  p = ssl->in_msg + 4;
388  end = ssl->in_msg + ssl->in_hslen;
389 
390  if( ( ret = dhm_read_params( &ssl->dhm_ctx, &p, end ) ) != 0 )
391  {
392  SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
394  }
395 
396  if( (unsigned int)( end - p ) != ssl->peer_cert->rsa.len )
397  {
398  SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
400  }
401 
402  if( ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 512 )
403  {
404  SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
406  }
407 
408  SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->dhm_ctx.P );
409  SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->dhm_ctx.G );
410  SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->dhm_ctx.GY );
411 
412  /*
413  * digitally-signed struct {
414  * opaque md5_hash[16];
415  * opaque sha_hash[20];
416  * };
417  *
418  * md5_hash
419  * MD5(ClientHello.random + ServerHello.random
420  * + ServerParams);
421  * sha_hash
422  * SHA(ClientHello.random + ServerHello.random
423  * + ServerParams);
424  */
425  n = ssl->in_hslen - ( end - p ) - 6;
426 
427  md5_starts( &md5 );
428  md5_update( &md5, ssl->randbytes, 64 );
429  md5_update( &md5, ssl->in_msg + 4, n );
430  md5_finish( &md5, hash );
431 
432  sha1_starts( &sha1 );
433  sha1_update( &sha1, ssl->randbytes, 64 );
434  sha1_update( &sha1, ssl->in_msg + 4, n );
435  sha1_finish( &sha1, hash + 16 );
436 
437  SSL_DEBUG_BUF( 3, "parameters hash", hash, 36 );
438 
439  if( ( ret = rsa_pkcs1_verify( &ssl->peer_cert->rsa, RSA_PUBLIC,
440  SIG_RSA_RAW, 36, hash, p ) ) != 0 )
441  {
442  SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
443  return( ret );
444  }
445 
446  ssl->state++;
447 
448  SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
449 
450  return( 0 );
451 #endif
452 }
453 
454 static int ssl_parse_certificate_request( ssl_context *ssl )
455 {
456  int ret;
457 
458  SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
459 
460  /*
461  * 0 . 0 handshake type
462  * 1 . 3 handshake length
463  * 4 . 5 SSL version
464  * 6 . 6 cert type count
465  * 7 .. n-1 cert types
466  * n .. n+1 length of all DNs
467  * n+2 .. n+3 length of DN 1
468  * n+4 .. ... Distinguished Name #1
469  * ... .. ... length of DN 2, etc.
470  */
471  if( ( ret = ssl_read_record( ssl ) ) != 0 )
472  {
473  SSL_DEBUG_RET( 1, "ssl_read_record", ret );
474  return( ret );
475  }
476 
477  if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
478  {
479  SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
481  }
482 
483  ssl->client_auth = 0;
484  ssl->state++;
485 
486  if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST )
487  ssl->client_auth++;
488 
489  SSL_DEBUG_MSG( 3, ( "got %s certificate request",
490  ssl->client_auth ? "a" : "no" ) );
491 
492  SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
493 
494  return( 0 );
495 }
496 
497 static int ssl_parse_server_hello_done( ssl_context *ssl )
498 {
499  int ret;
500 
501  SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
502 
503  if( ssl->client_auth != 0 )
504  {
505  if( ( ret = ssl_read_record( ssl ) ) != 0 )
506  {
507  SSL_DEBUG_RET( 1, "ssl_read_record", ret );
508  return( ret );
509  }
510 
511  if( ssl->in_msgtype != SSL_MSG_HANDSHAKE )
512  {
513  SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
515  }
516  }
517 
518  if( ssl->in_hslen != 4 ||
519  ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
520  {
521  SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) );
523  }
524 
525  ssl->state++;
526 
527  SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) );
528 
529  return( 0 );
530 }
531 
532 static int ssl_write_client_key_exchange( ssl_context *ssl )
533 {
534  int ret;
535  size_t i, n;
536 
537  SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
538 
544  {
545 #if !defined(POLARSSL_DHM_C)
546  SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
548 #else
549  /*
550  * DHM key exchange -- send G^X mod P
551  */
552  n = ssl->dhm_ctx.len;
553 
554  ssl->out_msg[4] = (unsigned char)( n >> 8 );
555  ssl->out_msg[5] = (unsigned char)( n );
556  i = 6;
557 
558  ret = dhm_make_public( &ssl->dhm_ctx, 256,
559  &ssl->out_msg[i], n,
560  ssl->f_rng, ssl->p_rng );
561  if( ret != 0 )
562  {
563  SSL_DEBUG_RET( 1, "dhm_make_public", ret );
564  return( ret );
565  }
566 
567  SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->dhm_ctx.X );
568  SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->dhm_ctx.GX );
569 
570  ssl->pmslen = ssl->dhm_ctx.len;
571 
572  if( ( ret = dhm_calc_secret( &ssl->dhm_ctx,
573  ssl->premaster,
574  &ssl->pmslen ) ) != 0 )
575  {
576  SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
577  return( ret );
578  }
579 
580  SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->dhm_ctx.K );
581 #endif
582  }
583  else
584  {
585  /*
586  * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
587  */
588  ssl->premaster[0] = (unsigned char) ssl->max_major_ver;
589  ssl->premaster[1] = (unsigned char) ssl->max_minor_ver;
590  ssl->pmslen = 48;
591 
592  ret = ssl->f_rng( ssl->p_rng, ssl->premaster + 2, ssl->pmslen - 2 );
593  if( ret != 0 )
594  return( ret );
595 
596  i = 4;
597  n = ssl->peer_cert->rsa.len;
598 
599  if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
600  {
601  i += 2;
602  ssl->out_msg[4] = (unsigned char)( n >> 8 );
603  ssl->out_msg[5] = (unsigned char)( n );
604  }
605 
606  ret = rsa_pkcs1_encrypt( &ssl->peer_cert->rsa,
607  ssl->f_rng, ssl->p_rng,
608  RSA_PUBLIC,
609  ssl->pmslen, ssl->premaster,
610  ssl->out_msg + i );
611  if( ret != 0 )
612  {
613  SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
614  return( ret );
615  }
616  }
617 
618  if( ( ret = ssl_derive_keys( ssl ) ) != 0 )
619  {
620  SSL_DEBUG_RET( 1, "ssl_derive_keys", ret );
621  return( ret );
622  }
623 
624  ssl->out_msglen = i + n;
627 
628  ssl->state++;
629 
630  if( ( ret = ssl_write_record( ssl ) ) != 0 )
631  {
632  SSL_DEBUG_RET( 1, "ssl_write_record", ret );
633  return( ret );
634  }
635 
636  SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) );
637 
638  return( 0 );
639 }
640 
641 static int ssl_write_certificate_verify( ssl_context *ssl )
642 {
643  int ret = 0;
644  size_t n = 0;
645  unsigned char hash[36];
646 
647  SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
648 
649  if( ssl->client_auth == 0 || ssl->own_cert == NULL )
650  {
651  SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
652  ssl->state++;
653  return( 0 );
654  }
655 
656  if( ssl->rsa_key == NULL )
657  {
658 #if defined(POLARSSL_PKCS11_C)
659  if( ssl->pkcs11_key == NULL )
660  {
661 #endif /* defined(POLARSSL_PKCS11_C) */
662  SSL_DEBUG_MSG( 1, ( "got no private key" ) );
664 #if defined(POLARSSL_PKCS11_C)
665  }
666 #endif /* defined(POLARSSL_PKCS11_C) */
667  }
668 
669  /*
670  * Make an RSA signature of the handshake digests
671  */
672  ssl_calc_verify( ssl, hash );
673 
674  if ( ssl->rsa_key )
675  n = ssl->rsa_key->len;
676 #if defined(POLARSSL_PKCS11_C)
677  else
678  n = ssl->pkcs11_key->len;
679 #endif /* defined(POLARSSL_PKCS11_C) */
680 
681  ssl->out_msg[4] = (unsigned char)( n >> 8 );
682  ssl->out_msg[5] = (unsigned char)( n );
683 
684  if( ssl->rsa_key )
685  {
686  ret = rsa_pkcs1_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng,
688  36, hash, ssl->out_msg + 6 );
689  } else {
690 #if defined(POLARSSL_PKCS11_C)
691  ret = pkcs11_sign( ssl->pkcs11_key, RSA_PRIVATE, SIG_RSA_RAW,
692  36, hash, ssl->out_msg + 6 );
693 #endif /* defined(POLARSSL_PKCS11_C) */
694  }
695 
696  if (ret != 0)
697  {
698  SSL_DEBUG_RET( 1, "pkcs1_sign", ret );
699  return( ret );
700  }
701 
702  ssl->out_msglen = 6 + n;
705 
706  ssl->state++;
707 
708  if( ( ret = ssl_write_record( ssl ) ) != 0 )
709  {
710  SSL_DEBUG_RET( 1, "ssl_write_record", ret );
711  return( ret );
712  }
713 
714  SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) );
715 
716  return( 0 );
717 }
718 
719 /*
720  * SSL handshake -- client side
721  */
723 {
724  int ret = 0;
725 
726  SSL_DEBUG_MSG( 2, ( "=> handshake client" ) );
727 
728  while( ssl->state != SSL_HANDSHAKE_OVER )
729  {
730  SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
731 
732  if( ( ret = ssl_flush_output( ssl ) ) != 0 )
733  break;
734 
735  switch( ssl->state )
736  {
737  case SSL_HELLO_REQUEST:
738  ssl->state = SSL_CLIENT_HELLO;
739  break;
740 
741  /*
742  * ==> ClientHello
743  */
744  case SSL_CLIENT_HELLO:
745  ret = ssl_write_client_hello( ssl );
746  break;
747 
748  /*
749  * <== ServerHello
750  * Certificate
751  * ( ServerKeyExchange )
752  * ( CertificateRequest )
753  * ServerHelloDone
754  */
755  case SSL_SERVER_HELLO:
756  ret = ssl_parse_server_hello( ssl );
757  break;
758 
760  ret = ssl_parse_certificate( ssl );
761  break;
762 
764  ret = ssl_parse_server_key_exchange( ssl );
765  break;
766 
768  ret = ssl_parse_certificate_request( ssl );
769  break;
770 
772  ret = ssl_parse_server_hello_done( ssl );
773  break;
774 
775  /*
776  * ==> ( Certificate/Alert )
777  * ClientKeyExchange
778  * ( CertificateVerify )
779  * ChangeCipherSpec
780  * Finished
781  */
783  ret = ssl_write_certificate( ssl );
784  break;
785 
787  ret = ssl_write_client_key_exchange( ssl );
788  break;
789 
791  ret = ssl_write_certificate_verify( ssl );
792  break;
793 
795  ret = ssl_write_change_cipher_spec( ssl );
796  break;
797 
798  case SSL_CLIENT_FINISHED:
799  ret = ssl_write_finished( ssl );
800  break;
801 
802  /*
803  * <== ChangeCipherSpec
804  * Finished
805  */
807  ret = ssl_parse_change_cipher_spec( ssl );
808  break;
809 
810  case SSL_SERVER_FINISHED:
811  ret = ssl_parse_finished( ssl );
812  break;
813 
814  case SSL_FLUSH_BUFFERS:
815  SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
816  ssl->state = SSL_HANDSHAKE_OVER;
817  break;
818 
819  default:
820  SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) );
822  }
823 
824  if( ret != 0 )
825  break;
826  }
827 
828  SSL_DEBUG_MSG( 2, ( "<= handshake client" ) );
829 
830  return( ret );
831 }
832 
833 #endif