xref: /openbsd-src/lib/libssl/ssl_both.c (revision 0f99faba209e74656b4fe1e71a63fb1fced3186e)
1*0f99fabaSjsing /* $OpenBSD: ssl_both.c,v 1.15 2019/03/25 16:35:48 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 		 */
149cef855dcSjsing 		tls1_transcript_record(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 
194312b4b14Sjsing 		if (!ssl3_handshake_msg_start(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;
199312b4b14Sjsing 		if (!ssl3_handshake_msg_finish(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 {
314ab211f3dSjsing 	size_t outlen;
315ab211f3dSjsing 	CBB cbb;
316ab211f3dSjsing 
317ab211f3dSjsing 	memset(&cbb, 0, sizeof(cbb));
3183395f70eSjsing 
319440bed4fSbeck 	if (S3I(s)->hs.state == a) {
320ab211f3dSjsing 		if (!CBB_init_fixed(&cbb, s->internal->init_buf->data,
321ab211f3dSjsing 		    s->internal->init_buf->length))
322ab211f3dSjsing 			goto err;
323ab211f3dSjsing 		if (!CBB_add_u8(&cbb, SSL3_MT_CCS))
324ab211f3dSjsing 			goto err;
325ab211f3dSjsing 		if (!CBB_finish(&cbb, NULL, &outlen))
326ab211f3dSjsing 			goto err;
327ab211f3dSjsing 
328ab211f3dSjsing 		if (outlen > INT_MAX)
329ab211f3dSjsing 			goto err;
330ab211f3dSjsing 
331ab211f3dSjsing 		s->internal->init_num = (int)outlen;
3323395f70eSjsing 		s->internal->init_off = 0;
3333395f70eSjsing 
334ab211f3dSjsing 		if (SSL_IS_DTLS(s)) {
335ab211f3dSjsing 			D1I(s)->handshake_write_seq =
336ab211f3dSjsing 			    D1I(s)->next_handshake_write_seq;
337ab211f3dSjsing 			dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
338ab211f3dSjsing 			    D1I(s)->handshake_write_seq, 0, 0);
339ab211f3dSjsing 			dtls1_buffer_message(s, 1);
340ab211f3dSjsing 		}
341ab211f3dSjsing 
342440bed4fSbeck 		S3I(s)->hs.state = b;
3433395f70eSjsing 	}
3443395f70eSjsing 
3453395f70eSjsing 	/* SSL3_ST_CW_CHANGE_B */
346ab211f3dSjsing 	return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
347ab211f3dSjsing 
348ab211f3dSjsing  err:
349ab211f3dSjsing 	CBB_cleanup(&cbb);
350ab211f3dSjsing 
351ab211f3dSjsing 	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
381*0f99fabaSjsing ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
3823395f70eSjsing {
383*0f99fabaSjsing 	X509_STORE_CTX *xs_ctx = NULL;
384*0f99fabaSjsing 	STACK_OF(X509) *chain;
3853395f70eSjsing 	CBB cert_list;
386*0f99fabaSjsing 	X509 *x;
3873395f70eSjsing 	int ret = 0;
3883395f70eSjsing 	int i;
3893395f70eSjsing 
3903395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
3913395f70eSjsing 		goto err;
3923395f70eSjsing 
393*0f99fabaSjsing 	/* Send an empty certificate list when no certificate is available. */
394*0f99fabaSjsing 	if (cpk == NULL)
395*0f99fabaSjsing 		goto done;
3963395f70eSjsing 
397*0f99fabaSjsing 	if ((chain = cpk->chain) == NULL)
398*0f99fabaSjsing 		chain = s->ctx->extra_certs;
399*0f99fabaSjsing 
400*0f99fabaSjsing 	if (chain != NULL || (s->internal->mode & SSL_MODE_NO_AUTO_CHAIN)) {
401*0f99fabaSjsing 		if (!ssl3_add_cert(&cert_list, cpk->x509))
4023395f70eSjsing 			goto err;
4033395f70eSjsing 	} else {
404*0f99fabaSjsing 		if ((xs_ctx = X509_STORE_CTX_new()) == NULL)
405*0f99fabaSjsing 			goto err;
406*0f99fabaSjsing 		if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store,
407*0f99fabaSjsing 		    cpk->x509, NULL)) {
408c9d7abb7Sbeck 			SSLerror(s, ERR_R_X509_LIB);
4093395f70eSjsing 			goto err;
4103395f70eSjsing 		}
411*0f99fabaSjsing 		X509_verify_cert(xs_ctx);
4123395f70eSjsing 		ERR_clear_error();
413*0f99fabaSjsing 		chain = xs_ctx->chain;
4143395f70eSjsing 	}
4153395f70eSjsing 
416*0f99fabaSjsing 	for (i = 0; i < sk_X509_num(chain); i++) {
417*0f99fabaSjsing 		x = sk_X509_value(chain, i);
4183395f70eSjsing 		if (!ssl3_add_cert(&cert_list, x))
4193395f70eSjsing 			goto err;
4203395f70eSjsing 	}
4213395f70eSjsing 
422*0f99fabaSjsing  done:
4233395f70eSjsing 	if (!CBB_flush(cbb))
4243395f70eSjsing 		goto err;
4253395f70eSjsing 
4263395f70eSjsing 	ret = 1;
4273395f70eSjsing 
4283395f70eSjsing  err:
429*0f99fabaSjsing 	X509_STORE_CTX_free(xs_ctx);
430*0f99fabaSjsing 
4313395f70eSjsing 	return (ret);
4323395f70eSjsing }
4333395f70eSjsing 
4343395f70eSjsing /*
4353395f70eSjsing  * Obtain handshake message of message type 'mt' (any if mt == -1),
4363395f70eSjsing  * maximum acceptable body length 'max'.
4373395f70eSjsing  * The first four bytes (msg_type and length) are read in state 'st1',
4383395f70eSjsing  * the body is read in state 'stn'.
4393395f70eSjsing  */
4403395f70eSjsing long
4413395f70eSjsing ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
4423395f70eSjsing {
4433395f70eSjsing 	unsigned char *p;
4443395f70eSjsing 	uint32_t l;
4453395f70eSjsing 	long n;
4463395f70eSjsing 	int i, al;
4473395f70eSjsing 	CBS cbs;
4483395f70eSjsing 	uint8_t u8;
4493395f70eSjsing 
4503395f70eSjsing 	if (S3I(s)->tmp.reuse_message) {
4513395f70eSjsing 		S3I(s)->tmp.reuse_message = 0;
4523395f70eSjsing 		if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
4533395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
454c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
4553395f70eSjsing 			goto f_err;
4563395f70eSjsing 		}
4573395f70eSjsing 		*ok = 1;
4583395f70eSjsing 		s->internal->init_msg = s->internal->init_buf->data + 4;
4593395f70eSjsing 		s->internal->init_num = (int)S3I(s)->tmp.message_size;
4603395f70eSjsing 		return s->internal->init_num;
4613395f70eSjsing 	}
4623395f70eSjsing 
4633395f70eSjsing 	p = (unsigned char *)s->internal->init_buf->data;
4643395f70eSjsing 
4653395f70eSjsing 	/* s->internal->init_num < 4 */
466440bed4fSbeck 	if (S3I(s)->hs.state == st1) {
4673395f70eSjsing 		int skip_message;
4683395f70eSjsing 
4693395f70eSjsing 		do {
4703395f70eSjsing 			while (s->internal->init_num < 4) {
4713395f70eSjsing 				i = s->method->internal->ssl_read_bytes(s,
4723395f70eSjsing 				    SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
4733395f70eSjsing 				    4 - s->internal->init_num, 0);
4743395f70eSjsing 				if (i <= 0) {
4753395f70eSjsing 					s->internal->rwstate = SSL_READING;
4763395f70eSjsing 					*ok = 0;
4773395f70eSjsing 					return i;
4783395f70eSjsing 				}
4793395f70eSjsing 				s->internal->init_num += i;
4803395f70eSjsing 			}
4813395f70eSjsing 
4823395f70eSjsing 			skip_message = 0;
4833395f70eSjsing 			if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
4843395f70eSjsing 				/*
4853395f70eSjsing 				 * The server may always send 'Hello Request'
4863395f70eSjsing 				 * messages -- we are doing a handshake anyway
4873395f70eSjsing 				 * now, so ignore them if their format is
4883395f70eSjsing 				 * correct.  Does not count for 'Finished' MAC.
4893395f70eSjsing 				 */
4903395f70eSjsing 				if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
4913395f70eSjsing 					s->internal->init_num = 0;
4923395f70eSjsing 					skip_message = 1;
4933395f70eSjsing 
4943395f70eSjsing 					if (s->internal->msg_callback)
4953395f70eSjsing 						s->internal->msg_callback(0, s->version,
4963395f70eSjsing 						    SSL3_RT_HANDSHAKE, p, 4, s,
4973395f70eSjsing 						    s->internal->msg_callback_arg);
4983395f70eSjsing 				}
4993395f70eSjsing 			}
5003395f70eSjsing 		} while (skip_message);
5013395f70eSjsing 
5023395f70eSjsing 		/* s->internal->init_num == 4 */
5033395f70eSjsing 
5043395f70eSjsing 		if ((mt >= 0) && (*p != mt)) {
5053395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
506c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
5073395f70eSjsing 			goto f_err;
5083395f70eSjsing 		}
5093395f70eSjsing 
5103395f70eSjsing 		CBS_init(&cbs, p, 4);
5113395f70eSjsing 		if (!CBS_get_u8(&cbs, &u8) ||
5123395f70eSjsing 		    !CBS_get_u24(&cbs, &l)) {
513c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
5143395f70eSjsing 			goto err;
5153395f70eSjsing 		}
5163395f70eSjsing 		S3I(s)->tmp.message_type = u8;
5173395f70eSjsing 
5183395f70eSjsing 		if (l > (unsigned long)max) {
5193395f70eSjsing 			al = SSL_AD_ILLEGAL_PARAMETER;
520c9d7abb7Sbeck 			SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
5213395f70eSjsing 			goto f_err;
5223395f70eSjsing 		}
5233395f70eSjsing 		if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
524c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
5253395f70eSjsing 			goto err;
5263395f70eSjsing 		}
5273395f70eSjsing 		S3I(s)->tmp.message_size = l;
528440bed4fSbeck 		S3I(s)->hs.state = stn;
5293395f70eSjsing 
5303395f70eSjsing 		s->internal->init_msg = s->internal->init_buf->data + 4;
5313395f70eSjsing 		s->internal->init_num = 0;
5323395f70eSjsing 	}
5333395f70eSjsing 
5343395f70eSjsing 	/* next state (stn) */
5353395f70eSjsing 	p = s->internal->init_msg;
5363395f70eSjsing 	n = S3I(s)->tmp.message_size - s->internal->init_num;
5373395f70eSjsing 	while (n > 0) {
5383395f70eSjsing 		i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
5393395f70eSjsing 		    &p[s->internal->init_num], n, 0);
5403395f70eSjsing 		if (i <= 0) {
5413395f70eSjsing 			s->internal->rwstate = SSL_READING;
5423395f70eSjsing 			*ok = 0;
5433395f70eSjsing 			return i;
5443395f70eSjsing 		}
5453395f70eSjsing 		s->internal->init_num += i;
5463395f70eSjsing 		n -= i;
5473395f70eSjsing 	}
5483395f70eSjsing 
5493395f70eSjsing 	/* If receiving Finished, record MAC of prior handshake messages for
5503395f70eSjsing 	 * Finished verification. */
5513395f70eSjsing 	if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
5523395f70eSjsing 		ssl3_take_mac(s);
5533395f70eSjsing 
5543395f70eSjsing 	/* Feed this message into MAC computation. */
5553395f70eSjsing 	if (s->internal->mac_packet) {
556cef855dcSjsing 		tls1_transcript_record(s, (unsigned char *)s->internal->init_buf->data,
5573395f70eSjsing 		    s->internal->init_num + 4);
5583395f70eSjsing 
5593395f70eSjsing 		if (s->internal->msg_callback)
5603395f70eSjsing 			s->internal->msg_callback(0, s->version,
5613395f70eSjsing 			    SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
5623395f70eSjsing 			    (size_t)s->internal->init_num + 4, s,
5633395f70eSjsing 			    s->internal->msg_callback_arg);
5643395f70eSjsing 	}
5653395f70eSjsing 
5663395f70eSjsing 	*ok = 1;
5673395f70eSjsing 	return (s->internal->init_num);
5683395f70eSjsing 
5693395f70eSjsing f_err:
5703395f70eSjsing 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
5713395f70eSjsing err:
5723395f70eSjsing 	*ok = 0;
5733395f70eSjsing 	return (-1);
5743395f70eSjsing }
5753395f70eSjsing 
5763395f70eSjsing int
5773395f70eSjsing ssl_cert_type(X509 *x, EVP_PKEY *pkey)
5783395f70eSjsing {
5793395f70eSjsing 	EVP_PKEY *pk;
5803395f70eSjsing 	int ret = -1, i;
5813395f70eSjsing 
5823395f70eSjsing 	if (pkey == NULL)
5833395f70eSjsing 		pk = X509_get_pubkey(x);
5843395f70eSjsing 	else
5853395f70eSjsing 		pk = pkey;
5863395f70eSjsing 	if (pk == NULL)
5873395f70eSjsing 		goto err;
5883395f70eSjsing 
5893395f70eSjsing 	i = pk->type;
5903395f70eSjsing 	if (i == EVP_PKEY_RSA) {
5913395f70eSjsing 		ret = SSL_PKEY_RSA_ENC;
5923395f70eSjsing 	} else if (i == EVP_PKEY_EC) {
5933395f70eSjsing 		ret = SSL_PKEY_ECC;
5943395f70eSjsing 	} else if (i == NID_id_GostR3410_2001 ||
5953395f70eSjsing 	    i == NID_id_GostR3410_2001_cc) {
5963395f70eSjsing 		ret = SSL_PKEY_GOST01;
5973395f70eSjsing 	}
5983395f70eSjsing 
5993395f70eSjsing err:
6003395f70eSjsing 	if (!pkey)
6013395f70eSjsing 		EVP_PKEY_free(pk);
6023395f70eSjsing 	return (ret);
6033395f70eSjsing }
6043395f70eSjsing 
6053395f70eSjsing int
6063395f70eSjsing ssl_verify_alarm_type(long type)
6073395f70eSjsing {
6083395f70eSjsing 	int al;
6093395f70eSjsing 
6103395f70eSjsing 	switch (type) {
6113395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
6123395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL:
6133395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
6143395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
6153395f70eSjsing 		break;
6163395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
6173395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
6183395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
6193395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
6203395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
6213395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
6223395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
6233395f70eSjsing 	case X509_V_ERR_CERT_NOT_YET_VALID:
6243395f70eSjsing 	case X509_V_ERR_CRL_NOT_YET_VALID:
6253395f70eSjsing 	case X509_V_ERR_CERT_UNTRUSTED:
6263395f70eSjsing 	case X509_V_ERR_CERT_REJECTED:
6273395f70eSjsing 		al = SSL_AD_BAD_CERTIFICATE;
6283395f70eSjsing 		break;
6293395f70eSjsing 	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
6303395f70eSjsing 	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
6313395f70eSjsing 		al = SSL_AD_DECRYPT_ERROR;
6323395f70eSjsing 		break;
6333395f70eSjsing 	case X509_V_ERR_CERT_HAS_EXPIRED:
6343395f70eSjsing 	case X509_V_ERR_CRL_HAS_EXPIRED:
6353395f70eSjsing 		al = SSL_AD_CERTIFICATE_EXPIRED;
6363395f70eSjsing 		break;
6373395f70eSjsing 	case X509_V_ERR_CERT_REVOKED:
6383395f70eSjsing 		al = SSL_AD_CERTIFICATE_REVOKED;
6393395f70eSjsing 		break;
6403395f70eSjsing 	case X509_V_ERR_OUT_OF_MEM:
6413395f70eSjsing 		al = SSL_AD_INTERNAL_ERROR;
6423395f70eSjsing 		break;
6433395f70eSjsing 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
6443395f70eSjsing 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
6453395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
6463395f70eSjsing 	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
6473395f70eSjsing 	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
6483395f70eSjsing 	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
6493395f70eSjsing 	case X509_V_ERR_INVALID_CA:
6503395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
6513395f70eSjsing 		break;
6523395f70eSjsing 	case X509_V_ERR_APPLICATION_VERIFICATION:
6533395f70eSjsing 		al = SSL_AD_HANDSHAKE_FAILURE;
6543395f70eSjsing 		break;
6553395f70eSjsing 	case X509_V_ERR_INVALID_PURPOSE:
6563395f70eSjsing 		al = SSL_AD_UNSUPPORTED_CERTIFICATE;
6573395f70eSjsing 		break;
6583395f70eSjsing 	default:
6593395f70eSjsing 		al = SSL_AD_CERTIFICATE_UNKNOWN;
6603395f70eSjsing 		break;
6613395f70eSjsing 	}
6623395f70eSjsing 	return (al);
6633395f70eSjsing }
6643395f70eSjsing 
6653395f70eSjsing int
6663395f70eSjsing ssl3_setup_init_buffer(SSL *s)
6673395f70eSjsing {
6683395f70eSjsing 	BUF_MEM *buf = NULL;
6693395f70eSjsing 
6703395f70eSjsing 	if (s->internal->init_buf != NULL)
6713395f70eSjsing 		return (1);
6723395f70eSjsing 
6733395f70eSjsing 	if ((buf = BUF_MEM_new()) == NULL)
6743395f70eSjsing 		goto err;
6753395f70eSjsing 	if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
6763395f70eSjsing 		goto err;
6773395f70eSjsing 
6783395f70eSjsing 	s->internal->init_buf = buf;
6793395f70eSjsing 	return (1);
6803395f70eSjsing 
6813395f70eSjsing err:
6823395f70eSjsing 	BUF_MEM_free(buf);
6833395f70eSjsing 	return (0);
6843395f70eSjsing }
6853395f70eSjsing 
6863395f70eSjsing int
6873395f70eSjsing ssl3_setup_read_buffer(SSL *s)
6883395f70eSjsing {
6893395f70eSjsing 	unsigned char *p;
6903395f70eSjsing 	size_t len, align, headerlen;
6913395f70eSjsing 
6923395f70eSjsing 	if (SSL_IS_DTLS(s))
6933395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH;
6943395f70eSjsing 	else
6953395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
6963395f70eSjsing 
6973395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
6983395f70eSjsing 
69975f93637Sjsing 	if (S3I(s)->rbuf.buf == NULL) {
7003395f70eSjsing 		len = SSL3_RT_MAX_PLAIN_LENGTH +
7013395f70eSjsing 		    SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
7023395f70eSjsing 		if ((p = malloc(len)) == NULL)
7033395f70eSjsing 			goto err;
70475f93637Sjsing 		S3I(s)->rbuf.buf = p;
70575f93637Sjsing 		S3I(s)->rbuf.len = len;
7063395f70eSjsing 	}
7073395f70eSjsing 
70875f93637Sjsing 	s->internal->packet = &(S3I(s)->rbuf.buf[0]);
7093395f70eSjsing 	return 1;
7103395f70eSjsing 
7113395f70eSjsing err:
712c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
7133395f70eSjsing 	return 0;
7143395f70eSjsing }
7153395f70eSjsing 
7163395f70eSjsing int
7173395f70eSjsing ssl3_setup_write_buffer(SSL *s)
7183395f70eSjsing {
7193395f70eSjsing 	unsigned char *p;
7203395f70eSjsing 	size_t len, align, headerlen;
7213395f70eSjsing 
7223395f70eSjsing 	if (SSL_IS_DTLS(s))
7233395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
7243395f70eSjsing 	else
7253395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
7263395f70eSjsing 
7273395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
7283395f70eSjsing 
72975f93637Sjsing 	if (S3I(s)->wbuf.buf == NULL) {
7303395f70eSjsing 		len = s->max_send_fragment +
7313395f70eSjsing 		    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
7323395f70eSjsing 		if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
7333395f70eSjsing 			len += headerlen + align +
7343395f70eSjsing 			    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
7353395f70eSjsing 
7363395f70eSjsing 		if ((p = malloc(len)) == NULL)
7373395f70eSjsing 			goto err;
73875f93637Sjsing 		S3I(s)->wbuf.buf = p;
73975f93637Sjsing 		S3I(s)->wbuf.len = len;
7403395f70eSjsing 	}
7413395f70eSjsing 
7423395f70eSjsing 	return 1;
7433395f70eSjsing 
7443395f70eSjsing err:
745c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
7463395f70eSjsing 	return 0;
7473395f70eSjsing }
7483395f70eSjsing 
7493395f70eSjsing int
7503395f70eSjsing ssl3_setup_buffers(SSL *s)
7513395f70eSjsing {
7523395f70eSjsing 	if (!ssl3_setup_read_buffer(s))
7533395f70eSjsing 		return 0;
7543395f70eSjsing 	if (!ssl3_setup_write_buffer(s))
7553395f70eSjsing 		return 0;
7563395f70eSjsing 	return 1;
7573395f70eSjsing }
7583395f70eSjsing 
7593395f70eSjsing int
7603395f70eSjsing ssl3_release_write_buffer(SSL *s)
7613395f70eSjsing {
76275f93637Sjsing 	free(S3I(s)->wbuf.buf);
76375f93637Sjsing 	S3I(s)->wbuf.buf = NULL;
7643395f70eSjsing 	return 1;
7653395f70eSjsing }
7663395f70eSjsing 
7673395f70eSjsing int
7683395f70eSjsing ssl3_release_read_buffer(SSL *s)
7693395f70eSjsing {
77075f93637Sjsing 	free(S3I(s)->rbuf.buf);
77175f93637Sjsing 	S3I(s)->rbuf.buf = NULL;
7723395f70eSjsing 	return 1;
7733395f70eSjsing }
774