2 * SSLv3/TLSv1 server-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_SRV_C)
40 #include "tropicssl/debug.h"
41 #include "tropicssl/ssl.h"
48 static int ssl_parse_client_hello(ssl_context
* ssl
)
51 int ciph_len
, sess_len
;
52 int chal_len
, comp_len
;
53 unsigned char *buf
, *p
;
55 SSL_DEBUG_MSG(2, ("=> parse client hello"));
57 if ((ret
= ssl_fetch_input(ssl
, 5)) != 0) {
58 SSL_DEBUG_RET(1, "ssl_fetch_input", ret
);
64 if ((buf
[0] & 0x80) != 0) {
65 SSL_DEBUG_BUF(4, "record header", buf
, 5);
67 SSL_DEBUG_MSG(3, ("client hello v2, message type: %d", buf
[2]));
68 SSL_DEBUG_MSG(3, ("client hello v2, message len.: %d",
69 ((buf
[0] & 0x7F) << 8) | buf
[1]));
70 SSL_DEBUG_MSG(3, ("client hello v2, max. version: [%d:%d]",
77 * 0 . 1 message length
81 * 3 . 4 protocol version
83 if (buf
[2] != SSL_HS_CLIENT_HELLO
||
84 buf
[3] != SSL_MAJOR_VERSION_3
) {
85 SSL_DEBUG_MSG(1, ("bad client hello message"));
86 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
89 n
= ((buf
[0] << 8) | buf
[1]) & 0x7FFF;
91 if (n
< 17 || n
> 512) {
92 SSL_DEBUG_MSG(1, ("bad client hello message"));
93 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
96 ssl
->max_major_ver
= buf
[3];
97 ssl
->max_minor_ver
= buf
[4];
99 ssl
->major_ver
= SSL_MAJOR_VERSION_3
;
100 ssl
->minor_ver
= (buf
[4] <= SSL_MINOR_VERSION_1
)
101 ? buf
[4] : SSL_MINOR_VERSION_1
;
103 if ((ret
= ssl_fetch_input(ssl
, 2 + n
)) != 0) {
104 SSL_DEBUG_RET(1, "ssl_fetch_input", ret
);
108 md5_update(&ssl
->fin_md5
, buf
+ 2, n
);
109 sha1_update(&ssl
->fin_sha1
, buf
+ 2, n
);
112 n
= ssl
->in_left
- 5;
115 * 0 . 1 cipherlist length
116 * 2 . 3 session id length
117 * 4 . 5 challenge length
122 SSL_DEBUG_BUF(4, "record contents", buf
, n
);
124 ciph_len
= (buf
[0] << 8) | buf
[1];
125 sess_len
= (buf
[2] << 8) | buf
[3];
126 chal_len
= (buf
[4] << 8) | buf
[5];
128 SSL_DEBUG_MSG(3, ("ciph_len: %d, sess_len: %d, chal_len: %d",
129 ciph_len
, sess_len
, chal_len
));
132 * Make sure each parameter length is valid
134 if (ciph_len
< 3 || (ciph_len
% 3) != 0) {
135 SSL_DEBUG_MSG(1, ("bad client hello message"));
136 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
139 if (sess_len
< 0 || sess_len
> 32) {
140 SSL_DEBUG_MSG(1, ("bad client hello message"));
141 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
144 if (chal_len
< 8 || chal_len
> 32) {
145 SSL_DEBUG_MSG(1, ("bad client hello message"));
146 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
149 if (n
!= 6 + ciph_len
+ sess_len
+ chal_len
) {
150 SSL_DEBUG_MSG(1, ("bad client hello message"));
151 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
154 SSL_DEBUG_BUF(3, "client hello, cipherlist", buf
+ 6, ciph_len
);
155 SSL_DEBUG_BUF(3, "client hello, session id",
156 buf
+ 6 + ciph_len
, sess_len
);
157 SSL_DEBUG_BUF(3, "client hello, challenge",
158 buf
+ 6 + ciph_len
+ sess_len
, chal_len
);
160 p
= buf
+ 6 + ciph_len
;
161 ssl
->session
->length
= sess_len
;
162 memset(ssl
->session
->id
, 0, sizeof(ssl
->session
->id
));
163 memcpy(ssl
->session
->id
, p
, ssl
->session
->length
);
166 memset(ssl
->randbytes
, 0, 64);
167 memcpy(ssl
->randbytes
+ 32 - chal_len
, p
, chal_len
);
169 for (i
= 0; ssl
->ciphers
[i
] != 0; i
++) {
170 for (j
= 0, p
= buf
+ 6; j
< ciph_len
; j
+= 3, p
+= 3) {
172 p
[1] == 0 && p
[2] == ssl
->ciphers
[i
])
177 SSL_DEBUG_BUF(4, "record header", buf
, 5);
179 SSL_DEBUG_MSG(3, ("client hello v3, message type: %d", buf
[0]));
180 SSL_DEBUG_MSG(3, ("client hello v3, message len.: %d",
181 (buf
[3] << 8) | buf
[4]));
182 SSL_DEBUG_MSG(3, ("client hello v3, protocol ver: [%d:%d]",
190 * 1 . 2 protocol version
191 * 3 . 4 message length
193 if (buf
[0] != SSL_MSG_HANDSHAKE
||
194 buf
[1] != SSL_MAJOR_VERSION_3
) {
195 SSL_DEBUG_MSG(1, ("bad client hello message"));
196 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
199 n
= (buf
[3] << 8) | buf
[4];
201 if (n
< 45 || n
> 512) {
202 SSL_DEBUG_MSG(1, ("bad client hello message"));
203 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
206 if ((ret
= ssl_fetch_input(ssl
, 5 + n
)) != 0) {
207 SSL_DEBUG_RET(1, "ssl_fetch_input", ret
);
212 n
= ssl
->in_left
- 5;
214 md5_update(&ssl
->fin_md5
, buf
, n
);
215 sha1_update(&ssl
->fin_sha1
, buf
, n
);
219 * 0 . 0 handshake type
220 * 1 . 3 handshake length
221 * 4 . 5 protocol version
223 * 10 . 37 random bytes
224 * 38 . 38 session id length
225 * 39 . 38+x session id
226 * 39+x . 40+x cipherlist length
227 * 41+x . .. cipherlist
228 * .. . .. compression alg.
231 SSL_DEBUG_BUF(4, "record contents", buf
, n
);
233 SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d",
235 SSL_DEBUG_MSG(3, ("client hello v3, handshake len.: %d",
236 (buf
[1] << 16) | (buf
[2] << 8) | buf
[3]));
237 SSL_DEBUG_MSG(3, ("client hello v3, max. version: [%d:%d]",
241 * Check the handshake type and protocol version
243 if (buf
[0] != SSL_HS_CLIENT_HELLO
||
244 buf
[4] != SSL_MAJOR_VERSION_3
) {
245 SSL_DEBUG_MSG(1, ("bad client hello message"));
246 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
249 ssl
->major_ver
= SSL_MAJOR_VERSION_3
;
250 ssl
->minor_ver
= (buf
[5] <= SSL_MINOR_VERSION_1
)
251 ? buf
[5] : SSL_MINOR_VERSION_1
;
253 ssl
->max_major_ver
= buf
[4];
254 ssl
->max_minor_ver
= buf
[5];
256 memcpy(ssl
->randbytes
, buf
+ 6, 32);
259 * Check the handshake message length
261 if (buf
[1] != 0 || n
!= 4 + ((buf
[2] << 8) | buf
[3])) {
262 SSL_DEBUG_MSG(1, ("bad client hello message"));
263 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
267 * Check the session length
271 if (sess_len
< 0 || sess_len
> 32) {
272 SSL_DEBUG_MSG(1, ("bad client hello message"));
273 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
276 ssl
->session
->length
= sess_len
;
277 memset(ssl
->session
->id
, 0, sizeof(ssl
->session
->id
));
278 memcpy(ssl
->session
->id
, buf
+ 39, ssl
->session
->length
);
281 * Check the cipherlist length
283 ciph_len
= (buf
[39 + sess_len
] << 8)
284 | (buf
[40 + sess_len
]);
286 if (ciph_len
< 2 || ciph_len
> 256 || (ciph_len
% 2) != 0) {
287 SSL_DEBUG_MSG(1, ("bad client hello message"));
288 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
292 * Check the compression algorithms length
294 comp_len
= buf
[41 + sess_len
+ ciph_len
];
296 if (comp_len
< 1 || comp_len
> 16) {
297 SSL_DEBUG_MSG(1, ("bad client hello message"));
298 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_HELLO
);
301 SSL_DEBUG_BUF(3, "client hello, random bytes", buf
+ 6, 32);
302 SSL_DEBUG_BUF(3, "client hello, session id",
304 SSL_DEBUG_BUF(3, "client hello, cipherlist",
305 buf
+ 41 + sess_len
, ciph_len
);
306 SSL_DEBUG_BUF(3, "client hello, compression",
307 buf
+ 42 + sess_len
+ ciph_len
, comp_len
);
310 * Search for a matching cipher
312 for (i
= 0; ssl
->ciphers
[i
] != 0; i
++) {
313 for (j
= 0, p
= buf
+ 41 + sess_len
; j
< ciph_len
;
315 if (p
[0] == 0 && p
[1] == ssl
->ciphers
[i
])
321 SSL_DEBUG_MSG(1, ("got no ciphers in common"));
323 return (TROPICSSL_ERR_SSL_NO_CIPHER_CHOSEN
);
327 ssl
->session
->cipher
= ssl
->ciphers
[i
];
331 SSL_DEBUG_MSG(2, ("<= parse client hello"));
336 static int ssl_write_server_hello(ssl_context
* ssl
)
340 unsigned char *buf
, *p
;
342 SSL_DEBUG_MSG(2, ("=> write server hello"));
345 * 0 . 0 handshake type
346 * 1 . 3 handshake length
347 * 4 . 5 protocol version
349 * 10 . 37 random bytes
354 *p
++ = (unsigned char)ssl
->major_ver
;
355 *p
++ = (unsigned char)ssl
->minor_ver
;
357 SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]",
361 *p
++ = (unsigned char)(t
>> 24);
362 *p
++ = (unsigned char)(t
>> 16);
363 *p
++ = (unsigned char)(t
>> 8);
364 *p
++ = (unsigned char)(t
);
366 SSL_DEBUG_MSG(3, ("server hello, current time: %lu", t
));
368 for (i
= 28; i
> 0; i
--)
369 *p
++ = (unsigned char)ssl
->f_rng(ssl
->p_rng
);
371 memcpy(ssl
->randbytes
+ 32, buf
+ 6, 32);
373 SSL_DEBUG_BUF(3, "server hello, random bytes", buf
+ 6, 32);
376 * 38 . 38 session id length
377 * 39 . 38+n session id
378 * 39+n . 40+n chosen cipher
379 * 41+n . 41+n chosen compression alg.
381 ssl
->session
->length
= n
= 32;
382 *p
++ = (unsigned char)ssl
->session
->length
;
384 if (ssl
->s_get
== NULL
|| ssl
->s_get(ssl
) != 0) {
386 * Not found, create a new session id
391 for (i
= 0; i
< n
; i
++)
392 ssl
->session
->id
[i
] =
393 (unsigned char)ssl
->f_rng(ssl
->p_rng
);
396 * Found a matching session, resume it
399 ssl
->state
= SSL_SERVER_CHANGE_CIPHER_SPEC
;
400 ssl_derive_keys(ssl
);
403 memcpy(p
, ssl
->session
->id
, ssl
->session
->length
);
404 p
+= ssl
->session
->length
;
406 SSL_DEBUG_MSG(3, ("server hello, session id len.: %d", n
));
407 SSL_DEBUG_BUF(3, "server hello, session id", buf
+ 39, n
);
408 SSL_DEBUG_MSG(3, ("%s session has been resumed",
409 ssl
->resume
? "a" : "no"));
411 *p
++ = (unsigned char)(ssl
->session
->cipher
>> 8);
412 *p
++ = (unsigned char)(ssl
->session
->cipher
);
413 *p
++ = SSL_COMPRESS_NULL
;
415 SSL_DEBUG_MSG(3, ("server hello, chosen cipher: %d",
416 ssl
->session
->cipher
));
417 SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d", 0));
419 ssl
->out_msglen
= p
- buf
;
420 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
421 ssl
->out_msg
[0] = SSL_HS_SERVER_HELLO
;
423 ret
= ssl_write_record(ssl
);
425 SSL_DEBUG_MSG(2, ("<= write server hello"));
430 static int ssl_write_certificate_request(ssl_context
* ssl
)
433 unsigned char *buf
, *p
;
436 SSL_DEBUG_MSG(2, ("=> write certificate request"));
440 if (ssl
->authmode
== SSL_VERIFY_NONE
) {
441 SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
446 * 0 . 0 handshake type
447 * 1 . 3 handshake length
448 * 4 . 4 cert type count
449 * 5 .. n-1 cert types
450 * n .. n+1 length of all DNs
451 * n+2 .. n+3 length of DN 1
452 * n+4 .. ... Distinguished Name #1
453 * ... .. ... length of DN 2, etc.
459 * At the moment, only RSA certificates are supported
467 while (crt
!= NULL
&& crt
->next
!= NULL
) {
471 n
= crt
->subject_raw
.len
;
472 *p
++ = (unsigned char)(n
>> 8);
473 *p
++ = (unsigned char)(n
);
474 memcpy(p
, crt
->subject_raw
.p
, n
);
476 SSL_DEBUG_BUF(3, "requested DN", p
, n
);
481 ssl
->out_msglen
= n
= p
- buf
;
482 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
483 ssl
->out_msg
[0] = SSL_HS_CERTIFICATE_REQUEST
;
484 ssl
->out_msg
[6] = (unsigned char)((n
- 8) >> 8);
485 ssl
->out_msg
[7] = (unsigned char)((n
- 8));
487 ret
= ssl_write_record(ssl
);
489 SSL_DEBUG_MSG(2, ("<= write certificate request"));
494 static int ssl_write_server_key_exchange(ssl_context
* ssl
)
497 unsigned char hash
[36];
499 sha1_context sha1_ctx
;
501 SSL_DEBUG_MSG(2, ("=> write server key exchange"));
503 if (ssl
->session
->cipher
!= SSL_EDH_RSA_DES_168_SHA
&&
504 ssl
->session
->cipher
!= SSL_EDH_RSA_AES_256_SHA
&&
505 ssl
->session
->cipher
!= SSL_EDH_RSA_CAMELLIA_256_SHA
) {
506 SSL_DEBUG_MSG(2, ("<= skip write server key exchange"));
510 #if !defined(TROPICSSL_DHM_C)
511 SSL_DEBUG_MSG(1, ("support for dhm is not available"));
512 return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE
);
515 * Ephemeral DH parameters:
518 * opaque dh_p<1..2^16-1>;
519 * opaque dh_g<1..2^16-1>;
520 * opaque dh_Ys<1..2^16-1>;
523 if ((ret
= dhm_make_params(&ssl
->dhm_ctx
, 256, ssl
->out_msg
+ 4,
524 &n
, ssl
->f_rng
, ssl
->p_rng
)) != 0) {
525 SSL_DEBUG_RET(1, "dhm_make_params", ret
);
529 SSL_DEBUG_MPI(3, "DHM: X ", &ssl
->dhm_ctx
.X
);
530 SSL_DEBUG_MPI(3, "DHM: P ", &ssl
->dhm_ctx
.P
);
531 SSL_DEBUG_MPI(3, "DHM: G ", &ssl
->dhm_ctx
.G
);
532 SSL_DEBUG_MPI(3, "DHM: GX", &ssl
->dhm_ctx
.GX
);
535 * digitally-signed struct {
536 * opaque md5_hash[16];
537 * opaque sha_hash[20];
541 * MD5(ClientHello.random + ServerHello.random
544 * SHA(ClientHello.random + ServerHello.random
547 md5_starts(&md5_ctx
);
548 md5_update(&md5_ctx
, ssl
->randbytes
, 64);
549 md5_update(&md5_ctx
, ssl
->out_msg
+ 4, n
);
550 md5_finish(&md5_ctx
, hash
);
552 sha1_starts(&sha1_ctx
);
553 sha1_update(&sha1_ctx
, ssl
->randbytes
, 64);
554 sha1_update(&sha1_ctx
, ssl
->out_msg
+ 4, n
);
555 sha1_finish(&sha1_ctx
, hash
+ 16);
557 SSL_DEBUG_BUF(3, "parameters hash", hash
, 36);
559 ssl
->out_msg
[4 + n
] = (unsigned char)(ssl
->rsa_key
->len
>> 8);
560 ssl
->out_msg
[5 + n
] = (unsigned char)(ssl
->rsa_key
->len
);
562 ret
= rsa_pkcs1_sign(ssl
->rsa_key
, RSA_PRIVATE
,
563 RSA_RAW
, 36, hash
, ssl
->out_msg
+ 6 + n
);
565 SSL_DEBUG_RET(1, "rsa_pkcs1_sign", ret
);
569 SSL_DEBUG_BUF(3, "my RSA sig", ssl
->out_msg
+ 6 + n
, ssl
->rsa_key
->len
);
571 ssl
->out_msglen
= 6 + n
+ ssl
->rsa_key
->len
;
572 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
573 ssl
->out_msg
[0] = SSL_HS_SERVER_KEY_EXCHANGE
;
577 if ((ret
= ssl_write_record(ssl
)) != 0) {
578 SSL_DEBUG_RET(1, "ssl_write_record", ret
);
582 SSL_DEBUG_MSG(2, ("<= write server key exchange"));
588 static int ssl_write_server_hello_done(ssl_context
* ssl
)
592 SSL_DEBUG_MSG(2, ("=> write server hello done"));
595 ssl
->out_msgtype
= SSL_MSG_HANDSHAKE
;
596 ssl
->out_msg
[0] = SSL_HS_SERVER_HELLO_DONE
;
600 if ((ret
= ssl_write_record(ssl
)) != 0) {
601 SSL_DEBUG_RET(1, "ssl_write_record", ret
);
605 SSL_DEBUG_MSG(2, ("<= write server hello done"));
610 static int ssl_parse_client_key_exchange(ssl_context
* ssl
)
614 SSL_DEBUG_MSG(2, ("=> parse client key exchange"));
616 if ((ret
= ssl_read_record(ssl
)) != 0) {
617 SSL_DEBUG_RET(1, "ssl_read_record", ret
);
621 if (ssl
->in_msgtype
!= SSL_MSG_HANDSHAKE
) {
622 SSL_DEBUG_MSG(1, ("bad client key exchange message"));
623 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
);
626 if (ssl
->in_msg
[0] != SSL_HS_CLIENT_KEY_EXCHANGE
) {
627 SSL_DEBUG_MSG(1, ("bad client key exchange message"));
628 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
);
631 if (ssl
->session
->cipher
== SSL_EDH_RSA_DES_168_SHA
||
632 ssl
->session
->cipher
== SSL_EDH_RSA_AES_256_SHA
||
633 ssl
->session
->cipher
== SSL_EDH_RSA_CAMELLIA_256_SHA
) {
634 #if !defined(TROPICSSL_DHM_C)
635 SSL_DEBUG_MSG(1, ("support for dhm is not available"));
636 return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE
);
639 * Receive G^Y mod P, premaster = (G^Y)^X mod P
641 n
= (ssl
->in_msg
[4] << 8) | ssl
->in_msg
[5];
643 if (n
< 1 || n
> ssl
->dhm_ctx
.len
|| n
+ 6 != ssl
->in_hslen
) {
644 SSL_DEBUG_MSG(1, ("bad client key exchange message"));
645 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
);
648 if ((ret
= dhm_read_public(&ssl
->dhm_ctx
,
649 ssl
->in_msg
+ 6, n
)) != 0) {
650 SSL_DEBUG_RET(1, "dhm_read_public", ret
);
651 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
|
655 SSL_DEBUG_MPI(3, "DHM: GY", &ssl
->dhm_ctx
.GY
);
657 ssl
->pmslen
= ssl
->dhm_ctx
.len
;
659 if ((ret
= dhm_calc_secret(&ssl
->dhm_ctx
,
661 &ssl
->pmslen
)) != 0) {
662 SSL_DEBUG_RET(1, "dhm_calc_secret", ret
);
663 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
|
667 SSL_DEBUG_MPI(3, "DHM: K ", &ssl
->dhm_ctx
.K
);
671 * Decrypt the premaster using own private RSA key
674 n
= ssl
->rsa_key
->len
;
677 if (ssl
->minor_ver
!= SSL_MINOR_VERSION_0
) {
679 if (ssl
->in_msg
[4] != ((n
>> 8) & 0xFF) ||
680 ssl
->in_msg
[5] != ((n
) & 0xFF)) {
682 ("bad client key exchange message"));
684 (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
);
688 if (ssl
->in_hslen
!= i
+ n
) {
689 SSL_DEBUG_MSG(1, ("bad client key exchange message"));
690 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE
);
693 ret
= rsa_pkcs1_decrypt(ssl
->rsa_key
, RSA_PRIVATE
, &ssl
->pmslen
,
694 ssl
->in_msg
+ i
, ssl
->premaster
,
695 sizeof(ssl
->premaster
));
697 if (ret
!= 0 || ssl
->pmslen
!= 48 ||
698 ssl
->premaster
[0] != ssl
->max_major_ver
||
699 ssl
->premaster
[1] != ssl
->max_minor_ver
) {
700 SSL_DEBUG_MSG(1, ("bad client key exchange message"));
703 * Protection against Bleichenbacher's attack:
704 * invalid PKCS#1 v1.5 padding must not cause
705 * the connection to end immediately; instead,
706 * send a bad_record_mac later in the handshake.
710 for (i
= 0; i
< ssl
->pmslen
; i
++)
712 (unsigned char)ssl
->f_rng(ssl
->p_rng
);
716 ssl_derive_keys(ssl
);
718 if (ssl
->s_set
!= NULL
)
723 SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
728 static int ssl_parse_certificate_verify(ssl_context
* ssl
)
731 unsigned char hash
[36];
733 SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
735 if (ssl
->peer_cert
== NULL
) {
736 SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
741 ssl_calc_verify(ssl
, hash
);
743 if ((ret
= ssl_read_record(ssl
)) != 0) {
744 SSL_DEBUG_RET(1, "ssl_read_record", ret
);
750 if (ssl
->in_msgtype
!= SSL_MSG_HANDSHAKE
) {
751 SSL_DEBUG_MSG(1, ("bad certificate verify message"));
752 return (TROPICSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY
);
755 if (ssl
->in_msg
[0] != SSL_HS_CERTIFICATE_VERIFY
) {
756 SSL_DEBUG_MSG(1, ("bad certificate verify message"));
757 return (TROPICSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY
);
760 n1
= ssl
->peer_cert
->rsa
.len
;
761 n2
= (ssl
->in_msg
[4] << 8) | ssl
->in_msg
[5];
763 if (n1
+ 6 != ssl
->in_hslen
|| n1
!= n2
) {
764 SSL_DEBUG_MSG(1, ("bad certificate verify message"));
765 return (TROPICSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY
);
768 ret
= rsa_pkcs1_verify(&ssl
->peer_cert
->rsa
, RSA_PUBLIC
,
769 RSA_RAW
, 36, hash
, ssl
->in_msg
+ 6);
771 SSL_DEBUG_RET(1, "rsa_pkcs1_verify", ret
);
775 SSL_DEBUG_MSG(2, ("<= parse certificate verify"));
781 * SSL handshake -- server side
783 int ssl_handshake_server(ssl_context
* ssl
)
787 SSL_DEBUG_MSG(2, ("=> handshake server"));
789 while (ssl
->state
!= SSL_HANDSHAKE_OVER
) {
790 SSL_DEBUG_MSG(2, ("server state: %d", ssl
->state
));
792 if ((ret
= ssl_flush_output(ssl
)) != 0)
795 switch (ssl
->state
) {
796 case SSL_HELLO_REQUEST
:
797 ssl
->state
= SSL_CLIENT_HELLO
;
803 case SSL_CLIENT_HELLO
:
804 ret
= ssl_parse_client_hello(ssl
);
810 * ( ServerKeyExchange )
811 * ( CertificateRequest )
814 case SSL_SERVER_HELLO
:
815 ret
= ssl_write_server_hello(ssl
);
818 case SSL_SERVER_CERTIFICATE
:
819 ret
= ssl_write_certificate(ssl
);
822 case SSL_SERVER_KEY_EXCHANGE
:
823 ret
= ssl_write_server_key_exchange(ssl
);
826 case SSL_CERTIFICATE_REQUEST
:
827 ret
= ssl_write_certificate_request(ssl
);
830 case SSL_SERVER_HELLO_DONE
:
831 ret
= ssl_write_server_hello_done(ssl
);
835 * <== ( Certificate/Alert )
837 * ( CertificateVerify )
841 case SSL_CLIENT_CERTIFICATE
:
842 ret
= ssl_parse_certificate(ssl
);
845 case SSL_CLIENT_KEY_EXCHANGE
:
846 ret
= ssl_parse_client_key_exchange(ssl
);
849 case SSL_CERTIFICATE_VERIFY
:
850 ret
= ssl_parse_certificate_verify(ssl
);
853 case SSL_CLIENT_CHANGE_CIPHER_SPEC
:
854 ret
= ssl_parse_change_cipher_spec(ssl
);
857 case SSL_CLIENT_FINISHED
:
858 ret
= ssl_parse_finished(ssl
);
862 * ==> ChangeCipherSpec
865 case SSL_SERVER_CHANGE_CIPHER_SPEC
:
866 ret
= ssl_write_change_cipher_spec(ssl
);
869 case SSL_SERVER_FINISHED
:
870 ret
= ssl_write_finished(ssl
);
873 case SSL_FLUSH_BUFFERS
:
874 SSL_DEBUG_MSG(2, ("handshake: done"));
875 ssl
->state
= SSL_HANDSHAKE_OVER
;
879 SSL_DEBUG_MSG(1, ("invalid state %d", ssl
->state
));
880 return (TROPICSSL_ERR_SSL_BAD_INPUT_DATA
);
887 SSL_DEBUG_MSG(2, ("<= handshake server"));