xref: /openbsd-src/lib/libssl/ssl_both.c (revision ab211f3d6a2af7f816fd335de234f45018dbbf23)
1*ab211f3dSjsing /* $OpenBSD: ssl_both.c,v 1.11 2017/10/08 16:24:02 jsing Exp $ */
23395f70eSjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
33395f70eSjsing  * All rights reserved.
43395f70eSjsing  *
53395f70eSjsing  * This package is an SSL implementation written
63395f70eSjsing  * by Eric Young (eay@cryptsoft.com).
73395f70eSjsing  * The implementation was written so as to conform with Netscapes SSL.
83395f70eSjsing  *
93395f70eSjsing  * This library is free for commercial and non-commercial use as long as
103395f70eSjsing  * the following conditions are aheared to.  The following conditions
113395f70eSjsing  * apply to all code found in this distribution, be it the RC4, RSA,
123395f70eSjsing  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
133395f70eSjsing  * included with this distribution is covered by the same copyright terms
143395f70eSjsing  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
153395f70eSjsing  *
163395f70eSjsing  * Copyright remains Eric Young's, and as such any Copyright notices in
173395f70eSjsing  * the code are not to be removed.
183395f70eSjsing  * If this package is used in a product, Eric Young should be given attribution
193395f70eSjsing  * as the author of the parts of the library used.
203395f70eSjsing  * This can be in the form of a textual message at program startup or
213395f70eSjsing  * in documentation (online or textual) provided with the package.
223395f70eSjsing  *
233395f70eSjsing  * Redistribution and use in source and binary forms, with or without
243395f70eSjsing  * modification, are permitted provided that the following conditions
253395f70eSjsing  * are met:
263395f70eSjsing  * 1. Redistributions of source code must retain the copyright
273395f70eSjsing  *    notice, this list of conditions and the following disclaimer.
283395f70eSjsing  * 2. Redistributions in binary form must reproduce the above copyright
293395f70eSjsing  *    notice, this list of conditions and the following disclaimer in the
303395f70eSjsing  *    documentation and/or other materials provided with the distribution.
313395f70eSjsing  * 3. All advertising materials mentioning features or use of this software
323395f70eSjsing  *    must display the following acknowledgement:
333395f70eSjsing  *    "This product includes cryptographic software written by
343395f70eSjsing  *     Eric Young (eay@cryptsoft.com)"
353395f70eSjsing  *    The word 'cryptographic' can be left out if the rouines from the library
363395f70eSjsing  *    being used are not cryptographic related :-).
373395f70eSjsing  * 4. If you include any Windows specific code (or a derivative thereof) from
383395f70eSjsing  *    the apps directory (application code) you must include an acknowledgement:
393395f70eSjsing  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
403395f70eSjsing  *
413395f70eSjsing  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
423395f70eSjsing  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
433395f70eSjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
443395f70eSjsing  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
453395f70eSjsing  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
463395f70eSjsing  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
473395f70eSjsing  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
483395f70eSjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
493395f70eSjsing  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
503395f70eSjsing  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
513395f70eSjsing  * SUCH DAMAGE.
523395f70eSjsing  *
533395f70eSjsing  * The licence and distribution terms for any publically available version or
543395f70eSjsing  * derivative of this code cannot be changed.  i.e. this code cannot simply be
553395f70eSjsing  * copied and put under another distribution licence
563395f70eSjsing  * [including the GNU Public Licence.]
573395f70eSjsing  */
583395f70eSjsing /* ====================================================================
593395f70eSjsing  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
603395f70eSjsing  *
613395f70eSjsing  * Redistribution and use in source and binary forms, with or without
623395f70eSjsing  * modification, are permitted provided that the following conditions
633395f70eSjsing  * are met:
643395f70eSjsing  *
653395f70eSjsing  * 1. Redistributions of source code must retain the above copyright
663395f70eSjsing  *    notice, this list of conditions and the following disclaimer.
673395f70eSjsing  *
683395f70eSjsing  * 2. Redistributions in binary form must reproduce the above copyright
693395f70eSjsing  *    notice, this list of conditions and the following disclaimer in
703395f70eSjsing  *    the documentation and/or other materials provided with the
713395f70eSjsing  *    distribution.
723395f70eSjsing  *
733395f70eSjsing  * 3. All advertising materials mentioning features or use of this
743395f70eSjsing  *    software must display the following acknowledgment:
753395f70eSjsing  *    "This product includes software developed by the OpenSSL Project
763395f70eSjsing  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
773395f70eSjsing  *
783395f70eSjsing  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
793395f70eSjsing  *    endorse or promote products derived from this software without
803395f70eSjsing  *    prior written permission. For written permission, please contact
813395f70eSjsing  *    openssl-core@openssl.org.
823395f70eSjsing  *
833395f70eSjsing  * 5. Products derived from this software may not be called "OpenSSL"
843395f70eSjsing  *    nor may "OpenSSL" appear in their names without prior written
853395f70eSjsing  *    permission of the OpenSSL Project.
863395f70eSjsing  *
873395f70eSjsing  * 6. Redistributions of any form whatsoever must retain the following
883395f70eSjsing  *    acknowledgment:
893395f70eSjsing  *    "This product includes software developed by the OpenSSL Project
903395f70eSjsing  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
913395f70eSjsing  *
923395f70eSjsing  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
933395f70eSjsing  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
943395f70eSjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
953395f70eSjsing  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
963395f70eSjsing  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
973395f70eSjsing  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
983395f70eSjsing  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
993395f70eSjsing  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1003395f70eSjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1013395f70eSjsing  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1023395f70eSjsing  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1033395f70eSjsing  * OF THE POSSIBILITY OF SUCH DAMAGE.
1043395f70eSjsing  * ====================================================================
1053395f70eSjsing  *
1063395f70eSjsing  * This product includes cryptographic software written by Eric Young
1073395f70eSjsing  * (eay@cryptsoft.com).  This product includes software written by Tim
1083395f70eSjsing  * Hudson (tjh@cryptsoft.com).
1093395f70eSjsing  *
1103395f70eSjsing  */
1113395f70eSjsing /* ====================================================================
1123395f70eSjsing  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1133395f70eSjsing  * ECC cipher suite support in OpenSSL originally developed by
1143395f70eSjsing  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1153395f70eSjsing  */
1163395f70eSjsing 
1173395f70eSjsing #include <limits.h>
1183395f70eSjsing #include <stdio.h>
1193395f70eSjsing #include <string.h>
1203395f70eSjsing 
1213395f70eSjsing #include "ssl_locl.h"
1223395f70eSjsing 
1233395f70eSjsing #include <openssl/buffer.h>
1243395f70eSjsing #include <openssl/evp.h>
1253395f70eSjsing #include <openssl/objects.h>
1263395f70eSjsing #include <openssl/x509.h>
1273395f70eSjsing 
1283395f70eSjsing #include "bytestring.h"
1293395f70eSjsing 
1303395f70eSjsing /*
1313395f70eSjsing  * Send s->internal->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
1323395f70eSjsing  * SSL3_RT_CHANGE_CIPHER_SPEC).
1333395f70eSjsing  */
1343395f70eSjsing int
1353395f70eSjsing ssl3_do_write(SSL *s, int type)
1363395f70eSjsing {
1373395f70eSjsing 	int ret;
1383395f70eSjsing 
1393395f70eSjsing 	ret = ssl3_write_bytes(s, type, &s->internal->init_buf->data[s->internal->init_off],
1403395f70eSjsing 	    s->internal->init_num);
1413395f70eSjsing 	if (ret < 0)
1423395f70eSjsing 		return (-1);
1433395f70eSjsing 
1443395f70eSjsing 	if (type == SSL3_RT_HANDSHAKE)
1453395f70eSjsing 		/*
1463395f70eSjsing 		 * Should not be done for 'Hello Request's, but in that case
1473395f70eSjsing 		 * we'll ignore the result anyway.
1483395f70eSjsing 		 */
1493395f70eSjsing 		tls1_finish_mac(s,
1503395f70eSjsing 		    (unsigned char *)&s->internal->init_buf->data[s->internal->init_off], ret);
1513395f70eSjsing 
1523395f70eSjsing 	if (ret == s->internal->init_num) {
1533395f70eSjsing 		if (s->internal->msg_callback)
1543395f70eSjsing 			s->internal->msg_callback(1, s->version, type, s->internal->init_buf->data,
1553395f70eSjsing 			    (size_t)(s->internal->init_off + s->internal->init_num), s,
1563395f70eSjsing 			    s->internal->msg_callback_arg);
1573395f70eSjsing 		return (1);
1583395f70eSjsing 	}
1593395f70eSjsing 
1603395f70eSjsing 	s->internal->init_off += ret;
1613395f70eSjsing 	s->internal->init_num -= ret;
1623395f70eSjsing 
1633395f70eSjsing 	return (0);
1643395f70eSjsing }
1653395f70eSjsing 
1663395f70eSjsing int
1673395f70eSjsing ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
1683395f70eSjsing {
169a9e43a46Sjsing 	CBB cbb, finished;
1703395f70eSjsing 	int md_len;
1713395f70eSjsing 
172a9e43a46Sjsing 	memset(&cbb, 0, sizeof(cbb));
173a9e43a46Sjsing 
174440bed4fSbeck 	if (S3I(s)->hs.state == a) {
17553f78dfdSjsing 		md_len = TLS1_FINISH_MAC_LENGTH;
1763395f70eSjsing 		OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
1773395f70eSjsing 
17853f78dfdSjsing 		if (tls1_final_finish_mac(s, sender, slen,
1793395f70eSjsing 		    S3I(s)->tmp.finish_md) != md_len)
1803395f70eSjsing 			return (0);
1813395f70eSjsing 		S3I(s)->tmp.finish_md_len = md_len;
1823395f70eSjsing 
1833395f70eSjsing 		/* Copy finished so we can use it for renegotiation checks. */
1843395f70eSjsing 		if (s->internal->type == SSL_ST_CONNECT) {
1853395f70eSjsing 			memcpy(S3I(s)->previous_client_finished,
1863395f70eSjsing 			    S3I(s)->tmp.finish_md, md_len);
1873395f70eSjsing 			S3I(s)->previous_client_finished_len = md_len;
1883395f70eSjsing 		} else {
1893395f70eSjsing 			memcpy(S3I(s)->previous_server_finished,
1903395f70eSjsing 			    S3I(s)->tmp.finish_md, md_len);
1913395f70eSjsing 			S3I(s)->previous_server_finished_len = md_len;
1923395f70eSjsing 		}
1933395f70eSjsing 
194a9e43a46Sjsing 		if (!ssl3_handshake_msg_start_cbb(s, &cbb, &finished,
195a9e43a46Sjsing 		    SSL3_MT_FINISHED))
196a9e43a46Sjsing                         goto err;
197a9e43a46Sjsing 		if (!CBB_add_bytes(&finished, S3I(s)->tmp.finish_md, md_len))
198a9e43a46Sjsing 			goto err;
199a9e43a46Sjsing 		if (!ssl3_handshake_msg_finish_cbb(s, &cbb))
200a9e43a46Sjsing 			goto err;
2013395f70eSjsing 
202440bed4fSbeck 		S3I(s)->hs.state = b;
2033395f70eSjsing 	}
2043395f70eSjsing 
2053395f70eSjsing 	return (ssl3_handshake_write(s));
206a9e43a46Sjsing 
207a9e43a46Sjsing  err:
208a9e43a46Sjsing 	CBB_cleanup(&cbb);
209a9e43a46Sjsing 
210a9e43a46Sjsing 	return (-1);
2113395f70eSjsing }
2123395f70eSjsing 
2133395f70eSjsing /*
2143395f70eSjsing  * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
2153395f70eSjsing  * so far.
2163395f70eSjsing  */
2173395f70eSjsing static void
2183395f70eSjsing ssl3_take_mac(SSL *s)
2193395f70eSjsing {
2203395f70eSjsing 	const char *sender;
2213395f70eSjsing 	int slen;
2223395f70eSjsing 
2233395f70eSjsing 	/*
2243395f70eSjsing 	 * If no new cipher setup return immediately: other functions will
2253395f70eSjsing 	 * set the appropriate error.
2263395f70eSjsing 	 */
2274de66e6cSbeck 	if (S3I(s)->hs.new_cipher == NULL)
2283395f70eSjsing 		return;
2293395f70eSjsing 
230440bed4fSbeck 	if (S3I(s)->hs.state & SSL_ST_CONNECT) {
23153f78dfdSjsing 		sender = TLS_MD_SERVER_FINISH_CONST;
23253f78dfdSjsing 		slen = TLS_MD_SERVER_FINISH_CONST_SIZE;
2333395f70eSjsing 	} else {
23453f78dfdSjsing 		sender = TLS_MD_CLIENT_FINISH_CONST;
23553f78dfdSjsing 		slen = TLS_MD_CLIENT_FINISH_CONST_SIZE;
2363395f70eSjsing 	}
2373395f70eSjsing 
2383395f70eSjsing 	S3I(s)->tmp.peer_finish_md_len =
23953f78dfdSjsing 	    tls1_final_finish_mac(s, sender, slen,
2403395f70eSjsing 		S3I(s)->tmp.peer_finish_md);
2413395f70eSjsing }
2423395f70eSjsing 
2433395f70eSjsing int
2443395f70eSjsing ssl3_get_finished(SSL *s, int a, int b)
2453395f70eSjsing {
2463395f70eSjsing 	int al, ok, md_len;
2473395f70eSjsing 	long n;
2483395f70eSjsing 	CBS cbs;
2493395f70eSjsing 
2503395f70eSjsing 	/* should actually be 36+4 :-) */
2513395f70eSjsing 	n = s->method->internal->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
2523395f70eSjsing 	if (!ok)
2533395f70eSjsing 		return ((int)n);
2543395f70eSjsing 
2553395f70eSjsing 	/* If this occurs, we have missed a message */
2563395f70eSjsing 	if (!S3I(s)->change_cipher_spec) {
2573395f70eSjsing 		al = SSL_AD_UNEXPECTED_MESSAGE;
258c9d7abb7Sbeck 		SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
2593395f70eSjsing 		goto f_err;
2603395f70eSjsing 	}
2613395f70eSjsing 	S3I(s)->change_cipher_spec = 0;
2623395f70eSjsing 
26353f78dfdSjsing 	md_len = TLS1_FINISH_MAC_LENGTH;
2643395f70eSjsing 
2653395f70eSjsing 	if (n < 0) {
2663395f70eSjsing 		al = SSL_AD_DECODE_ERROR;
267c9d7abb7Sbeck 		SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
2683395f70eSjsing 		goto f_err;
2693395f70eSjsing 	}
2703395f70eSjsing 
2713395f70eSjsing 	CBS_init(&cbs, s->internal->init_msg, n);
2723395f70eSjsing 
2733395f70eSjsing 	if (S3I(s)->tmp.peer_finish_md_len != md_len ||
2743395f70eSjsing 	    CBS_len(&cbs) != md_len) {
2753395f70eSjsing 		al = SSL_AD_DECODE_ERROR;
276c9d7abb7Sbeck 		SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
2773395f70eSjsing 		goto f_err;
2783395f70eSjsing 	}
2793395f70eSjsing 
2803395f70eSjsing 	if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
2813395f70eSjsing 		al = SSL_AD_DECRYPT_ERROR;
282c9d7abb7Sbeck 		SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
2833395f70eSjsing 		goto f_err;
2843395f70eSjsing 	}
2853395f70eSjsing 
2863395f70eSjsing 	/* Copy finished so we can use it for renegotiation checks. */
2873395f70eSjsing 	OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
2883395f70eSjsing 	if (s->internal->type == SSL_ST_ACCEPT) {
2893395f70eSjsing 		memcpy(S3I(s)->previous_client_finished,
2903395f70eSjsing 		    S3I(s)->tmp.peer_finish_md, md_len);
2913395f70eSjsing 		S3I(s)->previous_client_finished_len = md_len;
2923395f70eSjsing 	} else {
2933395f70eSjsing 		memcpy(S3I(s)->previous_server_finished,
2943395f70eSjsing 		    S3I(s)->tmp.peer_finish_md, md_len);
2953395f70eSjsing 		S3I(s)->previous_server_finished_len = md_len;
2963395f70eSjsing 	}
2973395f70eSjsing 
2983395f70eSjsing 	return (1);
2993395f70eSjsing f_err:
3003395f70eSjsing 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
3013395f70eSjsing 	return (0);
3023395f70eSjsing }
3033395f70eSjsing 
3043395f70eSjsing /* for these 2 messages, we need to
3053395f70eSjsing  * ssl->enc_read_ctx			re-init
3063395f70eSjsing  * ssl->s3->internal->read_sequence		zero
3073395f70eSjsing  * ssl->s3->internal->read_mac_secret		re-init
3083395f70eSjsing  * ssl->session->read_sym_enc		assign
3093395f70eSjsing  * ssl->session->read_hash		assign
3103395f70eSjsing  */
3113395f70eSjsing int
3123395f70eSjsing ssl3_send_change_cipher_spec(SSL *s, int a, int b)
3133395f70eSjsing {
314*ab211f3dSjsing 	size_t outlen;
315*ab211f3dSjsing 	CBB cbb;
316*ab211f3dSjsing 
317*ab211f3dSjsing 	memset(&cbb, 0, sizeof(cbb));
3183395f70eSjsing 
319440bed4fSbeck 	if (S3I(s)->hs.state == a) {
320*ab211f3dSjsing 		if (!CBB_init_fixed(&cbb, s->internal->init_buf->data,
321*ab211f3dSjsing 		    s->internal->init_buf->length))
322*ab211f3dSjsing 			goto err;
323*ab211f3dSjsing 		if (!CBB_add_u8(&cbb, SSL3_MT_CCS))
324*ab211f3dSjsing 			goto err;
325*ab211f3dSjsing 		if (!CBB_finish(&cbb, NULL, &outlen))
326*ab211f3dSjsing 			goto err;
327*ab211f3dSjsing 
328*ab211f3dSjsing 		if (outlen > INT_MAX)
329*ab211f3dSjsing 			goto err;
330*ab211f3dSjsing 
331*ab211f3dSjsing 		s->internal->init_num = (int)outlen;
3323395f70eSjsing 		s->internal->init_off = 0;
3333395f70eSjsing 
334*ab211f3dSjsing 		if (SSL_IS_DTLS(s)) {
335*ab211f3dSjsing 			D1I(s)->handshake_write_seq =
336*ab211f3dSjsing 			    D1I(s)->next_handshake_write_seq;
337*ab211f3dSjsing 			dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
338*ab211f3dSjsing 			    D1I(s)->handshake_write_seq, 0, 0);
339*ab211f3dSjsing 			dtls1_buffer_message(s, 1);
340*ab211f3dSjsing 		}
341*ab211f3dSjsing 
342440bed4fSbeck 		S3I(s)->hs.state = b;
3433395f70eSjsing 	}
3443395f70eSjsing 
3453395f70eSjsing 	/* SSL3_ST_CW_CHANGE_B */
346*ab211f3dSjsing 	return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
347*ab211f3dSjsing 
348*ab211f3dSjsing  err:
349*ab211f3dSjsing 	CBB_cleanup(&cbb);
350*ab211f3dSjsing 
351*ab211f3dSjsing 	return -1;
3523395f70eSjsing }
3533395f70eSjsing 
3543395f70eSjsing static int
3553395f70eSjsing ssl3_add_cert(CBB *cbb, X509 *x)
3563395f70eSjsing {
3573395f70eSjsing 	unsigned char *data;
3583395f70eSjsing 	int cert_len;
3593395f70eSjsing 	int ret = 0;
3603395f70eSjsing 	CBB cert;
3613395f70eSjsing 
3623395f70eSjsing 	if ((cert_len = i2d_X509(x, NULL)) < 0)
3633395f70eSjsing 		goto err;
3643395f70eSjsing 
3653395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert))
3663395f70eSjsing 		goto err;
3673395f70eSjsing 	if (!CBB_add_space(&cert, &data, cert_len))
3683395f70eSjsing 		goto err;
3693395f70eSjsing 	if (i2d_X509(x, &data) < 0)
3703395f70eSjsing 		goto err;
3713395f70eSjsing 	if (!CBB_flush(cbb))
3723395f70eSjsing 		goto err;
3733395f70eSjsing 
3743395f70eSjsing 	ret = 1;
3753395f70eSjsing 
3763395f70eSjsing  err:
3773395f70eSjsing 	return (ret);
3783395f70eSjsing }
3793395f70eSjsing 
3803395f70eSjsing int
3813395f70eSjsing ssl3_output_cert_chain(SSL *s, CBB *cbb, X509 *x)
3823395f70eSjsing {
3833395f70eSjsing 	int no_chain = 0;
3843395f70eSjsing 	CBB cert_list;
3853395f70eSjsing 	int ret = 0;
3863395f70eSjsing 	int i;
3873395f70eSjsing 
3883395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
3893395f70eSjsing 		goto err;
3903395f70eSjsing 
3913395f70eSjsing 	if ((s->internal->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
3923395f70eSjsing 		no_chain = 1;
3933395f70eSjsing 
3943395f70eSjsing 	/* TLSv1 sends a chain with nothing in it, instead of an alert. */
3953395f70eSjsing 	if (x != NULL) {
3963395f70eSjsing 		if (no_chain) {
3973395f70eSjsing 			if (!ssl3_add_cert(&cert_list, x))
3983395f70eSjsing 				goto err;
3993395f70eSjsing 		} else {
4003395f70eSjsing 			X509_STORE_CTX xs_ctx;
4013395f70eSjsing 
4023395f70eSjsing 			if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store,
4033395f70eSjsing 			    x, NULL)) {
404c9d7abb7Sbeck 				SSLerror(s, ERR_R_X509_LIB);
4053395f70eSjsing 				goto err;
4063395f70eSjsing 			}
4073395f70eSjsing 			X509_verify_cert(&xs_ctx);
4083395f70eSjsing 
4093395f70eSjsing 			/* Don't leave errors in the queue. */
4103395f70eSjsing 			ERR_clear_error();
4113395f70eSjsing 			for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
4123395f70eSjsing 				x = sk_X509_value(xs_ctx.chain, i);
4133395f70eSjsing 				if (!ssl3_add_cert(&cert_list, x)) {
4143395f70eSjsing 					X509_STORE_CTX_cleanup(&xs_ctx);
4153395f70eSjsing 					goto err;
4163395f70eSjsing 				}
4173395f70eSjsing 			}
4183395f70eSjsing 			X509_STORE_CTX_cleanup(&xs_ctx);
4193395f70eSjsing 		}
4203395f70eSjsing 	}
4213395f70eSjsing 
4223395f70eSjsing 	/* Thawte special :-) */
4233395f70eSjsing 	for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) {
4243395f70eSjsing 		x = sk_X509_value(s->ctx->extra_certs, i);
4253395f70eSjsing 		if (!ssl3_add_cert(&cert_list, x))
4263395f70eSjsing 			goto err;
4273395f70eSjsing 	}
4283395f70eSjsing 
4293395f70eSjsing 	if (!CBB_flush(cbb))
4303395f70eSjsing 		goto err;
4313395f70eSjsing 
4323395f70eSjsing 	ret = 1;
4333395f70eSjsing 
4343395f70eSjsing  err:
4353395f70eSjsing 	return (ret);
4363395f70eSjsing }
4373395f70eSjsing 
4383395f70eSjsing /*
4393395f70eSjsing  * Obtain handshake message of message type 'mt' (any if mt == -1),
4403395f70eSjsing  * maximum acceptable body length 'max'.
4413395f70eSjsing  * The first four bytes (msg_type and length) are read in state 'st1',
4423395f70eSjsing  * the body is read in state 'stn'.
4433395f70eSjsing  */
4443395f70eSjsing long
4453395f70eSjsing ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
4463395f70eSjsing {
4473395f70eSjsing 	unsigned char *p;
4483395f70eSjsing 	uint32_t l;
4493395f70eSjsing 	long n;
4503395f70eSjsing 	int i, al;
4513395f70eSjsing 	CBS cbs;
4523395f70eSjsing 	uint8_t u8;
4533395f70eSjsing 
4543395f70eSjsing 	if (S3I(s)->tmp.reuse_message) {
4553395f70eSjsing 		S3I(s)->tmp.reuse_message = 0;
4563395f70eSjsing 		if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
4573395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
458c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
4593395f70eSjsing 			goto f_err;
4603395f70eSjsing 		}
4613395f70eSjsing 		*ok = 1;
4623395f70eSjsing 		s->internal->init_msg = s->internal->init_buf->data + 4;
4633395f70eSjsing 		s->internal->init_num = (int)S3I(s)->tmp.message_size;
4643395f70eSjsing 		return s->internal->init_num;
4653395f70eSjsing 	}
4663395f70eSjsing 
4673395f70eSjsing 	p = (unsigned char *)s->internal->init_buf->data;
4683395f70eSjsing 
4693395f70eSjsing 	/* s->internal->init_num < 4 */
470440bed4fSbeck 	if (S3I(s)->hs.state == st1) {
4713395f70eSjsing 		int skip_message;
4723395f70eSjsing 
4733395f70eSjsing 		do {
4743395f70eSjsing 			while (s->internal->init_num < 4) {
4753395f70eSjsing 				i = s->method->internal->ssl_read_bytes(s,
4763395f70eSjsing 				    SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
4773395f70eSjsing 				    4 - s->internal->init_num, 0);
4783395f70eSjsing 				if (i <= 0) {
4793395f70eSjsing 					s->internal->rwstate = SSL_READING;
4803395f70eSjsing 					*ok = 0;
4813395f70eSjsing 					return i;
4823395f70eSjsing 				}
4833395f70eSjsing 				s->internal->init_num += i;
4843395f70eSjsing 			}
4853395f70eSjsing 
4863395f70eSjsing 			skip_message = 0;
4873395f70eSjsing 			if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
4883395f70eSjsing 				/*
4893395f70eSjsing 				 * The server may always send 'Hello Request'
4903395f70eSjsing 				 * messages -- we are doing a handshake anyway
4913395f70eSjsing 				 * now, so ignore them if their format is
4923395f70eSjsing 				 * correct.  Does not count for 'Finished' MAC.
4933395f70eSjsing 				 */
4943395f70eSjsing 				if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
4953395f70eSjsing 					s->internal->init_num = 0;
4963395f70eSjsing 					skip_message = 1;
4973395f70eSjsing 
4983395f70eSjsing 					if (s->internal->msg_callback)
4993395f70eSjsing 						s->internal->msg_callback(0, s->version,
5003395f70eSjsing 						    SSL3_RT_HANDSHAKE, p, 4, s,
5013395f70eSjsing 						    s->internal->msg_callback_arg);
5023395f70eSjsing 				}
5033395f70eSjsing 			}
5043395f70eSjsing 		} while (skip_message);
5053395f70eSjsing 
5063395f70eSjsing 		/* s->internal->init_num == 4 */
5073395f70eSjsing 
5083395f70eSjsing 		if ((mt >= 0) && (*p != mt)) {
5093395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
510c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
5113395f70eSjsing 			goto f_err;
5123395f70eSjsing 		}
5133395f70eSjsing 
5143395f70eSjsing 		CBS_init(&cbs, p, 4);
5153395f70eSjsing 		if (!CBS_get_u8(&cbs, &u8) ||
5163395f70eSjsing 		    !CBS_get_u24(&cbs, &l)) {
517c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
5183395f70eSjsing 			goto err;
5193395f70eSjsing 		}
5203395f70eSjsing 		S3I(s)->tmp.message_type = u8;
5213395f70eSjsing 
5223395f70eSjsing 		if (l > (unsigned long)max) {
5233395f70eSjsing 			al = SSL_AD_ILLEGAL_PARAMETER;
524c9d7abb7Sbeck 			SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
5253395f70eSjsing 			goto f_err;
5263395f70eSjsing 		}
5273395f70eSjsing 		if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
528c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
5293395f70eSjsing 			goto err;
5303395f70eSjsing 		}
5313395f70eSjsing 		S3I(s)->tmp.message_size = l;
532440bed4fSbeck 		S3I(s)->hs.state = stn;
5333395f70eSjsing 
5343395f70eSjsing 		s->internal->init_msg = s->internal->init_buf->data + 4;
5353395f70eSjsing 		s->internal->init_num = 0;
5363395f70eSjsing 	}
5373395f70eSjsing 
5383395f70eSjsing 	/* next state (stn) */
5393395f70eSjsing 	p = s->internal->init_msg;
5403395f70eSjsing 	n = S3I(s)->tmp.message_size - s->internal->init_num;
5413395f70eSjsing 	while (n > 0) {
5423395f70eSjsing 		i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
5433395f70eSjsing 		    &p[s->internal->init_num], n, 0);
5443395f70eSjsing 		if (i <= 0) {
5453395f70eSjsing 			s->internal->rwstate = SSL_READING;
5463395f70eSjsing 			*ok = 0;
5473395f70eSjsing 			return i;
5483395f70eSjsing 		}
5493395f70eSjsing 		s->internal->init_num += i;
5503395f70eSjsing 		n -= i;
5513395f70eSjsing 	}
5523395f70eSjsing 
5533395f70eSjsing 	/* If receiving Finished, record MAC of prior handshake messages for
5543395f70eSjsing 	 * Finished verification. */
5553395f70eSjsing 	if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
5563395f70eSjsing 		ssl3_take_mac(s);
5573395f70eSjsing 
5583395f70eSjsing 	/* Feed this message into MAC computation. */
5593395f70eSjsing 	if (s->internal->mac_packet) {
5603395f70eSjsing 		tls1_finish_mac(s, (unsigned char *)s->internal->init_buf->data,
5613395f70eSjsing 		    s->internal->init_num + 4);
5623395f70eSjsing 
5633395f70eSjsing 		if (s->internal->msg_callback)
5643395f70eSjsing 			s->internal->msg_callback(0, s->version,
5653395f70eSjsing 			    SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
5663395f70eSjsing 			    (size_t)s->internal->init_num + 4, s,
5673395f70eSjsing 			    s->internal->msg_callback_arg);
5683395f70eSjsing 	}
5693395f70eSjsing 
5703395f70eSjsing 	*ok = 1;
5713395f70eSjsing 	return (s->internal->init_num);
5723395f70eSjsing 
5733395f70eSjsing f_err:
5743395f70eSjsing 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
5753395f70eSjsing err:
5763395f70eSjsing 	*ok = 0;
5773395f70eSjsing 	return (-1);
5783395f70eSjsing }
5793395f70eSjsing 
5803395f70eSjsing int
5813395f70eSjsing ssl_cert_type(X509 *x, EVP_PKEY *pkey)
5823395f70eSjsing {
5833395f70eSjsing 	EVP_PKEY *pk;
5843395f70eSjsing 	int ret = -1, i;
5853395f70eSjsing 
5863395f70eSjsing 	if (pkey == NULL)
5873395f70eSjsing 		pk = X509_get_pubkey(x);
5883395f70eSjsing 	else
5893395f70eSjsing 		pk = pkey;
5903395f70eSjsing 	if (pk == NULL)
5913395f70eSjsing 		goto err;
5923395f70eSjsing 
5933395f70eSjsing 	i = pk->type;
5943395f70eSjsing 	if (i == EVP_PKEY_RSA) {
5953395f70eSjsing 		ret = SSL_PKEY_RSA_ENC;
5963395f70eSjsing 	} else if (i == EVP_PKEY_EC) {
5973395f70eSjsing 		ret = SSL_PKEY_ECC;
5983395f70eSjsing 	} else if (i == NID_id_GostR3410_2001 ||
5993395f70eSjsing 	    i == NID_id_GostR3410_2001_cc) {
6003395f70eSjsing 		ret = SSL_PKEY_GOST01;
6013395f70eSjsing 	}
6023395f70eSjsing 
6033395f70eSjsing err:
6043395f70eSjsing 	if (!pkey)
6053395f70eSjsing 		EVP_PKEY_free(pk);
6063395f70eSjsing 	return (ret);
6073395f70eSjsing }
6083395f70eSjsing 
6093395f70eSjsing int
6103395f70eSjsing ssl_verify_alarm_type(long type)
6113395f70eSjsing {
6123395f70eSjsing 	int al;
6133395f70eSjsing 
6143395f70eSjsing 	switch (type) {
6153395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
6163395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL:
6173395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
6183395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
6193395f70eSjsing 		break;
6203395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
6213395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
6223395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
6233395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
6243395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
6253395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
6263395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
6273395f70eSjsing 	case X509_V_ERR_CERT_NOT_YET_VALID:
6283395f70eSjsing 	case X509_V_ERR_CRL_NOT_YET_VALID:
6293395f70eSjsing 	case X509_V_ERR_CERT_UNTRUSTED:
6303395f70eSjsing 	case X509_V_ERR_CERT_REJECTED:
6313395f70eSjsing 		al = SSL_AD_BAD_CERTIFICATE;
6323395f70eSjsing 		break;
6333395f70eSjsing 	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
6343395f70eSjsing 	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
6353395f70eSjsing 		al = SSL_AD_DECRYPT_ERROR;
6363395f70eSjsing 		break;
6373395f70eSjsing 	case X509_V_ERR_CERT_HAS_EXPIRED:
6383395f70eSjsing 	case X509_V_ERR_CRL_HAS_EXPIRED:
6393395f70eSjsing 		al = SSL_AD_CERTIFICATE_EXPIRED;
6403395f70eSjsing 		break;
6413395f70eSjsing 	case X509_V_ERR_CERT_REVOKED:
6423395f70eSjsing 		al = SSL_AD_CERTIFICATE_REVOKED;
6433395f70eSjsing 		break;
6443395f70eSjsing 	case X509_V_ERR_OUT_OF_MEM:
6453395f70eSjsing 		al = SSL_AD_INTERNAL_ERROR;
6463395f70eSjsing 		break;
6473395f70eSjsing 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
6483395f70eSjsing 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
6493395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
6503395f70eSjsing 	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
6513395f70eSjsing 	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
6523395f70eSjsing 	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
6533395f70eSjsing 	case X509_V_ERR_INVALID_CA:
6543395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
6553395f70eSjsing 		break;
6563395f70eSjsing 	case X509_V_ERR_APPLICATION_VERIFICATION:
6573395f70eSjsing 		al = SSL_AD_HANDSHAKE_FAILURE;
6583395f70eSjsing 		break;
6593395f70eSjsing 	case X509_V_ERR_INVALID_PURPOSE:
6603395f70eSjsing 		al = SSL_AD_UNSUPPORTED_CERTIFICATE;
6613395f70eSjsing 		break;
6623395f70eSjsing 	default:
6633395f70eSjsing 		al = SSL_AD_CERTIFICATE_UNKNOWN;
6643395f70eSjsing 		break;
6653395f70eSjsing 	}
6663395f70eSjsing 	return (al);
6673395f70eSjsing }
6683395f70eSjsing 
6693395f70eSjsing int
6703395f70eSjsing ssl3_setup_init_buffer(SSL *s)
6713395f70eSjsing {
6723395f70eSjsing 	BUF_MEM *buf = NULL;
6733395f70eSjsing 
6743395f70eSjsing 	if (s->internal->init_buf != NULL)
6753395f70eSjsing 		return (1);
6763395f70eSjsing 
6773395f70eSjsing 	if ((buf = BUF_MEM_new()) == NULL)
6783395f70eSjsing 		goto err;
6793395f70eSjsing 	if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
6803395f70eSjsing 		goto err;
6813395f70eSjsing 
6823395f70eSjsing 	s->internal->init_buf = buf;
6833395f70eSjsing 	return (1);
6843395f70eSjsing 
6853395f70eSjsing err:
6863395f70eSjsing 	BUF_MEM_free(buf);
6873395f70eSjsing 	return (0);
6883395f70eSjsing }
6893395f70eSjsing 
6903395f70eSjsing int
6913395f70eSjsing ssl3_setup_read_buffer(SSL *s)
6923395f70eSjsing {
6933395f70eSjsing 	unsigned char *p;
6943395f70eSjsing 	size_t len, align, headerlen;
6953395f70eSjsing 
6963395f70eSjsing 	if (SSL_IS_DTLS(s))
6973395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH;
6983395f70eSjsing 	else
6993395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
7003395f70eSjsing 
7013395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
7023395f70eSjsing 
7033395f70eSjsing 	if (s->s3->rbuf.buf == NULL) {
7043395f70eSjsing 		len = SSL3_RT_MAX_PLAIN_LENGTH +
7053395f70eSjsing 		    SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
7063395f70eSjsing 		if ((p = malloc(len)) == NULL)
7073395f70eSjsing 			goto err;
7083395f70eSjsing 		s->s3->rbuf.buf = p;
7093395f70eSjsing 		s->s3->rbuf.len = len;
7103395f70eSjsing 	}
7113395f70eSjsing 
7123395f70eSjsing 	s->internal->packet = &(s->s3->rbuf.buf[0]);
7133395f70eSjsing 	return 1;
7143395f70eSjsing 
7153395f70eSjsing err:
716c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
7173395f70eSjsing 	return 0;
7183395f70eSjsing }
7193395f70eSjsing 
7203395f70eSjsing int
7213395f70eSjsing ssl3_setup_write_buffer(SSL *s)
7223395f70eSjsing {
7233395f70eSjsing 	unsigned char *p;
7243395f70eSjsing 	size_t len, align, headerlen;
7253395f70eSjsing 
7263395f70eSjsing 	if (SSL_IS_DTLS(s))
7273395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
7283395f70eSjsing 	else
7293395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
7303395f70eSjsing 
7313395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
7323395f70eSjsing 
7333395f70eSjsing 	if (s->s3->wbuf.buf == NULL) {
7343395f70eSjsing 		len = s->max_send_fragment +
7353395f70eSjsing 		    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
7363395f70eSjsing 		if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
7373395f70eSjsing 			len += headerlen + align +
7383395f70eSjsing 			    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
7393395f70eSjsing 
7403395f70eSjsing 		if ((p = malloc(len)) == NULL)
7413395f70eSjsing 			goto err;
7423395f70eSjsing 		s->s3->wbuf.buf = p;
7433395f70eSjsing 		s->s3->wbuf.len = len;
7443395f70eSjsing 	}
7453395f70eSjsing 
7463395f70eSjsing 	return 1;
7473395f70eSjsing 
7483395f70eSjsing err:
749c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
7503395f70eSjsing 	return 0;
7513395f70eSjsing }
7523395f70eSjsing 
7533395f70eSjsing int
7543395f70eSjsing ssl3_setup_buffers(SSL *s)
7553395f70eSjsing {
7563395f70eSjsing 	if (!ssl3_setup_read_buffer(s))
7573395f70eSjsing 		return 0;
7583395f70eSjsing 	if (!ssl3_setup_write_buffer(s))
7593395f70eSjsing 		return 0;
7603395f70eSjsing 	return 1;
7613395f70eSjsing }
7623395f70eSjsing 
7633395f70eSjsing int
7643395f70eSjsing ssl3_release_write_buffer(SSL *s)
7653395f70eSjsing {
7663395f70eSjsing 	free(s->s3->wbuf.buf);
7673395f70eSjsing 	s->s3->wbuf.buf = NULL;
7683395f70eSjsing 	return 1;
7693395f70eSjsing }
7703395f70eSjsing 
7713395f70eSjsing int
7723395f70eSjsing ssl3_release_read_buffer(SSL *s)
7733395f70eSjsing {
7743395f70eSjsing 	free(s->s3->rbuf.buf);
7753395f70eSjsing 	s->s3->rbuf.buf = NULL;
7763395f70eSjsing 	return 1;
7773395f70eSjsing }
778