early-access version 1255
This commit is contained in:
82
externals/libressl/ssl/CMakeLists.txt
vendored
Executable file
82
externals/libressl/ssl/CMakeLists.txt
vendored
Executable file
@@ -0,0 +1,82 @@
|
||||
set(
|
||||
SSL_SRC
|
||||
bio_ssl.c
|
||||
bs_ber.c
|
||||
bs_cbb.c
|
||||
bs_cbs.c
|
||||
d1_both.c
|
||||
d1_clnt.c
|
||||
d1_lib.c
|
||||
d1_pkt.c
|
||||
d1_srtp.c
|
||||
d1_srvr.c
|
||||
pqueue.c
|
||||
s3_cbc.c
|
||||
s3_lib.c
|
||||
ssl_algs.c
|
||||
ssl_asn1.c
|
||||
ssl_both.c
|
||||
ssl_cert.c
|
||||
ssl_ciph.c
|
||||
ssl_ciphers.c
|
||||
ssl_clnt.c
|
||||
ssl_err.c
|
||||
ssl_init.c
|
||||
ssl_kex.c
|
||||
ssl_lib.c
|
||||
ssl_methods.c
|
||||
ssl_packet.c
|
||||
ssl_pkt.c
|
||||
ssl_rsa.c
|
||||
ssl_sess.c
|
||||
ssl_sigalgs.c
|
||||
ssl_srvr.c
|
||||
ssl_stat.c
|
||||
ssl_tlsext.c
|
||||
ssl_transcript.c
|
||||
ssl_txt.c
|
||||
ssl_versions.c
|
||||
t1_enc.c
|
||||
t1_lib.c
|
||||
tls12_record_layer.c
|
||||
tls13_buffer.c
|
||||
tls13_client.c
|
||||
tls13_error.c
|
||||
tls13_handshake.c
|
||||
tls13_handshake_msg.c
|
||||
tls13_key_schedule.c
|
||||
tls13_key_share.c
|
||||
tls13_legacy.c
|
||||
tls13_lib.c
|
||||
tls13_record.c
|
||||
tls13_record_layer.c
|
||||
tls13_server.c
|
||||
)
|
||||
|
||||
add_library(ssl ${SSL_SRC})
|
||||
target_include_directories(ssl
|
||||
PRIVATE
|
||||
.
|
||||
../include/compat
|
||||
PUBLIC
|
||||
../include)
|
||||
|
||||
export_symbol(ssl ${CMAKE_CURRENT_SOURCE_DIR}/ssl.sym)
|
||||
target_link_libraries(ssl crypto ${PLATFORM_LIBS})
|
||||
if (WIN32)
|
||||
set(SSL_POSTFIX -${SSL_MAJOR_VERSION})
|
||||
endif()
|
||||
set_target_properties(ssl PROPERTIES
|
||||
OUTPUT_NAME ssl${SSL_POSTFIX}
|
||||
ARCHIVE_OUTPUT_NAME ssl${SSL_POSTFIX})
|
||||
set_target_properties(ssl PROPERTIES VERSION ${SSL_VERSION}
|
||||
SOVERSION ${SSL_MAJOR_VERSION})
|
||||
|
||||
if(ENABLE_LIBRESSL_INSTALL)
|
||||
install(
|
||||
TARGETS ssl
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif(ENABLE_LIBRESSL_INSTALL)
|
||||
1
externals/libressl/ssl/VERSION
vendored
Executable file
1
externals/libressl/ssl/VERSION
vendored
Executable file
@@ -0,0 +1 @@
|
||||
48:1:0
|
||||
590
externals/libressl/ssl/bio_ssl.c
vendored
Executable file
590
externals/libressl/ssl/bio_ssl.c
vendored
Executable file
@@ -0,0 +1,590 @@
|
||||
/* $OpenBSD: bio_ssl.c,v 1.29 2018/08/24 20:30:21 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
static int ssl_write(BIO *h, const char *buf, int num);
|
||||
static int ssl_read(BIO *h, char *buf, int size);
|
||||
static int ssl_puts(BIO *h, const char *str);
|
||||
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
|
||||
static int ssl_new(BIO *h);
|
||||
static int ssl_free(BIO *data);
|
||||
static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
|
||||
typedef struct bio_ssl_st {
|
||||
SSL *ssl; /* The ssl handle :-) */
|
||||
/* re-negotiate every time the total number of bytes is this size */
|
||||
int num_renegotiates;
|
||||
unsigned long renegotiate_count;
|
||||
unsigned long byte_count;
|
||||
unsigned long renegotiate_timeout;
|
||||
time_t last_time;
|
||||
} BIO_SSL;
|
||||
|
||||
static const BIO_METHOD methods_sslp = {
|
||||
.type = BIO_TYPE_SSL,
|
||||
.name = "ssl",
|
||||
.bwrite = ssl_write,
|
||||
.bread = ssl_read,
|
||||
.bputs = ssl_puts,
|
||||
.ctrl = ssl_ctrl,
|
||||
.create = ssl_new,
|
||||
.destroy = ssl_free,
|
||||
.callback_ctrl = ssl_callback_ctrl,
|
||||
};
|
||||
|
||||
const BIO_METHOD *
|
||||
BIO_f_ssl(void)
|
||||
{
|
||||
return (&methods_sslp);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_new(BIO *bi)
|
||||
{
|
||||
BIO_SSL *bs;
|
||||
|
||||
bs = calloc(1, sizeof(BIO_SSL));
|
||||
if (bs == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
bi->init = 0;
|
||||
bi->ptr = (char *)bs;
|
||||
bi->flags = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_free(BIO *a)
|
||||
{
|
||||
BIO_SSL *bs;
|
||||
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
bs = (BIO_SSL *)a->ptr;
|
||||
if (bs->ssl != NULL)
|
||||
SSL_shutdown(bs->ssl);
|
||||
if (a->shutdown) {
|
||||
if (a->init && (bs->ssl != NULL))
|
||||
SSL_free(bs->ssl);
|
||||
a->init = 0;
|
||||
a->flags = 0;
|
||||
}
|
||||
free(a->ptr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_read(BIO *b, char *out, int outl)
|
||||
{
|
||||
int ret = 1;
|
||||
BIO_SSL *sb;
|
||||
SSL *ssl;
|
||||
int retry_reason = 0;
|
||||
int r = 0;
|
||||
|
||||
if (out == NULL)
|
||||
return (0);
|
||||
sb = (BIO_SSL *)b->ptr;
|
||||
ssl = sb->ssl;
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
ret = SSL_read(ssl, out, outl);
|
||||
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_NONE:
|
||||
if (ret <= 0)
|
||||
break;
|
||||
if (sb->renegotiate_count > 0) {
|
||||
sb->byte_count += ret;
|
||||
if (sb->byte_count > sb->renegotiate_count) {
|
||||
sb->byte_count = 0;
|
||||
sb->num_renegotiates++;
|
||||
SSL_renegotiate(ssl);
|
||||
r = 1;
|
||||
}
|
||||
}
|
||||
if ((sb->renegotiate_timeout > 0) && (!r)) {
|
||||
time_t tm;
|
||||
|
||||
tm = time(NULL);
|
||||
if (tm > sb->last_time + sb->renegotiate_timeout) {
|
||||
sb->last_time = tm;
|
||||
sb->num_renegotiates++;
|
||||
SSL_renegotiate(ssl);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
BIO_set_retry_read(b);
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
BIO_set_retry_write(b);
|
||||
break;
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
BIO_set_retry_special(b);
|
||||
retry_reason = BIO_RR_SSL_X509_LOOKUP;
|
||||
break;
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
BIO_set_retry_special(b);
|
||||
retry_reason = BIO_RR_ACCEPT;
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
BIO_set_retry_special(b);
|
||||
retry_reason = BIO_RR_CONNECT;
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
b->retry_reason = retry_reason;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_write(BIO *b, const char *out, int outl)
|
||||
{
|
||||
int ret, r = 0;
|
||||
int retry_reason = 0;
|
||||
SSL *ssl;
|
||||
BIO_SSL *bs;
|
||||
|
||||
if (out == NULL)
|
||||
return (0);
|
||||
bs = (BIO_SSL *)b->ptr;
|
||||
ssl = bs->ssl;
|
||||
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
/* ret=SSL_do_handshake(ssl);
|
||||
if (ret > 0) */
|
||||
ret = SSL_write(ssl, out, outl);
|
||||
|
||||
switch (SSL_get_error(ssl, ret)) {
|
||||
case SSL_ERROR_NONE:
|
||||
if (ret <= 0)
|
||||
break;
|
||||
if (bs->renegotiate_count > 0) {
|
||||
bs->byte_count += ret;
|
||||
if (bs->byte_count > bs->renegotiate_count) {
|
||||
bs->byte_count = 0;
|
||||
bs->num_renegotiates++;
|
||||
SSL_renegotiate(ssl);
|
||||
r = 1;
|
||||
}
|
||||
}
|
||||
if ((bs->renegotiate_timeout > 0) && (!r)) {
|
||||
time_t tm;
|
||||
|
||||
tm = time(NULL);
|
||||
if (tm > bs->last_time + bs->renegotiate_timeout) {
|
||||
bs->last_time = tm;
|
||||
bs->num_renegotiates++;
|
||||
SSL_renegotiate(ssl);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
BIO_set_retry_write(b);
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
BIO_set_retry_read(b);
|
||||
break;
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
BIO_set_retry_special(b);
|
||||
retry_reason = BIO_RR_SSL_X509_LOOKUP;
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
BIO_set_retry_special(b);
|
||||
retry_reason = BIO_RR_CONNECT;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
case SSL_ERROR_SSL:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
b->retry_reason = retry_reason;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static long
|
||||
ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
{
|
||||
SSL **sslp, *ssl;
|
||||
BIO_SSL *bs;
|
||||
BIO *dbio, *bio;
|
||||
long ret = 1;
|
||||
|
||||
bs = (BIO_SSL *)b->ptr;
|
||||
ssl = bs->ssl;
|
||||
if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
|
||||
return (0);
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
SSL_shutdown(ssl);
|
||||
|
||||
if (ssl->internal->handshake_func ==
|
||||
ssl->method->internal->ssl_connect)
|
||||
SSL_set_connect_state(ssl);
|
||||
else if (ssl->internal->handshake_func ==
|
||||
ssl->method->internal->ssl_accept)
|
||||
SSL_set_accept_state(ssl);
|
||||
|
||||
SSL_clear(ssl);
|
||||
|
||||
if (b->next_bio != NULL)
|
||||
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
|
||||
else if (ssl->rbio != NULL)
|
||||
ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
|
||||
else
|
||||
ret = 1;
|
||||
break;
|
||||
case BIO_CTRL_INFO:
|
||||
ret = 0;
|
||||
break;
|
||||
case BIO_C_SSL_MODE:
|
||||
if (num) /* client mode */
|
||||
SSL_set_connect_state(ssl);
|
||||
else
|
||||
SSL_set_accept_state(ssl);
|
||||
break;
|
||||
case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
|
||||
ret = bs->renegotiate_timeout;
|
||||
if (num < 60)
|
||||
num = 5;
|
||||
bs->renegotiate_timeout = (unsigned long)num;
|
||||
bs->last_time = time(NULL);
|
||||
break;
|
||||
case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
|
||||
ret = bs->renegotiate_count;
|
||||
if ((long)num >=512)
|
||||
bs->renegotiate_count = (unsigned long)num;
|
||||
break;
|
||||
case BIO_C_GET_SSL_NUM_RENEGOTIATES:
|
||||
ret = bs->num_renegotiates;
|
||||
break;
|
||||
case BIO_C_SET_SSL:
|
||||
if (ssl != NULL) {
|
||||
ssl_free(b);
|
||||
if (!ssl_new(b))
|
||||
return 0;
|
||||
}
|
||||
b->shutdown = (int)num;
|
||||
ssl = (SSL *)ptr;
|
||||
((BIO_SSL *)b->ptr)->ssl = ssl;
|
||||
bio = SSL_get_rbio(ssl);
|
||||
if (bio != NULL) {
|
||||
if (b->next_bio != NULL)
|
||||
BIO_push(bio, b->next_bio);
|
||||
b->next_bio = bio;
|
||||
CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
|
||||
}
|
||||
b->init = 1;
|
||||
break;
|
||||
case BIO_C_GET_SSL:
|
||||
if (ptr != NULL) {
|
||||
sslp = (SSL **)ptr;
|
||||
*sslp = ssl;
|
||||
} else
|
||||
ret = 0;
|
||||
break;
|
||||
case BIO_CTRL_GET_CLOSE:
|
||||
ret = b->shutdown;
|
||||
break;
|
||||
case BIO_CTRL_SET_CLOSE:
|
||||
b->shutdown = (int)num;
|
||||
break;
|
||||
case BIO_CTRL_WPENDING:
|
||||
ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_CTRL_PENDING:
|
||||
ret = SSL_pending(ssl);
|
||||
if (ret == 0)
|
||||
ret = BIO_pending(ssl->rbio);
|
||||
break;
|
||||
case BIO_CTRL_FLUSH:
|
||||
BIO_clear_retry_flags(b);
|
||||
ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
|
||||
BIO_copy_next_retry(b);
|
||||
break;
|
||||
case BIO_CTRL_PUSH:
|
||||
if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) {
|
||||
SSL_set_bio(ssl, b->next_bio, b->next_bio);
|
||||
CRYPTO_add(&b->next_bio->references, 1,
|
||||
CRYPTO_LOCK_BIO);
|
||||
}
|
||||
break;
|
||||
case BIO_CTRL_POP:
|
||||
/* Only detach if we are the BIO explicitly being popped */
|
||||
if (b == ptr) {
|
||||
/* Shouldn't happen in practice because the
|
||||
* rbio and wbio are the same when pushed.
|
||||
*/
|
||||
if (ssl->rbio != ssl->wbio)
|
||||
BIO_free_all(ssl->wbio);
|
||||
if (b->next_bio != NULL)
|
||||
CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO);
|
||||
ssl->wbio = NULL;
|
||||
ssl->rbio = NULL;
|
||||
}
|
||||
break;
|
||||
case BIO_C_DO_STATE_MACHINE:
|
||||
BIO_clear_retry_flags(b);
|
||||
|
||||
b->retry_reason = 0;
|
||||
ret = (int)SSL_do_handshake(ssl);
|
||||
|
||||
switch (SSL_get_error(ssl, (int)ret)) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
BIO_set_flags(b,
|
||||
BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
BIO_set_flags(b,
|
||||
BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
|
||||
break;
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
BIO_set_flags(b,
|
||||
BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
|
||||
b->retry_reason = b->next_bio->retry_reason;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BIO_CTRL_DUP:
|
||||
dbio = (BIO *)ptr;
|
||||
if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
|
||||
SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
|
||||
((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl);
|
||||
((BIO_SSL *)dbio->ptr)->renegotiate_count =
|
||||
((BIO_SSL *)b->ptr)->renegotiate_count;
|
||||
((BIO_SSL *)dbio->ptr)->byte_count =
|
||||
((BIO_SSL *)b->ptr)->byte_count;
|
||||
((BIO_SSL *)dbio->ptr)->renegotiate_timeout =
|
||||
((BIO_SSL *)b->ptr)->renegotiate_timeout;
|
||||
((BIO_SSL *)dbio->ptr)->last_time =
|
||||
((BIO_SSL *)b->ptr)->last_time;
|
||||
ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL);
|
||||
break;
|
||||
case BIO_C_GET_FD:
|
||||
ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
|
||||
break;
|
||||
case BIO_CTRL_SET_CALLBACK:
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
case BIO_CTRL_GET_CALLBACK:
|
||||
{
|
||||
void (**fptr)(const SSL *xssl, int type, int val);
|
||||
|
||||
fptr = (void (**)(const SSL *xssl, int type, int val))
|
||||
ptr;
|
||||
*fptr = SSL_get_info_callback(ssl);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static long
|
||||
ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
|
||||
{
|
||||
SSL *ssl;
|
||||
BIO_SSL *bs;
|
||||
long ret = 1;
|
||||
|
||||
bs = (BIO_SSL *)b->ptr;
|
||||
ssl = bs->ssl;
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_SET_CALLBACK:
|
||||
{
|
||||
/* FIXME: setting this via a completely different prototype
|
||||
seems like a crap idea */
|
||||
SSL_set_info_callback(ssl,
|
||||
(void (*)(const SSL *, int, int))fp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_puts(BIO *bp, const char *str)
|
||||
{
|
||||
int n, ret;
|
||||
|
||||
n = strlen(str);
|
||||
ret = BIO_write(bp, str, n);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
BIO *
|
||||
BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
|
||||
{
|
||||
BIO *ret = NULL, *buf = NULL, *ssl = NULL;
|
||||
|
||||
if ((buf = BIO_new(BIO_f_buffer())) == NULL)
|
||||
goto err;
|
||||
if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)
|
||||
goto err;
|
||||
if ((ret = BIO_push(buf, ssl)) == NULL)
|
||||
goto err;
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
BIO_free(buf);
|
||||
BIO_free(ssl);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIO *
|
||||
BIO_new_ssl_connect(SSL_CTX *ctx)
|
||||
{
|
||||
BIO *ret = NULL, *con = NULL, *ssl = NULL;
|
||||
|
||||
if ((con = BIO_new(BIO_s_connect())) == NULL)
|
||||
goto err;
|
||||
if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)
|
||||
goto err;
|
||||
if ((ret = BIO_push(ssl, con)) == NULL)
|
||||
goto err;
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
BIO_free(con);
|
||||
BIO_free(ssl);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIO *
|
||||
BIO_new_ssl(SSL_CTX *ctx, int client)
|
||||
{
|
||||
BIO *ret;
|
||||
SSL *ssl;
|
||||
|
||||
if ((ret = BIO_new(BIO_f_ssl())) == NULL)
|
||||
goto err;
|
||||
if ((ssl = SSL_new(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (client)
|
||||
SSL_set_connect_state(ssl);
|
||||
else
|
||||
SSL_set_accept_state(ssl);
|
||||
|
||||
BIO_set_ssl(ret, ssl, BIO_CLOSE);
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
BIO_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
BIO_ssl_copy_session_id(BIO *t, BIO *f)
|
||||
{
|
||||
t = BIO_find_type(t, BIO_TYPE_SSL);
|
||||
f = BIO_find_type(f, BIO_TYPE_SSL);
|
||||
if ((t == NULL) || (f == NULL))
|
||||
return (0);
|
||||
if ((((BIO_SSL *)t->ptr)->ssl == NULL) ||
|
||||
(((BIO_SSL *)f->ptr)->ssl == NULL))
|
||||
return (0);
|
||||
if (!SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,
|
||||
((BIO_SSL *)f->ptr)->ssl))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
BIO_ssl_shutdown(BIO *b)
|
||||
{
|
||||
SSL *s;
|
||||
|
||||
while (b != NULL) {
|
||||
if (b->method->type == BIO_TYPE_SSL) {
|
||||
s = ((BIO_SSL *)b->ptr)->ssl;
|
||||
SSL_shutdown(s);
|
||||
break;
|
||||
}
|
||||
b = b->next_bio;
|
||||
}
|
||||
}
|
||||
270
externals/libressl/ssl/bs_ber.c
vendored
Executable file
270
externals/libressl/ssl/bs_ber.c
vendored
Executable file
@@ -0,0 +1,270 @@
|
||||
/* $OpenBSD: bs_ber.c,v 1.9 2016/12/03 12:34:35 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
/*
|
||||
* kMaxDepth is a just a sanity limit. The code should be such that the length
|
||||
* of the input being processes always decreases. None the less, a very large
|
||||
* input could otherwise cause the stack to overflow.
|
||||
*/
|
||||
static const unsigned int kMaxDepth = 2048;
|
||||
|
||||
/* Non-strict version that allows a relaxed DER with indefinite form. */
|
||||
static int
|
||||
cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
|
||||
size_t *out_header_len)
|
||||
{
|
||||
return cbs_get_any_asn1_element_internal(cbs, out,
|
||||
out_tag, out_header_len, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets
|
||||
* |*indefinite_found| depending on whether an indefinite length element was
|
||||
* found. The value of |orig_in| is not modified.
|
||||
*
|
||||
* Returns one on success (i.e. |*indefinite_found| was set) and zero on error.
|
||||
*/
|
||||
static int
|
||||
cbs_find_indefinite(const CBS *orig_in, char *indefinite_found,
|
||||
unsigned int depth)
|
||||
{
|
||||
CBS in;
|
||||
|
||||
if (depth > kMaxDepth)
|
||||
return 0;
|
||||
|
||||
CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
|
||||
|
||||
while (CBS_len(&in) > 0) {
|
||||
CBS contents;
|
||||
unsigned int tag;
|
||||
size_t header_len;
|
||||
|
||||
if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag,
|
||||
&header_len))
|
||||
return 0;
|
||||
|
||||
/* Indefinite form not allowed by DER. */
|
||||
if (CBS_len(&contents) == header_len && header_len > 0 &&
|
||||
CBS_data(&contents)[header_len - 1] == 0x80) {
|
||||
*indefinite_found = 1;
|
||||
return 1;
|
||||
}
|
||||
if (tag & CBS_ASN1_CONSTRUCTED) {
|
||||
if (!CBS_skip(&contents, header_len) ||
|
||||
!cbs_find_indefinite(&contents, indefinite_found,
|
||||
depth + 1))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*indefinite_found = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* is_primitive_type returns true if |tag| likely a primitive type. Normally
|
||||
* one can just test the "constructed" bit in the tag but, in BER, even
|
||||
* primitive tags can have the constructed bit if they have indefinite
|
||||
* length.
|
||||
*/
|
||||
static char
|
||||
is_primitive_type(unsigned int tag)
|
||||
{
|
||||
return (tag & 0xc0) == 0 &&
|
||||
(tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
|
||||
(tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
|
||||
}
|
||||
|
||||
/*
|
||||
* is_eoc returns true if |header_len| and |contents|, as returned by
|
||||
* |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC)
|
||||
* value.
|
||||
*/
|
||||
static char
|
||||
is_eoc(size_t header_len, CBS *contents)
|
||||
{
|
||||
const unsigned char eoc[] = {0x0, 0x0};
|
||||
|
||||
return header_len == 2 && CBS_mem_equal(contents, eoc, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* cbs_convert_indefinite reads data with DER encoding (but relaxed to allow
|
||||
* indefinite form) from |in| and writes definite form DER data to |out|. If
|
||||
* |squash_header| is set then the top-level of elements from |in| will not
|
||||
* have their headers written. This is used when concatenating the fragments of
|
||||
* an indefinite length, primitive value. If |looking_for_eoc| is set then any
|
||||
* EOC elements found will cause the function to return after consuming it.
|
||||
* It returns one on success and zero on error.
|
||||
*/
|
||||
static int
|
||||
cbs_convert_indefinite(CBS *in, CBB *out, char squash_header,
|
||||
char looking_for_eoc, unsigned int depth)
|
||||
{
|
||||
if (depth > kMaxDepth)
|
||||
return 0;
|
||||
|
||||
while (CBS_len(in) > 0) {
|
||||
CBS contents;
|
||||
unsigned int tag;
|
||||
size_t header_len;
|
||||
CBB *out_contents, out_contents_storage;
|
||||
|
||||
if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag,
|
||||
&header_len))
|
||||
return 0;
|
||||
|
||||
out_contents = out;
|
||||
|
||||
if (CBS_len(&contents) == header_len) {
|
||||
if (is_eoc(header_len, &contents))
|
||||
return looking_for_eoc;
|
||||
|
||||
if (header_len > 0 &&
|
||||
CBS_data(&contents)[header_len - 1] == 0x80) {
|
||||
/*
|
||||
* This is an indefinite length element. If
|
||||
* it's a SEQUENCE or SET then we just need to
|
||||
* write the out the contents as normal, but
|
||||
* with a concrete length prefix.
|
||||
*
|
||||
* If it's a something else then the contents
|
||||
* will be a series of DER elements of the same
|
||||
* type which need to be concatenated.
|
||||
*/
|
||||
const char context_specific = (tag & 0xc0)
|
||||
== 0x80;
|
||||
char squash_child_headers =
|
||||
is_primitive_type(tag);
|
||||
|
||||
/*
|
||||
* This is a hack, but it sufficies to handle
|
||||
* NSS's output. If we find an indefinite
|
||||
* length, context-specific tag with a definite,
|
||||
* primtive tag inside it, then we assume that
|
||||
* the context-specific tag is implicit and the
|
||||
* tags within are fragments of a primitive type
|
||||
* that need to be concatenated.
|
||||
*/
|
||||
if (context_specific &&
|
||||
(tag & CBS_ASN1_CONSTRUCTED)) {
|
||||
CBS in_copy, inner_contents;
|
||||
unsigned int inner_tag;
|
||||
size_t inner_header_len;
|
||||
|
||||
CBS_init(&in_copy, CBS_data(in),
|
||||
CBS_len(in));
|
||||
if (!cbs_nonstrict_get_any_asn1_element(
|
||||
&in_copy, &inner_contents,
|
||||
&inner_tag, &inner_header_len))
|
||||
return 0;
|
||||
|
||||
if (CBS_len(&inner_contents) >
|
||||
inner_header_len &&
|
||||
is_primitive_type(inner_tag))
|
||||
squash_child_headers = 1;
|
||||
}
|
||||
|
||||
if (!squash_header) {
|
||||
unsigned int out_tag = tag;
|
||||
|
||||
if (squash_child_headers)
|
||||
out_tag &=
|
||||
~CBS_ASN1_CONSTRUCTED;
|
||||
|
||||
if (!CBB_add_asn1(out,
|
||||
&out_contents_storage, out_tag))
|
||||
return 0;
|
||||
|
||||
out_contents = &out_contents_storage;
|
||||
}
|
||||
|
||||
if (!cbs_convert_indefinite(in, out_contents,
|
||||
squash_child_headers,
|
||||
1 /* looking for eoc */, depth + 1))
|
||||
return 0;
|
||||
|
||||
if (out_contents != out && !CBB_flush(out))
|
||||
return 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!squash_header) {
|
||||
if (!CBB_add_asn1(out, &out_contents_storage, tag))
|
||||
return 0;
|
||||
|
||||
out_contents = &out_contents_storage;
|
||||
}
|
||||
|
||||
if (!CBS_skip(&contents, header_len))
|
||||
return 0;
|
||||
|
||||
if (tag & CBS_ASN1_CONSTRUCTED) {
|
||||
if (!cbs_convert_indefinite(&contents, out_contents,
|
||||
0 /* don't squash header */,
|
||||
0 /* not looking for eoc */, depth + 1))
|
||||
return 0;
|
||||
} else {
|
||||
if (!CBB_add_bytes(out_contents, CBS_data(&contents),
|
||||
CBS_len(&contents)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (out_contents != out && !CBB_flush(out))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return looking_for_eoc == 0;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len)
|
||||
{
|
||||
CBB cbb;
|
||||
|
||||
/*
|
||||
* First, do a quick walk to find any indefinite-length elements. Most
|
||||
* of the time we hope that there aren't any and thus we can quickly
|
||||
* return.
|
||||
*/
|
||||
char conversion_needed;
|
||||
if (!cbs_find_indefinite(in, &conversion_needed, 0))
|
||||
return 0;
|
||||
|
||||
if (!conversion_needed) {
|
||||
*out = NULL;
|
||||
*out_len = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!CBB_init(&cbb, CBS_len(in)))
|
||||
return 0;
|
||||
if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBB_finish(&cbb, out, out_len);
|
||||
}
|
||||
468
externals/libressl/ssl/bs_cbb.c
vendored
Executable file
468
externals/libressl/ssl/bs_cbb.c
vendored
Executable file
@@ -0,0 +1,468 @@
|
||||
/* $OpenBSD: bs_cbb.c,v 1.23 2020/09/16 05:52:04 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
#define CBB_INITIAL_SIZE 64
|
||||
|
||||
static int
|
||||
cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
|
||||
{
|
||||
struct cbb_buffer_st *base;
|
||||
|
||||
if ((base = calloc(1, sizeof(struct cbb_buffer_st))) == NULL)
|
||||
return 0;
|
||||
|
||||
base->buf = buf;
|
||||
base->len = 0;
|
||||
base->cap = cap;
|
||||
base->can_resize = 1;
|
||||
|
||||
cbb->base = base;
|
||||
cbb->is_top_level = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_init(CBB *cbb, size_t initial_capacity)
|
||||
{
|
||||
uint8_t *buf = NULL;
|
||||
|
||||
memset(cbb, 0, sizeof(*cbb));
|
||||
|
||||
if (initial_capacity == 0)
|
||||
initial_capacity = CBB_INITIAL_SIZE;
|
||||
|
||||
if ((buf = calloc(1, initial_capacity)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!cbb_init(cbb, buf, initial_capacity)) {
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
|
||||
{
|
||||
memset(cbb, 0, sizeof(*cbb));
|
||||
|
||||
if (!cbb_init(cbb, buf, len))
|
||||
return 0;
|
||||
|
||||
cbb->base->can_resize = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
CBB_cleanup(CBB *cbb)
|
||||
{
|
||||
if (cbb->base) {
|
||||
if (cbb->base->can_resize)
|
||||
freezero(cbb->base->buf, cbb->base->cap);
|
||||
free(cbb->base);
|
||||
}
|
||||
cbb->base = NULL;
|
||||
cbb->child = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
|
||||
{
|
||||
size_t newlen;
|
||||
|
||||
if (base == NULL)
|
||||
return 0;
|
||||
|
||||
newlen = base->len + len;
|
||||
if (newlen < base->len)
|
||||
/* Overflow */
|
||||
return 0;
|
||||
|
||||
if (newlen > base->cap) {
|
||||
size_t newcap = base->cap * 2;
|
||||
uint8_t *newbuf;
|
||||
|
||||
if (!base->can_resize)
|
||||
return 0;
|
||||
|
||||
if (newcap < base->cap || newcap < newlen)
|
||||
newcap = newlen;
|
||||
|
||||
newbuf = recallocarray(base->buf, base->cap, newcap, 1);
|
||||
if (newbuf == NULL)
|
||||
return 0;
|
||||
|
||||
base->buf = newbuf;
|
||||
base->cap = newcap;
|
||||
}
|
||||
|
||||
if (out)
|
||||
*out = base->buf + base->len;
|
||||
|
||||
base->len = newlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
cbb_add_u(CBB *cbb, uint32_t v, size_t len_len)
|
||||
{
|
||||
uint8_t *buf;
|
||||
size_t i;
|
||||
|
||||
if (len_len == 0)
|
||||
return 1;
|
||||
|
||||
if (len_len > 4)
|
||||
return 0;
|
||||
|
||||
if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len))
|
||||
return 0;
|
||||
|
||||
for (i = len_len - 1; i < len_len; i--) {
|
||||
buf[i] = v;
|
||||
v >>= 8;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
|
||||
{
|
||||
if (!cbb->is_top_level)
|
||||
return 0;
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
|
||||
/*
|
||||
* |out_data| and |out_len| can only be NULL if the CBB is
|
||||
* fixed.
|
||||
*/
|
||||
return 0;
|
||||
|
||||
if (out_data != NULL)
|
||||
*out_data = cbb->base->buf;
|
||||
|
||||
if (out_len != NULL)
|
||||
*out_len = cbb->base->len;
|
||||
|
||||
cbb->base->buf = NULL;
|
||||
CBB_cleanup(cbb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* CBB_flush recurses and then writes out any pending length prefix. The current
|
||||
* length of the underlying base is taken to be the length of the
|
||||
* length-prefixed data.
|
||||
*/
|
||||
int
|
||||
CBB_flush(CBB *cbb)
|
||||
{
|
||||
size_t child_start, i, len;
|
||||
|
||||
if (cbb->base == NULL)
|
||||
return 0;
|
||||
|
||||
if (cbb->child == NULL || cbb->pending_len_len == 0)
|
||||
return 1;
|
||||
|
||||
child_start = cbb->offset + cbb->pending_len_len;
|
||||
|
||||
if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
|
||||
cbb->base->len < child_start)
|
||||
return 0;
|
||||
|
||||
len = cbb->base->len - child_start;
|
||||
|
||||
if (cbb->pending_is_asn1) {
|
||||
/*
|
||||
* For ASN.1, we assumed that we were using short form which
|
||||
* only requires a single byte for the length octet.
|
||||
*
|
||||
* If it turns out that we need long form, we have to move
|
||||
* the contents along in order to make space for more length
|
||||
* octets.
|
||||
*/
|
||||
size_t len_len = 1; /* total number of length octets */
|
||||
uint8_t initial_length_byte;
|
||||
|
||||
/* We already wrote 1 byte for the length. */
|
||||
if (cbb->pending_len_len != 1)
|
||||
return 0;
|
||||
|
||||
/* Check for long form */
|
||||
if (len > 0xfffffffe)
|
||||
return 0; /* 0xffffffff is reserved */
|
||||
else if (len > 0xffffff)
|
||||
len_len = 5;
|
||||
else if (len > 0xffff)
|
||||
len_len = 4;
|
||||
else if (len > 0xff)
|
||||
len_len = 3;
|
||||
else if (len > 0x7f)
|
||||
len_len = 2;
|
||||
|
||||
if (len_len == 1) {
|
||||
/* For short form, the initial byte is the length. */
|
||||
initial_length_byte = len;
|
||||
len = 0;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* For long form, the initial byte is the number of
|
||||
* subsequent length octets (plus bit 8 set).
|
||||
*/
|
||||
initial_length_byte = 0x80 | (len_len - 1);
|
||||
|
||||
/*
|
||||
* We need to move the contents along in order to make
|
||||
* space for the long form length octets.
|
||||
*/
|
||||
size_t extra_bytes = len_len - 1;
|
||||
if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
|
||||
return 0;
|
||||
|
||||
memmove(cbb->base->buf + child_start + extra_bytes,
|
||||
cbb->base->buf + child_start, len);
|
||||
}
|
||||
cbb->base->buf[cbb->offset++] = initial_length_byte;
|
||||
cbb->pending_len_len = len_len - 1;
|
||||
}
|
||||
|
||||
for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
|
||||
cbb->base->buf[cbb->offset + i] = len;
|
||||
len >>= 8;
|
||||
}
|
||||
if (len != 0)
|
||||
return 0;
|
||||
|
||||
cbb->child->base = NULL;
|
||||
cbb->child = NULL;
|
||||
cbb->pending_len_len = 0;
|
||||
cbb->pending_is_asn1 = 0;
|
||||
cbb->offset = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
CBB_discard_child(CBB *cbb)
|
||||
{
|
||||
if (cbb->child == NULL)
|
||||
return;
|
||||
|
||||
cbb->base->len = cbb->offset;
|
||||
|
||||
cbb->child->base = NULL;
|
||||
cbb->child = NULL;
|
||||
cbb->pending_len_len = 0;
|
||||
cbb->pending_is_asn1 = 0;
|
||||
cbb->offset = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
|
||||
{
|
||||
uint8_t *prefix_bytes;
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
cbb->offset = cbb->base->len;
|
||||
if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
|
||||
return 0;
|
||||
|
||||
memset(prefix_bytes, 0, len_len);
|
||||
memset(out_contents, 0, sizeof(CBB));
|
||||
out_contents->base = cbb->base;
|
||||
cbb->child = out_contents;
|
||||
cbb->pending_len_len = len_len;
|
||||
cbb->pending_is_asn1 = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
|
||||
{
|
||||
return cbb_add_length_prefixed(cbb, out_contents, 1);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
|
||||
{
|
||||
return cbb_add_length_prefixed(cbb, out_contents, 2);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
|
||||
{
|
||||
return cbb_add_length_prefixed(cbb, out_contents, 3);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag)
|
||||
{
|
||||
if (tag > UINT8_MAX)
|
||||
return 0;
|
||||
|
||||
/* Long form identifier octets are not supported. */
|
||||
if ((tag & 0x1f) == 0x1f)
|
||||
return 0;
|
||||
|
||||
/* Short-form identifier octet only needs a single byte */
|
||||
if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Add 1 byte to cover the short-form length octet case. If it turns
|
||||
* out we need long-form, it will be extended later.
|
||||
*/
|
||||
cbb->offset = cbb->base->len;
|
||||
if (!CBB_add_u8(cbb, 0))
|
||||
return 0;
|
||||
|
||||
memset(out_contents, 0, sizeof(CBB));
|
||||
out_contents->base = cbb->base;
|
||||
cbb->child = out_contents;
|
||||
cbb->pending_len_len = 1;
|
||||
cbb->pending_is_asn1 = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t *dest;
|
||||
|
||||
if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len))
|
||||
return 0;
|
||||
|
||||
memcpy(dest, data, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
|
||||
{
|
||||
if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
|
||||
return 0;
|
||||
|
||||
memset(*out_data, 0, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u8(CBB *cbb, size_t value)
|
||||
{
|
||||
if (value > UINT8_MAX)
|
||||
return 0;
|
||||
|
||||
return cbb_add_u(cbb, (uint32_t)value, 1);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u16(CBB *cbb, size_t value)
|
||||
{
|
||||
if (value > UINT16_MAX)
|
||||
return 0;
|
||||
|
||||
return cbb_add_u(cbb, (uint32_t)value, 2);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u24(CBB *cbb, size_t value)
|
||||
{
|
||||
if (value > 0xffffffUL)
|
||||
return 0;
|
||||
|
||||
return cbb_add_u(cbb, (uint32_t)value, 3);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_u32(CBB *cbb, size_t value)
|
||||
{
|
||||
if (value > 0xffffffffUL)
|
||||
return 0;
|
||||
|
||||
return cbb_add_u(cbb, (uint32_t)value, 4);
|
||||
}
|
||||
|
||||
int
|
||||
CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
|
||||
{
|
||||
CBB child;
|
||||
size_t i;
|
||||
int started = 0;
|
||||
|
||||
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint8_t byte = (value >> 8 * (7 - i)) & 0xff;
|
||||
|
||||
/*
|
||||
* ASN.1 restriction: first 9 bits cannot be all zeroes or
|
||||
* all ones. Since this function only encodes unsigned
|
||||
* integers, the only concerns are not encoding leading
|
||||
* zeros and adding a padding byte if necessary.
|
||||
*
|
||||
* In practice, this means:
|
||||
* 1) Skip leading octets of all zero bits in the value
|
||||
* 2) After skipping the leading zero octets, if the next 9
|
||||
* bits are all ones, add an all zero prefix octet (and
|
||||
* set the high bit of the prefix octet if negative).
|
||||
*
|
||||
* Additionally, for an unsigned value, add an all zero
|
||||
* prefix if the high bit of the first octet would be one.
|
||||
*/
|
||||
if (!started) {
|
||||
if (byte == 0)
|
||||
/* Don't encode leading zeros. */
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the high bit is set, add a padding byte to make it
|
||||
* unsigned.
|
||||
*/
|
||||
if ((byte & 0x80) && !CBB_add_u8(&child, 0))
|
||||
return 0;
|
||||
|
||||
started = 1;
|
||||
}
|
||||
if (!CBB_add_u8(&child, byte))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0 is encoded as a single 0, not the empty string. */
|
||||
if (!started && !CBB_add_u8(&child, 0))
|
||||
return 0;
|
||||
|
||||
return CBB_flush(cbb);
|
||||
}
|
||||
508
externals/libressl/ssl/bs_cbs.c
vendored
Executable file
508
externals/libressl/ssl/bs_cbs.c
vendored
Executable file
@@ -0,0 +1,508 @@
|
||||
/* $OpenBSD: bs_cbs.c,v 1.18 2019/01/23 22:20:40 beck Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
void
|
||||
CBS_init(CBS *cbs, const uint8_t *data, size_t len)
|
||||
{
|
||||
cbs->data = data;
|
||||
cbs->initial_len = len;
|
||||
cbs->len = len;
|
||||
}
|
||||
|
||||
void
|
||||
CBS_dup(const CBS *cbs, CBS *out)
|
||||
{
|
||||
CBS_init(out, CBS_data(cbs), CBS_len(cbs));
|
||||
out->initial_len = cbs->initial_len;
|
||||
}
|
||||
|
||||
static int
|
||||
cbs_get(CBS *cbs, const uint8_t **p, size_t n)
|
||||
{
|
||||
if (cbs->len < n)
|
||||
return 0;
|
||||
|
||||
*p = cbs->data;
|
||||
cbs->data += n;
|
||||
cbs->len -= n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
CBS_offset(const CBS *cbs)
|
||||
{
|
||||
return cbs->initial_len - cbs->len;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_skip(CBS *cbs, size_t len)
|
||||
{
|
||||
const uint8_t *dummy;
|
||||
return cbs_get(cbs, &dummy, len);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
CBS_data(const CBS *cbs)
|
||||
{
|
||||
return cbs->data;
|
||||
}
|
||||
|
||||
size_t
|
||||
CBS_len(const CBS *cbs)
|
||||
{
|
||||
return cbs->len;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
|
||||
{
|
||||
free(*out_ptr);
|
||||
*out_ptr = NULL;
|
||||
*out_len = 0;
|
||||
|
||||
if (cbs->len == 0)
|
||||
return 1;
|
||||
|
||||
if ((*out_ptr = malloc(cbs->len)) == NULL)
|
||||
return 0;
|
||||
|
||||
memcpy(*out_ptr, cbs->data, cbs->len);
|
||||
|
||||
*out_len = cbs->len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_strdup(const CBS *cbs, char **out_ptr)
|
||||
{
|
||||
free(*out_ptr);
|
||||
*out_ptr = strndup((const char *)cbs->data, cbs->len);
|
||||
return (*out_ptr != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied)
|
||||
{
|
||||
if (dst_len < cbs->len)
|
||||
return 0;
|
||||
|
||||
memmove(dst, cbs->data, cbs->len);
|
||||
|
||||
if (copied != NULL)
|
||||
*copied = cbs->len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_contains_zero_byte(const CBS *cbs)
|
||||
{
|
||||
return memchr(cbs->data, 0, cbs->len) != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
|
||||
{
|
||||
if (len != cbs->len)
|
||||
return 0;
|
||||
|
||||
return timingsafe_memcmp(cbs->data, data, len) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
size_t i;
|
||||
const uint8_t *data;
|
||||
|
||||
if (len < 1 || len > 4)
|
||||
return 0;
|
||||
|
||||
if (!cbs_get(cbs, &data, len))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
result <<= 8;
|
||||
result |= data[i];
|
||||
}
|
||||
*out = result;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u8(CBS *cbs, uint8_t *out)
|
||||
{
|
||||
const uint8_t *v;
|
||||
|
||||
if (!cbs_get(cbs, &v, 1))
|
||||
return 0;
|
||||
|
||||
*out = *v;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u16(CBS *cbs, uint16_t *out)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
if (!cbs_get_u(cbs, &v, 2))
|
||||
return 0;
|
||||
|
||||
*out = v;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u24(CBS *cbs, uint32_t *out)
|
||||
{
|
||||
return cbs_get_u(cbs, out, 3);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u32(CBS *cbs, uint32_t *out)
|
||||
{
|
||||
return cbs_get_u(cbs, out, 4);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
|
||||
{
|
||||
const uint8_t *v;
|
||||
|
||||
if (!cbs_get(cbs, &v, len))
|
||||
return 0;
|
||||
|
||||
CBS_init(out, v, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
|
||||
{
|
||||
uint32_t len;
|
||||
|
||||
if (!cbs_get_u(cbs, &len, len_len))
|
||||
return 0;
|
||||
|
||||
return CBS_get_bytes(cbs, out, len);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
|
||||
{
|
||||
return cbs_get_length_prefixed(cbs, out, 1);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
|
||||
{
|
||||
return cbs_get_length_prefixed(cbs, out, 2);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
|
||||
{
|
||||
return cbs_get_length_prefixed(cbs, out, 3);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
|
||||
size_t *out_header_len)
|
||||
{
|
||||
return cbs_get_any_asn1_element_internal(cbs, out, out_tag,
|
||||
out_header_len, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Review X.690 for details on ASN.1 DER encoding.
|
||||
*
|
||||
* If non-strict mode is enabled, then DER rules are relaxed
|
||||
* for indefinite constructs (violates DER but a little closer to BER).
|
||||
* Non-strict mode should only be used by bs_ber.c
|
||||
*
|
||||
* Sections 8, 10 and 11 for DER encoding
|
||||
*/
|
||||
int
|
||||
cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag,
|
||||
size_t *out_header_len, int strict)
|
||||
{
|
||||
uint8_t tag, length_byte;
|
||||
CBS header = *cbs;
|
||||
CBS throwaway;
|
||||
size_t len;
|
||||
|
||||
if (out == NULL)
|
||||
out = &throwaway;
|
||||
|
||||
/*
|
||||
* Get identifier octet and length octet. Only 1 octet for each
|
||||
* is a CBS limitation.
|
||||
*/
|
||||
if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
|
||||
return 0;
|
||||
|
||||
/* CBS limitation: long form tags are not supported. */
|
||||
if ((tag & 0x1f) == 0x1f)
|
||||
return 0;
|
||||
|
||||
if (out_tag != NULL)
|
||||
*out_tag = tag;
|
||||
|
||||
if ((length_byte & 0x80) == 0) {
|
||||
/* Short form length. */
|
||||
len = ((size_t) length_byte) + 2;
|
||||
if (out_header_len != NULL)
|
||||
*out_header_len = 2;
|
||||
|
||||
} else {
|
||||
/* Long form length. */
|
||||
const size_t num_bytes = length_byte & 0x7f;
|
||||
uint32_t len32;
|
||||
|
||||
/* ASN.1 reserved value for future extensions */
|
||||
if (num_bytes == 0x7f)
|
||||
return 0;
|
||||
|
||||
/* Handle indefinite form length */
|
||||
if (num_bytes == 0) {
|
||||
/* DER encoding doesn't allow for indefinite form. */
|
||||
if (strict)
|
||||
return 0;
|
||||
|
||||
/* Primitive cannot use indefinite in BER or DER. */
|
||||
if ((tag & CBS_ASN1_CONSTRUCTED) == 0)
|
||||
return 0;
|
||||
|
||||
/* Constructed, indefinite length allowed in BER. */
|
||||
if (out_header_len != NULL)
|
||||
*out_header_len = 2;
|
||||
return CBS_get_bytes(cbs, out, 2);
|
||||
}
|
||||
|
||||
/* CBS limitation. */
|
||||
if (num_bytes > 4)
|
||||
return 0;
|
||||
|
||||
if (!cbs_get_u(&header, &len32, num_bytes))
|
||||
return 0;
|
||||
|
||||
/* DER has a minimum length octet requirement. */
|
||||
if (len32 < 128)
|
||||
/* Should have used short form instead */
|
||||
return 0;
|
||||
|
||||
if ((len32 >> ((num_bytes - 1) * 8)) == 0)
|
||||
/* Length should have been at least one byte shorter. */
|
||||
return 0;
|
||||
|
||||
len = len32;
|
||||
if (len + 2 + num_bytes < len)
|
||||
/* Overflow. */
|
||||
return 0;
|
||||
|
||||
len += 2 + num_bytes;
|
||||
if (out_header_len != NULL)
|
||||
*out_header_len = 2 + num_bytes;
|
||||
}
|
||||
|
||||
return CBS_get_bytes(cbs, out, len);
|
||||
}
|
||||
|
||||
static int
|
||||
cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header)
|
||||
{
|
||||
size_t header_len;
|
||||
unsigned int tag;
|
||||
CBS throwaway;
|
||||
|
||||
if (out == NULL)
|
||||
out = &throwaway;
|
||||
|
||||
if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
|
||||
tag != tag_value)
|
||||
return 0;
|
||||
|
||||
if (skip_header && !CBS_skip(out, header_len))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value)
|
||||
{
|
||||
return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value)
|
||||
{
|
||||
return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value)
|
||||
{
|
||||
if (CBS_len(cbs) < 1)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Tag number 31 indicates the start of a long form number.
|
||||
* This is valid in ASN.1, but CBS only supports short form.
|
||||
*/
|
||||
if ((tag_value & 0x1f) == 0x1f)
|
||||
return 0;
|
||||
|
||||
return CBS_data(cbs)[0] == tag_value;
|
||||
}
|
||||
|
||||
/* Encoding details are in ASN.1: X.690 section 8.3 */
|
||||
int
|
||||
CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
|
||||
{
|
||||
CBS bytes;
|
||||
const uint8_t *data;
|
||||
size_t i, len;
|
||||
|
||||
if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
|
||||
return 0;
|
||||
|
||||
*out = 0;
|
||||
data = CBS_data(&bytes);
|
||||
len = CBS_len(&bytes);
|
||||
|
||||
if (len == 0)
|
||||
/* An INTEGER is encoded with at least one content octet. */
|
||||
return 0;
|
||||
|
||||
if ((data[0] & 0x80) != 0)
|
||||
/* Negative number. */
|
||||
return 0;
|
||||
|
||||
if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0)
|
||||
/* Violates smallest encoding rule: excessive leading zeros. */
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((*out >> 56) != 0)
|
||||
/* Too large to represent as a uint64_t. */
|
||||
return 0;
|
||||
|
||||
*out <<= 8;
|
||||
*out |= data[i];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag)
|
||||
{
|
||||
if (CBS_peek_asn1_tag(cbs, tag)) {
|
||||
if (!CBS_get_asn1(cbs, out, tag))
|
||||
return 0;
|
||||
|
||||
*out_present = 1;
|
||||
} else {
|
||||
*out_present = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
|
||||
unsigned int tag)
|
||||
{
|
||||
CBS child;
|
||||
int present;
|
||||
|
||||
if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
|
||||
return 0;
|
||||
|
||||
if (present) {
|
||||
if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
|
||||
CBS_len(&child) != 0)
|
||||
return 0;
|
||||
} else {
|
||||
CBS_init(out, NULL, 0);
|
||||
}
|
||||
if (out_present)
|
||||
*out_present = present;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
|
||||
uint64_t default_value)
|
||||
{
|
||||
CBS child;
|
||||
int present;
|
||||
|
||||
if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
|
||||
return 0;
|
||||
|
||||
if (present) {
|
||||
if (!CBS_get_asn1_uint64(&child, out) ||
|
||||
CBS_len(&child) != 0)
|
||||
return 0;
|
||||
} else {
|
||||
*out = default_value;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
|
||||
int default_value)
|
||||
{
|
||||
CBS child, child2;
|
||||
int present;
|
||||
|
||||
if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
|
||||
return 0;
|
||||
|
||||
if (present) {
|
||||
uint8_t boolean;
|
||||
|
||||
if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
|
||||
CBS_len(&child2) != 1 || CBS_len(&child) != 0)
|
||||
return 0;
|
||||
|
||||
boolean = CBS_data(&child2)[0];
|
||||
if (boolean == 0)
|
||||
*out = 0;
|
||||
else if (boolean == 0xff)
|
||||
*out = 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
*out = default_value;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
519
externals/libressl/ssl/bytestring.h
vendored
Executable file
519
externals/libressl/ssl/bytestring.h
vendored
Executable file
@@ -0,0 +1,519 @@
|
||||
/* $OpenBSD: bytestring.h,v 1.17 2018/08/16 18:39:37 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_BYTESTRING_H
|
||||
#define OPENSSL_HEADER_BYTESTRING_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
/*
|
||||
* Bytestrings are used for parsing and building TLS and ASN.1 messages.
|
||||
*
|
||||
* A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and
|
||||
* provides utility functions for safely parsing length-prefixed structures
|
||||
* like TLS and ASN.1 from it.
|
||||
*
|
||||
* A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and
|
||||
* provides utility functions for building length-prefixed messages.
|
||||
*/
|
||||
|
||||
/* CRYPTO ByteString */
|
||||
typedef struct cbs_st {
|
||||
const uint8_t *data;
|
||||
size_t initial_len;
|
||||
size_t len;
|
||||
} CBS;
|
||||
|
||||
/*
|
||||
* CBS_init sets |cbs| to point to |data|. It does not take ownership of
|
||||
* |data|.
|
||||
*/
|
||||
void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
|
||||
|
||||
/*
|
||||
* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
|
||||
* otherwise.
|
||||
*/
|
||||
int CBS_skip(CBS *cbs, size_t len);
|
||||
|
||||
/*
|
||||
* CBS_data returns a pointer to the contents of |cbs|.
|
||||
*/
|
||||
const uint8_t *CBS_data(const CBS *cbs);
|
||||
|
||||
/*
|
||||
* CBS_len returns the number of bytes remaining in |cbs|.
|
||||
*/
|
||||
size_t CBS_len(const CBS *cbs);
|
||||
|
||||
/*
|
||||
* CBS_offset returns the current offset into the original data of |cbs|.
|
||||
*/
|
||||
size_t CBS_offset(const CBS *cbs);
|
||||
|
||||
/*
|
||||
* CBS_stow copies the current contents of |cbs| into |*out_ptr| and
|
||||
* |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
|
||||
* free. It returns one on success and zero on allocation failure. On
|
||||
* success, |*out_ptr| should be freed with free. If |cbs| is empty,
|
||||
* |*out_ptr| will be NULL.
|
||||
*/
|
||||
int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
|
||||
|
||||
/*
|
||||
* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
|
||||
* NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
|
||||
* with free. It returns one on success and zero on allocation
|
||||
* failure. On success, |*out_ptr| should be freed with free.
|
||||
*
|
||||
* NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
|
||||
* |CBS_contains_zero_byte(cbs)| to check for NUL bytes.
|
||||
*/
|
||||
int CBS_strdup(const CBS *cbs, char **out_ptr);
|
||||
|
||||
/*
|
||||
* CBS_write_bytes writes all of the remaining data from |cbs| into |dst|
|
||||
* if it is at most |dst_len| bytes. If |copied| is not NULL, it will be set
|
||||
* to the amount copied. It returns one on success and zero otherwise.
|
||||
*/
|
||||
int CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len,
|
||||
size_t *copied);
|
||||
|
||||
/*
|
||||
* CBS_contains_zero_byte returns one if the current contents of |cbs| contains
|
||||
* a NUL byte and zero otherwise.
|
||||
*/
|
||||
int CBS_contains_zero_byte(const CBS *cbs);
|
||||
|
||||
/*
|
||||
* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
|
||||
* starting at |data|. If they're equal, it returns one, otherwise zero. If the
|
||||
* lengths match, it uses a constant-time comparison.
|
||||
*/
|
||||
int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len);
|
||||
|
||||
/*
|
||||
* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
|
||||
* returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u8(CBS *cbs, uint8_t *out);
|
||||
|
||||
/*
|
||||
* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
|
||||
* advances |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u16(CBS *cbs, uint16_t *out);
|
||||
|
||||
/*
|
||||
* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
|
||||
* advances |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u24(CBS *cbs, uint32_t *out);
|
||||
|
||||
/*
|
||||
* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
|
||||
* and advances |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u32(CBS *cbs, uint32_t *out);
|
||||
|
||||
/*
|
||||
* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
|
||||
* |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
|
||||
|
||||
/*
|
||||
* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
|
||||
* length-prefixed value from |cbs| and advances |cbs| over it. It returns one
|
||||
* on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
|
||||
|
||||
/*
|
||||
* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
|
||||
* big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
|
||||
* returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
|
||||
|
||||
/*
|
||||
* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
|
||||
* big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
|
||||
* returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
|
||||
|
||||
|
||||
/* Parsing ASN.1 */
|
||||
|
||||
/*
|
||||
* While an identifier can be multiple octets, this library only handles the
|
||||
* single octet variety currently. This limits support up to tag number 30
|
||||
* since tag number 31 is a reserved value to indicate multiple octets.
|
||||
*/
|
||||
|
||||
/* Bits 8 and 7: class tag type: See X.690 section 8.1.2.2. */
|
||||
#define CBS_ASN1_UNIVERSAL 0x00
|
||||
#define CBS_ASN1_APPLICATION 0x40
|
||||
#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
|
||||
#define CBS_ASN1_PRIVATE 0xc0
|
||||
|
||||
/* Bit 6: Primitive or constructed: See X.690 section 8.1.2.3. */
|
||||
#define CBS_ASN1_PRIMITIVE 0x00
|
||||
#define CBS_ASN1_CONSTRUCTED 0x20
|
||||
|
||||
/*
|
||||
* Bits 5 to 1 are the tag number. See X.680 section 8.6 for tag numbers of
|
||||
* the universal class.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common universal identifier octets.
|
||||
* See X.690 section 8.1 and X.680 section 8.6 for universal tag numbers.
|
||||
*
|
||||
* Note: These definitions are the cause of some of the strange behavior in
|
||||
* CBS's bs_ber.c.
|
||||
*
|
||||
* In BER, it is the sender's option to use primitive or constructed for
|
||||
* bitstring (X.690 section 8.6.1) and octetstring (X.690 section 8.7.1).
|
||||
*
|
||||
* In DER, bitstring and octetstring are required to be primitive
|
||||
* (X.690 section 10.2).
|
||||
*/
|
||||
#define CBS_ASN1_BOOLEAN (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x1)
|
||||
#define CBS_ASN1_INTEGER (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x2)
|
||||
#define CBS_ASN1_BITSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x3)
|
||||
#define CBS_ASN1_OCTETSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x4)
|
||||
#define CBS_ASN1_OBJECT (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x6)
|
||||
#define CBS_ASN1_ENUMERATED (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0xa)
|
||||
#define CBS_ASN1_SEQUENCE (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x10)
|
||||
#define CBS_ASN1_SET (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x11)
|
||||
|
||||
/*
|
||||
* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
|
||||
* including tag and length bytes) and advances |cbs| over it. The ASN.1
|
||||
* element must match |tag_value|. It returns one on success and zero
|
||||
* on error.
|
||||
*
|
||||
* Tag numbers greater than 30 are not supported (i.e. short form only).
|
||||
*/
|
||||
int CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value);
|
||||
|
||||
/*
|
||||
* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
|
||||
* ASN.1 header bytes too.
|
||||
*/
|
||||
int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value);
|
||||
|
||||
/*
|
||||
* CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
|
||||
* if the next ASN.1 element on |cbs| would have tag |tag_value|. If
|
||||
* |cbs| is empty or the tag does not match, it returns zero. Note: if
|
||||
* it returns one, CBS_get_asn1 may still fail if the rest of the
|
||||
* element is malformed.
|
||||
*/
|
||||
int CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value);
|
||||
|
||||
/*
|
||||
* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
|
||||
* |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
|
||||
* the tag number and |*out_header_len| to the length of the ASN.1 header.
|
||||
* Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
|
||||
* the value.
|
||||
*
|
||||
* Tag numbers greater than 30 are not supported (i.e. short form only).
|
||||
*/
|
||||
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
|
||||
size_t *out_header_len);
|
||||
|
||||
/*
|
||||
* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
|
||||
* and sets |*out| to its value. It returns one on success and zero on error,
|
||||
* where error includes the integer being negative, or too large to represent
|
||||
* in 64 bits.
|
||||
*/
|
||||
int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
|
||||
|
||||
/*
|
||||
* CBS_get_optional_asn1 gets an optional explicitly-tagged element
|
||||
* from |cbs| tagged with |tag| and sets |*out| to its contents. If
|
||||
* present, it sets |*out_present| to one, otherwise zero. It returns
|
||||
* one on success, whether or not the element was present, and zero on
|
||||
* decode failure.
|
||||
*/
|
||||
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
|
||||
unsigned int tag);
|
||||
|
||||
/*
|
||||
* CBS_get_optional_asn1_octet_string gets an optional
|
||||
* explicitly-tagged OCTET STRING from |cbs|. If present, it sets
|
||||
* |*out| to the string and |*out_present| to one. Otherwise, it sets
|
||||
* |*out| to empty and |*out_present| to zero. |out_present| may be
|
||||
* NULL. It returns one on success, whether or not the element was
|
||||
* present, and zero on decode failure.
|
||||
*/
|
||||
int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
|
||||
unsigned int tag);
|
||||
|
||||
/*
|
||||
* CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
|
||||
* INTEGER from |cbs|. If present, it sets |*out| to the
|
||||
* value. Otherwise, it sets |*out| to |default_value|. It returns one
|
||||
* on success, whether or not the element was present, and zero on
|
||||
* decode failure.
|
||||
*/
|
||||
int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
|
||||
uint64_t default_value);
|
||||
|
||||
/*
|
||||
* CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
|
||||
* |cbs|. If present, it sets |*out| to either zero or one, based on the
|
||||
* boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
|
||||
* success, whether or not the element was present, and zero on decode
|
||||
* failure.
|
||||
*/
|
||||
int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
|
||||
int default_value);
|
||||
|
||||
|
||||
/*
|
||||
* CRYPTO ByteBuilder.
|
||||
*
|
||||
* |CBB| objects allow one to build length-prefixed serialisations. A |CBB|
|
||||
* object is associated with a buffer and new buffers are created with
|
||||
* |CBB_init|. Several |CBB| objects can point at the same buffer when a
|
||||
* length-prefix is pending, however only a single |CBB| can be 'current' at
|
||||
* any one time. For example, if one calls |CBB_add_u8_length_prefixed| then
|
||||
* the new |CBB| points at the same buffer as the original. But if the original
|
||||
* |CBB| is used then the length prefix is written out and the new |CBB| must
|
||||
* not be used again.
|
||||
*
|
||||
* If one needs to force a length prefix to be written out because a |CBB| is
|
||||
* going out of scope, use |CBB_flush|.
|
||||
*/
|
||||
|
||||
struct cbb_buffer_st {
|
||||
uint8_t *buf;
|
||||
|
||||
/* The number of valid bytes. */
|
||||
size_t len;
|
||||
|
||||
/* The size of buf. */
|
||||
size_t cap;
|
||||
|
||||
/*
|
||||
* One iff |buf| is owned by this object. If not then |buf| cannot be
|
||||
* resized.
|
||||
*/
|
||||
char can_resize;
|
||||
};
|
||||
|
||||
typedef struct cbb_st {
|
||||
struct cbb_buffer_st *base;
|
||||
|
||||
/*
|
||||
* offset is the offset from the start of |base->buf| to the position of any
|
||||
* pending length-prefix.
|
||||
*/
|
||||
size_t offset;
|
||||
|
||||
/* child points to a child CBB if a length-prefix is pending. */
|
||||
struct cbb_st *child;
|
||||
|
||||
/*
|
||||
* pending_len_len contains the number of bytes in a pending length-prefix,
|
||||
* or zero if no length-prefix is pending.
|
||||
*/
|
||||
uint8_t pending_len_len;
|
||||
|
||||
char pending_is_asn1;
|
||||
|
||||
/*
|
||||
* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
|
||||
* |CBB|). Top-level objects are valid arguments for |CBB_finish|.
|
||||
*/
|
||||
char is_top_level;
|
||||
} CBB;
|
||||
|
||||
/*
|
||||
* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
|
||||
* needed, the |initial_capacity| is just a hint. It returns one on success or
|
||||
* zero on error.
|
||||
*/
|
||||
int CBB_init(CBB *cbb, size_t initial_capacity);
|
||||
|
||||
/*
|
||||
* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
|
||||
* |buf| cannot grow, trying to write more than |len| bytes will cause CBB
|
||||
* functions to fail. It returns one on success or zero on error.
|
||||
*/
|
||||
int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
|
||||
|
||||
/*
|
||||
* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
|
||||
* writing to the same buffer. This should be used in an error case where a
|
||||
* serialisation is abandoned.
|
||||
*/
|
||||
void CBB_cleanup(CBB *cbb);
|
||||
|
||||
/*
|
||||
* CBB_finish completes any pending length prefix and sets |*out_data| to a
|
||||
* malloced buffer and |*out_len| to the length of that buffer. The caller
|
||||
* takes ownership of the buffer and, unless the buffer was fixed with
|
||||
* |CBB_init_fixed|, must call |free| when done.
|
||||
*
|
||||
* It can only be called on a "top level" |CBB|, i.e. one initialised with
|
||||
* |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
|
||||
* error.
|
||||
*/
|
||||
int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
|
||||
|
||||
/*
|
||||
* CBB_flush causes any pending length prefixes to be written out and any child
|
||||
* |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
|
||||
* on error.
|
||||
*/
|
||||
int CBB_flush(CBB *cbb);
|
||||
|
||||
/*
|
||||
* CBB_discard_child discards the current unflushed child of |cbb|. Neither the
|
||||
* child's contents nor the length prefix will be included in the output.
|
||||
*/
|
||||
void CBB_discard_child(CBB *cbb);
|
||||
|
||||
/*
|
||||
* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
|
||||
* data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
|
||||
* length. It returns one on success or zero on error.
|
||||
*/
|
||||
int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
|
||||
|
||||
/*
|
||||
* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
|
||||
* The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
|
||||
* big-endian length. It returns one on success or zero on error.
|
||||
*/
|
||||
int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
|
||||
|
||||
/*
|
||||
* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
|
||||
* The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
|
||||
* big-endian length. It returns one on success or zero on error.
|
||||
*/
|
||||
int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
|
||||
|
||||
/*
|
||||
* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
|
||||
* ASN.1 object can be written. The |tag| argument will be used as the tag for
|
||||
* the object. Passing in |tag| number 31 will return in an error since only
|
||||
* single octet identifiers are supported. It returns one on success or zero
|
||||
* on error.
|
||||
*/
|
||||
int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag);
|
||||
|
||||
/*
|
||||
* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
|
||||
* success and zero otherwise.
|
||||
*/
|
||||
int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
|
||||
|
||||
/*
|
||||
* CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
|
||||
* the beginning of that space. The caller must then write |len| bytes of
|
||||
* actual contents to |*out_data|. It returns one on success and zero
|
||||
* otherwise.
|
||||
*/
|
||||
int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
|
||||
|
||||
/*
|
||||
* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
|
||||
* success and zero otherwise.
|
||||
*/
|
||||
int CBB_add_u8(CBB *cbb, size_t value);
|
||||
|
||||
/*
|
||||
* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
|
||||
* returns one on success and zero otherwise.
|
||||
*/
|
||||
int CBB_add_u16(CBB *cbb, size_t value);
|
||||
|
||||
/*
|
||||
* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
|
||||
* returns one on success and zero otherwise.
|
||||
*/
|
||||
int CBB_add_u24(CBB *cbb, size_t value);
|
||||
|
||||
/*
|
||||
* CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It
|
||||
* returns one on success and zero otherwise.
|
||||
*/
|
||||
int CBB_add_u32(CBB *cbb, size_t value);
|
||||
|
||||
/*
|
||||
* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
|
||||
* and writes |value| in its contents. It returns one on success and zero on
|
||||
* error.
|
||||
*/
|
||||
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
|
||||
|
||||
#ifdef LIBRESSL_INTERNAL
|
||||
/*
|
||||
* CBS_dup sets |out| to point to cbs's |data| and |len|. It results in two
|
||||
* CBS that point to the same buffer.
|
||||
*/
|
||||
void CBS_dup(const CBS *cbs, CBS *out);
|
||||
|
||||
/*
|
||||
* cbs_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
|
||||
* |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
|
||||
* the tag number and |*out_header_len| to the length of the ASN.1 header. If
|
||||
* strict mode is disabled and the element has indefinite length then |*out|
|
||||
* will only contain the header. Each of |out|, |out_tag|, and
|
||||
* |out_header_len| may be NULL to ignore the value.
|
||||
*
|
||||
* Tag numbers greater than 30 are not supported (i.e. short form only).
|
||||
*/
|
||||
int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag,
|
||||
size_t *out_header_len, int strict);
|
||||
|
||||
/*
|
||||
* CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it
|
||||
* finds indefinite-length elements that otherwise appear to be valid DER, it
|
||||
* attempts to convert the DER-like data to DER and sets |*out| and
|
||||
* |*out_length| to describe a malloced buffer containing the DER data.
|
||||
* Additionally, |*in| will be advanced over the ASN.1 data.
|
||||
*
|
||||
* If it doesn't find any indefinite-length elements then it sets |*out| to
|
||||
* NULL and |*in| is unmodified.
|
||||
*
|
||||
* This is NOT a conversion from BER to DER. There are many restrictions when
|
||||
* dealing with DER data. This is only concerned with one: indefinite vs.
|
||||
* definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output
|
||||
* from NSS.
|
||||
*
|
||||
* It returns one on success and zero otherwise.
|
||||
*/
|
||||
int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len);
|
||||
#endif /* LIBRESSL_INTERNAL */
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif /* OPENSSL_HEADER_BYTESTRING_H */
|
||||
1246
externals/libressl/ssl/d1_both.c
vendored
Executable file
1246
externals/libressl/ssl/d1_both.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
184
externals/libressl/ssl/d1_clnt.c
vendored
Executable file
184
externals/libressl/ssl/d1_clnt.c
vendored
Executable file
@@ -0,0 +1,184 @@
|
||||
/* $OpenBSD: d1_clnt.c,v 1.83 2020/01/23 10:48:37 jsing Exp $ */
|
||||
/*
|
||||
* DTLS implementation written by Nagendra Modadugu
|
||||
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
int
|
||||
dtls1_get_hello_verify(SSL *s)
|
||||
{
|
||||
long n;
|
||||
int al, ok = 0;
|
||||
size_t cookie_len;
|
||||
uint16_t ssl_version;
|
||||
CBS hello_verify_request, cookie;
|
||||
|
||||
n = ssl3_get_message(s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
|
||||
DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1, s->internal->max_cert_list, &ok);
|
||||
if (!ok)
|
||||
return ((int)n);
|
||||
|
||||
if (S3I(s)->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
|
||||
D1I(s)->send_cookie = 0;
|
||||
S3I(s)->tmp.reuse_message = 1;
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
goto truncated;
|
||||
|
||||
CBS_init(&hello_verify_request, s->internal->init_msg, n);
|
||||
|
||||
if (!CBS_get_u16(&hello_verify_request, &ssl_version))
|
||||
goto truncated;
|
||||
|
||||
if (ssl_version != s->version) {
|
||||
SSLerror(s, SSL_R_WRONG_SSL_VERSION);
|
||||
s->version = (s->version & 0xff00) | (ssl_version & 0xff);
|
||||
al = SSL_AD_PROTOCOL_VERSION;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if (!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie))
|
||||
goto truncated;
|
||||
|
||||
if (!CBS_write_bytes(&cookie, D1I(s)->cookie,
|
||||
sizeof(D1I(s)->cookie), &cookie_len)) {
|
||||
D1I(s)->cookie_len = 0;
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
goto f_err;
|
||||
}
|
||||
D1I(s)->cookie_len = cookie_len;
|
||||
D1I(s)->send_cookie = 1;
|
||||
|
||||
return 1;
|
||||
|
||||
truncated:
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
f_err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
return -1;
|
||||
}
|
||||
450
externals/libressl/ssl/d1_lib.c
vendored
Executable file
450
externals/libressl/ssl/d1_lib.c
vendored
Executable file
@@ -0,0 +1,450 @@
|
||||
/* $OpenBSD: d1_lib.c,v 1.50 2020/09/26 14:43:17 jsing Exp $ */
|
||||
/*
|
||||
* DTLS implementation written by Nagendra Modadugu
|
||||
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "pqueue.h"
|
||||
#include "ssl_locl.h"
|
||||
|
||||
void dtls1_hm_fragment_free(hm_fragment *frag);
|
||||
|
||||
static int dtls1_listen(SSL *s, struct sockaddr *client);
|
||||
|
||||
SSL3_ENC_METHOD DTLSv1_enc_data = {
|
||||
.enc_flags = SSL_ENC_FLAG_EXPLICIT_IV,
|
||||
};
|
||||
|
||||
int
|
||||
dtls1_new(SSL *s)
|
||||
{
|
||||
if (!ssl3_new(s))
|
||||
goto err;
|
||||
|
||||
if ((s->d1 = calloc(1, sizeof(*s->d1))) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->internal = calloc(1, sizeof(*s->d1->internal))) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((s->d1->internal->unprocessed_rcds.q = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->internal->processed_rcds.q = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->internal->buffered_messages = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->sent_messages = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->internal->buffered_app_data.q = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (s->server)
|
||||
s->d1->internal->cookie_len = sizeof(D1I(s)->cookie);
|
||||
|
||||
s->method->internal->ssl_clear(s);
|
||||
return (1);
|
||||
|
||||
err:
|
||||
dtls1_free(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
dtls1_drain_records(pqueue queue)
|
||||
{
|
||||
pitem *item;
|
||||
DTLS1_RECORD_DATA_INTERNAL *rdata;
|
||||
|
||||
if (queue == NULL)
|
||||
return;
|
||||
|
||||
while ((item = pqueue_pop(queue)) != NULL) {
|
||||
rdata = (DTLS1_RECORD_DATA_INTERNAL *)item->data;
|
||||
ssl3_release_buffer(&rdata->rbuf);
|
||||
free(item->data);
|
||||
pitem_free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dtls1_drain_fragments(pqueue queue)
|
||||
{
|
||||
pitem *item;
|
||||
|
||||
if (queue == NULL)
|
||||
return;
|
||||
|
||||
while ((item = pqueue_pop(queue)) != NULL) {
|
||||
dtls1_hm_fragment_free(item->data);
|
||||
pitem_free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dtls1_clear_queues(SSL *s)
|
||||
{
|
||||
dtls1_drain_records(D1I(s)->unprocessed_rcds.q);
|
||||
dtls1_drain_records(D1I(s)->processed_rcds.q);
|
||||
dtls1_drain_fragments(D1I(s)->buffered_messages);
|
||||
dtls1_drain_fragments(s->d1->sent_messages);
|
||||
dtls1_drain_records(D1I(s)->buffered_app_data.q);
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_free(SSL *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
ssl3_free(s);
|
||||
|
||||
dtls1_clear_queues(s);
|
||||
|
||||
pqueue_free(D1I(s)->unprocessed_rcds.q);
|
||||
pqueue_free(D1I(s)->processed_rcds.q);
|
||||
pqueue_free(D1I(s)->buffered_messages);
|
||||
pqueue_free(s->d1->sent_messages);
|
||||
pqueue_free(D1I(s)->buffered_app_data.q);
|
||||
|
||||
freezero(s->d1->internal, sizeof(*s->d1->internal));
|
||||
freezero(s->d1, sizeof(*s->d1));
|
||||
|
||||
s->d1 = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_clear(SSL *s)
|
||||
{
|
||||
struct dtls1_state_internal_st *internal;
|
||||
pqueue unprocessed_rcds;
|
||||
pqueue processed_rcds;
|
||||
pqueue buffered_messages;
|
||||
pqueue sent_messages;
|
||||
pqueue buffered_app_data;
|
||||
unsigned int mtu;
|
||||
|
||||
if (s->d1) {
|
||||
unprocessed_rcds = D1I(s)->unprocessed_rcds.q;
|
||||
processed_rcds = D1I(s)->processed_rcds.q;
|
||||
buffered_messages = D1I(s)->buffered_messages;
|
||||
sent_messages = s->d1->sent_messages;
|
||||
buffered_app_data = D1I(s)->buffered_app_data.q;
|
||||
mtu = D1I(s)->mtu;
|
||||
|
||||
dtls1_clear_queues(s);
|
||||
|
||||
memset(s->d1->internal, 0, sizeof(*s->d1->internal));
|
||||
internal = s->d1->internal;
|
||||
memset(s->d1, 0, sizeof(*s->d1));
|
||||
s->d1->internal = internal;
|
||||
|
||||
if (s->server) {
|
||||
D1I(s)->cookie_len = sizeof(D1I(s)->cookie);
|
||||
}
|
||||
|
||||
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
|
||||
D1I(s)->mtu = mtu;
|
||||
}
|
||||
|
||||
D1I(s)->unprocessed_rcds.q = unprocessed_rcds;
|
||||
D1I(s)->processed_rcds.q = processed_rcds;
|
||||
D1I(s)->buffered_messages = buffered_messages;
|
||||
s->d1->sent_messages = sent_messages;
|
||||
D1I(s)->buffered_app_data.q = buffered_app_data;
|
||||
}
|
||||
|
||||
ssl3_clear(s);
|
||||
|
||||
s->version = DTLS1_VERSION;
|
||||
}
|
||||
|
||||
long
|
||||
dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case DTLS_CTRL_GET_TIMEOUT:
|
||||
if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
case DTLS_CTRL_HANDLE_TIMEOUT:
|
||||
ret = dtls1_handle_timeout(s);
|
||||
break;
|
||||
case DTLS_CTRL_LISTEN:
|
||||
ret = dtls1_listen(s, parg);
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = ssl3_ctrl(s, cmd, larg, parg);
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* As it's impossible to use stream ciphers in "datagram" mode, this
|
||||
* simple filter is designed to disengage them in DTLS. Unfortunately
|
||||
* there is no universal way to identify stream SSL_CIPHER, so we have
|
||||
* to explicitly list their SSL_* codes. Currently RC4 is the only one
|
||||
* available, but if new ones emerge, they will have to be added...
|
||||
*/
|
||||
const SSL_CIPHER *
|
||||
dtls1_get_cipher(unsigned int u)
|
||||
{
|
||||
const SSL_CIPHER *ciph = ssl3_get_cipher(u);
|
||||
|
||||
if (ciph != NULL) {
|
||||
if (ciph->algorithm_enc == SSL_RC4)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ciph;
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_start_timer(SSL *s)
|
||||
{
|
||||
|
||||
/* If timer is not set, initialize duration with 1 second */
|
||||
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
|
||||
s->d1->timeout_duration = 1;
|
||||
}
|
||||
|
||||
/* Set timeout to current time */
|
||||
gettimeofday(&(s->d1->next_timeout), NULL);
|
||||
|
||||
/* Add duration to current time */
|
||||
s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
|
||||
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
|
||||
&s->d1->next_timeout);
|
||||
}
|
||||
|
||||
struct timeval*
|
||||
dtls1_get_timeout(SSL *s, struct timeval* timeleft)
|
||||
{
|
||||
struct timeval timenow;
|
||||
|
||||
/* If no timeout is set, just return NULL */
|
||||
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get current time */
|
||||
gettimeofday(&timenow, NULL);
|
||||
|
||||
/* If timer already expired, set remaining time to 0 */
|
||||
if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
|
||||
(s->d1->next_timeout.tv_sec == timenow.tv_sec &&
|
||||
s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
|
||||
memset(timeleft, 0, sizeof(struct timeval));
|
||||
return timeleft;
|
||||
}
|
||||
|
||||
/* Calculate time left until timer expires */
|
||||
memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
|
||||
timeleft->tv_sec -= timenow.tv_sec;
|
||||
timeleft->tv_usec -= timenow.tv_usec;
|
||||
if (timeleft->tv_usec < 0) {
|
||||
timeleft->tv_sec--;
|
||||
timeleft->tv_usec += 1000000;
|
||||
}
|
||||
|
||||
/* If remaining time is less than 15 ms, set it to 0
|
||||
* to prevent issues because of small devergences with
|
||||
* socket timeouts.
|
||||
*/
|
||||
if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
|
||||
memset(timeleft, 0, sizeof(struct timeval));
|
||||
}
|
||||
|
||||
|
||||
return timeleft;
|
||||
}
|
||||
|
||||
int
|
||||
dtls1_is_timer_expired(SSL *s)
|
||||
{
|
||||
struct timeval timeleft;
|
||||
|
||||
/* Get time left until timeout, return false if no timer running */
|
||||
if (dtls1_get_timeout(s, &timeleft) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return false if timer is not expired yet */
|
||||
if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Timer expired, so return true */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_double_timeout(SSL *s)
|
||||
{
|
||||
s->d1->timeout_duration *= 2;
|
||||
if (s->d1->timeout_duration > 60)
|
||||
s->d1->timeout_duration = 60;
|
||||
dtls1_start_timer(s);
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_stop_timer(SSL *s)
|
||||
{
|
||||
/* Reset everything */
|
||||
memset(&(D1I(s)->timeout), 0, sizeof(struct dtls1_timeout_st));
|
||||
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
|
||||
s->d1->timeout_duration = 1;
|
||||
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
|
||||
&(s->d1->next_timeout));
|
||||
/* Clear retransmission buffer */
|
||||
dtls1_clear_record_buffer(s);
|
||||
}
|
||||
|
||||
int
|
||||
dtls1_check_timeout_num(SSL *s)
|
||||
{
|
||||
D1I(s)->timeout.num_alerts++;
|
||||
|
||||
/* Reduce MTU after 2 unsuccessful retransmissions */
|
||||
if (D1I(s)->timeout.num_alerts > 2) {
|
||||
D1I(s)->mtu = BIO_ctrl(SSL_get_wbio(s),
|
||||
BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
|
||||
|
||||
}
|
||||
|
||||
if (D1I(s)->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
|
||||
/* fail the connection, enough alerts have been sent */
|
||||
SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dtls1_handle_timeout(SSL *s)
|
||||
{
|
||||
/* if no timer is expired, don't do anything */
|
||||
if (!dtls1_is_timer_expired(s)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dtls1_double_timeout(s);
|
||||
|
||||
if (dtls1_check_timeout_num(s) < 0)
|
||||
return -1;
|
||||
|
||||
D1I(s)->timeout.read_timeouts++;
|
||||
if (D1I(s)->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
|
||||
D1I(s)->timeout.read_timeouts = 1;
|
||||
}
|
||||
|
||||
dtls1_start_timer(s);
|
||||
return dtls1_retransmit_buffered_messages(s);
|
||||
}
|
||||
|
||||
int
|
||||
dtls1_listen(SSL *s, struct sockaddr *client)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Ensure there is no state left over from a previous invocation */
|
||||
SSL_clear(s);
|
||||
|
||||
SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
|
||||
D1I(s)->listen = 1;
|
||||
|
||||
ret = SSL_accept(s);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_build_sequence_number(unsigned char *dst, unsigned char *seq,
|
||||
unsigned short epoch)
|
||||
{
|
||||
CBB cbb;
|
||||
|
||||
if (!CBB_init_fixed(&cbb, dst, SSL3_SEQUENCE_SIZE))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&cbb, epoch))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, &seq[2], SSL3_SEQUENCE_SIZE - 2))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, NULL, NULL))
|
||||
goto err;
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
}
|
||||
1361
externals/libressl/ssl/d1_pkt.c
vendored
Executable file
1361
externals/libressl/ssl/d1_pkt.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
251
externals/libressl/ssl/d1_srtp.c
vendored
Executable file
251
externals/libressl/ssl/d1_srtp.c
vendored
Executable file
@@ -0,0 +1,251 @@
|
||||
/* $OpenBSD: d1_srtp.c,v 1.24 2020/03/16 15:25:13 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* DTLS code by Eric Rescorla <ekr@rtfm.com>
|
||||
*
|
||||
* Copyright (C) 2006, Network Resonance, Inc.
|
||||
* Copyright (C) 2011, RTFM, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "srtp.h"
|
||||
|
||||
static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
|
||||
{
|
||||
"SRTP_AES128_CM_SHA1_80",
|
||||
SRTP_AES128_CM_SHA1_80,
|
||||
},
|
||||
{
|
||||
"SRTP_AES128_CM_SHA1_32",
|
||||
SRTP_AES128_CM_SHA1_32,
|
||||
},
|
||||
{0}
|
||||
};
|
||||
|
||||
int
|
||||
srtp_find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
|
||||
unsigned int len)
|
||||
{
|
||||
SRTP_PROTECTION_PROFILE *p;
|
||||
|
||||
p = srtp_known_profiles;
|
||||
while (p->name) {
|
||||
if ((len == strlen(p->name)) &&
|
||||
!strncmp(p->name, profile_name, len)) {
|
||||
*pptr = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
srtp_find_profile_by_num(unsigned int profile_num,
|
||||
SRTP_PROTECTION_PROFILE **pptr)
|
||||
{
|
||||
SRTP_PROTECTION_PROFILE *p;
|
||||
|
||||
p = srtp_known_profiles;
|
||||
while (p->name) {
|
||||
if (p->id == profile_num) {
|
||||
*pptr = p;
|
||||
return 0;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_ctx_make_profiles(const char *profiles_string,
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) **out)
|
||||
{
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
|
||||
|
||||
char *col;
|
||||
char *ptr = (char *)profiles_string;
|
||||
|
||||
SRTP_PROTECTION_PROFILE *p;
|
||||
|
||||
if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) {
|
||||
SSLerrorx(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
|
||||
return 1;
|
||||
}
|
||||
|
||||
do {
|
||||
col = strchr(ptr, ':');
|
||||
|
||||
if (!srtp_find_profile_by_name(ptr, &p,
|
||||
col ? col - ptr : (int)strlen(ptr))) {
|
||||
sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
|
||||
} else {
|
||||
SSLerrorx(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
|
||||
sk_SRTP_PROTECTION_PROFILE_free(profiles);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (col)
|
||||
ptr = col + 1;
|
||||
} while (col);
|
||||
|
||||
sk_SRTP_PROTECTION_PROFILE_free(*out);
|
||||
*out = profiles;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
|
||||
{
|
||||
return ssl_ctx_make_profiles(profiles, &ctx->internal->srtp_profiles);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
|
||||
{
|
||||
return ssl_ctx_make_profiles(profiles, &s->internal->srtp_profiles);
|
||||
}
|
||||
|
||||
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *
|
||||
SSL_get_srtp_profiles(SSL *s)
|
||||
{
|
||||
if (s != NULL) {
|
||||
if (s->internal->srtp_profiles != NULL) {
|
||||
return s->internal->srtp_profiles;
|
||||
} else if ((s->ctx != NULL) &&
|
||||
(s->ctx->internal->srtp_profiles != NULL)) {
|
||||
return s->ctx->internal->srtp_profiles;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRTP_PROTECTION_PROFILE *
|
||||
SSL_get_selected_srtp_profile(SSL *s)
|
||||
{
|
||||
return s->internal->srtp_profile;
|
||||
}
|
||||
|
||||
#endif
|
||||
165
externals/libressl/ssl/d1_srvr.c
vendored
Executable file
165
externals/libressl/ssl/d1_srvr.c
vendored
Executable file
@@ -0,0 +1,165 @@
|
||||
/* $OpenBSD: d1_srvr.c,v 1.95 2018/11/05 05:45:15 jsing Exp $ */
|
||||
/*
|
||||
* DTLS implementation written by Nagendra Modadugu
|
||||
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
int
|
||||
dtls1_send_hello_verify_request(SSL *s)
|
||||
{
|
||||
CBB cbb, verify, cookie;
|
||||
|
||||
memset(&cbb, 0, sizeof(cbb));
|
||||
|
||||
if (S3I(s)->hs.state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) {
|
||||
if (s->ctx->internal->app_gen_cookie_cb == NULL ||
|
||||
s->ctx->internal->app_gen_cookie_cb(s, D1I(s)->cookie,
|
||||
&(D1I(s)->cookie_len)) == 0) {
|
||||
SSLerror(s, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl3_handshake_msg_start(s, &cbb, &verify,
|
||||
DTLS1_MT_HELLO_VERIFY_REQUEST))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&verify, s->version))
|
||||
goto err;
|
||||
if (!CBB_add_u8_length_prefixed(&verify, &cookie))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cookie, D1I(s)->cookie, D1I(s)->cookie_len))
|
||||
goto err;
|
||||
if (!ssl3_handshake_msg_finish(s, &cbb))
|
||||
goto err;
|
||||
|
||||
S3I(s)->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
|
||||
}
|
||||
|
||||
/* S3I(s)->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
|
||||
return (ssl3_handshake_write(s));
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
201
externals/libressl/ssl/pqueue.c
vendored
Executable file
201
externals/libressl/ssl/pqueue.c
vendored
Executable file
@@ -0,0 +1,201 @@
|
||||
/* $OpenBSD: pqueue.c,v 1.5 2014/06/12 15:49:31 deraadt Exp $ */
|
||||
/*
|
||||
* DTLS implementation written by Nagendra Modadugu
|
||||
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pqueue.h"
|
||||
|
||||
typedef struct _pqueue {
|
||||
pitem *items;
|
||||
int count;
|
||||
} pqueue_s;
|
||||
|
||||
pitem *
|
||||
pitem_new(unsigned char *prio64be, void *data)
|
||||
{
|
||||
pitem *item = malloc(sizeof(pitem));
|
||||
|
||||
if (item == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(item->priority, prio64be, sizeof(item->priority));
|
||||
|
||||
item->data = data;
|
||||
item->next = NULL;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void
|
||||
pitem_free(pitem *item)
|
||||
{
|
||||
free(item);
|
||||
}
|
||||
|
||||
pqueue_s *
|
||||
pqueue_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(pqueue_s));
|
||||
}
|
||||
|
||||
void
|
||||
pqueue_free(pqueue_s *pq)
|
||||
{
|
||||
free(pq);
|
||||
}
|
||||
|
||||
pitem *
|
||||
pqueue_insert(pqueue_s *pq, pitem *item)
|
||||
{
|
||||
pitem *curr, *next;
|
||||
|
||||
if (pq->items == NULL) {
|
||||
pq->items = item;
|
||||
return item;
|
||||
}
|
||||
|
||||
for (curr = NULL, next = pq->items; next != NULL;
|
||||
curr = next, next = next->next) {
|
||||
/* we can compare 64-bit value in big-endian encoding
|
||||
* with memcmp:-) */
|
||||
int cmp = memcmp(next->priority, item->priority,
|
||||
sizeof(item->priority));
|
||||
if (cmp > 0) { /* next > item */
|
||||
item->next = next;
|
||||
|
||||
if (curr == NULL)
|
||||
pq->items = item;
|
||||
else
|
||||
curr->next = item;
|
||||
|
||||
return item;
|
||||
} else if (cmp == 0) /* duplicates not allowed */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item->next = NULL;
|
||||
curr->next = item;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
pitem *
|
||||
pqueue_peek(pqueue_s *pq)
|
||||
{
|
||||
return pq->items;
|
||||
}
|
||||
|
||||
pitem *
|
||||
pqueue_pop(pqueue_s *pq)
|
||||
{
|
||||
pitem *item = pq->items;
|
||||
|
||||
if (pq->items != NULL)
|
||||
pq->items = pq->items->next;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
pitem *
|
||||
pqueue_find(pqueue_s *pq, unsigned char *prio64be)
|
||||
{
|
||||
pitem *next;
|
||||
|
||||
for (next = pq->items; next != NULL; next = next->next)
|
||||
if (memcmp(next->priority, prio64be,
|
||||
sizeof(next->priority)) == 0)
|
||||
return next;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pitem *
|
||||
pqueue_iterator(pqueue_s *pq)
|
||||
{
|
||||
return pqueue_peek(pq);
|
||||
}
|
||||
|
||||
pitem *
|
||||
pqueue_next(pitem **item)
|
||||
{
|
||||
pitem *ret;
|
||||
|
||||
if (item == NULL || *item == NULL)
|
||||
return NULL;
|
||||
|
||||
/* *item != NULL */
|
||||
ret = *item;
|
||||
*item = (*item)->next;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
pqueue_size(pqueue_s *pq)
|
||||
{
|
||||
pitem *item = pq->items;
|
||||
int count = 0;
|
||||
|
||||
while (item != NULL) {
|
||||
count++;
|
||||
item = item->next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
629
externals/libressl/ssl/s3_cbc.c
vendored
Executable file
629
externals/libressl/ssl/s3_cbc.c
vendored
Executable file
@@ -0,0 +1,629 @@
|
||||
/* $OpenBSD: s3_cbc.c,v 1.22 2020/06/19 21:26:40 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2012 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
|
||||
* field. (SHA-384/512 have 128-bit length.) */
|
||||
#define MAX_HASH_BIT_COUNT_BYTES 16
|
||||
|
||||
/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
|
||||
* Currently SHA-384/512 has a 128-byte block size and that's the largest
|
||||
* supported by TLS.) */
|
||||
#define MAX_HASH_BLOCK_SIZE 128
|
||||
|
||||
/* Some utility functions are needed:
|
||||
*
|
||||
* These macros return the given value with the MSB copied to all the other
|
||||
* bits. They use the fact that arithmetic shift shifts-in the sign bit.
|
||||
* However, this is not ensured by the C standard so you may need to replace
|
||||
* them with something else on odd CPUs. */
|
||||
#define DUPLICATE_MSB_TO_ALL(x) ((unsigned int)((int)(x) >> (sizeof(int) * 8 - 1)))
|
||||
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
|
||||
|
||||
/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
|
||||
static unsigned int
|
||||
constant_time_lt(unsigned int a, unsigned int b)
|
||||
{
|
||||
a -= b;
|
||||
return DUPLICATE_MSB_TO_ALL(a);
|
||||
}
|
||||
|
||||
/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
|
||||
static unsigned int
|
||||
constant_time_ge(unsigned int a, unsigned int b)
|
||||
{
|
||||
a -= b;
|
||||
return DUPLICATE_MSB_TO_ALL(~a);
|
||||
}
|
||||
|
||||
/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
|
||||
static unsigned char
|
||||
constant_time_eq_8(unsigned int a, unsigned int b)
|
||||
{
|
||||
unsigned int c = a ^ b;
|
||||
c--;
|
||||
return DUPLICATE_MSB_TO_ALL_8(c);
|
||||
}
|
||||
|
||||
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
|
||||
* record in |rec| in constant time and returns 1 if the padding is valid and
|
||||
* -1 otherwise. It also removes any explicit IV from the start of the record
|
||||
* without leaking any timing about whether there was enough space after the
|
||||
* padding was removed.
|
||||
*
|
||||
* block_size: the block size of the cipher used to encrypt the record.
|
||||
* returns:
|
||||
* 0: (in non-constant time) if the record is publicly invalid.
|
||||
* 1: if the padding was valid
|
||||
* -1: otherwise. */
|
||||
int
|
||||
tls1_cbc_remove_padding(const SSL* s, SSL3_RECORD_INTERNAL *rec,
|
||||
unsigned int block_size, unsigned int mac_size)
|
||||
{
|
||||
unsigned int padding_length, good, to_check, i;
|
||||
const unsigned int overhead = 1 /* padding length byte */ + mac_size;
|
||||
|
||||
/* Check if version requires explicit IV */
|
||||
if (SSL_USE_EXPLICIT_IV(s)) {
|
||||
/* These lengths are all public so we can test them in
|
||||
* non-constant time.
|
||||
*/
|
||||
if (overhead + block_size > rec->length)
|
||||
return 0;
|
||||
/* We can now safely skip explicit IV */
|
||||
rec->data += block_size;
|
||||
rec->input += block_size;
|
||||
rec->length -= block_size;
|
||||
} else if (overhead > rec->length)
|
||||
return 0;
|
||||
|
||||
padding_length = rec->data[rec->length - 1];
|
||||
|
||||
good = constant_time_ge(rec->length, overhead + padding_length);
|
||||
/* The padding consists of a length byte at the end of the record and
|
||||
* then that many bytes of padding, all with the same value as the
|
||||
* length byte. Thus, with the length byte included, there are i+1
|
||||
* bytes of padding.
|
||||
*
|
||||
* We can't check just |padding_length+1| bytes because that leaks
|
||||
* decrypted information. Therefore we always have to check the maximum
|
||||
* amount of padding possible. (Again, the length of the record is
|
||||
* public information so we can use it.) */
|
||||
to_check = 256; /* maximum amount of padding, inc length byte. */
|
||||
if (to_check > rec->length)
|
||||
to_check = rec->length;
|
||||
|
||||
for (i = 0; i < to_check; i++) {
|
||||
unsigned char mask = constant_time_ge(padding_length, i);
|
||||
unsigned char b = rec->data[rec->length - 1 - i];
|
||||
/* The final |padding_length+1| bytes should all have the value
|
||||
* |padding_length|. Therefore the XOR should be zero. */
|
||||
good &= ~(mask&(padding_length ^ b));
|
||||
}
|
||||
|
||||
/* If any of the final |padding_length+1| bytes had the wrong value,
|
||||
* one or more of the lower eight bits of |good| will be cleared. We
|
||||
* AND the bottom 8 bits together and duplicate the result to all the
|
||||
* bits. */
|
||||
good &= good >> 4;
|
||||
good &= good >> 2;
|
||||
good &= good >> 1;
|
||||
good <<= sizeof(good)*8 - 1;
|
||||
good = DUPLICATE_MSB_TO_ALL(good);
|
||||
|
||||
padding_length = good & (padding_length + 1);
|
||||
rec->length -= padding_length;
|
||||
rec->padding_length = padding_length;
|
||||
|
||||
return (int)((good & 1) | (~good & -1));
|
||||
}
|
||||
|
||||
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
|
||||
* constant time (independent of the concrete value of rec->length, which may
|
||||
* vary within a 256-byte window).
|
||||
*
|
||||
* ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
|
||||
* this function.
|
||||
*
|
||||
* On entry:
|
||||
* rec->orig_len >= md_size
|
||||
* md_size <= EVP_MAX_MD_SIZE
|
||||
*
|
||||
* If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
|
||||
* variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
|
||||
* a single or pair of cache-lines, then the variable memory accesses don't
|
||||
* actually affect the timing. CPUs with smaller cache-lines [if any] are
|
||||
* not multi-core and are not considered vulnerable to cache-timing attacks.
|
||||
*/
|
||||
#define CBC_MAC_ROTATE_IN_PLACE
|
||||
|
||||
void
|
||||
ssl3_cbc_copy_mac(unsigned char* out, const SSL3_RECORD_INTERNAL *rec,
|
||||
unsigned int md_size, unsigned int orig_len)
|
||||
{
|
||||
#if defined(CBC_MAC_ROTATE_IN_PLACE)
|
||||
unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
|
||||
unsigned char *rotated_mac;
|
||||
#else
|
||||
unsigned char rotated_mac[EVP_MAX_MD_SIZE];
|
||||
#endif
|
||||
|
||||
/* mac_end is the index of |rec->data| just after the end of the MAC. */
|
||||
unsigned int mac_end = rec->length;
|
||||
unsigned int mac_start = mac_end - md_size;
|
||||
/* scan_start contains the number of bytes that we can ignore because
|
||||
* the MAC's position can only vary by 255 bytes. */
|
||||
unsigned int scan_start = 0;
|
||||
unsigned int i, j;
|
||||
unsigned int div_spoiler;
|
||||
unsigned int rotate_offset;
|
||||
|
||||
OPENSSL_assert(orig_len >= md_size);
|
||||
OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
|
||||
|
||||
#if defined(CBC_MAC_ROTATE_IN_PLACE)
|
||||
rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf)&63);
|
||||
#endif
|
||||
|
||||
/* This information is public so it's safe to branch based on it. */
|
||||
if (orig_len > md_size + 255 + 1)
|
||||
scan_start = orig_len - (md_size + 255 + 1);
|
||||
/* div_spoiler contains a multiple of md_size that is used to cause the
|
||||
* modulo operation to be constant time. Without this, the time varies
|
||||
* based on the amount of padding when running on Intel chips at least.
|
||||
*
|
||||
* The aim of right-shifting md_size is so that the compiler doesn't
|
||||
* figure out that it can remove div_spoiler as that would require it
|
||||
* to prove that md_size is always even, which I hope is beyond it. */
|
||||
div_spoiler = md_size >> 1;
|
||||
div_spoiler <<= (sizeof(div_spoiler) - 1) * 8;
|
||||
rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
|
||||
|
||||
memset(rotated_mac, 0, md_size);
|
||||
for (i = scan_start, j = 0; i < orig_len; i++) {
|
||||
unsigned char mac_started = constant_time_ge(i, mac_start);
|
||||
unsigned char mac_ended = constant_time_ge(i, mac_end);
|
||||
unsigned char b = rec->data[i];
|
||||
rotated_mac[j++] |= b & mac_started & ~mac_ended;
|
||||
j &= constant_time_lt(j, md_size);
|
||||
}
|
||||
|
||||
/* Now rotate the MAC */
|
||||
#if defined(CBC_MAC_ROTATE_IN_PLACE)
|
||||
j = 0;
|
||||
for (i = 0; i < md_size; i++) {
|
||||
/* in case cache-line is 32 bytes, touch second line */
|
||||
((volatile unsigned char *)rotated_mac)[rotate_offset^32];
|
||||
out[j++] = rotated_mac[rotate_offset++];
|
||||
rotate_offset &= constant_time_lt(rotate_offset, md_size);
|
||||
}
|
||||
#else
|
||||
memset(out, 0, md_size);
|
||||
rotate_offset = md_size - rotate_offset;
|
||||
rotate_offset &= constant_time_lt(rotate_offset, md_size);
|
||||
for (i = 0; i < md_size; i++) {
|
||||
for (j = 0; j < md_size; j++)
|
||||
out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
|
||||
rotate_offset++;
|
||||
rotate_offset &= constant_time_lt(rotate_offset, md_size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l) )&0xff))
|
||||
|
||||
#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>48)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>40)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>32)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l) )&0xff))
|
||||
|
||||
/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
|
||||
* little-endian order. The value of p is advanced by four. */
|
||||
#define u32toLE(n, p) \
|
||||
(*((p)++)=(unsigned char)(n), \
|
||||
*((p)++)=(unsigned char)(n>>8), \
|
||||
*((p)++)=(unsigned char)(n>>16), \
|
||||
*((p)++)=(unsigned char)(n>>24))
|
||||
|
||||
/* These functions serialize the state of a hash and thus perform the standard
|
||||
* "final" operation without adding the padding and length that such a function
|
||||
* typically does. */
|
||||
static void
|
||||
tls1_md5_final_raw(void* ctx, unsigned char *md_out)
|
||||
{
|
||||
MD5_CTX *md5 = ctx;
|
||||
u32toLE(md5->A, md_out);
|
||||
u32toLE(md5->B, md_out);
|
||||
u32toLE(md5->C, md_out);
|
||||
u32toLE(md5->D, md_out);
|
||||
}
|
||||
|
||||
static void
|
||||
tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
|
||||
{
|
||||
SHA_CTX *sha1 = ctx;
|
||||
l2n(sha1->h0, md_out);
|
||||
l2n(sha1->h1, md_out);
|
||||
l2n(sha1->h2, md_out);
|
||||
l2n(sha1->h3, md_out);
|
||||
l2n(sha1->h4, md_out);
|
||||
}
|
||||
|
||||
static void
|
||||
tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
|
||||
{
|
||||
SHA256_CTX *sha256 = ctx;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
l2n(sha256->h[i], md_out);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
|
||||
{
|
||||
SHA512_CTX *sha512 = ctx;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
l2n8(sha512->h[i], md_out);
|
||||
}
|
||||
}
|
||||
|
||||
/* Largest hash context ever used by the functions above. */
|
||||
#define LARGEST_DIGEST_CTX SHA512_CTX
|
||||
|
||||
/* Type giving the alignment needed by the above */
|
||||
#define LARGEST_DIGEST_CTX_ALIGNMENT SHA_LONG64
|
||||
|
||||
/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
|
||||
* which ssl3_cbc_digest_record supports. */
|
||||
char
|
||||
ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
|
||||
{
|
||||
switch (EVP_MD_CTX_type(ctx)) {
|
||||
case NID_md5:
|
||||
case NID_sha1:
|
||||
case NID_sha224:
|
||||
case NID_sha256:
|
||||
case NID_sha384:
|
||||
case NID_sha512:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded TLS
|
||||
* record.
|
||||
*
|
||||
* ctx: the EVP_MD_CTX from which we take the hash function.
|
||||
* ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
|
||||
* md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
|
||||
* md_out_size: if non-NULL, the number of output bytes is written here.
|
||||
* header: the 13-byte, TLS record header.
|
||||
* data: the record data itself, less any preceeding explicit IV.
|
||||
* data_plus_mac_size: the secret, reported length of the data and MAC
|
||||
* once the padding has been removed.
|
||||
* data_plus_mac_plus_padding_size: the public length of the whole
|
||||
* record, including padding.
|
||||
*
|
||||
* On entry: by virtue of having been through one of the remove_padding
|
||||
* functions, above, we know that data_plus_mac_size is large enough to contain
|
||||
* a padding byte and MAC. (If the padding was invalid, it might contain the
|
||||
* padding too. )
|
||||
*/
|
||||
int
|
||||
ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out,
|
||||
size_t* md_out_size, const unsigned char header[13],
|
||||
const unsigned char *data, size_t data_plus_mac_size,
|
||||
size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret,
|
||||
unsigned int mac_secret_length)
|
||||
{
|
||||
union {
|
||||
/*
|
||||
* Alignment here is to allow this to be cast as SHA512_CTX
|
||||
* without losing alignment required by the 64-bit SHA_LONG64
|
||||
* integer it contains.
|
||||
*/
|
||||
LARGEST_DIGEST_CTX_ALIGNMENT align;
|
||||
unsigned char c[sizeof(LARGEST_DIGEST_CTX)];
|
||||
} md_state;
|
||||
void (*md_final_raw)(void *ctx, unsigned char *md_out);
|
||||
void (*md_transform)(void *ctx, const unsigned char *block);
|
||||
unsigned int md_size, md_block_size = 64;
|
||||
unsigned int header_length, variance_blocks,
|
||||
len, max_mac_bytes, num_blocks,
|
||||
num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
|
||||
unsigned int bits; /* at most 18 bits */
|
||||
unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
|
||||
/* hmac_pad is the masked HMAC key. */
|
||||
unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
|
||||
unsigned char first_block[MAX_HASH_BLOCK_SIZE];
|
||||
unsigned char mac_out[EVP_MAX_MD_SIZE];
|
||||
unsigned int i, j, md_out_size_u;
|
||||
EVP_MD_CTX md_ctx;
|
||||
/* mdLengthSize is the number of bytes in the length field that terminates
|
||||
* the hash. */
|
||||
unsigned int md_length_size = 8;
|
||||
char length_is_big_endian = 1;
|
||||
|
||||
/* This is a, hopefully redundant, check that allows us to forget about
|
||||
* many possible overflows later in this function. */
|
||||
OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
|
||||
|
||||
switch (EVP_MD_CTX_type(ctx)) {
|
||||
case NID_md5:
|
||||
MD5_Init((MD5_CTX*)md_state.c);
|
||||
md_final_raw = tls1_md5_final_raw;
|
||||
md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
|
||||
md_size = 16;
|
||||
length_is_big_endian = 0;
|
||||
break;
|
||||
case NID_sha1:
|
||||
SHA1_Init((SHA_CTX*)md_state.c);
|
||||
md_final_raw = tls1_sha1_final_raw;
|
||||
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
|
||||
md_size = 20;
|
||||
break;
|
||||
case NID_sha224:
|
||||
SHA224_Init((SHA256_CTX*)md_state.c);
|
||||
md_final_raw = tls1_sha256_final_raw;
|
||||
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
|
||||
md_size = 224/8;
|
||||
break;
|
||||
case NID_sha256:
|
||||
SHA256_Init((SHA256_CTX*)md_state.c);
|
||||
md_final_raw = tls1_sha256_final_raw;
|
||||
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
|
||||
md_size = 32;
|
||||
break;
|
||||
case NID_sha384:
|
||||
SHA384_Init((SHA512_CTX*)md_state.c);
|
||||
md_final_raw = tls1_sha512_final_raw;
|
||||
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
|
||||
md_size = 384/8;
|
||||
md_block_size = 128;
|
||||
md_length_size = 16;
|
||||
break;
|
||||
case NID_sha512:
|
||||
SHA512_Init((SHA512_CTX*)md_state.c);
|
||||
md_final_raw = tls1_sha512_final_raw;
|
||||
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
|
||||
md_size = 64;
|
||||
md_block_size = 128;
|
||||
md_length_size = 16;
|
||||
break;
|
||||
default:
|
||||
/* ssl3_cbc_record_digest_supported should have been
|
||||
* called first to check that the hash function is
|
||||
* supported. */
|
||||
OPENSSL_assert(0);
|
||||
if (md_out_size)
|
||||
*md_out_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
|
||||
OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
|
||||
OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
|
||||
|
||||
header_length = 13;
|
||||
|
||||
/* variance_blocks is the number of blocks of the hash that we have to
|
||||
* calculate in constant time because they could be altered by the
|
||||
* padding value.
|
||||
*
|
||||
* TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
|
||||
* required to be minimal. Therefore we say that the final six blocks
|
||||
* can vary based on the padding.
|
||||
*
|
||||
* Later in the function, if the message is short and there obviously
|
||||
* cannot be this many blocks then variance_blocks can be reduced. */
|
||||
variance_blocks = 6;
|
||||
/* From now on we're dealing with the MAC, which conceptually has 13
|
||||
* bytes of `header' before the start of the data (TLS) */
|
||||
len = data_plus_mac_plus_padding_size + header_length;
|
||||
/* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
|
||||
* |header|, assuming that there's no padding. */
|
||||
max_mac_bytes = len - md_size - 1;
|
||||
/* num_blocks is the maximum number of hash blocks. */
|
||||
num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
|
||||
/* In order to calculate the MAC in constant time we have to handle
|
||||
* the final blocks specially because the padding value could cause the
|
||||
* end to appear somewhere in the final |variance_blocks| blocks and we
|
||||
* can't leak where. However, |num_starting_blocks| worth of data can
|
||||
* be hashed right away because no padding value can affect whether
|
||||
* they are plaintext. */
|
||||
num_starting_blocks = 0;
|
||||
/* k is the starting byte offset into the conceptual header||data where
|
||||
* we start processing. */
|
||||
k = 0;
|
||||
/* mac_end_offset is the index just past the end of the data to be
|
||||
* MACed. */
|
||||
mac_end_offset = data_plus_mac_size + header_length - md_size;
|
||||
/* c is the index of the 0x80 byte in the final hash block that
|
||||
* contains application data. */
|
||||
c = mac_end_offset % md_block_size;
|
||||
/* index_a is the hash block number that contains the 0x80 terminating
|
||||
* value. */
|
||||
index_a = mac_end_offset / md_block_size;
|
||||
/* index_b is the hash block number that contains the 64-bit hash
|
||||
* length, in bits. */
|
||||
index_b = (mac_end_offset + md_length_size) / md_block_size;
|
||||
/* bits is the hash-length in bits. It includes the additional hash
|
||||
* block for the masked HMAC key. */
|
||||
|
||||
if (num_blocks > variance_blocks) {
|
||||
num_starting_blocks = num_blocks - variance_blocks;
|
||||
k = md_block_size*num_starting_blocks;
|
||||
}
|
||||
|
||||
bits = 8*mac_end_offset;
|
||||
/* Compute the initial HMAC block. */
|
||||
bits += 8*md_block_size;
|
||||
memset(hmac_pad, 0, md_block_size);
|
||||
OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
|
||||
memcpy(hmac_pad, mac_secret, mac_secret_length);
|
||||
for (i = 0; i < md_block_size; i++)
|
||||
hmac_pad[i] ^= 0x36;
|
||||
|
||||
md_transform(md_state.c, hmac_pad);
|
||||
|
||||
if (length_is_big_endian) {
|
||||
memset(length_bytes, 0, md_length_size - 4);
|
||||
length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24);
|
||||
length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16);
|
||||
length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8);
|
||||
length_bytes[md_length_size - 1] = (unsigned char)bits;
|
||||
} else {
|
||||
memset(length_bytes, 0, md_length_size);
|
||||
length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24);
|
||||
length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16);
|
||||
length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8);
|
||||
length_bytes[md_length_size - 8] = (unsigned char)bits;
|
||||
}
|
||||
|
||||
if (k > 0) {
|
||||
/* k is a multiple of md_block_size. */
|
||||
memcpy(first_block, header, 13);
|
||||
memcpy(first_block + 13, data, md_block_size - 13);
|
||||
md_transform(md_state.c, first_block);
|
||||
for (i = 1; i < k/md_block_size; i++)
|
||||
md_transform(md_state.c, data + md_block_size*i - 13);
|
||||
}
|
||||
|
||||
memset(mac_out, 0, sizeof(mac_out));
|
||||
|
||||
/* We now process the final hash blocks. For each block, we construct
|
||||
* it in constant time. If the |i==index_a| then we'll include the 0x80
|
||||
* bytes and zero pad etc. For each block we selectively copy it, in
|
||||
* constant time, to |mac_out|. */
|
||||
for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; i++) {
|
||||
unsigned char block[MAX_HASH_BLOCK_SIZE];
|
||||
unsigned char is_block_a = constant_time_eq_8(i, index_a);
|
||||
unsigned char is_block_b = constant_time_eq_8(i, index_b);
|
||||
for (j = 0; j < md_block_size; j++) {
|
||||
unsigned char b = 0, is_past_c, is_past_cp1;
|
||||
if (k < header_length)
|
||||
b = header[k];
|
||||
else if (k < data_plus_mac_plus_padding_size + header_length)
|
||||
b = data[k - header_length];
|
||||
k++;
|
||||
|
||||
is_past_c = is_block_a & constant_time_ge(j, c);
|
||||
is_past_cp1 = is_block_a & constant_time_ge(j, c + 1);
|
||||
/* If this is the block containing the end of the
|
||||
* application data, and we are at the offset for the
|
||||
* 0x80 value, then overwrite b with 0x80. */
|
||||
b = (b&~is_past_c) | (0x80&is_past_c);
|
||||
/* If this is the block containing the end of the
|
||||
* application data and we're past the 0x80 value then
|
||||
* just write zero. */
|
||||
b = b&~is_past_cp1;
|
||||
/* If this is index_b (the final block), but not
|
||||
* index_a (the end of the data), then the 64-bit
|
||||
* length didn't fit into index_a and we're having to
|
||||
* add an extra block of zeros. */
|
||||
b &= ~is_block_b | is_block_a;
|
||||
|
||||
/* The final bytes of one of the blocks contains the
|
||||
* length. */
|
||||
if (j >= md_block_size - md_length_size) {
|
||||
/* If this is index_b, write a length byte. */
|
||||
b = (b&~is_block_b) | (is_block_b&length_bytes[j - (md_block_size - md_length_size)]);
|
||||
}
|
||||
block[j] = b;
|
||||
}
|
||||
|
||||
md_transform(md_state.c, block);
|
||||
md_final_raw(md_state.c, block);
|
||||
/* If this is index_b, copy the hash value to |mac_out|. */
|
||||
for (j = 0; j < md_size; j++)
|
||||
mac_out[j] |= block[j]&is_block_b;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_init(&md_ctx);
|
||||
if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) {
|
||||
EVP_MD_CTX_cleanup(&md_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Complete the HMAC in the standard manner. */
|
||||
for (i = 0; i < md_block_size; i++)
|
||||
hmac_pad[i] ^= 0x6a;
|
||||
|
||||
EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
|
||||
EVP_DigestUpdate(&md_ctx, mac_out, md_size);
|
||||
|
||||
EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
|
||||
if (md_out_size)
|
||||
*md_out_size = md_out_size_u;
|
||||
EVP_MD_CTX_cleanup(&md_ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
2738
externals/libressl/ssl/s3_lib.c
vendored
Executable file
2738
externals/libressl/ssl/s3_lib.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
142
externals/libressl/ssl/srtp.h
vendored
Executable file
142
externals/libressl/ssl/srtp.h
vendored
Executable file
@@ -0,0 +1,142 @@
|
||||
/* $OpenBSD: srtp.h,v 1.6 2015/09/01 15:18:23 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* DTLS code by Eric Rescorla <ekr@rtfm.com>
|
||||
*
|
||||
* Copyright (C) 2006, Network Resonance, Inc.
|
||||
* Copyright (C) 2011, RTFM, Inc.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_D1_SRTP_H
|
||||
#define HEADER_D1_SRTP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SRTP_AES128_CM_SHA1_80 0x0001
|
||||
#define SRTP_AES128_CM_SHA1_32 0x0002
|
||||
#define SRTP_AES128_F8_SHA1_80 0x0003
|
||||
#define SRTP_AES128_F8_SHA1_32 0x0004
|
||||
#define SRTP_NULL_SHA1_80 0x0005
|
||||
#define SRTP_NULL_SHA1_32 0x0006
|
||||
|
||||
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
|
||||
int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
|
||||
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
|
||||
SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
311
externals/libressl/ssl/ssl.sym
vendored
Executable file
311
externals/libressl/ssl/ssl.sym
vendored
Executable file
@@ -0,0 +1,311 @@
|
||||
BIO_f_ssl
|
||||
BIO_new_buffer_ssl_connect
|
||||
BIO_new_ssl
|
||||
BIO_new_ssl_connect
|
||||
BIO_ssl_copy_session_id
|
||||
BIO_ssl_shutdown
|
||||
DTLS_client_method
|
||||
DTLS_method
|
||||
DTLS_server_method
|
||||
DTLSv1_client_method
|
||||
DTLSv1_method
|
||||
DTLSv1_server_method
|
||||
SSLv23_client_method
|
||||
SSLv23_method
|
||||
SSLv23_server_method
|
||||
TLS_client_method
|
||||
TLS_method
|
||||
TLS_server_method
|
||||
TLSv1_1_client_method
|
||||
TLSv1_1_method
|
||||
TLSv1_1_server_method
|
||||
TLSv1_2_client_method
|
||||
TLSv1_2_method
|
||||
TLSv1_2_server_method
|
||||
TLSv1_client_method
|
||||
TLSv1_method
|
||||
TLSv1_server_method
|
||||
PEM_read_SSL_SESSION
|
||||
PEM_read_bio_SSL_SESSION
|
||||
PEM_write_SSL_SESSION
|
||||
PEM_write_bio_SSL_SESSION
|
||||
d2i_SSL_SESSION
|
||||
i2d_SSL_SESSION
|
||||
ERR_load_SSL_strings
|
||||
SSL_CIPHER_description
|
||||
SSL_CIPHER_get_auth_nid
|
||||
SSL_CIPHER_get_bits
|
||||
SSL_CIPHER_get_by_id
|
||||
SSL_CIPHER_get_by_value
|
||||
SSL_CIPHER_get_cipher_nid
|
||||
SSL_CIPHER_get_digest_nid
|
||||
SSL_CIPHER_get_id
|
||||
SSL_CIPHER_get_kx_nid
|
||||
SSL_CIPHER_get_name
|
||||
SSL_CIPHER_get_value
|
||||
SSL_CIPHER_get_version
|
||||
SSL_CIPHER_is_aead
|
||||
SSL_COMP_add_compression_method
|
||||
SSL_COMP_get_compression_methods
|
||||
SSL_COMP_get_name
|
||||
SSL_CTX_add0_chain_cert
|
||||
SSL_CTX_add1_chain_cert
|
||||
SSL_CTX_add_client_CA
|
||||
SSL_CTX_add_session
|
||||
SSL_CTX_callback_ctrl
|
||||
SSL_CTX_check_private_key
|
||||
SSL_CTX_clear_chain_certs
|
||||
SSL_CTX_ctrl
|
||||
SSL_CTX_flush_sessions
|
||||
SSL_CTX_free
|
||||
SSL_CTX_get0_certificate
|
||||
SSL_CTX_get0_chain_certs
|
||||
SSL_CTX_get0_param
|
||||
SSL_CTX_get_cert_store
|
||||
SSL_CTX_get_ciphers
|
||||
SSL_CTX_get_client_CA_list
|
||||
SSL_CTX_get_client_cert_cb
|
||||
SSL_CTX_get_default_passwd_cb
|
||||
SSL_CTX_get_default_passwd_cb_userdata
|
||||
SSL_CTX_get_ex_data
|
||||
SSL_CTX_get_ex_new_index
|
||||
SSL_CTX_get_info_callback
|
||||
SSL_CTX_get_max_proto_version
|
||||
SSL_CTX_get_min_proto_version
|
||||
SSL_CTX_get_quiet_shutdown
|
||||
SSL_CTX_get_timeout
|
||||
SSL_CTX_get_verify_callback
|
||||
SSL_CTX_get_verify_depth
|
||||
SSL_CTX_get_verify_mode
|
||||
SSL_CTX_load_verify_locations
|
||||
SSL_CTX_load_verify_mem
|
||||
SSL_CTX_new
|
||||
SSL_CTX_remove_session
|
||||
SSL_CTX_sess_get_get_cb
|
||||
SSL_CTX_sess_get_new_cb
|
||||
SSL_CTX_sess_get_remove_cb
|
||||
SSL_CTX_sess_set_get_cb
|
||||
SSL_CTX_sess_set_new_cb
|
||||
SSL_CTX_sess_set_remove_cb
|
||||
SSL_CTX_sessions
|
||||
SSL_CTX_set0_chain
|
||||
SSL_CTX_set1_chain
|
||||
SSL_CTX_set1_groups
|
||||
SSL_CTX_set1_groups_list
|
||||
SSL_CTX_set1_param
|
||||
SSL_CTX_set_alpn_protos
|
||||
SSL_CTX_set_alpn_select_cb
|
||||
SSL_CTX_set_cert_store
|
||||
SSL_CTX_set_cert_verify_callback
|
||||
SSL_CTX_set_cipher_list
|
||||
SSL_CTX_set_client_CA_list
|
||||
SSL_CTX_set_client_cert_cb
|
||||
SSL_CTX_set_client_cert_engine
|
||||
SSL_CTX_set_cookie_generate_cb
|
||||
SSL_CTX_set_cookie_verify_cb
|
||||
SSL_CTX_set_default_passwd_cb
|
||||
SSL_CTX_set_default_passwd_cb_userdata
|
||||
SSL_CTX_set_default_verify_paths
|
||||
SSL_CTX_set_ex_data
|
||||
SSL_CTX_set_generate_session_id
|
||||
SSL_CTX_set_info_callback
|
||||
SSL_CTX_set_max_proto_version
|
||||
SSL_CTX_set_min_proto_version
|
||||
SSL_CTX_set_msg_callback
|
||||
SSL_CTX_set_next_proto_select_cb
|
||||
SSL_CTX_set_next_protos_advertised_cb
|
||||
SSL_CTX_set_purpose
|
||||
SSL_CTX_set_quiet_shutdown
|
||||
SSL_CTX_set_session_id_context
|
||||
SSL_CTX_set_ssl_version
|
||||
SSL_CTX_set_timeout
|
||||
SSL_CTX_set_tlsext_use_srtp
|
||||
SSL_CTX_set_tmp_dh_callback
|
||||
SSL_CTX_set_tmp_ecdh_callback
|
||||
SSL_CTX_set_tmp_rsa_callback
|
||||
SSL_CTX_set_trust
|
||||
SSL_CTX_set_verify
|
||||
SSL_CTX_set_verify_depth
|
||||
SSL_CTX_up_ref
|
||||
SSL_CTX_use_PrivateKey
|
||||
SSL_CTX_use_PrivateKey_ASN1
|
||||
SSL_CTX_use_PrivateKey_file
|
||||
SSL_CTX_use_RSAPrivateKey
|
||||
SSL_CTX_use_RSAPrivateKey_ASN1
|
||||
SSL_CTX_use_RSAPrivateKey_file
|
||||
SSL_CTX_use_certificate
|
||||
SSL_CTX_use_certificate_ASN1
|
||||
SSL_CTX_use_certificate_chain_file
|
||||
SSL_CTX_use_certificate_chain_mem
|
||||
SSL_CTX_use_certificate_file
|
||||
SSL_SESSION_free
|
||||
SSL_SESSION_get0_id_context
|
||||
SSL_SESSION_get0_peer
|
||||
SSL_SESSION_get_compress_id
|
||||
SSL_SESSION_get_ex_data
|
||||
SSL_SESSION_get_ex_new_index
|
||||
SSL_SESSION_get_id
|
||||
SSL_SESSION_get_master_key
|
||||
SSL_SESSION_get_protocol_version
|
||||
SSL_SESSION_get_ticket_lifetime_hint
|
||||
SSL_SESSION_get_time
|
||||
SSL_SESSION_get_timeout
|
||||
SSL_SESSION_has_ticket
|
||||
SSL_SESSION_new
|
||||
SSL_SESSION_print
|
||||
SSL_SESSION_print_fp
|
||||
SSL_SESSION_set1_id
|
||||
SSL_SESSION_set1_id_context
|
||||
SSL_SESSION_set_ex_data
|
||||
SSL_SESSION_set_time
|
||||
SSL_SESSION_set_timeout
|
||||
SSL_SESSION_up_ref
|
||||
SSL_accept
|
||||
SSL_add0_chain_cert
|
||||
SSL_add1_chain_cert
|
||||
SSL_add_client_CA
|
||||
SSL_add_dir_cert_subjects_to_stack
|
||||
SSL_add_file_cert_subjects_to_stack
|
||||
SSL_alert_desc_string
|
||||
SSL_alert_desc_string_long
|
||||
SSL_alert_type_string
|
||||
SSL_alert_type_string_long
|
||||
SSL_cache_hit
|
||||
SSL_callback_ctrl
|
||||
SSL_check_private_key
|
||||
SSL_clear
|
||||
SSL_clear_chain_certs
|
||||
SSL_connect
|
||||
SSL_copy_session_id
|
||||
SSL_ctrl
|
||||
SSL_do_handshake
|
||||
SSL_dup
|
||||
SSL_dup_CA_list
|
||||
SSL_export_keying_material
|
||||
SSL_free
|
||||
SSL_get0_alpn_selected
|
||||
SSL_get0_chain_certs
|
||||
SSL_get0_next_proto_negotiated
|
||||
SSL_get0_param
|
||||
SSL_get1_session
|
||||
SSL_get1_supported_ciphers
|
||||
SSL_get_SSL_CTX
|
||||
SSL_get_certificate
|
||||
SSL_get_cipher_list
|
||||
SSL_get_ciphers
|
||||
SSL_get_client_CA_list
|
||||
SSL_get_client_ciphers
|
||||
SSL_get_client_random
|
||||
SSL_get_current_cipher
|
||||
SSL_get_current_compression
|
||||
SSL_get_current_expansion
|
||||
SSL_get_default_timeout
|
||||
SSL_get_error
|
||||
SSL_get_ex_data
|
||||
SSL_get_ex_data_X509_STORE_CTX_idx
|
||||
SSL_get_ex_new_index
|
||||
SSL_get_fd
|
||||
SSL_get_finished
|
||||
SSL_get_info_callback
|
||||
SSL_get_max_proto_version
|
||||
SSL_get_min_proto_version
|
||||
SSL_get_peer_cert_chain
|
||||
SSL_get_peer_certificate
|
||||
SSL_get_peer_finished
|
||||
SSL_get_privatekey
|
||||
SSL_get_quiet_shutdown
|
||||
SSL_get_rbio
|
||||
SSL_get_read_ahead
|
||||
SSL_get_rfd
|
||||
SSL_get_selected_srtp_profile
|
||||
SSL_get_server_random
|
||||
SSL_get_servername
|
||||
SSL_get_servername_type
|
||||
SSL_get_session
|
||||
SSL_get_shared_ciphers
|
||||
SSL_get_shutdown
|
||||
SSL_get_srtp_profiles
|
||||
SSL_get_ssl_method
|
||||
SSL_get_verify_callback
|
||||
SSL_get_verify_depth
|
||||
SSL_get_verify_mode
|
||||
SSL_get_verify_result
|
||||
SSL_get_version
|
||||
SSL_get_wbio
|
||||
SSL_get_wfd
|
||||
SSL_has_matching_session_id
|
||||
SSL_is_server
|
||||
SSL_library_init
|
||||
SSL_load_client_CA_file
|
||||
SSL_load_error_strings
|
||||
SSL_new
|
||||
SSL_peek
|
||||
SSL_pending
|
||||
SSL_read
|
||||
SSL_renegotiate
|
||||
SSL_renegotiate_abbreviated
|
||||
SSL_renegotiate_pending
|
||||
SSL_rstate_string
|
||||
SSL_rstate_string_long
|
||||
SSL_select_next_proto
|
||||
SSL_set0_chain
|
||||
SSL_set1_chain
|
||||
SSL_set1_groups
|
||||
SSL_set1_groups_list
|
||||
SSL_set1_host
|
||||
SSL_set1_param
|
||||
SSL_set_SSL_CTX
|
||||
SSL_set_accept_state
|
||||
SSL_set_alpn_protos
|
||||
SSL_set_bio
|
||||
SSL_set_cipher_list
|
||||
SSL_set_client_CA_list
|
||||
SSL_set_connect_state
|
||||
SSL_set_debug
|
||||
SSL_set_ex_data
|
||||
SSL_set_fd
|
||||
SSL_set_generate_session_id
|
||||
SSL_set_info_callback
|
||||
SSL_set_max_proto_version
|
||||
SSL_set_min_proto_version
|
||||
SSL_set_msg_callback
|
||||
SSL_set_purpose
|
||||
SSL_set_quiet_shutdown
|
||||
SSL_set_read_ahead
|
||||
SSL_set_rfd
|
||||
SSL_set_session
|
||||
SSL_set_session_id_context
|
||||
SSL_set_session_secret_cb
|
||||
SSL_set_session_ticket_ext
|
||||
SSL_set_session_ticket_ext_cb
|
||||
SSL_set_shutdown
|
||||
SSL_set_ssl_method
|
||||
SSL_set_state
|
||||
SSL_set_tlsext_use_srtp
|
||||
SSL_set_tmp_dh_callback
|
||||
SSL_set_tmp_ecdh_callback
|
||||
SSL_set_tmp_rsa_callback
|
||||
SSL_set_trust
|
||||
SSL_set_verify
|
||||
SSL_set_verify_depth
|
||||
SSL_set_verify_result
|
||||
SSL_set_wfd
|
||||
SSL_shutdown
|
||||
SSL_state
|
||||
SSL_state_string
|
||||
SSL_state_string_long
|
||||
SSL_up_ref
|
||||
SSL_use_PrivateKey
|
||||
SSL_use_PrivateKey_ASN1
|
||||
SSL_use_PrivateKey_file
|
||||
SSL_use_RSAPrivateKey
|
||||
SSL_use_RSAPrivateKey_ASN1
|
||||
SSL_use_RSAPrivateKey_file
|
||||
SSL_use_certificate
|
||||
SSL_use_certificate_ASN1
|
||||
SSL_use_certificate_file
|
||||
SSL_version
|
||||
SSL_version_str
|
||||
SSL_want
|
||||
SSL_write
|
||||
OPENSSL_init_ssl
|
||||
125
externals/libressl/ssl/ssl_algs.c
vendored
Executable file
125
externals/libressl/ssl/ssl_algs.c
vendored
Executable file
@@ -0,0 +1,125 @@
|
||||
/* $OpenBSD: ssl_algs.c,v 1.28 2019/04/04 16:44:24 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
int
|
||||
SSL_library_init(void)
|
||||
{
|
||||
|
||||
#ifndef OPENSSL_NO_DES
|
||||
EVP_add_cipher(EVP_des_cbc());
|
||||
EVP_add_cipher(EVP_des_ede3_cbc());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
EVP_add_cipher(EVP_rc4());
|
||||
#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__))
|
||||
EVP_add_cipher(EVP_rc4_hmac_md5());
|
||||
#endif
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RC2
|
||||
EVP_add_cipher(EVP_rc2_cbc());
|
||||
/* Not actually used for SSL/TLS but this makes PKCS#12 work
|
||||
* if an application only calls SSL_library_init().
|
||||
*/
|
||||
EVP_add_cipher(EVP_rc2_40_cbc());
|
||||
#endif
|
||||
EVP_add_cipher(EVP_aes_128_cbc());
|
||||
EVP_add_cipher(EVP_aes_192_cbc());
|
||||
EVP_add_cipher(EVP_aes_256_cbc());
|
||||
EVP_add_cipher(EVP_aes_128_gcm());
|
||||
EVP_add_cipher(EVP_aes_256_gcm());
|
||||
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
|
||||
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
EVP_add_cipher(EVP_camellia_128_cbc());
|
||||
EVP_add_cipher(EVP_camellia_256_cbc());
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
EVP_add_cipher(EVP_gost2814789_cfb64());
|
||||
EVP_add_cipher(EVP_gost2814789_cnt());
|
||||
#endif
|
||||
|
||||
EVP_add_digest(EVP_md5());
|
||||
EVP_add_digest(EVP_md5_sha1());
|
||||
EVP_add_digest_alias(SN_md5, "ssl2-md5");
|
||||
EVP_add_digest_alias(SN_md5, "ssl3-md5");
|
||||
|
||||
EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
|
||||
EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
|
||||
EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
|
||||
EVP_add_digest(EVP_sha224());
|
||||
EVP_add_digest(EVP_sha256());
|
||||
EVP_add_digest(EVP_sha384());
|
||||
EVP_add_digest(EVP_sha512());
|
||||
EVP_add_digest(EVP_ecdsa());
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
EVP_add_digest(EVP_gostr341194());
|
||||
EVP_add_digest(EVP_gost2814789imit());
|
||||
EVP_add_digest(EVP_streebog256());
|
||||
EVP_add_digest(EVP_streebog512());
|
||||
#endif
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
431
externals/libressl/ssl/ssl_asn1.c
vendored
Executable file
431
externals/libressl/ssl/ssl_asn1.c
vendored
Executable file
@@ -0,0 +1,431 @@
|
||||
/* $OpenBSD: ssl_asn1.c,v 1.57 2018/08/27 16:42:48 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
#define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)
|
||||
#define SSLASN1_TIME_TAG (SSLASN1_TAG | 1)
|
||||
#define SSLASN1_TIMEOUT_TAG (SSLASN1_TAG | 2)
|
||||
#define SSLASN1_PEER_CERT_TAG (SSLASN1_TAG | 3)
|
||||
#define SSLASN1_SESSION_ID_CTX_TAG (SSLASN1_TAG | 4)
|
||||
#define SSLASN1_VERIFY_RESULT_TAG (SSLASN1_TAG | 5)
|
||||
#define SSLASN1_HOSTNAME_TAG (SSLASN1_TAG | 6)
|
||||
#define SSLASN1_LIFETIME_TAG (SSLASN1_TAG | 9)
|
||||
#define SSLASN1_TICKET_TAG (SSLASN1_TAG | 10)
|
||||
|
||||
static uint64_t
|
||||
time_max(void)
|
||||
{
|
||||
if (sizeof(time_t) == sizeof(int32_t))
|
||||
return INT32_MAX;
|
||||
if (sizeof(time_t) == sizeof(int64_t))
|
||||
return INT64_MAX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len,
|
||||
int ticket_encoding)
|
||||
{
|
||||
CBB cbb, session, cipher_suite, session_id, master_key, time, timeout;
|
||||
CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket, value;
|
||||
unsigned char *peer_cert_bytes = NULL;
|
||||
int len, rv = 0;
|
||||
uint16_t cid;
|
||||
|
||||
if (!CBB_init(&cbb, 0))
|
||||
goto err;
|
||||
|
||||
if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE))
|
||||
goto err;
|
||||
|
||||
/* Session ASN1 version. */
|
||||
if (!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION))
|
||||
goto err;
|
||||
|
||||
/* TLS/SSL protocol version. */
|
||||
if (s->ssl_version < 0)
|
||||
goto err;
|
||||
if (!CBB_add_asn1_uint64(&session, s->ssl_version))
|
||||
goto err;
|
||||
|
||||
/* Cipher suite ID. */
|
||||
/* XXX - require cipher to be non-NULL or always/only use cipher_id. */
|
||||
cid = (uint16_t)(s->cipher_id & 0xffff);
|
||||
if (s->cipher != NULL)
|
||||
cid = ssl3_cipher_get_value(s->cipher);
|
||||
if (!CBB_add_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&cipher_suite, cid))
|
||||
goto err;
|
||||
|
||||
/* Session ID - zero length for a ticket. */
|
||||
if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&session_id, s->session_id,
|
||||
ticket_encoding ? 0 : s->session_id_length))
|
||||
goto err;
|
||||
|
||||
/* Master key. */
|
||||
if (!CBB_add_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&master_key, s->master_key, s->master_key_length))
|
||||
goto err;
|
||||
|
||||
/* Time [1]. */
|
||||
if (s->time != 0) {
|
||||
if (s->time < 0)
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&session, &time, SSLASN1_TIME_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1_uint64(&time, s->time))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Timeout [2]. */
|
||||
if (s->timeout != 0) {
|
||||
if (s->timeout < 0)
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&session, &timeout, SSLASN1_TIMEOUT_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1_uint64(&timeout, s->timeout))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Peer certificate [3]. */
|
||||
if (s->peer != NULL) {
|
||||
if ((len = i2d_X509(s->peer, &peer_cert_bytes)) <= 0)
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&peer_cert, peer_cert_bytes, len))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Session ID context [4]. */
|
||||
/* XXX - Actually handle this as optional? */
|
||||
if (!CBB_add_asn1(&session, &sidctx, SSLASN1_SESSION_ID_CTX_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&sidctx, &value, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&value, s->sid_ctx, s->sid_ctx_length))
|
||||
goto err;
|
||||
|
||||
/* Verify result [5]. */
|
||||
if (s->verify_result != X509_V_OK) {
|
||||
if (s->verify_result < 0)
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&session, &verify_result,
|
||||
SSLASN1_VERIFY_RESULT_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1_uint64(&verify_result, s->verify_result))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Hostname [6]. */
|
||||
if (s->tlsext_hostname != NULL) {
|
||||
if (!CBB_add_asn1(&session, &hostname, SSLASN1_HOSTNAME_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&hostname, &value, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&value, (const uint8_t *)s->tlsext_hostname,
|
||||
strlen(s->tlsext_hostname)))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* PSK identity hint [7]. */
|
||||
/* PSK identity [8]. */
|
||||
|
||||
/* Ticket lifetime hint [9]. */
|
||||
if (s->tlsext_tick_lifetime_hint > 0) {
|
||||
if (!CBB_add_asn1(&session, &lifetime, SSLASN1_LIFETIME_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1_uint64(&lifetime,
|
||||
s->tlsext_tick_lifetime_hint))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Ticket [10]. */
|
||||
if (s->tlsext_tick != NULL) {
|
||||
if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG))
|
||||
goto err;
|
||||
if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&value, s->tlsext_tick, s->tlsext_ticklen))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Compression method [11]. */
|
||||
/* SRP username [12]. */
|
||||
|
||||
if (!CBB_finish(&cbb, out, out_len))
|
||||
goto err;
|
||||
|
||||
rv = 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
free(peer_cert_bytes);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len)
|
||||
{
|
||||
if (ss == NULL)
|
||||
return 0;
|
||||
|
||||
if (ss->cipher == NULL && ss->cipher_id == 0)
|
||||
return 0;
|
||||
|
||||
return SSL_SESSION_encode(ss, out, out_len, 1);
|
||||
}
|
||||
|
||||
int
|
||||
i2d_SSL_SESSION(SSL_SESSION *ss, unsigned char **pp)
|
||||
{
|
||||
unsigned char *data = NULL;
|
||||
size_t data_len = 0;
|
||||
int rv = -1;
|
||||
|
||||
if (ss == NULL)
|
||||
return 0;
|
||||
|
||||
if (ss->cipher == NULL && ss->cipher_id == 0)
|
||||
return 0;
|
||||
|
||||
if (!SSL_SESSION_encode(ss, &data, &data_len, 0))
|
||||
goto err;
|
||||
|
||||
if (data_len > INT_MAX)
|
||||
goto err;
|
||||
|
||||
if (pp != NULL) {
|
||||
if (*pp == NULL) {
|
||||
*pp = data;
|
||||
data = NULL;
|
||||
} else {
|
||||
memcpy(*pp, data, data_len);
|
||||
*pp += data_len;
|
||||
}
|
||||
}
|
||||
|
||||
rv = (int)data_len;
|
||||
|
||||
err:
|
||||
freezero(data, data_len);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSL_SESSION *
|
||||
d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
|
||||
{
|
||||
CBS cbs, session, cipher_suite, session_id, master_key, peer_cert;
|
||||
CBS hostname, ticket;
|
||||
uint64_t version, tls_version, stime, timeout, verify_result, lifetime;
|
||||
const unsigned char *peer_cert_bytes;
|
||||
uint16_t cipher_value;
|
||||
SSL_SESSION *s = NULL;
|
||||
size_t data_len;
|
||||
int present;
|
||||
|
||||
if (a != NULL)
|
||||
s = *a;
|
||||
|
||||
if (s == NULL) {
|
||||
if ((s = SSL_SESSION_new()) == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
CBS_init(&cbs, *pp, length);
|
||||
|
||||
if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE))
|
||||
goto err;
|
||||
|
||||
/* Session ASN1 version. */
|
||||
if (!CBS_get_asn1_uint64(&session, &version))
|
||||
goto err;
|
||||
if (version != SSL_SESSION_ASN1_VERSION)
|
||||
goto err;
|
||||
|
||||
/* TLS/SSL Protocol Version. */
|
||||
if (!CBS_get_asn1_uint64(&session, &tls_version))
|
||||
goto err;
|
||||
if (tls_version > INT_MAX)
|
||||
goto err;
|
||||
s->ssl_version = (int)tls_version;
|
||||
|
||||
/* Cipher suite. */
|
||||
if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBS_get_u16(&cipher_suite, &cipher_value))
|
||||
goto err;
|
||||
if (CBS_len(&cipher_suite) != 0)
|
||||
goto err;
|
||||
|
||||
/* XXX - populate cipher instead? */
|
||||
s->cipher = NULL;
|
||||
s->cipher_id = SSL3_CK_ID | cipher_value;
|
||||
|
||||
/* Session ID. */
|
||||
if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id),
|
||||
&data_len))
|
||||
goto err;
|
||||
if (data_len > UINT_MAX)
|
||||
goto err;
|
||||
s->session_id_length = (unsigned int)data_len;
|
||||
|
||||
/* Master key. */
|
||||
if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
|
||||
goto err;
|
||||
if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key),
|
||||
&data_len))
|
||||
goto err;
|
||||
if (data_len > INT_MAX)
|
||||
goto err;
|
||||
s->master_key_length = (int)data_len;
|
||||
|
||||
/* Time [1]. */
|
||||
s->time = time(NULL);
|
||||
if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG,
|
||||
0))
|
||||
goto err;
|
||||
if (stime > time_max())
|
||||
goto err;
|
||||
if (stime != 0)
|
||||
s->time = (time_t)stime;
|
||||
|
||||
/* Timeout [2]. */
|
||||
s->timeout = 3;
|
||||
if (!CBS_get_optional_asn1_uint64(&session, &timeout,
|
||||
SSLASN1_TIMEOUT_TAG, 0))
|
||||
goto err;
|
||||
if (timeout > LONG_MAX)
|
||||
goto err;
|
||||
if (timeout != 0)
|
||||
s->timeout = (long)timeout;
|
||||
|
||||
/* Peer certificate [3]. */
|
||||
X509_free(s->peer);
|
||||
s->peer = NULL;
|
||||
if (!CBS_get_optional_asn1(&session, &peer_cert, &present,
|
||||
SSLASN1_PEER_CERT_TAG))
|
||||
goto err;
|
||||
if (present) {
|
||||
data_len = CBS_len(&peer_cert);
|
||||
if (data_len > LONG_MAX)
|
||||
goto err;
|
||||
peer_cert_bytes = CBS_data(&peer_cert);
|
||||
if (d2i_X509(&s->peer, &peer_cert_bytes,
|
||||
(long)data_len) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Session ID context [4]. */
|
||||
s->sid_ctx_length = 0;
|
||||
if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present,
|
||||
SSLASN1_SESSION_ID_CTX_TAG))
|
||||
goto err;
|
||||
if (present) {
|
||||
if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx,
|
||||
sizeof(s->sid_ctx), &data_len))
|
||||
goto err;
|
||||
if (data_len > UINT_MAX)
|
||||
goto err;
|
||||
s->sid_ctx_length = (unsigned int)data_len;
|
||||
}
|
||||
|
||||
/* Verify result [5]. */
|
||||
s->verify_result = X509_V_OK;
|
||||
if (!CBS_get_optional_asn1_uint64(&session, &verify_result,
|
||||
SSLASN1_VERIFY_RESULT_TAG, X509_V_OK))
|
||||
goto err;
|
||||
if (verify_result > LONG_MAX)
|
||||
goto err;
|
||||
s->verify_result = (long)verify_result;
|
||||
|
||||
/* Hostname [6]. */
|
||||
free(s->tlsext_hostname);
|
||||
s->tlsext_hostname = NULL;
|
||||
if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present,
|
||||
SSLASN1_HOSTNAME_TAG))
|
||||
goto err;
|
||||
if (present) {
|
||||
if (CBS_contains_zero_byte(&hostname))
|
||||
goto err;
|
||||
if (!CBS_strdup(&hostname, &s->tlsext_hostname))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* PSK identity hint [7]. */
|
||||
/* PSK identity [8]. */
|
||||
|
||||
/* Ticket lifetime [9]. */
|
||||
s->tlsext_tick_lifetime_hint = 0;
|
||||
/* XXX - tlsext_ticklen is not yet set... */
|
||||
if (s->tlsext_ticklen > 0 && s->session_id_length > 0)
|
||||
s->tlsext_tick_lifetime_hint = -1;
|
||||
if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
|
||||
SSLASN1_LIFETIME_TAG, 0))
|
||||
goto err;
|
||||
if (lifetime > LONG_MAX)
|
||||
goto err;
|
||||
if (lifetime > 0)
|
||||
s->tlsext_tick_lifetime_hint = (long)lifetime;
|
||||
|
||||
/* Ticket [10]. */
|
||||
free(s->tlsext_tick);
|
||||
s->tlsext_tick = NULL;
|
||||
if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present,
|
||||
SSLASN1_TICKET_TAG))
|
||||
goto err;
|
||||
if (present) {
|
||||
if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Compression method [11]. */
|
||||
/* SRP username [12]. */
|
||||
|
||||
*pp = CBS_data(&cbs);
|
||||
|
||||
if (a != NULL)
|
||||
*a = s;
|
||||
|
||||
return (s);
|
||||
|
||||
err:
|
||||
ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp));
|
||||
|
||||
if (s != NULL && (a == NULL || *a != s))
|
||||
SSL_SESSION_free(s);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
790
externals/libressl/ssl/ssl_both.c
vendored
Executable file
790
externals/libressl/ssl/ssl_both.c
vendored
Executable file
@@ -0,0 +1,790 @@
|
||||
/* $OpenBSD: ssl_both.c,v 1.20 2020/09/24 18:12:00 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECC cipher suite support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
/*
|
||||
* Send s->internal->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
|
||||
* SSL3_RT_CHANGE_CIPHER_SPEC).
|
||||
*/
|
||||
int
|
||||
ssl3_do_write(SSL *s, int type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ssl3_write_bytes(s, type, &s->internal->init_buf->data[s->internal->init_off],
|
||||
s->internal->init_num);
|
||||
if (ret < 0)
|
||||
return (-1);
|
||||
|
||||
if (type == SSL3_RT_HANDSHAKE)
|
||||
/*
|
||||
* Should not be done for 'Hello Request's, but in that case
|
||||
* we'll ignore the result anyway.
|
||||
*/
|
||||
tls1_transcript_record(s,
|
||||
(unsigned char *)&s->internal->init_buf->data[s->internal->init_off], ret);
|
||||
|
||||
if (ret == s->internal->init_num) {
|
||||
if (s->internal->msg_callback)
|
||||
s->internal->msg_callback(1, s->version, type, s->internal->init_buf->data,
|
||||
(size_t)(s->internal->init_off + s->internal->init_num), s,
|
||||
s->internal->msg_callback_arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
s->internal->init_off += ret;
|
||||
s->internal->init_num -= ret;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
|
||||
{
|
||||
CBB cbb, finished;
|
||||
int md_len;
|
||||
|
||||
memset(&cbb, 0, sizeof(cbb));
|
||||
|
||||
if (S3I(s)->hs.state == a) {
|
||||
md_len = TLS1_FINISH_MAC_LENGTH;
|
||||
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
|
||||
|
||||
if (tls1_final_finish_mac(s, sender, slen,
|
||||
S3I(s)->tmp.finish_md) != md_len)
|
||||
return (0);
|
||||
S3I(s)->tmp.finish_md_len = md_len;
|
||||
|
||||
/* Copy finished so we can use it for renegotiation checks. */
|
||||
if (s->internal->type == SSL_ST_CONNECT) {
|
||||
memcpy(S3I(s)->previous_client_finished,
|
||||
S3I(s)->tmp.finish_md, md_len);
|
||||
S3I(s)->previous_client_finished_len = md_len;
|
||||
} else {
|
||||
memcpy(S3I(s)->previous_server_finished,
|
||||
S3I(s)->tmp.finish_md, md_len);
|
||||
S3I(s)->previous_server_finished_len = md_len;
|
||||
}
|
||||
|
||||
if (!ssl3_handshake_msg_start(s, &cbb, &finished,
|
||||
SSL3_MT_FINISHED))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&finished, S3I(s)->tmp.finish_md, md_len))
|
||||
goto err;
|
||||
if (!ssl3_handshake_msg_finish(s, &cbb))
|
||||
goto err;
|
||||
|
||||
S3I(s)->hs.state = b;
|
||||
}
|
||||
|
||||
return (ssl3_handshake_write(s));
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
|
||||
* so far.
|
||||
*/
|
||||
static void
|
||||
ssl3_take_mac(SSL *s)
|
||||
{
|
||||
const char *sender;
|
||||
int slen;
|
||||
|
||||
/*
|
||||
* If no new cipher setup return immediately: other functions will
|
||||
* set the appropriate error.
|
||||
*/
|
||||
if (S3I(s)->hs.new_cipher == NULL)
|
||||
return;
|
||||
|
||||
if (S3I(s)->hs.state & SSL_ST_CONNECT) {
|
||||
sender = TLS_MD_SERVER_FINISH_CONST;
|
||||
slen = TLS_MD_SERVER_FINISH_CONST_SIZE;
|
||||
} else {
|
||||
sender = TLS_MD_CLIENT_FINISH_CONST;
|
||||
slen = TLS_MD_CLIENT_FINISH_CONST_SIZE;
|
||||
}
|
||||
|
||||
S3I(s)->tmp.peer_finish_md_len =
|
||||
tls1_final_finish_mac(s, sender, slen,
|
||||
S3I(s)->tmp.peer_finish_md);
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_get_finished(SSL *s, int a, int b)
|
||||
{
|
||||
int al, ok, md_len;
|
||||
long n;
|
||||
CBS cbs;
|
||||
|
||||
/* should actually be 36+4 :-) */
|
||||
n = ssl3_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
|
||||
if (!ok)
|
||||
return ((int)n);
|
||||
|
||||
/* If this occurs, we have missed a message */
|
||||
if (!S3I(s)->change_cipher_spec) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
|
||||
goto f_err;
|
||||
}
|
||||
S3I(s)->change_cipher_spec = 0;
|
||||
|
||||
md_len = TLS1_FINISH_MAC_LENGTH;
|
||||
|
||||
if (n < 0) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
CBS_init(&cbs, s->internal->init_msg, n);
|
||||
|
||||
if (S3I(s)->tmp.peer_finish_md_len != md_len ||
|
||||
CBS_len(&cbs) != md_len) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
|
||||
al = SSL_AD_DECRYPT_ERROR;
|
||||
SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
/* Copy finished so we can use it for renegotiation checks. */
|
||||
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
|
||||
if (s->internal->type == SSL_ST_ACCEPT) {
|
||||
memcpy(S3I(s)->previous_client_finished,
|
||||
S3I(s)->tmp.peer_finish_md, md_len);
|
||||
S3I(s)->previous_client_finished_len = md_len;
|
||||
} else {
|
||||
memcpy(S3I(s)->previous_server_finished,
|
||||
S3I(s)->tmp.peer_finish_md, md_len);
|
||||
S3I(s)->previous_server_finished_len = md_len;
|
||||
}
|
||||
|
||||
return (1);
|
||||
f_err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* for these 2 messages, we need to
|
||||
* ssl->enc_read_ctx re-init
|
||||
* ssl->s3->internal->read_sequence zero
|
||||
* ssl->s3->internal->read_mac_secret re-init
|
||||
* ssl->session->read_sym_enc assign
|
||||
* ssl->session->read_hash assign
|
||||
*/
|
||||
int
|
||||
ssl3_send_change_cipher_spec(SSL *s, int a, int b)
|
||||
{
|
||||
size_t outlen;
|
||||
CBB cbb;
|
||||
|
||||
memset(&cbb, 0, sizeof(cbb));
|
||||
|
||||
if (S3I(s)->hs.state == a) {
|
||||
if (!CBB_init_fixed(&cbb, s->internal->init_buf->data,
|
||||
s->internal->init_buf->length))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&cbb, SSL3_MT_CCS))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, NULL, &outlen))
|
||||
goto err;
|
||||
|
||||
if (outlen > INT_MAX)
|
||||
goto err;
|
||||
|
||||
s->internal->init_num = (int)outlen;
|
||||
s->internal->init_off = 0;
|
||||
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
D1I(s)->handshake_write_seq =
|
||||
D1I(s)->next_handshake_write_seq;
|
||||
dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
|
||||
D1I(s)->handshake_write_seq, 0, 0);
|
||||
dtls1_buffer_message(s, 1);
|
||||
}
|
||||
|
||||
S3I(s)->hs.state = b;
|
||||
}
|
||||
|
||||
/* SSL3_ST_CW_CHANGE_B */
|
||||
return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl3_add_cert(CBB *cbb, X509 *x)
|
||||
{
|
||||
unsigned char *data;
|
||||
int cert_len;
|
||||
int ret = 0;
|
||||
CBB cert;
|
||||
|
||||
if ((cert_len = i2d_X509(x, NULL)) < 0)
|
||||
goto err;
|
||||
|
||||
if (!CBB_add_u24_length_prefixed(cbb, &cert))
|
||||
goto err;
|
||||
if (!CBB_add_space(&cert, &data, cert_len))
|
||||
goto err;
|
||||
if (i2d_X509(x, &data) < 0)
|
||||
goto err;
|
||||
if (!CBB_flush(cbb))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
|
||||
{
|
||||
X509_STORE_CTX *xs_ctx = NULL;
|
||||
STACK_OF(X509) *chain;
|
||||
CBB cert_list;
|
||||
X509 *x;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
|
||||
goto err;
|
||||
|
||||
/* Send an empty certificate list when no certificate is available. */
|
||||
if (cpk == NULL)
|
||||
goto done;
|
||||
|
||||
if ((chain = cpk->chain) == NULL)
|
||||
chain = s->ctx->extra_certs;
|
||||
|
||||
if (chain != NULL || (s->internal->mode & SSL_MODE_NO_AUTO_CHAIN)) {
|
||||
if (!ssl3_add_cert(&cert_list, cpk->x509))
|
||||
goto err;
|
||||
} else {
|
||||
if ((xs_ctx = X509_STORE_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store,
|
||||
cpk->x509, NULL)) {
|
||||
SSLerror(s, ERR_R_X509_LIB);
|
||||
goto err;
|
||||
}
|
||||
X509_verify_cert(xs_ctx);
|
||||
ERR_clear_error();
|
||||
chain = xs_ctx->chain;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_X509_num(chain); i++) {
|
||||
x = sk_X509_value(chain, i);
|
||||
if (!ssl3_add_cert(&cert_list, x))
|
||||
goto err;
|
||||
}
|
||||
|
||||
done:
|
||||
if (!CBB_flush(cbb))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
X509_STORE_CTX_free(xs_ctx);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain handshake message of message type 'mt' (any if mt == -1),
|
||||
* maximum acceptable body length 'max'.
|
||||
* The first four bytes (msg_type and length) are read in state 'st1',
|
||||
* the body is read in state 'stn'.
|
||||
*/
|
||||
long
|
||||
ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
|
||||
{
|
||||
unsigned char *p;
|
||||
uint32_t l;
|
||||
long n;
|
||||
int i, al;
|
||||
CBS cbs;
|
||||
uint8_t u8;
|
||||
|
||||
if (SSL_IS_DTLS(s))
|
||||
return (dtls1_get_message(s, st1, stn, mt, max, ok));
|
||||
|
||||
if (S3I(s)->tmp.reuse_message) {
|
||||
S3I(s)->tmp.reuse_message = 0;
|
||||
if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
|
||||
goto f_err;
|
||||
}
|
||||
*ok = 1;
|
||||
s->internal->init_msg = s->internal->init_buf->data + 4;
|
||||
s->internal->init_num = (int)S3I(s)->tmp.message_size;
|
||||
return s->internal->init_num;
|
||||
}
|
||||
|
||||
p = (unsigned char *)s->internal->init_buf->data;
|
||||
|
||||
/* s->internal->init_num < 4 */
|
||||
if (S3I(s)->hs.state == st1) {
|
||||
int skip_message;
|
||||
|
||||
do {
|
||||
while (s->internal->init_num < 4) {
|
||||
i = s->method->internal->ssl_read_bytes(s,
|
||||
SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
|
||||
4 - s->internal->init_num, 0);
|
||||
if (i <= 0) {
|
||||
s->internal->rwstate = SSL_READING;
|
||||
*ok = 0;
|
||||
return i;
|
||||
}
|
||||
s->internal->init_num += i;
|
||||
}
|
||||
|
||||
skip_message = 0;
|
||||
if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
|
||||
/*
|
||||
* The server may always send 'Hello Request'
|
||||
* messages -- we are doing a handshake anyway
|
||||
* now, so ignore them if their format is
|
||||
* correct. Does not count for 'Finished' MAC.
|
||||
*/
|
||||
if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
|
||||
s->internal->init_num = 0;
|
||||
skip_message = 1;
|
||||
|
||||
if (s->internal->msg_callback)
|
||||
s->internal->msg_callback(0, s->version,
|
||||
SSL3_RT_HANDSHAKE, p, 4, s,
|
||||
s->internal->msg_callback_arg);
|
||||
}
|
||||
}
|
||||
} while (skip_message);
|
||||
|
||||
/* s->internal->init_num == 4 */
|
||||
|
||||
if ((mt >= 0) && (*p != mt)) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
CBS_init(&cbs, p, 4);
|
||||
if (!CBS_get_u8(&cbs, &u8) ||
|
||||
!CBS_get_u24(&cbs, &l)) {
|
||||
SSLerror(s, ERR_R_BUF_LIB);
|
||||
goto err;
|
||||
}
|
||||
S3I(s)->tmp.message_type = u8;
|
||||
|
||||
if (l > (unsigned long)max) {
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
|
||||
goto f_err;
|
||||
}
|
||||
if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
|
||||
SSLerror(s, ERR_R_BUF_LIB);
|
||||
goto err;
|
||||
}
|
||||
S3I(s)->tmp.message_size = l;
|
||||
S3I(s)->hs.state = stn;
|
||||
|
||||
s->internal->init_msg = s->internal->init_buf->data + 4;
|
||||
s->internal->init_num = 0;
|
||||
}
|
||||
|
||||
/* next state (stn) */
|
||||
p = s->internal->init_msg;
|
||||
n = S3I(s)->tmp.message_size - s->internal->init_num;
|
||||
while (n > 0) {
|
||||
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
|
||||
&p[s->internal->init_num], n, 0);
|
||||
if (i <= 0) {
|
||||
s->internal->rwstate = SSL_READING;
|
||||
*ok = 0;
|
||||
return i;
|
||||
}
|
||||
s->internal->init_num += i;
|
||||
n -= i;
|
||||
}
|
||||
|
||||
/* If receiving Finished, record MAC of prior handshake messages for
|
||||
* Finished verification. */
|
||||
if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
|
||||
ssl3_take_mac(s);
|
||||
|
||||
/* Feed this message into MAC computation. */
|
||||
if (s->internal->mac_packet) {
|
||||
tls1_transcript_record(s, (unsigned char *)s->internal->init_buf->data,
|
||||
s->internal->init_num + 4);
|
||||
|
||||
if (s->internal->msg_callback)
|
||||
s->internal->msg_callback(0, s->version,
|
||||
SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
|
||||
(size_t)s->internal->init_num + 4, s,
|
||||
s->internal->msg_callback_arg);
|
||||
}
|
||||
|
||||
*ok = 1;
|
||||
return (s->internal->init_num);
|
||||
|
||||
f_err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
err:
|
||||
*ok = 0;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_type(X509 *x, EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_PKEY *pk;
|
||||
int ret = -1, i;
|
||||
|
||||
if (pkey == NULL)
|
||||
pk = X509_get_pubkey(x);
|
||||
else
|
||||
pk = pkey;
|
||||
if (pk == NULL)
|
||||
goto err;
|
||||
|
||||
i = pk->type;
|
||||
if (i == EVP_PKEY_RSA) {
|
||||
ret = SSL_PKEY_RSA;
|
||||
} else if (i == EVP_PKEY_EC) {
|
||||
ret = SSL_PKEY_ECC;
|
||||
} else if (i == NID_id_GostR3410_2001 ||
|
||||
i == NID_id_GostR3410_2001_cc) {
|
||||
ret = SSL_PKEY_GOST01;
|
||||
}
|
||||
|
||||
err:
|
||||
if (!pkey)
|
||||
EVP_PKEY_free(pk);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_verify_alarm_type(long type)
|
||||
{
|
||||
int al;
|
||||
|
||||
switch (type) {
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL:
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
|
||||
al = SSL_AD_UNKNOWN_CA;
|
||||
break;
|
||||
case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
|
||||
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
|
||||
case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
|
||||
case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
|
||||
case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
case X509_V_ERR_CRL_NOT_YET_VALID:
|
||||
case X509_V_ERR_CERT_UNTRUSTED:
|
||||
case X509_V_ERR_CERT_REJECTED:
|
||||
al = SSL_AD_BAD_CERTIFICATE;
|
||||
break;
|
||||
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
|
||||
case X509_V_ERR_CRL_SIGNATURE_FAILURE:
|
||||
al = SSL_AD_DECRYPT_ERROR;
|
||||
break;
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
case X509_V_ERR_CRL_HAS_EXPIRED:
|
||||
al = SSL_AD_CERTIFICATE_EXPIRED;
|
||||
break;
|
||||
case X509_V_ERR_CERT_REVOKED:
|
||||
al = SSL_AD_CERTIFICATE_REVOKED;
|
||||
break;
|
||||
case X509_V_ERR_OUT_OF_MEM:
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
break;
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
|
||||
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
|
||||
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
|
||||
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
|
||||
case X509_V_ERR_INVALID_CA:
|
||||
al = SSL_AD_UNKNOWN_CA;
|
||||
break;
|
||||
case X509_V_ERR_APPLICATION_VERIFICATION:
|
||||
al = SSL_AD_HANDSHAKE_FAILURE;
|
||||
break;
|
||||
case X509_V_ERR_INVALID_PURPOSE:
|
||||
al = SSL_AD_UNSUPPORTED_CERTIFICATE;
|
||||
break;
|
||||
default:
|
||||
al = SSL_AD_CERTIFICATE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return (al);
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_setup_init_buffer(SSL *s)
|
||||
{
|
||||
BUF_MEM *buf = NULL;
|
||||
|
||||
if (s->internal->init_buf != NULL)
|
||||
return (1);
|
||||
|
||||
if ((buf = BUF_MEM_new()) == NULL)
|
||||
goto err;
|
||||
if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
|
||||
goto err;
|
||||
|
||||
s->internal->init_buf = buf;
|
||||
return (1);
|
||||
|
||||
err:
|
||||
BUF_MEM_free(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_release_init_buffer(SSL *s)
|
||||
{
|
||||
BUF_MEM_free(s->internal->init_buf);
|
||||
s->internal->init_buf = NULL;
|
||||
s->internal->init_msg = NULL;
|
||||
s->internal->init_num = 0;
|
||||
s->internal->init_off = 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_setup_read_buffer(SSL *s)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t len, align, headerlen;
|
||||
|
||||
if (SSL_IS_DTLS(s))
|
||||
headerlen = DTLS1_RT_HEADER_LENGTH;
|
||||
else
|
||||
headerlen = SSL3_RT_HEADER_LENGTH;
|
||||
|
||||
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
|
||||
|
||||
if (S3I(s)->rbuf.buf == NULL) {
|
||||
len = SSL3_RT_MAX_PLAIN_LENGTH +
|
||||
SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
if ((p = calloc(1, len)) == NULL)
|
||||
goto err;
|
||||
S3I(s)->rbuf.buf = p;
|
||||
S3I(s)->rbuf.len = len;
|
||||
}
|
||||
|
||||
s->internal->packet = S3I(s)->rbuf.buf;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_setup_write_buffer(SSL *s)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t len, align, headerlen;
|
||||
|
||||
if (SSL_IS_DTLS(s))
|
||||
headerlen = DTLS1_RT_HEADER_LENGTH + 1;
|
||||
else
|
||||
headerlen = SSL3_RT_HEADER_LENGTH;
|
||||
|
||||
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
|
||||
|
||||
if (S3I(s)->wbuf.buf == NULL) {
|
||||
len = s->max_send_fragment +
|
||||
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
|
||||
len += headerlen + align +
|
||||
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
|
||||
|
||||
if ((p = calloc(1, len)) == NULL)
|
||||
goto err;
|
||||
S3I(s)->wbuf.buf = p;
|
||||
S3I(s)->wbuf.len = len;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssl3_setup_buffers(SSL *s)
|
||||
{
|
||||
if (!ssl3_setup_read_buffer(s))
|
||||
return 0;
|
||||
if (!ssl3_setup_write_buffer(s))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_release_buffer(SSL3_BUFFER_INTERNAL *b)
|
||||
{
|
||||
freezero(b->buf, b->len);
|
||||
b->buf = NULL;
|
||||
b->len = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_release_read_buffer(SSL *s)
|
||||
{
|
||||
ssl3_release_buffer(&S3I(s)->rbuf);
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_release_write_buffer(SSL *s)
|
||||
{
|
||||
ssl3_release_buffer(&S3I(s)->wbuf);
|
||||
}
|
||||
721
externals/libressl/ssl/ssl_cert.c
vendored
Executable file
721
externals/libressl/ssl/ssl_cert.c
vendored
Executable file
@@ -0,0 +1,721 @@
|
||||
/* $OpenBSD: ssl_cert.c,v 1.78 2020/06/05 17:55:24 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECC cipher suite support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
int
|
||||
SSL_get_ex_data_X509_STORE_CTX_idx(void)
|
||||
{
|
||||
static volatile int ssl_x509_store_ctx_idx = -1;
|
||||
int got_write_lock = 0;
|
||||
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
|
||||
|
||||
if (ssl_x509_store_ctx_idx < 0) {
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
|
||||
got_write_lock = 1;
|
||||
|
||||
if (ssl_x509_store_ctx_idx < 0) {
|
||||
ssl_x509_store_ctx_idx =
|
||||
X509_STORE_CTX_get_ex_new_index(
|
||||
0, "SSL for verify callback", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (got_write_lock)
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
|
||||
else
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
|
||||
|
||||
return ssl_x509_store_ctx_idx;
|
||||
}
|
||||
|
||||
CERT *
|
||||
ssl_cert_new(void)
|
||||
{
|
||||
CERT *ret;
|
||||
|
||||
ret = calloc(1, sizeof(CERT));
|
||||
if (ret == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
ret->key = &(ret->pkeys[SSL_PKEY_RSA]);
|
||||
ret->references = 1;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
CERT *
|
||||
ssl_cert_dup(CERT *cert)
|
||||
{
|
||||
CERT *ret;
|
||||
int i;
|
||||
|
||||
ret = calloc(1, sizeof(CERT));
|
||||
if (ret == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* same as ret->key = ret->pkeys + (cert->key - cert->pkeys),
|
||||
* if you find that more readable
|
||||
*/
|
||||
ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
|
||||
|
||||
ret->valid = cert->valid;
|
||||
ret->mask_k = cert->mask_k;
|
||||
ret->mask_a = cert->mask_a;
|
||||
|
||||
if (cert->dh_tmp != NULL) {
|
||||
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
|
||||
if (ret->dh_tmp == NULL) {
|
||||
SSLerrorx(ERR_R_DH_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (cert->dh_tmp->priv_key) {
|
||||
BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
|
||||
if (!b) {
|
||||
SSLerrorx(ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->dh_tmp->priv_key = b;
|
||||
}
|
||||
if (cert->dh_tmp->pub_key) {
|
||||
BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
|
||||
if (!b) {
|
||||
SSLerrorx(ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
ret->dh_tmp->pub_key = b;
|
||||
}
|
||||
}
|
||||
ret->dh_tmp_cb = cert->dh_tmp_cb;
|
||||
ret->dh_tmp_auto = cert->dh_tmp_auto;
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
if (cert->pkeys[i].x509 != NULL) {
|
||||
ret->pkeys[i].x509 = cert->pkeys[i].x509;
|
||||
CRYPTO_add(&ret->pkeys[i].x509->references, 1,
|
||||
CRYPTO_LOCK_X509);
|
||||
}
|
||||
|
||||
if (cert->pkeys[i].privatekey != NULL) {
|
||||
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
|
||||
CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
|
||||
CRYPTO_LOCK_EVP_PKEY);
|
||||
|
||||
switch (i) {
|
||||
/*
|
||||
* If there was anything special to do for
|
||||
* certain types of keys, we'd do it here.
|
||||
* (Nothing at the moment, I think.)
|
||||
*/
|
||||
|
||||
case SSL_PKEY_RSA:
|
||||
/* We have an RSA key. */
|
||||
break;
|
||||
|
||||
case SSL_PKEY_ECC:
|
||||
/* We have an ECC key */
|
||||
break;
|
||||
|
||||
case SSL_PKEY_GOST01:
|
||||
/* We have a GOST key */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Can't happen. */
|
||||
SSLerrorx(SSL_R_LIBRARY_BUG);
|
||||
}
|
||||
}
|
||||
|
||||
if (cert->pkeys[i].chain != NULL) {
|
||||
if ((ret->pkeys[i].chain =
|
||||
X509_chain_up_ref(cert->pkeys[i].chain)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ret->extra_certs *should* exist, but currently the own certificate
|
||||
* chain is held inside SSL_CTX
|
||||
*/
|
||||
|
||||
ret->references = 1;
|
||||
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
DH_free(ret->dh_tmp);
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
X509_free(ret->pkeys[i].x509);
|
||||
EVP_PKEY_free(ret->pkeys[i].privatekey);
|
||||
sk_X509_pop_free(ret->pkeys[i].chain, X509_free);
|
||||
}
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ssl_cert_free(CERT *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (c == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
DH_free(c->dh_tmp);
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
X509_free(c->pkeys[i].x509);
|
||||
EVP_PKEY_free(c->pkeys[i].privatekey);
|
||||
sk_X509_pop_free(c->pkeys[i].chain, X509_free);
|
||||
}
|
||||
|
||||
free(c);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
|
||||
{
|
||||
if (c->key == NULL)
|
||||
return 0;
|
||||
|
||||
sk_X509_pop_free(c->key->chain, X509_free);
|
||||
c->key->chain = chain;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
|
||||
{
|
||||
STACK_OF(X509) *new_chain = NULL;
|
||||
|
||||
if (chain != NULL) {
|
||||
if ((new_chain = X509_chain_up_ref(chain)) == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_cert_set0_chain(c, new_chain)) {
|
||||
sk_X509_pop_free(new_chain, X509_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_add0_chain_cert(CERT *c, X509 *cert)
|
||||
{
|
||||
if (c->key == NULL)
|
||||
return 0;
|
||||
|
||||
if (c->key->chain == NULL) {
|
||||
if ((c->key->chain = sk_X509_new_null()) == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_X509_push(c->key->chain, cert))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_add1_chain_cert(CERT *c, X509 *cert)
|
||||
{
|
||||
if (!ssl_cert_add0_chain_cert(c, cert))
|
||||
return 0;
|
||||
|
||||
X509_up_ref(cert);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
SESS_CERT *
|
||||
ssl_sess_cert_new(void)
|
||||
{
|
||||
SESS_CERT *ret;
|
||||
|
||||
ret = calloc(1, sizeof *ret);
|
||||
if (ret == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA]);
|
||||
ret->references = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
ssl_sess_cert_free(SESS_CERT *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sc == NULL)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
sk_X509_pop_free(sc->cert_chain, X509_free);
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++)
|
||||
X509_free(sc->peer_pkeys[i].x509);
|
||||
|
||||
DH_free(sc->peer_dh_tmp);
|
||||
EC_KEY_free(sc->peer_ecdh_tmp);
|
||||
free(sc->peer_x25519_tmp);
|
||||
|
||||
free(sc);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
|
||||
{
|
||||
X509_STORE_CTX ctx;
|
||||
X509 *x;
|
||||
int ret;
|
||||
|
||||
if ((sk == NULL) || (sk_X509_num(sk) == 0))
|
||||
return (0);
|
||||
|
||||
x = sk_X509_value(sk, 0);
|
||||
if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
|
||||
SSLerror(s, ERR_R_X509_LIB);
|
||||
return (0);
|
||||
}
|
||||
X509_STORE_CTX_set_ex_data(&ctx,
|
||||
SSL_get_ex_data_X509_STORE_CTX_idx(), s);
|
||||
|
||||
/*
|
||||
* We need to inherit the verify parameters. These can be
|
||||
* determined by the context: if its a server it will verify
|
||||
* SSL client certificates or vice versa.
|
||||
*/
|
||||
X509_STORE_CTX_set_default(&ctx,
|
||||
s->server ? "ssl_client" : "ssl_server");
|
||||
|
||||
/*
|
||||
* Anything non-default in "param" should overwrite anything
|
||||
* in the ctx.
|
||||
*/
|
||||
X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
|
||||
|
||||
if (s->internal->verify_callback)
|
||||
X509_STORE_CTX_set_verify_cb(&ctx, s->internal->verify_callback);
|
||||
|
||||
if (s->ctx->internal->app_verify_callback != NULL)
|
||||
ret = s->ctx->internal->app_verify_callback(&ctx,
|
||||
s->ctx->internal->app_verify_arg);
|
||||
else
|
||||
ret = X509_verify_cert(&ctx);
|
||||
|
||||
s->verify_result = ctx.error;
|
||||
X509_STORE_CTX_cleanup(&ctx);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
|
||||
STACK_OF(X509_NAME) *name_list)
|
||||
{
|
||||
sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
|
||||
*ca_list = name_list;
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *
|
||||
SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509_NAME) *ret;
|
||||
X509_NAME *name = NULL;
|
||||
|
||||
if ((ret = sk_X509_NAME_new_null()) == NULL)
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
|
||||
if ((name = X509_NAME_dup(sk_X509_NAME_value(sk, i))) == NULL)
|
||||
goto err;
|
||||
if (!sk_X509_NAME_push(ret, name))
|
||||
goto err;
|
||||
}
|
||||
return (ret);
|
||||
|
||||
err:
|
||||
X509_NAME_free(name);
|
||||
sk_X509_NAME_pop_free(ret, X509_NAME_free);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
|
||||
{
|
||||
set_client_CA_list(&(s->internal->client_CA), name_list);
|
||||
}
|
||||
|
||||
void
|
||||
SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
|
||||
{
|
||||
set_client_CA_list(&(ctx->internal->client_CA), name_list);
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *
|
||||
SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
|
||||
{
|
||||
return (ctx->internal->client_CA);
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *
|
||||
SSL_get_client_CA_list(const SSL *s)
|
||||
{
|
||||
if (s->internal->type == SSL_ST_CONNECT) {
|
||||
/* We are in the client. */
|
||||
if ((s->version >> 8) == SSL3_VERSION_MAJOR)
|
||||
return (S3I(s)->tmp.ca_names);
|
||||
else
|
||||
return (NULL);
|
||||
} else {
|
||||
if (s->internal->client_CA != NULL)
|
||||
return (s->internal->client_CA);
|
||||
else
|
||||
return (s->ctx->internal->client_CA);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
|
||||
{
|
||||
X509_NAME *name;
|
||||
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
|
||||
return (0);
|
||||
|
||||
if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
|
||||
return (0);
|
||||
|
||||
if (!sk_X509_NAME_push(*sk, name)) {
|
||||
X509_NAME_free(name);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_add_client_CA(SSL *ssl, X509 *x)
|
||||
{
|
||||
return (add_client_CA(&(ssl->internal->client_CA), x));
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
return (add_client_CA(&(ctx->internal->client_CA), x));
|
||||
}
|
||||
|
||||
static int
|
||||
xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
|
||||
{
|
||||
return (X509_NAME_cmp(*a, *b));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
|
||||
* it doesn't really have anything to do with clients (except that a common use
|
||||
* for a stack of CAs is to send it to the client). Actually, it doesn't have
|
||||
* much to do with CAs, either, since it will load any old cert.
|
||||
* \param file the file containing one or more certs.
|
||||
* \return a ::STACK containing the certs.
|
||||
*/
|
||||
STACK_OF(X509_NAME) *
|
||||
SSL_load_client_CA_file(const char *file)
|
||||
{
|
||||
BIO *in;
|
||||
X509 *x = NULL;
|
||||
X509_NAME *xn = NULL;
|
||||
STACK_OF(X509_NAME) *ret = NULL, *sk;
|
||||
|
||||
sk = sk_X509_NAME_new(xname_cmp);
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
|
||||
if ((sk == NULL) || (in == NULL)) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BIO_read_filename(in, file))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
|
||||
break;
|
||||
if (ret == NULL) {
|
||||
ret = sk_X509_NAME_new_null();
|
||||
if (ret == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if ((xn = X509_get_subject_name(x)) == NULL) goto err;
|
||||
/* check for duplicates */
|
||||
xn = X509_NAME_dup(xn);
|
||||
if (xn == NULL)
|
||||
goto err;
|
||||
if (sk_X509_NAME_find(sk, xn) >= 0)
|
||||
X509_NAME_free(xn);
|
||||
else {
|
||||
sk_X509_NAME_push(sk, xn);
|
||||
sk_X509_NAME_push(ret, xn);
|
||||
}
|
||||
}
|
||||
|
||||
if (0) {
|
||||
err:
|
||||
sk_X509_NAME_pop_free(ret, X509_NAME_free);
|
||||
ret = NULL;
|
||||
}
|
||||
sk_X509_NAME_free(sk);
|
||||
BIO_free(in);
|
||||
X509_free(x);
|
||||
if (ret != NULL)
|
||||
ERR_clear_error();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a file of certs to a stack.
|
||||
* \param stack the stack to add to.
|
||||
* \param file the file to add from. All certs in this file that are not
|
||||
* already in the stack will be added.
|
||||
* \return 1 for success, 0 for failure. Note that in the case of failure some
|
||||
* certs may have been added to \c stack.
|
||||
*/
|
||||
|
||||
int
|
||||
SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
|
||||
const char *file)
|
||||
{
|
||||
BIO *in;
|
||||
X509 *x = NULL;
|
||||
X509_NAME *xn = NULL;
|
||||
int ret = 1;
|
||||
int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
|
||||
|
||||
oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
|
||||
if (in == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BIO_read_filename(in, file))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
|
||||
break;
|
||||
if ((xn = X509_get_subject_name(x)) == NULL) goto err;
|
||||
xn = X509_NAME_dup(xn);
|
||||
if (xn == NULL)
|
||||
goto err;
|
||||
if (sk_X509_NAME_find(stack, xn) >= 0)
|
||||
X509_NAME_free(xn);
|
||||
else
|
||||
sk_X509_NAME_push(stack, xn);
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
if (0) {
|
||||
err:
|
||||
ret = 0;
|
||||
}
|
||||
BIO_free(in);
|
||||
X509_free(x);
|
||||
|
||||
(void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add a directory of certs to a stack.
|
||||
* \param stack the stack to append to.
|
||||
* \param dir the directory to append from. All files in this directory will be
|
||||
* examined as potential certs. Any that are acceptable to
|
||||
* SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
|
||||
* be included.
|
||||
* \return 1 for success, 0 for failure. Note that in the case of failure some
|
||||
* certs may have been added to \c stack.
|
||||
*/
|
||||
|
||||
int
|
||||
SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir)
|
||||
{
|
||||
DIR *dirp = NULL;
|
||||
char *path = NULL;
|
||||
int ret = 0;
|
||||
|
||||
dirp = opendir(dir);
|
||||
if (dirp) {
|
||||
struct dirent *dp;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (asprintf(&path, "%s/%s", dir, dp->d_name) != -1) {
|
||||
ret = SSL_add_file_cert_subjects_to_stack(
|
||||
stack, path);
|
||||
free(path);
|
||||
}
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
(void) closedir(dirp);
|
||||
}
|
||||
if (!ret) {
|
||||
SYSerror(errno);
|
||||
ERR_asprintf_error_data("opendir ('%s')", dir);
|
||||
SSLerrorx(ERR_R_SYS_LIB);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
1704
externals/libressl/ssl/ssl_ciph.c
vendored
Executable file
1704
externals/libressl/ssl/ssl_ciph.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
296
externals/libressl/ssl/ssl_ciphers.c
vendored
Executable file
296
externals/libressl/ssl/ssl_ciphers.c
vendored
Executable file
@@ -0,0 +1,296 @@
|
||||
/* $OpenBSD: ssl_ciphers.c,v 1.9 2020/09/15 15:28:38 schwarze Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org>
|
||||
* Copyright (c) 2015-2018, 2020 Joel Sing <jsing@openbsd.org>
|
||||
* Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <openssl/safestack.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_locl.h"
|
||||
|
||||
int
|
||||
ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
|
||||
if (sk_SSL_CIPHER_value(ciphers, i)->id == cipher->id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cipher_allowed_in_version_range(const SSL_CIPHER *cipher, uint16_t min_ver,
|
||||
uint16_t max_ver)
|
||||
{
|
||||
/* XXX: We only support DTLSv1 which is effectively TLSv1.1 */
|
||||
if (min_ver == DTLS1_VERSION || max_ver == DTLS1_VERSION)
|
||||
min_ver = max_ver = TLS1_1_VERSION;
|
||||
|
||||
switch(cipher->algorithm_ssl) {
|
||||
case SSL_SSLV3:
|
||||
if (min_ver <= TLS1_2_VERSION)
|
||||
return 1;
|
||||
break;
|
||||
case SSL_TLSV1_2:
|
||||
if (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver)
|
||||
return 1;
|
||||
break;
|
||||
case SSL_TLSV1_3:
|
||||
if (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb)
|
||||
{
|
||||
SSL_CIPHER *cipher;
|
||||
int num_ciphers = 0;
|
||||
uint16_t min_vers, max_vers;
|
||||
int i;
|
||||
|
||||
if (ciphers == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ssl_supported_version_range(s, &min_vers, &max_vers))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
|
||||
if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL)
|
||||
return 0;
|
||||
if (!ssl_cipher_allowed_in_version_range(cipher, min_vers,
|
||||
max_vers))
|
||||
continue;
|
||||
if (!CBB_add_u16(cbb, ssl3_cipher_get_value(cipher)))
|
||||
return 0;
|
||||
|
||||
num_ciphers++;
|
||||
}
|
||||
|
||||
/* Add SCSV if there are other ciphers and we're not renegotiating. */
|
||||
if (num_ciphers > 0 && !s->internal->renegotiate) {
|
||||
if (!CBB_add_u16(cbb, SSL3_CK_SCSV & SSL3_CK_VALUE_MASK))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
STACK_OF(SSL_CIPHER) *
|
||||
ssl_bytes_to_cipher_list(SSL *s, CBS *cbs)
|
||||
{
|
||||
STACK_OF(SSL_CIPHER) *ciphers = NULL;
|
||||
const SSL_CIPHER *cipher;
|
||||
uint16_t cipher_value, max_version;
|
||||
unsigned long cipher_id;
|
||||
|
||||
S3I(s)->send_connection_binding = 0;
|
||||
|
||||
if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) {
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (CBS_len(cbs) > 0) {
|
||||
if (!CBS_get_u16(cbs, &cipher_value)) {
|
||||
SSLerror(s, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
|
||||
goto err;
|
||||
}
|
||||
|
||||
cipher_id = SSL3_CK_ID | cipher_value;
|
||||
|
||||
if (cipher_id == SSL3_CK_SCSV) {
|
||||
/*
|
||||
* TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if
|
||||
* renegotiating.
|
||||
*/
|
||||
if (s->internal->renegotiate) {
|
||||
SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL,
|
||||
SSL_AD_HANDSHAKE_FAILURE);
|
||||
|
||||
goto err;
|
||||
}
|
||||
S3I(s)->send_connection_binding = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cipher_id == SSL3_CK_FALLBACK_SCSV) {
|
||||
/*
|
||||
* TLS_FALLBACK_SCSV indicates that the client
|
||||
* previously tried a higher protocol version.
|
||||
* Fail if the current version is an unexpected
|
||||
* downgrade.
|
||||
*/
|
||||
if (!ssl_downgrade_max_version(s, &max_version))
|
||||
goto err;
|
||||
if (s->version < max_version) {
|
||||
SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK);
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL,
|
||||
SSL_AD_INAPPROPRIATE_FALLBACK);
|
||||
goto err;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cipher = ssl3_get_cipher_by_value(cipher_value)) != NULL) {
|
||||
if (!sk_SSL_CIPHER_push(ciphers, cipher)) {
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (ciphers);
|
||||
|
||||
err:
|
||||
sk_SSL_CIPHER_free(ciphers);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct ssl_tls13_ciphersuite {
|
||||
const char *name;
|
||||
const char *alias;
|
||||
unsigned long cid;
|
||||
};
|
||||
|
||||
static const struct ssl_tls13_ciphersuite ssl_tls13_ciphersuites[] = {
|
||||
{
|
||||
.name = TLS1_3_TXT_AES_128_GCM_SHA256,
|
||||
.alias = "TLS_AES_128_GCM_SHA256",
|
||||
.cid = TLS1_3_CK_AES_128_GCM_SHA256,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_TXT_AES_256_GCM_SHA384,
|
||||
.alias = "TLS_AES_256_GCM_SHA384",
|
||||
.cid = TLS1_3_CK_AES_256_GCM_SHA384,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
|
||||
.alias = "TLS_CHACHA20_POLY1305_SHA256",
|
||||
.cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_TXT_AES_128_CCM_SHA256,
|
||||
.alias = "TLS_AES_128_CCM_SHA256",
|
||||
.cid = TLS1_3_CK_AES_128_CCM_SHA256,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_TXT_AES_128_CCM_8_SHA256,
|
||||
.alias = "TLS_AES_128_CCM_8_SHA256",
|
||||
.cid = TLS1_3_CK_AES_128_CCM_8_SHA256,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
int
|
||||
ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str)
|
||||
{
|
||||
const struct ssl_tls13_ciphersuite *ciphersuite;
|
||||
STACK_OF(SSL_CIPHER) *ciphers;
|
||||
const SSL_CIPHER *cipher;
|
||||
char *s = NULL;
|
||||
char *p, *q;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL)
|
||||
goto err;
|
||||
|
||||
/* An empty string is valid and means no ciphers. */
|
||||
if (strcmp(str, "") == 0)
|
||||
goto done;
|
||||
|
||||
if ((s = strdup(str)) == NULL)
|
||||
goto err;
|
||||
|
||||
q = s;
|
||||
while ((p = strsep(&q, ":")) != NULL) {
|
||||
ciphersuite = &ssl_tls13_ciphersuites[0];
|
||||
for (i = 0; ciphersuite->name != NULL; i++) {
|
||||
if (strcmp(p, ciphersuite->name) == 0)
|
||||
break;
|
||||
if (strcmp(p, ciphersuite->alias) == 0)
|
||||
break;
|
||||
ciphersuite = &ssl_tls13_ciphersuites[i];
|
||||
}
|
||||
if (ciphersuite->name == NULL)
|
||||
goto err;
|
||||
|
||||
/* We know about the cipher suite, but it is not supported. */
|
||||
if ((cipher = ssl3_get_cipher_by_id(ciphersuite->cid)) == NULL)
|
||||
continue;
|
||||
|
||||
if (!sk_SSL_CIPHER_push(ciphers, cipher))
|
||||
goto err;
|
||||
}
|
||||
|
||||
done:
|
||||
sk_SSL_CIPHER_free(*out_ciphers);
|
||||
*out_ciphers = ciphers;
|
||||
ciphers = NULL;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
sk_SSL_CIPHER_free(ciphers);
|
||||
free(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_merge_cipherlists(STACK_OF(SSL_CIPHER) *cipherlist,
|
||||
STACK_OF(SSL_CIPHER) *cipherlist_tls13,
|
||||
STACK_OF(SSL_CIPHER) **out_cipherlist)
|
||||
{
|
||||
STACK_OF(SSL_CIPHER) *ciphers = NULL;
|
||||
const SSL_CIPHER *cipher;
|
||||
int i, ret = 0;
|
||||
|
||||
if ((ciphers = sk_SSL_CIPHER_dup(cipherlist_tls13)) == NULL)
|
||||
goto err;
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(cipherlist); i++) {
|
||||
cipher = sk_SSL_CIPHER_value(cipherlist, i);
|
||||
if (cipher->algorithm_ssl == SSL_TLSV1_3)
|
||||
continue;
|
||||
if (!sk_SSL_CIPHER_push(ciphers, cipher))
|
||||
goto err;
|
||||
}
|
||||
|
||||
sk_SSL_CIPHER_free(*out_cipherlist);
|
||||
*out_cipherlist = ciphers;
|
||||
ciphers = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
sk_SSL_CIPHER_free(ciphers);
|
||||
|
||||
return ret;
|
||||
}
|
||||
2768
externals/libressl/ssl/ssl_clnt.c
vendored
Executable file
2768
externals/libressl/ssl/ssl_clnt.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
668
externals/libressl/ssl/ssl_err.c
vendored
Executable file
668
externals/libressl/ssl/ssl_err.c
vendored
Executable file
@@ -0,0 +1,668 @@
|
||||
/* $OpenBSD: ssl_err.c,v 1.37 2020/01/21 05:19:02 jsing Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||
* made to it will be overwritten when the script next updates this file,
|
||||
* only reason strings will be preserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason)
|
||||
|
||||
/* See SSL_state_func_code below */
|
||||
static ERR_STRING_DATA SSL_str_functs[]= {
|
||||
{ERR_FUNC(1), "CONNECT_CW_FLUSH"},
|
||||
{ERR_FUNC(2), "CONNECT_CW_CLNT_HELLO"},
|
||||
{ERR_FUNC(3), "CONNECT_CW_CLNT_HELLO"},
|
||||
{ERR_FUNC(4), "CONNECT_CR_SRVR_HELLO"},
|
||||
{ERR_FUNC(5), "CONNECT_CR_SRVR_HELLO"},
|
||||
{ERR_FUNC(6), "CONNECT_CR_CERT"},
|
||||
{ERR_FUNC(7), "CONNECT_CR_CERT"},
|
||||
{ERR_FUNC(8), "CONNECT_CR_KEY_EXCH"},
|
||||
{ERR_FUNC(9), "CONNECT_CR_KEY_EXCH"},
|
||||
{ERR_FUNC(10), "CONNECT_CR_CERT_REQ"},
|
||||
{ERR_FUNC(11), "CONNECT_CR_CERT_REQ"},
|
||||
{ERR_FUNC(12), "CONNECT_CR_SRVR_DONE"},
|
||||
{ERR_FUNC(13), "CONNECT_CR_SRVR_DONE"},
|
||||
{ERR_FUNC(14), "CONNECT_CW_CERT"},
|
||||
{ERR_FUNC(15), "CONNECT_CW_CERT"},
|
||||
{ERR_FUNC(16), "CONNECT_CW_CERT_C"},
|
||||
{ERR_FUNC(17), "CONNECT_CW_CERT_D"},
|
||||
{ERR_FUNC(18), "CONNECT_CW_KEY_EXCH"},
|
||||
{ERR_FUNC(19), "CONNECT_CW_KEY_EXCH"},
|
||||
{ERR_FUNC(20), "CONNECT_CW_CERT_VRFY"},
|
||||
{ERR_FUNC(21), "CONNECT_CW_CERT_VRFY"},
|
||||
{ERR_FUNC(22), "CONNECT_CW_CHANGE"},
|
||||
{ERR_FUNC(23), "CONNECT_CW_CHANGE"},
|
||||
{ERR_FUNC(26), "CONNECT_CW_FINISHED"},
|
||||
{ERR_FUNC(27), "CONNECT_CW_FINISHED"},
|
||||
{ERR_FUNC(28), "CONNECT_CR_CHANGE"},
|
||||
{ERR_FUNC(29), "CONNECT_CR_CHANGE"},
|
||||
{ERR_FUNC(30), "CONNECT_CR_FINISHED"},
|
||||
{ERR_FUNC(31), "CONNECT_CR_FINISHED"},
|
||||
{ERR_FUNC(32), "CONNECT_CR_SESSION_TICKET"},
|
||||
{ERR_FUNC(33), "CONNECT_CR_SESSION_TICKET"},
|
||||
{ERR_FUNC(34), "CONNECT_CR_CERT_STATUS"},
|
||||
{ERR_FUNC(35), "CONNECT_CR_CERT_STATUS"},
|
||||
{ERR_FUNC(36), "ACCEPT_SW_FLUSH"},
|
||||
{ERR_FUNC(37), "ACCEPT_SR_CLNT_HELLO"},
|
||||
{ERR_FUNC(38), "ACCEPT_SR_CLNT_HELLO"},
|
||||
{ERR_FUNC(39), "ACCEPT_SR_CLNT_HELLO_C"},
|
||||
{ERR_FUNC(40), "ACCEPT_SW_HELLO_REQ"},
|
||||
{ERR_FUNC(41), "ACCEPT_SW_HELLO_REQ"},
|
||||
{ERR_FUNC(42), "ACCEPT_SW_HELLO_REQ_C"},
|
||||
{ERR_FUNC(43), "ACCEPT_SW_SRVR_HELLO"},
|
||||
{ERR_FUNC(44), "ACCEPT_SW_SRVR_HELLO"},
|
||||
{ERR_FUNC(45), "ACCEPT_SW_CERT"},
|
||||
{ERR_FUNC(46), "ACCEPT_SW_CERT"},
|
||||
{ERR_FUNC(47), "ACCEPT_SW_KEY_EXCH"},
|
||||
{ERR_FUNC(48), "ACCEPT_SW_KEY_EXCH"},
|
||||
{ERR_FUNC(49), "ACCEPT_SW_CERT_REQ"},
|
||||
{ERR_FUNC(50), "ACCEPT_SW_CERT_REQ"},
|
||||
{ERR_FUNC(51), "ACCEPT_SW_SRVR_DONE"},
|
||||
{ERR_FUNC(52), "ACCEPT_SW_SRVR_DONE"},
|
||||
{ERR_FUNC(53), "ACCEPT_SR_CERT"},
|
||||
{ERR_FUNC(54), "ACCEPT_SR_CERT"},
|
||||
{ERR_FUNC(55), "ACCEPT_SR_KEY_EXCH"},
|
||||
{ERR_FUNC(56), "ACCEPT_SR_KEY_EXCH"},
|
||||
{ERR_FUNC(57), "ACCEPT_SR_CERT_VRFY"},
|
||||
{ERR_FUNC(58), "ACCEPT_SR_CERT_VRFY"},
|
||||
{ERR_FUNC(59), "ACCEPT_SR_CHANGE"},
|
||||
{ERR_FUNC(60), "ACCEPT_SR_CHANGE"},
|
||||
{ERR_FUNC(63), "ACCEPT_SR_FINISHED"},
|
||||
{ERR_FUNC(64), "ACCEPT_SR_FINISHED"},
|
||||
{ERR_FUNC(65), "ACCEPT_SW_CHANGE"},
|
||||
{ERR_FUNC(66), "ACCEPT_SW_CHANGE"},
|
||||
{ERR_FUNC(67), "ACCEPT_SW_FINISHED"},
|
||||
{ERR_FUNC(68), "ACCEPT_SW_FINISHED"},
|
||||
{ERR_FUNC(69), "ACCEPT_SW_SESSION_TICKET"},
|
||||
{ERR_FUNC(70), "ACCEPT_SW_SESSION_TICKET"},
|
||||
{ERR_FUNC(71), "ACCEPT_SW_CERT_STATUS"},
|
||||
{ERR_FUNC(72), "ACCEPT_SW_CERT_STATUS"},
|
||||
{ERR_FUNC(73), "ST_BEFORE"},
|
||||
{ERR_FUNC(74), "ST_ACCEPT"},
|
||||
{ERR_FUNC(75), "ST_CONNECT"},
|
||||
{ERR_FUNC(76), "ST_OK"},
|
||||
{ERR_FUNC(77), "ST_RENEGOTIATE"},
|
||||
{ERR_FUNC(78), "ST_BEFORE_CONNECT"},
|
||||
{ERR_FUNC(79), "ST_OK_CONNECT"},
|
||||
{ERR_FUNC(80), "ST_BEFORE_ACCEPT"},
|
||||
{ERR_FUNC(81), "ST_OK_ACCEPT"},
|
||||
{ERR_FUNC(83), "DTLS1_ST_CR_HELLO_VERIFY_REQUEST"},
|
||||
{ERR_FUNC(84), "DTLS1_ST_CR_HELLO_VERIFY_REQUEST"},
|
||||
{ERR_FUNC(85), "DTLS1_ST_SW_HELLO_VERIFY_REQUEST"},
|
||||
{ERR_FUNC(86), "DTLS1_ST_SW_HELLO_VERIFY_REQUEST"},
|
||||
{ERR_FUNC(0xfff), "(UNKNOWN)SSL_internal"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA SSL_str_reasons[]= {
|
||||
{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) , "app data in handshake"},
|
||||
{ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), "attempt to reuse session in different context"},
|
||||
{ERR_REASON(SSL_R_BAD_ALERT_RECORD) , "bad alert record"},
|
||||
{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"},
|
||||
{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"},
|
||||
{ERR_REASON(SSL_R_BAD_CHECKSUM) , "bad checksum"},
|
||||
{ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), "bad data returned by callback"},
|
||||
{ERR_REASON(SSL_R_BAD_DECOMPRESSION) , "bad decompression"},
|
||||
{ERR_REASON(SSL_R_BAD_DH_G_LENGTH) , "bad dh g length"},
|
||||
{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH) , "bad dh pub key length"},
|
||||
{ERR_REASON(SSL_R_BAD_DH_P_LENGTH) , "bad dh p length"},
|
||||
{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH) , "bad digest length"},
|
||||
{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE) , "bad dsa signature"},
|
||||
{ERR_REASON(SSL_R_BAD_ECC_CERT) , "bad ecc cert"},
|
||||
{ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE) , "bad ecdsa signature"},
|
||||
{ERR_REASON(SSL_R_BAD_ECPOINT) , "bad ecpoint"},
|
||||
{ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH) , "bad handshake length"},
|
||||
{ERR_REASON(SSL_R_BAD_HELLO_REQUEST) , "bad hello request"},
|
||||
{ERR_REASON(SSL_R_BAD_LENGTH) , "bad length"},
|
||||
{ERR_REASON(SSL_R_BAD_MAC_DECODE) , "bad mac decode"},
|
||||
{ERR_REASON(SSL_R_BAD_MAC_LENGTH) , "bad mac length"},
|
||||
{ERR_REASON(SSL_R_BAD_MESSAGE_TYPE) , "bad message type"},
|
||||
{ERR_REASON(SSL_R_BAD_PACKET_LENGTH) , "bad packet length"},
|
||||
{ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), "bad protocol version number"},
|
||||
{ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), "bad psk identity hint length"},
|
||||
{ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) , "bad response argument"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_DECRYPT) , "bad rsa decrypt"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_ENCRYPT) , "bad rsa encrypt"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_E_LENGTH) , "bad rsa e length"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"},
|
||||
{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) , "bad rsa signature"},
|
||||
{ERR_REASON(SSL_R_BAD_SIGNATURE) , "bad signature"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) , "bad srp a length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) , "bad srp b length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) , "bad srp g length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) , "bad srp n length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) , "bad srp s length"},
|
||||
{ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE) , "bad srtp mki value"},
|
||||
{ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), "bad srtp protection profile list"},
|
||||
{ERR_REASON(SSL_R_BAD_SSL_FILETYPE) , "bad ssl filetype"},
|
||||
{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), "bad ssl session id length"},
|
||||
{ERR_REASON(SSL_R_BAD_STATE) , "bad state"},
|
||||
{ERR_REASON(SSL_R_BAD_WRITE_RETRY) , "bad write retry"},
|
||||
{ERR_REASON(SSL_R_BIO_NOT_SET) , "bio not set"},
|
||||
{ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), "block cipher pad is wrong"},
|
||||
{ERR_REASON(SSL_R_BN_LIB) , "bn lib"},
|
||||
{ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) , "ca dn length mismatch"},
|
||||
{ERR_REASON(SSL_R_CA_DN_TOO_LONG) , "ca dn too long"},
|
||||
{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) , "ccs received early"},
|
||||
{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), "certificate verify failed"},
|
||||
{ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) , "cert length mismatch"},
|
||||
{ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"},
|
||||
{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"},
|
||||
{ERR_REASON(SSL_R_CIPHER_COMPRESSION_UNAVAILABLE), "cipher compression unavailable"},
|
||||
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), "cipher or hash unavailable"},
|
||||
{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"},
|
||||
{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) , "clienthello tlsext"},
|
||||
{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), "compressed length too long"},
|
||||
{ERR_REASON(SSL_R_COMPRESSION_DISABLED) , "compression disabled"},
|
||||
{ERR_REASON(SSL_R_COMPRESSION_FAILURE) , "compression failure"},
|
||||
{ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), "compression id not within private range"},
|
||||
{ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), "compression library error"},
|
||||
{ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), "connection id is different"},
|
||||
{ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"},
|
||||
{ERR_REASON(SSL_R_COOKIE_MISMATCH) , "cookie mismatch"},
|
||||
{ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), "data between ccs and finished"},
|
||||
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) , "data length too long"},
|
||||
{ERR_REASON(SSL_R_DECRYPTION_FAILED) , "decryption failed"},
|
||||
{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), "decryption failed or bad record mac"},
|
||||
{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), "dh public value length is wrong"},
|
||||
{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) , "digest check failed"},
|
||||
{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) , "dtls message too big"},
|
||||
{ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"},
|
||||
{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), "ecc cert not for key agreement"},
|
||||
{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"},
|
||||
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), "ecc cert should have rsa signature"},
|
||||
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), "ecc cert should have sha1 signature"},
|
||||
{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), "ecgroup too large for cipher"},
|
||||
{ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), "empty srtp protection profile list"},
|
||||
{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), "encrypted length too long"},
|
||||
{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), "error generating tmp rsa key"},
|
||||
{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), "error in received cipher list"},
|
||||
{ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
|
||||
{ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) , "extra data in message"},
|
||||
{ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"},
|
||||
{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), "got next proto before a ccs"},
|
||||
{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), "got next proto without seeing extension"},
|
||||
{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"},
|
||||
{ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"},
|
||||
{ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"},
|
||||
{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
|
||||
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
|
||||
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), "invalid compression algorithm"},
|
||||
{ERR_REASON(SSL_R_INVALID_PURPOSE) , "invalid purpose"},
|
||||
{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) , "invalid srp username"},
|
||||
{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"},
|
||||
{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), "invalid ticket keys length"},
|
||||
{ERR_REASON(SSL_R_INVALID_TRUST) , "invalid trust"},
|
||||
{ERR_REASON(SSL_R_KEY_ARG_TOO_LONG) , "key arg too long"},
|
||||
{ERR_REASON(SSL_R_KRB5) , "krb5"},
|
||||
{ERR_REASON(SSL_R_KRB5_C_CC_PRINC) , "krb5 client cc principal (no tkt?)"},
|
||||
{ERR_REASON(SSL_R_KRB5_C_GET_CRED) , "krb5 client get cred"},
|
||||
{ERR_REASON(SSL_R_KRB5_C_INIT) , "krb5 client init"},
|
||||
{ERR_REASON(SSL_R_KRB5_C_MK_REQ) , "krb5 client mk_req (expired tkt?)"},
|
||||
{ERR_REASON(SSL_R_KRB5_S_BAD_TICKET) , "krb5 server bad ticket"},
|
||||
{ERR_REASON(SSL_R_KRB5_S_INIT) , "krb5 server init"},
|
||||
{ERR_REASON(SSL_R_KRB5_S_RD_REQ) , "krb5 server rd_req (keytab perms?)"},
|
||||
{ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED) , "krb5 server tkt expired"},
|
||||
{ERR_REASON(SSL_R_KRB5_S_TKT_NYV) , "krb5 server tkt not yet valid"},
|
||||
{ERR_REASON(SSL_R_KRB5_S_TKT_SKEW) , "krb5 server tkt skew"},
|
||||
{ERR_REASON(SSL_R_LENGTH_MISMATCH) , "length mismatch"},
|
||||
{ERR_REASON(SSL_R_LENGTH_TOO_SHORT) , "length too short"},
|
||||
{ERR_REASON(SSL_R_LIBRARY_BUG) , "library bug"},
|
||||
{ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"},
|
||||
{ERR_REASON(SSL_R_MESSAGE_TOO_LONG) , "message too long"},
|
||||
{ERR_REASON(SSL_R_MISSING_DH_DSA_CERT) , "missing dh dsa cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_DH_KEY) , "missing dh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_DH_RSA_CERT) , "missing dh rsa cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), "missing export tmp dh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), "missing export tmp rsa key"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), "missing rsa encrypting cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"},
|
||||
{ERR_REASON(SSL_R_MISSING_SRP_PARAM) , "can't find SRP server param"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) , "missing tmp dh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) , "missing tmp ecdh key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) , "missing tmp rsa key"},
|
||||
{ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) , "missing tmp rsa pkey"},
|
||||
{ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"},
|
||||
{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) , "multiple sgc restarts"},
|
||||
{ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"},
|
||||
{ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"},
|
||||
{ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"},
|
||||
{ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"},
|
||||
{ERR_REASON(SSL_R_NO_CERTIFICATE_SET) , "no certificate set"},
|
||||
{ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"},
|
||||
{ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE) , "no ciphers available"},
|
||||
{ERR_REASON(SSL_R_NO_CIPHERS_PASSED) , "no ciphers passed"},
|
||||
{ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED) , "no ciphers specified"},
|
||||
{ERR_REASON(SSL_R_NO_CIPHER_LIST) , "no cipher list"},
|
||||
{ERR_REASON(SSL_R_NO_CIPHER_MATCH) , "no cipher match"},
|
||||
{ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) , "no client cert method"},
|
||||
{ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"},
|
||||
{ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"},
|
||||
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), "Peer haven't sent GOST certificate, required for selected ciphersuite"},
|
||||
{ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) , "no method specified"},
|
||||
{ERR_REASON(SSL_R_NO_PRIVATEKEY) , "no privatekey"},
|
||||
{ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"},
|
||||
{ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"},
|
||||
{ERR_REASON(SSL_R_NO_PUBLICKEY) , "no publickey"},
|
||||
{ERR_REASON(SSL_R_NO_RENEGOTIATION) , "no renegotiation"},
|
||||
{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST) , "digest requred for handshake isn't computed"},
|
||||
{ERR_REASON(SSL_R_NO_SHARED_CIPHER) , "no shared cipher"},
|
||||
{ERR_REASON(SSL_R_NO_SRTP_PROFILES) , "no srtp profiles"},
|
||||
{ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) , "no verify callback"},
|
||||
{ERR_REASON(SSL_R_NULL_SSL_CTX) , "null ssl ctx"},
|
||||
{ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"},
|
||||
{ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), "old session cipher not returned"},
|
||||
{ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), "old session compression algorithm not returned"},
|
||||
{ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), "only tls allowed in fips mode"},
|
||||
{ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"},
|
||||
{ERR_REASON(SSL_R_PARSE_TLSEXT) , "parse tlsext"},
|
||||
{ERR_REASON(SSL_R_PATH_TOO_LONG) , "path too long"},
|
||||
{ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), "peer did not return a certificate"},
|
||||
{ERR_REASON(SSL_R_PEER_ERROR) , "peer error"},
|
||||
{ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"},
|
||||
{ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), "peer error no certificate"},
|
||||
{ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER) , "peer error no cipher"},
|
||||
{ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), "peer error unsupported certificate type"},
|
||||
{ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"},
|
||||
{ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), "problems mapping cipher functions"},
|
||||
{ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN) , "protocol is shutdown"},
|
||||
{ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"},
|
||||
{ERR_REASON(SSL_R_PSK_NO_CLIENT_CB) , "psk no client cb"},
|
||||
{ERR_REASON(SSL_R_PSK_NO_SERVER_CB) , "psk no server cb"},
|
||||
{ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"},
|
||||
{ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) , "public key is not rsa"},
|
||||
{ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA) , "public key not rsa"},
|
||||
{ERR_REASON(SSL_R_READ_BIO_NOT_SET) , "read bio not set"},
|
||||
{ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED) , "read timeout expired"},
|
||||
{ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"},
|
||||
{ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"},
|
||||
{ERR_REASON(SSL_R_RECORD_TOO_LARGE) , "record too large"},
|
||||
{ERR_REASON(SSL_R_RECORD_TOO_SMALL) , "record too small"},
|
||||
{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"},
|
||||
{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), "renegotiation encoding err"},
|
||||
{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"},
|
||||
{ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"},
|
||||
{ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), "required compresssion algorithm missing"},
|
||||
{ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), "reuse cert length not zero"},
|
||||
{ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"},
|
||||
{ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), "reuse cipher list not zero"},
|
||||
{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), "scsv received when renegotiating"},
|
||||
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) , "serverhello tlsext"},
|
||||
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), "session id context uninitialized"},
|
||||
{ERR_REASON(SSL_R_SHORT_READ) , "short read"},
|
||||
{ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), "signature algorithms error"},
|
||||
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), "signature for non signing certificate"},
|
||||
{ERR_REASON(SSL_R_SRP_A_CALC) , "error with the srp params"},
|
||||
{ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), "srtp could not allocate profiles"},
|
||||
{ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), "srtp protection profile list too long"},
|
||||
{ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), "srtp unknown protection profile"},
|
||||
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), "ssl23 doing session id reuse"},
|
||||
{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), "ssl2 connection id too long"},
|
||||
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), "ssl3 ext invalid ecpointformat"},
|
||||
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), "ssl3 ext invalid servername"},
|
||||
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), "ssl3 ext invalid servername type"},
|
||||
{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"},
|
||||
{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), "ssl3 session id too short"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), "sslv3 alert bad certificate"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), "sslv3 alert bad record mac"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), "sslv3 alert certificate expired"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), "sslv3 alert certificate revoked"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), "sslv3 alert certificate unknown"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), "sslv3 alert decompression failure"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), "sslv3 alert handshake failure"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), "sslv3 alert illegal parameter"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), "sslv3 alert no certificate"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), "sslv3 alert unexpected message"},
|
||||
{ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), "sslv3 alert unsupported certificate"},
|
||||
{ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), "ssl ctx has no default ssl version"},
|
||||
{ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE) , "ssl handshake failure"},
|
||||
{ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), "ssl library has no ciphers"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), "ssl session id callback failed"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), "ssl session id context too long"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), "ssl session id has bad length"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), "ssl session id is different"},
|
||||
{ERR_REASON(SSL_R_SSL_SESSION_ID_TOO_LONG), "ssl session id is too long"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), "tlsv1 alert access denied"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), "tlsv1 alert inappropriate fallback"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), "tlsv1 alert protocol version"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), "tlsv1 alert record overflow"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"},
|
||||
{ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), "tlsv1 alert user cancelled"},
|
||||
{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), "tlsv1 bad certificate hash value"},
|
||||
{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), "tlsv1 bad certificate status response"},
|
||||
{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), "tlsv1 certificate unobtainable"},
|
||||
{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"},
|
||||
{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), "tlsv1 unsupported extension"},
|
||||
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), "tls client cert req with anon cipher"},
|
||||
{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), "peer does not accept heartbeats"},
|
||||
{ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) , "heartbeat request already pending"},
|
||||
{ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), "tls illegal exporter label"},
|
||||
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), "tls invalid ecpointformat list"},
|
||||
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), "tls peer did not respond with certificate list"},
|
||||
{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), "tls rsa encrypted value length is wrong"},
|
||||
{ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), "tried to use unsupported cipher"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), "unable to decode dh certs"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), "unable to decode ecdh certs"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), "unable to extract public key"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), "unable to find dh parameters"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), "unable to find ecdh parameters"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), "unable to find public key parameters"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), "unable to find ssl method"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), "unable to load ssl2 md5 routines"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), "unable to load ssl3 md5 routines"},
|
||||
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), "unable to load ssl3 sha1 routines"},
|
||||
{ERR_REASON(SSL_R_UNEXPECTED_MESSAGE) , "unexpected message"},
|
||||
{ERR_REASON(SSL_R_UNEXPECTED_RECORD) , "unexpected record"},
|
||||
{ERR_REASON(SSL_R_UNINITIALIZED) , "uninitialized"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) , "unknown alert type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) , "unknown cipher type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_DIGEST) , "unknown digest"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), "unknown key exchange type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) , "unknown pkey type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_PROTOCOL) , "unknown protocol"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), "unknown remote error type"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION) , "unknown ssl version"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN_STATE) , "unknown state"},
|
||||
{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), "unsafe legacy renegotiation disabled"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) , "unsupported cipher"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), "unsupported compression algorithm"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), "unsupported elliptic curve"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL) , "unsupported protocol"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"},
|
||||
{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"},
|
||||
{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"},
|
||||
{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) , "write bio not set"},
|
||||
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) , "wrong cipher returned"},
|
||||
{ERR_REASON(SSL_R_WRONG_CURVE) , "wrong curve"},
|
||||
{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) , "wrong message type"},
|
||||
{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"},
|
||||
{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
|
||||
{ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE) , "wrong signature size"},
|
||||
{ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE) , "wrong signature type"},
|
||||
{ERR_REASON(SSL_R_WRONG_SSL_VERSION) , "wrong ssl version"},
|
||||
{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) , "wrong version number"},
|
||||
{ERR_REASON(SSL_R_X509_LIB) , "x509 lib"},
|
||||
{ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), "x509 verification setup problems"},
|
||||
{ERR_REASON(SSL_R_PEER_BEHAVING_BADLY), "peer is doing strange or hostile things"},
|
||||
{ERR_REASON(SSL_R_UNKNOWN), "unknown failure occurred"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
ERR_load_SSL_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, SSL_str_functs);
|
||||
ERR_load_strings(0, SSL_str_reasons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
SSL_load_error_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
ERR_load_crypto_strings();
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
SSL_state_func_code(int state) {
|
||||
switch (state) {
|
||||
case SSL3_ST_CW_FLUSH:
|
||||
return 1;
|
||||
case SSL3_ST_CW_CLNT_HELLO_A:
|
||||
return 2;
|
||||
case SSL3_ST_CW_CLNT_HELLO_B:
|
||||
return 3;
|
||||
case SSL3_ST_CR_SRVR_HELLO_A:
|
||||
return 4;
|
||||
case SSL3_ST_CR_SRVR_HELLO_B:
|
||||
return 5;
|
||||
case SSL3_ST_CR_CERT_A:
|
||||
return 6;
|
||||
case SSL3_ST_CR_CERT_B:
|
||||
return 7;
|
||||
case SSL3_ST_CR_KEY_EXCH_A:
|
||||
return 8;
|
||||
case SSL3_ST_CR_KEY_EXCH_B:
|
||||
return 9;
|
||||
case SSL3_ST_CR_CERT_REQ_A:
|
||||
return 10;
|
||||
case SSL3_ST_CR_CERT_REQ_B:
|
||||
return 11;
|
||||
case SSL3_ST_CR_SRVR_DONE_A:
|
||||
return 12;
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
return 13;
|
||||
case SSL3_ST_CW_CERT_A:
|
||||
return 14;
|
||||
case SSL3_ST_CW_CERT_B:
|
||||
return 15;
|
||||
case SSL3_ST_CW_CERT_C:
|
||||
return 16;
|
||||
case SSL3_ST_CW_CERT_D:
|
||||
return 17;
|
||||
case SSL3_ST_CW_KEY_EXCH_A:
|
||||
return 18;
|
||||
case SSL3_ST_CW_KEY_EXCH_B:
|
||||
return 19;
|
||||
case SSL3_ST_CW_CERT_VRFY_A:
|
||||
return 20;
|
||||
case SSL3_ST_CW_CERT_VRFY_B:
|
||||
return 21;
|
||||
case SSL3_ST_CW_CHANGE_A:
|
||||
return 22;
|
||||
case SSL3_ST_CW_CHANGE_B:
|
||||
return 23;
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
return 26;
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
return 27;
|
||||
case SSL3_ST_CR_CHANGE_A:
|
||||
return 28;
|
||||
case SSL3_ST_CR_CHANGE_B:
|
||||
return 29;
|
||||
case SSL3_ST_CR_FINISHED_A:
|
||||
return 30;
|
||||
case SSL3_ST_CR_FINISHED_B:
|
||||
return 31;
|
||||
case SSL3_ST_CR_SESSION_TICKET_A:
|
||||
return 32;
|
||||
case SSL3_ST_CR_SESSION_TICKET_B:
|
||||
return 33;
|
||||
case SSL3_ST_CR_CERT_STATUS_A:
|
||||
return 34;
|
||||
case SSL3_ST_CR_CERT_STATUS_B:
|
||||
return 35;
|
||||
case SSL3_ST_SW_FLUSH:
|
||||
return 36;
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
return 37;
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
return 38;
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
return 39;
|
||||
case SSL3_ST_SW_HELLO_REQ_A:
|
||||
return 40;
|
||||
case SSL3_ST_SW_HELLO_REQ_B:
|
||||
return 41;
|
||||
case SSL3_ST_SW_HELLO_REQ_C:
|
||||
return 42;
|
||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||
return 43;
|
||||
case SSL3_ST_SW_SRVR_HELLO_B:
|
||||
return 44;
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
return 45;
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
return 46;
|
||||
case SSL3_ST_SW_KEY_EXCH_A:
|
||||
return 47;
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
return 48;
|
||||
case SSL3_ST_SW_CERT_REQ_A:
|
||||
return 49;
|
||||
case SSL3_ST_SW_CERT_REQ_B:
|
||||
return 50;
|
||||
case SSL3_ST_SW_SRVR_DONE_A:
|
||||
return 51;
|
||||
case SSL3_ST_SW_SRVR_DONE_B:
|
||||
return 52;
|
||||
case SSL3_ST_SR_CERT_A:
|
||||
return 53;
|
||||
case SSL3_ST_SR_CERT_B:
|
||||
return 54;
|
||||
case SSL3_ST_SR_KEY_EXCH_A:
|
||||
return 55;
|
||||
case SSL3_ST_SR_KEY_EXCH_B:
|
||||
return 56;
|
||||
case SSL3_ST_SR_CERT_VRFY_A:
|
||||
return 57;
|
||||
case SSL3_ST_SR_CERT_VRFY_B:
|
||||
return 58;
|
||||
case SSL3_ST_SR_CHANGE_A:
|
||||
return 59;
|
||||
case SSL3_ST_SR_CHANGE_B:
|
||||
return 60;
|
||||
case SSL3_ST_SR_FINISHED_A:
|
||||
return 63;
|
||||
case SSL3_ST_SR_FINISHED_B:
|
||||
return 64;
|
||||
case SSL3_ST_SW_CHANGE_A:
|
||||
return 65;
|
||||
case SSL3_ST_SW_CHANGE_B:
|
||||
return 66;
|
||||
case SSL3_ST_SW_FINISHED_A:
|
||||
return 67;
|
||||
case SSL3_ST_SW_FINISHED_B:
|
||||
return 68;
|
||||
case SSL3_ST_SW_SESSION_TICKET_A:
|
||||
return 69;
|
||||
case SSL3_ST_SW_SESSION_TICKET_B:
|
||||
return 70;
|
||||
case SSL3_ST_SW_CERT_STATUS_A:
|
||||
return 71;
|
||||
case SSL3_ST_SW_CERT_STATUS_B:
|
||||
return 72;
|
||||
case SSL_ST_BEFORE:
|
||||
return 73;
|
||||
case SSL_ST_ACCEPT:
|
||||
return 74;
|
||||
case SSL_ST_CONNECT:
|
||||
return 75;
|
||||
case SSL_ST_OK:
|
||||
return 76;
|
||||
case SSL_ST_RENEGOTIATE:
|
||||
return 77;
|
||||
case SSL_ST_BEFORE|SSL_ST_CONNECT:
|
||||
return 78;
|
||||
case SSL_ST_OK|SSL_ST_CONNECT:
|
||||
return 79;
|
||||
case SSL_ST_BEFORE|SSL_ST_ACCEPT:
|
||||
return 80;
|
||||
case SSL_ST_OK|SSL_ST_ACCEPT:
|
||||
return 81;
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
|
||||
return 83;
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
|
||||
return 84;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
|
||||
return 85;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
|
||||
return 86;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0xfff;
|
||||
}
|
||||
|
||||
void
|
||||
SSL_error_internal(const SSL *s, int r, char *f, int l)
|
||||
{
|
||||
ERR_PUT_error(ERR_LIB_SSL,
|
||||
(SSL_state_func_code(S3I(s)->hs.state)), r, f, l);
|
||||
}
|
||||
51
externals/libressl/ssl/ssl_init.c
vendored
Executable file
51
externals/libressl/ssl/ssl_init.c
vendored
Executable file
@@ -0,0 +1,51 @@
|
||||
/* $OpenBSD: ssl_init.c,v 1.2 2018/03/30 14:59:46 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* OpenSSL style init */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
static pthread_t ssl_init_thread;
|
||||
|
||||
static void
|
||||
OPENSSL_init_ssl_internal(void)
|
||||
{
|
||||
ssl_init_thread = pthread_self();
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
}
|
||||
|
||||
int
|
||||
OPENSSL_init_ssl(uint64_t opts, const void *settings)
|
||||
{
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
|
||||
if (pthread_equal(pthread_self(), ssl_init_thread))
|
||||
return 1; /* don't recurse */
|
||||
|
||||
OPENSSL_init_crypto(opts, settings);
|
||||
|
||||
if (pthread_once(&once, OPENSSL_init_ssl_internal) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
182
externals/libressl/ssl/ssl_kex.c
vendored
Executable file
182
externals/libressl/ssl/ssl_kex.c
vendored
Executable file
@@ -0,0 +1,182 @@
|
||||
/* $OpenBSD: ssl_kex.c,v 1.2 2020/04/18 14:07:56 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
int
|
||||
ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey)
|
||||
{
|
||||
EC_GROUP *group = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
EC_KEY *ec_key = NULL;
|
||||
BIGNUM *order = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* Fudge up an EC_KEY that looks like X25519... */
|
||||
if ((group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL)
|
||||
goto err;
|
||||
if ((point = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
if ((order = BN_new()) == NULL)
|
||||
goto err;
|
||||
if (!BN_set_bit(order, 252))
|
||||
goto err;
|
||||
if (!EC_GROUP_set_generator(group, point, order, NULL))
|
||||
goto err;
|
||||
EC_GROUP_set_curve_name(group, NID_X25519);
|
||||
if ((ec_key = EC_KEY_new()) == NULL)
|
||||
goto err;
|
||||
if (!EC_KEY_set_group(ec_key, group))
|
||||
goto err;
|
||||
if (!EVP_PKEY_set1_EC_KEY(pkey, ec_key))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_GROUP_free(group);
|
||||
EC_POINT_free(point);
|
||||
EC_KEY_free(ec_key);
|
||||
BN_free(order);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid)
|
||||
{
|
||||
EC_GROUP *group;
|
||||
int ret = 0;
|
||||
|
||||
if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_KEY_set_group(ecdh, group))
|
||||
goto err;
|
||||
if (!EC_KEY_generate_key(ecdh))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_GROUP_free(group);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb)
|
||||
{
|
||||
const EC_GROUP *group;
|
||||
const EC_POINT *point;
|
||||
uint8_t *ecp;
|
||||
size_t ecp_len;
|
||||
int ret = 0;
|
||||
|
||||
if ((group = EC_KEY_get0_group(ecdh)) == NULL)
|
||||
goto err;
|
||||
if ((point = EC_KEY_get0_public_key(ecdh)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((ecp_len = EC_POINT_point2oct(group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)) == 0)
|
||||
goto err;
|
||||
if (!CBB_add_space(cbb, &ecp, ecp_len))
|
||||
goto err;
|
||||
if ((EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED,
|
||||
ecp, ecp_len, NULL)) == 0)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs)
|
||||
{
|
||||
EC_GROUP *group = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_KEY_set_group(ecdh, group))
|
||||
goto err;
|
||||
|
||||
if ((point = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
if (EC_POINT_oct2point(group, point, CBS_data(cbs), CBS_len(cbs),
|
||||
NULL) == 0)
|
||||
goto err;
|
||||
if (!EC_KEY_set_public_key(ecdh, point))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_GROUP_free(group);
|
||||
EC_POINT_free(point);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer,
|
||||
uint8_t **shared_key, size_t *shared_key_len)
|
||||
{
|
||||
const EC_POINT *point;
|
||||
uint8_t *sk = NULL;
|
||||
int sk_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!EC_GROUP_check(EC_KEY_get0_group(ecdh), NULL))
|
||||
goto err;
|
||||
if (!EC_GROUP_check(EC_KEY_get0_group(ecdh_peer), NULL))
|
||||
goto err;
|
||||
|
||||
if ((point = EC_KEY_get0_public_key(ecdh_peer)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((sk_len = ECDH_size(ecdh)) <= 0)
|
||||
goto err;
|
||||
if ((sk = calloc(1, sk_len)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (ECDH_compute_key(sk, sk_len, point, ecdh, NULL) <= 0)
|
||||
goto err;
|
||||
|
||||
*shared_key = sk;
|
||||
*shared_key_len = sk_len;
|
||||
sk = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(sk, sk_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
3067
externals/libressl/ssl/ssl_lib.c
vendored
Executable file
3067
externals/libressl/ssl/ssl_lib.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1439
externals/libressl/ssl/ssl_locl.h
vendored
Executable file
1439
externals/libressl/ssl/ssl_locl.h
vendored
Executable file
File diff suppressed because it is too large
Load Diff
742
externals/libressl/ssl/ssl_methods.c
vendored
Executable file
742
externals/libressl/ssl/ssl_methods.c
vendored
Executable file
@@ -0,0 +1,742 @@
|
||||
/* $OpenBSD: ssl_methods.c,v 1.16 2020/09/17 15:23:29 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = {
|
||||
.version = DTLS1_VERSION,
|
||||
.min_version = DTLS1_VERSION,
|
||||
.max_version = DTLS1_VERSION,
|
||||
.ssl_new = dtls1_new,
|
||||
.ssl_clear = dtls1_clear,
|
||||
.ssl_free = dtls1_free,
|
||||
.ssl_accept = ssl_undefined_function,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = dtls1_read_bytes,
|
||||
.ssl_write_bytes = dtls1_write_app_data_bytes,
|
||||
.ssl3_enc = &DTLSv1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_client_method_data = {
|
||||
.ssl_dispatch_alert = dtls1_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &DTLSv1_client_method_internal_data,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_client_method(void)
|
||||
{
|
||||
return &DTLSv1_client_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLS_client_method(void)
|
||||
{
|
||||
return DTLSv1_client_method();
|
||||
}
|
||||
|
||||
static const SSL_METHOD_INTERNAL DTLSv1_method_internal_data = {
|
||||
.version = DTLS1_VERSION,
|
||||
.min_version = DTLS1_VERSION,
|
||||
.max_version = DTLS1_VERSION,
|
||||
.ssl_new = dtls1_new,
|
||||
.ssl_clear = dtls1_clear,
|
||||
.ssl_free = dtls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = dtls1_read_bytes,
|
||||
.ssl_write_bytes = dtls1_write_app_data_bytes,
|
||||
.ssl3_enc = &DTLSv1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_method_data = {
|
||||
.ssl_dispatch_alert = dtls1_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &DTLSv1_method_internal_data,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_method(void)
|
||||
{
|
||||
return &DTLSv1_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLS_method(void)
|
||||
{
|
||||
return DTLSv1_method();
|
||||
}
|
||||
|
||||
static const SSL_METHOD_INTERNAL DTLSv1_server_method_internal_data = {
|
||||
.version = DTLS1_VERSION,
|
||||
.min_version = DTLS1_VERSION,
|
||||
.max_version = DTLS1_VERSION,
|
||||
.ssl_new = dtls1_new,
|
||||
.ssl_clear = dtls1_clear,
|
||||
.ssl_free = dtls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl_undefined_function,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = dtls1_read_bytes,
|
||||
.ssl_write_bytes = dtls1_write_app_data_bytes,
|
||||
.ssl3_enc = &DTLSv1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_server_method_data = {
|
||||
.ssl_dispatch_alert = dtls1_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &DTLSv1_server_method_internal_data,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_server_method(void)
|
||||
{
|
||||
return &DTLSv1_server_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLS_server_method(void)
|
||||
{
|
||||
return DTLSv1_server_method();
|
||||
}
|
||||
|
||||
#ifdef LIBRESSL_HAS_TLS1_3_CLIENT
|
||||
static const SSL_METHOD_INTERNAL TLS_client_method_internal_data = {
|
||||
.version = TLS1_3_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_3_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl_undefined_function,
|
||||
.ssl_connect = tls13_legacy_connect,
|
||||
.ssl_shutdown = tls13_legacy_shutdown,
|
||||
.ssl_renegotiate = ssl_undefined_function,
|
||||
.ssl_renegotiate_check = ssl_ok,
|
||||
.ssl_pending = tls13_legacy_pending,
|
||||
.ssl_read_bytes = tls13_legacy_read_bytes,
|
||||
.ssl_write_bytes = tls13_legacy_write_bytes,
|
||||
.ssl3_enc = &TLSv1_3_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLS_client_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLS_client_method_internal_data,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLS_legacy_client_method_internal_data = {
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_2_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl_undefined_function,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl_undefined_function,
|
||||
.ssl_renegotiate_check = ssl_ok,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_2_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLS_legacy_client_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLS_legacy_client_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_client_method_internal_data = {
|
||||
.version = TLS1_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl_undefined_function,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_client_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_client_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_1_client_method_internal_data = {
|
||||
.version = TLS1_1_VERSION,
|
||||
.min_version = TLS1_1_VERSION,
|
||||
.max_version = TLS1_1_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl_undefined_function,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_1_client_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_1_client_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_2_client_method_internal_data = {
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_version = TLS1_2_VERSION,
|
||||
.max_version = TLS1_2_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl_undefined_function,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_2_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_2_client_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_2_client_method_internal_data,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
SSLv23_client_method(void)
|
||||
{
|
||||
return (TLS_client_method());
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLS_client_method(void)
|
||||
{
|
||||
#ifdef LIBRESSL_HAS_TLS1_3_CLIENT
|
||||
return (&TLS_client_method_data);
|
||||
#else
|
||||
return tls_legacy_client_method();
|
||||
#endif
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
tls_legacy_client_method(void)
|
||||
{
|
||||
return (&TLS_legacy_client_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_client_method(void)
|
||||
{
|
||||
return (&TLSv1_client_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_1_client_method(void)
|
||||
{
|
||||
return (&TLSv1_1_client_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_2_client_method(void)
|
||||
{
|
||||
return (&TLSv1_2_client_method_data);
|
||||
}
|
||||
|
||||
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT) && defined(LIBRESSL_HAS_TLS1_3_SERVER)
|
||||
static const SSL_METHOD_INTERNAL TLS_method_internal_data = {
|
||||
.version = TLS1_3_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_3_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = tls13_legacy_accept,
|
||||
.ssl_connect = tls13_legacy_connect,
|
||||
.ssl_shutdown = tls13_legacy_shutdown,
|
||||
.ssl_renegotiate = ssl_undefined_function,
|
||||
.ssl_renegotiate_check = ssl_ok,
|
||||
.ssl_pending = tls13_legacy_pending,
|
||||
.ssl_read_bytes = tls13_legacy_read_bytes,
|
||||
.ssl_write_bytes = tls13_legacy_write_bytes,
|
||||
.ssl3_enc = &TLSv1_3_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLS_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLS_method_internal_data,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLS_legacy_method_internal_data = {
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_2_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl_undefined_function,
|
||||
.ssl_renegotiate_check = ssl_ok,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_2_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLS_legacy_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLS_legacy_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_method_internal_data = {
|
||||
.version = TLS1_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_1_method_internal_data = {
|
||||
.version = TLS1_1_VERSION,
|
||||
.min_version = TLS1_1_VERSION,
|
||||
.max_version = TLS1_1_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_1_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_1_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_2_method_internal_data = {
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_version = TLS1_2_VERSION,
|
||||
.max_version = TLS1_2_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl3_connect,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_2_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_2_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_2_method_internal_data,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
SSLv23_method(void)
|
||||
{
|
||||
return (TLS_method());
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLS_method(void)
|
||||
{
|
||||
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT) && defined(LIBRESSL_HAS_TLS1_3_SERVER)
|
||||
return (&TLS_method_data);
|
||||
#else
|
||||
return tls_legacy_method();
|
||||
#endif
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
tls_legacy_method(void)
|
||||
{
|
||||
return (&TLS_legacy_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_method(void)
|
||||
{
|
||||
return (&TLSv1_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_1_method(void)
|
||||
{
|
||||
return (&TLSv1_1_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_2_method(void)
|
||||
{
|
||||
return (&TLSv1_2_method_data);
|
||||
}
|
||||
|
||||
#ifdef LIBRESSL_HAS_TLS1_3_SERVER
|
||||
static const SSL_METHOD_INTERNAL TLS_server_method_internal_data = {
|
||||
.version = TLS1_3_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_3_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = tls13_legacy_accept,
|
||||
.ssl_connect = ssl_undefined_function,
|
||||
.ssl_shutdown = tls13_legacy_shutdown,
|
||||
.ssl_renegotiate = ssl_undefined_function,
|
||||
.ssl_renegotiate_check = ssl_ok,
|
||||
.ssl_pending = tls13_legacy_pending,
|
||||
.ssl_read_bytes = tls13_legacy_read_bytes,
|
||||
.ssl_write_bytes = tls13_legacy_write_bytes,
|
||||
.ssl3_enc = &TLSv1_3_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLS_server_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLS_server_method_internal_data,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLS_legacy_server_method_internal_data = {
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_2_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl_undefined_function,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl_undefined_function,
|
||||
.ssl_renegotiate_check = ssl_ok,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_2_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLS_legacy_server_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLS_legacy_server_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_server_method_internal_data = {
|
||||
.version = TLS1_VERSION,
|
||||
.min_version = TLS1_VERSION,
|
||||
.max_version = TLS1_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl_undefined_function,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_server_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_server_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_1_server_method_internal_data = {
|
||||
.version = TLS1_1_VERSION,
|
||||
.min_version = TLS1_1_VERSION,
|
||||
.max_version = TLS1_1_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl_undefined_function,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_1_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_1_server_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_1_server_method_internal_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD_INTERNAL TLSv1_2_server_method_internal_data = {
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_version = TLS1_2_VERSION,
|
||||
.max_version = TLS1_2_VERSION,
|
||||
.ssl_new = tls1_new,
|
||||
.ssl_clear = tls1_clear,
|
||||
.ssl_free = tls1_free,
|
||||
.ssl_accept = ssl3_accept,
|
||||
.ssl_connect = ssl_undefined_function,
|
||||
.ssl_shutdown = ssl3_shutdown,
|
||||
.ssl_renegotiate = ssl3_renegotiate,
|
||||
.ssl_renegotiate_check = ssl3_renegotiate_check,
|
||||
.ssl_pending = ssl3_pending,
|
||||
.ssl_read_bytes = ssl3_read_bytes,
|
||||
.ssl_write_bytes = ssl3_write_bytes,
|
||||
.ssl3_enc = &TLSv1_2_enc_data,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_2_server_method_data = {
|
||||
.ssl_dispatch_alert = ssl3_dispatch_alert,
|
||||
.num_ciphers = ssl3_num_ciphers,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.get_cipher_by_char = ssl3_get_cipher_by_char,
|
||||
.put_cipher_by_char = ssl3_put_cipher_by_char,
|
||||
.internal = &TLSv1_2_server_method_internal_data,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
SSLv23_server_method(void)
|
||||
{
|
||||
return (TLS_server_method());
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLS_server_method(void)
|
||||
{
|
||||
#ifdef LIBRESSL_HAS_TLS1_3_SERVER
|
||||
return (&TLS_server_method_data);
|
||||
#else
|
||||
return tls_legacy_server_method();
|
||||
#endif
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
tls_legacy_server_method(void)
|
||||
{
|
||||
return (&TLS_legacy_server_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_server_method(void)
|
||||
{
|
||||
return (&TLSv1_server_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_1_server_method(void)
|
||||
{
|
||||
return (&TLSv1_1_server_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_2_server_method(void)
|
||||
{
|
||||
return (&TLSv1_2_server_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
ssl_get_client_method(uint16_t version)
|
||||
{
|
||||
if (version == TLS1_3_VERSION)
|
||||
return (TLS_client_method());
|
||||
if (version == TLS1_2_VERSION)
|
||||
return (TLSv1_2_client_method());
|
||||
if (version == TLS1_1_VERSION)
|
||||
return (TLSv1_1_client_method());
|
||||
if (version == TLS1_VERSION)
|
||||
return (TLSv1_client_method());
|
||||
if (version == DTLS1_VERSION)
|
||||
return (DTLSv1_client_method());
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
ssl_get_server_method(uint16_t version)
|
||||
{
|
||||
if (version == TLS1_3_VERSION)
|
||||
return (TLS_server_method());
|
||||
if (version == TLS1_2_VERSION)
|
||||
return (TLSv1_2_server_method());
|
||||
if (version == TLS1_1_VERSION)
|
||||
return (TLSv1_1_server_method());
|
||||
if (version == TLS1_VERSION)
|
||||
return (TLSv1_server_method());
|
||||
if (version == DTLS1_VERSION)
|
||||
return (DTLSv1_server_method());
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
293
externals/libressl/ssl/ssl_packet.c
vendored
Executable file
293
externals/libressl/ssl/ssl_packet.c
vendored
Executable file
@@ -0,0 +1,293 @@
|
||||
/* $OpenBSD: ssl_packet.c,v 1.8 2018/11/08 22:28:52 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
static int
|
||||
ssl_is_sslv2_client_hello(CBS *header)
|
||||
{
|
||||
uint16_t record_length;
|
||||
uint8_t message_type;
|
||||
CBS cbs;
|
||||
|
||||
CBS_dup(header, &cbs);
|
||||
|
||||
if (!CBS_get_u16(&cbs, &record_length) ||
|
||||
!CBS_get_u8(&cbs, &message_type))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The SSLv2 record length field uses variable length (2 or 3 byte)
|
||||
* encoding. Given the size of a client hello, we expect/require the
|
||||
* 2-byte form which is indicated by a one in the most significant bit.
|
||||
*/
|
||||
if ((record_length & 0x8000) == 0)
|
||||
return 0;
|
||||
if ((record_length & ~0x8000) < 3)
|
||||
return 0;
|
||||
if (message_type != SSL2_MT_CLIENT_HELLO)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_is_sslv3_handshake(CBS *header)
|
||||
{
|
||||
uint16_t record_version;
|
||||
uint8_t record_type;
|
||||
CBS cbs;
|
||||
|
||||
CBS_dup(header, &cbs);
|
||||
|
||||
if (!CBS_get_u8(&cbs, &record_type) ||
|
||||
!CBS_get_u16(&cbs, &record_version))
|
||||
return 0;
|
||||
|
||||
if (record_type != SSL3_RT_HANDSHAKE)
|
||||
return 0;
|
||||
if ((record_version >> 8) != SSL3_VERSION_MAJOR)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_convert_sslv2_client_hello(SSL *s)
|
||||
{
|
||||
CBB cbb, handshake, client_hello, cipher_suites, compression, session_id;
|
||||
CBS cbs, challenge, cipher_specs, session;
|
||||
uint16_t record_length, client_version, cipher_specs_length;
|
||||
uint16_t session_id_length, challenge_length;
|
||||
unsigned char *client_random = NULL, *data = NULL;
|
||||
size_t data_len, pad_len, len;
|
||||
uint32_t cipher_spec;
|
||||
uint8_t message_type;
|
||||
unsigned char *pad;
|
||||
int ret = -1;
|
||||
int n;
|
||||
|
||||
memset(&cbb, 0, sizeof(cbb));
|
||||
|
||||
CBS_init(&cbs, s->internal->packet, SSL3_RT_HEADER_LENGTH);
|
||||
|
||||
if (!CBS_get_u16(&cbs, &record_length) ||
|
||||
!CBS_get_u8(&cbs, &message_type) ||
|
||||
!CBS_get_u16(&cbs, &client_version))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* The SSLv2 record length field uses variable length (2 or 3 byte)
|
||||
* encoding. Given the size of a client hello, we expect/require the
|
||||
* 2-byte form which is indicated by a one in the most significant bit.
|
||||
* Also note that the record length value does not include the bytes
|
||||
* used for the record length field.
|
||||
*/
|
||||
if ((record_length & 0x8000) == 0)
|
||||
return -1;
|
||||
record_length &= ~0x8000;
|
||||
if (record_length < SSL3_RT_HEADER_LENGTH - 2)
|
||||
return -1;
|
||||
if (message_type != SSL2_MT_CLIENT_HELLO)
|
||||
return -1;
|
||||
|
||||
if (record_length < 9) {
|
||||
SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
|
||||
return -1;
|
||||
}
|
||||
if (record_length > 4096) {
|
||||
SSLerror(s, SSL_R_RECORD_TOO_LARGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = ssl3_packet_extend(s, record_length + 2);
|
||||
if (n != record_length + 2)
|
||||
return n;
|
||||
|
||||
tls1_transcript_record(s, s->internal->packet + 2,
|
||||
s->internal->packet_length - 2);
|
||||
s->internal->mac_packet = 0;
|
||||
|
||||
if (s->internal->msg_callback)
|
||||
s->internal->msg_callback(0, SSL2_VERSION, 0,
|
||||
s->internal->packet + 2, s->internal->packet_length - 2, s,
|
||||
s->internal->msg_callback_arg);
|
||||
|
||||
/* Decode the SSLv2 record containing the client hello. */
|
||||
CBS_init(&cbs, s->internal->packet, s->internal->packet_length);
|
||||
|
||||
if (!CBS_get_u16(&cbs, &record_length))
|
||||
return -1;
|
||||
if (!CBS_get_u8(&cbs, &message_type))
|
||||
return -1;
|
||||
if (!CBS_get_u16(&cbs, &client_version))
|
||||
return -1;
|
||||
if (!CBS_get_u16(&cbs, &cipher_specs_length))
|
||||
return -1;
|
||||
if (!CBS_get_u16(&cbs, &session_id_length))
|
||||
return -1;
|
||||
if (!CBS_get_u16(&cbs, &challenge_length))
|
||||
return -1;
|
||||
if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length))
|
||||
return -1;
|
||||
if (!CBS_get_bytes(&cbs, &session, session_id_length))
|
||||
return -1;
|
||||
if (!CBS_get_bytes(&cbs, &challenge, challenge_length))
|
||||
return -1;
|
||||
if (CBS_len(&cbs) != 0) {
|
||||
SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
|
||||
* left-padding with zero bytes.
|
||||
*/
|
||||
if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL)
|
||||
goto err;
|
||||
if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE))
|
||||
goto err;
|
||||
if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE)
|
||||
len = SSL3_RANDOM_SIZE;
|
||||
pad_len = SSL3_RANDOM_SIZE - len;
|
||||
if (!CBB_add_space(&cbb, &pad, pad_len))
|
||||
goto err;
|
||||
memset(pad, 0, pad_len);
|
||||
if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, NULL, NULL))
|
||||
goto err;
|
||||
|
||||
/* Build SSLv3/TLS record with client hello. */
|
||||
if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&cbb, 0x0301))
|
||||
goto err;
|
||||
if (!CBB_add_u16_length_prefixed(&cbb, &handshake))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO))
|
||||
goto err;
|
||||
if (!CBB_add_u24_length_prefixed(&handshake, &client_hello))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&client_hello, client_version))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE))
|
||||
goto err;
|
||||
if (!CBB_add_u8_length_prefixed(&client_hello, &session_id))
|
||||
goto err;
|
||||
if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites))
|
||||
goto err;
|
||||
while (CBS_len(&cipher_specs) > 0) {
|
||||
if (!CBS_get_u24(&cipher_specs, &cipher_spec))
|
||||
goto err;
|
||||
if ((cipher_spec & 0xff0000) != 0)
|
||||
continue;
|
||||
if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff))
|
||||
goto err;
|
||||
}
|
||||
if (!CBB_add_u8_length_prefixed(&client_hello, &compression))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&compression, 0))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, &data, &data_len))
|
||||
goto err;
|
||||
|
||||
if (data_len > S3I(s)->rbuf.len)
|
||||
goto err;
|
||||
|
||||
s->internal->packet = S3I(s)->rbuf.buf;
|
||||
s->internal->packet_length = data_len;
|
||||
memcpy(s->internal->packet, data, data_len);
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
free(client_random);
|
||||
free(data);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Potentially do legacy processing on the first packet received by a TLS
|
||||
* server. We return 1 if we want SSLv3/TLS record processing to continue
|
||||
* normally, otherwise we must set an SSLerr and return -1.
|
||||
*/
|
||||
int
|
||||
ssl_server_legacy_first_packet(SSL *s)
|
||||
{
|
||||
uint16_t min_version;
|
||||
const char *data;
|
||||
CBS header;
|
||||
|
||||
if (SSL_IS_DTLS(s))
|
||||
return 1;
|
||||
|
||||
CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
|
||||
|
||||
if (ssl_is_sslv3_handshake(&header) == 1)
|
||||
return 1;
|
||||
|
||||
/* Only continue if this is not a version locked method. */
|
||||
if (s->method->internal->min_version == s->method->internal->max_version)
|
||||
return 1;
|
||||
|
||||
if (ssl_is_sslv2_client_hello(&header) == 1) {
|
||||
/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
|
||||
if (ssl_enabled_version_range(s, &min_version, NULL) != 1) {
|
||||
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
|
||||
return -1;
|
||||
}
|
||||
if (min_version > TLS1_VERSION)
|
||||
return 1;
|
||||
|
||||
if (ssl_convert_sslv2_client_hello(s) != 1) {
|
||||
SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
|
||||
if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
|
||||
SSLerror(s, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
data = (const char *)CBS_data(&header);
|
||||
|
||||
/* Is this a cleartext protocol? */
|
||||
if (strncmp("GET ", data, 4) == 0 ||
|
||||
strncmp("POST ", data, 5) == 0 ||
|
||||
strncmp("HEAD ", data, 5) == 0 ||
|
||||
strncmp("PUT ", data, 4) == 0) {
|
||||
SSLerror(s, SSL_R_HTTP_REQUEST);
|
||||
return -1;
|
||||
}
|
||||
if (strncmp("CONNE", data, 5) == 0) {
|
||||
SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSLerror(s, SSL_R_UNKNOWN_PROTOCOL);
|
||||
|
||||
return -1;
|
||||
}
|
||||
1356
externals/libressl/ssl/ssl_pkt.c
vendored
Executable file
1356
externals/libressl/ssl/ssl_pkt.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
695
externals/libressl/ssl/ssl_rsa.c
vendored
Executable file
695
externals/libressl/ssl/ssl_rsa.c
vendored
Executable file
@@ -0,0 +1,695 @@
|
||||
/* $OpenBSD: ssl_rsa.c,v 1.31 2019/03/25 16:46:48 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static int ssl_set_cert(CERT *c, X509 *x509);
|
||||
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
|
||||
static int ssl_ctx_use_certificate_chain_bio(SSL_CTX *, BIO *);
|
||||
|
||||
int
|
||||
SSL_use_certificate(SSL *ssl, X509 *x)
|
||||
{
|
||||
if (x == NULL) {
|
||||
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
return (ssl_set_cert(ssl->cert, x));
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_certificate_file(SSL *ssl, const char *file, int type)
|
||||
{
|
||||
int j;
|
||||
BIO *in;
|
||||
int ret = 0;
|
||||
X509 *x = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerror(ssl, ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerror(ssl, ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (type == SSL_FILETYPE_ASN1) {
|
||||
j = ERR_R_ASN1_LIB;
|
||||
x = d2i_X509_bio(in, NULL);
|
||||
} else if (type == SSL_FILETYPE_PEM) {
|
||||
j = ERR_R_PEM_LIB;
|
||||
x = PEM_read_bio_X509(in, NULL,
|
||||
ssl->ctx->default_passwd_callback,
|
||||
ssl->ctx->default_passwd_callback_userdata);
|
||||
} else {
|
||||
SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (x == NULL) {
|
||||
SSLerror(ssl, j);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SSL_use_certificate(ssl, x);
|
||||
end:
|
||||
X509_free(x);
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
|
||||
{
|
||||
X509 *x;
|
||||
int ret;
|
||||
|
||||
x = d2i_X509(NULL, &d, (long)len);
|
||||
if (x == NULL) {
|
||||
SSLerror(ssl, ERR_R_ASN1_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = SSL_use_certificate(ssl, x);
|
||||
X509_free(x);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
int ret;
|
||||
|
||||
if (rsa == NULL) {
|
||||
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
if ((pkey = EVP_PKEY_new()) == NULL) {
|
||||
SSLerror(ssl, ERR_R_EVP_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
RSA_up_ref(rsa);
|
||||
EVP_PKEY_assign_RSA(pkey, rsa);
|
||||
|
||||
ret = ssl_set_pkey(ssl->cert, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = ssl_cert_type(NULL, pkey);
|
||||
if (i < 0) {
|
||||
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (c->pkeys[i].x509 != NULL) {
|
||||
EVP_PKEY *pktmp;
|
||||
pktmp = X509_get_pubkey(c->pkeys[i].x509);
|
||||
EVP_PKEY_copy_parameters(pktmp, pkey);
|
||||
EVP_PKEY_free(pktmp);
|
||||
ERR_clear_error();
|
||||
|
||||
/*
|
||||
* Don't check the public/private key, this is mostly
|
||||
* for smart cards.
|
||||
*/
|
||||
if ((pkey->type == EVP_PKEY_RSA) &&
|
||||
(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
|
||||
;
|
||||
else
|
||||
if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
|
||||
X509_free(c->pkeys[i].x509);
|
||||
c->pkeys[i].x509 = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_PKEY_free(c->pkeys[i].privatekey);
|
||||
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
c->pkeys[i].privatekey = pkey;
|
||||
c->key = &(c->pkeys[i]);
|
||||
|
||||
c->valid = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
|
||||
{
|
||||
int j, ret = 0;
|
||||
BIO *in;
|
||||
RSA *rsa = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerror(ssl, ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerror(ssl, ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (type == SSL_FILETYPE_ASN1) {
|
||||
j = ERR_R_ASN1_LIB;
|
||||
rsa = d2i_RSAPrivateKey_bio(in, NULL);
|
||||
} else if (type == SSL_FILETYPE_PEM) {
|
||||
j = ERR_R_PEM_LIB;
|
||||
rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
|
||||
ssl->ctx->default_passwd_callback,
|
||||
ssl->ctx->default_passwd_callback_userdata);
|
||||
} else {
|
||||
SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
|
||||
goto end;
|
||||
}
|
||||
if (rsa == NULL) {
|
||||
SSLerror(ssl, j);
|
||||
goto end;
|
||||
}
|
||||
ret = SSL_use_RSAPrivateKey(ssl, rsa);
|
||||
RSA_free(rsa);
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
|
||||
{
|
||||
int ret;
|
||||
RSA *rsa;
|
||||
|
||||
if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
|
||||
SSLerror(ssl, ERR_R_ASN1_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = SSL_use_RSAPrivateKey(ssl, rsa);
|
||||
RSA_free(rsa);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (pkey == NULL) {
|
||||
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
ret = ssl_set_pkey(ssl->cert, pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
|
||||
{
|
||||
int j, ret = 0;
|
||||
BIO *in;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerror(ssl, ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerror(ssl, ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (type == SSL_FILETYPE_PEM) {
|
||||
j = ERR_R_PEM_LIB;
|
||||
pkey = PEM_read_bio_PrivateKey(in, NULL,
|
||||
ssl->ctx->default_passwd_callback,
|
||||
ssl->ctx->default_passwd_callback_userdata);
|
||||
} else if (type == SSL_FILETYPE_ASN1) {
|
||||
j = ERR_R_ASN1_LIB;
|
||||
pkey = d2i_PrivateKey_bio(in, NULL);
|
||||
} else {
|
||||
SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
|
||||
goto end;
|
||||
}
|
||||
if (pkey == NULL) {
|
||||
SSLerror(ssl, j);
|
||||
goto end;
|
||||
}
|
||||
ret = SSL_use_PrivateKey(ssl, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
|
||||
SSLerror(ssl, ERR_R_ASN1_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = SSL_use_PrivateKey(ssl, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
if (x == NULL) {
|
||||
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
return (ssl_set_cert(ctx->internal->cert, x));
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_set_cert(CERT *c, X509 *x)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
int i;
|
||||
|
||||
pkey = X509_get_pubkey(x);
|
||||
if (pkey == NULL) {
|
||||
SSLerrorx(SSL_R_X509_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
i = ssl_cert_type(x, pkey);
|
||||
if (i < 0) {
|
||||
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (c->pkeys[i].privatekey != NULL) {
|
||||
EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
|
||||
ERR_clear_error();
|
||||
|
||||
/*
|
||||
* Don't check the public/private key, this is mostly
|
||||
* for smart cards.
|
||||
*/
|
||||
if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
|
||||
(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
|
||||
RSA_METHOD_FLAG_NO_CHECK))
|
||||
;
|
||||
else
|
||||
if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
|
||||
/*
|
||||
* don't fail for a cert/key mismatch, just free
|
||||
* current private key (when switching to a different
|
||||
* cert & key, first this function should be used,
|
||||
* then ssl_set_pkey
|
||||
*/
|
||||
EVP_PKEY_free(c->pkeys[i].privatekey);
|
||||
c->pkeys[i].privatekey = NULL;
|
||||
/* clear error queue */
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
X509_free(c->pkeys[i].x509);
|
||||
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
|
||||
c->pkeys[i].x509 = x;
|
||||
c->key = &(c->pkeys[i]);
|
||||
|
||||
c->valid = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
int j;
|
||||
BIO *in;
|
||||
int ret = 0;
|
||||
X509 *x = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerrorx(ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerrorx(ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (type == SSL_FILETYPE_ASN1) {
|
||||
j = ERR_R_ASN1_LIB;
|
||||
x = d2i_X509_bio(in, NULL);
|
||||
} else if (type == SSL_FILETYPE_PEM) {
|
||||
j = ERR_R_PEM_LIB;
|
||||
x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
|
||||
ctx->default_passwd_callback_userdata);
|
||||
} else {
|
||||
SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (x == NULL) {
|
||||
SSLerrorx(j);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SSL_CTX_use_certificate(ctx, x);
|
||||
end:
|
||||
X509_free(x);
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
|
||||
{
|
||||
X509 *x;
|
||||
int ret;
|
||||
|
||||
x = d2i_X509(NULL, &d, (long)len);
|
||||
if (x == NULL) {
|
||||
SSLerrorx(ERR_R_ASN1_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = SSL_CTX_use_certificate(ctx, x);
|
||||
X509_free(x);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (rsa == NULL) {
|
||||
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
if ((pkey = EVP_PKEY_new()) == NULL) {
|
||||
SSLerrorx(ERR_R_EVP_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
RSA_up_ref(rsa);
|
||||
EVP_PKEY_assign_RSA(pkey, rsa);
|
||||
|
||||
ret = ssl_set_pkey(ctx->internal->cert, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
int j, ret = 0;
|
||||
BIO *in;
|
||||
RSA *rsa = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerrorx(ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerrorx(ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (type == SSL_FILETYPE_ASN1) {
|
||||
j = ERR_R_ASN1_LIB;
|
||||
rsa = d2i_RSAPrivateKey_bio(in, NULL);
|
||||
} else if (type == SSL_FILETYPE_PEM) {
|
||||
j = ERR_R_PEM_LIB;
|
||||
rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
|
||||
ctx->default_passwd_callback,
|
||||
ctx->default_passwd_callback_userdata);
|
||||
} else {
|
||||
SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
|
||||
goto end;
|
||||
}
|
||||
if (rsa == NULL) {
|
||||
SSLerrorx(j);
|
||||
goto end;
|
||||
}
|
||||
ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
|
||||
RSA_free(rsa);
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
|
||||
{
|
||||
int ret;
|
||||
RSA *rsa;
|
||||
|
||||
if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
|
||||
SSLerrorx(ERR_R_ASN1_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
|
||||
RSA_free(rsa);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey == NULL) {
|
||||
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
return (ssl_set_pkey(ctx->internal->cert, pkey));
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
int j, ret = 0;
|
||||
BIO *in;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerrorx(ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerrorx(ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (type == SSL_FILETYPE_PEM) {
|
||||
j = ERR_R_PEM_LIB;
|
||||
pkey = PEM_read_bio_PrivateKey(in, NULL,
|
||||
ctx->default_passwd_callback,
|
||||
ctx->default_passwd_callback_userdata);
|
||||
} else if (type == SSL_FILETYPE_ASN1) {
|
||||
j = ERR_R_ASN1_LIB;
|
||||
pkey = d2i_PrivateKey_bio(in, NULL);
|
||||
} else {
|
||||
SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
|
||||
goto end;
|
||||
}
|
||||
if (pkey == NULL) {
|
||||
SSLerrorx(j);
|
||||
goto end;
|
||||
}
|
||||
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
|
||||
long len)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
|
||||
SSLerrorx(ERR_R_ASN1_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read a bio that contains our certificate in "PEM" format,
|
||||
* possibly followed by a sequence of CA certificates that should be
|
||||
* sent to the peer in the Certificate message.
|
||||
*/
|
||||
static int
|
||||
ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
|
||||
{
|
||||
X509 *ca, *x = NULL;
|
||||
unsigned long err;
|
||||
int ret = 0;
|
||||
|
||||
if ((x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
|
||||
ctx->default_passwd_callback_userdata)) == NULL) {
|
||||
SSLerrorx(ERR_R_PEM_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!SSL_CTX_use_certificate(ctx, x))
|
||||
goto err;
|
||||
|
||||
if (!ssl_cert_set0_chain(ctx->internal->cert, NULL))
|
||||
goto err;
|
||||
|
||||
/* Process any additional CA certificates. */
|
||||
while ((ca = PEM_read_bio_X509(in, NULL,
|
||||
ctx->default_passwd_callback,
|
||||
ctx->default_passwd_callback_userdata)) != NULL) {
|
||||
if (!ssl_cert_add0_chain_cert(ctx->internal->cert, ca)) {
|
||||
X509_free(ca);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* When the while loop ends, it's usually just EOF. */
|
||||
err = ERR_peek_last_error();
|
||||
if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
|
||||
ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
|
||||
ERR_clear_error();
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
err:
|
||||
X509_free(x);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
BIO *in;
|
||||
int ret = 0;
|
||||
|
||||
in = BIO_new(BIO_s_file_internal());
|
||||
if (in == NULL) {
|
||||
SSLerrorx(ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (BIO_read_filename(in, file) <= 0) {
|
||||
SSLerrorx(ERR_R_SYS_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
|
||||
{
|
||||
BIO *in;
|
||||
int ret = 0;
|
||||
|
||||
in = BIO_new_mem_buf(buf, len);
|
||||
if (in == NULL) {
|
||||
SSLerrorx(ERR_R_BUF_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
1220
externals/libressl/ssl/ssl_sess.c
vendored
Executable file
1220
externals/libressl/ssl/ssl_sess.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
337
externals/libressl/ssl/ssl_sigalgs.c
vendored
Executable file
337
externals/libressl/ssl/ssl_sigalgs.c
vendored
Executable file
@@ -0,0 +1,337 @@
|
||||
/* $OpenBSD: ssl_sigalgs.c,v 1.21 2020/05/09 16:52:15 beck Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_locl.h"
|
||||
#include "ssl_sigalgs.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
const struct ssl_sigalg sigalgs[] = {
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA512,
|
||||
.md = EVP_sha512,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP521R1_SHA512,
|
||||
.md = EVP_sha512,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.curve_nid = NID_secp521r1,
|
||||
},
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
.value = SIGALG_GOSTR12_512_STREEBOG_512,
|
||||
.md = EVP_streebog512,
|
||||
.key_type = EVP_PKEY_GOSTR12_512,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA384,
|
||||
.md = EVP_sha384,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP384R1_SHA384,
|
||||
.md = EVP_sha384,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.curve_nid = NID_secp384r1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA256,
|
||||
.md = EVP_sha256,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP256R1_SHA256,
|
||||
.md = EVP_sha256,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.curve_nid = NID_X9_62_prime256v1,
|
||||
},
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
.value = SIGALG_GOSTR12_256_STREEBOG_256,
|
||||
.md = EVP_streebog256,
|
||||
.key_type = EVP_PKEY_GOSTR12_256,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_GOSTR01_GOST94,
|
||||
.md = EVP_gostr341194,
|
||||
.key_type = EVP_PKEY_GOSTR01,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_RSAE_SHA256,
|
||||
.md = EVP_sha256,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_RSAE_SHA384,
|
||||
.md = EVP_sha384,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_RSAE_SHA512,
|
||||
.md = EVP_sha512,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_PSS_SHA256,
|
||||
.md = EVP_sha256,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_PSS_SHA384,
|
||||
.md = EVP_sha384,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_PSS_SHA512,
|
||||
.md = EVP_sha512,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA224,
|
||||
.md = EVP_sha224,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP224R1_SHA224,
|
||||
.md = EVP_sha224,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA1,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SHA1,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.md = EVP_sha1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_MD5_SHA1,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_md5_sha1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
/* Sigalgs for tls 1.3, in preference order, */
|
||||
uint16_t tls13_sigalgs[] = {
|
||||
SIGALG_RSA_PSS_RSAE_SHA512,
|
||||
SIGALG_RSA_PKCS1_SHA512,
|
||||
SIGALG_ECDSA_SECP521R1_SHA512,
|
||||
SIGALG_RSA_PSS_RSAE_SHA384,
|
||||
SIGALG_RSA_PKCS1_SHA384,
|
||||
SIGALG_ECDSA_SECP384R1_SHA384,
|
||||
SIGALG_RSA_PSS_RSAE_SHA256,
|
||||
SIGALG_RSA_PKCS1_SHA256,
|
||||
SIGALG_ECDSA_SECP256R1_SHA256,
|
||||
};
|
||||
size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0]));
|
||||
|
||||
/* Sigalgs for tls 1.2, in preference order, */
|
||||
uint16_t tls12_sigalgs[] = {
|
||||
SIGALG_RSA_PSS_RSAE_SHA512,
|
||||
SIGALG_RSA_PKCS1_SHA512,
|
||||
SIGALG_ECDSA_SECP521R1_SHA512,
|
||||
SIGALG_RSA_PSS_RSAE_SHA384,
|
||||
SIGALG_RSA_PKCS1_SHA384,
|
||||
SIGALG_ECDSA_SECP384R1_SHA384,
|
||||
SIGALG_RSA_PSS_RSAE_SHA256,
|
||||
SIGALG_RSA_PKCS1_SHA256,
|
||||
SIGALG_ECDSA_SECP256R1_SHA256,
|
||||
SIGALG_RSA_PKCS1_SHA1, /* XXX */
|
||||
SIGALG_ECDSA_SHA1, /* XXX */
|
||||
};
|
||||
size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
|
||||
|
||||
const struct ssl_sigalg *
|
||||
ssl_sigalg_lookup(uint16_t sigalg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) {
|
||||
if (sigalgs[i].value == sigalg)
|
||||
return &sigalgs[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct ssl_sigalg *
|
||||
ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (values[i] == sigalg)
|
||||
return ssl_sigalg_lookup(sigalg);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++);
|
||||
if (len > i)
|
||||
return 0;
|
||||
|
||||
/* XXX check for duplicates and other sanity BS? */
|
||||
|
||||
/* Add values in order as long as they are supported. */
|
||||
for (i = 0; i < len; i++) {
|
||||
/* Do not allow the legacy value for < 1.2 to be used */
|
||||
if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1)
|
||||
return 0;
|
||||
|
||||
if (ssl_sigalg_lookup(values[i]) != NULL) {
|
||||
if (!CBB_add_u16(cbb, values[i]))
|
||||
return 0;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
|
||||
int check_curve)
|
||||
{
|
||||
if (sigalg == NULL || pkey == NULL)
|
||||
return 0;
|
||||
if (sigalg->key_type != pkey->type)
|
||||
return 0;
|
||||
|
||||
if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) {
|
||||
/*
|
||||
* RSA PSS Must have an RSA key that needs to be at
|
||||
* least as big as twice the size of the hash + 2
|
||||
*/
|
||||
if (pkey->type != EVP_PKEY_RSA ||
|
||||
EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pkey->type == EVP_PKEY_EC && check_curve) {
|
||||
/* Curve must match for EC keys. */
|
||||
if (sigalg->curve_nid == 0)
|
||||
return 0;
|
||||
if (EC_GROUP_get_curve_name(EC_KEY_get0_group
|
||||
(EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const struct ssl_sigalg *
|
||||
ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
|
||||
{
|
||||
uint16_t *tls_sigalgs = tls12_sigalgs;
|
||||
size_t tls_sigalgs_len = tls12_sigalgs_len;
|
||||
int check_curve = 0;
|
||||
CBS cbs;
|
||||
|
||||
if (TLS1_get_version(s) >= TLS1_3_VERSION) {
|
||||
tls_sigalgs = tls13_sigalgs;
|
||||
tls_sigalgs_len = tls13_sigalgs_len;
|
||||
check_curve = 1;
|
||||
}
|
||||
|
||||
/* Pre TLS 1.2 defaults */
|
||||
if (!SSL_USE_SIGALGS(s)) {
|
||||
switch (pkey->type) {
|
||||
case EVP_PKEY_RSA:
|
||||
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
|
||||
case EVP_PKEY_EC:
|
||||
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
case EVP_PKEY_GOSTR01:
|
||||
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
|
||||
#endif
|
||||
}
|
||||
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 5246 allows a TLS 1.2 client to send no sigalgs, in
|
||||
* which case the server must use the the default.
|
||||
*/
|
||||
if (TLS1_get_version(s) < TLS1_3_VERSION &&
|
||||
S3I(s)->hs.sigalgs == NULL) {
|
||||
switch (pkey->type) {
|
||||
case EVP_PKEY_RSA:
|
||||
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1);
|
||||
case EVP_PKEY_EC:
|
||||
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
case EVP_PKEY_GOSTR01:
|
||||
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
|
||||
#endif
|
||||
}
|
||||
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, we have client or server sent sigalgs, use one.
|
||||
*/
|
||||
CBS_init(&cbs, S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
|
||||
while (CBS_len(&cbs) > 0) {
|
||||
uint16_t sig_alg;
|
||||
const struct ssl_sigalg *sigalg;
|
||||
|
||||
if (!CBS_get_u16(&cbs, &sig_alg))
|
||||
return 0;
|
||||
|
||||
if ((sigalg = ssl_sigalg(sig_alg, tls_sigalgs,
|
||||
tls_sigalgs_len)) == NULL)
|
||||
continue;
|
||||
|
||||
/* RSA cannot be used without PSS in TLSv1.3. */
|
||||
if (TLS1_get_version(s) >= TLS1_3_VERSION &&
|
||||
sigalg->key_type == EVP_PKEY_RSA &&
|
||||
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
|
||||
continue;
|
||||
|
||||
if (ssl_sigalg_pkey_ok(sigalg, pkey, check_curve))
|
||||
return sigalg;
|
||||
}
|
||||
|
||||
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
86
externals/libressl/ssl/ssl_sigalgs.h
vendored
Executable file
86
externals/libressl/ssl/ssl_sigalgs.h
vendored
Executable file
@@ -0,0 +1,86 @@
|
||||
/* $OpenBSD: ssl_sigalgs.h,v 1.14 2019/03/25 17:33:26 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_SSL_SIGALGS_H
|
||||
#define HEADER_SSL_SIGALGS_H
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define SIGALG_NONE 0x0000
|
||||
|
||||
/*
|
||||
* RFC 8446 Section 4.2.3
|
||||
* RFC 5246 Section 7.4.1.4.1
|
||||
*/
|
||||
#define SIGALG_RSA_PKCS1_SHA224 0x0301
|
||||
#define SIGALG_RSA_PKCS1_SHA256 0x0401
|
||||
#define SIGALG_RSA_PKCS1_SHA384 0x0501
|
||||
#define SIGALG_RSA_PKCS1_SHA512 0x0601
|
||||
#define SIGALG_ECDSA_SECP224R1_SHA224 0x0303
|
||||
#define SIGALG_ECDSA_SECP256R1_SHA256 0x0403
|
||||
#define SIGALG_ECDSA_SECP384R1_SHA384 0x0503
|
||||
#define SIGALG_ECDSA_SECP521R1_SHA512 0x0603
|
||||
#define SIGALG_RSA_PSS_RSAE_SHA256 0x0804
|
||||
#define SIGALG_RSA_PSS_RSAE_SHA384 0x0805
|
||||
#define SIGALG_RSA_PSS_RSAE_SHA512 0x0806
|
||||
#define SIGALG_ED25519 0x0807
|
||||
#define SIGALG_ED448 0x0808
|
||||
#define SIGALG_RSA_PSS_PSS_SHA256 0x0809
|
||||
#define SIGALG_RSA_PSS_PSS_SHA384 0x080a
|
||||
#define SIGALG_RSA_PSS_PSS_SHA512 0x080b
|
||||
#define SIGALG_RSA_PKCS1_SHA1 0x0201
|
||||
#define SIGALG_ECDSA_SHA1 0x0203
|
||||
#define SIGALG_PRIVATE_START 0xFE00
|
||||
#define SIGALG_PRIVATE_END 0xFFFF
|
||||
|
||||
/*
|
||||
* If Russia can elect the US President, surely
|
||||
* IANA could fix this problem.
|
||||
*/
|
||||
#define SIGALG_GOSTR12_512_STREEBOG_512 0xEFEF
|
||||
#define SIGALG_GOSTR12_256_STREEBOG_256 0xEEEE
|
||||
#define SIGALG_GOSTR01_GOST94 0xEDED
|
||||
|
||||
/* Legacy sigalg for < 1.2 same value as boring uses*/
|
||||
#define SIGALG_RSA_PKCS1_MD5_SHA1 0xFF01
|
||||
|
||||
#define SIGALG_FLAG_RSA_PSS 0x00000001
|
||||
|
||||
struct ssl_sigalg{
|
||||
uint16_t value;
|
||||
const EVP_MD *(*md)(void);
|
||||
int key_type;
|
||||
int curve_nid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
extern uint16_t tls12_sigalgs[];
|
||||
extern size_t tls12_sigalgs_len;
|
||||
extern uint16_t tls13_sigalgs[];
|
||||
extern size_t tls13_sigalgs_len;
|
||||
|
||||
const struct ssl_sigalg *ssl_sigalg_lookup(uint16_t sigalg);
|
||||
const struct ssl_sigalg *ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len);
|
||||
int ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len);
|
||||
int ssl_sigalg_pkey_check(uint16_t sigalg, EVP_PKEY *pk);
|
||||
int ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
|
||||
int check_curve);
|
||||
const struct ssl_sigalg *ssl_sigalg_select(SSL *s, EVP_PKEY *pkey);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
2653
externals/libressl/ssl/ssl_srvr.c
vendored
Executable file
2653
externals/libressl/ssl/ssl_srvr.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
801
externals/libressl/ssl/ssl_stat.c
vendored
Executable file
801
externals/libressl/ssl/ssl_stat.c
vendored
Executable file
@@ -0,0 +1,801 @@
|
||||
/* $OpenBSD: ssl_stat.c,v 1.14 2017/05/07 04:22:24 beck Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* The portions of the attached software ("Contribution") is developed by
|
||||
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
|
||||
* license.
|
||||
*
|
||||
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
|
||||
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
|
||||
* support (see RFC 4279) to OpenSSL.
|
||||
*
|
||||
* No patent licenses or other rights except those expressly stated in
|
||||
* the OpenSSL open source license shall be deemed granted or received
|
||||
* expressly, by implication, estoppel, or otherwise.
|
||||
*
|
||||
* No assurances are provided by Nokia that the Contribution does not
|
||||
* infringe the patent or other intellectual property rights of any third
|
||||
* party or that the license provides you with all the necessary rights
|
||||
* to make use of the Contribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
|
||||
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
|
||||
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
|
||||
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
|
||||
* OTHERWISE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
const char *
|
||||
SSL_state_string_long(const SSL *s)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (S3I(s)->hs.state) {
|
||||
case SSL_ST_BEFORE:
|
||||
str = "before SSL initialization";
|
||||
break;
|
||||
case SSL_ST_ACCEPT:
|
||||
str = "before accept initialization";
|
||||
break;
|
||||
case SSL_ST_CONNECT:
|
||||
str = "before connect initialization";
|
||||
break;
|
||||
case SSL_ST_OK:
|
||||
str = "SSL negotiation finished successfully";
|
||||
break;
|
||||
case SSL_ST_RENEGOTIATE:
|
||||
str = "SSL renegotiate ciphers";
|
||||
break;
|
||||
case SSL_ST_BEFORE|SSL_ST_CONNECT:
|
||||
str = "before/connect initialization";
|
||||
break;
|
||||
case SSL_ST_OK|SSL_ST_CONNECT:
|
||||
str = "ok/connect SSL initialization";
|
||||
break;
|
||||
case SSL_ST_BEFORE|SSL_ST_ACCEPT:
|
||||
str = "before/accept initialization";
|
||||
break;
|
||||
case SSL_ST_OK|SSL_ST_ACCEPT:
|
||||
str = "ok/accept SSL initialization";
|
||||
break;
|
||||
|
||||
/* SSLv3 additions */
|
||||
case SSL3_ST_CW_CLNT_HELLO_A:
|
||||
str = "SSLv3 write client hello A";
|
||||
break;
|
||||
case SSL3_ST_CW_CLNT_HELLO_B:
|
||||
str = "SSLv3 write client hello B";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_HELLO_A:
|
||||
str = "SSLv3 read server hello A";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_HELLO_B:
|
||||
str = "SSLv3 read server hello B";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_A:
|
||||
str = "SSLv3 read server certificate A";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_B:
|
||||
str = "SSLv3 read server certificate B";
|
||||
break;
|
||||
case SSL3_ST_CR_KEY_EXCH_A:
|
||||
str = "SSLv3 read server key exchange A";
|
||||
break;
|
||||
case SSL3_ST_CR_KEY_EXCH_B:
|
||||
str = "SSLv3 read server key exchange B";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_REQ_A:
|
||||
str = "SSLv3 read server certificate request A";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_REQ_B:
|
||||
str = "SSLv3 read server certificate request B";
|
||||
break;
|
||||
case SSL3_ST_CR_SESSION_TICKET_A:
|
||||
str = "SSLv3 read server session ticket A";
|
||||
break;
|
||||
case SSL3_ST_CR_SESSION_TICKET_B:
|
||||
str = "SSLv3 read server session ticket B";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_A:
|
||||
str = "SSLv3 read server done A";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
str = "SSLv3 read server done B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_A:
|
||||
str = "SSLv3 write client certificate A";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_B:
|
||||
str = "SSLv3 write client certificate B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_C:
|
||||
str = "SSLv3 write client certificate C";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_D:
|
||||
str = "SSLv3 write client certificate D";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_A:
|
||||
str = "SSLv3 write client key exchange A";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_B:
|
||||
str = "SSLv3 write client key exchange B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_VRFY_A:
|
||||
str = "SSLv3 write certificate verify A";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_VRFY_B:
|
||||
str = "SSLv3 write certificate verify B";
|
||||
break;
|
||||
|
||||
case SSL3_ST_CW_CHANGE_A:
|
||||
case SSL3_ST_SW_CHANGE_A:
|
||||
str = "SSLv3 write change cipher spec A";
|
||||
break;
|
||||
case SSL3_ST_CW_CHANGE_B:
|
||||
case SSL3_ST_SW_CHANGE_B:
|
||||
str = "SSLv3 write change cipher spec B";
|
||||
break;
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
case SSL3_ST_SW_FINISHED_A:
|
||||
str = "SSLv3 write finished A";
|
||||
break;
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
case SSL3_ST_SW_FINISHED_B:
|
||||
str = "SSLv3 write finished B";
|
||||
break;
|
||||
case SSL3_ST_CR_CHANGE_A:
|
||||
case SSL3_ST_SR_CHANGE_A:
|
||||
str = "SSLv3 read change cipher spec A";
|
||||
break;
|
||||
case SSL3_ST_CR_CHANGE_B:
|
||||
case SSL3_ST_SR_CHANGE_B:
|
||||
str = "SSLv3 read change cipher spec B";
|
||||
break;
|
||||
case SSL3_ST_CR_FINISHED_A:
|
||||
case SSL3_ST_SR_FINISHED_A:
|
||||
str = "SSLv3 read finished A";
|
||||
break;
|
||||
case SSL3_ST_CR_FINISHED_B:
|
||||
case SSL3_ST_SR_FINISHED_B:
|
||||
str = "SSLv3 read finished B";
|
||||
break;
|
||||
|
||||
case SSL3_ST_CW_FLUSH:
|
||||
case SSL3_ST_SW_FLUSH:
|
||||
str = "SSLv3 flush data";
|
||||
break;
|
||||
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
str = "SSLv3 read client hello A";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
str = "SSLv3 read client hello B";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
str = "SSLv3 read client hello C";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_A:
|
||||
str = "SSLv3 write hello request A";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_B:
|
||||
str = "SSLv3 write hello request B";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_C:
|
||||
str = "SSLv3 write hello request C";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||
str = "SSLv3 write server hello A";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_B:
|
||||
str = "SSLv3 write server hello B";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
str = "SSLv3 write certificate A";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
str = "SSLv3 write certificate B";
|
||||
break;
|
||||
case SSL3_ST_SW_KEY_EXCH_A:
|
||||
str = "SSLv3 write key exchange A";
|
||||
break;
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
str = "SSLv3 write key exchange B";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_A:
|
||||
str = "SSLv3 write certificate request A";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_B:
|
||||
str = "SSLv3 write certificate request B";
|
||||
break;
|
||||
case SSL3_ST_SW_SESSION_TICKET_A:
|
||||
str = "SSLv3 write session ticket A";
|
||||
break;
|
||||
case SSL3_ST_SW_SESSION_TICKET_B:
|
||||
str = "SSLv3 write session ticket B";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_A:
|
||||
str = "SSLv3 write server done A";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_B:
|
||||
str = "SSLv3 write server done B";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_A:
|
||||
str = "SSLv3 read client certificate A";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_B:
|
||||
str = "SSLv3 read client certificate B";
|
||||
break;
|
||||
case SSL3_ST_SR_KEY_EXCH_A:
|
||||
str = "SSLv3 read client key exchange A";
|
||||
break;
|
||||
case SSL3_ST_SR_KEY_EXCH_B:
|
||||
str = "SSLv3 read client key exchange B";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_VRFY_A:
|
||||
str = "SSLv3 read certificate verify A";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_VRFY_B:
|
||||
str = "SSLv3 read certificate verify B";
|
||||
break;
|
||||
|
||||
/* DTLS */
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
|
||||
str = "DTLS1 read hello verify request A";
|
||||
break;
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
|
||||
str = "DTLS1 read hello verify request B";
|
||||
break;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
|
||||
str = "DTLS1 write hello verify request A";
|
||||
break;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
|
||||
str = "DTLS1 write hello verify request B";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "unknown state";
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_rstate_string_long(const SSL *s)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (s->internal->rstate) {
|
||||
case SSL_ST_READ_HEADER:
|
||||
str = "read header";
|
||||
break;
|
||||
case SSL_ST_READ_BODY:
|
||||
str = "read body";
|
||||
break;
|
||||
case SSL_ST_READ_DONE:
|
||||
str = "read done";
|
||||
break;
|
||||
default:
|
||||
str = "unknown";
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_state_string(const SSL *s)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (S3I(s)->hs.state) {
|
||||
case SSL_ST_BEFORE:
|
||||
str = "PINIT ";
|
||||
break;
|
||||
case SSL_ST_ACCEPT:
|
||||
str = "AINIT ";
|
||||
break;
|
||||
case SSL_ST_CONNECT:
|
||||
str = "CINIT ";
|
||||
break;
|
||||
case SSL_ST_OK:
|
||||
str = "SSLOK ";
|
||||
break;
|
||||
|
||||
/* SSLv3 additions */
|
||||
case SSL3_ST_SW_FLUSH:
|
||||
case SSL3_ST_CW_FLUSH:
|
||||
str = "3FLUSH";
|
||||
break;
|
||||
case SSL3_ST_CW_CLNT_HELLO_A:
|
||||
str = "3WCH_A";
|
||||
break;
|
||||
case SSL3_ST_CW_CLNT_HELLO_B:
|
||||
str = "3WCH_B";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_HELLO_A:
|
||||
str = "3RSH_A";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_HELLO_B:
|
||||
str = "3RSH_B";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_A:
|
||||
str = "3RSC_A";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_B:
|
||||
str = "3RSC_B";
|
||||
break;
|
||||
case SSL3_ST_CR_KEY_EXCH_A:
|
||||
str = "3RSKEA";
|
||||
break;
|
||||
case SSL3_ST_CR_KEY_EXCH_B:
|
||||
str = "3RSKEB";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_REQ_A:
|
||||
str = "3RCR_A";
|
||||
break;
|
||||
case SSL3_ST_CR_CERT_REQ_B:
|
||||
str = "3RCR_B";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_A:
|
||||
str = "3RSD_A";
|
||||
break;
|
||||
case SSL3_ST_CR_SRVR_DONE_B:
|
||||
str = "3RSD_B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_A:
|
||||
str = "3WCC_A";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_B:
|
||||
str = "3WCC_B";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_C:
|
||||
str = "3WCC_C";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_D:
|
||||
str = "3WCC_D";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_A:
|
||||
str = "3WCKEA";
|
||||
break;
|
||||
case SSL3_ST_CW_KEY_EXCH_B:
|
||||
str = "3WCKEB";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_VRFY_A:
|
||||
str = "3WCV_A";
|
||||
break;
|
||||
case SSL3_ST_CW_CERT_VRFY_B:
|
||||
str = "3WCV_B";
|
||||
break;
|
||||
|
||||
case SSL3_ST_SW_CHANGE_A:
|
||||
case SSL3_ST_CW_CHANGE_A:
|
||||
str = "3WCCSA";
|
||||
break;
|
||||
case SSL3_ST_SW_CHANGE_B:
|
||||
case SSL3_ST_CW_CHANGE_B:
|
||||
str = "3WCCSB";
|
||||
break;
|
||||
case SSL3_ST_SW_FINISHED_A:
|
||||
case SSL3_ST_CW_FINISHED_A:
|
||||
str = "3WFINA";
|
||||
break;
|
||||
case SSL3_ST_SW_FINISHED_B:
|
||||
case SSL3_ST_CW_FINISHED_B:
|
||||
str = "3WFINB";
|
||||
break;
|
||||
case SSL3_ST_SR_CHANGE_A:
|
||||
case SSL3_ST_CR_CHANGE_A:
|
||||
str = "3RCCSA";
|
||||
break;
|
||||
case SSL3_ST_SR_CHANGE_B:
|
||||
case SSL3_ST_CR_CHANGE_B:
|
||||
str = "3RCCSB";
|
||||
break;
|
||||
case SSL3_ST_SR_FINISHED_A:
|
||||
case SSL3_ST_CR_FINISHED_A:
|
||||
str = "3RFINA";
|
||||
break;
|
||||
case SSL3_ST_SR_FINISHED_B:
|
||||
case SSL3_ST_CR_FINISHED_B:
|
||||
str = "3RFINB";
|
||||
break;
|
||||
|
||||
case SSL3_ST_SW_HELLO_REQ_A:
|
||||
str = "3WHR_A";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_B:
|
||||
str = "3WHR_B";
|
||||
break;
|
||||
case SSL3_ST_SW_HELLO_REQ_C:
|
||||
str = "3WHR_C";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_A:
|
||||
str = "3RCH_A";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_B:
|
||||
str = "3RCH_B";
|
||||
break;
|
||||
case SSL3_ST_SR_CLNT_HELLO_C:
|
||||
str = "3RCH_C";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||
str = "3WSH_A";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_HELLO_B:
|
||||
str = "3WSH_B";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_A:
|
||||
str = "3WSC_A";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
str = "3WSC_B";
|
||||
break;
|
||||
case SSL3_ST_SW_KEY_EXCH_A:
|
||||
str = "3WSKEA";
|
||||
break;
|
||||
case SSL3_ST_SW_KEY_EXCH_B:
|
||||
str = "3WSKEB";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_A:
|
||||
str = "3WCR_A";
|
||||
break;
|
||||
case SSL3_ST_SW_CERT_REQ_B:
|
||||
str = "3WCR_B";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_A:
|
||||
str = "3WSD_A";
|
||||
break;
|
||||
case SSL3_ST_SW_SRVR_DONE_B:
|
||||
str = "3WSD_B";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_A:
|
||||
str = "3RCC_A";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_B:
|
||||
str = "3RCC_B";
|
||||
break;
|
||||
case SSL3_ST_SR_KEY_EXCH_A:
|
||||
str = "3RCKEA";
|
||||
break;
|
||||
case SSL3_ST_SR_KEY_EXCH_B:
|
||||
str = "3RCKEB";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_VRFY_A:
|
||||
str = "3RCV_A";
|
||||
break;
|
||||
case SSL3_ST_SR_CERT_VRFY_B:
|
||||
str = "3RCV_B";
|
||||
break;
|
||||
|
||||
/* DTLS */
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
|
||||
str = "DRCHVA";
|
||||
break;
|
||||
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
|
||||
str = "DRCHVB";
|
||||
break;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
|
||||
str = "DWCHVA";
|
||||
break;
|
||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
|
||||
str = "DWCHVB";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "UNKWN ";
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_alert_type_string_long(int value)
|
||||
{
|
||||
value >>= 8;
|
||||
if (value == SSL3_AL_WARNING)
|
||||
return ("warning");
|
||||
else if (value == SSL3_AL_FATAL)
|
||||
return ("fatal");
|
||||
else
|
||||
return ("unknown");
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_alert_type_string(int value)
|
||||
{
|
||||
value >>= 8;
|
||||
if (value == SSL3_AL_WARNING)
|
||||
return ("W");
|
||||
else if (value == SSL3_AL_FATAL)
|
||||
return ("F");
|
||||
else
|
||||
return ("U");
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_alert_desc_string(int value)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (value & 0xff) {
|
||||
case SSL3_AD_CLOSE_NOTIFY:
|
||||
str = "CN";
|
||||
break;
|
||||
case SSL3_AD_UNEXPECTED_MESSAGE:
|
||||
str = "UM";
|
||||
break;
|
||||
case SSL3_AD_BAD_RECORD_MAC:
|
||||
str = "BM";
|
||||
break;
|
||||
case SSL3_AD_DECOMPRESSION_FAILURE:
|
||||
str = "DF";
|
||||
break;
|
||||
case SSL3_AD_HANDSHAKE_FAILURE:
|
||||
str = "HF";
|
||||
break;
|
||||
case SSL3_AD_NO_CERTIFICATE:
|
||||
str = "NC";
|
||||
break;
|
||||
case SSL3_AD_BAD_CERTIFICATE:
|
||||
str = "BC";
|
||||
break;
|
||||
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
|
||||
str = "UC";
|
||||
break;
|
||||
case SSL3_AD_CERTIFICATE_REVOKED:
|
||||
str = "CR";
|
||||
break;
|
||||
case SSL3_AD_CERTIFICATE_EXPIRED:
|
||||
str = "CE";
|
||||
break;
|
||||
case SSL3_AD_CERTIFICATE_UNKNOWN:
|
||||
str = "CU";
|
||||
break;
|
||||
case SSL3_AD_ILLEGAL_PARAMETER:
|
||||
str = "IP";
|
||||
break;
|
||||
case TLS1_AD_DECRYPTION_FAILED:
|
||||
str = "DC";
|
||||
break;
|
||||
case TLS1_AD_RECORD_OVERFLOW:
|
||||
str = "RO";
|
||||
break;
|
||||
case TLS1_AD_UNKNOWN_CA:
|
||||
str = "CA";
|
||||
break;
|
||||
case TLS1_AD_ACCESS_DENIED:
|
||||
str = "AD";
|
||||
break;
|
||||
case TLS1_AD_DECODE_ERROR:
|
||||
str = "DE";
|
||||
break;
|
||||
case TLS1_AD_DECRYPT_ERROR:
|
||||
str = "CY";
|
||||
break;
|
||||
case TLS1_AD_EXPORT_RESTRICTION:
|
||||
str = "ER";
|
||||
break;
|
||||
case TLS1_AD_PROTOCOL_VERSION:
|
||||
str = "PV";
|
||||
break;
|
||||
case TLS1_AD_INSUFFICIENT_SECURITY:
|
||||
str = "IS";
|
||||
break;
|
||||
case TLS1_AD_INTERNAL_ERROR:
|
||||
str = "IE";
|
||||
break;
|
||||
case TLS1_AD_USER_CANCELLED:
|
||||
str = "US";
|
||||
break;
|
||||
case TLS1_AD_NO_RENEGOTIATION:
|
||||
str = "NR";
|
||||
break;
|
||||
case TLS1_AD_UNSUPPORTED_EXTENSION:
|
||||
str = "UE";
|
||||
break;
|
||||
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
|
||||
str = "CO";
|
||||
break;
|
||||
case TLS1_AD_UNRECOGNIZED_NAME:
|
||||
str = "UN";
|
||||
break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
|
||||
str = "BR";
|
||||
break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
|
||||
str = "BH";
|
||||
break;
|
||||
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
|
||||
str = "UP";
|
||||
break;
|
||||
default:
|
||||
str = "UK";
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_alert_desc_string_long(int value)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (value & 0xff) {
|
||||
case SSL3_AD_CLOSE_NOTIFY:
|
||||
str = "close notify";
|
||||
break;
|
||||
case SSL3_AD_UNEXPECTED_MESSAGE:
|
||||
str = "unexpected_message";
|
||||
break;
|
||||
case SSL3_AD_BAD_RECORD_MAC:
|
||||
str = "bad record mac";
|
||||
break;
|
||||
case SSL3_AD_DECOMPRESSION_FAILURE:
|
||||
str = "decompression failure";
|
||||
break;
|
||||
case SSL3_AD_HANDSHAKE_FAILURE:
|
||||
str = "handshake failure";
|
||||
break;
|
||||
case SSL3_AD_NO_CERTIFICATE:
|
||||
str = "no certificate";
|
||||
break;
|
||||
case SSL3_AD_BAD_CERTIFICATE:
|
||||
str = "bad certificate";
|
||||
break;
|
||||
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
|
||||
str = "unsupported certificate";
|
||||
break;
|
||||
case SSL3_AD_CERTIFICATE_REVOKED:
|
||||
str = "certificate revoked";
|
||||
break;
|
||||
case SSL3_AD_CERTIFICATE_EXPIRED:
|
||||
str = "certificate expired";
|
||||
break;
|
||||
case SSL3_AD_CERTIFICATE_UNKNOWN:
|
||||
str = "certificate unknown";
|
||||
break;
|
||||
case SSL3_AD_ILLEGAL_PARAMETER:
|
||||
str = "illegal parameter";
|
||||
break;
|
||||
case TLS1_AD_DECRYPTION_FAILED:
|
||||
str = "decryption failed";
|
||||
break;
|
||||
case TLS1_AD_RECORD_OVERFLOW:
|
||||
str = "record overflow";
|
||||
break;
|
||||
case TLS1_AD_UNKNOWN_CA:
|
||||
str = "unknown CA";
|
||||
break;
|
||||
case TLS1_AD_ACCESS_DENIED:
|
||||
str = "access denied";
|
||||
break;
|
||||
case TLS1_AD_DECODE_ERROR:
|
||||
str = "decode error";
|
||||
break;
|
||||
case TLS1_AD_DECRYPT_ERROR:
|
||||
str = "decrypt error";
|
||||
break;
|
||||
case TLS1_AD_EXPORT_RESTRICTION:
|
||||
str = "export restriction";
|
||||
break;
|
||||
case TLS1_AD_PROTOCOL_VERSION:
|
||||
str = "protocol version";
|
||||
break;
|
||||
case TLS1_AD_INSUFFICIENT_SECURITY:
|
||||
str = "insufficient security";
|
||||
break;
|
||||
case TLS1_AD_INTERNAL_ERROR:
|
||||
str = "internal error";
|
||||
break;
|
||||
case TLS1_AD_USER_CANCELLED:
|
||||
str = "user canceled";
|
||||
break;
|
||||
case TLS1_AD_NO_RENEGOTIATION:
|
||||
str = "no renegotiation";
|
||||
break;
|
||||
case TLS1_AD_UNSUPPORTED_EXTENSION:
|
||||
str = "unsupported extension";
|
||||
break;
|
||||
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
|
||||
str = "certificate unobtainable";
|
||||
break;
|
||||
case TLS1_AD_UNRECOGNIZED_NAME:
|
||||
str = "unrecognized name";
|
||||
break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
|
||||
str = "bad certificate status response";
|
||||
break;
|
||||
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
|
||||
str = "bad certificate hash value";
|
||||
break;
|
||||
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
|
||||
str = "unknown PSK identity";
|
||||
break;
|
||||
default:
|
||||
str = "unknown";
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
const char *
|
||||
SSL_rstate_string(const SSL *s)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (s->internal->rstate) {
|
||||
case SSL_ST_READ_HEADER:
|
||||
str = "RH";
|
||||
break;
|
||||
case SSL_ST_READ_BODY:
|
||||
str = "RB";
|
||||
break;
|
||||
case SSL_ST_READ_DONE:
|
||||
str = "RD";
|
||||
break;
|
||||
default:
|
||||
str = "unknown";
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
2240
externals/libressl/ssl/ssl_tlsext.c
vendored
Executable file
2240
externals/libressl/ssl/ssl_tlsext.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
141
externals/libressl/ssl/ssl_tlsext.h
vendored
Executable file
141
externals/libressl/ssl/ssl_tlsext.h
vendored
Executable file
@@ -0,0 +1,141 @@
|
||||
/* $OpenBSD: ssl_tlsext.h,v 1.25 2020/07/03 04:51:59 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
|
||||
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
|
||||
* Copyright (c) 2019 Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_SSL_TLSEXT_H
|
||||
#define HEADER_SSL_TLSEXT_H
|
||||
|
||||
/* TLSv1.3 - RFC 8446 Section 4.2. */
|
||||
#define SSL_TLSEXT_MSG_CH 0x0001 /* ClientHello */
|
||||
#define SSL_TLSEXT_MSG_SH 0x0002 /* ServerHello */
|
||||
#define SSL_TLSEXT_MSG_EE 0x0004 /* EncryptedExtension */
|
||||
#define SSL_TLSEXT_MSG_CT 0x0008 /* Certificate */
|
||||
#define SSL_TLSEXT_MSG_CR 0x0010 /* CertificateRequest */
|
||||
#define SSL_TLSEXT_MSG_NST 0x0020 /* NewSessionTicket */
|
||||
#define SSL_TLSEXT_MSG_HRR 0x0040 /* HelloRetryRequest */
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
int tlsext_alpn_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_alpn_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_alpn_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_alpn_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_alpn_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_alpn_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
int tlsext_ri_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_ri_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_ri_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_ri_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_ri_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_ri_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
int tlsext_sigalgs_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_sigalgs_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_sigalgs_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
int tlsext_sigalgs_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_sigalgs_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_sigalgs_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
|
||||
int tlsext_sni_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_sni_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_sni_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_sni_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_sni_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_sni_is_valid_hostname(CBS *cbs);
|
||||
|
||||
int tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_supportedgroups_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_supportedgroups_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
int tlsext_supportedgroups_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_supportedgroups_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_supportedgroups_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
|
||||
int tlsext_ecpf_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_ecpf_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_ecpf_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_ecpf_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_ecpf_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_ecpf_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
int tlsext_ocsp_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_ocsp_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_ocsp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_ocsp_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_ocsp_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_ocsp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
int tlsext_sessionticket_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_sessionticket_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_sessionticket_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
int tlsext_sessionticket_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_sessionticket_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_sessionticket_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
|
||||
int tlsext_versions_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_versions_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_versions_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
int tlsext_versions_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_versions_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_versions_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
|
||||
int tlsext_keyshare_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_keyshare_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
int tlsext_keyshare_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_keyshare_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
|
||||
int *alert);
|
||||
|
||||
int tlsext_cookie_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_cookie_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_cookie_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_cookie_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_cookie_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_cookie_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
int tlsext_srtp_client_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_srtp_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_srtp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
int tlsext_srtp_server_needs(SSL *s, uint16_t msg_type);
|
||||
int tlsext_srtp_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_srtp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
#endif
|
||||
|
||||
int tlsext_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
int tlsext_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
|
||||
int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
|
||||
|
||||
struct tls_extension *tls_extension_find(uint16_t, size_t *);
|
||||
int tlsext_extension_seen(SSL *s, uint16_t);
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
207
externals/libressl/ssl/ssl_transcript.c
vendored
Executable file
207
externals/libressl/ssl/ssl_transcript.c
vendored
Executable file
@@ -0,0 +1,207 @@
|
||||
/* $OpenBSD: ssl_transcript.c,v 1.2 2020/02/05 16:47:34 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
int
|
||||
tls1_transcript_hash_init(SSL *s)
|
||||
{
|
||||
const unsigned char *data;
|
||||
const EVP_MD *md;
|
||||
size_t len;
|
||||
|
||||
tls1_transcript_hash_free(s);
|
||||
|
||||
if (!ssl_get_handshake_evp_md(s, &md)) {
|
||||
SSLerrorx(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((S3I(s)->handshake_hash = EVP_MD_CTX_new()) == NULL) {
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestInit_ex(S3I(s)->handshake_hash, md, NULL)) {
|
||||
SSLerror(s, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!tls1_transcript_data(s, &data, &len)) {
|
||||
SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH);
|
||||
goto err;
|
||||
}
|
||||
if (!tls1_transcript_hash_update(s, data, len)) {
|
||||
SSLerror(s, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
tls1_transcript_hash_free(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_hash_update(SSL *s, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (S3I(s)->handshake_hash == NULL)
|
||||
return 1;
|
||||
|
||||
return EVP_DigestUpdate(S3I(s)->handshake_hash, buf, len);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_hash_value(SSL *s, const unsigned char *out, size_t len,
|
||||
size_t *outlen)
|
||||
{
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
unsigned int mdlen;
|
||||
int ret = 0;
|
||||
|
||||
if (EVP_MD_CTX_size(S3I(s)->handshake_hash) > len)
|
||||
goto err;
|
||||
|
||||
if ((mdctx = EVP_MD_CTX_new()) == NULL) {
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_MD_CTX_copy_ex(mdctx, S3I(s)->handshake_hash)) {
|
||||
SSLerror(s, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(mdctx, (unsigned char *)out, &mdlen)) {
|
||||
SSLerror(s, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (outlen != NULL)
|
||||
*outlen = mdlen;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_hash_free(SSL *s)
|
||||
{
|
||||
EVP_MD_CTX_free(S3I(s)->handshake_hash);
|
||||
S3I(s)->handshake_hash = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_init(SSL *s)
|
||||
{
|
||||
if (S3I(s)->handshake_transcript != NULL)
|
||||
return 0;
|
||||
|
||||
if ((S3I(s)->handshake_transcript = BUF_MEM_new()) == NULL)
|
||||
return 0;
|
||||
|
||||
tls1_transcript_reset(s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_free(SSL *s)
|
||||
{
|
||||
BUF_MEM_free(S3I(s)->handshake_transcript);
|
||||
S3I(s)->handshake_transcript = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_reset(SSL *s)
|
||||
{
|
||||
/*
|
||||
* We should check the return value of BUF_MEM_grow_clean(), however
|
||||
* due to yet another bad API design, when called with a length of zero
|
||||
* it is impossible to tell if it succeeded (returning a length of zero)
|
||||
* or if it failed (and returned zero)... our implementation never
|
||||
* fails with a length of zero, so we trust all is okay...
|
||||
*/
|
||||
(void)BUF_MEM_grow_clean(S3I(s)->handshake_transcript, 0);
|
||||
|
||||
tls1_transcript_unfreeze(s);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t olen, nlen;
|
||||
|
||||
if (S3I(s)->handshake_transcript == NULL)
|
||||
return 1;
|
||||
|
||||
if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT)
|
||||
return 1;
|
||||
|
||||
olen = S3I(s)->handshake_transcript->length;
|
||||
nlen = olen + len;
|
||||
|
||||
if (nlen < olen)
|
||||
return 0;
|
||||
|
||||
if (BUF_MEM_grow(S3I(s)->handshake_transcript, nlen) == 0)
|
||||
return 0;
|
||||
|
||||
memcpy(S3I(s)->handshake_transcript->data + olen, buf, len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len)
|
||||
{
|
||||
if (S3I(s)->handshake_transcript == NULL)
|
||||
return 0;
|
||||
|
||||
*data = S3I(s)->handshake_transcript->data;
|
||||
*len = S3I(s)->handshake_transcript->length;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_freeze(SSL *s)
|
||||
{
|
||||
s->s3->flags |= TLS1_FLAGS_FREEZE_TRANSCRIPT;
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_unfreeze(SSL *s)
|
||||
{
|
||||
s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT;
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (!tls1_transcript_hash_update(s, buf, len))
|
||||
return 0;
|
||||
|
||||
if (!tls1_transcript_append(s, buf, len))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
188
externals/libressl/ssl/ssl_txt.c
vendored
Executable file
188
externals/libressl/ssl/ssl_txt.c
vendored
Executable file
@@ -0,0 +1,188 @@
|
||||
/* $OpenBSD: ssl_txt.c,v 1.28 2017/02/07 02:08:38 beck Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* The portions of the attached software ("Contribution") is developed by
|
||||
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
|
||||
* license.
|
||||
*
|
||||
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
|
||||
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
|
||||
* support (see RFC 4279) to OpenSSL.
|
||||
*
|
||||
* No patent licenses or other rights except those expressly stated in
|
||||
* the OpenSSL open source license shall be deemed granted or received
|
||||
* expressly, by implication, estoppel, or otherwise.
|
||||
*
|
||||
* No assurances are provided by Nokia that the Contribution does not
|
||||
* infringe the patent or other intellectual property rights of any third
|
||||
* party or that the license provides you with all the necessary rights
|
||||
* to make use of the Contribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
|
||||
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
|
||||
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
|
||||
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
|
||||
* OTHERWISE.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/buffer.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
int
|
||||
SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b = BIO_new(BIO_s_file_internal())) == NULL) {
|
||||
SSLerrorx(ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = SSL_SESSION_print(b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
|
||||
{
|
||||
unsigned int i;
|
||||
const char *s;
|
||||
|
||||
if (x == NULL)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "SSL-Session:\n") <= 0)
|
||||
goto err;
|
||||
|
||||
s = ssl_version_string(x->ssl_version);
|
||||
if (BIO_printf(bp, " Protocol : %s\n", s) <= 0)
|
||||
goto err;
|
||||
|
||||
if (x->cipher == NULL) {
|
||||
if (((x->cipher_id) & 0xff000000) == 0x02000000) {
|
||||
if (BIO_printf(bp, " Cipher : %06lX\n", x->cipher_id&0xffffff) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (BIO_printf(bp, " Cipher : %04lX\n", x->cipher_id&0xffff) <= 0)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (BIO_printf(bp, " Cipher : %s\n",((x->cipher == NULL)?"unknown":x->cipher->name)) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (BIO_puts(bp, " Session-ID: ") <= 0)
|
||||
goto err;
|
||||
for (i = 0; i < x->session_id_length; i++) {
|
||||
if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0)
|
||||
goto err;
|
||||
for (i = 0; i < x->sid_ctx_length; i++) {
|
||||
if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (BIO_puts(bp, "\n Master-Key: ") <= 0)
|
||||
goto err;
|
||||
for (i = 0; i < (unsigned int)x->master_key_length; i++) {
|
||||
if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (x->tlsext_tick_lifetime_hint) {
|
||||
if (BIO_printf(bp,
|
||||
"\n TLS session ticket lifetime hint: %ld (seconds)",
|
||||
x->tlsext_tick_lifetime_hint) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (x->tlsext_tick) {
|
||||
if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0)
|
||||
goto err;
|
||||
if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (x->time != 0) {
|
||||
if (BIO_printf(bp, "\n Start Time: %"PRId64, (int64_t)x->time) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (x->timeout != 0L) {
|
||||
if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
|
||||
if (BIO_puts(bp, " Verify return code: ") <= 0)
|
||||
goto err;
|
||||
|
||||
if (BIO_printf(bp, "%ld (%s)\n", x->verify_result,
|
||||
X509_verify_cert_error_string(x->verify_result)) <= 0)
|
||||
goto err;
|
||||
|
||||
return (1);
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
233
externals/libressl/ssl/ssl_versions.c
vendored
Executable file
233
externals/libressl/ssl/ssl_versions.c
vendored
Executable file
@@ -0,0 +1,233 @@
|
||||
/* $OpenBSD: ssl_versions.c,v 1.6 2020/05/31 18:03:32 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
static int
|
||||
ssl_clamp_version_range(uint16_t *min_ver, uint16_t *max_ver,
|
||||
uint16_t clamp_min, uint16_t clamp_max)
|
||||
{
|
||||
if (clamp_min > clamp_max || *min_ver > *max_ver)
|
||||
return 0;
|
||||
if (clamp_max < *min_ver || clamp_min > *max_ver)
|
||||
return 0;
|
||||
|
||||
if (*min_ver < clamp_min)
|
||||
*min_ver = clamp_min;
|
||||
if (*max_ver > clamp_max)
|
||||
*max_ver = clamp_max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
|
||||
uint16_t *out_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
|
||||
if (ver == 0) {
|
||||
*out_ver = meth->internal->min_version;
|
||||
return 1;
|
||||
}
|
||||
|
||||
min_version = ver;
|
||||
max_version = max_ver;
|
||||
|
||||
if (!ssl_clamp_version_range(&min_version, &max_version,
|
||||
meth->internal->min_version, meth->internal->max_version))
|
||||
return 0;
|
||||
|
||||
*out_ver = min_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
|
||||
uint16_t *out_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
|
||||
if (ver == 0) {
|
||||
*out_ver = meth->internal->max_version;
|
||||
return 1;
|
||||
}
|
||||
|
||||
min_version = min_ver;
|
||||
max_version = ver;
|
||||
|
||||
if (!ssl_clamp_version_range(&min_version, &max_version,
|
||||
meth->internal->min_version, meth->internal->max_version))
|
||||
return 0;
|
||||
|
||||
*out_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
|
||||
/*
|
||||
* The enabled versions have to be a contiguous range, which means we
|
||||
* cannot enable and disable single versions at our whim, even though
|
||||
* this is what the OpenSSL flags allow. The historical way this has
|
||||
* been handled is by making a flag mean that all higher versions
|
||||
* are disabled, if any version lower than the flag is enabled.
|
||||
*/
|
||||
|
||||
min_version = 0;
|
||||
max_version = TLS1_3_VERSION;
|
||||
|
||||
if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
|
||||
min_version = TLS1_VERSION;
|
||||
else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
|
||||
min_version = TLS1_1_VERSION;
|
||||
else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
|
||||
min_version = TLS1_2_VERSION;
|
||||
else if ((s->internal->options & SSL_OP_NO_TLSv1_3) == 0)
|
||||
min_version = TLS1_3_VERSION;
|
||||
|
||||
if ((s->internal->options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
|
||||
max_version = TLS1_2_VERSION;
|
||||
if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
|
||||
max_version = TLS1_1_VERSION;
|
||||
if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
|
||||
max_version = TLS1_VERSION;
|
||||
if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
|
||||
max_version = 0;
|
||||
|
||||
/* Everything has been disabled... */
|
||||
if (min_version == 0 || max_version == 0)
|
||||
return 0;
|
||||
|
||||
/* Limit to configured version range. */
|
||||
if (!ssl_clamp_version_range(&min_version, &max_version,
|
||||
s->internal->min_version, s->internal->max_version))
|
||||
return 0;
|
||||
|
||||
if (min_ver != NULL)
|
||||
*min_ver = min_version;
|
||||
if (max_ver != NULL)
|
||||
*max_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
|
||||
/* DTLS cannot currently be disabled... */
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
min_version = max_version = DTLS1_VERSION;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!ssl_enabled_version_range(s, &min_version, &max_version))
|
||||
return 0;
|
||||
|
||||
/* Limit to the versions supported by this method. */
|
||||
if (!ssl_clamp_version_range(&min_version, &max_version,
|
||||
s->method->internal->min_version,
|
||||
s->method->internal->max_version))
|
||||
return 0;
|
||||
|
||||
done:
|
||||
if (min_ver != NULL)
|
||||
*min_ver = min_version;
|
||||
if (max_ver != NULL)
|
||||
*max_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t min_version, max_version, shared_version;
|
||||
|
||||
*max_ver = 0;
|
||||
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
if (peer_ver >= DTLS1_VERSION) {
|
||||
*max_ver = DTLS1_VERSION;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (peer_ver >= TLS1_3_VERSION)
|
||||
shared_version = TLS1_3_VERSION;
|
||||
else if (peer_ver >= TLS1_2_VERSION)
|
||||
shared_version = TLS1_2_VERSION;
|
||||
else if (peer_ver >= TLS1_1_VERSION)
|
||||
shared_version = TLS1_1_VERSION;
|
||||
else if (peer_ver >= TLS1_VERSION)
|
||||
shared_version = TLS1_VERSION;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (!ssl_supported_version_range(s, &min_version, &max_version))
|
||||
return 0;
|
||||
|
||||
if (shared_version < min_version)
|
||||
return 0;
|
||||
|
||||
if (shared_version > max_version)
|
||||
shared_version = max_version;
|
||||
|
||||
*max_ver = shared_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_downgrade_max_version(SSL *s, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
|
||||
/*
|
||||
* The downgrade maximum version is based on the versions that are
|
||||
* enabled, however we also have to then limit to the versions
|
||||
* supported by the method. The SSL method will be changed during
|
||||
* version negotiation and when switching from the new stack to
|
||||
* the legacy context, as such we want to use the method from the
|
||||
* context.
|
||||
*/
|
||||
|
||||
if (SSL_IS_DTLS(s)) {
|
||||
*max_ver = DTLS1_VERSION;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ssl_enabled_version_range(s, &min_version, &max_version))
|
||||
return 0;
|
||||
|
||||
if (!ssl_clamp_version_range(&min_version, &max_version,
|
||||
s->ctx->method->internal->min_version,
|
||||
s->ctx->method->internal->max_version))
|
||||
return 0;
|
||||
|
||||
*max_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
1189
externals/libressl/ssl/t1_enc.c
vendored
Executable file
1189
externals/libressl/ssl/t1_enc.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1008
externals/libressl/ssl/t1_lib.c
vendored
Executable file
1008
externals/libressl/ssl/t1_lib.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
542
externals/libressl/ssl/tls12_record_layer.c
vendored
Executable file
542
externals/libressl/ssl/tls12_record_layer.c
vendored
Executable file
@@ -0,0 +1,542 @@
|
||||
/* $OpenBSD: tls12_record_layer.c,v 1.4 2020/09/16 17:15:01 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
struct tls12_record_layer {
|
||||
uint16_t version;
|
||||
int dtls;
|
||||
|
||||
uint16_t read_epoch;
|
||||
uint16_t write_epoch;
|
||||
|
||||
int read_stream_mac;
|
||||
int write_stream_mac;
|
||||
|
||||
/*
|
||||
* XXX - for now these are just pointers to externally managed
|
||||
* structs/memory. These should eventually be owned by the record layer.
|
||||
*/
|
||||
SSL_AEAD_CTX *read_aead_ctx;
|
||||
SSL_AEAD_CTX *write_aead_ctx;
|
||||
|
||||
EVP_CIPHER_CTX *read_cipher_ctx;
|
||||
EVP_MD_CTX *read_hash_ctx;
|
||||
EVP_CIPHER_CTX *write_cipher_ctx;
|
||||
EVP_MD_CTX *write_hash_ctx;
|
||||
|
||||
uint8_t *read_seq_num;
|
||||
uint8_t *write_seq_num;
|
||||
};
|
||||
|
||||
struct tls12_record_layer *
|
||||
tls12_record_layer_new(void)
|
||||
{
|
||||
struct tls12_record_layer *rl;
|
||||
|
||||
if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL)
|
||||
return NULL;
|
||||
|
||||
return rl;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_free(struct tls12_record_layer *rl)
|
||||
{
|
||||
freezero(rl, sizeof(struct tls12_record_layer));
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version)
|
||||
{
|
||||
rl->version = version;
|
||||
rl->dtls = (version == DTLS1_VERSION);
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_set_read_epoch(struct tls12_record_layer *rl, uint16_t epoch)
|
||||
{
|
||||
rl->read_epoch = epoch;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch)
|
||||
{
|
||||
rl->write_epoch = epoch;
|
||||
}
|
||||
|
||||
static void
|
||||
tls12_record_layer_set_read_state(struct tls12_record_layer *rl,
|
||||
SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx,
|
||||
int stream_mac)
|
||||
{
|
||||
rl->read_aead_ctx = aead_ctx;
|
||||
|
||||
rl->read_cipher_ctx = cipher_ctx;
|
||||
rl->read_hash_ctx = hash_ctx;
|
||||
rl->read_stream_mac = stream_mac;
|
||||
}
|
||||
|
||||
static void
|
||||
tls12_record_layer_set_write_state(struct tls12_record_layer *rl,
|
||||
SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx,
|
||||
int stream_mac)
|
||||
{
|
||||
rl->write_aead_ctx = aead_ctx;
|
||||
|
||||
rl->write_cipher_ctx = cipher_ctx;
|
||||
rl->write_hash_ctx = hash_ctx;
|
||||
rl->write_stream_mac = stream_mac;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_clear_read_state(struct tls12_record_layer *rl)
|
||||
{
|
||||
tls12_record_layer_set_read_state(rl, NULL, NULL, NULL, 0);
|
||||
rl->read_seq_num = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_clear_write_state(struct tls12_record_layer *rl)
|
||||
{
|
||||
tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0);
|
||||
rl->write_seq_num = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl,
|
||||
uint8_t *seq_num)
|
||||
{
|
||||
rl->read_seq_num = seq_num;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_record_layer_set_write_seq_num(struct tls12_record_layer *rl,
|
||||
uint8_t *seq_num)
|
||||
{
|
||||
rl->write_seq_num = seq_num;
|
||||
}
|
||||
|
||||
int
|
||||
tls12_record_layer_set_read_aead(struct tls12_record_layer *rl,
|
||||
SSL_AEAD_CTX *aead_ctx)
|
||||
{
|
||||
tls12_record_layer_set_read_state(rl, aead_ctx, NULL, NULL, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls12_record_layer_set_write_aead(struct tls12_record_layer *rl,
|
||||
SSL_AEAD_CTX *aead_ctx)
|
||||
{
|
||||
tls12_record_layer_set_write_state(rl, aead_ctx, NULL, NULL, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl,
|
||||
EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac)
|
||||
{
|
||||
tls12_record_layer_set_read_state(rl, NULL, cipher_ctx, hash_ctx,
|
||||
stream_mac);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl,
|
||||
EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac)
|
||||
{
|
||||
tls12_record_layer_set_write_state(rl, NULL, cipher_ctx, hash_ctx,
|
||||
stream_mac);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb,
|
||||
uint16_t epoch, uint8_t *seq_num, size_t seq_num_len)
|
||||
{
|
||||
CBS seq;
|
||||
|
||||
CBS_init(&seq, seq_num, seq_num_len);
|
||||
|
||||
if (rl->dtls) {
|
||||
if (!CBB_add_u16(cbb, epoch))
|
||||
return 0;
|
||||
if (!CBS_skip(&seq, 2))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBB_add_bytes(cbb, CBS_data(&seq), CBS_len(&seq));
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_pseudo_header(struct tls12_record_layer *rl,
|
||||
uint8_t content_type, uint16_t record_len, uint16_t epoch, uint8_t *seq_num,
|
||||
size_t seq_num_len, uint8_t **out, size_t *out_len)
|
||||
{
|
||||
CBB cbb;
|
||||
|
||||
*out = NULL;
|
||||
*out_len = 0;
|
||||
|
||||
/* Build the pseudo-header used for MAC/AEAD. */
|
||||
if (!CBB_init(&cbb, 13))
|
||||
goto err;
|
||||
|
||||
if (!tls12_record_layer_build_seq_num(rl, &cbb, epoch,
|
||||
seq_num, seq_num_len))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&cbb, content_type))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&cbb, rl->version))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&cbb, record_len))
|
||||
goto err;
|
||||
|
||||
if (!CBB_finish(&cbb, out, out_len))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb,
|
||||
EVP_MD_CTX *hash_ctx, int stream_mac, uint16_t epoch, uint8_t *seq_num,
|
||||
size_t seq_num_len, uint8_t content_type, const uint8_t *content,
|
||||
size_t content_len, size_t *out_len)
|
||||
{
|
||||
EVP_MD_CTX *mac_ctx = NULL;
|
||||
uint8_t *header = NULL;
|
||||
size_t header_len;
|
||||
size_t mac_len;
|
||||
uint8_t *mac;
|
||||
int ret = 0;
|
||||
|
||||
if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!EVP_MD_CTX_copy(mac_ctx, hash_ctx))
|
||||
goto err;
|
||||
|
||||
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
|
||||
epoch, seq_num, seq_num_len, &header, &header_len))
|
||||
goto err;
|
||||
|
||||
if (EVP_DigestSignUpdate(mac_ctx, header, header_len) <= 0)
|
||||
goto err;
|
||||
if (EVP_DigestSignUpdate(mac_ctx, content, content_len) <= 0)
|
||||
goto err;
|
||||
if (EVP_DigestSignFinal(mac_ctx, NULL, &mac_len) <= 0)
|
||||
goto err;
|
||||
if (!CBB_add_space(cbb, &mac, mac_len))
|
||||
goto err;
|
||||
if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0)
|
||||
goto err;
|
||||
|
||||
if (stream_mac) {
|
||||
if (!EVP_MD_CTX_copy(hash_ctx, mac_ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
*out_len = mac_len;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_CTX_free(mac_ctx);
|
||||
free(header);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb,
|
||||
uint8_t content_type, const uint8_t *content, size_t content_len,
|
||||
size_t *out_len)
|
||||
{
|
||||
return tls12_record_layer_mac(rl, cbb, rl->write_hash_ctx,
|
||||
rl->write_stream_mac, rl->write_epoch, rl->write_seq_num,
|
||||
SSL3_SEQUENCE_SIZE, content_type, content, content_len, out_len);
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl,
|
||||
const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len)
|
||||
{
|
||||
CBB cbb;
|
||||
|
||||
if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE)
|
||||
return 0;
|
||||
|
||||
/* Fixed nonce and variable nonce (sequence number) are concatenated. */
|
||||
if (!CBB_init(&cbb, 16))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, aead->fixed_nonce,
|
||||
aead->fixed_nonce_len))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, out, out_len))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl,
|
||||
const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len)
|
||||
{
|
||||
uint8_t *nonce = NULL;
|
||||
size_t nonce_len = 0;
|
||||
uint8_t *pad;
|
||||
CBB cbb;
|
||||
int i;
|
||||
|
||||
if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE)
|
||||
return 0;
|
||||
if (aead->fixed_nonce_len < aead->variable_nonce_len)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Variable nonce (sequence number) is right padded, before the fixed
|
||||
* nonce is XOR'd in.
|
||||
*/
|
||||
if (!CBB_init(&cbb, 16))
|
||||
goto err;
|
||||
if (!CBB_add_space(&cbb, &pad,
|
||||
aead->fixed_nonce_len - aead->variable_nonce_len))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, &nonce, &nonce_len))
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < aead->fixed_nonce_len; i++)
|
||||
nonce[i] ^= aead->fixed_nonce[i];
|
||||
|
||||
*out = nonce;
|
||||
*out_len = nonce_len;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
freezero(nonce, nonce_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl,
|
||||
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
|
||||
{
|
||||
if (rl->write_aead_ctx != NULL || rl->write_cipher_ctx != NULL)
|
||||
return 0;
|
||||
|
||||
return CBB_add_bytes(out, content, content_len);
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl,
|
||||
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
|
||||
{
|
||||
const SSL_AEAD_CTX *aead = rl->write_aead_ctx;
|
||||
uint8_t *header = NULL, *nonce = NULL;
|
||||
size_t header_len = 0, nonce_len = 0;
|
||||
size_t enc_record_len, out_len;
|
||||
uint16_t epoch = 0;
|
||||
uint8_t *enc_data;
|
||||
int ret = 0;
|
||||
|
||||
/* XXX - move to nonce allocated in record layer, matching TLSv1.3 */
|
||||
if (aead->xor_fixed_nonce) {
|
||||
if (!tls12_record_layer_aead_xored_nonce(rl, aead,
|
||||
rl->write_seq_num, &nonce, &nonce_len))
|
||||
goto err;
|
||||
} else {
|
||||
if (!tls12_record_layer_aead_concat_nonce(rl, aead,
|
||||
rl->write_seq_num, &nonce, &nonce_len))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (aead->variable_nonce_in_record) {
|
||||
/* XXX - length check? */
|
||||
if (!CBB_add_bytes(out, rl->write_seq_num, aead->variable_nonce_len))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
|
||||
epoch, rl->write_seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len))
|
||||
goto err;
|
||||
|
||||
/* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */
|
||||
enc_record_len = content_len + aead->tag_len;
|
||||
if (enc_record_len > SSL3_RT_MAX_ENCRYPTED_LENGTH)
|
||||
goto err;
|
||||
if (!CBB_add_space(out, &enc_data, enc_record_len))
|
||||
goto err;
|
||||
|
||||
if (!EVP_AEAD_CTX_seal(&aead->ctx, enc_data, &out_len, enc_record_len,
|
||||
nonce, nonce_len, content, content_len, header, header_len))
|
||||
goto err;
|
||||
|
||||
if (out_len != enc_record_len)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(header, header_len);
|
||||
freezero(nonce, nonce_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl,
|
||||
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
|
||||
{
|
||||
EVP_CIPHER_CTX *enc = rl->write_cipher_ctx;
|
||||
size_t mac_len, pad_len;
|
||||
int block_size, eiv_len;
|
||||
uint8_t *enc_data, *eiv, *pad, pad_val;
|
||||
uint8_t *plain = NULL;
|
||||
size_t plain_len = 0;
|
||||
int ret = 0;
|
||||
CBB cbb;
|
||||
|
||||
if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
|
||||
goto err;
|
||||
|
||||
/* Add explicit IV if necessary. */
|
||||
eiv_len = 0;
|
||||
if (rl->version != TLS1_VERSION &&
|
||||
EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE)
|
||||
eiv_len = EVP_CIPHER_CTX_iv_length(enc);
|
||||
if (eiv_len < 0 || eiv_len > EVP_MAX_IV_LENGTH)
|
||||
goto err;
|
||||
if (eiv_len > 0) {
|
||||
if (!CBB_add_space(&cbb, &eiv, eiv_len))
|
||||
goto err;
|
||||
arc4random_buf(eiv, eiv_len);
|
||||
}
|
||||
|
||||
if (!CBB_add_bytes(&cbb, content, content_len))
|
||||
goto err;
|
||||
|
||||
mac_len = 0;
|
||||
if (rl->write_hash_ctx != NULL) {
|
||||
if (!tls12_record_layer_write_mac(rl, &cbb, content_type,
|
||||
content, content_len, &mac_len))
|
||||
goto err;
|
||||
}
|
||||
|
||||
plain_len = (size_t)eiv_len + content_len + mac_len;
|
||||
|
||||
/* Add padding to block size, if necessary. */
|
||||
block_size = EVP_CIPHER_CTX_block_size(enc);
|
||||
if (block_size < 0 || block_size > EVP_MAX_BLOCK_LENGTH)
|
||||
goto err;
|
||||
if (block_size > 1) {
|
||||
pad_len = block_size - (plain_len % block_size);
|
||||
pad_val = pad_len - 1;
|
||||
|
||||
if (pad_len > 255)
|
||||
goto err;
|
||||
if (!CBB_add_space(&cbb, &pad, pad_len))
|
||||
goto err;
|
||||
memset(pad, pad_val, pad_len);
|
||||
}
|
||||
|
||||
if (!CBB_finish(&cbb, &plain, &plain_len))
|
||||
goto err;
|
||||
|
||||
if (plain_len % block_size != 0)
|
||||
goto err;
|
||||
if (plain_len > SSL3_RT_MAX_ENCRYPTED_LENGTH)
|
||||
goto err;
|
||||
|
||||
if (!CBB_add_space(out, &enc_data, plain_len))
|
||||
goto err;
|
||||
if (!EVP_Cipher(enc, enc_data, plain, plain_len))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
freezero(plain, plain_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls12_record_layer_seal_record(struct tls12_record_layer *rl,
|
||||
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *cbb)
|
||||
{
|
||||
CBB fragment;
|
||||
|
||||
if (!CBB_add_u8(cbb, content_type))
|
||||
return 0;
|
||||
if (!CBB_add_u16(cbb, rl->version))
|
||||
return 0;
|
||||
if (rl->dtls) {
|
||||
if (!tls12_record_layer_build_seq_num(rl, cbb,
|
||||
rl->write_epoch, rl->write_seq_num,
|
||||
SSL3_SEQUENCE_SIZE))
|
||||
return 0;
|
||||
}
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &fragment))
|
||||
return 0;
|
||||
|
||||
if (rl->write_aead_ctx != NULL) {
|
||||
if (!tls12_record_layer_seal_record_protected_aead(rl,
|
||||
content_type, content, content_len, &fragment))
|
||||
return 0;
|
||||
} else if (rl->write_cipher_ctx != NULL) {
|
||||
if (!tls12_record_layer_seal_record_protected_cipher(rl,
|
||||
content_type, content, content_len, &fragment))
|
||||
return 0;
|
||||
} else {
|
||||
if (!tls12_record_layer_seal_record_plaintext(rl,
|
||||
content_type, content, content_len, &fragment))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
tls1_record_sequence_increment(rl->write_seq_num);
|
||||
|
||||
return 1;
|
||||
}
|
||||
137
externals/libressl/ssl/tls13_buffer.c
vendored
Executable file
137
externals/libressl/ssl/tls13_buffer.c
vendored
Executable file
@@ -0,0 +1,137 @@
|
||||
/* $OpenBSD: tls13_buffer.c,v 1.3 2020/03/10 17:11:25 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
struct tls13_buffer {
|
||||
size_t capacity;
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
static int tls13_buffer_resize(struct tls13_buffer *buf, size_t capacity);
|
||||
|
||||
struct tls13_buffer *
|
||||
tls13_buffer_new(size_t init_size)
|
||||
{
|
||||
struct tls13_buffer *buf = NULL;
|
||||
|
||||
if ((buf = calloc(1, sizeof(struct tls13_buffer))) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!tls13_buffer_resize(buf, init_size))
|
||||
goto err;
|
||||
|
||||
return buf;
|
||||
|
||||
err:
|
||||
tls13_buffer_free(buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_buffer_free(struct tls13_buffer *buf)
|
||||
{
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
||||
freezero(buf->data, buf->capacity);
|
||||
freezero(buf, sizeof(struct tls13_buffer));
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_buffer_resize(struct tls13_buffer *buf, size_t capacity)
|
||||
{
|
||||
uint8_t *data;
|
||||
|
||||
if (buf->capacity == capacity)
|
||||
return 1;
|
||||
|
||||
if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL)
|
||||
return 0;
|
||||
|
||||
buf->data = data;
|
||||
buf->capacity = capacity;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_buffer_set_data(struct tls13_buffer *buf, CBS *data)
|
||||
{
|
||||
if (!tls13_buffer_resize(buf, CBS_len(data)))
|
||||
return 0;
|
||||
memcpy(buf->data, CBS_data(data), CBS_len(data));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_buffer_extend(struct tls13_buffer *buf, size_t len,
|
||||
tls13_read_cb read_cb, void *cb_arg)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (len == buf->len)
|
||||
return buf->len;
|
||||
|
||||
if (len < buf->len)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (!tls13_buffer_resize(buf, len))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
for (;;) {
|
||||
if ((ret = read_cb(&buf->data[buf->len],
|
||||
buf->capacity - buf->len, cb_arg)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (ret > buf->capacity - buf->len)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
buf->len += ret;
|
||||
|
||||
if (buf->len == buf->capacity)
|
||||
return buf->len;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs)
|
||||
{
|
||||
CBS_init(cbs, buf->data, buf->len);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out, size_t *out_len)
|
||||
{
|
||||
if (out == NULL || out_len == NULL)
|
||||
return 0;
|
||||
|
||||
*out = buf->data;
|
||||
*out_len = buf->len;
|
||||
|
||||
buf->capacity = 0;
|
||||
buf->data = NULL;
|
||||
buf->len = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
1088
externals/libressl/ssl/tls13_client.c
vendored
Executable file
1088
externals/libressl/ssl/tls13_client.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
99
externals/libressl/ssl/tls13_error.c
vendored
Executable file
99
externals/libressl/ssl/tls13_error.c
vendored
Executable file
@@ -0,0 +1,99 @@
|
||||
/* $OpenBSD: tls13_error.c,v 1.1 2020/01/20 13:10:37 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014,2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "tls13_internal.h"
|
||||
|
||||
void
|
||||
tls13_error_clear(struct tls13_error *error)
|
||||
{
|
||||
error->code = 0;
|
||||
error->subcode = 0;
|
||||
error->errnum = 0;
|
||||
error->file = NULL;
|
||||
error->line = 0;
|
||||
free(error->msg);
|
||||
error->msg = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_error_vset(struct tls13_error *error, int code, int subcode, int errnum,
|
||||
const char *file, int line, const char *fmt, va_list ap)
|
||||
{
|
||||
char *errmsg = NULL;
|
||||
int rv = -1;
|
||||
|
||||
tls13_error_clear(error);
|
||||
|
||||
error->code = code;
|
||||
error->subcode = subcode;
|
||||
error->errnum = errnum;
|
||||
error->file = file;
|
||||
error->line = line;
|
||||
|
||||
if (vasprintf(&errmsg, fmt, ap) == -1) {
|
||||
errmsg = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (errnum == -1) {
|
||||
error->msg = errmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (asprintf(&error->msg, "%s: %s", errmsg, strerror(errnum)) == -1) {
|
||||
error->msg = NULL;
|
||||
goto err;
|
||||
}
|
||||
rv = 0;
|
||||
|
||||
err:
|
||||
free(errmsg);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_error_set(struct tls13_error *error, int code, int subcode,
|
||||
const char *file, int line, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int errnum, rv;
|
||||
|
||||
errnum = errno;
|
||||
|
||||
va_start(ap, fmt);
|
||||
rv = tls13_error_vset(error, code, subcode, errnum, file, line, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_error_setx(struct tls13_error *error, int code, int subcode,
|
||||
const char *file, int line, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rv;
|
||||
|
||||
va_start(ap, fmt);
|
||||
rv = tls13_error_vset(error, code, subcode, -1, file, line, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
517
externals/libressl/ssl/tls13_handshake.c
vendored
Executable file
517
externals/libressl/ssl/tls13_handshake.c
vendored
Executable file
@@ -0,0 +1,517 @@
|
||||
/* $OpenBSD: tls13_handshake.c,v 1.64 2020/07/30 16:23:17 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org>
|
||||
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
#include "tls13_handshake.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
/* Based on RFC 8446 and inspired by s2n's TLS 1.2 state machine. */
|
||||
|
||||
struct tls13_handshake_action {
|
||||
uint8_t handshake_type;
|
||||
uint8_t sender;
|
||||
uint8_t handshake_complete;
|
||||
uint8_t send_preserve_transcript_hash;
|
||||
uint8_t recv_preserve_transcript_hash;
|
||||
|
||||
int (*send)(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int (*sent)(struct tls13_ctx *ctx);
|
||||
int (*recv)(struct tls13_ctx *ctx, CBS *cbs);
|
||||
};
|
||||
|
||||
static enum tls13_message_type
|
||||
tls13_handshake_active_state(struct tls13_ctx *ctx);
|
||||
|
||||
static const struct tls13_handshake_action *
|
||||
tls13_handshake_active_action(struct tls13_ctx *ctx);
|
||||
static int tls13_handshake_advance_state_machine(struct tls13_ctx *ctx);
|
||||
|
||||
static int tls13_handshake_send_action(struct tls13_ctx *ctx,
|
||||
const struct tls13_handshake_action *action);
|
||||
static int tls13_handshake_recv_action(struct tls13_ctx *ctx,
|
||||
const struct tls13_handshake_action *action);
|
||||
|
||||
static const struct tls13_handshake_action state_machine[] = {
|
||||
[CLIENT_HELLO] = {
|
||||
.handshake_type = TLS13_MT_CLIENT_HELLO,
|
||||
.sender = TLS13_HS_CLIENT,
|
||||
.send = tls13_client_hello_send,
|
||||
.sent = tls13_client_hello_sent,
|
||||
.recv = tls13_client_hello_recv,
|
||||
},
|
||||
[CLIENT_HELLO_RETRY] = {
|
||||
.handshake_type = TLS13_MT_CLIENT_HELLO,
|
||||
.sender = TLS13_HS_CLIENT,
|
||||
.send = tls13_client_hello_retry_send,
|
||||
.recv = tls13_client_hello_retry_recv,
|
||||
},
|
||||
[CLIENT_END_OF_EARLY_DATA] = {
|
||||
.handshake_type = TLS13_MT_END_OF_EARLY_DATA,
|
||||
.sender = TLS13_HS_CLIENT,
|
||||
.send = tls13_client_end_of_early_data_send,
|
||||
.recv = tls13_client_end_of_early_data_recv,
|
||||
},
|
||||
[CLIENT_CERTIFICATE] = {
|
||||
.handshake_type = TLS13_MT_CERTIFICATE,
|
||||
.sender = TLS13_HS_CLIENT,
|
||||
.send_preserve_transcript_hash = 1,
|
||||
.send = tls13_client_certificate_send,
|
||||
.recv = tls13_client_certificate_recv,
|
||||
},
|
||||
[CLIENT_CERTIFICATE_VERIFY] = {
|
||||
.handshake_type = TLS13_MT_CERTIFICATE_VERIFY,
|
||||
.sender = TLS13_HS_CLIENT,
|
||||
.recv_preserve_transcript_hash = 1,
|
||||
.send = tls13_client_certificate_verify_send,
|
||||
.recv = tls13_client_certificate_verify_recv,
|
||||
},
|
||||
[CLIENT_FINISHED] = {
|
||||
.handshake_type = TLS13_MT_FINISHED,
|
||||
.sender = TLS13_HS_CLIENT,
|
||||
.recv_preserve_transcript_hash = 1,
|
||||
.send = tls13_client_finished_send,
|
||||
.sent = tls13_client_finished_sent,
|
||||
.recv = tls13_client_finished_recv,
|
||||
},
|
||||
[SERVER_HELLO] = {
|
||||
.handshake_type = TLS13_MT_SERVER_HELLO,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.send = tls13_server_hello_send,
|
||||
.sent = tls13_server_hello_sent,
|
||||
.recv = tls13_server_hello_recv,
|
||||
},
|
||||
[SERVER_HELLO_RETRY_REQUEST] = {
|
||||
.handshake_type = TLS13_MT_SERVER_HELLO,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.send = tls13_server_hello_retry_request_send,
|
||||
.recv = tls13_server_hello_retry_request_recv,
|
||||
.sent = tls13_server_hello_retry_request_sent,
|
||||
},
|
||||
[SERVER_ENCRYPTED_EXTENSIONS] = {
|
||||
.handshake_type = TLS13_MT_ENCRYPTED_EXTENSIONS,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.send = tls13_server_encrypted_extensions_send,
|
||||
.recv = tls13_server_encrypted_extensions_recv,
|
||||
},
|
||||
[SERVER_CERTIFICATE] = {
|
||||
.handshake_type = TLS13_MT_CERTIFICATE,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.send_preserve_transcript_hash = 1,
|
||||
.send = tls13_server_certificate_send,
|
||||
.recv = tls13_server_certificate_recv,
|
||||
},
|
||||
[SERVER_CERTIFICATE_REQUEST] = {
|
||||
.handshake_type = TLS13_MT_CERTIFICATE_REQUEST,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.send = tls13_server_certificate_request_send,
|
||||
.recv = tls13_server_certificate_request_recv,
|
||||
},
|
||||
[SERVER_CERTIFICATE_VERIFY] = {
|
||||
.handshake_type = TLS13_MT_CERTIFICATE_VERIFY,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.recv_preserve_transcript_hash = 1,
|
||||
.send = tls13_server_certificate_verify_send,
|
||||
.recv = tls13_server_certificate_verify_recv,
|
||||
},
|
||||
[SERVER_FINISHED] = {
|
||||
.handshake_type = TLS13_MT_FINISHED,
|
||||
.sender = TLS13_HS_SERVER,
|
||||
.recv_preserve_transcript_hash = 1,
|
||||
.send_preserve_transcript_hash = 1,
|
||||
.send = tls13_server_finished_send,
|
||||
.sent = tls13_server_finished_sent,
|
||||
.recv = tls13_server_finished_recv,
|
||||
},
|
||||
[APPLICATION_DATA] = {
|
||||
.handshake_complete = 1,
|
||||
},
|
||||
};
|
||||
|
||||
const enum tls13_message_type handshakes[][TLS13_NUM_MESSAGE_TYPES] = {
|
||||
[INITIAL] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO_RETRY_REQUEST,
|
||||
CLIENT_HELLO_RETRY,
|
||||
SERVER_HELLO,
|
||||
},
|
||||
[NEGOTIATED] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO_RETRY_REQUEST,
|
||||
CLIENT_HELLO_RETRY,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE_REQUEST,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_CERTIFICATE,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITHOUT_HRR] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE_REQUEST,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_CERTIFICATE,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITHOUT_CR] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO_RETRY_REQUEST,
|
||||
CLIENT_HELLO_RETRY,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITHOUT_HRR | WITHOUT_CR] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITH_PSK] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO_RETRY_REQUEST,
|
||||
CLIENT_HELLO_RETRY,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITHOUT_HRR | WITH_PSK] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITH_CCV] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO_RETRY_REQUEST,
|
||||
CLIENT_HELLO_RETRY,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE_REQUEST,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_CERTIFICATE,
|
||||
CLIENT_CERTIFICATE_VERIFY,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
[NEGOTIATED | WITHOUT_HRR | WITH_CCV] = {
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE_REQUEST,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_CERTIFICATE,
|
||||
CLIENT_CERTIFICATE_VERIFY,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
},
|
||||
};
|
||||
|
||||
const size_t handshake_count = sizeof(handshakes) / sizeof(handshakes[0]);
|
||||
|
||||
#ifndef TLS13_DEBUG
|
||||
#define DEBUGF(...)
|
||||
#else
|
||||
#define DEBUGF(...) fprintf(stderr, __VA_ARGS__)
|
||||
|
||||
static const char *
|
||||
tls13_handshake_mode_name(uint8_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case TLS13_HS_CLIENT:
|
||||
return "Client";
|
||||
case TLS13_HS_SERVER:
|
||||
return "Server";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
static const char *
|
||||
tls13_handshake_message_name(uint8_t msg_type)
|
||||
{
|
||||
switch (msg_type) {
|
||||
case TLS13_MT_CLIENT_HELLO:
|
||||
return "ClientHello";
|
||||
case TLS13_MT_SERVER_HELLO:
|
||||
return "ServerHello";
|
||||
case TLS13_MT_NEW_SESSION_TICKET:
|
||||
return "NewSessionTicket";
|
||||
case TLS13_MT_END_OF_EARLY_DATA:
|
||||
return "EndOfEarlyData";
|
||||
case TLS13_MT_ENCRYPTED_EXTENSIONS:
|
||||
return "EncryptedExtensions";
|
||||
case TLS13_MT_CERTIFICATE:
|
||||
return "Certificate";
|
||||
case TLS13_MT_CERTIFICATE_REQUEST:
|
||||
return "CertificateRequest";
|
||||
case TLS13_MT_CERTIFICATE_VERIFY:
|
||||
return "CertificateVerify";
|
||||
case TLS13_MT_FINISHED:
|
||||
return "Finished";
|
||||
case TLS13_MT_KEY_UPDATE:
|
||||
return "KeyUpdate";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
#endif
|
||||
|
||||
static enum tls13_message_type
|
||||
tls13_handshake_active_state(struct tls13_ctx *ctx)
|
||||
{
|
||||
struct tls13_handshake_stage hs = ctx->handshake_stage;
|
||||
|
||||
if (hs.hs_type >= handshake_count)
|
||||
return INVALID;
|
||||
if (hs.message_number >= TLS13_NUM_MESSAGE_TYPES)
|
||||
return INVALID;
|
||||
|
||||
return handshakes[hs.hs_type][hs.message_number];
|
||||
}
|
||||
|
||||
static const struct tls13_handshake_action *
|
||||
tls13_handshake_active_action(struct tls13_ctx *ctx)
|
||||
{
|
||||
enum tls13_message_type mt = tls13_handshake_active_state(ctx);
|
||||
|
||||
if (mt == INVALID)
|
||||
return NULL;
|
||||
|
||||
return &state_machine[mt];
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_advance_state_machine(struct tls13_ctx *ctx)
|
||||
{
|
||||
if (++ctx->handshake_stage.message_number >= TLS13_NUM_MESSAGE_TYPES)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_record(struct tls13_ctx *ctx)
|
||||
{
|
||||
CBS cbs;
|
||||
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
return tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs));
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_perform(struct tls13_ctx *ctx)
|
||||
{
|
||||
const struct tls13_handshake_action *action;
|
||||
int ret;
|
||||
|
||||
if (!ctx->handshake_started) {
|
||||
ctx->handshake_started = 1;
|
||||
if (ctx->info_cb != NULL)
|
||||
ctx->info_cb(ctx, TLS13_INFO_HANDSHAKE_STARTED, 1);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((action = tls13_handshake_active_action(ctx)) == NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (action->handshake_complete) {
|
||||
ctx->handshake_completed = 1;
|
||||
tls13_record_layer_handshake_completed(ctx->rl);
|
||||
if (ctx->info_cb != NULL)
|
||||
ctx->info_cb(ctx,
|
||||
TLS13_INFO_HANDSHAKE_COMPLETED, 1);
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode),
|
||||
(action->sender == ctx->mode) ? "sending" : "receiving",
|
||||
tls13_handshake_message_name(action->handshake_type));
|
||||
|
||||
if (ctx->alert)
|
||||
return tls13_send_alert(ctx->rl, ctx->alert);
|
||||
|
||||
if (action->sender == ctx->mode)
|
||||
ret = tls13_handshake_send_action(ctx, action);
|
||||
else
|
||||
ret = tls13_handshake_recv_action(ctx, action);
|
||||
|
||||
if (ctx->alert)
|
||||
return tls13_send_alert(ctx->rl, ctx->alert);
|
||||
|
||||
if (ret <= 0) {
|
||||
DEBUGF("%s %s returned %d\n",
|
||||
tls13_handshake_mode_name(ctx->mode),
|
||||
(action->sender == ctx->mode) ? "send" : "recv",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!tls13_handshake_advance_state_machine(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_send_action(struct tls13_ctx *ctx,
|
||||
const struct tls13_handshake_action *action)
|
||||
{
|
||||
ssize_t ret;
|
||||
CBB cbb;
|
||||
|
||||
if (ctx->send_dummy_ccs) {
|
||||
if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS)
|
||||
return ret;
|
||||
ctx->send_dummy_ccs = 0;
|
||||
if (ctx->send_dummy_ccs_after) {
|
||||
ctx->send_dummy_ccs_after = 0;
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have no handshake message, we need to build one. */
|
||||
if (ctx->hs_msg == NULL) {
|
||||
if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!tls13_handshake_msg_start(ctx->hs_msg, &cbb,
|
||||
action->handshake_type))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!action->send(ctx, &cbb))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!tls13_handshake_msg_finish(ctx->hs_msg))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if ((ret = tls13_handshake_msg_send(ctx->hs_msg, ctx->rl)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls13_handshake_msg_record(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (action->send_preserve_transcript_hash) {
|
||||
if (!tls1_transcript_hash_value(ctx->ssl,
|
||||
ctx->hs->transcript_hash, sizeof(ctx->hs->transcript_hash),
|
||||
&ctx->hs->transcript_hash_len))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->handshake_message_sent_cb != NULL)
|
||||
ctx->handshake_message_sent_cb(ctx);
|
||||
|
||||
tls13_handshake_msg_free(ctx->hs_msg);
|
||||
ctx->hs_msg = NULL;
|
||||
|
||||
if (action->sent != NULL && !action->sent(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (ctx->send_dummy_ccs_after) {
|
||||
ctx->send_dummy_ccs = 1;
|
||||
if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS)
|
||||
return ret;
|
||||
ctx->send_dummy_ccs = 0;
|
||||
ctx->send_dummy_ccs_after = 0;
|
||||
}
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_recv_action(struct tls13_ctx *ctx,
|
||||
const struct tls13_handshake_action *action)
|
||||
{
|
||||
uint8_t msg_type;
|
||||
ssize_t ret;
|
||||
CBS cbs;
|
||||
|
||||
if (ctx->hs_msg == NULL) {
|
||||
if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (action->recv_preserve_transcript_hash) {
|
||||
if (!tls1_transcript_hash_value(ctx->ssl,
|
||||
ctx->hs->transcript_hash, sizeof(ctx->hs->transcript_hash),
|
||||
&ctx->hs->transcript_hash_len))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if (!tls13_handshake_msg_record(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (ctx->handshake_message_recv_cb != NULL)
|
||||
ctx->handshake_message_recv_cb(ctx);
|
||||
|
||||
/*
|
||||
* In TLSv1.3 there is no way to know if you're going to receive a
|
||||
* certificate request message or not, hence we have to special case it
|
||||
* here. The receive handler also knows how to deal with this situation.
|
||||
*/
|
||||
msg_type = tls13_handshake_msg_type(ctx->hs_msg);
|
||||
if (msg_type != action->handshake_type &&
|
||||
(msg_type != TLS13_MT_CERTIFICATE ||
|
||||
action->handshake_type != TLS13_MT_CERTIFICATE_REQUEST))
|
||||
return tls13_send_alert(ctx->rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
|
||||
|
||||
if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
ret = TLS13_IO_FAILURE;
|
||||
if (action->recv(ctx, &cbs)) {
|
||||
if (CBS_len(&cbs) != 0) {
|
||||
tls13_set_errorx(ctx, TLS13_ERR_TRAILING_DATA, 0,
|
||||
"trailing data in handshake message", NULL);
|
||||
ctx->alert = TLS13_ALERT_DECODE_ERROR;
|
||||
} else {
|
||||
ret = TLS13_IO_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
tls13_handshake_msg_free(ctx->hs_msg);
|
||||
ctx->hs_msg = NULL;
|
||||
|
||||
if (ctx->ssl->method->internal->version < TLS1_3_VERSION)
|
||||
return TLS13_IO_USE_LEGACY;
|
||||
|
||||
return ret;
|
||||
}
|
||||
54
externals/libressl/ssl/tls13_handshake.h
vendored
Executable file
54
externals/libressl/ssl/tls13_handshake.h
vendored
Executable file
@@ -0,0 +1,54 @@
|
||||
/* $OpenBSD: tls13_handshake.h,v 1.5 2020/04/22 17:05:07 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TLS13_HANDSHAKE_H
|
||||
#define HEADER_TLS13_HANDSHAKE_H
|
||||
|
||||
#include <stddef.h> /* for NULL */
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define INITIAL 0x00
|
||||
#define NEGOTIATED 0x01
|
||||
#define WITHOUT_HRR 0x02
|
||||
#define WITHOUT_CR 0x04
|
||||
#define WITH_PSK 0x08
|
||||
#define WITH_CCV 0x10
|
||||
#define WITH_0RTT 0x20
|
||||
|
||||
enum tls13_message_type {
|
||||
INVALID,
|
||||
CLIENT_HELLO,
|
||||
SERVER_HELLO_RETRY_REQUEST,
|
||||
CLIENT_HELLO_RETRY,
|
||||
SERVER_HELLO,
|
||||
SERVER_ENCRYPTED_EXTENSIONS,
|
||||
SERVER_CERTIFICATE_REQUEST,
|
||||
SERVER_CERTIFICATE,
|
||||
SERVER_CERTIFICATE_VERIFY,
|
||||
SERVER_FINISHED,
|
||||
CLIENT_END_OF_EARLY_DATA,
|
||||
CLIENT_CERTIFICATE,
|
||||
CLIENT_CERTIFICATE_VERIFY,
|
||||
CLIENT_FINISHED,
|
||||
APPLICATION_DATA,
|
||||
TLS13_NUM_MESSAGE_TYPES,
|
||||
};
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif /* !HEADER_TLS13_HANDSHAKE_H */
|
||||
194
externals/libressl/ssl/tls13_handshake_msg.c
vendored
Executable file
194
externals/libressl/ssl/tls13_handshake_msg.c
vendored
Executable file
@@ -0,0 +1,194 @@
|
||||
/* $OpenBSD: tls13_handshake_msg.c,v 1.2 2019/11/20 16:21:20 beck Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_locl.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
#define TLS13_HANDSHAKE_MSG_HEADER_LEN 4
|
||||
#define TLS13_HANDSHAKE_MSG_INITIAL_LEN 256
|
||||
#define TLS13_HANDSHAKE_MSG_MAX_LEN (256 * 1024)
|
||||
|
||||
struct tls13_handshake_msg {
|
||||
uint8_t msg_type;
|
||||
uint32_t msg_len;
|
||||
uint8_t *data;
|
||||
size_t data_len;
|
||||
|
||||
struct tls13_buffer *buf;
|
||||
CBS cbs;
|
||||
CBB cbb;
|
||||
};
|
||||
|
||||
struct tls13_handshake_msg *
|
||||
tls13_handshake_msg_new()
|
||||
{
|
||||
struct tls13_handshake_msg *msg = NULL;
|
||||
|
||||
if ((msg = calloc(1, sizeof(struct tls13_handshake_msg))) == NULL)
|
||||
goto err;
|
||||
if ((msg->buf = tls13_buffer_new(0)) == NULL)
|
||||
goto err;
|
||||
|
||||
return msg;
|
||||
|
||||
err:
|
||||
tls13_handshake_msg_free(msg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_handshake_msg_free(struct tls13_handshake_msg *msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return;
|
||||
|
||||
tls13_buffer_free(msg->buf);
|
||||
|
||||
CBB_cleanup(&msg->cbb);
|
||||
|
||||
freezero(msg->data, msg->data_len);
|
||||
freezero(msg, sizeof(struct tls13_handshake_msg));
|
||||
}
|
||||
|
||||
void
|
||||
tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs)
|
||||
{
|
||||
CBS_init(cbs, msg->data, msg->data_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_set_buffer(struct tls13_handshake_msg *msg, CBS *cbs)
|
||||
{
|
||||
return tls13_buffer_set_data(msg->buf, cbs);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
tls13_handshake_msg_type(struct tls13_handshake_msg *msg)
|
||||
{
|
||||
return msg->msg_type;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_content(struct tls13_handshake_msg *msg, CBS *cbs)
|
||||
{
|
||||
tls13_handshake_msg_data(msg, cbs);
|
||||
|
||||
return CBS_skip(cbs, TLS13_HANDSHAKE_MSG_HEADER_LEN);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_start(struct tls13_handshake_msg *msg, CBB *body,
|
||||
uint8_t msg_type)
|
||||
{
|
||||
if (!CBB_init(&msg->cbb, TLS13_HANDSHAKE_MSG_INITIAL_LEN))
|
||||
return 0;
|
||||
if (!CBB_add_u8(&msg->cbb, msg_type))
|
||||
return 0;
|
||||
if (!CBB_add_u24_length_prefixed(&msg->cbb, body))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_finish(struct tls13_handshake_msg *msg)
|
||||
{
|
||||
if (!CBB_finish(&msg->cbb, &msg->data, &msg->data_len))
|
||||
return 0;
|
||||
|
||||
CBS_init(&msg->cbs, msg->data, msg->data_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_handshake_msg_read_cb(void *buf, size_t n, void *cb_arg)
|
||||
{
|
||||
struct tls13_record_layer *rl = cb_arg;
|
||||
|
||||
return tls13_read_handshake_data(rl, buf, n);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
|
||||
struct tls13_record_layer *rl)
|
||||
{
|
||||
uint8_t msg_type;
|
||||
uint32_t msg_len;
|
||||
CBS cbs;
|
||||
int ret;
|
||||
|
||||
if (msg->data != NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (msg->msg_type == 0) {
|
||||
if ((ret = tls13_buffer_extend(msg->buf,
|
||||
TLS13_HANDSHAKE_MSG_HEADER_LEN,
|
||||
tls13_handshake_msg_read_cb, rl)) <= 0)
|
||||
return ret;
|
||||
|
||||
tls13_buffer_cbs(msg->buf, &cbs);
|
||||
|
||||
if (!CBS_get_u8(&cbs, &msg_type))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!CBS_get_u24(&cbs, &msg_len))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
/* XXX - do we want to make this variable on message type? */
|
||||
if (msg_len > TLS13_HANDSHAKE_MSG_MAX_LEN)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
msg->msg_type = msg_type;
|
||||
msg->msg_len = msg_len;
|
||||
}
|
||||
|
||||
if ((ret = tls13_buffer_extend(msg->buf,
|
||||
TLS13_HANDSHAKE_MSG_HEADER_LEN + msg->msg_len,
|
||||
tls13_handshake_msg_read_cb, rl)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls13_buffer_finish(msg->buf, &msg->data, &msg->data_len))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_handshake_msg_send(struct tls13_handshake_msg *msg,
|
||||
struct tls13_record_layer *rl)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (msg->data == NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (CBS_len(&msg->cbs) == 0)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
while (CBS_len(&msg->cbs) > 0) {
|
||||
if ((ret = tls13_write_handshake_data(rl, CBS_data(&msg->cbs),
|
||||
CBS_len(&msg->cbs))) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!CBS_skip(&msg->cbs, ret))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
424
externals/libressl/ssl/tls13_internal.h
vendored
Executable file
424
externals/libressl/ssl/tls13_internal.h
vendored
Executable file
@@ -0,0 +1,424 @@
|
||||
/* $OpenBSD: tls13_internal.h,v 1.86 2020/07/30 16:23:17 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
|
||||
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
|
||||
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TLS13_INTERNAL_H
|
||||
#define HEADER_TLS13_INTERNAL_H
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define TLS13_HS_CLIENT 1
|
||||
#define TLS13_HS_SERVER 2
|
||||
|
||||
#define TLS13_IO_SUCCESS 1
|
||||
#define TLS13_IO_EOF 0
|
||||
#define TLS13_IO_FAILURE -1
|
||||
#define TLS13_IO_ALERT -2
|
||||
#define TLS13_IO_WANT_POLLIN -3
|
||||
#define TLS13_IO_WANT_POLLOUT -4
|
||||
#define TLS13_IO_WANT_RETRY -5 /* Retry the previous call immediately. */
|
||||
#define TLS13_IO_USE_LEGACY -6
|
||||
#define TLS13_IO_RECORD_VERSION -7
|
||||
#define TLS13_IO_RECORD_OVERFLOW -8
|
||||
|
||||
#define TLS13_ERR_VERIFY_FAILED 16
|
||||
#define TLS13_ERR_HRR_FAILED 17
|
||||
#define TLS13_ERR_TRAILING_DATA 18
|
||||
#define TLS13_ERR_NO_SHARED_CIPHER 19
|
||||
#define TLS13_ERR_NO_CERTIFICATE 20
|
||||
#define TLS13_ERR_NO_PEER_CERTIFICATE 21
|
||||
|
||||
#define TLS13_ALERT_LEVEL_WARNING 1
|
||||
#define TLS13_ALERT_LEVEL_FATAL 2
|
||||
|
||||
#define TLS13_ALERT_CLOSE_NOTIFY 0
|
||||
#define TLS13_ALERT_UNEXPECTED_MESSAGE 10
|
||||
#define TLS13_ALERT_BAD_RECORD_MAC 20
|
||||
#define TLS13_ALERT_RECORD_OVERFLOW 22
|
||||
#define TLS13_ALERT_HANDSHAKE_FAILURE 40
|
||||
#define TLS13_ALERT_BAD_CERTIFICATE 42
|
||||
#define TLS13_ALERT_UNSUPPORTED_CERTIFICATE 43
|
||||
#define TLS13_ALERT_CERTIFICATE_REVOKED 44
|
||||
#define TLS13_ALERT_CERTIFICATE_EXPIRED 45
|
||||
#define TLS13_ALERT_CERTIFICATE_UNKNOWN 46
|
||||
#define TLS13_ALERT_ILLEGAL_PARAMETER 47
|
||||
#define TLS13_ALERT_UNKNOWN_CA 48
|
||||
#define TLS13_ALERT_ACCESS_DENIED 49
|
||||
#define TLS13_ALERT_DECODE_ERROR 50
|
||||
#define TLS13_ALERT_DECRYPT_ERROR 51
|
||||
#define TLS13_ALERT_PROTOCOL_VERSION 70
|
||||
#define TLS13_ALERT_INSUFFICIENT_SECURITY 71
|
||||
#define TLS13_ALERT_INTERNAL_ERROR 80
|
||||
#define TLS13_ALERT_INAPPROPRIATE_FALLBACK 86
|
||||
#define TLS13_ALERT_USER_CANCELED 90
|
||||
#define TLS13_ALERT_MISSING_EXTENSION 109
|
||||
#define TLS13_ALERT_UNSUPPORTED_EXTENSION 110
|
||||
#define TLS13_ALERT_UNRECOGNIZED_NAME 112
|
||||
#define TLS13_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113
|
||||
#define TLS13_ALERT_UNKNOWN_PSK_IDENTITY 115
|
||||
#define TLS13_ALERT_CERTIFICATE_REQUIRED 116
|
||||
#define TLS13_ALERT_NO_APPLICATION_PROTOCOL 120
|
||||
|
||||
#define TLS13_INFO_HANDSHAKE_STARTED SSL_CB_HANDSHAKE_START
|
||||
#define TLS13_INFO_HANDSHAKE_COMPLETED SSL_CB_HANDSHAKE_DONE
|
||||
|
||||
typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg);
|
||||
typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg, CBS *_cbs);
|
||||
typedef void (*tls13_phh_sent_cb)(void *_cb_arg);
|
||||
typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg);
|
||||
typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen,
|
||||
void *_cb_arg);
|
||||
typedef void (*tls13_handshake_message_cb)(void *_cb_arg);
|
||||
typedef void (*tls13_info_cb)(void *_cb_arg, int _state, int _ret);
|
||||
typedef int (*tls13_ocsp_status_cb)(void *_cb_arg);
|
||||
|
||||
/*
|
||||
* Buffers.
|
||||
*/
|
||||
struct tls13_buffer;
|
||||
|
||||
struct tls13_buffer *tls13_buffer_new(size_t init_size);
|
||||
int tls13_buffer_set_data(struct tls13_buffer *buf, CBS *data);
|
||||
void tls13_buffer_free(struct tls13_buffer *buf);
|
||||
ssize_t tls13_buffer_extend(struct tls13_buffer *buf, size_t len,
|
||||
tls13_read_cb read_cb, void *cb_arg);
|
||||
void tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs);
|
||||
int tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out,
|
||||
size_t *out_len);
|
||||
|
||||
/*
|
||||
* Secrets.
|
||||
*/
|
||||
struct tls13_secret {
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/* RFC 8446 Section 7.1 Page 92 */
|
||||
struct tls13_secrets {
|
||||
const EVP_MD *digest;
|
||||
int resumption;
|
||||
int init_done;
|
||||
int early_done;
|
||||
int handshake_done;
|
||||
int schedule_done;
|
||||
int insecure; /* Set by tests */
|
||||
struct tls13_secret zeros;
|
||||
struct tls13_secret empty_hash;
|
||||
struct tls13_secret extracted_early;
|
||||
struct tls13_secret binder_key;
|
||||
struct tls13_secret client_early_traffic;
|
||||
struct tls13_secret early_exporter_master;
|
||||
struct tls13_secret derived_early;
|
||||
struct tls13_secret extracted_handshake;
|
||||
struct tls13_secret client_handshake_traffic;
|
||||
struct tls13_secret server_handshake_traffic;
|
||||
struct tls13_secret derived_handshake;
|
||||
struct tls13_secret extracted_master;
|
||||
struct tls13_secret client_application_traffic;
|
||||
struct tls13_secret server_application_traffic;
|
||||
struct tls13_secret exporter_master;
|
||||
struct tls13_secret resumption_master;
|
||||
};
|
||||
|
||||
struct tls13_secrets *tls13_secrets_create(const EVP_MD *digest,
|
||||
int resumption);
|
||||
void tls13_secrets_destroy(struct tls13_secrets *secrets);
|
||||
|
||||
int tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
|
||||
const struct tls13_secret *secret, const char *label,
|
||||
const struct tls13_secret *context);
|
||||
|
||||
int tls13_derive_early_secrets(struct tls13_secrets *secrets, uint8_t *psk,
|
||||
size_t psk_len, const struct tls13_secret *context);
|
||||
int tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
|
||||
const uint8_t *ecdhe, size_t ecdhe_len, const struct tls13_secret *context);
|
||||
int tls13_derive_application_secrets(struct tls13_secrets *secrets,
|
||||
const struct tls13_secret *context);
|
||||
int tls13_update_client_traffic_secret(struct tls13_secrets *secrets);
|
||||
int tls13_update_server_traffic_secret(struct tls13_secrets *secrets);
|
||||
|
||||
/*
|
||||
* Key shares.
|
||||
*/
|
||||
struct tls13_key_share;
|
||||
|
||||
struct tls13_key_share *tls13_key_share_new(uint16_t group_id);
|
||||
struct tls13_key_share *tls13_key_share_new_nid(int nid);
|
||||
void tls13_key_share_free(struct tls13_key_share *ks);
|
||||
|
||||
uint16_t tls13_key_share_group(struct tls13_key_share *ks);
|
||||
int tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey);
|
||||
int tls13_key_share_generate(struct tls13_key_share *ks);
|
||||
int tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb);
|
||||
int tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
|
||||
CBS *cbs);
|
||||
int tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
|
||||
size_t *shared_key_len);
|
||||
|
||||
/*
|
||||
* Record Layer.
|
||||
*/
|
||||
struct tls13_record_layer;
|
||||
|
||||
struct tls13_record_layer_callbacks {
|
||||
tls13_read_cb wire_read;
|
||||
tls13_write_cb wire_write;
|
||||
tls13_alert_cb alert_recv;
|
||||
tls13_alert_cb alert_sent;
|
||||
tls13_phh_recv_cb phh_recv;
|
||||
tls13_phh_sent_cb phh_sent;
|
||||
};
|
||||
|
||||
struct tls13_record_layer *tls13_record_layer_new(
|
||||
const struct tls13_record_layer_callbacks *callbacks, void *cb_arg);
|
||||
void tls13_record_layer_free(struct tls13_record_layer *rl);
|
||||
void tls13_record_layer_allow_ccs(struct tls13_record_layer *rl, int allow);
|
||||
void tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer *rl, int allow);
|
||||
void tls13_record_layer_rbuf(struct tls13_record_layer *rl, CBS *cbs);
|
||||
void tls13_record_layer_set_aead(struct tls13_record_layer *rl,
|
||||
const EVP_AEAD *aead);
|
||||
void tls13_record_layer_set_hash(struct tls13_record_layer *rl,
|
||||
const EVP_MD *hash);
|
||||
void tls13_record_layer_set_legacy_version(struct tls13_record_layer *rl,
|
||||
uint16_t version);
|
||||
void tls13_record_layer_set_retry_after_phh(struct tls13_record_layer *rl, int retry);
|
||||
void tls13_record_layer_handshake_completed(struct tls13_record_layer *rl);
|
||||
int tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl,
|
||||
struct tls13_secret *read_key);
|
||||
int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
|
||||
struct tls13_secret *write_key);
|
||||
ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl);
|
||||
ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs);
|
||||
|
||||
ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
|
||||
ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf,
|
||||
size_t n);
|
||||
ssize_t tls13_pending_application_data(struct tls13_record_layer *rl);
|
||||
ssize_t tls13_peek_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
|
||||
ssize_t tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
|
||||
ssize_t tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf,
|
||||
size_t n);
|
||||
|
||||
ssize_t tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc);
|
||||
ssize_t tls13_send_dummy_ccs(struct tls13_record_layer *rl);
|
||||
|
||||
/*
|
||||
* Handshake Messages.
|
||||
*/
|
||||
struct tls13_handshake_msg;
|
||||
|
||||
struct tls13_handshake_msg *tls13_handshake_msg_new(void);
|
||||
void tls13_handshake_msg_free(struct tls13_handshake_msg *msg);
|
||||
void tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs);
|
||||
int tls13_handshake_msg_set_buffer(struct tls13_handshake_msg *msg, CBS *cbs);
|
||||
uint8_t tls13_handshake_msg_type(struct tls13_handshake_msg *msg);
|
||||
int tls13_handshake_msg_content(struct tls13_handshake_msg *msg, CBS *cbs);
|
||||
int tls13_handshake_msg_start(struct tls13_handshake_msg *msg, CBB *body,
|
||||
uint8_t msg_type);
|
||||
int tls13_handshake_msg_finish(struct tls13_handshake_msg *msg);
|
||||
int tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
|
||||
struct tls13_record_layer *rl);
|
||||
int tls13_handshake_msg_send(struct tls13_handshake_msg *msg,
|
||||
struct tls13_record_layer *rl);
|
||||
|
||||
struct tls13_handshake_stage {
|
||||
uint8_t hs_type;
|
||||
uint8_t message_number;
|
||||
};
|
||||
|
||||
struct ssl_handshake_tls13_st;
|
||||
|
||||
struct tls13_error {
|
||||
int code;
|
||||
int subcode;
|
||||
int errnum;
|
||||
const char *file;
|
||||
int line;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
struct tls13_ctx {
|
||||
struct tls13_error error;
|
||||
|
||||
SSL *ssl;
|
||||
struct ssl_handshake_tls13_st *hs;
|
||||
uint8_t mode;
|
||||
struct tls13_handshake_stage handshake_stage;
|
||||
int handshake_started;
|
||||
int handshake_completed;
|
||||
int middlebox_compat;
|
||||
int send_dummy_ccs;
|
||||
int send_dummy_ccs_after;
|
||||
|
||||
int close_notify_sent;
|
||||
int close_notify_recv;
|
||||
|
||||
const EVP_AEAD *aead;
|
||||
const EVP_MD *hash;
|
||||
|
||||
struct tls13_record_layer *rl;
|
||||
struct tls13_handshake_msg *hs_msg;
|
||||
uint8_t key_update_request;
|
||||
uint8_t alert;
|
||||
int phh_count;
|
||||
time_t phh_last_seen;
|
||||
|
||||
tls13_handshake_message_cb handshake_message_sent_cb;
|
||||
tls13_handshake_message_cb handshake_message_recv_cb;
|
||||
tls13_info_cb info_cb;
|
||||
tls13_ocsp_status_cb ocsp_status_recv_cb;
|
||||
};
|
||||
#ifndef TLS13_PHH_LIMIT_TIME
|
||||
#define TLS13_PHH_LIMIT_TIME 3600
|
||||
#endif
|
||||
#ifndef TLS13_PHH_LIMIT
|
||||
#define TLS13_PHH_LIMIT 100
|
||||
#endif
|
||||
|
||||
struct tls13_ctx *tls13_ctx_new(int mode);
|
||||
void tls13_ctx_free(struct tls13_ctx *ctx);
|
||||
|
||||
const EVP_AEAD *tls13_cipher_aead(const SSL_CIPHER *cipher);
|
||||
const EVP_MD *tls13_cipher_hash(const SSL_CIPHER *cipher);
|
||||
|
||||
/*
|
||||
* Legacy interfaces.
|
||||
*/
|
||||
int tls13_use_legacy_client(struct tls13_ctx *ctx);
|
||||
int tls13_use_legacy_server(struct tls13_ctx *ctx);
|
||||
int tls13_legacy_accept(SSL *ssl);
|
||||
int tls13_legacy_connect(SSL *ssl);
|
||||
int tls13_legacy_return_code(SSL *ssl, ssize_t ret);
|
||||
ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg);
|
||||
ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg);
|
||||
int tls13_legacy_pending(const SSL *ssl);
|
||||
int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len,
|
||||
int peek);
|
||||
int tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len);
|
||||
int tls13_legacy_shutdown(SSL *ssl);
|
||||
int tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert);
|
||||
|
||||
/*
|
||||
* Message Types - RFC 8446, Section B.3.
|
||||
*
|
||||
* Values listed as "_RESERVED" were used in previous versions of TLS and are
|
||||
* listed here for completeness. TLS 1.3 implementations MUST NOT send them but
|
||||
* might receive them from older TLS implementations.
|
||||
*/
|
||||
#define TLS13_MT_HELLO_REQUEST_RESERVED 0
|
||||
#define TLS13_MT_CLIENT_HELLO 1
|
||||
#define TLS13_MT_SERVER_HELLO 2
|
||||
#define TLS13_MT_HELLO_VERIFY_REQUEST_RESERVED 3
|
||||
#define TLS13_MT_NEW_SESSION_TICKET 4
|
||||
#define TLS13_MT_END_OF_EARLY_DATA 5
|
||||
#define TLS13_MT_HELLO_RETRY_REQUEST_RESERVED 6
|
||||
#define TLS13_MT_ENCRYPTED_EXTENSIONS 8
|
||||
#define TLS13_MT_CERTIFICATE 11
|
||||
#define TLS13_MT_SERVER_KEY_EXCHANGE_RESERVED 12
|
||||
#define TLS13_MT_CERTIFICATE_REQUEST 13
|
||||
#define TLS13_MT_SERVER_HELLO_DONE_RESERVED 14
|
||||
#define TLS13_MT_CERTIFICATE_VERIFY 15
|
||||
#define TLS13_MT_CLIENT_KEY_EXCHANGE_RESERVED 16
|
||||
#define TLS13_MT_FINISHED 20
|
||||
#define TLS13_MT_CERTIFICATE_URL_RESERVED 21
|
||||
#define TLS13_MT_CERTIFICATE_STATUS_RESERVED 22
|
||||
#define TLS13_MT_SUPPLEMENTAL_DATA_RESERVED 23
|
||||
#define TLS13_MT_KEY_UPDATE 24
|
||||
#define TLS13_MT_MESSAGE_HASH 254
|
||||
|
||||
int tls13_handshake_msg_record(struct tls13_ctx *ctx);
|
||||
int tls13_handshake_perform(struct tls13_ctx *ctx);
|
||||
|
||||
int tls13_client_init(struct tls13_ctx *ctx);
|
||||
int tls13_server_init(struct tls13_ctx *ctx);
|
||||
int tls13_client_connect(struct tls13_ctx *ctx);
|
||||
int tls13_server_accept(struct tls13_ctx *ctx);
|
||||
|
||||
int tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_client_hello_sent(struct tls13_ctx *ctx);
|
||||
int tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_client_end_of_early_data_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_client_finished_sent(struct tls13_ctx *ctx);
|
||||
int tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_hello_sent(struct tls13_ctx *ctx);
|
||||
int tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_hello_retry_request_sent(struct tls13_ctx *ctx);
|
||||
int tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb);
|
||||
int tls13_server_finished_sent(struct tls13_ctx *ctx);
|
||||
|
||||
void tls13_error_clear(struct tls13_error *error);
|
||||
int tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert,
|
||||
int(*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb));
|
||||
|
||||
int tls13_synthetic_handshake_message(struct tls13_ctx *ctx);
|
||||
int tls13_clienthello_hash_init(struct tls13_ctx *ctx);
|
||||
void tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs);
|
||||
int tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data,
|
||||
size_t len);
|
||||
int tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs);
|
||||
int tls13_clienthello_hash_finalize(struct tls13_ctx *ctx);
|
||||
int tls13_clienthello_hash_validate(struct tls13_ctx *ctx);
|
||||
|
||||
int tls13_error_set(struct tls13_error *error, int code, int subcode,
|
||||
const char *file, int line, const char *fmt, ...);
|
||||
int tls13_error_setx(struct tls13_error *error, int code, int subcode,
|
||||
const char *file, int line, const char *fmt, ...);
|
||||
|
||||
#define tls13_set_error(ctx, code, subcode, fmt, ...) \
|
||||
tls13_error_set(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \
|
||||
(fmt), __VA_ARGS__)
|
||||
#define tls13_set_errorx(ctx, code, subcode, fmt, ...) \
|
||||
tls13_error_setx(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \
|
||||
(fmt), __VA_ARGS__)
|
||||
|
||||
extern const uint8_t tls13_downgrade_12[8];
|
||||
extern const uint8_t tls13_downgrade_11[8];
|
||||
extern const uint8_t tls13_hello_retry_request_hash[32];
|
||||
extern const uint8_t tls13_cert_verify_pad[64];
|
||||
extern const uint8_t tls13_cert_client_verify_context[];
|
||||
extern const uint8_t tls13_cert_server_verify_context[];
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
380
externals/libressl/ssl/tls13_key_schedule.c
vendored
Executable file
380
externals/libressl/ssl/tls13_key_schedule.c
vendored
Executable file
@@ -0,0 +1,380 @@
|
||||
/* $OpenBSD: tls13_key_schedule.c,v 1.8 2019/11/17 21:01:08 beck Exp $ */
|
||||
/* Copyright (c) 2018, Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/hkdf.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
void
|
||||
tls13_secrets_destroy(struct tls13_secrets *secrets)
|
||||
{
|
||||
if (secrets == NULL)
|
||||
return;
|
||||
|
||||
/* you can never be too sure :) */
|
||||
freezero(secrets->zeros.data, secrets->zeros.len);
|
||||
freezero(secrets->empty_hash.data, secrets->empty_hash.len);
|
||||
|
||||
freezero(secrets->extracted_early.data,
|
||||
secrets->extracted_early.len);
|
||||
freezero(secrets->binder_key.data,
|
||||
secrets->binder_key.len);
|
||||
freezero(secrets->client_early_traffic.data,
|
||||
secrets->client_early_traffic.len);
|
||||
freezero(secrets->early_exporter_master.data,
|
||||
secrets->early_exporter_master.len);
|
||||
freezero(secrets->derived_early.data,
|
||||
secrets->derived_early.len);
|
||||
freezero(secrets->extracted_handshake.data,
|
||||
secrets->extracted_handshake.len);
|
||||
freezero(secrets->client_handshake_traffic.data,
|
||||
secrets->client_handshake_traffic.len);
|
||||
freezero(secrets->server_handshake_traffic.data,
|
||||
secrets->server_handshake_traffic.len);
|
||||
freezero(secrets->derived_handshake.data,
|
||||
secrets->derived_handshake.len);
|
||||
freezero(secrets->extracted_master.data,
|
||||
secrets->extracted_master.len);
|
||||
freezero(secrets->client_application_traffic.data,
|
||||
secrets->client_application_traffic.len);
|
||||
freezero(secrets->server_application_traffic.data,
|
||||
secrets->server_application_traffic.len);
|
||||
freezero(secrets->exporter_master.data,
|
||||
secrets->exporter_master.len);
|
||||
freezero(secrets->resumption_master.data,
|
||||
secrets->resumption_master.len);
|
||||
|
||||
freezero(secrets, sizeof(struct tls13_secrets));
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a set of secrets for a key schedule using
|
||||
* a size of hash_length from RFC 8446 section 7.1.
|
||||
*/
|
||||
struct tls13_secrets *
|
||||
tls13_secrets_create(const EVP_MD *digest, int resumption)
|
||||
{
|
||||
struct tls13_secrets *secrets = NULL;
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
unsigned int mdlen;
|
||||
size_t hash_length;
|
||||
|
||||
hash_length = EVP_MD_size(digest);
|
||||
|
||||
if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((secrets->zeros.data = calloc(hash_length, sizeof(uint8_t))) ==
|
||||
NULL)
|
||||
goto err;
|
||||
secrets->zeros.len = hash_length;
|
||||
|
||||
if ((secrets->empty_hash.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->empty_hash.len = hash_length;
|
||||
|
||||
if ((secrets->extracted_early.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->extracted_early.len = hash_length;
|
||||
if ((secrets->binder_key.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->binder_key.len = hash_length;
|
||||
if ((secrets->client_early_traffic.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->client_early_traffic.len = hash_length;
|
||||
if ((secrets->early_exporter_master.data = malloc(hash_length)) ==
|
||||
NULL)
|
||||
goto err;
|
||||
secrets->early_exporter_master.len = hash_length;
|
||||
if ((secrets->derived_early.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->derived_early.len = hash_length;
|
||||
if ((secrets->extracted_handshake.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->extracted_handshake.len = hash_length;
|
||||
if ((secrets->client_handshake_traffic.data = malloc(hash_length))
|
||||
== NULL)
|
||||
goto err;
|
||||
secrets->client_handshake_traffic.len = hash_length;
|
||||
if ((secrets->server_handshake_traffic.data = malloc(hash_length))
|
||||
== NULL)
|
||||
goto err;
|
||||
secrets->server_handshake_traffic.len = hash_length;
|
||||
if ((secrets->derived_handshake.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->derived_handshake.len = hash_length;
|
||||
if ((secrets->extracted_master.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->extracted_master.len = hash_length;
|
||||
if ((secrets->client_application_traffic.data = malloc(hash_length)) ==
|
||||
NULL)
|
||||
goto err;
|
||||
secrets->client_application_traffic.len = hash_length;
|
||||
if ((secrets->server_application_traffic.data = malloc(hash_length)) ==
|
||||
NULL)
|
||||
goto err;
|
||||
secrets->server_application_traffic.len = hash_length;
|
||||
if ((secrets->exporter_master.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->exporter_master.len = hash_length;
|
||||
if ((secrets->resumption_master.data = malloc(hash_length)) == NULL)
|
||||
goto err;
|
||||
secrets->resumption_master.len = hash_length;
|
||||
|
||||
/*
|
||||
* Calculate the hash of a zero-length string - this is needed during
|
||||
* the "derived" step for key extraction.
|
||||
*/
|
||||
if ((mdctx = EVP_MD_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!EVP_DigestInit_ex(mdctx, digest, NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen))
|
||||
goto err;
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
mdctx = NULL;
|
||||
|
||||
if (secrets->empty_hash.len != mdlen)
|
||||
goto err;
|
||||
|
||||
secrets->digest = digest;
|
||||
secrets->resumption = resumption;
|
||||
secrets->init_done = 1;
|
||||
|
||||
return secrets;
|
||||
|
||||
err:
|
||||
tls13_secrets_destroy(secrets);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
|
||||
const struct tls13_secret *secret, const char *label,
|
||||
const struct tls13_secret *context)
|
||||
{
|
||||
const char tls13_plabel[] = "tls13 ";
|
||||
uint8_t *hkdf_label;
|
||||
size_t hkdf_label_len;
|
||||
CBB cbb, child;
|
||||
int ret;
|
||||
|
||||
if (!CBB_init(&cbb, 256))
|
||||
return 0;
|
||||
if (!CBB_add_u16(&cbb, out->len))
|
||||
goto err;
|
||||
if (!CBB_add_u8_length_prefixed(&cbb, &child))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&child, label, strlen(label)))
|
||||
goto err;
|
||||
if (!CBB_add_u8_length_prefixed(&cbb, &child))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&child, context->data, context->len))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
|
||||
goto err;
|
||||
|
||||
ret = HKDF_expand(out->data, out->len, digest, secret->data,
|
||||
secret->len, hkdf_label, hkdf_label_len);
|
||||
|
||||
free(hkdf_label);
|
||||
return(ret);
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
|
||||
const struct tls13_secret *secret, const char *label,
|
||||
const struct tls13_secret *context)
|
||||
{
|
||||
return tls13_hkdf_expand_label(out, digest, secret, label, context);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_derive_early_secrets(struct tls13_secrets *secrets,
|
||||
uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
|
||||
{
|
||||
if (!secrets->init_done || secrets->early_done)
|
||||
return 0;
|
||||
|
||||
if (!HKDF_extract(secrets->extracted_early.data,
|
||||
&secrets->extracted_early.len, secrets->digest, psk, psk_len,
|
||||
secrets->zeros.data, secrets->zeros.len))
|
||||
return 0;
|
||||
|
||||
if (secrets->extracted_early.len != secrets->zeros.len)
|
||||
return 0;
|
||||
|
||||
if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
|
||||
&secrets->extracted_early,
|
||||
secrets->resumption ? "res binder" : "ext binder",
|
||||
&secrets->empty_hash))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->client_early_traffic,
|
||||
secrets->digest, &secrets->extracted_early, "c e traffic",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->early_exporter_master,
|
||||
secrets->digest, &secrets->extracted_early, "e exp master",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->derived_early,
|
||||
secrets->digest, &secrets->extracted_early, "derived",
|
||||
&secrets->empty_hash))
|
||||
return 0;
|
||||
|
||||
/* RFC 8446 recommends */
|
||||
if (!secrets->insecure)
|
||||
explicit_bzero(secrets->extracted_early.data,
|
||||
secrets->extracted_early.len);
|
||||
secrets->early_done = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
|
||||
const uint8_t *ecdhe, size_t ecdhe_len,
|
||||
const struct tls13_secret *context)
|
||||
{
|
||||
if (!secrets->init_done || !secrets->early_done ||
|
||||
secrets->handshake_done)
|
||||
return 0;
|
||||
|
||||
if (!HKDF_extract(secrets->extracted_handshake.data,
|
||||
&secrets->extracted_handshake.len, secrets->digest,
|
||||
ecdhe, ecdhe_len, secrets->derived_early.data,
|
||||
secrets->derived_early.len))
|
||||
return 0;
|
||||
|
||||
if (secrets->extracted_handshake.len != secrets->zeros.len)
|
||||
return 0;
|
||||
|
||||
/* XXX */
|
||||
if (!secrets->insecure)
|
||||
explicit_bzero(secrets->derived_early.data,
|
||||
secrets->derived_early.len);
|
||||
|
||||
if (!tls13_derive_secret(&secrets->client_handshake_traffic,
|
||||
secrets->digest, &secrets->extracted_handshake, "c hs traffic",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->server_handshake_traffic,
|
||||
secrets->digest, &secrets->extracted_handshake, "s hs traffic",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->derived_handshake,
|
||||
secrets->digest, &secrets->extracted_handshake, "derived",
|
||||
&secrets->empty_hash))
|
||||
return 0;
|
||||
|
||||
/* RFC 8446 recommends */
|
||||
if (!secrets->insecure)
|
||||
explicit_bzero(secrets->extracted_handshake.data,
|
||||
secrets->extracted_handshake.len);
|
||||
|
||||
secrets->handshake_done = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_derive_application_secrets(struct tls13_secrets *secrets,
|
||||
const struct tls13_secret *context)
|
||||
{
|
||||
if (!secrets->init_done || !secrets->early_done ||
|
||||
!secrets->handshake_done || secrets->schedule_done)
|
||||
return 0;
|
||||
|
||||
if (!HKDF_extract(secrets->extracted_master.data,
|
||||
&secrets->extracted_master.len, secrets->digest,
|
||||
secrets->zeros.data, secrets->zeros.len,
|
||||
secrets->derived_handshake.data, secrets->derived_handshake.len))
|
||||
return 0;
|
||||
|
||||
if (secrets->extracted_master.len != secrets->zeros.len)
|
||||
return 0;
|
||||
|
||||
/* XXX */
|
||||
if (!secrets->insecure)
|
||||
explicit_bzero(secrets->derived_handshake.data,
|
||||
secrets->derived_handshake.len);
|
||||
|
||||
if (!tls13_derive_secret(&secrets->client_application_traffic,
|
||||
secrets->digest, &secrets->extracted_master, "c ap traffic",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->server_application_traffic,
|
||||
secrets->digest, &secrets->extracted_master, "s ap traffic",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->exporter_master,
|
||||
secrets->digest, &secrets->extracted_master, "exp master",
|
||||
context))
|
||||
return 0;
|
||||
if (!tls13_derive_secret(&secrets->resumption_master,
|
||||
secrets->digest, &secrets->extracted_master, "res master",
|
||||
context))
|
||||
return 0;
|
||||
|
||||
/* RFC 8446 recommends */
|
||||
if (!secrets->insecure)
|
||||
explicit_bzero(secrets->extracted_master.data,
|
||||
secrets->extracted_master.len);
|
||||
|
||||
secrets->schedule_done = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
|
||||
{
|
||||
struct tls13_secret context = { .data = "", .len = 0 };
|
||||
|
||||
if (!secrets->init_done || !secrets->early_done ||
|
||||
!secrets->handshake_done || !secrets->schedule_done)
|
||||
return 0;
|
||||
|
||||
return tls13_hkdf_expand_label(&secrets->client_application_traffic,
|
||||
secrets->digest, &secrets->client_application_traffic,
|
||||
"traffic upd", &context);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
|
||||
{
|
||||
struct tls13_secret context = { .data = "", .len = 0 };
|
||||
|
||||
if (!secrets->init_done || !secrets->early_done ||
|
||||
!secrets->handshake_done || !secrets->schedule_done)
|
||||
return 0;
|
||||
|
||||
return tls13_hkdf_expand_label(&secrets->server_application_traffic,
|
||||
secrets->digest, &secrets->server_application_traffic,
|
||||
"traffic upd", &context);
|
||||
}
|
||||
324
externals/libressl/ssl/tls13_key_share.c
vendored
Executable file
324
externals/libressl/ssl/tls13_key_share.c
vendored
Executable file
@@ -0,0 +1,324 @@
|
||||
/* $OpenBSD: tls13_key_share.c,v 1.6 2020/04/18 14:07:56 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/curve25519.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_locl.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
struct tls13_key_share {
|
||||
int nid;
|
||||
uint16_t group_id;
|
||||
|
||||
EC_KEY *ecdhe;
|
||||
EC_KEY *ecdhe_peer;
|
||||
|
||||
uint8_t *x25519_public;
|
||||
uint8_t *x25519_private;
|
||||
uint8_t *x25519_peer_public;
|
||||
};
|
||||
|
||||
struct tls13_key_share *
|
||||
tls13_key_share_new(uint16_t group_id)
|
||||
{
|
||||
struct tls13_key_share *ks;
|
||||
int nid;
|
||||
|
||||
if ((nid = tls1_ec_curve_id2nid(group_id)) == 0)
|
||||
return NULL;
|
||||
|
||||
if ((ks = calloc(1, sizeof(struct tls13_key_share))) == NULL)
|
||||
return NULL;
|
||||
|
||||
ks->group_id = group_id;
|
||||
ks->nid = nid;
|
||||
|
||||
return ks;
|
||||
}
|
||||
|
||||
struct tls13_key_share *
|
||||
tls13_key_share_new_nid(int nid)
|
||||
{
|
||||
uint16_t group_id;
|
||||
|
||||
if ((group_id = tls1_ec_nid2curve_id(nid)) == 0)
|
||||
return NULL;
|
||||
|
||||
return tls13_key_share_new(group_id);
|
||||
}
|
||||
|
||||
void
|
||||
tls13_key_share_free(struct tls13_key_share *ks)
|
||||
{
|
||||
if (ks == NULL)
|
||||
return;
|
||||
|
||||
EC_KEY_free(ks->ecdhe);
|
||||
EC_KEY_free(ks->ecdhe_peer);
|
||||
|
||||
freezero(ks->x25519_public, X25519_KEY_LENGTH);
|
||||
freezero(ks->x25519_private, X25519_KEY_LENGTH);
|
||||
freezero(ks->x25519_peer_public, X25519_KEY_LENGTH);
|
||||
|
||||
freezero(ks, sizeof(*ks));
|
||||
}
|
||||
|
||||
uint16_t
|
||||
tls13_key_share_group(struct tls13_key_share *ks)
|
||||
{
|
||||
return ks->group_id;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey)
|
||||
{
|
||||
if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) {
|
||||
if (!ssl_kex_dummy_ecdhe_x25519(pkey))
|
||||
return 0;
|
||||
} else if (ks->ecdhe_peer != NULL) {
|
||||
if (!EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer))
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_generate_ecdhe_ecp(struct tls13_key_share *ks)
|
||||
{
|
||||
EC_KEY *ecdhe = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ks->ecdhe != NULL)
|
||||
goto err;
|
||||
|
||||
if ((ecdhe = EC_KEY_new()) == NULL)
|
||||
goto err;
|
||||
if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid))
|
||||
goto err;
|
||||
|
||||
ks->ecdhe = ecdhe;
|
||||
ecdhe = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_KEY_free(ecdhe);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_generate_x25519(struct tls13_key_share *ks)
|
||||
{
|
||||
uint8_t *public = NULL, *private = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ks->x25519_public != NULL || ks->x25519_private != NULL)
|
||||
goto err;
|
||||
|
||||
if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL)
|
||||
goto err;
|
||||
if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL)
|
||||
goto err;
|
||||
|
||||
X25519_keypair(public, private);
|
||||
|
||||
ks->x25519_public = public;
|
||||
ks->x25519_private = private;
|
||||
public = NULL;
|
||||
private = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(public, X25519_KEY_LENGTH);
|
||||
freezero(private, X25519_KEY_LENGTH);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_key_share_generate(struct tls13_key_share *ks)
|
||||
{
|
||||
if (ks->nid == NID_X25519)
|
||||
return tls13_key_share_generate_x25519(ks);
|
||||
|
||||
return tls13_key_share_generate_ecdhe_ecp(ks);
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_public_ecdhe_ecp(struct tls13_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->ecdhe == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb);
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_public_x25519(struct tls13_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->x25519_public == NULL)
|
||||
return 0;
|
||||
|
||||
return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb)
|
||||
{
|
||||
CBB key_exchange;
|
||||
|
||||
if (!CBB_add_u16(cbb, ks->group_id))
|
||||
goto err;
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &key_exchange))
|
||||
goto err;
|
||||
|
||||
if (ks->nid == NID_X25519) {
|
||||
if (!tls13_key_share_public_x25519(ks, &key_exchange))
|
||||
goto err;
|
||||
} else {
|
||||
if (!tls13_key_share_public_ecdhe_ecp(ks, &key_exchange))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_peer_public_ecdhe_ecp(struct tls13_key_share *ks, CBS *cbs)
|
||||
{
|
||||
EC_KEY *ecdhe = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ks->ecdhe_peer != NULL)
|
||||
goto err;
|
||||
|
||||
if ((ecdhe = EC_KEY_new()) == NULL)
|
||||
goto err;
|
||||
if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs))
|
||||
goto err;
|
||||
|
||||
ks->ecdhe_peer = ecdhe;
|
||||
ecdhe = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_KEY_free(ecdhe);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_peer_public_x25519(struct tls13_key_share *ks, CBS *cbs)
|
||||
{
|
||||
size_t out_len;
|
||||
|
||||
if (ks->x25519_peer_public != NULL)
|
||||
return 0;
|
||||
|
||||
if (CBS_len(cbs) != X25519_KEY_LENGTH)
|
||||
return 0;
|
||||
|
||||
return CBS_stow(cbs, &ks->x25519_peer_public, &out_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
|
||||
CBS *cbs)
|
||||
{
|
||||
if (ks->group_id != group)
|
||||
return 0;
|
||||
|
||||
if (ks->nid == NID_X25519) {
|
||||
if (!tls13_key_share_peer_public_x25519(ks, cbs))
|
||||
return 0;
|
||||
} else {
|
||||
if (!tls13_key_share_peer_public_ecdhe_ecp(ks, cbs))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_derive_ecdhe_ecp(struct tls13_key_share *ks,
|
||||
uint8_t **shared_key, size_t *shared_key_len)
|
||||
{
|
||||
if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer,
|
||||
shared_key, shared_key_len);
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_key_share_derive_x25519(struct tls13_key_share *ks,
|
||||
uint8_t **shared_key, size_t *shared_key_len)
|
||||
{
|
||||
uint8_t *sk = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL)
|
||||
goto err;
|
||||
|
||||
if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL)
|
||||
goto err;
|
||||
if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public))
|
||||
goto err;
|
||||
|
||||
*shared_key = sk;
|
||||
*shared_key_len = X25519_KEY_LENGTH;
|
||||
sk = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(sk, X25519_KEY_LENGTH);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
|
||||
size_t *shared_key_len)
|
||||
{
|
||||
if (*shared_key != NULL)
|
||||
return 0;
|
||||
|
||||
*shared_key_len = 0;
|
||||
|
||||
if (ks->nid == NID_X25519)
|
||||
return tls13_key_share_derive_x25519(ks, shared_key,
|
||||
shared_key_len);
|
||||
|
||||
return tls13_key_share_derive_ecdhe_ecp(ks, shared_key,
|
||||
shared_key_len);
|
||||
}
|
||||
525
externals/libressl/ssl/tls13_legacy.c
vendored
Executable file
525
externals/libressl/ssl/tls13_legacy.c
vendored
Executable file
@@ -0,0 +1,525 @@
|
||||
/* $OpenBSD: tls13_legacy.c,v 1.13 2020/09/13 15:04:35 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
SSL3_ENC_METHOD TLSv1_3_enc_data = {
|
||||
.enc_flags = SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_TLS1_3_CIPHERS,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (ssl->rbio == NULL) {
|
||||
SSLerror(ssl, SSL_R_BIO_NOT_SET);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
ssl->internal->rwstate = SSL_READING;
|
||||
errno = 0;
|
||||
|
||||
if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) {
|
||||
if (BIO_should_read(ssl->rbio))
|
||||
return TLS13_IO_WANT_POLLIN;
|
||||
if (BIO_should_write(ssl->rbio))
|
||||
return TLS13_IO_WANT_POLLOUT;
|
||||
if (n == 0)
|
||||
return TLS13_IO_EOF;
|
||||
|
||||
if (ERR_peek_error() == 0 && errno != 0)
|
||||
SYSerror(errno);
|
||||
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if (n == len)
|
||||
ssl->internal->rwstate = SSL_NOTHING;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
|
||||
return tls13_legacy_wire_read(ctx->ssl, buf, n);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (ssl->wbio == NULL) {
|
||||
SSLerror(ssl, SSL_R_BIO_NOT_SET);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
ssl->internal->rwstate = SSL_WRITING;
|
||||
errno = 0;
|
||||
|
||||
if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
|
||||
if (BIO_should_read(ssl->wbio))
|
||||
return TLS13_IO_WANT_POLLIN;
|
||||
if (BIO_should_write(ssl->wbio))
|
||||
return TLS13_IO_WANT_POLLOUT;
|
||||
|
||||
if (ERR_peek_error() == 0 && errno != 0)
|
||||
SYSerror(errno);
|
||||
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if (n == len)
|
||||
ssl->internal->rwstate = SSL_NOTHING;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
|
||||
return tls13_legacy_wire_write(ctx->ssl, buf, n);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_error(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
int reason = SSL_R_UNKNOWN;
|
||||
|
||||
/* If we received a fatal alert we already put an error on the stack. */
|
||||
if (S3I(ssl)->fatal_alert != 0)
|
||||
return;
|
||||
|
||||
switch (ctx->error.code) {
|
||||
case TLS13_ERR_VERIFY_FAILED:
|
||||
reason = SSL_R_CERTIFICATE_VERIFY_FAILED;
|
||||
break;
|
||||
case TLS13_ERR_HRR_FAILED:
|
||||
reason = SSL_R_NO_CIPHERS_AVAILABLE;
|
||||
break;
|
||||
case TLS13_ERR_TRAILING_DATA:
|
||||
reason = SSL_R_EXTRA_DATA_IN_MESSAGE;
|
||||
break;
|
||||
case TLS13_ERR_NO_SHARED_CIPHER:
|
||||
reason = SSL_R_NO_SHARED_CIPHER;
|
||||
break;
|
||||
case TLS13_ERR_NO_CERTIFICATE:
|
||||
reason = SSL_R_MISSING_RSA_CERTIFICATE; /* XXX */
|
||||
break;
|
||||
case TLS13_ERR_NO_PEER_CERTIFICATE:
|
||||
reason = SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Something (probably libcrypto) already pushed an error on the stack. */
|
||||
if (reason == SSL_R_UNKNOWN && ERR_peek_error() != 0)
|
||||
return;
|
||||
|
||||
ERR_put_error(ERR_LIB_SSL, (0xfff), reason, ctx->error.file,
|
||||
ctx->error.line);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_return_code(SSL *ssl, ssize_t ret)
|
||||
{
|
||||
if (ret > INT_MAX) {
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* A successful read, write or other operation. */
|
||||
if (ret > 0)
|
||||
return ret;
|
||||
|
||||
ssl->internal->rwstate = SSL_NOTHING;
|
||||
|
||||
switch (ret) {
|
||||
case TLS13_IO_EOF:
|
||||
return 0;
|
||||
|
||||
case TLS13_IO_FAILURE:
|
||||
tls13_legacy_error(ssl);
|
||||
return -1;
|
||||
|
||||
case TLS13_IO_ALERT:
|
||||
tls13_legacy_error(ssl);
|
||||
return -1;
|
||||
|
||||
case TLS13_IO_WANT_POLLIN:
|
||||
BIO_set_retry_read(ssl->rbio);
|
||||
ssl->internal->rwstate = SSL_READING;
|
||||
return -1;
|
||||
|
||||
case TLS13_IO_WANT_POLLOUT:
|
||||
BIO_set_retry_write(ssl->wbio);
|
||||
ssl->internal->rwstate = SSL_WRITING;
|
||||
return -1;
|
||||
|
||||
case TLS13_IO_WANT_RETRY:
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_pending(const SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
ssize_t ret;
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
ret = tls13_pending_application_data(ctx->rl);
|
||||
if (ret < 0 || ret > INT_MAX)
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
ssize_t ret;
|
||||
|
||||
if (ctx == NULL || !ctx->handshake_completed) {
|
||||
if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
|
||||
return ret;
|
||||
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN);
|
||||
}
|
||||
|
||||
tls13_record_layer_set_retry_after_phh(ctx->rl,
|
||||
(ctx->ssl->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
|
||||
|
||||
if (type != SSL3_RT_APPLICATION_DATA) {
|
||||
SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
if (len < 0) {
|
||||
SSLerror(ssl, SSL_R_BAD_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (peek)
|
||||
ret = tls13_peek_application_data(ctx->rl, buf, len);
|
||||
else
|
||||
ret = tls13_read_application_data(ctx->rl, buf, len);
|
||||
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
const uint8_t *buf = vbuf;
|
||||
size_t n, sent;
|
||||
ssize_t ret;
|
||||
|
||||
if (ctx == NULL || !ctx->handshake_completed) {
|
||||
if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
|
||||
return ret;
|
||||
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLOUT);
|
||||
}
|
||||
|
||||
if (type != SSL3_RT_APPLICATION_DATA) {
|
||||
SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
if (len < 0) {
|
||||
SSLerror(ssl, SSL_R_BAD_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The TLSv1.3 record layer write behaviour is the same as
|
||||
* SSL_MODE_ENABLE_PARTIAL_WRITE.
|
||||
*/
|
||||
if (ssl->internal->mode & SSL_MODE_ENABLE_PARTIAL_WRITE) {
|
||||
ret = tls13_write_application_data(ctx->rl, buf, len);
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until
|
||||
* we have written out all of the requested data.
|
||||
*/
|
||||
sent = S3I(ssl)->wnum;
|
||||
if (len < sent) {
|
||||
SSLerror(ssl, SSL_R_BAD_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
n = len - sent;
|
||||
for (;;) {
|
||||
if (n == 0) {
|
||||
S3I(ssl)->wnum = 0;
|
||||
return sent;
|
||||
}
|
||||
if ((ret = tls13_write_application_data(ctx->rl,
|
||||
&buf[sent], n)) <= 0) {
|
||||
S3I(ssl)->wnum = sent;
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
sent += ret;
|
||||
n -= ret;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_use_legacy_stack(struct tls13_ctx *ctx)
|
||||
{
|
||||
SSL *s = ctx->ssl;
|
||||
CBS cbs;
|
||||
|
||||
if (!ssl3_setup_init_buffer(s))
|
||||
return 0;
|
||||
if (!ssl3_setup_buffers(s))
|
||||
return 0;
|
||||
if (!ssl_init_wbio_buffer(s, 1))
|
||||
return 0;
|
||||
|
||||
/* Stash any unprocessed data from the last record. */
|
||||
tls13_record_layer_rbuf(ctx->rl, &cbs);
|
||||
if (CBS_len(&cbs) > 0) {
|
||||
if (!CBS_write_bytes(&cbs,
|
||||
S3I(s)->rbuf.buf + SSL3_RT_HEADER_LENGTH,
|
||||
S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH, NULL))
|
||||
return 0;
|
||||
|
||||
S3I(s)->rbuf.offset = SSL3_RT_HEADER_LENGTH;
|
||||
S3I(s)->rbuf.left = CBS_len(&cbs);
|
||||
S3I(s)->rrec.type = SSL3_RT_HANDSHAKE;
|
||||
S3I(s)->rrec.length = CBS_len(&cbs);
|
||||
s->internal->rstate = SSL_ST_READ_BODY;
|
||||
s->internal->packet = S3I(s)->rbuf.buf;
|
||||
s->internal->packet_length = SSL3_RT_HEADER_LENGTH;
|
||||
s->internal->mac_packet = 1;
|
||||
}
|
||||
|
||||
/* Stash the current handshake message. */
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
if (!CBS_write_bytes(&cbs, s->internal->init_buf->data,
|
||||
s->internal->init_buf->length, NULL))
|
||||
return 0;
|
||||
|
||||
S3I(s)->tmp.reuse_message = 1;
|
||||
S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg);
|
||||
S3I(s)->tmp.message_size = CBS_len(&cbs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_use_legacy_client(struct tls13_ctx *ctx)
|
||||
{
|
||||
SSL *s = ctx->ssl;
|
||||
|
||||
s->method = tls_legacy_client_method();
|
||||
s->internal->handshake_func = s->method->internal->ssl_connect;
|
||||
s->client_version = s->version = s->method->internal->max_version;
|
||||
|
||||
if (!tls13_use_legacy_stack(ctx))
|
||||
return 0;
|
||||
|
||||
S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_use_legacy_server(struct tls13_ctx *ctx)
|
||||
{
|
||||
SSL *s = ctx->ssl;
|
||||
|
||||
s->method = tls_legacy_server_method();
|
||||
s->internal->handshake_func = s->method->internal->ssl_accept;
|
||||
s->client_version = s->version = s->method->internal->max_version;
|
||||
s->server = 1;
|
||||
|
||||
if (!tls13_use_legacy_stack(ctx))
|
||||
return 0;
|
||||
|
||||
S3I(s)->hs.state = SSL3_ST_SR_CLNT_HELLO_A;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_accept(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
if ((ctx = tls13_ctx_new(TLS13_HS_SERVER)) == NULL) {
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
ssl->internal->tls13 = ctx;
|
||||
ctx->ssl = ssl;
|
||||
ctx->hs = &S3I(ssl)->hs_tls13;
|
||||
|
||||
if (!tls13_server_init(ctx)) {
|
||||
if (ERR_peek_error() == 0)
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
S3I(ssl)->hs.state = SSL_ST_ACCEPT;
|
||||
|
||||
ret = tls13_server_accept(ctx);
|
||||
if (ret == TLS13_IO_USE_LEGACY)
|
||||
return ssl->method->internal->ssl_accept(ssl);
|
||||
if (ret == TLS13_IO_SUCCESS)
|
||||
S3I(ssl)->hs.state = SSL_ST_OK;
|
||||
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_connect(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
int ret;
|
||||
|
||||
#ifdef TLS13_USE_LEGACY_CLIENT_AUTH
|
||||
/* XXX drop back to legacy for client auth for now */
|
||||
if (ssl->cert->key->privatekey != NULL) {
|
||||
ssl->method = tls_legacy_client_method();
|
||||
return ssl->method->internal->ssl_connect(ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ctx == NULL) {
|
||||
if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) {
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
ssl->internal->tls13 = ctx;
|
||||
ctx->ssl = ssl;
|
||||
ctx->hs = &S3I(ssl)->hs_tls13;
|
||||
|
||||
if (!tls13_client_init(ctx)) {
|
||||
if (ERR_peek_error() == 0)
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
S3I(ssl)->hs.state = SSL_ST_CONNECT;
|
||||
|
||||
ret = tls13_client_connect(ctx);
|
||||
if (ret == TLS13_IO_USE_LEGACY)
|
||||
return ssl->method->internal->ssl_connect(ssl);
|
||||
if (ret == TLS13_IO_SUCCESS)
|
||||
S3I(ssl)->hs.state = SSL_ST_OK;
|
||||
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_shutdown(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->internal->tls13;
|
||||
uint8_t buf[512]; /* XXX */
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
* We need to return 0 when we have sent a close-notify but have not
|
||||
* yet received one. We return 1 only once we have sent and received
|
||||
* close-notify alerts. All other cases return -1 and set internal
|
||||
* state appropriately.
|
||||
*/
|
||||
if (ctx == NULL || ssl->internal->quiet_shutdown) {
|
||||
ssl->internal->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ctx->close_notify_sent) {
|
||||
/* Enqueue and send close notify. */
|
||||
if (!(ssl->internal->shutdown & SSL_SENT_SHUTDOWN)) {
|
||||
ssl->internal->shutdown |= SSL_SENT_SHUTDOWN;
|
||||
if ((ret = tls13_send_alert(ctx->rl,
|
||||
TLS13_ALERT_CLOSE_NOTIFY)) < 0)
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
if ((ret = tls13_record_layer_send_pending(ctx->rl)) !=
|
||||
TLS13_IO_SUCCESS)
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
} else if (!ctx->close_notify_recv) {
|
||||
/*
|
||||
* If there is no application data pending, attempt to read more
|
||||
* data in order to receive a close notify. This should trigger
|
||||
* a record to be read from the wire, which may be application
|
||||
* handshake or alert data. Only one attempt is made to match
|
||||
* previous semantics.
|
||||
*/
|
||||
if (tls13_pending_application_data(ctx->rl) == 0) {
|
||||
if ((ret = tls13_read_application_data(ctx->rl, buf,
|
||||
sizeof(buf))) < 0)
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->close_notify_recv)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert)
|
||||
{
|
||||
int legacy_alert = SSL_AD_UNRECOGNIZED_NAME;
|
||||
int ret = SSL_TLSEXT_ERR_NOACK;
|
||||
SSL_CTX *ssl_ctx = ctx->ssl->ctx;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
if (ssl_ctx->internal->tlsext_servername_callback == NULL)
|
||||
ssl_ctx = ssl->initial_ctx;
|
||||
if (ssl_ctx->internal->tlsext_servername_callback == NULL)
|
||||
return 1;
|
||||
|
||||
ret = ssl_ctx->internal->tlsext_servername_callback(ssl, &legacy_alert,
|
||||
ssl_ctx->internal->tlsext_servername_arg);
|
||||
|
||||
if (ret == SSL_TLSEXT_ERR_ALERT_FATAL ||
|
||||
ret == SSL_TLSEXT_ERR_ALERT_WARNING) {
|
||||
if (legacy_alert >= 0 && legacy_alert <= 255)
|
||||
*alert = legacy_alert;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
581
externals/libressl/ssl/tls13_lib.c
vendored
Executable file
581
externals/libressl/ssl/tls13_lib.c
vendored
Executable file
@@ -0,0 +1,581 @@
|
||||
/* $OpenBSD: tls13_lib.c,v 1.54 2020/09/11 15:03:36 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
|
||||
* Copyright (c) 2019 Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "ssl_locl.h"
|
||||
#include "ssl_tlsext.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
/*
|
||||
* Downgrade sentinels - RFC 8446 section 4.1.3, magic values which must be set
|
||||
* by the server in server random if it is willing to downgrade but supports
|
||||
* TLSv1.3
|
||||
*/
|
||||
const uint8_t tls13_downgrade_12[8] = {
|
||||
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01,
|
||||
};
|
||||
const uint8_t tls13_downgrade_11[8] = {
|
||||
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00,
|
||||
};
|
||||
|
||||
/*
|
||||
* HelloRetryRequest hash - RFC 8446 section 4.1.3.
|
||||
*/
|
||||
const uint8_t tls13_hello_retry_request_hash[32] = {
|
||||
0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11,
|
||||
0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91,
|
||||
0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e,
|
||||
0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
|
||||
};
|
||||
|
||||
/*
|
||||
* Certificate Verify padding - RFC 8446 section 4.4.3.
|
||||
*/
|
||||
const uint8_t tls13_cert_verify_pad[64] = {
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
};
|
||||
|
||||
const uint8_t tls13_cert_client_verify_context[] =
|
||||
"TLS 1.3, client CertificateVerify";
|
||||
const uint8_t tls13_cert_server_verify_context[] =
|
||||
"TLS 1.3, server CertificateVerify";
|
||||
|
||||
const EVP_AEAD *
|
||||
tls13_cipher_aead(const SSL_CIPHER *cipher)
|
||||
{
|
||||
if (cipher == NULL)
|
||||
return NULL;
|
||||
if (cipher->algorithm_ssl != SSL_TLSV1_3)
|
||||
return NULL;
|
||||
|
||||
switch (cipher->algorithm_enc) {
|
||||
case SSL_AES128GCM:
|
||||
return EVP_aead_aes_128_gcm();
|
||||
case SSL_AES256GCM:
|
||||
return EVP_aead_aes_256_gcm();
|
||||
case SSL_CHACHA20POLY1305:
|
||||
return EVP_aead_chacha20_poly1305();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
tls13_cipher_hash(const SSL_CIPHER *cipher)
|
||||
{
|
||||
if (cipher == NULL)
|
||||
return NULL;
|
||||
if (cipher->algorithm_ssl != SSL_TLSV1_3)
|
||||
return NULL;
|
||||
|
||||
switch (cipher->algorithm2) {
|
||||
case SSL_HANDSHAKE_MAC_SHA256:
|
||||
return EVP_sha256();
|
||||
case SSL_HANDSHAKE_MAC_SHA384:
|
||||
return EVP_sha384();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_alert_received_cb(uint8_t alert_desc, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
|
||||
if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
|
||||
ctx->close_notify_recv = 1;
|
||||
ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
|
||||
S3I(ctx->ssl)->warn_alert = alert_desc;
|
||||
return;
|
||||
}
|
||||
|
||||
if (alert_desc == TLS13_ALERT_USER_CANCELED) {
|
||||
/*
|
||||
* We treat this as advisory, since a close_notify alert
|
||||
* SHOULD follow this alert (RFC 8446 section 6.1).
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* All other alerts are treated as fatal in TLSv1.3. */
|
||||
S3I(ctx->ssl)->fatal_alert = alert_desc;
|
||||
|
||||
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
|
||||
ERR_asprintf_error_data("SSL alert number %d", alert_desc);
|
||||
|
||||
SSL_CTX_remove_session(ctx->ssl->ctx, ctx->ssl->session);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_alert_sent_cb(uint8_t alert_desc, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
|
||||
if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
|
||||
ctx->close_notify_sent = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (alert_desc == TLS13_ALERT_USER_CANCELED) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* All other alerts are treated as fatal in TLSv1.3. */
|
||||
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_handshake_message_recv_cb(void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *s = ctx->ssl;
|
||||
CBS cbs;
|
||||
|
||||
if (s->internal->msg_callback == NULL)
|
||||
return;
|
||||
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
s->internal->msg_callback(0, TLS1_3_VERSION, SSL3_RT_HANDSHAKE,
|
||||
CBS_data(&cbs), CBS_len(&cbs), s, s->internal->msg_callback_arg);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_handshake_message_sent_cb(void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *s = ctx->ssl;
|
||||
CBS cbs;
|
||||
|
||||
if (s->internal->msg_callback == NULL)
|
||||
return;
|
||||
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
s->internal->msg_callback(1, TLS1_3_VERSION, SSL3_RT_HANDSHAKE,
|
||||
CBS_data(&cbs), CBS_len(&cbs), s, s->internal->msg_callback_arg);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_info_cb(void *arg, int state, int ret)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *s = ctx->ssl;
|
||||
void (*cb)(const SSL *, int, int);
|
||||
|
||||
if ((cb = s->internal->info_callback) == NULL)
|
||||
cb = s->ctx->internal->info_callback;
|
||||
if (cb != NULL)
|
||||
cb(s, state, ret);
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_legacy_ocsp_status_recv_cb(void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *s = ctx->ssl;
|
||||
int ret;
|
||||
|
||||
if (s->ctx->internal->tlsext_status_cb == NULL ||
|
||||
s->internal->tlsext_ocsp_resp == NULL)
|
||||
return 1;
|
||||
|
||||
ret = s->ctx->internal->tlsext_status_cb(s,
|
||||
s->ctx->internal->tlsext_status_arg);
|
||||
if (ret < 0) {
|
||||
ctx->alert = TLS13_ALERT_INTERNAL_ERROR;
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (ret == 0) {
|
||||
ctx->alert = TLS13_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE;
|
||||
SSLerror(s, SSL_R_INVALID_STATUS_RESPONSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_phh_update_local_traffic_secret(struct tls13_ctx *ctx)
|
||||
{
|
||||
struct tls13_secrets *secrets = ctx->hs->secrets;
|
||||
|
||||
if (ctx->mode == TLS13_HS_CLIENT)
|
||||
return (tls13_update_client_traffic_secret(secrets) &&
|
||||
tls13_record_layer_set_write_traffic_key(ctx->rl,
|
||||
&secrets->client_application_traffic));
|
||||
return (tls13_update_server_traffic_secret(secrets) &&
|
||||
tls13_record_layer_set_read_traffic_key(ctx->rl,
|
||||
&secrets->server_application_traffic));
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_phh_update_peer_traffic_secret(struct tls13_ctx *ctx)
|
||||
{
|
||||
struct tls13_secrets *secrets = ctx->hs->secrets;
|
||||
|
||||
if (ctx->mode == TLS13_HS_CLIENT)
|
||||
return (tls13_update_server_traffic_secret(secrets) &&
|
||||
tls13_record_layer_set_read_traffic_key(ctx->rl,
|
||||
&secrets->server_application_traffic));
|
||||
return (tls13_update_client_traffic_secret(secrets) &&
|
||||
tls13_record_layer_set_write_traffic_key(ctx->rl,
|
||||
&secrets->client_application_traffic));
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX arbitrarily chosen limit of 100 post handshake handshake
|
||||
* messages in an hour - to avoid a hostile peer from constantly
|
||||
* requesting certificates or key renegotiaitons, etc.
|
||||
*/
|
||||
static int
|
||||
tls13_phh_limit_check(struct tls13_ctx *ctx)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
if (ctx->phh_last_seen > now - TLS13_PHH_LIMIT_TIME) {
|
||||
if (ctx->phh_count > TLS13_PHH_LIMIT)
|
||||
return 0;
|
||||
} else
|
||||
ctx->phh_count = 0;
|
||||
ctx->phh_count++;
|
||||
ctx->phh_last_seen = now;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_key_update_recv(struct tls13_ctx *ctx, CBS *cbs)
|
||||
{
|
||||
struct tls13_handshake_msg *hs_msg = NULL;
|
||||
CBB cbb_hs;
|
||||
CBS cbs_hs;
|
||||
uint8_t alert = TLS13_ALERT_INTERNAL_ERROR;
|
||||
uint8_t key_update_request;
|
||||
ssize_t ret;
|
||||
|
||||
if (!CBS_get_u8(cbs, &key_update_request)) {
|
||||
alert = TLS13_ALERT_DECODE_ERROR;
|
||||
goto err;
|
||||
}
|
||||
if (CBS_len(cbs) != 0) {
|
||||
alert = TLS13_ALERT_DECODE_ERROR;
|
||||
goto err;
|
||||
}
|
||||
if (key_update_request > 1) {
|
||||
alert = TLS13_ALERT_ILLEGAL_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!tls13_phh_update_peer_traffic_secret(ctx))
|
||||
goto err;
|
||||
|
||||
if (key_update_request == 0)
|
||||
return TLS13_IO_SUCCESS;
|
||||
|
||||
/* key_update_request == 1 */
|
||||
if ((hs_msg = tls13_handshake_msg_new()) == NULL)
|
||||
goto err;
|
||||
if (!tls13_handshake_msg_start(hs_msg, &cbb_hs, TLS13_MT_KEY_UPDATE))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&cbb_hs, 0))
|
||||
goto err;
|
||||
if (!tls13_handshake_msg_finish(hs_msg))
|
||||
goto err;
|
||||
|
||||
ctx->key_update_request = 1;
|
||||
tls13_handshake_msg_data(hs_msg, &cbs_hs);
|
||||
ret = tls13_record_layer_phh(ctx->rl, &cbs_hs);
|
||||
|
||||
tls13_handshake_msg_free(hs_msg);
|
||||
hs_msg = NULL;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
tls13_handshake_msg_free(hs_msg);
|
||||
|
||||
return tls13_send_alert(ctx->rl, alert);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_phh_done_cb(void *cb_arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = cb_arg;
|
||||
|
||||
if (ctx->key_update_request) {
|
||||
tls13_phh_update_local_traffic_secret(ctx);
|
||||
ctx->key_update_request = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_phh_received_cb(void *cb_arg, CBS *cbs)
|
||||
{
|
||||
ssize_t ret = TLS13_IO_FAILURE;
|
||||
struct tls13_ctx *ctx = cb_arg;
|
||||
CBS phh_cbs;
|
||||
|
||||
if (!tls13_phh_limit_check(ctx))
|
||||
return tls13_send_alert(ctx->rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
|
||||
|
||||
if ((ctx->hs_msg == NULL) &&
|
||||
((ctx->hs_msg = tls13_handshake_msg_new()) == NULL))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (!tls13_handshake_msg_set_buffer(ctx->hs_msg, cbs))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl))
|
||||
!= TLS13_IO_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (!tls13_handshake_msg_content(ctx->hs_msg, &phh_cbs))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
switch(tls13_handshake_msg_type(ctx->hs_msg)) {
|
||||
case TLS13_MT_KEY_UPDATE:
|
||||
ret = tls13_key_update_recv(ctx, &phh_cbs);
|
||||
break;
|
||||
case TLS13_MT_NEW_SESSION_TICKET:
|
||||
/* XXX do nothing for now and ignore this */
|
||||
break;
|
||||
case TLS13_MT_CERTIFICATE_REQUEST:
|
||||
/* XXX add support if we choose to advertise this */
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
ret = TLS13_IO_FAILURE; /* XXX send alert */
|
||||
break;
|
||||
}
|
||||
|
||||
tls13_handshake_msg_free(ctx->hs_msg);
|
||||
ctx->hs_msg = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct tls13_record_layer_callbacks rl_callbacks = {
|
||||
.wire_read = tls13_legacy_wire_read_cb,
|
||||
.wire_write = tls13_legacy_wire_write_cb,
|
||||
.alert_recv = tls13_alert_received_cb,
|
||||
.alert_sent = tls13_alert_sent_cb,
|
||||
.phh_recv = tls13_phh_received_cb,
|
||||
.phh_sent = tls13_phh_done_cb,
|
||||
};
|
||||
|
||||
struct tls13_ctx *
|
||||
tls13_ctx_new(int mode)
|
||||
{
|
||||
struct tls13_ctx *ctx = NULL;
|
||||
|
||||
if ((ctx = calloc(sizeof(struct tls13_ctx), 1)) == NULL)
|
||||
goto err;
|
||||
|
||||
ctx->mode = mode;
|
||||
|
||||
if ((ctx->rl = tls13_record_layer_new(&rl_callbacks, ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
ctx->handshake_message_sent_cb = tls13_legacy_handshake_message_sent_cb;
|
||||
ctx->handshake_message_recv_cb = tls13_legacy_handshake_message_recv_cb;
|
||||
ctx->info_cb = tls13_legacy_info_cb;
|
||||
ctx->ocsp_status_recv_cb = tls13_legacy_ocsp_status_recv_cb;
|
||||
|
||||
ctx->middlebox_compat = 1;
|
||||
|
||||
return ctx;
|
||||
|
||||
err:
|
||||
tls13_ctx_free(ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_ctx_free(struct tls13_ctx *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
tls13_error_clear(&ctx->error);
|
||||
tls13_record_layer_free(ctx->rl);
|
||||
tls13_handshake_msg_free(ctx->hs_msg);
|
||||
|
||||
freezero(ctx, sizeof(struct tls13_ctx));
|
||||
}
|
||||
|
||||
int
|
||||
tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert,
|
||||
int(*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb))
|
||||
{
|
||||
CBB cert_data;
|
||||
uint8_t *data;
|
||||
int cert_len;
|
||||
|
||||
if ((cert_len = i2d_X509(cert, NULL)) < 0)
|
||||
return 0;
|
||||
|
||||
if (!CBB_add_u24_length_prefixed(cbb, &cert_data))
|
||||
return 0;
|
||||
if (!CBB_add_space(&cert_data, &data, cert_len))
|
||||
return 0;
|
||||
if (i2d_X509(cert, &data) != cert_len)
|
||||
return 0;
|
||||
if (build_extensions != NULL) {
|
||||
if (!build_extensions(ctx->ssl, SSL_TLSEXT_MSG_CT, cbb))
|
||||
return 0;
|
||||
} else {
|
||||
CBB cert_exts;
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &cert_exts))
|
||||
return 0;
|
||||
}
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_synthetic_handshake_message(struct tls13_ctx *ctx)
|
||||
{
|
||||
struct tls13_handshake_msg *hm = NULL;
|
||||
unsigned char buf[EVP_MAX_MD_SIZE];
|
||||
size_t hash_len;
|
||||
CBB cbb;
|
||||
CBS cbs;
|
||||
SSL *s = ctx->ssl;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Replace ClientHello with synthetic handshake message - see
|
||||
* RFC 8446 section 4.4.1.
|
||||
*/
|
||||
if (!tls1_transcript_hash_init(s))
|
||||
goto err;
|
||||
if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len))
|
||||
goto err;
|
||||
|
||||
if ((hm = tls13_handshake_msg_new()) == NULL)
|
||||
goto err;
|
||||
if (!tls13_handshake_msg_start(hm, &cbb, TLS13_MT_MESSAGE_HASH))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, buf, hash_len))
|
||||
goto err;
|
||||
if (!tls13_handshake_msg_finish(hm))
|
||||
goto err;
|
||||
|
||||
tls13_handshake_msg_data(hm, &cbs);
|
||||
|
||||
tls1_transcript_reset(ctx->ssl);
|
||||
if (!tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs)))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
tls13_handshake_msg_free(hm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_clienthello_hash_init(struct tls13_ctx *ctx)
|
||||
{
|
||||
if (ctx->hs->clienthello_md_ctx != NULL)
|
||||
return 0;
|
||||
if ((ctx->hs->clienthello_md_ctx = EVP_MD_CTX_new()) == NULL)
|
||||
return 0;
|
||||
if (!EVP_DigestInit_ex(ctx->hs->clienthello_md_ctx,
|
||||
EVP_sha256(), NULL))
|
||||
return 0;
|
||||
|
||||
if ((ctx->hs->clienthello_hash == NULL) &&
|
||||
(ctx->hs->clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) ==
|
||||
NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs)
|
||||
{
|
||||
EVP_MD_CTX_free(hs->clienthello_md_ctx);
|
||||
hs->clienthello_md_ctx = NULL;
|
||||
freezero(hs->clienthello_hash, EVP_MAX_MD_SIZE);
|
||||
hs->clienthello_hash = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data,
|
||||
size_t len)
|
||||
{
|
||||
return EVP_DigestUpdate(ctx->hs->clienthello_md_ctx, data, len);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs)
|
||||
{
|
||||
return tls13_clienthello_hash_update_bytes(ctx, (void *)CBS_data(cbs),
|
||||
CBS_len(cbs));
|
||||
}
|
||||
|
||||
int
|
||||
tls13_clienthello_hash_finalize(struct tls13_ctx *ctx)
|
||||
{
|
||||
if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx,
|
||||
ctx->hs->clienthello_hash,
|
||||
&ctx->hs->clienthello_hash_len))
|
||||
return 0;
|
||||
EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx);
|
||||
ctx->hs->clienthello_md_ctx = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_clienthello_hash_validate(struct tls13_ctx *ctx)
|
||||
{
|
||||
unsigned char new_ch_hash[EVP_MAX_MD_SIZE];
|
||||
unsigned int new_ch_hash_len;
|
||||
|
||||
if (ctx->hs->clienthello_hash == NULL)
|
||||
return 0;
|
||||
|
||||
if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx,
|
||||
new_ch_hash, &new_ch_hash_len))
|
||||
return 0;
|
||||
EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx);
|
||||
ctx->hs->clienthello_md_ctx = NULL;
|
||||
|
||||
if (ctx->hs->clienthello_hash_len != new_ch_hash_len)
|
||||
return 0;
|
||||
if (memcmp(ctx->hs->clienthello_hash, new_ch_hash,
|
||||
new_ch_hash_len) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
187
externals/libressl/ssl/tls13_record.c
vendored
Executable file
187
externals/libressl/ssl/tls13_record.c
vendored
Executable file
@@ -0,0 +1,187 @@
|
||||
/* $OpenBSD: tls13_record.c,v 1.6 2020/05/11 18:08:11 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "ssl_locl.h"
|
||||
|
||||
#include "tls13_internal.h"
|
||||
#include "tls13_record.h"
|
||||
|
||||
struct tls13_record {
|
||||
uint16_t version;
|
||||
uint8_t content_type;
|
||||
size_t rec_len;
|
||||
uint8_t *data;
|
||||
size_t data_len;
|
||||
CBS cbs;
|
||||
|
||||
struct tls13_buffer *buf;
|
||||
};
|
||||
|
||||
struct tls13_record *
|
||||
tls13_record_new(void)
|
||||
{
|
||||
struct tls13_record *rec = NULL;
|
||||
|
||||
if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL)
|
||||
goto err;
|
||||
if ((rec->buf = tls13_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
|
||||
goto err;
|
||||
|
||||
return rec;
|
||||
|
||||
err:
|
||||
tls13_record_free(rec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_record_free(struct tls13_record *rec)
|
||||
{
|
||||
if (rec == NULL)
|
||||
return;
|
||||
|
||||
tls13_buffer_free(rec->buf);
|
||||
|
||||
freezero(rec->data, rec->data_len);
|
||||
freezero(rec, sizeof(struct tls13_record));
|
||||
}
|
||||
|
||||
uint16_t
|
||||
tls13_record_version(struct tls13_record *rec)
|
||||
{
|
||||
return rec->version;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
tls13_record_content_type(struct tls13_record *rec)
|
||||
{
|
||||
return rec->content_type;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_record_header(struct tls13_record *rec, CBS *cbs)
|
||||
{
|
||||
if (rec->data_len < TLS13_RECORD_HEADER_LEN)
|
||||
return 0;
|
||||
|
||||
CBS_init(cbs, rec->data, TLS13_RECORD_HEADER_LEN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_record_content(struct tls13_record *rec, CBS *cbs)
|
||||
{
|
||||
CBS content;
|
||||
|
||||
tls13_record_data(rec, &content);
|
||||
|
||||
if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN))
|
||||
return 0;
|
||||
|
||||
CBS_dup(&content, cbs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_record_data(struct tls13_record *rec, CBS *cbs)
|
||||
{
|
||||
CBS_init(cbs, rec->data, rec->data_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len)
|
||||
{
|
||||
if (data_len > TLS13_RECORD_MAX_LEN)
|
||||
return 0;
|
||||
|
||||
freezero(rec->data, rec->data_len);
|
||||
rec->data = data;
|
||||
rec->data_len = data_len;
|
||||
CBS_init(&rec->cbs, rec->data, rec->data_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read,
|
||||
void *wire_arg)
|
||||
{
|
||||
uint16_t rec_len, rec_version;
|
||||
uint8_t content_type;
|
||||
ssize_t ret;
|
||||
CBS cbs;
|
||||
|
||||
if (rec->data != NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (rec->content_type == 0) {
|
||||
if ((ret = tls13_buffer_extend(rec->buf,
|
||||
TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
|
||||
return ret;
|
||||
|
||||
tls13_buffer_cbs(rec->buf, &cbs);
|
||||
|
||||
if (!CBS_get_u8(&cbs, &content_type))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!CBS_get_u16(&cbs, &rec_version))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!CBS_get_u16(&cbs, &rec_len))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if ((rec_version >> 8) != SSL3_VERSION_MAJOR)
|
||||
return TLS13_IO_RECORD_VERSION;
|
||||
if (rec_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN)
|
||||
return TLS13_IO_RECORD_OVERFLOW;
|
||||
|
||||
rec->content_type = content_type;
|
||||
rec->version = rec_version;
|
||||
rec->rec_len = rec_len;
|
||||
}
|
||||
|
||||
if ((ret = tls13_buffer_extend(rec->buf,
|
||||
TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls13_buffer_finish(rec->buf, &rec->data, &rec->data_len))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
return rec->data_len;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_record_send(struct tls13_record *rec, tls13_write_cb wire_write,
|
||||
void *wire_arg)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (rec->data == NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
while (CBS_len(&rec->cbs) > 0) {
|
||||
if ((ret = wire_write(CBS_data(&rec->cbs),
|
||||
CBS_len(&rec->cbs), wire_arg)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!CBS_skip(&rec->cbs, ret))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
return rec->data_len;
|
||||
}
|
||||
67
externals/libressl/ssl/tls13_record.h
vendored
Executable file
67
externals/libressl/ssl/tls13_record.h
vendored
Executable file
@@ -0,0 +1,67 @@
|
||||
/* $OpenBSD: tls13_record.h,v 1.3 2019/01/21 00:24:19 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TLS13_RECORD_H
|
||||
#define HEADER_TLS13_RECORD_H
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
/*
|
||||
* TLSv1.3 Record Protocol - RFC 8446 section 5.
|
||||
*
|
||||
* The maximum plaintext is 2^14, however for inner plaintext an additional
|
||||
* byte is allowed for the content type. A maximum AEAD overhead of 255-bytes
|
||||
* is permitted, along with a 5-byte header, giving a maximum size of
|
||||
* 5 + 2^14 + 1 + 255 = 16,645-bytes.
|
||||
*/
|
||||
#define TLS13_RECORD_HEADER_LEN 5
|
||||
#define TLS13_RECORD_MAX_AEAD_OVERHEAD 255
|
||||
#define TLS13_RECORD_MAX_PLAINTEXT_LEN 16384
|
||||
#define TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN \
|
||||
(TLS13_RECORD_MAX_PLAINTEXT_LEN + 1)
|
||||
#define TLS13_RECORD_MAX_CIPHERTEXT_LEN \
|
||||
(TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN + TLS13_RECORD_MAX_AEAD_OVERHEAD)
|
||||
#define TLS13_RECORD_MAX_LEN \
|
||||
(TLS13_RECORD_HEADER_LEN + TLS13_RECORD_MAX_CIPHERTEXT_LEN)
|
||||
|
||||
/*
|
||||
* TLSv1.3 Per-Record Nonces and Sequence Numbers - RFC 8446 section 5.3.
|
||||
*/
|
||||
#define TLS13_RECORD_SEQ_NUM_LEN 8
|
||||
|
||||
struct tls13_record;
|
||||
|
||||
struct tls13_record *tls13_record_new(void);
|
||||
void tls13_record_free(struct tls13_record *_rec);
|
||||
uint16_t tls13_record_version(struct tls13_record *_rec);
|
||||
uint8_t tls13_record_content_type(struct tls13_record *_rec);
|
||||
int tls13_record_header(struct tls13_record *_rec, CBS *_cbs);
|
||||
int tls13_record_content(struct tls13_record *_rec, CBS *_cbs);
|
||||
void tls13_record_data(struct tls13_record *_rec, CBS *_cbs);
|
||||
int tls13_record_set_data(struct tls13_record *_rec, uint8_t *_data,
|
||||
size_t _data_len);
|
||||
ssize_t tls13_record_recv(struct tls13_record *_rec, tls13_read_cb _wire_read,
|
||||
void *_wire_arg);
|
||||
ssize_t tls13_record_send(struct tls13_record *_rec, tls13_write_cb _wire_write,
|
||||
void *_wire_arg);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
1200
externals/libressl/ssl/tls13_record_layer.c
vendored
Executable file
1200
externals/libressl/ssl/tls13_record_layer.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1071
externals/libressl/ssl/tls13_server.c
vendored
Executable file
1071
externals/libressl/ssl/tls13_server.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user