ssl_tls: fix format warning in ssl_parse_certificate() on x86_64
[tropicssl.git] / library / ssl_cli.c
blob6dd09c8d0ea0898470c88de912fc584d1b4a5f53
1 /*
2 * SSLv3/TLSv1 client-side functions
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * * Neither the names of PolarSSL or XySSL nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "tropicssl/config.h"
38 #if defined(TROPICSSL_SSL_CLI_C)
40 #include "tropicssl/debug.h"
41 #include "tropicssl/ssl.h"
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <time.h>
48 static int ssl_write_client_hello(ssl_context * ssl)
50 int ret, i, n;
51 unsigned char *buf;
52 unsigned char *p;
53 time_t t;
55 SSL_DEBUG_MSG(2, ("=> write client hello"));
57 ssl->major_ver = SSL_MAJOR_VERSION_3;
58 ssl->minor_ver = SSL_MINOR_VERSION_0;
60 ssl->max_major_ver = SSL_MAJOR_VERSION_3;
61 ssl->max_minor_ver = SSL_MINOR_VERSION_1;
64 * 0 . 0 handshake type
65 * 1 . 3 handshake length
66 * 4 . 5 highest version supported
67 * 6 . 9 current UNIX time
68 * 10 . 37 random bytes
70 buf = ssl->out_msg;
71 p = buf + 4;
73 *p++ = (unsigned char)ssl->max_major_ver;
74 *p++ = (unsigned char)ssl->max_minor_ver;
76 SSL_DEBUG_MSG(3, ("client hello, max version: [%d:%d]",
77 buf[4], buf[5]));
79 t = time(NULL);
80 *p++ = (unsigned char)(t >> 24);
81 *p++ = (unsigned char)(t >> 16);
82 *p++ = (unsigned char)(t >> 8);
83 *p++ = (unsigned char)(t);
85 SSL_DEBUG_MSG(3, ("client hello, current time: %lu", t));
87 for (i = 28; i > 0; i--)
88 *p++ = (unsigned char)ssl->f_rng(ssl->p_rng);
90 memcpy(ssl->randbytes, buf + 6, 32);
92 SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 6, 32);
95 * 38 . 38 session id length
96 * 39 . 39+n session id
97 * 40+n . 41+n cipherlist length
98 * 42+n . .. cipherlist
99 * .. . .. compression alg. (0)
100 * .. . .. extensions (unused)
102 n = ssl->session->length;
104 if (n < 16 || n > 32 || ssl->resume == 0 ||
105 t - ssl->session->start > ssl->timeout)
106 n = 0;
108 *p++ = (unsigned char)n;
110 for (i = 0; i < n; i++)
111 *p++ = ssl->session->id[i];
113 SSL_DEBUG_MSG(3, ("client hello, session id len.: %d", n));
114 SSL_DEBUG_BUF(3, "client hello, session id", buf + 39, n);
116 for (n = 0; ssl->ciphers[n] != 0; n++) ;
117 *p++ = (unsigned char)(n >> 7);
118 *p++ = (unsigned char)(n << 1);
120 SSL_DEBUG_MSG(3, ("client hello, got %d ciphers", n));
122 for (i = 0; i < n; i++) {
123 SSL_DEBUG_MSG(3, ("client hello, add cipher: %2d",
124 ssl->ciphers[i]));
126 *p++ = (unsigned char)(ssl->ciphers[i] >> 8);
127 *p++ = (unsigned char)(ssl->ciphers[i]);
130 SSL_DEBUG_MSG(3, ("client hello, compress len.: %d", 1));
131 SSL_DEBUG_MSG(3, ("client hello, compress alg.: %d", 0));
133 *p++ = 1;
134 *p++ = SSL_COMPRESS_NULL;
136 if (ssl->hostname != NULL) {
137 SSL_DEBUG_MSG(3, ("client hello, server name extension: %s",
138 ssl->hostname));
140 *p++ = (unsigned char)(((ssl->hostname_len + 9) >> 8) & 0xFF);
141 *p++ = (unsigned char)(((ssl->hostname_len + 9)) & 0xFF);
143 *p++ = (unsigned char)((TLS_EXT_SERVERNAME >> 8) & 0xFF);
144 *p++ = (unsigned char)((TLS_EXT_SERVERNAME) & 0xFF);
146 *p++ = (unsigned char)(((ssl->hostname_len + 5) >> 8) & 0xFF);
147 *p++ = (unsigned char)(((ssl->hostname_len + 5)) & 0xFF);
149 *p++ = (unsigned char)(((ssl->hostname_len + 3) >> 8) & 0xFF);
150 *p++ = (unsigned char)(((ssl->hostname_len + 3)) & 0xFF);
152 *p++ = (unsigned char)((TLS_EXT_SERVERNAME_HOSTNAME) & 0xFF);
153 *p++ = (unsigned char)((ssl->hostname_len >> 8) & 0xFF);
154 *p++ = (unsigned char)((ssl->hostname_len) & 0xFF);
156 memcpy(p, ssl->hostname, ssl->hostname_len);
158 p += ssl->hostname_len;
161 ssl->out_msglen = p - buf;
162 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
163 ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
165 ssl->state++;
167 if ((ret = ssl_write_record(ssl)) != 0) {
168 SSL_DEBUG_RET(1, "ssl_write_record", ret);
169 return (ret);
172 SSL_DEBUG_MSG(2, ("<= write client hello"));
174 return (0);
177 static int ssl_parse_server_hello(ssl_context * ssl)
179 time_t t;
180 int ret, i, n;
181 int ext_len;
182 unsigned char *buf;
184 SSL_DEBUG_MSG(2, ("=> parse server hello"));
187 * 0 . 0 handshake type
188 * 1 . 3 handshake length
189 * 4 . 5 protocol version
190 * 6 . 9 UNIX time()
191 * 10 . 37 random bytes
193 buf = ssl->in_msg;
195 if ((ret = ssl_read_record(ssl)) != 0) {
196 SSL_DEBUG_RET(1, "ssl_read_record", ret);
197 return (ret);
200 if (ssl->in_msgtype != SSL_MSG_HANDSHAKE) {
201 SSL_DEBUG_MSG(1, ("bad server hello message"));
202 return (TROPICSSL_ERR_SSL_UNEXPECTED_MESSAGE);
205 SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]",
206 buf[4], buf[5]));
208 if (ssl->in_hslen < 42 ||
209 buf[0] != SSL_HS_SERVER_HELLO || buf[4] != SSL_MAJOR_VERSION_3) {
210 SSL_DEBUG_MSG(1, ("bad server hello message"));
211 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_HELLO);
214 if (buf[5] != SSL_MINOR_VERSION_0 && buf[5] != SSL_MINOR_VERSION_1) {
215 SSL_DEBUG_MSG(1, ("bad server hello message"));
216 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_HELLO);
219 ssl->minor_ver = buf[5];
221 t = ((time_t) buf[6] << 24)
222 | ((time_t) buf[7] << 16)
223 | ((time_t) buf[8] << 8)
224 | ((time_t) buf[9]);
226 memcpy(ssl->randbytes + 32, buf + 6, 32);
228 n = buf[38];
230 SSL_DEBUG_MSG(3, ("server hello, current time: %lu", t));
231 SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32);
234 * 38 . 38 session id length
235 * 39 . 38+n session id
236 * 39+n . 40+n chosen cipher
237 * 41+n . 41+n chosen compression alg.
238 * 42+n . 43+n extensions length
239 * 44+n . 44+n+m extensions
241 if (n < 0 || n > 32 || ssl->in_hslen > 42 + n) {
242 ext_len = ((buf[42 + n] << 8)
243 | (buf[43 + n])) + 2;
244 } else {
245 ext_len = 0;
248 if (n < 0 || n > 32 || ssl->in_hslen != 42 + n + ext_len) {
249 SSL_DEBUG_MSG(1, ("bad server hello message"));
250 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_HELLO);
253 i = (buf[39 + n] << 8) | buf[40 + n];
255 SSL_DEBUG_MSG(3, ("server hello, session id len.: %d", n));
256 SSL_DEBUG_BUF(3, "server hello, session id", buf + 39, n);
259 * Check if the session can be resumed
261 if (ssl->resume == 0 || n == 0 ||
262 ssl->session->cipher != i ||
263 ssl->session->length != n ||
264 memcmp(ssl->session->id, buf + 39, n) != 0) {
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 } else {
272 ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC;
273 ssl_derive_keys(ssl);
276 SSL_DEBUG_MSG(3, ("%s session has been resumed",
277 ssl->resume ? "a" : "no"));
279 SSL_DEBUG_MSG(3, ("server hello, chosen cipher: %d", i));
280 SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d", buf[41 + n]));
282 i = 0;
283 while (1) {
284 if (ssl->ciphers[i] == 0) {
285 SSL_DEBUG_MSG(1, ("bad server hello message"));
286 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_HELLO);
289 if (ssl->ciphers[i++] == ssl->session->cipher)
290 break;
293 if (buf[41 + n] != SSL_COMPRESS_NULL) {
294 SSL_DEBUG_MSG(1, ("bad server hello message"));
295 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_HELLO);
298 /* TODO: Process extensions */
300 SSL_DEBUG_MSG(2, ("<= parse server hello"));
302 return (0);
305 static int ssl_parse_server_key_exchange(ssl_context * ssl)
307 int ret, n;
308 unsigned char *p, *end;
309 unsigned char hash[36];
310 md5_context md5_ctx;
311 sha1_context sha1_ctx;
313 SSL_DEBUG_MSG(2, ("=> parse server key exchange"));
315 if (ssl->session->cipher != SSL_EDH_RSA_DES_168_SHA &&
316 ssl->session->cipher != SSL_EDH_RSA_AES_256_SHA &&
317 ssl->session->cipher != SSL_EDH_RSA_CAMELLIA_256_SHA) {
318 SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
319 ssl->state++;
320 return (0);
322 #if !defined(TROPICSSL_DHM_C)
323 SSL_DEBUG_MSG(1, ("support for dhm in not available"));
324 return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
325 #else
326 if ((ret = ssl_read_record(ssl)) != 0) {
327 SSL_DEBUG_RET(1, "ssl_read_record", ret);
328 return (ret);
331 if (ssl->in_msgtype != SSL_MSG_HANDSHAKE) {
332 SSL_DEBUG_MSG(1, ("bad server key exchange message"));
333 return (TROPICSSL_ERR_SSL_UNEXPECTED_MESSAGE);
336 if (ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE) {
337 SSL_DEBUG_MSG(1, ("bad server key exchange message"));
338 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE);
342 * Ephemeral DH parameters:
344 * struct {
345 * opaque dh_p<1..2^16-1>;
346 * opaque dh_g<1..2^16-1>;
347 * opaque dh_Ys<1..2^16-1>;
348 * } ServerDHParams;
350 p = ssl->in_msg + 4;
351 end = ssl->in_msg + ssl->in_hslen;
353 if ((ret = dhm_read_params(&ssl->dhm_ctx, &p, end)) != 0) {
354 SSL_DEBUG_MSG(1, ("bad server key exchange message"));
355 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE);
358 if ((int)(end - p) != ssl->peer_cert->rsa.len) {
359 SSL_DEBUG_MSG(1, ("bad server key exchange message"));
360 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE);
363 if (ssl->dhm_ctx.len < 64 || ssl->dhm_ctx.len > 256) {
364 SSL_DEBUG_MSG(1, ("bad server key exchange message"));
365 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE);
368 SSL_DEBUG_MPI(3, "DHM: P ", &ssl->dhm_ctx.P);
369 SSL_DEBUG_MPI(3, "DHM: G ", &ssl->dhm_ctx.G);
370 SSL_DEBUG_MPI(3, "DHM: GY", &ssl->dhm_ctx.GY);
373 * digitally-signed struct {
374 * opaque md5_hash[16];
375 * opaque sha_hash[20];
376 * };
378 * md5_hash
379 * MD5(ClientHello.random + ServerHello.random
380 * + ServerParams);
381 * sha_hash
382 * SHA(ClientHello.random + ServerHello.random
383 * + ServerParams);
385 n = ssl->in_hslen - (end - p) - 6;
387 md5_starts(&md5_ctx);
388 md5_update(&md5_ctx, ssl->randbytes, 64);
389 md5_update(&md5_ctx, ssl->in_msg + 4, n);
390 md5_finish(&md5_ctx, hash);
392 sha1_starts(&sha1_ctx);
393 sha1_update(&sha1_ctx, ssl->randbytes, 64);
394 sha1_update(&sha1_ctx, ssl->in_msg + 4, n);
395 sha1_finish(&sha1_ctx, hash + 16);
397 SSL_DEBUG_BUF(3, "parameters hash", hash, 36);
399 if ((ret = rsa_pkcs1_verify(&ssl->peer_cert->rsa, RSA_PUBLIC,
400 RSA_RAW, 36, hash, p)) != 0) {
401 SSL_DEBUG_RET(1, "rsa_pkcs1_verify", ret);
402 return (ret);
405 ssl->state++;
407 SSL_DEBUG_MSG(2, ("<= parse server key exchange"));
409 return (0);
410 #endif
413 static int ssl_parse_certificate_request(ssl_context * ssl)
415 int ret;
417 SSL_DEBUG_MSG(2, ("=> parse certificate request"));
420 * 0 . 0 handshake type
421 * 1 . 3 handshake length
422 * 4 . 5 SSL version
423 * 6 . 6 cert type count
424 * 7 .. n-1 cert types
425 * n .. n+1 length of all DNs
426 * n+2 .. n+3 length of DN 1
427 * n+4 .. ... Distinguished Name #1
428 * ... .. ... length of DN 2, etc.
430 if ((ret = ssl_read_record(ssl)) != 0) {
431 SSL_DEBUG_RET(1, "ssl_read_record", ret);
432 return (ret);
435 if (ssl->in_msgtype != SSL_MSG_HANDSHAKE) {
436 SSL_DEBUG_MSG(1, ("bad certificate request message"));
437 return (TROPICSSL_ERR_SSL_UNEXPECTED_MESSAGE);
440 ssl->client_auth = 0;
441 ssl->state++;
443 if (ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST)
444 ssl->client_auth++;
446 SSL_DEBUG_MSG(3, ("got %s certificate request",
447 ssl->client_auth ? "a" : "no"));
449 SSL_DEBUG_MSG(2, ("<= parse certificate request"));
451 return (0);
454 static int ssl_parse_server_hello_done(ssl_context * ssl)
456 int ret;
458 SSL_DEBUG_MSG(2, ("=> parse server hello done"));
460 if (ssl->client_auth != 0) {
461 if ((ret = ssl_read_record(ssl)) != 0) {
462 SSL_DEBUG_RET(1, "ssl_read_record", ret);
463 return (ret);
466 if (ssl->in_msgtype != SSL_MSG_HANDSHAKE) {
467 SSL_DEBUG_MSG(1, ("bad server hello done message"));
468 return (TROPICSSL_ERR_SSL_UNEXPECTED_MESSAGE);
472 if (ssl->in_hslen != 4 || ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE) {
473 SSL_DEBUG_MSG(1, ("bad server hello done message"));
474 return (TROPICSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE);
477 ssl->state++;
479 SSL_DEBUG_MSG(2, ("<= parse server hello done"));
481 return (0);
484 static int ssl_write_client_key_exchange(ssl_context * ssl)
486 int ret, i, n;
488 SSL_DEBUG_MSG(2, ("=> write client key exchange"));
490 if (ssl->session->cipher == SSL_EDH_RSA_DES_168_SHA ||
491 ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA ||
492 ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA) {
493 #if !defined(TROPICSSL_DHM_C)
494 SSL_DEBUG_MSG(1, ("support for dhm in not available"));
495 return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
496 #else
498 * DHM key exchange -- send G^X mod P
500 n = ssl->dhm_ctx.len;
502 ssl->out_msg[4] = (unsigned char)(n >> 8);
503 ssl->out_msg[5] = (unsigned char)(n);
504 i = 6;
506 ret = dhm_make_public(&ssl->dhm_ctx, 256,
507 &ssl->out_msg[i], n,
508 ssl->f_rng, ssl->p_rng);
509 if (ret != 0) {
510 SSL_DEBUG_RET(1, "dhm_make_public", ret);
511 return (ret);
514 SSL_DEBUG_MPI(3, "DHM: X ", &ssl->dhm_ctx.X);
515 SSL_DEBUG_MPI(3, "DHM: GX", &ssl->dhm_ctx.GX);
517 ssl->pmslen = ssl->dhm_ctx.len;
519 if ((ret = dhm_calc_secret(&ssl->dhm_ctx,
520 ssl->premaster,
521 &ssl->pmslen)) != 0) {
522 SSL_DEBUG_RET(1, "dhm_calc_secret", ret);
523 return (ret);
526 SSL_DEBUG_MPI(3, "DHM: K ", &ssl->dhm_ctx.K);
527 #endif
528 } else {
530 * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
532 ssl->premaster[0] = (unsigned char)ssl->max_major_ver;
533 ssl->premaster[1] = (unsigned char)ssl->max_minor_ver;
534 ssl->pmslen = 48;
536 for (i = 2; i < ssl->pmslen; i++)
537 ssl->premaster[i] =
538 (unsigned char)ssl->f_rng(ssl->p_rng);
540 i = 4;
541 n = ssl->peer_cert->rsa.len;
543 if (ssl->minor_ver != SSL_MINOR_VERSION_0) {
544 i += 2;
545 ssl->out_msg[4] = (unsigned char)(n >> 8);
546 ssl->out_msg[5] = (unsigned char)(n);
549 ret = rsa_pkcs1_encrypt(&ssl->peer_cert->rsa, RSA_PUBLIC,
550 ssl->pmslen, ssl->premaster,
551 ssl->out_msg + i);
552 if (ret != 0) {
553 SSL_DEBUG_RET(1, "rsa_pkcs1_encrypt", ret);
554 return (ret);
558 ssl_derive_keys(ssl);
560 ssl->out_msglen = i + n;
561 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
562 ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE;
564 ssl->state++;
566 if ((ret = ssl_write_record(ssl)) != 0) {
567 SSL_DEBUG_RET(1, "ssl_write_record", ret);
568 return (ret);
571 SSL_DEBUG_MSG(2, ("<= write client key exchange"));
573 return (0);
576 static int ssl_write_certificate_verify(ssl_context * ssl)
578 int ret, n;
579 unsigned char hash[36];
581 SSL_DEBUG_MSG(2, ("=> write certificate verify"));
583 if (ssl->client_auth == 0) {
584 SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
585 ssl->state++;
586 return (0);
589 if (ssl->rsa_key == NULL) {
590 SSL_DEBUG_MSG(1, ("got no private key"));
591 return (TROPICSSL_ERR_SSL_PRIVATE_KEY_REQUIRED);
595 * Make an RSA signature of the handshake digests
597 ssl_calc_verify(ssl, hash);
599 n = ssl->rsa_key->len;
600 ssl->out_msg[4] = (unsigned char)(n >> 8);
601 ssl->out_msg[5] = (unsigned char)(n);
603 if ((ret = rsa_pkcs1_sign(ssl->rsa_key, RSA_PRIVATE, RSA_RAW,
604 36, hash, ssl->out_msg + 6)) != 0) {
605 SSL_DEBUG_RET(1, "rsa_pkcs1_sign", ret);
606 return (ret);
609 ssl->out_msglen = 6 + n;
610 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
611 ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;
613 ssl->state++;
615 if ((ret = ssl_write_record(ssl)) != 0) {
616 SSL_DEBUG_RET(1, "ssl_write_record", ret);
617 return (ret);
620 SSL_DEBUG_MSG(2, ("<= write certificate verify"));
622 return (0);
626 * SSL handshake -- client side
628 int ssl_handshake_client(ssl_context * ssl)
630 int ret = 0;
632 SSL_DEBUG_MSG(2, ("=> handshake client"));
634 while (ssl->state != SSL_HANDSHAKE_OVER) {
635 SSL_DEBUG_MSG(2, ("client state: %d", ssl->state));
637 if ((ret = ssl_flush_output(ssl)) != 0)
638 break;
640 switch (ssl->state) {
641 case SSL_HELLO_REQUEST:
642 ssl->state = SSL_CLIENT_HELLO;
643 break;
646 * ==> ClientHello
648 case SSL_CLIENT_HELLO:
649 ret = ssl_write_client_hello(ssl);
650 break;
653 * <== ServerHello
654 * Certificate
655 * ( ServerKeyExchange )
656 * ( CertificateRequest )
657 * ServerHelloDone
659 case SSL_SERVER_HELLO:
660 ret = ssl_parse_server_hello(ssl);
661 break;
663 case SSL_SERVER_CERTIFICATE:
664 ret = ssl_parse_certificate(ssl);
665 break;
667 case SSL_SERVER_KEY_EXCHANGE:
668 ret = ssl_parse_server_key_exchange(ssl);
669 break;
671 case SSL_CERTIFICATE_REQUEST:
672 ret = ssl_parse_certificate_request(ssl);
673 break;
675 case SSL_SERVER_HELLO_DONE:
676 ret = ssl_parse_server_hello_done(ssl);
677 break;
680 * ==> ( Certificate/Alert )
681 * ClientKeyExchange
682 * ( CertificateVerify )
683 * ChangeCipherSpec
684 * Finished
686 case SSL_CLIENT_CERTIFICATE:
687 ret = ssl_write_certificate(ssl);
688 break;
690 case SSL_CLIENT_KEY_EXCHANGE:
691 ret = ssl_write_client_key_exchange(ssl);
692 break;
694 case SSL_CERTIFICATE_VERIFY:
695 ret = ssl_write_certificate_verify(ssl);
696 break;
698 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
699 ret = ssl_write_change_cipher_spec(ssl);
700 break;
702 case SSL_CLIENT_FINISHED:
703 ret = ssl_write_finished(ssl);
704 break;
707 * <== ChangeCipherSpec
708 * Finished
710 case SSL_SERVER_CHANGE_CIPHER_SPEC:
711 ret = ssl_parse_change_cipher_spec(ssl);
712 break;
714 case SSL_SERVER_FINISHED:
715 ret = ssl_parse_finished(ssl);
716 break;
718 case SSL_FLUSH_BUFFERS:
719 SSL_DEBUG_MSG(2, ("handshake: done"));
720 ssl->state = SSL_HANDSHAKE_OVER;
721 break;
723 default:
724 SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
725 return (TROPICSSL_ERR_SSL_BAD_INPUT_DATA);
728 if (ret != 0)
729 break;
732 SSL_DEBUG_MSG(2, ("<= handshake client"));
734 return (ret);
737 #endif