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>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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"
48 static int ssl_write_client_hello(ssl_context
* ssl
)
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
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]",
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
)
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",
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));
134 *p
++ = SSL_COMPRESS_NULL
;
136 if (ssl
->hostname
!= NULL
) {
137 SSL_DEBUG_MSG(3, ("client hello, server name extension: %s",
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
;
167 if ((ret
= ssl_write_record(ssl
)) != 0) {
168 SSL_DEBUG_RET(1, "ssl_write_record", ret
);
172 SSL_DEBUG_MSG(2, ("<= write client hello"));
177 static int ssl_parse_server_hello(ssl_context
* ssl
)
184 SSL_DEBUG_MSG(2, ("=> parse server hello"));
187 * 0 . 0 handshake type
188 * 1 . 3 handshake length
189 * 4 . 5 protocol version
191 * 10 . 37 random bytes
195 if ((ret
= ssl_read_record(ssl
)) != 0) {
196 SSL_DEBUG_RET(1, "ssl_read_record", 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]",
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)
226 memcpy(ssl
->randbytes
+ 32, buf
+ 6, 32);
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;
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) {
267 ssl
->session
->start
= time(NULL
);
268 ssl
->session
->cipher
= i
;
269 ssl
->session
->length
= n
;
270 memcpy(ssl
->session
->id
, buf
+ 39, n
);
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
]));
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
)
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"));
305 static int ssl_parse_server_key_exchange(ssl_context
* ssl
)
308 unsigned char *p
, *end
;
309 unsigned char hash
[36];
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"));
322 #if !defined(TROPICSSL_DHM_C)
323 SSL_DEBUG_MSG(1, ("support for dhm in not available"));
324 return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE
);
326 if ((ret
= ssl_read_record(ssl
)) != 0) {
327 SSL_DEBUG_RET(1, "ssl_read_record", 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:
345 * opaque dh_p<1..2^16-1>;
346 * opaque dh_g<1..2^16-1>;
347 * opaque dh_Ys<1..2^16-1>;
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];
379 * MD5(ClientHello.random + ServerHello.random
382 * SHA(ClientHello.random + ServerHello.random
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
);
407 SSL_DEBUG_MSG(2, ("<= parse server key exchange"));
413 static int ssl_parse_certificate_request(ssl_context
* ssl
)
417 SSL_DEBUG_MSG(2, ("=> parse certificate request"));
420 * 0 . 0 handshake type
421 * 1 . 3 handshake length
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
);
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;
443 if (ssl
->in_msg
[0] == SSL_HS_CERTIFICATE_REQUEST
)
446 SSL_DEBUG_MSG(3, ("got %s certificate request",
447 ssl
->client_auth
? "a" : "no"));
449 SSL_DEBUG_MSG(2, ("<= parse certificate request"));
454 static int ssl_parse_server_hello_done(ssl_context
* ssl
)
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
);
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
);
479 SSL_DEBUG_MSG(2, ("<= parse server hello done"));
484 static int ssl_write_client_key_exchange(ssl_context
* ssl
)
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
);
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
);
506 ret
= dhm_make_public(&ssl
->dhm_ctx
, 256,
508 ssl
->f_rng
, ssl
->p_rng
);
510 SSL_DEBUG_RET(1, "dhm_make_public", 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
,
521 &ssl
->pmslen
)) != 0) {
522 SSL_DEBUG_RET(1, "dhm_calc_secret", ret
);
526 SSL_DEBUG_MPI(3, "DHM: K ", &ssl
->dhm_ctx
.K
);
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
;
536 for (i
= 2; i
< ssl
->pmslen
; i
++)
538 (unsigned char)ssl
->f_rng(ssl
->p_rng
);
541 n
= ssl
->peer_cert
->rsa
.len
;
543 if (ssl
->minor_ver
!= SSL_MINOR_VERSION_0
) {
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
,
553 SSL_DEBUG_RET(1, "rsa_pkcs1_encrypt", 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
;
566 if ((ret
= ssl_write_record(ssl
)) != 0) {
567 SSL_DEBUG_RET(1, "ssl_write_record", ret
);
571 SSL_DEBUG_MSG(2, ("<= write client key exchange"));
576 static int ssl_write_certificate_verify(ssl_context
* ssl
)
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"));
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
);
609 ssl
->out_msglen
= 6 + n
;
610 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
611 ssl
->out_msg
[0] = SSL_HS_CERTIFICATE_VERIFY
;
615 if ((ret
= ssl_write_record(ssl
)) != 0) {
616 SSL_DEBUG_RET(1, "ssl_write_record", ret
);
620 SSL_DEBUG_MSG(2, ("<= write certificate verify"));
626 * SSL handshake -- client side
628 int ssl_handshake_client(ssl_context
* ssl
)
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)
640 switch (ssl
->state
) {
641 case SSL_HELLO_REQUEST
:
642 ssl
->state
= SSL_CLIENT_HELLO
;
648 case SSL_CLIENT_HELLO
:
649 ret
= ssl_write_client_hello(ssl
);
655 * ( ServerKeyExchange )
656 * ( CertificateRequest )
659 case SSL_SERVER_HELLO
:
660 ret
= ssl_parse_server_hello(ssl
);
663 case SSL_SERVER_CERTIFICATE
:
664 ret
= ssl_parse_certificate(ssl
);
667 case SSL_SERVER_KEY_EXCHANGE
:
668 ret
= ssl_parse_server_key_exchange(ssl
);
671 case SSL_CERTIFICATE_REQUEST
:
672 ret
= ssl_parse_certificate_request(ssl
);
675 case SSL_SERVER_HELLO_DONE
:
676 ret
= ssl_parse_server_hello_done(ssl
);
680 * ==> ( Certificate/Alert )
682 * ( CertificateVerify )
686 case SSL_CLIENT_CERTIFICATE
:
687 ret
= ssl_write_certificate(ssl
);
690 case SSL_CLIENT_KEY_EXCHANGE
:
691 ret
= ssl_write_client_key_exchange(ssl
);
694 case SSL_CERTIFICATE_VERIFY
:
695 ret
= ssl_write_certificate_verify(ssl
);
698 case SSL_CLIENT_CHANGE_CIPHER_SPEC
:
699 ret
= ssl_write_change_cipher_spec(ssl
);
702 case SSL_CLIENT_FINISHED
:
703 ret
= ssl_write_finished(ssl
);
707 * <== ChangeCipherSpec
710 case SSL_SERVER_CHANGE_CIPHER_SPEC
:
711 ret
= ssl_parse_change_cipher_spec(ssl
);
714 case SSL_SERVER_FINISHED
:
715 ret
= ssl_parse_finished(ssl
);
718 case SSL_FLUSH_BUFFERS
:
719 SSL_DEBUG_MSG(2, ("handshake: done"));
720 ssl
->state
= SSL_HANDSHAKE_OVER
;
724 SSL_DEBUG_MSG(1, ("invalid state %d", ssl
->state
));
725 return (TROPICSSL_ERR_SSL_BAD_INPUT_DATA
);
732 SSL_DEBUG_MSG(2, ("<= handshake client"));