xref: /openbsd/lib/libssl/ssl_both.c (revision 689a9b7e)
1*689a9b7eSbeck /* $OpenBSD: ssl_both.c,v 1.47 2024/02/03 15:58:33 beck 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 <openssl/buffer.h>
1223395f70eSjsing #include <openssl/evp.h>
1233395f70eSjsing #include <openssl/objects.h>
1243395f70eSjsing #include <openssl/x509.h>
1253395f70eSjsing 
1263395f70eSjsing #include "bytestring.h"
127c9675a23Stb #include "dtls_local.h"
128c9675a23Stb #include "ssl_local.h"
1293395f70eSjsing 
1303395f70eSjsing /*
1316f7f653bSjsing  * Send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
1323395f70eSjsing  * SSL3_RT_CHANGE_CIPHER_SPEC).
1333395f70eSjsing  */
1343395f70eSjsing int
ssl3_do_write(SSL * s,int type)1353395f70eSjsing ssl3_do_write(SSL *s, int type)
1363395f70eSjsing {
1373395f70eSjsing 	int ret;
1383395f70eSjsing 
1396f7f653bSjsing 	ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
1406f7f653bSjsing 	    s->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,
1506f7f653bSjsing 		    (unsigned char *)&s->init_buf->data[s->init_off], ret);
1513395f70eSjsing 
1526f7f653bSjsing 	if (ret == s->init_num) {
1536f7f653bSjsing 		ssl_msg_callback(s, 1, type, s->init_buf->data,
1546f7f653bSjsing 		    (size_t)(s->init_off + s->init_num));
1553395f70eSjsing 		return (1);
1563395f70eSjsing 	}
1573395f70eSjsing 
1586f7f653bSjsing 	s->init_off += ret;
1596f7f653bSjsing 	s->init_num -= ret;
1603395f70eSjsing 
1613395f70eSjsing 	return (0);
1623395f70eSjsing }
1633395f70eSjsing 
1643395f70eSjsing static int
ssl3_add_cert(CBB * cbb,X509 * x)1653395f70eSjsing ssl3_add_cert(CBB *cbb, X509 *x)
1663395f70eSjsing {
1673395f70eSjsing 	unsigned char *data;
1683395f70eSjsing 	int cert_len;
1693395f70eSjsing 	int ret = 0;
1703395f70eSjsing 	CBB cert;
1713395f70eSjsing 
1723395f70eSjsing 	if ((cert_len = i2d_X509(x, NULL)) < 0)
1733395f70eSjsing 		goto err;
1743395f70eSjsing 
1753395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert))
1763395f70eSjsing 		goto err;
1773395f70eSjsing 	if (!CBB_add_space(&cert, &data, cert_len))
1783395f70eSjsing 		goto err;
1793395f70eSjsing 	if (i2d_X509(x, &data) < 0)
1803395f70eSjsing 		goto err;
1813395f70eSjsing 	if (!CBB_flush(cbb))
1823395f70eSjsing 		goto err;
1833395f70eSjsing 
1843395f70eSjsing 	ret = 1;
1853395f70eSjsing 
1863395f70eSjsing  err:
1873395f70eSjsing 	return (ret);
1883395f70eSjsing }
1893395f70eSjsing 
1903395f70eSjsing int
ssl3_output_cert_chain(SSL * s,CBB * cbb,SSL_CERT_PKEY * cpk)191ef36d1f9Sjsing ssl3_output_cert_chain(SSL *s, CBB *cbb, SSL_CERT_PKEY *cpk)
1923395f70eSjsing {
1930f99fabaSjsing 	X509_STORE_CTX *xs_ctx = NULL;
1940f99fabaSjsing 	STACK_OF(X509) *chain;
1953395f70eSjsing 	CBB cert_list;
1960f99fabaSjsing 	X509 *x;
1973395f70eSjsing 	int ret = 0;
1983395f70eSjsing 	int i;
1993395f70eSjsing 
2003395f70eSjsing 	if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
2013395f70eSjsing 		goto err;
2023395f70eSjsing 
2030f99fabaSjsing 	/* Send an empty certificate list when no certificate is available. */
2040f99fabaSjsing 	if (cpk == NULL)
2050f99fabaSjsing 		goto done;
2063395f70eSjsing 
2070f99fabaSjsing 	if ((chain = cpk->chain) == NULL)
2080f99fabaSjsing 		chain = s->ctx->extra_certs;
2090f99fabaSjsing 
2106f7f653bSjsing 	if (chain != NULL || (s->mode & SSL_MODE_NO_AUTO_CHAIN)) {
2110f99fabaSjsing 		if (!ssl3_add_cert(&cert_list, cpk->x509))
2123395f70eSjsing 			goto err;
2133395f70eSjsing 	} else {
2140f99fabaSjsing 		if ((xs_ctx = X509_STORE_CTX_new()) == NULL)
2150f99fabaSjsing 			goto err;
2160f99fabaSjsing 		if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store,
2170f99fabaSjsing 		    cpk->x509, NULL)) {
218c9d7abb7Sbeck 			SSLerror(s, ERR_R_X509_LIB);
2193395f70eSjsing 			goto err;
2203395f70eSjsing 		}
221fda9215fSjsing 		X509_VERIFY_PARAM_set_flags(X509_STORE_CTX_get0_param(xs_ctx),
222fda9215fSjsing 		    X509_V_FLAG_LEGACY_VERIFY);
2230f99fabaSjsing 		X509_verify_cert(xs_ctx);
2243395f70eSjsing 		ERR_clear_error();
225d3771e01Stb 		chain = X509_STORE_CTX_get0_chain(xs_ctx);
2263395f70eSjsing 	}
2273395f70eSjsing 
2280f99fabaSjsing 	for (i = 0; i < sk_X509_num(chain); i++) {
2290f99fabaSjsing 		x = sk_X509_value(chain, i);
2303395f70eSjsing 		if (!ssl3_add_cert(&cert_list, x))
2313395f70eSjsing 			goto err;
2323395f70eSjsing 	}
2333395f70eSjsing 
2340f99fabaSjsing  done:
2353395f70eSjsing 	if (!CBB_flush(cbb))
2363395f70eSjsing 		goto err;
2373395f70eSjsing 
2383395f70eSjsing 	ret = 1;
2393395f70eSjsing 
2403395f70eSjsing  err:
2410f99fabaSjsing 	X509_STORE_CTX_free(xs_ctx);
2420f99fabaSjsing 
2433395f70eSjsing 	return (ret);
2443395f70eSjsing }
2453395f70eSjsing 
2463395f70eSjsing /*
2473395f70eSjsing  * Obtain handshake message of message type 'mt' (any if mt == -1),
2483395f70eSjsing  * maximum acceptable body length 'max'.
2493395f70eSjsing  * The first four bytes (msg_type and length) are read in state 'st1',
2503395f70eSjsing  * the body is read in state 'stn'.
2513395f70eSjsing  */
252f2c3e964Sjsing int
ssl3_get_message(SSL * s,int st1,int stn,int mt,long max)253f2c3e964Sjsing ssl3_get_message(SSL *s, int st1, int stn, int mt, long max)
2543395f70eSjsing {
2553395f70eSjsing 	unsigned char *p;
2563395f70eSjsing 	uint32_t l;
2573395f70eSjsing 	long n;
2583395f70eSjsing 	int i, al;
2593395f70eSjsing 	CBS cbs;
2603395f70eSjsing 	uint8_t u8;
2613395f70eSjsing 
2629e659261Sjsing 	if (SSL_is_dtls(s))
263f2c3e964Sjsing 		return dtls1_get_message(s, st1, stn, mt, max);
264dc77a1b6Sjsing 
26502876cc3Sjsing 	if (s->s3->hs.tls12.reuse_message) {
26602876cc3Sjsing 		s->s3->hs.tls12.reuse_message = 0;
26702876cc3Sjsing 		if ((mt >= 0) && (s->s3->hs.tls12.message_type != mt)) {
2683395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
269c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
270ba06b73eStb 			goto fatal_err;
2713395f70eSjsing 		}
2726f7f653bSjsing 		s->init_msg = s->init_buf->data +
2737795c7f4Sjsing 		    SSL3_HM_HEADER_LENGTH;
2746f7f653bSjsing 		s->init_num = (int)s->s3->hs.tls12.message_size;
275f2c3e964Sjsing 		return 1;
2763395f70eSjsing 	}
2773395f70eSjsing 
2786f7f653bSjsing 	p = (unsigned char *)s->init_buf->data;
2793395f70eSjsing 
28002876cc3Sjsing 	if (s->s3->hs.state == st1) {
2813395f70eSjsing 		int skip_message;
2823395f70eSjsing 
2833395f70eSjsing 		do {
2846f7f653bSjsing 			while (s->init_num < SSL3_HM_HEADER_LENGTH) {
2856ba40c14Sjsing 				i = s->method->ssl_read_bytes(s,
2866f7f653bSjsing 				    SSL3_RT_HANDSHAKE, &p[s->init_num],
2876f7f653bSjsing 				    SSL3_HM_HEADER_LENGTH - s->init_num, 0);
2883395f70eSjsing 				if (i <= 0) {
2896f7f653bSjsing 					s->rwstate = SSL_READING;
2903395f70eSjsing 					return i;
2913395f70eSjsing 				}
2926f7f653bSjsing 				s->init_num += i;
2933395f70eSjsing 			}
2943395f70eSjsing 
2953395f70eSjsing 			skip_message = 0;
2963395f70eSjsing 			if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
2973395f70eSjsing 				/*
2983395f70eSjsing 				 * The server may always send 'Hello Request'
2993395f70eSjsing 				 * messages -- we are doing a handshake anyway
3003395f70eSjsing 				 * now, so ignore them if their format is
3013395f70eSjsing 				 * correct.  Does not count for 'Finished' MAC.
3023395f70eSjsing 				 */
3033395f70eSjsing 				if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
3046f7f653bSjsing 					s->init_num = 0;
3053395f70eSjsing 					skip_message = 1;
3063395f70eSjsing 
307545b2b63Sjsing 					ssl_msg_callback(s, 0,
3087795c7f4Sjsing 					    SSL3_RT_HANDSHAKE, p,
3097795c7f4Sjsing 					    SSL3_HM_HEADER_LENGTH);
3103395f70eSjsing 				}
3113395f70eSjsing 			}
3123395f70eSjsing 		} while (skip_message);
3133395f70eSjsing 
3143395f70eSjsing 		if ((mt >= 0) && (*p != mt)) {
3153395f70eSjsing 			al = SSL_AD_UNEXPECTED_MESSAGE;
316c9d7abb7Sbeck 			SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
317ba06b73eStb 			goto fatal_err;
3183395f70eSjsing 		}
3193395f70eSjsing 
3207795c7f4Sjsing 		CBS_init(&cbs, p, SSL3_HM_HEADER_LENGTH);
3213395f70eSjsing 		if (!CBS_get_u8(&cbs, &u8) ||
3223395f70eSjsing 		    !CBS_get_u24(&cbs, &l)) {
323c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
3243395f70eSjsing 			goto err;
3253395f70eSjsing 		}
32602876cc3Sjsing 		s->s3->hs.tls12.message_type = u8;
3273395f70eSjsing 
3283395f70eSjsing 		if (l > (unsigned long)max) {
3293395f70eSjsing 			al = SSL_AD_ILLEGAL_PARAMETER;
330c9d7abb7Sbeck 			SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
331ba06b73eStb 			goto fatal_err;
3323395f70eSjsing 		}
3336f7f653bSjsing 		if (l && !BUF_MEM_grow_clean(s->init_buf,
3347795c7f4Sjsing 		    l + SSL3_HM_HEADER_LENGTH)) {
335c9d7abb7Sbeck 			SSLerror(s, ERR_R_BUF_LIB);
3363395f70eSjsing 			goto err;
3373395f70eSjsing 		}
33802876cc3Sjsing 		s->s3->hs.tls12.message_size = l;
33902876cc3Sjsing 		s->s3->hs.state = stn;
3403395f70eSjsing 
3416f7f653bSjsing 		s->init_msg = s->init_buf->data +
3427795c7f4Sjsing 		    SSL3_HM_HEADER_LENGTH;
3436f7f653bSjsing 		s->init_num = 0;
3443395f70eSjsing 	}
3453395f70eSjsing 
3463395f70eSjsing 	/* next state (stn) */
3476f7f653bSjsing 	p = s->init_msg;
3486f7f653bSjsing 	n = s->s3->hs.tls12.message_size - s->init_num;
3493395f70eSjsing 	while (n > 0) {
3506ba40c14Sjsing 		i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
3516f7f653bSjsing 		    &p[s->init_num], n, 0);
3523395f70eSjsing 		if (i <= 0) {
3536f7f653bSjsing 			s->rwstate = SSL_READING;
3543395f70eSjsing 			return i;
3553395f70eSjsing 		}
3566f7f653bSjsing 		s->init_num += i;
3573395f70eSjsing 		n -= i;
3583395f70eSjsing 	}
3593395f70eSjsing 
3603395f70eSjsing 	/* Feed this message into MAC computation. */
3616f7f653bSjsing 	if (s->mac_packet) {
3626f7f653bSjsing 		tls1_transcript_record(s, (unsigned char *)s->init_buf->data,
3636f7f653bSjsing 		    s->init_num + SSL3_HM_HEADER_LENGTH);
3643395f70eSjsing 
365545b2b63Sjsing 		ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE,
3666f7f653bSjsing 		    s->init_buf->data,
3676f7f653bSjsing 		    (size_t)s->init_num + SSL3_HM_HEADER_LENGTH);
3683395f70eSjsing 	}
3693395f70eSjsing 
370f2c3e964Sjsing 	return 1;
3713395f70eSjsing 
372ba06b73eStb  fatal_err:
3733395f70eSjsing 	ssl3_send_alert(s, SSL3_AL_FATAL, al);
3743395f70eSjsing  err:
375f2c3e964Sjsing 	return -1;
3763395f70eSjsing }
3773395f70eSjsing 
3783395f70eSjsing int
ssl_cert_type(EVP_PKEY * pkey)379e7fd08e8Sjsing ssl_cert_type(EVP_PKEY *pkey)
3803395f70eSjsing {
3813395f70eSjsing 	if (pkey == NULL)
382e7fd08e8Sjsing 		return -1;
3833395f70eSjsing 
384e7fd08e8Sjsing 	switch (EVP_PKEY_id(pkey)) {
385e7fd08e8Sjsing 	case EVP_PKEY_EC:
386e7fd08e8Sjsing 		return SSL_PKEY_ECC;
387e7fd08e8Sjsing 	case EVP_PKEY_RSA:
38811b12eccStb 	case EVP_PKEY_RSA_PSS:
389e7fd08e8Sjsing 		return SSL_PKEY_RSA;
3903395f70eSjsing 	}
3913395f70eSjsing 
392e7fd08e8Sjsing 	return -1;
3933395f70eSjsing }
3943395f70eSjsing 
3953395f70eSjsing int
ssl_verify_alarm_type(long type)3963395f70eSjsing ssl_verify_alarm_type(long type)
3973395f70eSjsing {
3983395f70eSjsing 	int al;
3993395f70eSjsing 
4003395f70eSjsing 	switch (type) {
4013395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
4023395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL:
4033395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
4043395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
4053395f70eSjsing 		break;
4063395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
4073395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
4083395f70eSjsing 	case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
4093395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
4103395f70eSjsing 	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
4113395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
4123395f70eSjsing 	case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
4133395f70eSjsing 	case X509_V_ERR_CERT_NOT_YET_VALID:
4143395f70eSjsing 	case X509_V_ERR_CRL_NOT_YET_VALID:
4153395f70eSjsing 	case X509_V_ERR_CERT_UNTRUSTED:
4163395f70eSjsing 	case X509_V_ERR_CERT_REJECTED:
4173395f70eSjsing 		al = SSL_AD_BAD_CERTIFICATE;
4183395f70eSjsing 		break;
4193395f70eSjsing 	case X509_V_ERR_CERT_SIGNATURE_FAILURE:
4203395f70eSjsing 	case X509_V_ERR_CRL_SIGNATURE_FAILURE:
4213395f70eSjsing 		al = SSL_AD_DECRYPT_ERROR;
4223395f70eSjsing 		break;
4233395f70eSjsing 	case X509_V_ERR_CERT_HAS_EXPIRED:
4243395f70eSjsing 	case X509_V_ERR_CRL_HAS_EXPIRED:
4253395f70eSjsing 		al = SSL_AD_CERTIFICATE_EXPIRED;
4263395f70eSjsing 		break;
4273395f70eSjsing 	case X509_V_ERR_CERT_REVOKED:
4283395f70eSjsing 		al = SSL_AD_CERTIFICATE_REVOKED;
4293395f70eSjsing 		break;
4303395f70eSjsing 	case X509_V_ERR_OUT_OF_MEM:
4313395f70eSjsing 		al = SSL_AD_INTERNAL_ERROR;
4323395f70eSjsing 		break;
4333395f70eSjsing 	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
4343395f70eSjsing 	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
4353395f70eSjsing 	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
4363395f70eSjsing 	case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
4373395f70eSjsing 	case X509_V_ERR_CERT_CHAIN_TOO_LONG:
4383395f70eSjsing 	case X509_V_ERR_PATH_LENGTH_EXCEEDED:
4393395f70eSjsing 	case X509_V_ERR_INVALID_CA:
4403395f70eSjsing 		al = SSL_AD_UNKNOWN_CA;
4413395f70eSjsing 		break;
4423395f70eSjsing 	case X509_V_ERR_APPLICATION_VERIFICATION:
4433395f70eSjsing 		al = SSL_AD_HANDSHAKE_FAILURE;
4443395f70eSjsing 		break;
4453395f70eSjsing 	case X509_V_ERR_INVALID_PURPOSE:
4463395f70eSjsing 		al = SSL_AD_UNSUPPORTED_CERTIFICATE;
4473395f70eSjsing 		break;
4483395f70eSjsing 	default:
4493395f70eSjsing 		al = SSL_AD_CERTIFICATE_UNKNOWN;
4503395f70eSjsing 		break;
4513395f70eSjsing 	}
4523395f70eSjsing 	return (al);
4533395f70eSjsing }
4543395f70eSjsing 
4553395f70eSjsing int
ssl3_setup_init_buffer(SSL * s)4563395f70eSjsing ssl3_setup_init_buffer(SSL *s)
4573395f70eSjsing {
4583395f70eSjsing 	BUF_MEM *buf = NULL;
4593395f70eSjsing 
4606f7f653bSjsing 	if (s->init_buf != NULL)
4613395f70eSjsing 		return (1);
4623395f70eSjsing 
4633395f70eSjsing 	if ((buf = BUF_MEM_new()) == NULL)
4643395f70eSjsing 		goto err;
4653395f70eSjsing 	if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
4663395f70eSjsing 		goto err;
4673395f70eSjsing 
4686f7f653bSjsing 	s->init_buf = buf;
4693395f70eSjsing 	return (1);
4703395f70eSjsing 
4713395f70eSjsing  err:
4723395f70eSjsing 	BUF_MEM_free(buf);
4733395f70eSjsing 	return (0);
4743395f70eSjsing }
4753395f70eSjsing 
476beb7767dSjsing void
ssl3_release_init_buffer(SSL * s)477beb7767dSjsing ssl3_release_init_buffer(SSL *s)
478beb7767dSjsing {
4796f7f653bSjsing 	BUF_MEM_free(s->init_buf);
4806f7f653bSjsing 	s->init_buf = NULL;
4816f7f653bSjsing 	s->init_msg = NULL;
4826f7f653bSjsing 	s->init_num = 0;
4836f7f653bSjsing 	s->init_off = 0;
484beb7767dSjsing }
485beb7767dSjsing 
4863395f70eSjsing int
ssl3_setup_read_buffer(SSL * s)4873395f70eSjsing ssl3_setup_read_buffer(SSL *s)
4883395f70eSjsing {
4893395f70eSjsing 	unsigned char *p;
4903395f70eSjsing 	size_t len, align, headerlen;
4913395f70eSjsing 
4929e659261Sjsing 	if (SSL_is_dtls(s))
4933395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH;
4943395f70eSjsing 	else
4953395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
4963395f70eSjsing 
4973395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
4983395f70eSjsing 
49902876cc3Sjsing 	if (s->s3->rbuf.buf == NULL) {
5003395f70eSjsing 		len = SSL3_RT_MAX_PLAIN_LENGTH +
5013395f70eSjsing 		    SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
502faf44e99Sjsing 		if ((p = calloc(1, len)) == NULL)
5033395f70eSjsing 			goto err;
50402876cc3Sjsing 		s->s3->rbuf.buf = p;
50502876cc3Sjsing 		s->s3->rbuf.len = len;
5063395f70eSjsing 	}
5073395f70eSjsing 
5086f7f653bSjsing 	s->packet = s->s3->rbuf.buf;
5093395f70eSjsing 	return 1;
5103395f70eSjsing 
5113395f70eSjsing  err:
512c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
5133395f70eSjsing 	return 0;
5143395f70eSjsing }
5153395f70eSjsing 
5163395f70eSjsing int
ssl3_setup_write_buffer(SSL * s)5173395f70eSjsing ssl3_setup_write_buffer(SSL *s)
5183395f70eSjsing {
5193395f70eSjsing 	unsigned char *p;
5203395f70eSjsing 	size_t len, align, headerlen;
5213395f70eSjsing 
5229e659261Sjsing 	if (SSL_is_dtls(s))
5233395f70eSjsing 		headerlen = DTLS1_RT_HEADER_LENGTH + 1;
5243395f70eSjsing 	else
5253395f70eSjsing 		headerlen = SSL3_RT_HEADER_LENGTH;
5263395f70eSjsing 
5273395f70eSjsing 	align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
5283395f70eSjsing 
52902876cc3Sjsing 	if (s->s3->wbuf.buf == NULL) {
5303395f70eSjsing 		len = s->max_send_fragment +
5313395f70eSjsing 		    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
5326f7f653bSjsing 		if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
5333395f70eSjsing 			len += headerlen + align +
5343395f70eSjsing 			    SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
5353395f70eSjsing 
536faf44e99Sjsing 		if ((p = calloc(1, len)) == NULL)
5373395f70eSjsing 			goto err;
53802876cc3Sjsing 		s->s3->wbuf.buf = p;
53902876cc3Sjsing 		s->s3->wbuf.len = len;
5403395f70eSjsing 	}
5413395f70eSjsing 
5423395f70eSjsing 	return 1;
5433395f70eSjsing 
5443395f70eSjsing  err:
545c9d7abb7Sbeck 	SSLerror(s, ERR_R_MALLOC_FAILURE);
5463395f70eSjsing 	return 0;
5473395f70eSjsing }
5483395f70eSjsing 
5493395f70eSjsing int
ssl3_setup_buffers(SSL * s)5503395f70eSjsing ssl3_setup_buffers(SSL *s)
5513395f70eSjsing {
5523395f70eSjsing 	if (!ssl3_setup_read_buffer(s))
5533395f70eSjsing 		return 0;
5543395f70eSjsing 	if (!ssl3_setup_write_buffer(s))
5553395f70eSjsing 		return 0;
5563395f70eSjsing 	return 1;
5573395f70eSjsing }
5583395f70eSjsing 
559435f94b7Sjsing void
ssl3_release_buffer(SSL3_BUFFER_INTERNAL * b)560435f94b7Sjsing ssl3_release_buffer(SSL3_BUFFER_INTERNAL *b)
5613395f70eSjsing {
562435f94b7Sjsing 	freezero(b->buf, b->len);
563435f94b7Sjsing 	b->buf = NULL;
564435f94b7Sjsing 	b->len = 0;
5653395f70eSjsing }
5663395f70eSjsing 
567435f94b7Sjsing void
ssl3_release_read_buffer(SSL * s)5683395f70eSjsing ssl3_release_read_buffer(SSL *s)
5693395f70eSjsing {
57002876cc3Sjsing 	ssl3_release_buffer(&s->s3->rbuf);
571435f94b7Sjsing }
572435f94b7Sjsing 
573435f94b7Sjsing void
ssl3_release_write_buffer(SSL * s)574435f94b7Sjsing ssl3_release_write_buffer(SSL *s)
575435f94b7Sjsing {
57602876cc3Sjsing 	ssl3_release_buffer(&s->s3->wbuf);
5773395f70eSjsing }
578