xref: /openbsd-src/lib/libssl/ssl_both.c (revision a9e43a46453719e446ba6c550d97b12d57af555f)
1*a9e43a46Sjsing /* $OpenBSD: ssl_both.c,v 1.7 2017/03/05 14:24:12 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 {
169*a9e43a46Sjsing 	CBB cbb, finished;
1703395f70eSjsing 	int md_len;
1713395f70eSjsing 
172*a9e43a46Sjsing 	memset(&cbb, 0, sizeof(cbb));
173*a9e43a46Sjsing 
1743395f70eSjsing 	if (s->internal->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 
194*a9e43a46Sjsing 		if (!ssl3_handshake_msg_start_cbb(s, &cbb, &finished,
195*a9e43a46Sjsing 		    SSL3_MT_FINISHED))
196*a9e43a46Sjsing                         goto err;
197*a9e43a46Sjsing 		if (!CBB_add_bytes(&finished, S3I(s)->tmp.finish_md, md_len))
198*a9e43a46Sjsing 			goto err;
199*a9e43a46Sjsing 		if (!ssl3_handshake_msg_finish_cbb(s, &cbb))
200*a9e43a46Sjsing 			goto err;
2013395f70eSjsing 
2023395f70eSjsing 		s->internal->state = b;
2033395f70eSjsing 	}
2043395f70eSjsing 
2053395f70eSjsing 	return (ssl3_handshake_write(s));
206*a9e43a46Sjsing 
207*a9e43a46Sjsing  err:
208*a9e43a46Sjsing 	CBB_cleanup(&cbb);
209*a9e43a46Sjsing 
210*a9e43a46Sjsing 	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 	 */
2273395f70eSjsing 	if (S3I(s)->tmp.new_cipher == NULL)
2283395f70eSjsing 		return;
2293395f70eSjsing 
2303395f70eSjsing 	if (s->internal->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 {
3143395f70eSjsing 	unsigned char *p;
3153395f70eSjsing 
3163395f70eSjsing 	if (s->internal->state == a) {
3173395f70eSjsing 		p = (unsigned char *)s->internal->init_buf->data;
3183395f70eSjsing 		*p = SSL3_MT_CCS;
3193395f70eSjsing 		s->internal->init_num = 1;
3203395f70eSjsing 		s->internal->init_off = 0;
3213395f70eSjsing 
3223395f70eSjsing 		s->internal->state = b;
3233395f70eSjsing 	}
3243395f70eSjsing 
3253395f70eSjsing 	/* SSL3_ST_CW_CHANGE_B */
3263395f70eSjsing 	return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC));
3273395f70eSjsing }
3283395f70eSjsing 
3293395f70eSjsing static int
3303395f70eSjsing ssl3_add_cert(CBB *cbb, X509 *x)
3313395f70eSjsing {
3323395f70eSjsing 	unsigned char *data;
3333395f70eSjsing 	int cert_len;
3343395f70eSjsing 	int ret = 0;
3353395f70eSjsing 	CBB cert;
3363395f70eSjsing 
3373395f70eSjsing 	if ((cert_len = i2d_X509(x, NULL)) < 0)
3383395f70eSjsing 		goto err;
3393395f70eSjsing 
3403395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert))
3413395f70eSjsing 		goto err;
3423395f70eSjsing 	if (!CBB_add_space(&cert, &data, cert_len))
3433395f70eSjsing 		goto err;
3443395f70eSjsing 	if (i2d_X509(x, &data) < 0)
3453395f70eSjsing 		goto err;
3463395f70eSjsing 	if (!CBB_flush(cbb))
3473395f70eSjsing 		goto err;
3483395f70eSjsing 
3493395f70eSjsing 	ret = 1;
3503395f70eSjsing 
3513395f70eSjsing  err:
3523395f70eSjsing 	return (ret);
3533395f70eSjsing }
3543395f70eSjsing 
3553395f70eSjsing int
3563395f70eSjsing ssl3_output_cert_chain(SSL *s, CBB *cbb, X509 *x)
3573395f70eSjsing {
3583395f70eSjsing 	int no_chain = 0;
3593395f70eSjsing 	CBB cert_list;
3603395f70eSjsing 	int ret = 0;
3613395f70eSjsing 	int i;
3623395f70eSjsing 
3633395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
3643395f70eSjsing 		goto err;
3653395f70eSjsing 
3663395f70eSjsing 	if ((s->internal->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
3673395f70eSjsing 		no_chain = 1;
3683395f70eSjsing 
3693395f70eSjsing 	/* TLSv1 sends a chain with nothing in it, instead of an alert. */
3703395f70eSjsing 	if (x != NULL) {
3713395f70eSjsing 		if (no_chain) {
3723395f70eSjsing 			if (!ssl3_add_cert(&cert_list, x))
3733395f70eSjsing 				goto err;
3743395f70eSjsing 		} else {
3753395f70eSjsing 			X509_STORE_CTX xs_ctx;
3763395f70eSjsing 
3773395f70eSjsing 			if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store,
3783395f70eSjsing 			    x, NULL)) {
379c9d7abb7Sbeck 				SSLerror(s, ERR_R_X509_LIB);
3803395f70eSjsing 				goto err;
3813395f70eSjsing 			}
3823395f70eSjsing 			X509_verify_cert(&xs_ctx);
3833395f70eSjsing 
3843395f70eSjsing 			/* Don't leave errors in the queue. */
3853395f70eSjsing 			ERR_clear_error();
3863395f70eSjsing 			for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
3873395f70eSjsing 				x = sk_X509_value(xs_ctx.chain, i);
3883395f70eSjsing 				if (!ssl3_add_cert(&cert_list, x)) {
3893395f70eSjsing 					X509_STORE_CTX_cleanup(&xs_ctx);
3903395f70eSjsing 					goto err;
3913395f70eSjsing 				}
3923395f70eSjsing 			}
3933395f70eSjsing 			X509_STORE_CTX_cleanup(&xs_ctx);
3943395f70eSjsing 		}
3953395f70eSjsing 	}
3963395f70eSjsing 
3973395f70eSjsing 	/* Thawte special :-) */
3983395f70eSjsing 	for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) {
3993395f70eSjsing 		x = sk_X509_value(s->ctx->extra_certs, i);
4003395f70eSjsing 		if (!ssl3_add_cert(&cert_list, x))
4013395f70eSjsing 			goto err;
4023395f70eSjsing 	}
4033395f70eSjsing 
4043395f70eSjsing 	if (!CBB_flush(cbb))
4053395f70eSjsing 		goto err;
4063395f70eSjsing 
4073395f70eSjsing 	ret = 1;
4083395f70eSjsing 
4093395f70eSjsing  err:
4103395f70eSjsing 	return (ret);
4113395f70eSjsing }
4123395f70eSjsing 
4133395f70eSjsing /*
4143395f70eSjsing  * Obtain handshake message of message type 'mt' (any if mt == -1),
4153395f70eSjsing  * maximum acceptable body length 'max'.
4163395f70eSjsing  * The first four bytes (msg_type and length) are read in state 'st1',
4173395f70eSjsing  * the body is read in state 'stn'.
4183395f70eSjsing  */
4193395f70eSjsing long
4203395f70eSjsing ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
4213395f70eSjsing {
4223395f70eSjsing 	unsigned char *p;
4233395f70eSjsing 	uint32_t l;
4243395f70eSjsing 	long n;
4253395f70eSjsing 	int i, al;
4263395f70eSjsing 	CBS cbs;
4273395f70eSjsing 	uint8_t u8;
4283395f70eSjsing 
4293395f70eSjsing 	if (S3I(s)->tmp.reuse_message) {
4303395f70eSjsing 		S3I(s)->tmp.reuse_message = 0;
4313395f70eSjsing 		if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
4323395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
433c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
4343395f70eSjsing 			goto f_err;
4353395f70eSjsing 		}
4363395f70eSjsing 		*ok = 1;
4373395f70eSjsing 		s->internal->init_msg = s->internal->init_buf->data + 4;
4383395f70eSjsing 		s->internal->init_num = (int)S3I(s)->tmp.message_size;
4393395f70eSjsing 		return s->internal->init_num;
4403395f70eSjsing 	}
4413395f70eSjsing 
4423395f70eSjsing 	p = (unsigned char *)s->internal->init_buf->data;
4433395f70eSjsing 
4443395f70eSjsing 	/* s->internal->init_num < 4 */
4453395f70eSjsing 	if (s->internal->state == st1) {
4463395f70eSjsing 		int skip_message;
4473395f70eSjsing 
4483395f70eSjsing 		do {
4493395f70eSjsing 			while (s->internal->init_num < 4) {
4503395f70eSjsing 				i = s->method->internal->ssl_read_bytes(s,
4513395f70eSjsing 				    SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
4523395f70eSjsing 				    4 - s->internal->init_num, 0);
4533395f70eSjsing 				if (i <= 0) {
4543395f70eSjsing 					s->internal->rwstate = SSL_READING;
4553395f70eSjsing 					*ok = 0;
4563395f70eSjsing 					return i;
4573395f70eSjsing 				}
4583395f70eSjsing 				s->internal->init_num += i;
4593395f70eSjsing 			}
4603395f70eSjsing 
4613395f70eSjsing 			skip_message = 0;
4623395f70eSjsing 			if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
4633395f70eSjsing 				/*
4643395f70eSjsing 				 * The server may always send 'Hello Request'
4653395f70eSjsing 				 * messages -- we are doing a handshake anyway
4663395f70eSjsing 				 * now, so ignore them if their format is
4673395f70eSjsing 				 * correct.  Does not count for 'Finished' MAC.
4683395f70eSjsing 				 */
4693395f70eSjsing 				if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
4703395f70eSjsing 					s->internal->init_num = 0;
4713395f70eSjsing 					skip_message = 1;
4723395f70eSjsing 
4733395f70eSjsing 					if (s->internal->msg_callback)
4743395f70eSjsing 						s->internal->msg_callback(0, s->version,
4753395f70eSjsing 						    SSL3_RT_HANDSHAKE, p, 4, s,
4763395f70eSjsing 						    s->internal->msg_callback_arg);
4773395f70eSjsing 				}
4783395f70eSjsing 			}
4793395f70eSjsing 		} while (skip_message);
4803395f70eSjsing 
4813395f70eSjsing 		/* s->internal->init_num == 4 */
4823395f70eSjsing 
4833395f70eSjsing 		if ((mt >= 0) && (*p != mt)) {
4843395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
485c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
4863395f70eSjsing 			goto f_err;
4873395f70eSjsing 		}
4883395f70eSjsing 
4893395f70eSjsing 		CBS_init(&cbs, p, 4);
4903395f70eSjsing 		if (!CBS_get_u8(&cbs, &u8) ||
4913395f70eSjsing 		    !CBS_get_u24(&cbs, &l)) {
492c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
4933395f70eSjsing 			goto err;
4943395f70eSjsing 		}
4953395f70eSjsing 		S3I(s)->tmp.message_type = u8;
4963395f70eSjsing 
4973395f70eSjsing 		if (l > (unsigned long)max) {
4983395f70eSjsing 			al = SSL_AD_ILLEGAL_PARAMETER;
499c9d7abb7Sbeck 			SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
5003395f70eSjsing 			goto f_err;
5013395f70eSjsing 		}
5023395f70eSjsing 		if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
503c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
5043395f70eSjsing 			goto err;
5053395f70eSjsing 		}
5063395f70eSjsing 		S3I(s)->tmp.message_size = l;
5073395f70eSjsing 		s->internal->state = stn;
5083395f70eSjsing 
5093395f70eSjsing 		s->internal->init_msg = s->internal->init_buf->data + 4;
5103395f70eSjsing 		s->internal->init_num = 0;
5113395f70eSjsing 	}
5123395f70eSjsing 
5133395f70eSjsing 	/* next state (stn) */
5143395f70eSjsing 	p = s->internal->init_msg;
5153395f70eSjsing 	n = S3I(s)->tmp.message_size - s->internal->init_num;
5163395f70eSjsing 	while (n > 0) {
5173395f70eSjsing 		i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
5183395f70eSjsing 		    &p[s->internal->init_num], n, 0);
5193395f70eSjsing 		if (i <= 0) {
5203395f70eSjsing 			s->internal->rwstate = SSL_READING;
5213395f70eSjsing 			*ok = 0;
5223395f70eSjsing 			return i;
5233395f70eSjsing 		}
5243395f70eSjsing 		s->internal->init_num += i;
5253395f70eSjsing 		n -= i;
5263395f70eSjsing 	}
5273395f70eSjsing 
5283395f70eSjsing 	/* If receiving Finished, record MAC of prior handshake messages for
5293395f70eSjsing 	 * Finished verification. */
5303395f70eSjsing 	if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
5313395f70eSjsing 		ssl3_take_mac(s);
5323395f70eSjsing 
5333395f70eSjsing 	/* Feed this message into MAC computation. */
5343395f70eSjsing 	if (s->internal->mac_packet) {
5353395f70eSjsing 		tls1_finish_mac(s, (unsigned char *)s->internal->init_buf->data,
5363395f70eSjsing 		    s->internal->init_num + 4);
5373395f70eSjsing 
5383395f70eSjsing 		if (s->internal->msg_callback)
5393395f70eSjsing 			s->internal->msg_callback(0, s->version,
5403395f70eSjsing 			    SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
5413395f70eSjsing 			    (size_t)s->internal->init_num + 4, s,
5423395f70eSjsing 			    s->internal->msg_callback_arg);
5433395f70eSjsing 	}
5443395f70eSjsing 
5453395f70eSjsing 	*ok = 1;
5463395f70eSjsing 	return (s->internal->init_num);
5473395f70eSjsing 
5483395f70eSjsing f_err:
5493395f70eSjsing 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
5503395f70eSjsing err:
5513395f70eSjsing 	*ok = 0;
5523395f70eSjsing 	return (-1);
5533395f70eSjsing }
5543395f70eSjsing 
5553395f70eSjsing int
5563395f70eSjsing ssl_cert_type(X509 *x, EVP_PKEY *pkey)
5573395f70eSjsing {
5583395f70eSjsing 	EVP_PKEY *pk;
5593395f70eSjsing 	int ret = -1, i;
5603395f70eSjsing 
5613395f70eSjsing 	if (pkey == NULL)
5623395f70eSjsing 		pk = X509_get_pubkey(x);
5633395f70eSjsing 	else
5643395f70eSjsing 		pk = pkey;
5653395f70eSjsing 	if (pk == NULL)
5663395f70eSjsing 		goto err;
5673395f70eSjsing 
5683395f70eSjsing 	i = pk->type;
5693395f70eSjsing 	if (i == EVP_PKEY_RSA) {
5703395f70eSjsing 		ret = SSL_PKEY_RSA_ENC;
5713395f70eSjsing 	} else if (i == EVP_PKEY_DSA) {
5723395f70eSjsing 		ret = SSL_PKEY_DSA_SIGN;
5733395f70eSjsing 	} else if (i == EVP_PKEY_EC) {
5743395f70eSjsing 		ret = SSL_PKEY_ECC;
5753395f70eSjsing 	} else if (i == NID_id_GostR3410_2001 ||
5763395f70eSjsing 	    i == NID_id_GostR3410_2001_cc) {
5773395f70eSjsing 		ret = SSL_PKEY_GOST01;
5783395f70eSjsing 	}
5793395f70eSjsing 
5803395f70eSjsing err:
5813395f70eSjsing 	if (!pkey)
5823395f70eSjsing 		EVP_PKEY_free(pk);
5833395f70eSjsing 	return (ret);
5843395f70eSjsing }
5853395f70eSjsing 
5863395f70eSjsing int
5873395f70eSjsing ssl_verify_alarm_type(long type)
5883395f70eSjsing {
5893395f70eSjsing 	int al;
5903395f70eSjsing 
5913395f70eSjsing 	switch (type) {
5923395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
5933395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL:
5943395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
5953395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
5963395f70eSjsing 		break;
5973395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
5983395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
5993395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
6003395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
6013395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
6023395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
6033395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
6043395f70eSjsing 	case X509_V_ERR_CERT_NOT_YET_VALID:
6053395f70eSjsing 	case X509_V_ERR_CRL_NOT_YET_VALID:
6063395f70eSjsing 	case X509_V_ERR_CERT_UNTRUSTED:
6073395f70eSjsing 	case X509_V_ERR_CERT_REJECTED:
6083395f70eSjsing 		al = SSL_AD_BAD_CERTIFICATE;
6093395f70eSjsing 		break;
6103395f70eSjsing 	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
6113395f70eSjsing 	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
6123395f70eSjsing 		al = SSL_AD_DECRYPT_ERROR;
6133395f70eSjsing 		break;
6143395f70eSjsing 	case X509_V_ERR_CERT_HAS_EXPIRED:
6153395f70eSjsing 	case X509_V_ERR_CRL_HAS_EXPIRED:
6163395f70eSjsing 		al = SSL_AD_CERTIFICATE_EXPIRED;
6173395f70eSjsing 		break;
6183395f70eSjsing 	case X509_V_ERR_CERT_REVOKED:
6193395f70eSjsing 		al = SSL_AD_CERTIFICATE_REVOKED;
6203395f70eSjsing 		break;
6213395f70eSjsing 	case X509_V_ERR_OUT_OF_MEM:
6223395f70eSjsing 		al = SSL_AD_INTERNAL_ERROR;
6233395f70eSjsing 		break;
6243395f70eSjsing 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
6253395f70eSjsing 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
6263395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
6273395f70eSjsing 	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
6283395f70eSjsing 	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
6293395f70eSjsing 	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
6303395f70eSjsing 	case X509_V_ERR_INVALID_CA:
6313395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
6323395f70eSjsing 		break;
6333395f70eSjsing 	case X509_V_ERR_APPLICATION_VERIFICATION:
6343395f70eSjsing 		al = SSL_AD_HANDSHAKE_FAILURE;
6353395f70eSjsing 		break;
6363395f70eSjsing 	case X509_V_ERR_INVALID_PURPOSE:
6373395f70eSjsing 		al = SSL_AD_UNSUPPORTED_CERTIFICATE;
6383395f70eSjsing 		break;
6393395f70eSjsing 	default:
6403395f70eSjsing 		al = SSL_AD_CERTIFICATE_UNKNOWN;
6413395f70eSjsing 		break;
6423395f70eSjsing 	}
6433395f70eSjsing 	return (al);
6443395f70eSjsing }
6453395f70eSjsing 
6463395f70eSjsing int
6473395f70eSjsing ssl3_setup_init_buffer(SSL *s)
6483395f70eSjsing {
6493395f70eSjsing 	BUF_MEM *buf = NULL;
6503395f70eSjsing 
6513395f70eSjsing 	if (s->internal->init_buf != NULL)
6523395f70eSjsing 		return (1);
6533395f70eSjsing 
6543395f70eSjsing 	if ((buf = BUF_MEM_new()) == NULL)
6553395f70eSjsing 		goto err;
6563395f70eSjsing 	if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
6573395f70eSjsing 		goto err;
6583395f70eSjsing 
6593395f70eSjsing 	s->internal->init_buf = buf;
6603395f70eSjsing 	return (1);
6613395f70eSjsing 
6623395f70eSjsing err:
6633395f70eSjsing 	BUF_MEM_free(buf);
6643395f70eSjsing 	return (0);
6653395f70eSjsing }
6663395f70eSjsing 
6673395f70eSjsing int
6683395f70eSjsing ssl3_setup_read_buffer(SSL *s)
6693395f70eSjsing {
6703395f70eSjsing 	unsigned char *p;
6713395f70eSjsing 	size_t len, align, headerlen;
6723395f70eSjsing 
6733395f70eSjsing 	if (SSL_IS_DTLS(s))
6743395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH;
6753395f70eSjsing 	else
6763395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
6773395f70eSjsing 
6783395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
6793395f70eSjsing 
6803395f70eSjsing 	if (s->s3->rbuf.buf == NULL) {
6813395f70eSjsing 		len = SSL3_RT_MAX_PLAIN_LENGTH +
6823395f70eSjsing 		    SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
6833395f70eSjsing 		if ((p = malloc(len)) == NULL)
6843395f70eSjsing 			goto err;
6853395f70eSjsing 		s->s3->rbuf.buf = p;
6863395f70eSjsing 		s->s3->rbuf.len = len;
6873395f70eSjsing 	}
6883395f70eSjsing 
6893395f70eSjsing 	s->internal->packet = &(s->s3->rbuf.buf[0]);
6903395f70eSjsing 	return 1;
6913395f70eSjsing 
6923395f70eSjsing err:
693c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
6943395f70eSjsing 	return 0;
6953395f70eSjsing }
6963395f70eSjsing 
6973395f70eSjsing int
6983395f70eSjsing ssl3_setup_write_buffer(SSL *s)
6993395f70eSjsing {
7003395f70eSjsing 	unsigned char *p;
7013395f70eSjsing 	size_t len, align, headerlen;
7023395f70eSjsing 
7033395f70eSjsing 	if (SSL_IS_DTLS(s))
7043395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
7053395f70eSjsing 	else
7063395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
7073395f70eSjsing 
7083395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
7093395f70eSjsing 
7103395f70eSjsing 	if (s->s3->wbuf.buf == NULL) {
7113395f70eSjsing 		len = s->max_send_fragment +
7123395f70eSjsing 		    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
7133395f70eSjsing 		if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
7143395f70eSjsing 			len += headerlen + align +
7153395f70eSjsing 			    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
7163395f70eSjsing 
7173395f70eSjsing 		if ((p = malloc(len)) == NULL)
7183395f70eSjsing 			goto err;
7193395f70eSjsing 		s->s3->wbuf.buf = p;
7203395f70eSjsing 		s->s3->wbuf.len = len;
7213395f70eSjsing 	}
7223395f70eSjsing 
7233395f70eSjsing 	return 1;
7243395f70eSjsing 
7253395f70eSjsing err:
726c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
7273395f70eSjsing 	return 0;
7283395f70eSjsing }
7293395f70eSjsing 
7303395f70eSjsing int
7313395f70eSjsing ssl3_setup_buffers(SSL *s)
7323395f70eSjsing {
7333395f70eSjsing 	if (!ssl3_setup_read_buffer(s))
7343395f70eSjsing 		return 0;
7353395f70eSjsing 	if (!ssl3_setup_write_buffer(s))
7363395f70eSjsing 		return 0;
7373395f70eSjsing 	return 1;
7383395f70eSjsing }
7393395f70eSjsing 
7403395f70eSjsing int
7413395f70eSjsing ssl3_release_write_buffer(SSL *s)
7423395f70eSjsing {
7433395f70eSjsing 	free(s->s3->wbuf.buf);
7443395f70eSjsing 	s->s3->wbuf.buf = NULL;
7453395f70eSjsing 	return 1;
7463395f70eSjsing }
7473395f70eSjsing 
7483395f70eSjsing int
7493395f70eSjsing ssl3_release_read_buffer(SSL *s)
7503395f70eSjsing {
7513395f70eSjsing 	free(s->s3->rbuf.buf);
7523395f70eSjsing 	s->s3->rbuf.buf = NULL;
7533395f70eSjsing 	return 1;
7543395f70eSjsing }
755