ssl/tls: add proper const attributes to functions, context members
[tropicssl.git] / library / ssl_srv.c
blobc5d984fcce74f00e79aaeddee45d5d4d2ef370ce
1 /*
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>
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_SRV_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_parse_client_hello(ssl_context * ssl)
50 int ret, i, j, n;
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);
59 return (ret);
62 buf = ssl->in_hdr;
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]",
71 buf[3], buf[4]));
74 * SSLv2 Client Hello
76 * Record layer:
77 * 0 . 1 message length
79 * SSL layer:
80 * 2 . 2 message type
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);
105 return (ret);
108 md5_update(&ssl->fin_md5, buf + 2, n);
109 sha1_update(&ssl->fin_sha1, buf + 2, n);
111 buf = ssl->in_msg;
112 n = ssl->in_left - 5;
115 * 0 . 1 cipherlist length
116 * 2 . 3 session id length
117 * 4 . 5 challenge length
118 * 6 . .. cipherlist
119 * .. . .. session id
120 * .. . .. challenge
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);
165 p += sess_len;
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) {
171 if (p[0] == 0 &&
172 p[1] == 0 && p[2] == ssl->ciphers[i])
173 goto have_cipher;
176 } else {
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]",
183 buf[1], buf[2]));
186 * SSLv3 Client Hello
188 * Record layer:
189 * 0 . 0 message type
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);
208 return (ret);
211 buf = ssl->in_msg;
212 n = ssl->in_left - 5;
214 md5_update(&ssl->fin_md5, buf, n);
215 sha1_update(&ssl->fin_sha1, buf, n);
218 * SSL layer:
219 * 0 . 0 handshake type
220 * 1 . 3 handshake length
221 * 4 . 5 protocol version
222 * 6 . 9 UNIX time()
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.
229 * .. . .. extensions
231 SSL_DEBUG_BUF(4, "record contents", buf, n);
233 SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d",
234 buf[0]));
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]",
238 buf[4], buf[5]));
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
269 sess_len = buf[38];
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",
303 buf + 38, sess_len);
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;
314 j += 2, p += 2) {
315 if (p[0] == 0 && p[1] == ssl->ciphers[i])
316 goto have_cipher;
321 SSL_DEBUG_MSG(1, ("got no ciphers in common"));
323 return (TROPICSSL_ERR_SSL_NO_CIPHER_CHOSEN);
325 have_cipher:
327 ssl->session->cipher = ssl->ciphers[i];
328 ssl->in_left = 0;
329 ssl->state++;
331 SSL_DEBUG_MSG(2, ("<= parse client hello"));
333 return (0);
336 static int ssl_write_server_hello(ssl_context * ssl)
338 time_t t;
339 int ret, i, n;
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
348 * 6 . 9 UNIX time()
349 * 10 . 37 random bytes
351 buf = ssl->out_msg;
352 p = buf + 4;
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]",
358 buf[4], buf[5]));
360 t = time(NULL);
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
388 ssl->resume = 0;
389 ssl->state++;
391 for (i = 0; i < n; i++)
392 ssl->session->id[i] =
393 (unsigned char)ssl->f_rng(ssl->p_rng);
394 } else {
396 * Found a matching session, resume it
398 ssl->resume = 1;
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"));
427 return (ret);
430 static int ssl_write_certificate_request(ssl_context * ssl)
432 int ret, n;
433 unsigned char *buf, *p;
434 x509_cert *crt;
436 SSL_DEBUG_MSG(2, ("=> write certificate request"));
438 ssl->state++;
440 if (ssl->authmode == SSL_VERIFY_NONE) {
441 SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
442 return (0);
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.
455 buf = ssl->out_msg;
456 p = buf + 4;
459 * At the moment, only RSA certificates are supported
461 *p++ = 1;
462 *p++ = 1;
464 p += 2;
465 crt = ssl->ca_chain;
467 while (crt != NULL && crt->next != NULL) {
468 if (p - buf > 4096)
469 break;
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);
477 p += n;
478 crt = crt->next;
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"));
491 return (ret);
494 static int ssl_write_server_key_exchange(ssl_context * ssl)
496 int ret, n;
497 unsigned char hash[36];
498 md5_context md5;
499 sha1_context sha1;
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"));
507 ssl->state++;
508 return (0);
510 #if !defined(TROPICSSL_DHM_C)
511 SSL_DEBUG_MSG(1, ("support for dhm is not available"));
512 return (TROPICSSL_ERR_SSL_FEATURE_UNAVAILABLE);
513 #else
515 * Ephemeral DH parameters:
517 * struct {
518 * opaque dh_p<1..2^16-1>;
519 * opaque dh_g<1..2^16-1>;
520 * opaque dh_Ys<1..2^16-1>;
521 * } ServerDHParams;
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);
526 return (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];
538 * };
540 * md5_hash
541 * MD5(ClientHello.random + ServerHello.random
542 * + ServerParams);
543 * sha_hash
544 * SHA(ClientHello.random + ServerHello.random
545 * + ServerParams);
547 md5_starts(&md5);
548 md5_update(&md5, ssl->randbytes, 64);
549 md5_update(&md5, ssl->out_msg + 4, n);
550 md5_finish(&md5, hash);
552 sha1_starts(&sha1);
553 sha1_update(&sha1, ssl->randbytes, 64);
554 sha1_update(&sha1, ssl->out_msg + 4, n);
555 sha1_finish(&sha1, 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);
564 if (ret != 0) {
565 SSL_DEBUG_RET(1, "rsa_pkcs1_sign", ret);
566 return (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;
575 ssl->state++;
577 if ((ret = ssl_write_record(ssl)) != 0) {
578 SSL_DEBUG_RET(1, "ssl_write_record", ret);
579 return (ret);
582 SSL_DEBUG_MSG(2, ("<= write server key exchange"));
584 return (0);
585 #endif
588 static int ssl_write_server_hello_done(ssl_context * ssl)
590 int ret;
592 SSL_DEBUG_MSG(2, ("=> write server hello done"));
594 ssl->out_msglen = 4;
595 ssl->out_msgtype = SSL_MSG_HANDSHAKE;
596 ssl->out_msg[0] = SSL_HS_SERVER_HELLO_DONE;
598 ssl->state++;
600 if ((ret = ssl_write_record(ssl)) != 0) {
601 SSL_DEBUG_RET(1, "ssl_write_record", ret);
602 return (ret);
605 SSL_DEBUG_MSG(2, ("<= write server hello done"));
607 return (0);
610 static int ssl_parse_client_key_exchange(ssl_context * ssl)
612 int ret, i, n;
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);
618 return (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);
637 #else
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 |
652 ret);
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,
660 ssl->premaster,
661 &ssl->pmslen)) != 0) {
662 SSL_DEBUG_RET(1, "dhm_calc_secret", ret);
663 return (TROPICSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE |
664 ret);
667 SSL_DEBUG_MPI(3, "DHM: K ", &ssl->dhm_ctx.K);
668 #endif
669 } else {
671 * Decrypt the premaster using own private RSA key
673 i = 4;
674 n = ssl->rsa_key->len;
675 ssl->pmslen = 48;
677 if (ssl->minor_ver != SSL_MINOR_VERSION_0) {
678 i += 2;
679 if (ssl->in_msg[4] != ((n >> 8) & 0xFF) ||
680 ssl->in_msg[5] != ((n) & 0xFF)) {
681 SSL_DEBUG_MSG(1,
682 ("bad client key exchange message"));
683 return
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.
708 ssl->pmslen = 48;
710 for (i = 0; i < ssl->pmslen; i++)
711 ssl->premaster[i] =
712 (unsigned char)ssl->f_rng(ssl->p_rng);
716 ssl_derive_keys(ssl);
718 if (ssl->s_set != NULL)
719 ssl->s_set(ssl);
721 ssl->state++;
723 SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
725 return (0);
728 static int ssl_parse_certificate_verify(ssl_context * ssl)
730 int n1, n2, ret;
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"));
737 ssl->state++;
738 return (0);
741 ssl_calc_verify(ssl, hash);
743 if ((ret = ssl_read_record(ssl)) != 0) {
744 SSL_DEBUG_RET(1, "ssl_read_record", ret);
745 return (ret);
748 ssl->state++;
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);
770 if (ret != 0) {
771 SSL_DEBUG_RET(1, "rsa_pkcs1_verify", ret);
772 return (ret);
775 SSL_DEBUG_MSG(2, ("<= parse certificate verify"));
777 return (0);
781 * SSL handshake -- server side
783 int ssl_handshake_server(ssl_context * ssl)
785 int ret = 0;
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)
793 break;
795 switch (ssl->state) {
796 case SSL_HELLO_REQUEST:
797 ssl->state = SSL_CLIENT_HELLO;
798 break;
801 * <== ClientHello
803 case SSL_CLIENT_HELLO:
804 ret = ssl_parse_client_hello(ssl);
805 break;
808 * ==> ServerHello
809 * Certificate
810 * ( ServerKeyExchange )
811 * ( CertificateRequest )
812 * ServerHelloDone
814 case SSL_SERVER_HELLO:
815 ret = ssl_write_server_hello(ssl);
816 break;
818 case SSL_SERVER_CERTIFICATE:
819 ret = ssl_write_certificate(ssl);
820 break;
822 case SSL_SERVER_KEY_EXCHANGE:
823 ret = ssl_write_server_key_exchange(ssl);
824 break;
826 case SSL_CERTIFICATE_REQUEST:
827 ret = ssl_write_certificate_request(ssl);
828 break;
830 case SSL_SERVER_HELLO_DONE:
831 ret = ssl_write_server_hello_done(ssl);
832 break;
835 * <== ( Certificate/Alert )
836 * ClientKeyExchange
837 * ( CertificateVerify )
838 * ChangeCipherSpec
839 * Finished
841 case SSL_CLIENT_CERTIFICATE:
842 ret = ssl_parse_certificate(ssl);
843 break;
845 case SSL_CLIENT_KEY_EXCHANGE:
846 ret = ssl_parse_client_key_exchange(ssl);
847 break;
849 case SSL_CERTIFICATE_VERIFY:
850 ret = ssl_parse_certificate_verify(ssl);
851 break;
853 case SSL_CLIENT_CHANGE_CIPHER_SPEC:
854 ret = ssl_parse_change_cipher_spec(ssl);
855 break;
857 case SSL_CLIENT_FINISHED:
858 ret = ssl_parse_finished(ssl);
859 break;
862 * ==> ChangeCipherSpec
863 * Finished
865 case SSL_SERVER_CHANGE_CIPHER_SPEC:
866 ret = ssl_write_change_cipher_spec(ssl);
867 break;
869 case SSL_SERVER_FINISHED:
870 ret = ssl_write_finished(ssl);
871 break;
873 case SSL_FLUSH_BUFFERS:
874 SSL_DEBUG_MSG(2, ("handshake: done"));
875 ssl->state = SSL_HANDSHAKE_OVER;
876 break;
878 default:
879 SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
880 return (TROPICSSL_ERR_SSL_BAD_INPUT_DATA);
883 if (ret != 0)
884 break;
887 SSL_DEBUG_MSG(2, ("<= handshake server"));
889 return (ret);
892 #endif