xref: /dflybsd-src/crypto/libressl/ssl/ssl_both.c (revision cca6fc5243d2098262ea81f83ad5b28d3b800f4a)
1*cca6fc52SDaniel Fojt /* $OpenBSD: ssl_both.c,v 1.17 2020/03/12 17:15:33 jsing Exp $ */
272c33676SMaxim Ag /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
372c33676SMaxim Ag  * All rights reserved.
472c33676SMaxim Ag  *
572c33676SMaxim Ag  * This package is an SSL implementation written
672c33676SMaxim Ag  * by Eric Young (eay@cryptsoft.com).
772c33676SMaxim Ag  * The implementation was written so as to conform with Netscapes SSL.
872c33676SMaxim Ag  *
972c33676SMaxim Ag  * This library is free for commercial and non-commercial use as long as
1072c33676SMaxim Ag  * the following conditions are aheared to.  The following conditions
1172c33676SMaxim Ag  * apply to all code found in this distribution, be it the RC4, RSA,
1272c33676SMaxim Ag  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1372c33676SMaxim Ag  * included with this distribution is covered by the same copyright terms
1472c33676SMaxim Ag  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1572c33676SMaxim Ag  *
1672c33676SMaxim Ag  * Copyright remains Eric Young's, and as such any Copyright notices in
1772c33676SMaxim Ag  * the code are not to be removed.
1872c33676SMaxim Ag  * If this package is used in a product, Eric Young should be given attribution
1972c33676SMaxim Ag  * as the author of the parts of the library used.
2072c33676SMaxim Ag  * This can be in the form of a textual message at program startup or
2172c33676SMaxim Ag  * in documentation (online or textual) provided with the package.
2272c33676SMaxim Ag  *
2372c33676SMaxim Ag  * Redistribution and use in source and binary forms, with or without
2472c33676SMaxim Ag  * modification, are permitted provided that the following conditions
2572c33676SMaxim Ag  * are met:
2672c33676SMaxim Ag  * 1. Redistributions of source code must retain the copyright
2772c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer.
2872c33676SMaxim Ag  * 2. Redistributions in binary form must reproduce the above copyright
2972c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer in the
3072c33676SMaxim Ag  *    documentation and/or other materials provided with the distribution.
3172c33676SMaxim Ag  * 3. All advertising materials mentioning features or use of this software
3272c33676SMaxim Ag  *    must display the following acknowledgement:
3372c33676SMaxim Ag  *    "This product includes cryptographic software written by
3472c33676SMaxim Ag  *     Eric Young (eay@cryptsoft.com)"
3572c33676SMaxim Ag  *    The word 'cryptographic' can be left out if the rouines from the library
3672c33676SMaxim Ag  *    being used are not cryptographic related :-).
3772c33676SMaxim Ag  * 4. If you include any Windows specific code (or a derivative thereof) from
3872c33676SMaxim Ag  *    the apps directory (application code) you must include an acknowledgement:
3972c33676SMaxim Ag  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4072c33676SMaxim Ag  *
4172c33676SMaxim Ag  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4272c33676SMaxim Ag  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4372c33676SMaxim Ag  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4472c33676SMaxim Ag  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4572c33676SMaxim Ag  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4672c33676SMaxim Ag  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4772c33676SMaxim Ag  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4872c33676SMaxim Ag  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4972c33676SMaxim Ag  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5072c33676SMaxim Ag  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5172c33676SMaxim Ag  * SUCH DAMAGE.
5272c33676SMaxim Ag  *
5372c33676SMaxim Ag  * The licence and distribution terms for any publically available version or
5472c33676SMaxim Ag  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5572c33676SMaxim Ag  * copied and put under another distribution licence
5672c33676SMaxim Ag  * [including the GNU Public Licence.]
5772c33676SMaxim Ag  */
5872c33676SMaxim Ag /* ====================================================================
5972c33676SMaxim Ag  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
6072c33676SMaxim Ag  *
6172c33676SMaxim Ag  * Redistribution and use in source and binary forms, with or without
6272c33676SMaxim Ag  * modification, are permitted provided that the following conditions
6372c33676SMaxim Ag  * are met:
6472c33676SMaxim Ag  *
6572c33676SMaxim Ag  * 1. Redistributions of source code must retain the above copyright
6672c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer.
6772c33676SMaxim Ag  *
6872c33676SMaxim Ag  * 2. Redistributions in binary form must reproduce the above copyright
6972c33676SMaxim Ag  *    notice, this list of conditions and the following disclaimer in
7072c33676SMaxim Ag  *    the documentation and/or other materials provided with the
7172c33676SMaxim Ag  *    distribution.
7272c33676SMaxim Ag  *
7372c33676SMaxim Ag  * 3. All advertising materials mentioning features or use of this
7472c33676SMaxim Ag  *    software must display the following acknowledgment:
7572c33676SMaxim Ag  *    "This product includes software developed by the OpenSSL Project
7672c33676SMaxim Ag  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7772c33676SMaxim Ag  *
7872c33676SMaxim Ag  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
7972c33676SMaxim Ag  *    endorse or promote products derived from this software without
8072c33676SMaxim Ag  *    prior written permission. For written permission, please contact
8172c33676SMaxim Ag  *    openssl-core@openssl.org.
8272c33676SMaxim Ag  *
8372c33676SMaxim Ag  * 5. Products derived from this software may not be called "OpenSSL"
8472c33676SMaxim Ag  *    nor may "OpenSSL" appear in their names without prior written
8572c33676SMaxim Ag  *    permission of the OpenSSL Project.
8672c33676SMaxim Ag  *
8772c33676SMaxim Ag  * 6. Redistributions of any form whatsoever must retain the following
8872c33676SMaxim Ag  *    acknowledgment:
8972c33676SMaxim Ag  *    "This product includes software developed by the OpenSSL Project
9072c33676SMaxim Ag  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9172c33676SMaxim Ag  *
9272c33676SMaxim Ag  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9372c33676SMaxim Ag  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9472c33676SMaxim Ag  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9572c33676SMaxim Ag  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9672c33676SMaxim Ag  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9772c33676SMaxim Ag  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9872c33676SMaxim Ag  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9972c33676SMaxim Ag  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10072c33676SMaxim Ag  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10172c33676SMaxim Ag  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10272c33676SMaxim Ag  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10372c33676SMaxim Ag  * OF THE POSSIBILITY OF SUCH DAMAGE.
10472c33676SMaxim Ag  * ====================================================================
10572c33676SMaxim Ag  *
10672c33676SMaxim Ag  * This product includes cryptographic software written by Eric Young
10772c33676SMaxim Ag  * (eay@cryptsoft.com).  This product includes software written by Tim
10872c33676SMaxim Ag  * Hudson (tjh@cryptsoft.com).
10972c33676SMaxim Ag  *
11072c33676SMaxim Ag  */
11172c33676SMaxim Ag /* ====================================================================
11272c33676SMaxim Ag  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
11372c33676SMaxim Ag  * ECC cipher suite support in OpenSSL originally developed by
11472c33676SMaxim Ag  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
11572c33676SMaxim Ag  */
11672c33676SMaxim Ag 
11772c33676SMaxim Ag #include <limits.h>
11872c33676SMaxim Ag #include <stdio.h>
11972c33676SMaxim Ag #include <string.h>
12072c33676SMaxim Ag 
12172c33676SMaxim Ag #include "ssl_locl.h"
12272c33676SMaxim Ag 
12372c33676SMaxim Ag #include <openssl/buffer.h>
12472c33676SMaxim Ag #include <openssl/evp.h>
12572c33676SMaxim Ag #include <openssl/objects.h>
12672c33676SMaxim Ag #include <openssl/x509.h>
12772c33676SMaxim Ag 
12872c33676SMaxim Ag #include "bytestring.h"
12972c33676SMaxim Ag 
13072c33676SMaxim Ag /*
13172c33676SMaxim Ag  * Send s->internal->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
13272c33676SMaxim Ag  * SSL3_RT_CHANGE_CIPHER_SPEC).
13372c33676SMaxim Ag  */
13472c33676SMaxim Ag int
13572c33676SMaxim Ag ssl3_do_write(SSL *s, int type)
13672c33676SMaxim Ag {
13772c33676SMaxim Ag 	int ret;
13872c33676SMaxim Ag 
13972c33676SMaxim Ag 	ret = ssl3_write_bytes(s, type, &s->internal->init_buf->data[s->internal->init_off],
14072c33676SMaxim Ag 	    s->internal->init_num);
14172c33676SMaxim Ag 	if (ret < 0)
14272c33676SMaxim Ag 		return (-1);
14372c33676SMaxim Ag 
14472c33676SMaxim Ag 	if (type == SSL3_RT_HANDSHAKE)
14572c33676SMaxim Ag 		/*
14672c33676SMaxim Ag 		 * Should not be done for 'Hello Request's, but in that case
14772c33676SMaxim Ag 		 * we'll ignore the result anyway.
14872c33676SMaxim Ag 		 */
14972c33676SMaxim Ag 		tls1_transcript_record(s,
15072c33676SMaxim Ag 		    (unsigned char *)&s->internal->init_buf->data[s->internal->init_off], ret);
15172c33676SMaxim Ag 
15272c33676SMaxim Ag 	if (ret == s->internal->init_num) {
15372c33676SMaxim Ag 		if (s->internal->msg_callback)
15472c33676SMaxim Ag 			s->internal->msg_callback(1, s->version, type, s->internal->init_buf->data,
15572c33676SMaxim Ag 			    (size_t)(s->internal->init_off + s->internal->init_num), s,
15672c33676SMaxim Ag 			    s->internal->msg_callback_arg);
15772c33676SMaxim Ag 		return (1);
15872c33676SMaxim Ag 	}
15972c33676SMaxim Ag 
16072c33676SMaxim Ag 	s->internal->init_off += ret;
16172c33676SMaxim Ag 	s->internal->init_num -= ret;
16272c33676SMaxim Ag 
16372c33676SMaxim Ag 	return (0);
16472c33676SMaxim Ag }
16572c33676SMaxim Ag 
16672c33676SMaxim Ag int
16772c33676SMaxim Ag ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
16872c33676SMaxim Ag {
16972c33676SMaxim Ag 	CBB cbb, finished;
17072c33676SMaxim Ag 	int md_len;
17172c33676SMaxim Ag 
17272c33676SMaxim Ag 	memset(&cbb, 0, sizeof(cbb));
17372c33676SMaxim Ag 
17472c33676SMaxim Ag 	if (S3I(s)->hs.state == a) {
17572c33676SMaxim Ag 		md_len = TLS1_FINISH_MAC_LENGTH;
17672c33676SMaxim Ag 		OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
17772c33676SMaxim Ag 
17872c33676SMaxim Ag 		if (tls1_final_finish_mac(s, sender, slen,
17972c33676SMaxim Ag 		    S3I(s)->tmp.finish_md) != md_len)
18072c33676SMaxim Ag 			return (0);
18172c33676SMaxim Ag 		S3I(s)->tmp.finish_md_len = md_len;
18272c33676SMaxim Ag 
18372c33676SMaxim Ag 		/* Copy finished so we can use it for renegotiation checks. */
18472c33676SMaxim Ag 		if (s->internal->type == SSL_ST_CONNECT) {
18572c33676SMaxim Ag 			memcpy(S3I(s)->previous_client_finished,
18672c33676SMaxim Ag 			    S3I(s)->tmp.finish_md, md_len);
18772c33676SMaxim Ag 			S3I(s)->previous_client_finished_len = md_len;
18872c33676SMaxim Ag 		} else {
18972c33676SMaxim Ag 			memcpy(S3I(s)->previous_server_finished,
19072c33676SMaxim Ag 			    S3I(s)->tmp.finish_md, md_len);
19172c33676SMaxim Ag 			S3I(s)->previous_server_finished_len = md_len;
19272c33676SMaxim Ag 		}
19372c33676SMaxim Ag 
19472c33676SMaxim Ag 		if (!ssl3_handshake_msg_start(s, &cbb, &finished,
19572c33676SMaxim Ag 		    SSL3_MT_FINISHED))
19672c33676SMaxim Ag                         goto err;
19772c33676SMaxim Ag 		if (!CBB_add_bytes(&finished, S3I(s)->tmp.finish_md, md_len))
19872c33676SMaxim Ag 			goto err;
19972c33676SMaxim Ag 		if (!ssl3_handshake_msg_finish(s, &cbb))
20072c33676SMaxim Ag 			goto err;
20172c33676SMaxim Ag 
20272c33676SMaxim Ag 		S3I(s)->hs.state = b;
20372c33676SMaxim Ag 	}
20472c33676SMaxim Ag 
20572c33676SMaxim Ag 	return (ssl3_handshake_write(s));
20672c33676SMaxim Ag 
20772c33676SMaxim Ag  err:
20872c33676SMaxim Ag 	CBB_cleanup(&cbb);
20972c33676SMaxim Ag 
21072c33676SMaxim Ag 	return (-1);
21172c33676SMaxim Ag }
21272c33676SMaxim Ag 
21372c33676SMaxim Ag /*
21472c33676SMaxim Ag  * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
21572c33676SMaxim Ag  * so far.
21672c33676SMaxim Ag  */
21772c33676SMaxim Ag static void
21872c33676SMaxim Ag ssl3_take_mac(SSL *s)
21972c33676SMaxim Ag {
22072c33676SMaxim Ag 	const char *sender;
22172c33676SMaxim Ag 	int slen;
22272c33676SMaxim Ag 
22372c33676SMaxim Ag 	/*
22472c33676SMaxim Ag 	 * If no new cipher setup return immediately: other functions will
22572c33676SMaxim Ag 	 * set the appropriate error.
22672c33676SMaxim Ag 	 */
22772c33676SMaxim Ag 	if (S3I(s)->hs.new_cipher == NULL)
22872c33676SMaxim Ag 		return;
22972c33676SMaxim Ag 
23072c33676SMaxim Ag 	if (S3I(s)->hs.state & SSL_ST_CONNECT) {
23172c33676SMaxim Ag 		sender = TLS_MD_SERVER_FINISH_CONST;
23272c33676SMaxim Ag 		slen = TLS_MD_SERVER_FINISH_CONST_SIZE;
23372c33676SMaxim Ag 	} else {
23472c33676SMaxim Ag 		sender = TLS_MD_CLIENT_FINISH_CONST;
23572c33676SMaxim Ag 		slen = TLS_MD_CLIENT_FINISH_CONST_SIZE;
23672c33676SMaxim Ag 	}
23772c33676SMaxim Ag 
23872c33676SMaxim Ag 	S3I(s)->tmp.peer_finish_md_len =
23972c33676SMaxim Ag 	    tls1_final_finish_mac(s, sender, slen,
24072c33676SMaxim Ag 		S3I(s)->tmp.peer_finish_md);
24172c33676SMaxim Ag }
24272c33676SMaxim Ag 
24372c33676SMaxim Ag int
24472c33676SMaxim Ag ssl3_get_finished(SSL *s, int a, int b)
24572c33676SMaxim Ag {
24672c33676SMaxim Ag 	int al, ok, md_len;
24772c33676SMaxim Ag 	long n;
24872c33676SMaxim Ag 	CBS cbs;
24972c33676SMaxim Ag 
25072c33676SMaxim Ag 	/* should actually be 36+4 :-) */
251*cca6fc52SDaniel Fojt 	n = ssl3_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
25272c33676SMaxim Ag 	if (!ok)
25372c33676SMaxim Ag 		return ((int)n);
25472c33676SMaxim Ag 
25572c33676SMaxim Ag 	/* If this occurs, we have missed a message */
25672c33676SMaxim Ag 	if (!S3I(s)->change_cipher_spec) {
25772c33676SMaxim Ag 		al = SSL_AD_UNEXPECTED_MESSAGE;
25872c33676SMaxim Ag 		SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
25972c33676SMaxim Ag 		goto f_err;
26072c33676SMaxim Ag 	}
26172c33676SMaxim Ag 	S3I(s)->change_cipher_spec = 0;
26272c33676SMaxim Ag 
26372c33676SMaxim Ag 	md_len = TLS1_FINISH_MAC_LENGTH;
26472c33676SMaxim Ag 
26572c33676SMaxim Ag 	if (n < 0) {
26672c33676SMaxim Ag 		al = SSL_AD_DECODE_ERROR;
26772c33676SMaxim Ag 		SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
26872c33676SMaxim Ag 		goto f_err;
26972c33676SMaxim Ag 	}
27072c33676SMaxim Ag 
27172c33676SMaxim Ag 	CBS_init(&cbs, s->internal->init_msg, n);
27272c33676SMaxim Ag 
27372c33676SMaxim Ag 	if (S3I(s)->tmp.peer_finish_md_len != md_len ||
27472c33676SMaxim Ag 	    CBS_len(&cbs) != md_len) {
27572c33676SMaxim Ag 		al = SSL_AD_DECODE_ERROR;
27672c33676SMaxim Ag 		SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
27772c33676SMaxim Ag 		goto f_err;
27872c33676SMaxim Ag 	}
27972c33676SMaxim Ag 
28072c33676SMaxim Ag 	if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
28172c33676SMaxim Ag 		al = SSL_AD_DECRYPT_ERROR;
28272c33676SMaxim Ag 		SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
28372c33676SMaxim Ag 		goto f_err;
28472c33676SMaxim Ag 	}
28572c33676SMaxim Ag 
28672c33676SMaxim Ag 	/* Copy finished so we can use it for renegotiation checks. */
28772c33676SMaxim Ag 	OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
28872c33676SMaxim Ag 	if (s->internal->type == SSL_ST_ACCEPT) {
28972c33676SMaxim Ag 		memcpy(S3I(s)->previous_client_finished,
29072c33676SMaxim Ag 		    S3I(s)->tmp.peer_finish_md, md_len);
29172c33676SMaxim Ag 		S3I(s)->previous_client_finished_len = md_len;
29272c33676SMaxim Ag 	} else {
29372c33676SMaxim Ag 		memcpy(S3I(s)->previous_server_finished,
29472c33676SMaxim Ag 		    S3I(s)->tmp.peer_finish_md, md_len);
29572c33676SMaxim Ag 		S3I(s)->previous_server_finished_len = md_len;
29672c33676SMaxim Ag 	}
29772c33676SMaxim Ag 
29872c33676SMaxim Ag 	return (1);
29972c33676SMaxim Ag f_err:
30072c33676SMaxim Ag 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
30172c33676SMaxim Ag 	return (0);
30272c33676SMaxim Ag }
30372c33676SMaxim Ag 
30472c33676SMaxim Ag /* for these 2 messages, we need to
30572c33676SMaxim Ag  * ssl->enc_read_ctx			re-init
30672c33676SMaxim Ag  * ssl->s3->internal->read_sequence		zero
30772c33676SMaxim Ag  * ssl->s3->internal->read_mac_secret		re-init
30872c33676SMaxim Ag  * ssl->session->read_sym_enc		assign
30972c33676SMaxim Ag  * ssl->session->read_hash		assign
31072c33676SMaxim Ag  */
31172c33676SMaxim Ag int
31272c33676SMaxim Ag ssl3_send_change_cipher_spec(SSL *s, int a, int b)
31372c33676SMaxim Ag {
31472c33676SMaxim Ag 	size_t outlen;
31572c33676SMaxim Ag 	CBB cbb;
31672c33676SMaxim Ag 
31772c33676SMaxim Ag 	memset(&cbb, 0, sizeof(cbb));
31872c33676SMaxim Ag 
31972c33676SMaxim Ag 	if (S3I(s)->hs.state == a) {
32072c33676SMaxim Ag 		if (!CBB_init_fixed(&cbb, s->internal->init_buf->data,
32172c33676SMaxim Ag 		    s->internal->init_buf->length))
32272c33676SMaxim Ag 			goto err;
32372c33676SMaxim Ag 		if (!CBB_add_u8(&cbb, SSL3_MT_CCS))
32472c33676SMaxim Ag 			goto err;
32572c33676SMaxim Ag 		if (!CBB_finish(&cbb, NULL, &outlen))
32672c33676SMaxim Ag 			goto err;
32772c33676SMaxim Ag 
32872c33676SMaxim Ag 		if (outlen > INT_MAX)
32972c33676SMaxim Ag 			goto err;
33072c33676SMaxim Ag 
33172c33676SMaxim Ag 		s->internal->init_num = (int)outlen;
33272c33676SMaxim Ag 		s->internal->init_off = 0;
33372c33676SMaxim Ag 
33472c33676SMaxim Ag 		if (SSL_IS_DTLS(s)) {
33572c33676SMaxim Ag 			D1I(s)->handshake_write_seq =
33672c33676SMaxim Ag 			    D1I(s)->next_handshake_write_seq;
33772c33676SMaxim Ag 			dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
33872c33676SMaxim Ag 			    D1I(s)->handshake_write_seq, 0, 0);
33972c33676SMaxim Ag 			dtls1_buffer_message(s, 1);
34072c33676SMaxim Ag 		}
34172c33676SMaxim Ag 
34272c33676SMaxim Ag 		S3I(s)->hs.state = b;
34372c33676SMaxim Ag 	}
34472c33676SMaxim Ag 
34572c33676SMaxim Ag 	/* SSL3_ST_CW_CHANGE_B */
34672c33676SMaxim Ag 	return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
34772c33676SMaxim Ag 
34872c33676SMaxim Ag  err:
34972c33676SMaxim Ag 	CBB_cleanup(&cbb);
35072c33676SMaxim Ag 
35172c33676SMaxim Ag 	return -1;
35272c33676SMaxim Ag }
35372c33676SMaxim Ag 
35472c33676SMaxim Ag static int
35572c33676SMaxim Ag ssl3_add_cert(CBB *cbb, X509 *x)
35672c33676SMaxim Ag {
35772c33676SMaxim Ag 	unsigned char *data;
35872c33676SMaxim Ag 	int cert_len;
35972c33676SMaxim Ag 	int ret = 0;
36072c33676SMaxim Ag 	CBB cert;
36172c33676SMaxim Ag 
36272c33676SMaxim Ag 	if ((cert_len = i2d_X509(x, NULL)) < 0)
36372c33676SMaxim Ag 		goto err;
36472c33676SMaxim Ag 
36572c33676SMaxim Ag 	if (!CBB_add_u24_length_prefixed(cbb, &cert))
36672c33676SMaxim Ag 		goto err;
36772c33676SMaxim Ag 	if (!CBB_add_space(&cert, &data, cert_len))
36872c33676SMaxim Ag 		goto err;
36972c33676SMaxim Ag 	if (i2d_X509(x, &data) < 0)
37072c33676SMaxim Ag 		goto err;
37172c33676SMaxim Ag 	if (!CBB_flush(cbb))
37272c33676SMaxim Ag 		goto err;
37372c33676SMaxim Ag 
37472c33676SMaxim Ag 	ret = 1;
37572c33676SMaxim Ag 
37672c33676SMaxim Ag  err:
37772c33676SMaxim Ag 	return (ret);
37872c33676SMaxim Ag }
37972c33676SMaxim Ag 
38072c33676SMaxim Ag int
38172c33676SMaxim Ag ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
38272c33676SMaxim Ag {
38372c33676SMaxim Ag 	X509_STORE_CTX *xs_ctx = NULL;
38472c33676SMaxim Ag 	STACK_OF(X509) *chain;
38572c33676SMaxim Ag 	CBB cert_list;
38672c33676SMaxim Ag 	X509 *x;
38772c33676SMaxim Ag 	int ret = 0;
38872c33676SMaxim Ag 	int i;
38972c33676SMaxim Ag 
39072c33676SMaxim Ag 	if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
39172c33676SMaxim Ag 		goto err;
39272c33676SMaxim Ag 
39372c33676SMaxim Ag 	/* Send an empty certificate list when no certificate is available. */
39472c33676SMaxim Ag 	if (cpk == NULL)
39572c33676SMaxim Ag 		goto done;
39672c33676SMaxim Ag 
39772c33676SMaxim Ag 	if ((chain = cpk->chain) == NULL)
39872c33676SMaxim Ag 		chain = s->ctx->extra_certs;
39972c33676SMaxim Ag 
40072c33676SMaxim Ag 	if (chain != NULL || (s->internal->mode & SSL_MODE_NO_AUTO_CHAIN)) {
40172c33676SMaxim Ag 		if (!ssl3_add_cert(&cert_list, cpk->x509))
40272c33676SMaxim Ag 			goto err;
40372c33676SMaxim Ag 	} else {
40472c33676SMaxim Ag 		if ((xs_ctx = X509_STORE_CTX_new()) == NULL)
40572c33676SMaxim Ag 			goto err;
40672c33676SMaxim Ag 		if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store,
40772c33676SMaxim Ag 		    cpk->x509, NULL)) {
40872c33676SMaxim Ag 			SSLerror(s, ERR_R_X509_LIB);
40972c33676SMaxim Ag 			goto err;
41072c33676SMaxim Ag 		}
41172c33676SMaxim Ag 		X509_verify_cert(xs_ctx);
41272c33676SMaxim Ag 		ERR_clear_error();
41372c33676SMaxim Ag 		chain = xs_ctx->chain;
41472c33676SMaxim Ag 	}
41572c33676SMaxim Ag 
41672c33676SMaxim Ag 	for (i = 0; i < sk_X509_num(chain); i++) {
41772c33676SMaxim Ag 		x = sk_X509_value(chain, i);
41872c33676SMaxim Ag 		if (!ssl3_add_cert(&cert_list, x))
41972c33676SMaxim Ag 			goto err;
42072c33676SMaxim Ag 	}
42172c33676SMaxim Ag 
42272c33676SMaxim Ag  done:
42372c33676SMaxim Ag 	if (!CBB_flush(cbb))
42472c33676SMaxim Ag 		goto err;
42572c33676SMaxim Ag 
42672c33676SMaxim Ag 	ret = 1;
42772c33676SMaxim Ag 
42872c33676SMaxim Ag  err:
42972c33676SMaxim Ag 	X509_STORE_CTX_free(xs_ctx);
43072c33676SMaxim Ag 
43172c33676SMaxim Ag 	return (ret);
43272c33676SMaxim Ag }
43372c33676SMaxim Ag 
43472c33676SMaxim Ag /*
43572c33676SMaxim Ag  * Obtain handshake message of message type 'mt' (any if mt == -1),
43672c33676SMaxim Ag  * maximum acceptable body length 'max'.
43772c33676SMaxim Ag  * The first four bytes (msg_type and length) are read in state 'st1',
43872c33676SMaxim Ag  * the body is read in state 'stn'.
43972c33676SMaxim Ag  */
44072c33676SMaxim Ag long
44172c33676SMaxim Ag ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
44272c33676SMaxim Ag {
44372c33676SMaxim Ag 	unsigned char *p;
44472c33676SMaxim Ag 	uint32_t l;
44572c33676SMaxim Ag 	long n;
44672c33676SMaxim Ag 	int i, al;
44772c33676SMaxim Ag 	CBS cbs;
44872c33676SMaxim Ag 	uint8_t u8;
44972c33676SMaxim Ag 
450*cca6fc52SDaniel Fojt 	if (SSL_IS_DTLS(s))
451*cca6fc52SDaniel Fojt 		return (dtls1_get_message(s, st1, stn, mt, max, ok));
452*cca6fc52SDaniel Fojt 
45372c33676SMaxim Ag 	if (S3I(s)->tmp.reuse_message) {
45472c33676SMaxim Ag 		S3I(s)->tmp.reuse_message = 0;
45572c33676SMaxim Ag 		if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
45672c33676SMaxim Ag 			al = SSL_AD_UNEXPECTED_MESSAGE;
45772c33676SMaxim Ag 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
45872c33676SMaxim Ag 			goto f_err;
45972c33676SMaxim Ag 		}
46072c33676SMaxim Ag 		*ok = 1;
46172c33676SMaxim Ag 		s->internal->init_msg = s->internal->init_buf->data + 4;
46272c33676SMaxim Ag 		s->internal->init_num = (int)S3I(s)->tmp.message_size;
46372c33676SMaxim Ag 		return s->internal->init_num;
46472c33676SMaxim Ag 	}
46572c33676SMaxim Ag 
46672c33676SMaxim Ag 	p = (unsigned char *)s->internal->init_buf->data;
46772c33676SMaxim Ag 
46872c33676SMaxim Ag 	/* s->internal->init_num < 4 */
46972c33676SMaxim Ag 	if (S3I(s)->hs.state == st1) {
47072c33676SMaxim Ag 		int skip_message;
47172c33676SMaxim Ag 
47272c33676SMaxim Ag 		do {
47372c33676SMaxim Ag 			while (s->internal->init_num < 4) {
47472c33676SMaxim Ag 				i = s->method->internal->ssl_read_bytes(s,
47572c33676SMaxim Ag 				    SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
47672c33676SMaxim Ag 				    4 - s->internal->init_num, 0);
47772c33676SMaxim Ag 				if (i <= 0) {
47872c33676SMaxim Ag 					s->internal->rwstate = SSL_READING;
47972c33676SMaxim Ag 					*ok = 0;
48072c33676SMaxim Ag 					return i;
48172c33676SMaxim Ag 				}
48272c33676SMaxim Ag 				s->internal->init_num += i;
48372c33676SMaxim Ag 			}
48472c33676SMaxim Ag 
48572c33676SMaxim Ag 			skip_message = 0;
48672c33676SMaxim Ag 			if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
48772c33676SMaxim Ag 				/*
48872c33676SMaxim Ag 				 * The server may always send 'Hello Request'
48972c33676SMaxim Ag 				 * messages -- we are doing a handshake anyway
49072c33676SMaxim Ag 				 * now, so ignore them if their format is
49172c33676SMaxim Ag 				 * correct.  Does not count for 'Finished' MAC.
49272c33676SMaxim Ag 				 */
49372c33676SMaxim Ag 				if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
49472c33676SMaxim Ag 					s->internal->init_num = 0;
49572c33676SMaxim Ag 					skip_message = 1;
49672c33676SMaxim Ag 
49772c33676SMaxim Ag 					if (s->internal->msg_callback)
49872c33676SMaxim Ag 						s->internal->msg_callback(0, s->version,
49972c33676SMaxim Ag 						    SSL3_RT_HANDSHAKE, p, 4, s,
50072c33676SMaxim Ag 						    s->internal->msg_callback_arg);
50172c33676SMaxim Ag 				}
50272c33676SMaxim Ag 			}
50372c33676SMaxim Ag 		} while (skip_message);
50472c33676SMaxim Ag 
50572c33676SMaxim Ag 		/* s->internal->init_num == 4 */
50672c33676SMaxim Ag 
50772c33676SMaxim Ag 		if ((mt >= 0) && (*p != mt)) {
50872c33676SMaxim Ag 			al = SSL_AD_UNEXPECTED_MESSAGE;
50972c33676SMaxim Ag 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
51072c33676SMaxim Ag 			goto f_err;
51172c33676SMaxim Ag 		}
51272c33676SMaxim Ag 
51372c33676SMaxim Ag 		CBS_init(&cbs, p, 4);
51472c33676SMaxim Ag 		if (!CBS_get_u8(&cbs, &u8) ||
51572c33676SMaxim Ag 		    !CBS_get_u24(&cbs, &l)) {
51672c33676SMaxim Ag 			SSLerror(s, ERR_R_BUF_LIB);
51772c33676SMaxim Ag 			goto err;
51872c33676SMaxim Ag 		}
51972c33676SMaxim Ag 		S3I(s)->tmp.message_type = u8;
52072c33676SMaxim Ag 
52172c33676SMaxim Ag 		if (l > (unsigned long)max) {
52272c33676SMaxim Ag 			al = SSL_AD_ILLEGAL_PARAMETER;
52372c33676SMaxim Ag 			SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
52472c33676SMaxim Ag 			goto f_err;
52572c33676SMaxim Ag 		}
52672c33676SMaxim Ag 		if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
52772c33676SMaxim Ag 			SSLerror(s, ERR_R_BUF_LIB);
52872c33676SMaxim Ag 			goto err;
52972c33676SMaxim Ag 		}
53072c33676SMaxim Ag 		S3I(s)->tmp.message_size = l;
53172c33676SMaxim Ag 		S3I(s)->hs.state = stn;
53272c33676SMaxim Ag 
53372c33676SMaxim Ag 		s->internal->init_msg = s->internal->init_buf->data + 4;
53472c33676SMaxim Ag 		s->internal->init_num = 0;
53572c33676SMaxim Ag 	}
53672c33676SMaxim Ag 
53772c33676SMaxim Ag 	/* next state (stn) */
53872c33676SMaxim Ag 	p = s->internal->init_msg;
53972c33676SMaxim Ag 	n = S3I(s)->tmp.message_size - s->internal->init_num;
54072c33676SMaxim Ag 	while (n > 0) {
54172c33676SMaxim Ag 		i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
54272c33676SMaxim Ag 		    &p[s->internal->init_num], n, 0);
54372c33676SMaxim Ag 		if (i <= 0) {
54472c33676SMaxim Ag 			s->internal->rwstate = SSL_READING;
54572c33676SMaxim Ag 			*ok = 0;
54672c33676SMaxim Ag 			return i;
54772c33676SMaxim Ag 		}
54872c33676SMaxim Ag 		s->internal->init_num += i;
54972c33676SMaxim Ag 		n -= i;
55072c33676SMaxim Ag 	}
55172c33676SMaxim Ag 
55272c33676SMaxim Ag 	/* If receiving Finished, record MAC of prior handshake messages for
55372c33676SMaxim Ag 	 * Finished verification. */
55472c33676SMaxim Ag 	if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
55572c33676SMaxim Ag 		ssl3_take_mac(s);
55672c33676SMaxim Ag 
55772c33676SMaxim Ag 	/* Feed this message into MAC computation. */
55872c33676SMaxim Ag 	if (s->internal->mac_packet) {
55972c33676SMaxim Ag 		tls1_transcript_record(s, (unsigned char *)s->internal->init_buf->data,
56072c33676SMaxim Ag 		    s->internal->init_num + 4);
56172c33676SMaxim Ag 
56272c33676SMaxim Ag 		if (s->internal->msg_callback)
56372c33676SMaxim Ag 			s->internal->msg_callback(0, s->version,
56472c33676SMaxim Ag 			    SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
56572c33676SMaxim Ag 			    (size_t)s->internal->init_num + 4, s,
56672c33676SMaxim Ag 			    s->internal->msg_callback_arg);
56772c33676SMaxim Ag 	}
56872c33676SMaxim Ag 
56972c33676SMaxim Ag 	*ok = 1;
57072c33676SMaxim Ag 	return (s->internal->init_num);
57172c33676SMaxim Ag 
57272c33676SMaxim Ag f_err:
57372c33676SMaxim Ag 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
57472c33676SMaxim Ag err:
57572c33676SMaxim Ag 	*ok = 0;
57672c33676SMaxim Ag 	return (-1);
57772c33676SMaxim Ag }
57872c33676SMaxim Ag 
57972c33676SMaxim Ag int
58072c33676SMaxim Ag ssl_cert_type(X509 *x, EVP_PKEY *pkey)
58172c33676SMaxim Ag {
58272c33676SMaxim Ag 	EVP_PKEY *pk;
58372c33676SMaxim Ag 	int ret = -1, i;
58472c33676SMaxim Ag 
58572c33676SMaxim Ag 	if (pkey == NULL)
58672c33676SMaxim Ag 		pk = X509_get_pubkey(x);
58772c33676SMaxim Ag 	else
58872c33676SMaxim Ag 		pk = pkey;
58972c33676SMaxim Ag 	if (pk == NULL)
59072c33676SMaxim Ag 		goto err;
59172c33676SMaxim Ag 
59272c33676SMaxim Ag 	i = pk->type;
59372c33676SMaxim Ag 	if (i == EVP_PKEY_RSA) {
59472c33676SMaxim Ag 		ret = SSL_PKEY_RSA_ENC;
59572c33676SMaxim Ag 	} else if (i == EVP_PKEY_EC) {
59672c33676SMaxim Ag 		ret = SSL_PKEY_ECC;
59772c33676SMaxim Ag 	} else if (i == NID_id_GostR3410_2001 ||
59872c33676SMaxim Ag 	    i == NID_id_GostR3410_2001_cc) {
59972c33676SMaxim Ag 		ret = SSL_PKEY_GOST01;
60072c33676SMaxim Ag 	}
60172c33676SMaxim Ag 
60272c33676SMaxim Ag err:
60372c33676SMaxim Ag 	if (!pkey)
60472c33676SMaxim Ag 		EVP_PKEY_free(pk);
60572c33676SMaxim Ag 	return (ret);
60672c33676SMaxim Ag }
60772c33676SMaxim Ag 
60872c33676SMaxim Ag int
60972c33676SMaxim Ag ssl_verify_alarm_type(long type)
61072c33676SMaxim Ag {
61172c33676SMaxim Ag 	int al;
61272c33676SMaxim Ag 
61372c33676SMaxim Ag 	switch (type) {
61472c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
61572c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_GET_CRL:
61672c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
61772c33676SMaxim Ag 		al = SSL_AD_UNKNOWN_CA;
61872c33676SMaxim Ag 		break;
61972c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
62072c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
62172c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
62272c33676SMaxim Ag 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
62372c33676SMaxim Ag 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
62472c33676SMaxim Ag 	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
62572c33676SMaxim Ag 	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
62672c33676SMaxim Ag 	case X509_V_ERR_CERT_NOT_YET_VALID:
62772c33676SMaxim Ag 	case X509_V_ERR_CRL_NOT_YET_VALID:
62872c33676SMaxim Ag 	case X509_V_ERR_CERT_UNTRUSTED:
62972c33676SMaxim Ag 	case X509_V_ERR_CERT_REJECTED:
63072c33676SMaxim Ag 		al = SSL_AD_BAD_CERTIFICATE;
63172c33676SMaxim Ag 		break;
63272c33676SMaxim Ag 	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
63372c33676SMaxim Ag 	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
63472c33676SMaxim Ag 		al = SSL_AD_DECRYPT_ERROR;
63572c33676SMaxim Ag 		break;
63672c33676SMaxim Ag 	case X509_V_ERR_CERT_HAS_EXPIRED:
63772c33676SMaxim Ag 	case X509_V_ERR_CRL_HAS_EXPIRED:
63872c33676SMaxim Ag 		al = SSL_AD_CERTIFICATE_EXPIRED;
63972c33676SMaxim Ag 		break;
64072c33676SMaxim Ag 	case X509_V_ERR_CERT_REVOKED:
64172c33676SMaxim Ag 		al = SSL_AD_CERTIFICATE_REVOKED;
64272c33676SMaxim Ag 		break;
64372c33676SMaxim Ag 	case X509_V_ERR_OUT_OF_MEM:
64472c33676SMaxim Ag 		al = SSL_AD_INTERNAL_ERROR;
64572c33676SMaxim Ag 		break;
64672c33676SMaxim Ag 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
64772c33676SMaxim Ag 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
64872c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
64972c33676SMaxim Ag 	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
65072c33676SMaxim Ag 	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
65172c33676SMaxim Ag 	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
65272c33676SMaxim Ag 	case X509_V_ERR_INVALID_CA:
65372c33676SMaxim Ag 		al = SSL_AD_UNKNOWN_CA;
65472c33676SMaxim Ag 		break;
65572c33676SMaxim Ag 	case X509_V_ERR_APPLICATION_VERIFICATION:
65672c33676SMaxim Ag 		al = SSL_AD_HANDSHAKE_FAILURE;
65772c33676SMaxim Ag 		break;
65872c33676SMaxim Ag 	case X509_V_ERR_INVALID_PURPOSE:
65972c33676SMaxim Ag 		al = SSL_AD_UNSUPPORTED_CERTIFICATE;
66072c33676SMaxim Ag 		break;
66172c33676SMaxim Ag 	default:
66272c33676SMaxim Ag 		al = SSL_AD_CERTIFICATE_UNKNOWN;
66372c33676SMaxim Ag 		break;
66472c33676SMaxim Ag 	}
66572c33676SMaxim Ag 	return (al);
66672c33676SMaxim Ag }
66772c33676SMaxim Ag 
66872c33676SMaxim Ag int
66972c33676SMaxim Ag ssl3_setup_init_buffer(SSL *s)
67072c33676SMaxim Ag {
67172c33676SMaxim Ag 	BUF_MEM *buf = NULL;
67272c33676SMaxim Ag 
67372c33676SMaxim Ag 	if (s->internal->init_buf != NULL)
67472c33676SMaxim Ag 		return (1);
67572c33676SMaxim Ag 
67672c33676SMaxim Ag 	if ((buf = BUF_MEM_new()) == NULL)
67772c33676SMaxim Ag 		goto err;
67872c33676SMaxim Ag 	if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
67972c33676SMaxim Ag 		goto err;
68072c33676SMaxim Ag 
68172c33676SMaxim Ag 	s->internal->init_buf = buf;
68272c33676SMaxim Ag 	return (1);
68372c33676SMaxim Ag 
68472c33676SMaxim Ag err:
68572c33676SMaxim Ag 	BUF_MEM_free(buf);
68672c33676SMaxim Ag 	return (0);
68772c33676SMaxim Ag }
68872c33676SMaxim Ag 
68972c33676SMaxim Ag int
69072c33676SMaxim Ag ssl3_setup_read_buffer(SSL *s)
69172c33676SMaxim Ag {
69272c33676SMaxim Ag 	unsigned char *p;
69372c33676SMaxim Ag 	size_t len, align, headerlen;
69472c33676SMaxim Ag 
69572c33676SMaxim Ag 	if (SSL_IS_DTLS(s))
69672c33676SMaxim Ag 		headerlen = DTLS1_RT_HEADER_LENGTH;
69772c33676SMaxim Ag 	else
69872c33676SMaxim Ag 		headerlen = SSL3_RT_HEADER_LENGTH;
69972c33676SMaxim Ag 
70072c33676SMaxim Ag 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
70172c33676SMaxim Ag 
70272c33676SMaxim Ag 	if (S3I(s)->rbuf.buf == NULL) {
70372c33676SMaxim Ag 		len = SSL3_RT_MAX_PLAIN_LENGTH +
70472c33676SMaxim Ag 		    SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
705*cca6fc52SDaniel Fojt 		if ((p = calloc(1, len)) == NULL)
70672c33676SMaxim Ag 			goto err;
70772c33676SMaxim Ag 		S3I(s)->rbuf.buf = p;
70872c33676SMaxim Ag 		S3I(s)->rbuf.len = len;
70972c33676SMaxim Ag 	}
71072c33676SMaxim Ag 
71172c33676SMaxim Ag 	s->internal->packet = &(S3I(s)->rbuf.buf[0]);
71272c33676SMaxim Ag 	return 1;
71372c33676SMaxim Ag 
71472c33676SMaxim Ag err:
71572c33676SMaxim Ag 	SSLerror(s, ERR_R_MALLOC_FAILURE);
71672c33676SMaxim Ag 	return 0;
71772c33676SMaxim Ag }
71872c33676SMaxim Ag 
71972c33676SMaxim Ag int
72072c33676SMaxim Ag ssl3_setup_write_buffer(SSL *s)
72172c33676SMaxim Ag {
72272c33676SMaxim Ag 	unsigned char *p;
72372c33676SMaxim Ag 	size_t len, align, headerlen;
72472c33676SMaxim Ag 
72572c33676SMaxim Ag 	if (SSL_IS_DTLS(s))
72672c33676SMaxim Ag 		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
72772c33676SMaxim Ag 	else
72872c33676SMaxim Ag 		headerlen = SSL3_RT_HEADER_LENGTH;
72972c33676SMaxim Ag 
73072c33676SMaxim Ag 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
73172c33676SMaxim Ag 
73272c33676SMaxim Ag 	if (S3I(s)->wbuf.buf == NULL) {
73372c33676SMaxim Ag 		len = s->max_send_fragment +
73472c33676SMaxim Ag 		    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
73572c33676SMaxim Ag 		if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
73672c33676SMaxim Ag 			len += headerlen + align +
73772c33676SMaxim Ag 			    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
73872c33676SMaxim Ag 
739*cca6fc52SDaniel Fojt 		if ((p = calloc(1, len)) == NULL)
74072c33676SMaxim Ag 			goto err;
74172c33676SMaxim Ag 		S3I(s)->wbuf.buf = p;
74272c33676SMaxim Ag 		S3I(s)->wbuf.len = len;
74372c33676SMaxim Ag 	}
74472c33676SMaxim Ag 
74572c33676SMaxim Ag 	return 1;
74672c33676SMaxim Ag 
74772c33676SMaxim Ag err:
74872c33676SMaxim Ag 	SSLerror(s, ERR_R_MALLOC_FAILURE);
74972c33676SMaxim Ag 	return 0;
75072c33676SMaxim Ag }
75172c33676SMaxim Ag 
75272c33676SMaxim Ag int
75372c33676SMaxim Ag ssl3_setup_buffers(SSL *s)
75472c33676SMaxim Ag {
75572c33676SMaxim Ag 	if (!ssl3_setup_read_buffer(s))
75672c33676SMaxim Ag 		return 0;
75772c33676SMaxim Ag 	if (!ssl3_setup_write_buffer(s))
75872c33676SMaxim Ag 		return 0;
75972c33676SMaxim Ag 	return 1;
76072c33676SMaxim Ag }
76172c33676SMaxim Ag 
76272c33676SMaxim Ag int
76372c33676SMaxim Ag ssl3_release_write_buffer(SSL *s)
76472c33676SMaxim Ag {
76572c33676SMaxim Ag 	free(S3I(s)->wbuf.buf);
76672c33676SMaxim Ag 	S3I(s)->wbuf.buf = NULL;
76772c33676SMaxim Ag 	return 1;
76872c33676SMaxim Ag }
76972c33676SMaxim Ag 
77072c33676SMaxim Ag int
77172c33676SMaxim Ag ssl3_release_read_buffer(SSL *s)
77272c33676SMaxim Ag {
77372c33676SMaxim Ag 	free(S3I(s)->rbuf.buf);
77472c33676SMaxim Ag 	S3I(s)->rbuf.buf = NULL;
77572c33676SMaxim Ag 	return 1;
77672c33676SMaxim Ag }
777