First Commit
This commit is contained in:
103
externals/libressl/ssl/CMakeLists.txt
vendored
Normal file
103
externals/libressl/ssl/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
set(
|
||||
SSL_SRC
|
||||
bio_ssl.c
|
||||
d1_both.c
|
||||
d1_lib.c
|
||||
d1_pkt.c
|
||||
d1_srtp.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_seclevel.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
|
||||
tls_buffer.c
|
||||
tls_content.c
|
||||
tls_key_share.c
|
||||
tls_lib.c
|
||||
tls12_key_schedule.c
|
||||
tls12_lib.c
|
||||
tls12_record_layer.c
|
||||
tls13_client.c
|
||||
tls13_error.c
|
||||
tls13_handshake.c
|
||||
tls13_handshake_msg.c
|
||||
tls13_key_schedule.c
|
||||
tls13_legacy.c
|
||||
tls13_lib.c
|
||||
tls13_quic.c
|
||||
tls13_record.c
|
||||
tls13_record_layer.c
|
||||
tls13_server.c
|
||||
)
|
||||
|
||||
set(
|
||||
BS_SRC
|
||||
bs_ber.c
|
||||
bs_cbb.c
|
||||
bs_cbs.c
|
||||
)
|
||||
|
||||
add_library(ssl_obj OBJECT ${SSL_SRC})
|
||||
target_include_directories(ssl_obj
|
||||
PRIVATE
|
||||
.
|
||||
hidden
|
||||
../crypto/bio
|
||||
../include/compat
|
||||
PUBLIC
|
||||
../include
|
||||
${CMAKE_BINARY_DIR}/include)
|
||||
|
||||
add_library(bs_obj OBJECT ${BS_SRC})
|
||||
target_include_directories(bs_obj
|
||||
PRIVATE
|
||||
.
|
||||
../include/compat)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_library(ssl $<TARGET_OBJECTS:ssl_obj> $<TARGET_OBJECTS:bs_obj>)
|
||||
else()
|
||||
add_library(ssl $<TARGET_OBJECTS:ssl_obj> empty.c)
|
||||
endif()
|
||||
|
||||
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})
|
||||
|
||||
# build static library for regression test
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_library(ssl-static STATIC $<TARGET_OBJECTS:ssl_obj>)
|
||||
target_link_libraries(ssl-static crypto-static ${PLATFORM_LIBS})
|
||||
endif()
|
||||
|
||||
1
externals/libressl/ssl/VERSION
vendored
Normal file
1
externals/libressl/ssl/VERSION
vendored
Normal file
@@ -0,0 +1 @@
|
||||
54:0:0
|
||||
592
externals/libressl/ssl/bio_ssl.c
vendored
Normal file
592
externals/libressl/ssl/bio_ssl.c
vendored
Normal file
@@ -0,0 +1,592 @@
|
||||
/* $OpenBSD: bio_ssl.c,v 1.38 2023/02/16 08:38:17 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 "bio_local.h"
|
||||
#include "ssl_local.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);
|
||||
}
|
||||
LSSL_ALIAS(BIO_f_ssl);
|
||||
|
||||
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->handshake_func == ssl->method->ssl_connect)
|
||||
SSL_set_connect_state(ssl);
|
||||
else if (ssl->handshake_func == ssl->method->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);
|
||||
}
|
||||
LSSL_ALIAS(BIO_new_ssl_connect);
|
||||
|
||||
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);
|
||||
}
|
||||
LSSL_ALIAS(BIO_new_ssl);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
269
externals/libressl/ssl/bs_ber.c
vendored
Normal file
269
externals/libressl/ssl/bs_ber.c
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/* $OpenBSD: bs_ber.c,v 1.11 2021/05/16 10:58:27 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 "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);
|
||||
}
|
||||
483
externals/libressl/ssl/bs_cbb.c
vendored
Normal file
483
externals/libressl/ssl/bs_cbb.c
vendored
Normal file
@@ -0,0 +1,483 @@
|
||||
/* $OpenBSD: bs_cbb.c,v 1.28 2022/07/07 17:12:15 tb 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 "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 != NULL)
|
||||
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_u64(CBB *cbb, uint64_t value)
|
||||
{
|
||||
uint32_t a, b;
|
||||
|
||||
a = value >> 32;
|
||||
b = value & 0xffffffff;
|
||||
|
||||
if (!CBB_add_u32(cbb, a))
|
||||
return 0;
|
||||
return CBB_add_u32(cbb, b);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
615
externals/libressl/ssl/bs_cbs.c
vendored
Normal file
615
externals/libressl/ssl/bs_cbs.c
vendored
Normal file
@@ -0,0 +1,615 @@
|
||||
/* $OpenBSD: bs_cbs.c,v 1.24 2021/12/15 17:36:49 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 "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;
|
||||
}
|
||||
|
||||
static int
|
||||
cbs_peek(CBS *cbs, const uint8_t **p, size_t n)
|
||||
{
|
||||
if (cbs->len < n)
|
||||
return 0;
|
||||
|
||||
*p = cbs->data;
|
||||
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 = NULL;
|
||||
|
||||
if (CBS_contains_zero_byte(cbs))
|
||||
return 0;
|
||||
|
||||
*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_u64(CBS *cbs, uint64_t *out)
|
||||
{
|
||||
uint32_t a, b;
|
||||
|
||||
if (cbs->len < 8)
|
||||
return 0;
|
||||
|
||||
if (!CBS_get_u32(cbs, &a))
|
||||
return 0;
|
||||
if (!CBS_get_u32(cbs, &b))
|
||||
return 0;
|
||||
|
||||
*out = (uint64_t)a << 32 | b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_get_last_u8(CBS *cbs, uint8_t *out)
|
||||
{
|
||||
if (cbs->len == 0)
|
||||
return 0;
|
||||
|
||||
*out = cbs->data[cbs->len - 1];
|
||||
cbs->len--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static int
|
||||
cbs_peek_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_peek(cbs, &data, len))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
result <<= 8;
|
||||
result |= data[i];
|
||||
}
|
||||
*out = result;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_peek_u8(CBS *cbs, uint8_t *out)
|
||||
{
|
||||
const uint8_t *v;
|
||||
|
||||
if (!cbs_peek(cbs, &v, 1))
|
||||
return 0;
|
||||
|
||||
*out = *v;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_peek_u16(CBS *cbs, uint16_t *out)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
if (!cbs_peek_u(cbs, &v, 2))
|
||||
return 0;
|
||||
|
||||
*out = v;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
CBS_peek_u24(CBS *cbs, uint32_t *out)
|
||||
{
|
||||
return cbs_peek_u(cbs, out, 3);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_peek_u32(CBS *cbs, uint32_t *out)
|
||||
{
|
||||
return cbs_peek_u(cbs, out, 4);
|
||||
}
|
||||
|
||||
int
|
||||
CBS_peek_last_u8(CBS *cbs, uint8_t *out)
|
||||
{
|
||||
if (cbs->len == 0)
|
||||
return 0;
|
||||
|
||||
*out = cbs->data[cbs->len - 1];
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
564
externals/libressl/ssl/bytestring.h
vendored
Normal file
564
externals/libressl/ssl/bytestring.h
vendored
Normal file
@@ -0,0 +1,564 @@
|
||||
/* $OpenBSD: bytestring.h,v 1.24 2022/11/09 23:14:51 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>
|
||||
|
||||
__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 failure. On success,
|
||||
* |*out_ptr| should be freed with free. If |cbs| contains NUL bytes,
|
||||
* CBS_strdup will fail.
|
||||
*/
|
||||
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_u64 sets |*out| to the next, big-endian uint64_t value from |cbs|
|
||||
* and advances |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_u64(CBS *cbs, uint64_t *out);
|
||||
|
||||
/*
|
||||
* CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens
|
||||
* |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_get_last_u8(CBS *cbs, uint8_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);
|
||||
|
||||
/*
|
||||
* CBS_peek_u8 sets |*out| to the next uint8_t from |cbs|, but does not advance
|
||||
* |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_peek_u8(CBS *cbs, uint8_t *out);
|
||||
|
||||
/*
|
||||
* CBS_peek_u16 sets |*out| to the next, big-endian uint16_t from |cbs|, but
|
||||
* does not advance |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_peek_u16(CBS *cbs, uint16_t *out);
|
||||
|
||||
/*
|
||||
* CBS_peek_u24 sets |*out| to the next, big-endian 24-bit value from |cbs|, but
|
||||
* does not advance |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_peek_u24(CBS *cbs, uint32_t *out);
|
||||
|
||||
/*
|
||||
* CBS_peek_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|,
|
||||
* but does not advance |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_peek_u32(CBS *cbs, uint32_t *out);
|
||||
|
||||
/*
|
||||
* CBS_peek_last_u8 sets |*out| to the last uint8_t from |cbs|, but does not
|
||||
* shorten |cbs|. It returns one on success and zero on error.
|
||||
*/
|
||||
int CBS_peek_last_u8(CBS *cbs, uint8_t *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_u64 appends a 64-bit, big-endian number from |value| to |cbb|. It
|
||||
* returns one on success and zero otherwise.
|
||||
*/
|
||||
int CBB_add_u64(CBB *cbb, uint64_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 */
|
||||
1198
externals/libressl/ssl/d1_both.c
vendored
Normal file
1198
externals/libressl/ssl/d1_both.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
435
externals/libressl/ssl/d1_lib.c
vendored
Normal file
435
externals/libressl/ssl/d1_lib.c
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
/* $OpenBSD: d1_lib.c,v 1.64 2022/11/26 16:08:55 tb 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 "dtls_local.h"
|
||||
#include "pqueue.h"
|
||||
#include "ssl_local.h"
|
||||
|
||||
void dtls1_hm_fragment_free(hm_fragment *frag);
|
||||
|
||||
static int dtls1_listen(SSL *s, struct sockaddr *client);
|
||||
|
||||
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->unprocessed_rcds.q = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->buffered_messages = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->sent_messages = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
if ((s->d1->buffered_app_data.q = pqueue_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if (s->server)
|
||||
s->d1->cookie_len = sizeof(s->d1->cookie);
|
||||
|
||||
s->method->ssl_clear(s);
|
||||
return (1);
|
||||
|
||||
err:
|
||||
dtls1_free(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
dtls1_drain_rcontents(pqueue queue)
|
||||
{
|
||||
DTLS1_RCONTENT_DATA_INTERNAL *rdata;
|
||||
pitem *item;
|
||||
|
||||
if (queue == NULL)
|
||||
return;
|
||||
|
||||
while ((item = pqueue_pop(queue)) != NULL) {
|
||||
rdata = (DTLS1_RCONTENT_DATA_INTERNAL *)item->data;
|
||||
tls_content_free(rdata->rcontent);
|
||||
free(item->data);
|
||||
pitem_free(item);
|
||||
}
|
||||
}
|
||||
|
||||
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(s->d1->unprocessed_rcds.q);
|
||||
dtls1_drain_fragments(s->d1->buffered_messages);
|
||||
dtls1_drain_fragments(s->d1->sent_messages);
|
||||
dtls1_drain_rcontents(s->d1->buffered_app_data.q);
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_free(SSL *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
ssl3_free(s);
|
||||
|
||||
if (s->d1 == NULL)
|
||||
return;
|
||||
|
||||
dtls1_clear_queues(s);
|
||||
|
||||
pqueue_free(s->d1->unprocessed_rcds.q);
|
||||
pqueue_free(s->d1->buffered_messages);
|
||||
pqueue_free(s->d1->sent_messages);
|
||||
pqueue_free(s->d1->buffered_app_data.q);
|
||||
|
||||
freezero(s->d1, sizeof(*s->d1));
|
||||
s->d1 = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dtls1_clear(SSL *s)
|
||||
{
|
||||
pqueue unprocessed_rcds;
|
||||
pqueue buffered_messages;
|
||||
pqueue sent_messages;
|
||||
pqueue buffered_app_data;
|
||||
unsigned int mtu;
|
||||
|
||||
if (s->d1) {
|
||||
unprocessed_rcds = s->d1->unprocessed_rcds.q;
|
||||
buffered_messages = s->d1->buffered_messages;
|
||||
sent_messages = s->d1->sent_messages;
|
||||
buffered_app_data = s->d1->buffered_app_data.q;
|
||||
mtu = s->d1->mtu;
|
||||
|
||||
dtls1_clear_queues(s);
|
||||
|
||||
memset(s->d1, 0, sizeof(*s->d1));
|
||||
|
||||
s->d1->unprocessed_rcds.epoch =
|
||||
tls12_record_layer_read_epoch(s->rl) + 1;
|
||||
|
||||
if (s->server) {
|
||||
s->d1->cookie_len = sizeof(s->d1->cookie);
|
||||
}
|
||||
|
||||
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
|
||||
s->d1->mtu = mtu;
|
||||
}
|
||||
|
||||
s->d1->unprocessed_rcds.q = unprocessed_rcds;
|
||||
s->d1->buffered_messages = buffered_messages;
|
||||
s->d1->sent_messages = sent_messages;
|
||||
s->d1->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 *cipher;
|
||||
|
||||
if ((cipher = ssl3_get_cipher(u)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (cipher->algorithm_enc == SSL_RC4)
|
||||
return NULL;
|
||||
|
||||
return cipher;
|
||||
}
|
||||
|
||||
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(&(s->d1->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)
|
||||
{
|
||||
s->d1->timeout.num_alerts++;
|
||||
|
||||
/* Reduce MTU after 2 unsuccessful retransmissions */
|
||||
if (s->d1->timeout.num_alerts > 2) {
|
||||
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
|
||||
BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
|
||||
|
||||
}
|
||||
|
||||
if (s->d1->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;
|
||||
|
||||
s->d1->timeout.read_timeouts++;
|
||||
if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
|
||||
s->d1->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);
|
||||
s->d1->listen = 1;
|
||||
|
||||
ret = SSL_accept(s);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
|
||||
return 1;
|
||||
}
|
||||
1116
externals/libressl/ssl/d1_pkt.c
vendored
Normal file
1116
externals/libressl/ssl/d1_pkt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
262
externals/libressl/ssl/d1_srtp.c
vendored
Normal file
262
externals/libressl/ssl/d1_srtp.c
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
/* $OpenBSD: d1_srtp.c,v 1.32 2022/11/26 16:08:55 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 <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "dtls_local.h"
|
||||
#include "ssl_local.h"
|
||||
#include "srtp.h"
|
||||
|
||||
static const 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,
|
||||
},
|
||||
{
|
||||
"SRTP_AEAD_AES_128_GCM",
|
||||
SRTP_AEAD_AES_128_GCM,
|
||||
},
|
||||
{
|
||||
"SRTP_AEAD_AES_256_GCM",
|
||||
SRTP_AEAD_AES_256_GCM,
|
||||
},
|
||||
{0}
|
||||
};
|
||||
|
||||
int
|
||||
srtp_find_profile_by_name(const char *profile_name,
|
||||
const SRTP_PROTECTION_PROFILE **pptr, unsigned int len)
|
||||
{
|
||||
const 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,
|
||||
const SRTP_PROTECTION_PROFILE **pptr)
|
||||
{
|
||||
const 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;
|
||||
const char *ptr = profiles_string;
|
||||
const 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))) {
|
||||
if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) {
|
||||
sk_SRTP_PROTECTION_PROFILE_free(profiles);
|
||||
return 1;
|
||||
}
|
||||
} 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->srtp_profiles);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
|
||||
{
|
||||
return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
|
||||
}
|
||||
|
||||
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *
|
||||
SSL_get_srtp_profiles(SSL *s)
|
||||
{
|
||||
if (s != NULL) {
|
||||
if (s->srtp_profiles != NULL) {
|
||||
return s->srtp_profiles;
|
||||
} else if ((s->ctx != NULL) &&
|
||||
(s->ctx->srtp_profiles != NULL)) {
|
||||
return s->ctx->srtp_profiles;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SRTP_PROTECTION_PROFILE *
|
||||
SSL_get_selected_srtp_profile(SSL *s)
|
||||
{
|
||||
/* XXX cast away the const */
|
||||
return (SRTP_PROTECTION_PROFILE *)s->srtp_profile;
|
||||
}
|
||||
|
||||
#endif
|
||||
232
externals/libressl/ssl/dtls_local.h
vendored
Normal file
232
externals/libressl/ssl/dtls_local.h
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
/* $OpenBSD: dtls_local.h,v 1.2 2022/11/26 17:23:18 tb 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).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_DTLS_LOCL_H
|
||||
#define HEADER_DTLS_LOCL_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <openssl/dtls1.h>
|
||||
|
||||
#include "ssl_local.h"
|
||||
#include "tls_content.h"
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
typedef struct dtls1_bitmap_st {
|
||||
unsigned long map; /* track 32 packets on 32-bit systems
|
||||
and 64 - on 64-bit systems */
|
||||
unsigned char max_seq_num[8]; /* max record number seen so far,
|
||||
64-bit value in big-endian
|
||||
encoding */
|
||||
} DTLS1_BITMAP;
|
||||
|
||||
struct dtls1_retransmit_state {
|
||||
SSL_SESSION *session;
|
||||
unsigned short epoch;
|
||||
};
|
||||
|
||||
struct hm_header_st {
|
||||
unsigned char type;
|
||||
unsigned long msg_len;
|
||||
unsigned short seq;
|
||||
unsigned long frag_off;
|
||||
unsigned long frag_len;
|
||||
unsigned int is_ccs;
|
||||
struct dtls1_retransmit_state saved_retransmit_state;
|
||||
};
|
||||
|
||||
struct dtls1_timeout_st {
|
||||
/* Number of read timeouts so far */
|
||||
unsigned int read_timeouts;
|
||||
|
||||
/* Number of write timeouts so far */
|
||||
unsigned int write_timeouts;
|
||||
|
||||
/* Number of alerts received so far */
|
||||
unsigned int num_alerts;
|
||||
};
|
||||
|
||||
struct _pqueue;
|
||||
|
||||
typedef struct record_pqueue_st {
|
||||
unsigned short epoch;
|
||||
struct _pqueue *q;
|
||||
} record_pqueue;
|
||||
|
||||
typedef struct rcontent_pqueue_st {
|
||||
unsigned short epoch;
|
||||
struct _pqueue *q;
|
||||
} rcontent_pqueue;
|
||||
|
||||
typedef struct hm_fragment_st {
|
||||
struct hm_header_st msg_header;
|
||||
unsigned char *fragment;
|
||||
unsigned char *reassembly;
|
||||
} hm_fragment;
|
||||
|
||||
typedef struct dtls1_record_data_internal_st {
|
||||
unsigned char *packet;
|
||||
unsigned int packet_length;
|
||||
SSL3_BUFFER_INTERNAL rbuf;
|
||||
SSL3_RECORD_INTERNAL rrec;
|
||||
} DTLS1_RECORD_DATA_INTERNAL;
|
||||
|
||||
typedef struct dtls1_rcontent_data_internal_st {
|
||||
struct tls_content *rcontent;
|
||||
} DTLS1_RCONTENT_DATA_INTERNAL;
|
||||
|
||||
struct dtls1_state_st {
|
||||
/* Buffered (sent) handshake records */
|
||||
struct _pqueue *sent_messages;
|
||||
|
||||
/* Indicates when the last handshake msg or heartbeat sent will timeout */
|
||||
struct timeval next_timeout;
|
||||
|
||||
/* Timeout duration */
|
||||
unsigned short timeout_duration;
|
||||
|
||||
unsigned int send_cookie;
|
||||
unsigned char cookie[DTLS1_COOKIE_LENGTH];
|
||||
unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
|
||||
unsigned int cookie_len;
|
||||
|
||||
/* records being received in the current epoch */
|
||||
DTLS1_BITMAP bitmap;
|
||||
|
||||
/* renegotiation starts a new set of sequence numbers */
|
||||
DTLS1_BITMAP next_bitmap;
|
||||
|
||||
/* handshake message numbers */
|
||||
unsigned short handshake_write_seq;
|
||||
unsigned short next_handshake_write_seq;
|
||||
|
||||
unsigned short handshake_read_seq;
|
||||
|
||||
/* Received handshake records (unprocessed) */
|
||||
record_pqueue unprocessed_rcds;
|
||||
|
||||
/* Buffered handshake messages */
|
||||
struct _pqueue *buffered_messages;
|
||||
|
||||
/* Buffered application records.
|
||||
* Only for records between CCS and Finished
|
||||
* to prevent either protocol violation or
|
||||
* unnecessary message loss.
|
||||
*/
|
||||
rcontent_pqueue buffered_app_data;
|
||||
|
||||
/* Is set when listening for new connections with dtls1_listen() */
|
||||
unsigned int listen;
|
||||
|
||||
unsigned int mtu; /* max DTLS packet size */
|
||||
|
||||
struct hm_header_st w_msg_hdr;
|
||||
struct hm_header_st r_msg_hdr;
|
||||
|
||||
struct dtls1_timeout_st timeout;
|
||||
|
||||
unsigned int retransmitting;
|
||||
unsigned int change_cipher_spec_ok;
|
||||
};
|
||||
|
||||
int dtls1_do_write(SSL *s, int type);
|
||||
int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
|
||||
void dtls1_set_message_header(SSL *s, unsigned char mt, unsigned long len,
|
||||
unsigned long frag_off, unsigned long frag_len);
|
||||
void dtls1_set_message_header_int(SSL *s, unsigned char mt,
|
||||
unsigned long len, unsigned short seq_num, unsigned long frag_off,
|
||||
unsigned long frag_len);
|
||||
|
||||
int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
|
||||
unsigned int len);
|
||||
|
||||
int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
|
||||
int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
|
||||
|
||||
int dtls1_read_failed(SSL *s, int code);
|
||||
int dtls1_buffer_message(SSL *s, int ccs);
|
||||
int dtls1_retransmit_message(SSL *s, unsigned short seq,
|
||||
unsigned long frag_off, int *found);
|
||||
int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
|
||||
int dtls1_retransmit_buffered_messages(SSL *s);
|
||||
void dtls1_clear_record_buffer(SSL *s);
|
||||
int dtls1_get_message_header(CBS *header, struct hm_header_st *msg_hdr);
|
||||
void dtls1_reset_read_seq_numbers(SSL *s);
|
||||
struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
|
||||
int dtls1_check_timeout_num(SSL *s);
|
||||
int dtls1_handle_timeout(SSL *s);
|
||||
const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
|
||||
void dtls1_start_timer(SSL *s);
|
||||
void dtls1_stop_timer(SSL *s);
|
||||
int dtls1_is_timer_expired(SSL *s);
|
||||
void dtls1_double_timeout(SSL *s);
|
||||
unsigned int dtls1_min_mtu(void);
|
||||
|
||||
int dtls1_new(SSL *s);
|
||||
void dtls1_free(SSL *s);
|
||||
void dtls1_clear(SSL *s);
|
||||
long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg);
|
||||
|
||||
int dtls1_get_message(SSL *s, int st1, int stn, int mt, long max);
|
||||
int dtls1_get_record(SSL *s);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif /* !HEADER_DTLS_LOCL_H */
|
||||
0
externals/libressl/ssl/empty.c
vendored
Normal file
0
externals/libressl/ssl/empty.c
vendored
Normal file
35
externals/libressl/ssl/hidden/openssl/ssl.h
vendored
Normal file
35
externals/libressl/ssl/hidden/openssl/ssl.h
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/* $OpenBSD: ssl.h,v 1.1 2022/11/11 11:25:18 beck Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 Philip Guenther <guenther@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 _LIBSSL_SSL_H_
|
||||
#define _LIBSSL_SSL_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <../include/openssl/ssl.h>
|
||||
#else
|
||||
#include_next <openssl/ssl.h>
|
||||
#endif
|
||||
#include "ssl_namespace.h"
|
||||
|
||||
LSSL_USED(BIO_f_ssl);
|
||||
LSSL_USED(BIO_new_ssl);
|
||||
LSSL_USED(BIO_new_ssl_connect);
|
||||
LSSL_UNUSED(BIO_new_buffer_ssl_connect);
|
||||
LSSL_UNUSED(BIO_ssl_copy_session_id);
|
||||
LSSL_UNUSED(BIO_ssl_shutdown);
|
||||
|
||||
#endif /* _LIBSSL_SSL_H_ */
|
||||
43
externals/libressl/ssl/hidden/ssl_namespace.h
vendored
Normal file
43
externals/libressl/ssl/hidden/ssl_namespace.h
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/* $OpenBSD: ssl_namespace.h,v 1.2 2023/02/16 08:38:17 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Philip Guenther <guenther@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 _LIBSSL_SSL_NAMESPACE_H_
|
||||
#define _LIBSSL_SSL_NAMESPACE_H_
|
||||
|
||||
/*
|
||||
* If marked as 'used', then internal calls use the name with prefix "_lssl_"
|
||||
* and we alias that to the normal name.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define LSSL_UNUSED(x)
|
||||
#define LSSL_USED(x)
|
||||
#define LSSL_ALIAS(x)
|
||||
#else
|
||||
#ifdef LIBRESSL_NAMESPACE
|
||||
#define LSSL_UNUSED(x) typeof(x) x __attribute__((deprecated))
|
||||
#define LSSL_USED(x) __attribute__((visibility("hidden"))) \
|
||||
typeof(x) x asm("_lssl_"#x)
|
||||
#define LSSL_ALIAS(x) asm(".global "#x"; "#x" = _lssl_"#x)
|
||||
#else
|
||||
#define LSSL_UNUSED(x)
|
||||
#define LSSL_USED(x)
|
||||
#define LSSL_ALIAS(x) asm("")
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* _LIBSSL_SSL_NAMESPACE_H_ */
|
||||
201
externals/libressl/ssl/pqueue.c
vendored
Normal file
201
externals/libressl/ssl/pqueue.c
vendored
Normal 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;
|
||||
}
|
||||
628
externals/libressl/ssl/s3_cbc.c
vendored
Normal file
628
externals/libressl/ssl/s3_cbc.c
vendored
Normal file
@@ -0,0 +1,628 @@
|
||||
/* $OpenBSD: s3_cbc.c,v 1.26 2022/11/26 16:08:55 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 <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "ssl_local.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);
|
||||
}
|
||||
|
||||
/* ssl3_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
|
||||
ssl3_cbc_remove_padding(SSL3_RECORD_INTERNAL *rec, unsigned int eiv_len,
|
||||
unsigned int mac_size)
|
||||
{
|
||||
unsigned int padding_length, good, to_check, i;
|
||||
const unsigned int overhead = 1 /* padding length byte */ + mac_size;
|
||||
|
||||
/*
|
||||
* These lengths are all public so we can test them in
|
||||
* non-constant time.
|
||||
*/
|
||||
if (overhead + eiv_len > rec->length)
|
||||
return 0;
|
||||
|
||||
/* We can now safely skip explicit IV, if any. */
|
||||
rec->data += eiv_len;
|
||||
rec->input += eiv_len;
|
||||
rec->length -= eiv_len;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ((md_ctx = EVP_MD_CTX_new()) == NULL)
|
||||
return 0;
|
||||
if (!EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */)) {
|
||||
EVP_MD_CTX_free(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_free(md_ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
2812
externals/libressl/ssl/s3_lib.c
vendored
Normal file
2812
externals/libressl/ssl/s3_lib.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
146
externals/libressl/ssl/srtp.h
vendored
Normal file
146
externals/libressl/ssl/srtp.h
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/* $OpenBSD: srtp.h,v 1.7 2021/06/11 15:28:13 landry 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
|
||||
|
||||
/* AEAD SRTP protection profiles from RFC 7714 */
|
||||
#define SRTP_AEAD_AES_128_GCM 0x0007
|
||||
#define SRTP_AEAD_AES_256_GCM 0x0008
|
||||
|
||||
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
|
||||
364
externals/libressl/ssl/ssl.sym
vendored
Normal file
364
externals/libressl/ssl/ssl.sym
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
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_2_client_method
|
||||
DTLSv1_2_method
|
||||
DTLSv1_2_server_method
|
||||
DTLSv1_client_method
|
||||
DTLSv1_method
|
||||
DTLSv1_server_method
|
||||
ERR_load_SSL_strings
|
||||
OPENSSL_init_ssl
|
||||
PEM_read_SSL_SESSION
|
||||
PEM_read_bio_SSL_SESSION
|
||||
PEM_write_SSL_SESSION
|
||||
PEM_write_bio_SSL_SESSION
|
||||
SSL_CIPHER_description
|
||||
SSL_CIPHER_find
|
||||
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_get0_privatekey
|
||||
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_keylog_callback
|
||||
SSL_CTX_get_max_early_data
|
||||
SSL_CTX_get_max_proto_version
|
||||
SSL_CTX_get_min_proto_version
|
||||
SSL_CTX_get_num_tickets
|
||||
SSL_CTX_get_quiet_shutdown
|
||||
SSL_CTX_get_security_level
|
||||
SSL_CTX_get_ssl_method
|
||||
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_ciphersuites
|
||||
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_keylog_callback
|
||||
SSL_CTX_set_max_early_data
|
||||
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_num_tickets
|
||||
SSL_CTX_set_post_handshake_auth
|
||||
SSL_CTX_set_purpose
|
||||
SSL_CTX_set_quic_method
|
||||
SSL_CTX_set_quiet_shutdown
|
||||
SSL_CTX_set_security_level
|
||||
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_cipher
|
||||
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_max_early_data
|
||||
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_is_resumable
|
||||
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_max_early_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_get0_peername
|
||||
SSL_get0_verified_chain
|
||||
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_early_data_status
|
||||
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_early_data
|
||||
SSL_get_max_proto_version
|
||||
SSL_get_min_proto_version
|
||||
SSL_get_num_tickets
|
||||
SSL_get_peer_cert_chain
|
||||
SSL_get_peer_certificate
|
||||
SSL_get_peer_finished
|
||||
SSL_get_peer_quic_transport_params
|
||||
SSL_get_privatekey
|
||||
SSL_get_quiet_shutdown
|
||||
SSL_get_rbio
|
||||
SSL_get_read_ahead
|
||||
SSL_get_rfd
|
||||
SSL_get_security_level
|
||||
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_dtls
|
||||
SSL_is_quic
|
||||
SSL_is_server
|
||||
SSL_library_init
|
||||
SSL_load_client_CA_file
|
||||
SSL_load_error_strings
|
||||
SSL_new
|
||||
SSL_peek
|
||||
SSL_peek_ex
|
||||
SSL_pending
|
||||
SSL_process_quic_post_handshake
|
||||
SSL_provide_quic_data
|
||||
SSL_quic_max_handshake_flight_len
|
||||
SSL_quic_read_level
|
||||
SSL_quic_write_level
|
||||
SSL_read
|
||||
SSL_read_early_data
|
||||
SSL_read_ex
|
||||
SSL_renegotiate
|
||||
SSL_renegotiate_abbreviated
|
||||
SSL_renegotiate_pending
|
||||
SSL_rstate_string
|
||||
SSL_rstate_string_long
|
||||
SSL_select_next_proto
|
||||
SSL_set0_chain
|
||||
SSL_set0_rbio
|
||||
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_ciphersuites
|
||||
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_hostflags
|
||||
SSL_set_info_callback
|
||||
SSL_set_max_early_data
|
||||
SSL_set_max_proto_version
|
||||
SSL_set_min_proto_version
|
||||
SSL_set_msg_callback
|
||||
SSL_set_num_tickets
|
||||
SSL_set_post_handshake_auth
|
||||
SSL_set_psk_use_session_callback
|
||||
SSL_set_purpose
|
||||
SSL_set_quic_method
|
||||
SSL_set_quic_transport_params
|
||||
SSL_set_quic_use_legacy_codepoint
|
||||
SSL_set_quiet_shutdown
|
||||
SSL_set_read_ahead
|
||||
SSL_set_rfd
|
||||
SSL_set_security_level
|
||||
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_chain_file
|
||||
SSL_use_certificate_file
|
||||
SSL_verify_client_post_handshake
|
||||
SSL_version
|
||||
SSL_version_str
|
||||
SSL_want
|
||||
SSL_write
|
||||
SSL_write_early_data
|
||||
SSL_write_ex
|
||||
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
|
||||
d2i_SSL_SESSION
|
||||
i2d_SSL_SESSION
|
||||
125
externals/libressl/ssl/ssl_algs.c
vendored
Normal file
125
externals/libressl/ssl/ssl_algs.c
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/* $OpenBSD: ssl_algs.c,v 1.31 2022/11/26 16:08:55 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 <stdio.h>
|
||||
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include "ssl_local.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());
|
||||
#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);
|
||||
}
|
||||
|
||||
418
externals/libressl/ssl/ssl_asn1.c
vendored
Normal file
418
externals/libressl/ssl/ssl_asn1.c
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
/* $OpenBSD: ssl_asn1.c,v 1.66 2022/11/26 16:08:55 tb 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 "bytestring.h"
|
||||
#include "ssl_local.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 & SSL3_CK_VALUE_MASK);
|
||||
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_cert != NULL) {
|
||||
if ((len = i2d_X509(s->peer_cert, &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),
|
||||
&s->session_id_length))
|
||||
goto err;
|
||||
|
||||
/* 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),
|
||||
&s->master_key_length))
|
||||
goto err;
|
||||
|
||||
/* 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_cert);
|
||||
s->peer_cert = 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_cert, &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), &s->sid_ctx_length))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
|
||||
SSLASN1_LIFETIME_TAG, 0))
|
||||
goto err;
|
||||
if (lifetime > UINT32_MAX)
|
||||
goto err;
|
||||
if (lifetime > 0)
|
||||
s->tlsext_tick_lifetime_hint = (uint32_t)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);
|
||||
}
|
||||
579
externals/libressl/ssl/ssl_both.c
vendored
Normal file
579
externals/libressl/ssl/ssl_both.c
vendored
Normal file
@@ -0,0 +1,579 @@
|
||||
/* $OpenBSD: ssl_both.c,v 1.45 2022/11/26 16:08:55 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-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 <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "dtls_local.h"
|
||||
#include "ssl_local.h"
|
||||
|
||||
/*
|
||||
* Send s->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->init_buf->data[s->init_off],
|
||||
s->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->init_buf->data[s->init_off], ret);
|
||||
|
||||
if (ret == s->init_num) {
|
||||
ssl_msg_callback(s, 1, type, s->init_buf->data,
|
||||
(size_t)(s->init_off + s->init_num));
|
||||
return (1);
|
||||
}
|
||||
|
||||
s->init_off += ret;
|
||||
s->init_num -= ret;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
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, SSL_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->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_PARAM_set_flags(X509_STORE_CTX_get0_param(xs_ctx),
|
||||
X509_V_FLAG_LEGACY_VERIFY);
|
||||
X509_verify_cert(xs_ctx);
|
||||
ERR_clear_error();
|
||||
chain = X509_STORE_CTX_get0_chain(xs_ctx);
|
||||
}
|
||||
|
||||
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'.
|
||||
*/
|
||||
int
|
||||
ssl3_get_message(SSL *s, int st1, int stn, int mt, long max)
|
||||
{
|
||||
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);
|
||||
|
||||
if (s->s3->hs.tls12.reuse_message) {
|
||||
s->s3->hs.tls12.reuse_message = 0;
|
||||
if ((mt >= 0) && (s->s3->hs.tls12.message_type != mt)) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
|
||||
goto fatal_err;
|
||||
}
|
||||
s->init_msg = s->init_buf->data +
|
||||
SSL3_HM_HEADER_LENGTH;
|
||||
s->init_num = (int)s->s3->hs.tls12.message_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = (unsigned char *)s->init_buf->data;
|
||||
|
||||
if (s->s3->hs.state == st1) {
|
||||
int skip_message;
|
||||
|
||||
do {
|
||||
while (s->init_num < SSL3_HM_HEADER_LENGTH) {
|
||||
i = s->method->ssl_read_bytes(s,
|
||||
SSL3_RT_HANDSHAKE, &p[s->init_num],
|
||||
SSL3_HM_HEADER_LENGTH - s->init_num, 0);
|
||||
if (i <= 0) {
|
||||
s->rwstate = SSL_READING;
|
||||
return i;
|
||||
}
|
||||
s->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->init_num = 0;
|
||||
skip_message = 1;
|
||||
|
||||
ssl_msg_callback(s, 0,
|
||||
SSL3_RT_HANDSHAKE, p,
|
||||
SSL3_HM_HEADER_LENGTH);
|
||||
}
|
||||
}
|
||||
} while (skip_message);
|
||||
|
||||
if ((mt >= 0) && (*p != mt)) {
|
||||
al = SSL_AD_UNEXPECTED_MESSAGE;
|
||||
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
|
||||
goto fatal_err;
|
||||
}
|
||||
|
||||
CBS_init(&cbs, p, SSL3_HM_HEADER_LENGTH);
|
||||
if (!CBS_get_u8(&cbs, &u8) ||
|
||||
!CBS_get_u24(&cbs, &l)) {
|
||||
SSLerror(s, ERR_R_BUF_LIB);
|
||||
goto err;
|
||||
}
|
||||
s->s3->hs.tls12.message_type = u8;
|
||||
|
||||
if (l > (unsigned long)max) {
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
|
||||
goto fatal_err;
|
||||
}
|
||||
if (l && !BUF_MEM_grow_clean(s->init_buf,
|
||||
l + SSL3_HM_HEADER_LENGTH)) {
|
||||
SSLerror(s, ERR_R_BUF_LIB);
|
||||
goto err;
|
||||
}
|
||||
s->s3->hs.tls12.message_size = l;
|
||||
s->s3->hs.state = stn;
|
||||
|
||||
s->init_msg = s->init_buf->data +
|
||||
SSL3_HM_HEADER_LENGTH;
|
||||
s->init_num = 0;
|
||||
}
|
||||
|
||||
/* next state (stn) */
|
||||
p = s->init_msg;
|
||||
n = s->s3->hs.tls12.message_size - s->init_num;
|
||||
while (n > 0) {
|
||||
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
|
||||
&p[s->init_num], n, 0);
|
||||
if (i <= 0) {
|
||||
s->rwstate = SSL_READING;
|
||||
return i;
|
||||
}
|
||||
s->init_num += i;
|
||||
n -= i;
|
||||
}
|
||||
|
||||
/* Feed this message into MAC computation. */
|
||||
if (s->mac_packet) {
|
||||
tls1_transcript_record(s, (unsigned char *)s->init_buf->data,
|
||||
s->init_num + SSL3_HM_HEADER_LENGTH);
|
||||
|
||||
ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE,
|
||||
s->init_buf->data,
|
||||
(size_t)s->init_num + SSL3_HM_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
fatal_err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_type(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey == NULL)
|
||||
return -1;
|
||||
|
||||
switch (EVP_PKEY_id(pkey)) {
|
||||
case EVP_PKEY_EC:
|
||||
return SSL_PKEY_ECC;
|
||||
case NID_id_GostR3410_2001:
|
||||
case NID_id_GostR3410_2001_cc:
|
||||
return SSL_PKEY_GOST01;
|
||||
case EVP_PKEY_RSA:
|
||||
return SSL_PKEY_RSA;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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->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->init_buf = buf;
|
||||
return (1);
|
||||
|
||||
err:
|
||||
BUF_MEM_free(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_release_init_buffer(SSL *s)
|
||||
{
|
||||
BUF_MEM_free(s->init_buf);
|
||||
s->init_buf = NULL;
|
||||
s->init_msg = NULL;
|
||||
s->init_num = 0;
|
||||
s->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 (s->s3->rbuf.buf == NULL) {
|
||||
len = SSL3_RT_MAX_PLAIN_LENGTH +
|
||||
SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
if ((p = calloc(1, len)) == NULL)
|
||||
goto err;
|
||||
s->s3->rbuf.buf = p;
|
||||
s->s3->rbuf.len = len;
|
||||
}
|
||||
|
||||
s->packet = s->s3->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 (s->s3->wbuf.buf == NULL) {
|
||||
len = s->max_send_fragment +
|
||||
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
|
||||
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
|
||||
len += headerlen + align +
|
||||
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
|
||||
|
||||
if ((p = calloc(1, len)) == NULL)
|
||||
goto err;
|
||||
s->s3->wbuf.buf = p;
|
||||
s->s3->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(&s->s3->rbuf);
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_release_write_buffer(SSL *s)
|
||||
{
|
||||
ssl3_release_buffer(&s->s3->wbuf);
|
||||
}
|
||||
730
externals/libressl/ssl/ssl_cert.c
vendored
Normal file
730
externals/libressl/ssl/ssl_cert.c
vendored
Normal file
@@ -0,0 +1,730 @@
|
||||
/* $OpenBSD: ssl_cert.c,v 1.105 2022/11/26 16:08:55 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-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_local.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;
|
||||
}
|
||||
|
||||
SSL_CERT *
|
||||
ssl_cert_new(void)
|
||||
{
|
||||
SSL_CERT *ret;
|
||||
|
||||
ret = calloc(1, sizeof(SSL_CERT));
|
||||
if (ret == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
ret->key = &(ret->pkeys[SSL_PKEY_RSA]);
|
||||
ret->references = 1;
|
||||
ret->security_cb = ssl_security_default_cb;
|
||||
ret->security_level = OPENSSL_TLS_SECURITY_LEVEL;
|
||||
ret->security_ex_data = NULL;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
SSL_CERT *
|
||||
ssl_cert_dup(SSL_CERT *cert)
|
||||
{
|
||||
SSL_CERT *ret;
|
||||
int i;
|
||||
|
||||
ret = calloc(1, sizeof(SSL_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->dhe_params != NULL) {
|
||||
ret->dhe_params = DHparams_dup(cert->dhe_params);
|
||||
if (ret->dhe_params == NULL) {
|
||||
SSLerrorx(ERR_R_DH_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ret->dhe_params_cb = cert->dhe_params_cb;
|
||||
ret->dhe_params_auto = cert->dhe_params_auto;
|
||||
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++) {
|
||||
if (cert->pkeys[i].x509 != NULL) {
|
||||
ret->pkeys[i].x509 = cert->pkeys[i].x509;
|
||||
X509_up_ref(ret->pkeys[i].x509);
|
||||
}
|
||||
|
||||
if (cert->pkeys[i].privatekey != NULL) {
|
||||
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
|
||||
EVP_PKEY_up_ref(ret->pkeys[i].privatekey);
|
||||
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->security_cb = cert->security_cb;
|
||||
ret->security_level = cert->security_level;
|
||||
ret->security_ex_data = cert->security_ex_data;
|
||||
|
||||
/*
|
||||
* 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->dhe_params);
|
||||
|
||||
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(SSL_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->dhe_params);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
SSL_CERT *
|
||||
ssl_get0_cert(SSL_CTX *ctx, SSL *ssl)
|
||||
{
|
||||
if (ssl != NULL)
|
||||
return ssl->cert;
|
||||
|
||||
return ctx->cert;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_set0_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain)
|
||||
{
|
||||
SSL_CERT *ssl_cert;
|
||||
SSL_CERT_PKEY *cpk;
|
||||
X509 *x509;
|
||||
int ssl_err;
|
||||
int i;
|
||||
|
||||
if ((ssl_cert = ssl_get0_cert(ctx, ssl)) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((cpk = ssl_cert->key) == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < sk_X509_num(chain); i++) {
|
||||
x509 = sk_X509_value(chain, i);
|
||||
if (!ssl_security_cert(ctx, ssl, x509, 0, &ssl_err)) {
|
||||
SSLerrorx(ssl_err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sk_X509_pop_free(cpk->chain, X509_free);
|
||||
cpk->chain = chain;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_set1_chain(SSL_CTX *ctx, SSL *ssl, 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(ctx, ssl, new_chain)) {
|
||||
sk_X509_pop_free(new_chain, X509_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_add0_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert)
|
||||
{
|
||||
SSL_CERT *ssl_cert;
|
||||
SSL_CERT_PKEY *cpk;
|
||||
int ssl_err;
|
||||
|
||||
if ((ssl_cert = ssl_get0_cert(ctx, ssl)) == NULL)
|
||||
return 0;
|
||||
|
||||
if ((cpk = ssl_cert->key) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ssl_security_cert(ctx, ssl, cert, 0, &ssl_err)) {
|
||||
SSLerrorx(ssl_err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cpk->chain == NULL) {
|
||||
if ((cpk->chain = sk_X509_new_null()) == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_X509_push(cpk->chain, cert))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_add1_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert)
|
||||
{
|
||||
if (!ssl_cert_add0_chain_cert(ctx, ssl, cert))
|
||||
return 0;
|
||||
|
||||
X509_up_ref(cert);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *certs)
|
||||
{
|
||||
X509_STORE_CTX *ctx = NULL;
|
||||
X509_VERIFY_PARAM *param;
|
||||
X509 *cert;
|
||||
int ret = 0;
|
||||
|
||||
if (sk_X509_num(certs) < 1)
|
||||
goto err;
|
||||
|
||||
if ((ctx = X509_STORE_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
cert = sk_X509_value(certs, 0);
|
||||
if (!X509_STORE_CTX_init(ctx, s->ctx->cert_store, cert, certs)) {
|
||||
SSLerror(s, ERR_R_X509_LIB);
|
||||
goto err;
|
||||
}
|
||||
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");
|
||||
|
||||
param = X509_STORE_CTX_get0_param(ctx);
|
||||
|
||||
X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s));
|
||||
|
||||
/*
|
||||
* Anything non-default in "param" should overwrite anything
|
||||
* in the ctx.
|
||||
*/
|
||||
X509_VERIFY_PARAM_set1(param, s->param);
|
||||
|
||||
if (s->verify_callback)
|
||||
X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback);
|
||||
|
||||
if (s->ctx->app_verify_callback != NULL)
|
||||
ret = s->ctx->app_verify_callback(ctx,
|
||||
s->ctx->app_verify_arg);
|
||||
else
|
||||
ret = X509_verify_cert(ctx);
|
||||
|
||||
s->verify_result = X509_STORE_CTX_get_error(ctx);
|
||||
sk_X509_pop_free(s->verified_chain, X509_free);
|
||||
s->verified_chain = NULL;
|
||||
if (X509_STORE_CTX_get0_chain(ctx) != NULL) {
|
||||
s->verified_chain = X509_STORE_CTX_get1_chain(ctx);
|
||||
if (s->verified_chain == NULL) {
|
||||
SSLerrorx(ERR_R_MALLOC_FAILURE);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
X509_STORE_CTX_free(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->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->client_CA), name_list);
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *
|
||||
SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
|
||||
{
|
||||
return (ctx->client_CA);
|
||||
}
|
||||
|
||||
STACK_OF(X509_NAME) *
|
||||
SSL_get_client_CA_list(const SSL *s)
|
||||
{
|
||||
if (!s->server) {
|
||||
/* We are in the client. */
|
||||
if ((s->version >> 8) == SSL3_VERSION_MAJOR)
|
||||
return (s->s3->hs.tls12.ca_names);
|
||||
else
|
||||
return (NULL);
|
||||
} else {
|
||||
if (s->client_CA != NULL)
|
||||
return (s->client_CA);
|
||||
else
|
||||
return (s->ctx->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->client_CA), x));
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
return (add_client_CA(&(ctx->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());
|
||||
|
||||
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 {
|
||||
if (!sk_X509_NAME_push(sk, xn))
|
||||
goto err;
|
||||
if (!sk_X509_NAME_push(ret, xn))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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
|
||||
if (!sk_X509_NAME_push(stack, xn))
|
||||
goto err;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
1743
externals/libressl/ssl/ssl_ciph.c
vendored
Normal file
1743
externals/libressl/ssl/ssl_ciph.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
286
externals/libressl/ssl/ssl_ciphers.c
vendored
Normal file
286
externals/libressl/ssl/ssl_ciphers.c
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
/* $OpenBSD: ssl_ciphers.c,v 1.17 2022/11/26 16:08:55 tb 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_local.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_tls_version_range(const SSL_CIPHER *cipher, uint16_t min_ver,
|
||||
uint16_t max_ver)
|
||||
{
|
||||
switch(cipher->algorithm_ssl) {
|
||||
case SSL_SSLV3:
|
||||
return (min_ver <= TLS1_2_VERSION);
|
||||
case SSL_TLSV1_2:
|
||||
return (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver);
|
||||
case SSL_TLSV1_3:
|
||||
return (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver);
|
||||
}
|
||||
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_tls_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_tls_version_range(cipher, min_vers,
|
||||
max_vers))
|
||||
continue;
|
||||
if (!ssl_security_cipher_check(s, cipher))
|
||||
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->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;
|
||||
unsigned long cipher_id;
|
||||
|
||||
s->s3->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->renegotiate) {
|
||||
SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL,
|
||||
SSL_AD_HANDSHAKE_FAILURE);
|
||||
|
||||
goto err;
|
||||
}
|
||||
s->s3->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 (s->s3->hs.negotiated_tls_version <
|
||||
s->s3->hs.our_max_tls_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_RFC_AES_128_GCM_SHA256,
|
||||
.alias = TLS1_3_TXT_AES_128_GCM_SHA256,
|
||||
.cid = TLS1_3_CK_AES_128_GCM_SHA256,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_RFC_AES_256_GCM_SHA384,
|
||||
.alias = TLS1_3_TXT_AES_256_GCM_SHA384,
|
||||
.cid = TLS1_3_CK_AES_256_GCM_SHA384,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
|
||||
.alias = TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
|
||||
.cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_RFC_AES_128_CCM_SHA256,
|
||||
.alias = TLS1_3_TXT_AES_128_CCM_SHA256,
|
||||
.cid = TLS1_3_CK_AES_128_CCM_SHA256,
|
||||
},
|
||||
{
|
||||
.name = TLS1_3_RFC_AES_128_CCM_8_SHA256,
|
||||
.alias = TLS1_3_TXT_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;
|
||||
}
|
||||
2674
externals/libressl/ssl/ssl_clnt.c
vendored
Normal file
2674
externals/libressl/ssl/ssl_clnt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
671
externals/libressl/ssl/ssl_err.c
vendored
Normal file
671
externals/libressl/ssl/ssl_err.c
vendored
Normal file
@@ -0,0 +1,671 @@
|
||||
/* $OpenBSD: ssl_err.c,v 1.45 2022/11/26 16:08:55 tb 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).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "ssl_local.h"
|
||||
|
||||
#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_CA_KEY_TOO_SMALL) , "ca key too small"},
|
||||
{ERR_REASON(SSL_R_CA_MD_TOO_WEAK) , "ca md too weak"},
|
||||
{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_KEY_TOO_SMALL) , "dh key too small"},
|
||||
{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_EE_KEY_TOO_SMALL) , "ee key too small"},
|
||||
{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_APPLICATION_PROTOCOL), "no application protocol"},
|
||||
{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_BEHAVING_BADLY) , "peer is doing strange or hostile things"},
|
||||
{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_QUIC_INTERNAL_ERROR) , "QUIC: internal error"},
|
||||
{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), "unknown failure occurred"},
|
||||
{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_VERSION_TOO_LOW) , "version too low"},
|
||||
{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_ENCRYPTION_LEVEL_RECEIVED), "QUIC: wrong encryption level received"},
|
||||
{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"},
|
||||
{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(s->s3->hs.state)), r, f, l);
|
||||
}
|
||||
51
externals/libressl/ssl/ssl_init.c
vendored
Normal file
51
externals/libressl/ssl/ssl_init.c
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/* $OpenBSD: ssl_init.c,v 1.3 2022/11/26 16:08:55 tb 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_local.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;
|
||||
}
|
||||
423
externals/libressl/ssl/ssl_kex.c
vendored
Normal file
423
externals/libressl/ssl/ssl_kex.c
vendored
Normal file
@@ -0,0 +1,423 @@
|
||||
/* $OpenBSD: ssl_kex.c,v 1.10 2022/01/14 09:11:22 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2020, 2021 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/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
#define DHE_MINIMUM_BITS 1024
|
||||
|
||||
int
|
||||
ssl_kex_generate_dhe(DH *dh, DH *dh_params)
|
||||
{
|
||||
BIGNUM *p = NULL, *g = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if ((p = BN_dup(DH_get0_p(dh_params))) == NULL)
|
||||
goto err;
|
||||
if ((g = BN_dup(DH_get0_g(dh_params))) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!DH_set0_pqg(dh, p, NULL, g))
|
||||
goto err;
|
||||
p = NULL;
|
||||
g = NULL;
|
||||
|
||||
if (!DH_generate_key(dh))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_generate_dhe_params_auto(DH *dh, size_t key_bits)
|
||||
{
|
||||
BIGNUM *p = NULL, *g = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (key_bits >= 8192)
|
||||
p = get_rfc3526_prime_8192(NULL);
|
||||
else if (key_bits >= 4096)
|
||||
p = get_rfc3526_prime_4096(NULL);
|
||||
else if (key_bits >= 3072)
|
||||
p = get_rfc3526_prime_3072(NULL);
|
||||
else if (key_bits >= 2048)
|
||||
p = get_rfc3526_prime_2048(NULL);
|
||||
else if (key_bits >= 1536)
|
||||
p = get_rfc3526_prime_1536(NULL);
|
||||
else
|
||||
p = get_rfc2409_prime_1024(NULL);
|
||||
|
||||
if (p == NULL)
|
||||
goto err;
|
||||
|
||||
if ((g = BN_new()) == NULL)
|
||||
goto err;
|
||||
if (!BN_set_word(g, 2))
|
||||
goto err;
|
||||
|
||||
if (!DH_set0_pqg(dh, p, NULL, g))
|
||||
goto err;
|
||||
p = NULL;
|
||||
g = NULL;
|
||||
|
||||
if (!DH_generate_key(dh))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_params_dhe(DH *dh, CBB *cbb)
|
||||
{
|
||||
int dh_p_len, dh_g_len;
|
||||
CBB dh_p, dh_g;
|
||||
uint8_t *data;
|
||||
|
||||
if ((dh_p_len = BN_num_bytes(DH_get0_p(dh))) <= 0)
|
||||
return 0;
|
||||
if ((dh_g_len = BN_num_bytes(DH_get0_g(dh))) <= 0)
|
||||
return 0;
|
||||
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &dh_p))
|
||||
return 0;
|
||||
if (!CBB_add_space(&dh_p, &data, dh_p_len))
|
||||
return 0;
|
||||
if (BN_bn2bin(DH_get0_p(dh), data) != dh_p_len)
|
||||
return 0;
|
||||
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &dh_g))
|
||||
return 0;
|
||||
if (!CBB_add_space(&dh_g, &data, dh_g_len))
|
||||
return 0;
|
||||
if (BN_bn2bin(DH_get0_g(dh), data) != dh_g_len)
|
||||
return 0;
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_public_dhe(DH *dh, CBB *cbb)
|
||||
{
|
||||
uint8_t *data;
|
||||
int dh_y_len;
|
||||
CBB dh_y;
|
||||
|
||||
if ((dh_y_len = BN_num_bytes(DH_get0_pub_key(dh))) <= 0)
|
||||
return 0;
|
||||
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &dh_y))
|
||||
return 0;
|
||||
if (!CBB_add_space(&dh_y, &data, dh_y_len))
|
||||
return 0;
|
||||
if (BN_bn2bin(DH_get0_pub_key(dh), data) != dh_y_len)
|
||||
return 0;
|
||||
|
||||
if (!CBB_flush(cbb))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_peer_params_dhe(DH *dh, CBS *cbs, int *decode_error,
|
||||
int *invalid_params)
|
||||
{
|
||||
BIGNUM *p = NULL, *g = NULL;
|
||||
CBS dh_p, dh_g;
|
||||
int ret = 0;
|
||||
|
||||
*decode_error = 0;
|
||||
*invalid_params = 0;
|
||||
|
||||
if (!CBS_get_u16_length_prefixed(cbs, &dh_p)) {
|
||||
*decode_error = 1;
|
||||
goto err;
|
||||
}
|
||||
if (!CBS_get_u16_length_prefixed(cbs, &dh_g)) {
|
||||
*decode_error = 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((p = BN_bin2bn(CBS_data(&dh_p), CBS_len(&dh_p), NULL)) == NULL)
|
||||
goto err;
|
||||
if ((g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!DH_set0_pqg(dh, p, NULL, g))
|
||||
goto err;
|
||||
p = NULL;
|
||||
g = NULL;
|
||||
|
||||
/* XXX - consider calling DH_check(). */
|
||||
|
||||
if (DH_bits(dh) < DHE_MINIMUM_BITS)
|
||||
*invalid_params = 1;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_peer_public_dhe(DH *dh, CBS *cbs, int *decode_error,
|
||||
int *invalid_key)
|
||||
{
|
||||
BIGNUM *pub_key = NULL;
|
||||
int check_flags;
|
||||
CBS dh_y;
|
||||
int ret = 0;
|
||||
|
||||
*decode_error = 0;
|
||||
*invalid_key = 0;
|
||||
|
||||
if (!CBS_get_u16_length_prefixed(cbs, &dh_y)) {
|
||||
*decode_error = 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((pub_key = BN_bin2bn(CBS_data(&dh_y), CBS_len(&dh_y),
|
||||
NULL)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!DH_set0_key(dh, pub_key, NULL))
|
||||
goto err;
|
||||
pub_key = NULL;
|
||||
|
||||
if (!DH_check_pub_key(dh, DH_get0_pub_key(dh), &check_flags))
|
||||
goto err;
|
||||
if (check_flags != 0)
|
||||
*invalid_key = 1;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_free(pub_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_kex_derive_dhe(DH *dh, DH *dh_peer,
|
||||
uint8_t **shared_key, size_t *shared_key_len)
|
||||
{
|
||||
uint8_t *key = NULL;
|
||||
int key_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
if ((key_len = DH_size(dh)) <= 0)
|
||||
goto err;
|
||||
if ((key = calloc(1, key_len)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((key_len = DH_compute_key(key, DH_get0_pub_key(dh_peer), dh)) <= 0)
|
||||
goto err;
|
||||
|
||||
*shared_key = key;
|
||||
*shared_key_len = key_len;
|
||||
key = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(key, key_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 *key = NULL;
|
||||
int key_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 ((key_len = ECDH_size(ecdh)) <= 0)
|
||||
goto err;
|
||||
if ((key = calloc(1, key_len)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (ECDH_compute_key(key, key_len, point, ecdh, NULL) <= 0)
|
||||
goto err;
|
||||
|
||||
*shared_key = key;
|
||||
*shared_key_len = key_len;
|
||||
key = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(key, key_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
3497
externals/libressl/ssl/ssl_lib.c
vendored
Normal file
3497
externals/libressl/ssl/ssl_lib.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1541
externals/libressl/ssl/ssl_local.h
vendored
Normal file
1541
externals/libressl/ssl/ssl_local.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
580
externals/libressl/ssl/ssl_methods.c
vendored
Normal file
580
externals/libressl/ssl/ssl_methods.c
vendored
Normal file
@@ -0,0 +1,580 @@
|
||||
/* $OpenBSD: ssl_methods.c,v 1.29 2022/11/26 16:08:56 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 "dtls_local.h"
|
||||
#include "ssl_local.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
static const SSL_METHOD DTLS_method_data = {
|
||||
.dtls = 1,
|
||||
.server = 1,
|
||||
.version = DTLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_1_VERSION,
|
||||
.max_tls_version = TLS1_2_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,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLS_client_method_data = {
|
||||
.dtls = 1,
|
||||
.server = 0,
|
||||
.version = DTLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_1_VERSION,
|
||||
.max_tls_version = TLS1_2_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,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_method_data = {
|
||||
.dtls = 1,
|
||||
.server = 1,
|
||||
.version = DTLS1_VERSION,
|
||||
.min_tls_version = TLS1_1_VERSION,
|
||||
.max_tls_version = TLS1_1_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,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.enc_flags = TLSV1_1_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_client_method_data = {
|
||||
.dtls = 1,
|
||||
.server = 0,
|
||||
.version = DTLS1_VERSION,
|
||||
.min_tls_version = TLS1_1_VERSION,
|
||||
.max_tls_version = TLS1_1_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,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.enc_flags = TLSV1_1_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_2_method_data = {
|
||||
.dtls = 1,
|
||||
.server = 1,
|
||||
.version = DTLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_2_VERSION,
|
||||
.max_tls_version = TLS1_2_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,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD DTLSv1_2_client_method_data = {
|
||||
.dtls = 1,
|
||||
.server = 0,
|
||||
.version = DTLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_2_VERSION,
|
||||
.max_tls_version = TLS1_2_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,
|
||||
.get_cipher = dtls1_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_client_method(void)
|
||||
{
|
||||
return &DTLSv1_client_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_method(void)
|
||||
{
|
||||
return &DTLSv1_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_server_method(void)
|
||||
{
|
||||
return &DTLSv1_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_2_client_method(void)
|
||||
{
|
||||
return &DTLSv1_2_client_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_2_method(void)
|
||||
{
|
||||
return &DTLSv1_2_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLSv1_2_server_method(void)
|
||||
{
|
||||
return &DTLSv1_2_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLS_client_method(void)
|
||||
{
|
||||
return &DTLS_client_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLS_method(void)
|
||||
{
|
||||
return &DTLS_method_data;
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
DTLS_server_method(void)
|
||||
{
|
||||
return &DTLS_method_data;
|
||||
}
|
||||
|
||||
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT) && defined(LIBRESSL_HAS_TLS1_3_SERVER)
|
||||
static const SSL_METHOD TLS_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 1,
|
||||
.version = TLS1_3_VERSION,
|
||||
.min_tls_version = TLS1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_3_ENC_FLAGS,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const SSL_METHOD TLS_legacy_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 1,
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT)
|
||||
static const SSL_METHOD TLS_client_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 0,
|
||||
.version = TLS1_3_VERSION,
|
||||
.min_tls_version = TLS1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_3_ENC_FLAGS,
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const SSL_METHOD TLS_legacy_client_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 0,
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const SSL_METHOD TLSv1_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 1,
|
||||
.version = TLS1_VERSION,
|
||||
.min_tls_version = TLS1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_client_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 0,
|
||||
.version = TLS1_VERSION,
|
||||
.min_tls_version = TLS1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_1_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 1,
|
||||
.version = TLS1_1_VERSION,
|
||||
.min_tls_version = TLS1_1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_1_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_1_client_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 0,
|
||||
.version = TLS1_1_VERSION,
|
||||
.min_tls_version = TLS1_1_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_1_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_2_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 1,
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_2_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
static const SSL_METHOD TLSv1_2_client_method_data = {
|
||||
.dtls = 0,
|
||||
.server = 0,
|
||||
.version = TLS1_2_VERSION,
|
||||
.min_tls_version = TLS1_2_VERSION,
|
||||
.max_tls_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,
|
||||
.get_cipher = ssl3_get_cipher,
|
||||
.enc_flags = TLSV1_2_ENC_FLAGS,
|
||||
};
|
||||
|
||||
const SSL_METHOD *
|
||||
TLS_client_method(void)
|
||||
{
|
||||
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT)
|
||||
return (&TLS_client_method_data);
|
||||
#else
|
||||
return (&TLS_legacy_client_method_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
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_server_method(void)
|
||||
{
|
||||
return TLS_method();
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
tls_legacy_method(void)
|
||||
{
|
||||
return (&TLS_legacy_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
SSLv23_client_method(void)
|
||||
{
|
||||
return TLS_client_method();
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
SSLv23_method(void)
|
||||
{
|
||||
return TLS_method();
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
SSLv23_server_method(void)
|
||||
{
|
||||
return TLS_method();
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_client_method(void)
|
||||
{
|
||||
return (&TLSv1_client_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_method(void)
|
||||
{
|
||||
return (&TLSv1_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_server_method(void)
|
||||
{
|
||||
return (&TLSv1_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_1_client_method(void)
|
||||
{
|
||||
return (&TLSv1_1_client_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_1_method(void)
|
||||
{
|
||||
return (&TLSv1_1_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_1_server_method(void)
|
||||
{
|
||||
return (&TLSv1_1_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_2_client_method(void)
|
||||
{
|
||||
return (&TLSv1_2_client_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_2_method(void)
|
||||
{
|
||||
return (&TLSv1_2_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
TLSv1_2_server_method(void)
|
||||
{
|
||||
return (&TLSv1_2_method_data);
|
||||
}
|
||||
|
||||
const SSL_METHOD *
|
||||
ssl_get_method(uint16_t version)
|
||||
{
|
||||
if (version == TLS1_3_VERSION)
|
||||
return (TLS_method());
|
||||
if (version == TLS1_2_VERSION)
|
||||
return (TLSv1_2_method());
|
||||
if (version == TLS1_1_VERSION)
|
||||
return (TLSv1_1_method());
|
||||
if (version == TLS1_VERSION)
|
||||
return (TLSv1_method());
|
||||
if (version == DTLS1_VERSION)
|
||||
return (DTLSv1_method());
|
||||
if (version == DTLS1_2_VERSION)
|
||||
return (DTLSv1_2_method());
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
292
externals/libressl/ssl/ssl_packet.c
vendored
Normal file
292
externals/libressl/ssl/ssl_packet.c
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
/* $OpenBSD: ssl_packet.c,v 1.15 2022/11/26 16:08:56 tb 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 "bytestring.h"
|
||||
#include "ssl_local.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->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->packet + 2,
|
||||
s->packet_length - 2);
|
||||
s->mac_packet = 0;
|
||||
|
||||
if (s->msg_callback)
|
||||
s->msg_callback(0, SSL2_VERSION, 0,
|
||||
s->packet + 2, s->packet_length - 2, s,
|
||||
s->msg_callback_arg);
|
||||
|
||||
/* Decode the SSLv2 record containing the client hello. */
|
||||
CBS_init(&cbs, s->packet, s->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 > s->s3->rbuf.len)
|
||||
goto err;
|
||||
|
||||
s->packet = s->s3->rbuf.buf;
|
||||
s->packet_length = data_len;
|
||||
memcpy(s->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->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->min_tls_version == s->method->max_tls_version)
|
||||
return 1;
|
||||
|
||||
if (ssl_is_sslv2_client_hello(&header) == 1) {
|
||||
/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
|
||||
if (ssl_enabled_tls_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;
|
||||
}
|
||||
1324
externals/libressl/ssl/ssl_pkt.c
vendored
Normal file
1324
externals/libressl/ssl/ssl_pkt.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
748
externals/libressl/ssl/ssl_rsa.c
vendored
Normal file
748
externals/libressl/ssl/ssl_rsa.c
vendored
Normal file
@@ -0,0 +1,748 @@
|
||||
/* $OpenBSD: ssl_rsa.c,v 1.49 2022/11/26 16:08:56 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 <stdio.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "ssl_local.h"
|
||||
|
||||
static int ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl,
|
||||
pem_password_cb **passwd_cb, void **passwd_arg);
|
||||
static int ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x509);
|
||||
static int ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey);
|
||||
static int ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in);
|
||||
static int ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl,
|
||||
const char *file);
|
||||
|
||||
int
|
||||
SSL_use_certificate(SSL *ssl, X509 *x)
|
||||
{
|
||||
if (x == NULL) {
|
||||
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return (0);
|
||||
}
|
||||
return ssl_set_cert(NULL, ssl, 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());
|
||||
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(NULL, ssl, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey)
|
||||
{
|
||||
SSL_CERT *c;
|
||||
int i;
|
||||
|
||||
i = ssl_cert_type(pkey);
|
||||
if (i < 0) {
|
||||
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((c = ssl_get0_cert(ctx, ssl)) == NULL)
|
||||
return (0);
|
||||
|
||||
if (c->pkeys[i].x509 != NULL) {
|
||||
EVP_PKEY *pktmp;
|
||||
|
||||
if ((pktmp = X509_get0_pubkey(c->pkeys[i].x509)) == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Callers of EVP_PKEY_copy_parameters() can't distinguish
|
||||
* errors from the absence of a param_copy() method. So
|
||||
* pretend it can never fail.
|
||||
*/
|
||||
EVP_PKEY_copy_parameters(pktmp, pkey);
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
/*
|
||||
* Don't check the public/private key, this is mostly
|
||||
* for smart cards.
|
||||
*/
|
||||
if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
|
||||
!(RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK)) {
|
||||
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);
|
||||
EVP_PKEY_up_ref(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());
|
||||
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(NULL, ssl, 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());
|
||||
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, NULL, x);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl,
|
||||
pem_password_cb **passwd_cb, void **passwd_arg)
|
||||
{
|
||||
if (ssl != NULL)
|
||||
ctx = ssl->ctx;
|
||||
|
||||
*passwd_cb = ctx->default_passwd_callback;
|
||||
*passwd_arg = ctx->default_passwd_callback_userdata;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x)
|
||||
{
|
||||
SSL_CERT *c;
|
||||
EVP_PKEY *pkey;
|
||||
int ssl_err;
|
||||
int i;
|
||||
|
||||
if (!ssl_security_cert(ctx, ssl, x, 1, &ssl_err)) {
|
||||
SSLerrorx(ssl_err);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((c = ssl_get0_cert(ctx, ssl)) == NULL)
|
||||
return (0);
|
||||
|
||||
pkey = X509_get_pubkey(x);
|
||||
if (pkey == NULL) {
|
||||
SSLerrorx(SSL_R_X509_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
i = ssl_cert_type(pkey);
|
||||
if (i < 0) {
|
||||
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
|
||||
EVP_PKEY_free(pkey);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (c->pkeys[i].privatekey != NULL) {
|
||||
EVP_PKEY *priv_key = c->pkeys[i].privatekey;
|
||||
|
||||
EVP_PKEY_copy_parameters(pkey, priv_key);
|
||||
ERR_clear_error();
|
||||
|
||||
/*
|
||||
* Don't check the public/private key, this is mostly
|
||||
* for smart cards.
|
||||
*/
|
||||
if (EVP_PKEY_id(priv_key) != EVP_PKEY_RSA ||
|
||||
!(RSA_flags(EVP_PKEY_get0_RSA(priv_key)) & RSA_METHOD_FLAG_NO_CHECK)) {
|
||||
if (!X509_check_private_key(x, priv_key)) {
|
||||
/*
|
||||
* 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;
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
X509_free(c->pkeys[i].x509);
|
||||
X509_up_ref(x);
|
||||
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());
|
||||
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, NULL, 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());
|
||||
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, NULL, 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());
|
||||
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_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in)
|
||||
{
|
||||
pem_password_cb *passwd_cb;
|
||||
void *passwd_arg;
|
||||
X509 *ca, *x = NULL;
|
||||
unsigned long err;
|
||||
int ret = 0;
|
||||
|
||||
if (!ssl_get_password_cb_and_arg(ctx, ssl, &passwd_cb, &passwd_arg))
|
||||
goto err;
|
||||
|
||||
if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) ==
|
||||
NULL) {
|
||||
SSLerrorx(ERR_R_PEM_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ssl_set_cert(ctx, ssl, x))
|
||||
goto err;
|
||||
|
||||
if (!ssl_cert_set0_chain(ctx, ssl, NULL))
|
||||
goto err;
|
||||
|
||||
/* Process any additional CA certificates. */
|
||||
while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) !=
|
||||
NULL) {
|
||||
if (!ssl_cert_add0_chain_cert(ctx, ssl, 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_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
|
||||
{
|
||||
BIO *in;
|
||||
int ret = 0;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
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_use_certificate_chain_bio(ctx, ssl, in);
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
|
||||
{
|
||||
return ssl_use_certificate_chain_file(ctx, NULL, file);
|
||||
}
|
||||
|
||||
int
|
||||
SSL_use_certificate_chain_file(SSL *ssl, const char *file)
|
||||
{
|
||||
return ssl_use_certificate_chain_file(NULL, ssl, file);
|
||||
}
|
||||
|
||||
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_use_certificate_chain_bio(ctx, NULL, in);
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (ret);
|
||||
}
|
||||
473
externals/libressl/ssl/ssl_seclevel.c
vendored
Normal file
473
externals/libressl/ssl/ssl_seclevel.c
vendored
Normal file
@@ -0,0 +1,473 @@
|
||||
/* $OpenBSD: ssl_seclevel.c,v 1.27 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2020-2022 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 <stddef.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/tls1.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_local.h"
|
||||
|
||||
static int
|
||||
ssl_security_normalize_level(const SSL_CTX *ctx, const SSL *ssl, int *out_level)
|
||||
{
|
||||
int security_level;
|
||||
|
||||
if (ctx != NULL)
|
||||
security_level = SSL_CTX_get_security_level(ctx);
|
||||
else
|
||||
security_level = SSL_get_security_level(ssl);
|
||||
|
||||
if (security_level < 0)
|
||||
security_level = 0;
|
||||
if (security_level > 5)
|
||||
security_level = 5;
|
||||
|
||||
*out_level = security_level;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_level_to_minimum_bits(int security_level, int *out_minimum_bits)
|
||||
{
|
||||
if (security_level < 0)
|
||||
return 0;
|
||||
|
||||
if (security_level == 0)
|
||||
*out_minimum_bits = 0;
|
||||
else if (security_level == 1)
|
||||
*out_minimum_bits = 80;
|
||||
else if (security_level == 2)
|
||||
*out_minimum_bits = 112;
|
||||
else if (security_level == 3)
|
||||
*out_minimum_bits = 128;
|
||||
else if (security_level == 4)
|
||||
*out_minimum_bits = 192;
|
||||
else if (security_level >= 5)
|
||||
*out_minimum_bits = 256;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_level_and_minimum_bits(const SSL_CTX *ctx, const SSL *ssl,
|
||||
int *out_level, int *out_minimum_bits)
|
||||
{
|
||||
int security_level = 0, minimum_bits = 0;
|
||||
|
||||
if (!ssl_security_normalize_level(ctx, ssl, &security_level))
|
||||
return 0;
|
||||
if (!ssl_security_level_to_minimum_bits(security_level, &minimum_bits))
|
||||
return 0;
|
||||
|
||||
if (out_level != NULL)
|
||||
*out_level = security_level;
|
||||
if (out_minimum_bits != NULL)
|
||||
*out_minimum_bits = minimum_bits;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_secop_cipher(const SSL_CTX *ctx, const SSL *ssl, int bits,
|
||||
void *arg)
|
||||
{
|
||||
const SSL_CIPHER *cipher = arg;
|
||||
int security_level, minimum_bits;
|
||||
|
||||
if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
|
||||
&minimum_bits))
|
||||
return 0;
|
||||
|
||||
if (security_level <= 0)
|
||||
return 1;
|
||||
|
||||
if (bits < minimum_bits)
|
||||
return 0;
|
||||
|
||||
/* No unauthenticated ciphersuites. */
|
||||
if (cipher->algorithm_auth & SSL_aNULL)
|
||||
return 0;
|
||||
|
||||
if (cipher->algorithm_mac & SSL_MD5)
|
||||
return 0;
|
||||
|
||||
if (security_level <= 1)
|
||||
return 1;
|
||||
|
||||
if (cipher->algorithm_enc & SSL_RC4)
|
||||
return 0;
|
||||
|
||||
if (security_level <= 2)
|
||||
return 1;
|
||||
|
||||
/* Security level >= 3 requires a cipher with forward secrecy. */
|
||||
if ((cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) == 0 &&
|
||||
cipher->algorithm_ssl != SSL_TLSV1_3)
|
||||
return 0;
|
||||
|
||||
if (security_level <= 3)
|
||||
return 1;
|
||||
|
||||
if (cipher->algorithm_mac & SSL_SHA1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_secop_version(const SSL_CTX *ctx, const SSL *ssl, int version)
|
||||
{
|
||||
int min_version = TLS1_2_VERSION;
|
||||
int security_level;
|
||||
|
||||
if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL))
|
||||
return 0;
|
||||
|
||||
if (security_level < 4)
|
||||
min_version = TLS1_1_VERSION;
|
||||
if (security_level < 3)
|
||||
min_version = TLS1_VERSION;
|
||||
|
||||
return ssl_tls_version(version) >= min_version;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_secop_compression(const SSL_CTX *ctx, const SSL *ssl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_secop_tickets(const SSL_CTX *ctx, const SSL *ssl)
|
||||
{
|
||||
int security_level;
|
||||
|
||||
if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level, NULL))
|
||||
return 0;
|
||||
|
||||
return security_level < 3;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_secop_tmp_dh(const SSL_CTX *ctx, const SSL *ssl, int bits)
|
||||
{
|
||||
int security_level, minimum_bits;
|
||||
|
||||
if (!ssl_security_level_and_minimum_bits(ctx, ssl, &security_level,
|
||||
&minimum_bits))
|
||||
return 0;
|
||||
|
||||
/* Disallow DHE keys weaker than 1024 bits even at security level 0. */
|
||||
if (security_level <= 0 && bits < 80)
|
||||
return 0;
|
||||
|
||||
return bits >= minimum_bits;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_secop_default(const SSL_CTX *ctx, const SSL *ssl, int bits)
|
||||
{
|
||||
int minimum_bits;
|
||||
|
||||
if (!ssl_security_level_and_minimum_bits(ctx, ssl, NULL, &minimum_bits))
|
||||
return 0;
|
||||
|
||||
return bits >= minimum_bits;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_default_cb(const SSL *ssl, const SSL_CTX *ctx, int secop, int bits,
|
||||
int version, void *cipher, void *ex_data)
|
||||
{
|
||||
switch (secop) {
|
||||
case SSL_SECOP_CIPHER_SUPPORTED:
|
||||
case SSL_SECOP_CIPHER_SHARED:
|
||||
case SSL_SECOP_CIPHER_CHECK:
|
||||
return ssl_security_secop_cipher(ctx, ssl, bits, cipher);
|
||||
case SSL_SECOP_VERSION:
|
||||
return ssl_security_secop_version(ctx, ssl, version);
|
||||
case SSL_SECOP_COMPRESSION:
|
||||
return ssl_security_secop_compression(ctx, ssl);
|
||||
case SSL_SECOP_TICKET:
|
||||
return ssl_security_secop_tickets(ctx, ssl);
|
||||
case SSL_SECOP_TMP_DH:
|
||||
return ssl_security_secop_tmp_dh(ctx, ssl, bits);
|
||||
default:
|
||||
return ssl_security_secop_default(ctx, ssl, bits);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_ctx_security(const SSL_CTX *ctx, int secop, int bits, int nid, void *other)
|
||||
{
|
||||
return ctx->cert->security_cb(NULL, ctx, secop, bits, nid,
|
||||
other, ctx->cert->security_ex_data);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security(const SSL *ssl, int secop, int bits, int nid, void *other)
|
||||
{
|
||||
return ssl->cert->security_cb(ssl, NULL, secop, bits, nid, other,
|
||||
ssl->cert->security_ex_data);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_sigalg_check(const SSL *ssl, const EVP_PKEY *pkey)
|
||||
{
|
||||
int bits;
|
||||
|
||||
bits = EVP_PKEY_security_bits(pkey);
|
||||
|
||||
return ssl_security(ssl, SSL_SECOP_SIGALG_CHECK, bits, 0, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_tickets(const SSL *ssl)
|
||||
{
|
||||
return ssl_security(ssl, SSL_SECOP_TICKET, 0, 0, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_version(const SSL *ssl, int version)
|
||||
{
|
||||
return ssl_security(ssl, SSL_SECOP_VERSION, 0, version, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_cipher(const SSL *ssl, SSL_CIPHER *cipher, int secop)
|
||||
{
|
||||
return ssl_security(ssl, secop, cipher->strength_bits, 0, cipher);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_cipher_check(const SSL *ssl, SSL_CIPHER *cipher)
|
||||
{
|
||||
return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_CHECK);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_shared_cipher(const SSL *ssl, SSL_CIPHER *cipher)
|
||||
{
|
||||
return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SHARED);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_supported_cipher(const SSL *ssl, SSL_CIPHER *cipher)
|
||||
{
|
||||
return ssl_security_cipher(ssl, cipher, SSL_SECOP_CIPHER_SUPPORTED);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_ctx_security_dh(const SSL_CTX *ctx, DH *dh)
|
||||
{
|
||||
int bits;
|
||||
|
||||
bits = DH_security_bits(dh);
|
||||
|
||||
return ssl_ctx_security(ctx, SSL_SECOP_TMP_DH, bits, 0, dh);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_dh(const SSL *ssl, DH *dh)
|
||||
{
|
||||
int bits;
|
||||
|
||||
bits = DH_security_bits(dh);
|
||||
|
||||
return ssl_security(ssl, SSL_SECOP_TMP_DH, bits, 0, dh);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_cert_pubkey_security_bits(const X509 *x509)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if ((pkey = X509_get0_pubkey(x509)) == NULL)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* XXX: DSA_security_bits() returns -1 on keys without parameters and
|
||||
* makes the default security callback fail.
|
||||
*/
|
||||
|
||||
return EVP_PKEY_security_bits(pkey);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_cert_key(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
|
||||
{
|
||||
int security_bits;
|
||||
|
||||
security_bits = ssl_cert_pubkey_security_bits(x509);
|
||||
|
||||
if (ssl != NULL)
|
||||
return ssl_security(ssl, secop, security_bits, 0, x509);
|
||||
|
||||
return ssl_ctx_security(ctx, secop, security_bits, 0, x509);
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_cert_signature_md_nid(X509 *x509)
|
||||
{
|
||||
int md_nid, signature_nid;
|
||||
|
||||
if ((signature_nid = X509_get_signature_nid(x509)) == NID_undef)
|
||||
return NID_undef;
|
||||
|
||||
if (!OBJ_find_sigid_algs(signature_nid, &md_nid, NULL))
|
||||
return NID_undef;
|
||||
|
||||
return md_nid;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_cert_md_nid_security_bits(int md_nid)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
|
||||
if (md_nid == NID_undef)
|
||||
return -1;
|
||||
|
||||
if ((md = EVP_get_digestbynid(md_nid)) == NULL)
|
||||
return -1;
|
||||
|
||||
/* Assume 4 bits of collision resistance for each hash octet. */
|
||||
return EVP_MD_size(md) * 4;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_cert_sig(const SSL_CTX *ctx, const SSL *ssl, X509 *x509, int secop)
|
||||
{
|
||||
int md_nid, security_bits;
|
||||
|
||||
/* Don't check signature if self signed. */
|
||||
if ((X509_get_extension_flags(x509) & EXFLAG_SS) != 0)
|
||||
return 1;
|
||||
|
||||
md_nid = ssl_cert_signature_md_nid(x509);
|
||||
security_bits = ssl_cert_md_nid_security_bits(md_nid);
|
||||
|
||||
if (ssl != NULL)
|
||||
return ssl_security(ssl, secop, security_bits, md_nid, x509);
|
||||
|
||||
return ssl_ctx_security(ctx, secop, security_bits, md_nid, x509);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_cert(const SSL_CTX *ctx, const SSL *ssl, X509 *x509,
|
||||
int is_ee, int *out_error)
|
||||
{
|
||||
int key_error, operation;
|
||||
|
||||
*out_error = 0;
|
||||
|
||||
if (is_ee) {
|
||||
operation = SSL_SECOP_EE_KEY;
|
||||
key_error = SSL_R_EE_KEY_TOO_SMALL;
|
||||
} else {
|
||||
operation = SSL_SECOP_CA_KEY;
|
||||
key_error = SSL_R_CA_KEY_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (!ssl_security_cert_key(ctx, ssl, x509, operation)) {
|
||||
*out_error = key_error;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_security_cert_sig(ctx, ssl, x509, SSL_SECOP_CA_MD)) {
|
||||
*out_error = SSL_R_CA_MD_TOO_WEAK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check security of a chain. If |sk| includes the end entity certificate
|
||||
* then |x509| must be NULL.
|
||||
*/
|
||||
int
|
||||
ssl_security_cert_chain(const SSL *ssl, STACK_OF(X509) *sk, X509 *x509,
|
||||
int *out_error)
|
||||
{
|
||||
int start_idx = 0;
|
||||
int is_ee;
|
||||
int i;
|
||||
|
||||
if (x509 == NULL) {
|
||||
x509 = sk_X509_value(sk, 0);
|
||||
start_idx = 1;
|
||||
}
|
||||
|
||||
is_ee = 1;
|
||||
if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error))
|
||||
return 0;
|
||||
|
||||
is_ee = 0;
|
||||
for (i = start_idx; i < sk_X509_num(sk); i++) {
|
||||
x509 = sk_X509_value(sk, i);
|
||||
|
||||
if (!ssl_security_cert(NULL, ssl, x509, is_ee, out_error))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_security_group(const SSL *ssl, uint16_t group_id, int secop)
|
||||
{
|
||||
CBB cbb;
|
||||
int bits, nid;
|
||||
uint8_t group[2];
|
||||
|
||||
if (!tls1_ec_group_id2bits(group_id, &bits))
|
||||
return 0;
|
||||
if (!tls1_ec_group_id2nid(group_id, &nid))
|
||||
return 0;
|
||||
|
||||
if (!CBB_init_fixed(&cbb, group, sizeof(group)))
|
||||
return 0;
|
||||
if (!CBB_add_u16(&cbb, group_id))
|
||||
return 0;
|
||||
if (!CBB_finish(&cbb, NULL, NULL))
|
||||
return 0;
|
||||
|
||||
return ssl_security(ssl, secop, bits, nid, group);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_shared_group(const SSL *ssl, uint16_t group_id)
|
||||
{
|
||||
return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SHARED);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_security_supported_group(const SSL *ssl, uint16_t group_id)
|
||||
{
|
||||
return ssl_security_group(ssl, group_id, SSL_SECOP_CURVE_SUPPORTED);
|
||||
}
|
||||
1336
externals/libressl/ssl/ssl_sess.c
vendored
Normal file
1336
externals/libressl/ssl/ssl_sess.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
388
externals/libressl/ssl/ssl_sigalgs.c
vendored
Normal file
388
externals/libressl/ssl/ssl_sigalgs.c
vendored
Normal file
@@ -0,0 +1,388 @@
|
||||
/* $OpenBSD: ssl_sigalgs.c,v 1.48 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_local.h"
|
||||
#include "ssl_sigalgs.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
const struct ssl_sigalg sigalgs[] = {
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA512,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha512,
|
||||
.security_level = 5,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP521R1_SHA512,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.md = EVP_sha512,
|
||||
.security_level = 5,
|
||||
.group_nid = NID_secp521r1,
|
||||
},
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
.value = SIGALG_GOSTR12_512_STREEBOG_512,
|
||||
.key_type = EVP_PKEY_GOSTR12_512,
|
||||
.md = EVP_streebog512,
|
||||
.security_level = 0,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA384,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha384,
|
||||
.security_level = 4,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP384R1_SHA384,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.md = EVP_sha384,
|
||||
.security_level = 4,
|
||||
.group_nid = NID_secp384r1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA256,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha256,
|
||||
.security_level = 3,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP256R1_SHA256,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.md = EVP_sha256,
|
||||
.security_level = 3,
|
||||
.group_nid = NID_X9_62_prime256v1,
|
||||
},
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
.value = SIGALG_GOSTR12_256_STREEBOG_256,
|
||||
.key_type = EVP_PKEY_GOSTR12_256,
|
||||
.md = EVP_streebog256,
|
||||
.security_level = 0,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_GOSTR01_GOST94,
|
||||
.key_type = EVP_PKEY_GOSTR01,
|
||||
.md = EVP_gostr341194,
|
||||
.security_level = 0, /* XXX */
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_RSAE_SHA256,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha256,
|
||||
.security_level = 3,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_RSAE_SHA384,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha384,
|
||||
.security_level = 4,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_RSAE_SHA512,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha512,
|
||||
.security_level = 5,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_PSS_SHA256,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha256,
|
||||
.security_level = 3,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_PSS_SHA384,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha384,
|
||||
.security_level = 4,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PSS_PSS_SHA512,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha512,
|
||||
.security_level = 5,
|
||||
.flags = SIGALG_FLAG_RSA_PSS,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA224,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha224,
|
||||
.security_level = 2,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SECP224R1_SHA224,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.md = EVP_sha224,
|
||||
.security_level = 2,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_SHA1,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_sha1,
|
||||
.security_level = 1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_ECDSA_SHA1,
|
||||
.key_type = EVP_PKEY_EC,
|
||||
.md = EVP_sha1,
|
||||
.security_level = 1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_RSA_PKCS1_MD5_SHA1,
|
||||
.key_type = EVP_PKEY_RSA,
|
||||
.md = EVP_md5_sha1,
|
||||
.security_level = 1,
|
||||
},
|
||||
{
|
||||
.value = SIGALG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
/* Sigalgs for TLSv1.3, in preference order. */
|
||||
const 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,
|
||||
};
|
||||
const size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0]));
|
||||
|
||||
/* Sigalgs for TLSv1.2, in preference order. */
|
||||
const 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 */
|
||||
};
|
||||
const size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
|
||||
|
||||
static void
|
||||
ssl_sigalgs_for_version(uint16_t tls_version, const uint16_t **out_values,
|
||||
size_t *out_len)
|
||||
{
|
||||
if (tls_version >= TLS1_3_VERSION) {
|
||||
*out_values = tls13_sigalgs;
|
||||
*out_len = tls13_sigalgs_len;
|
||||
} else {
|
||||
*out_values = tls12_sigalgs;
|
||||
*out_len = tls12_sigalgs_len;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct ssl_sigalg *
|
||||
ssl_sigalg_lookup(uint16_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) {
|
||||
if (sigalgs[i].value == value)
|
||||
return &sigalgs[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ssl_sigalg *
|
||||
ssl_sigalg_from_value(SSL *s, uint16_t value)
|
||||
{
|
||||
const uint16_t *values;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
ssl_sigalgs_for_version(s->s3->hs.negotiated_tls_version,
|
||||
&values, &len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (values[i] == value)
|
||||
return ssl_sigalg_lookup(value);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_sigalgs_build(uint16_t tls_version, CBB *cbb, int security_level)
|
||||
{
|
||||
const struct ssl_sigalg *sigalg;
|
||||
const uint16_t *values;
|
||||
size_t len;
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
|
||||
ssl_sigalgs_for_version(tls_version, &values, &len);
|
||||
|
||||
/* 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 ((sigalg = ssl_sigalg_lookup(values[i])) == NULL)
|
||||
return 0;
|
||||
if (sigalg->security_level < security_level)
|
||||
continue;
|
||||
|
||||
if (!CBB_add_u16(cbb, values[i]))
|
||||
return 0;
|
||||
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct ssl_sigalg *
|
||||
ssl_sigalg_for_legacy(SSL *s, EVP_PKEY *pkey)
|
||||
{
|
||||
if (SSL_get_security_level(s) > 1)
|
||||
return NULL;
|
||||
|
||||
/* Default signature algorithms used for TLSv1.2 and earlier. */
|
||||
switch (EVP_PKEY_id(pkey)) {
|
||||
case EVP_PKEY_RSA:
|
||||
if (s->s3->hs.negotiated_tls_version < TLS1_2_VERSION)
|
||||
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_sigalg_pkey_ok(SSL *s, const struct ssl_sigalg *sigalg, EVP_PKEY *pkey)
|
||||
{
|
||||
if (sigalg == NULL || pkey == NULL)
|
||||
return 0;
|
||||
if (sigalg->key_type != EVP_PKEY_id(pkey))
|
||||
return 0;
|
||||
|
||||
/* RSA PSS must have a sufficiently large RSA key. */
|
||||
if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) {
|
||||
if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
|
||||
EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_security_sigalg_check(s, pkey))
|
||||
return 0;
|
||||
|
||||
if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION)
|
||||
return 1;
|
||||
|
||||
/* RSA cannot be used without PSS in TLSv1.3. */
|
||||
if (sigalg->key_type == EVP_PKEY_RSA &&
|
||||
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
|
||||
return 0;
|
||||
|
||||
/* Ensure that group matches for EC keys. */
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
|
||||
if (sigalg->group_nid == 0)
|
||||
return 0;
|
||||
if (EC_GROUP_get_curve_name(EC_KEY_get0_group(
|
||||
EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->group_nid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const struct ssl_sigalg *
|
||||
ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
|
||||
{
|
||||
CBS cbs;
|
||||
|
||||
if (!SSL_USE_SIGALGS(s))
|
||||
return ssl_sigalg_for_legacy(s, pkey);
|
||||
|
||||
/*
|
||||
* RFC 5246 allows a TLS 1.2 client to send no sigalgs extension,
|
||||
* in which case the server must use the default.
|
||||
*/
|
||||
if (s->s3->hs.negotiated_tls_version < TLS1_3_VERSION &&
|
||||
s->s3->hs.sigalgs == NULL)
|
||||
return ssl_sigalg_for_legacy(s, pkey);
|
||||
|
||||
/*
|
||||
* If we get here, we have client or server sent sigalgs, use one.
|
||||
*/
|
||||
CBS_init(&cbs, s->s3->hs.sigalgs, s->s3->hs.sigalgs_len);
|
||||
while (CBS_len(&cbs) > 0) {
|
||||
const struct ssl_sigalg *sigalg;
|
||||
uint16_t sigalg_value;
|
||||
|
||||
if (!CBS_get_u16(&cbs, &sigalg_value))
|
||||
return NULL;
|
||||
|
||||
if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL)
|
||||
continue;
|
||||
if (ssl_sigalg_pkey_ok(s, sigalg, pkey))
|
||||
return sigalg;
|
||||
}
|
||||
|
||||
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct ssl_sigalg *
|
||||
ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey, uint16_t sigalg_value)
|
||||
{
|
||||
const struct ssl_sigalg *sigalg;
|
||||
|
||||
if (!SSL_USE_SIGALGS(s))
|
||||
return ssl_sigalg_for_legacy(s, pkey);
|
||||
|
||||
if ((sigalg = ssl_sigalg_from_value(s, sigalg_value)) == NULL) {
|
||||
SSLerror(s, SSL_R_UNKNOWN_DIGEST);
|
||||
return NULL;
|
||||
}
|
||||
if (!ssl_sigalg_pkey_ok(s, sigalg, pkey)) {
|
||||
SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sigalg;
|
||||
}
|
||||
79
externals/libressl/ssl/ssl_sigalgs.h
vendored
Normal file
79
externals/libressl/ssl/ssl_sigalgs.h
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/* $OpenBSD: ssl_sigalgs.h,v 1.26 2022/07/02 16:00:12 tb 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 < TLSv1.2 same value as BoringSSL uses. */
|
||||
#define SIGALG_RSA_PKCS1_MD5_SHA1 0xFF01
|
||||
|
||||
#define SIGALG_FLAG_RSA_PSS 0x00000001
|
||||
|
||||
struct ssl_sigalg {
|
||||
uint16_t value;
|
||||
int key_type;
|
||||
const EVP_MD *(*md)(void);
|
||||
int security_level;
|
||||
int group_nid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
int ssl_sigalgs_build(uint16_t tls_version, CBB *cbb, int security_level);
|
||||
const struct ssl_sigalg *ssl_sigalg_select(SSL *s, EVP_PKEY *pkey);
|
||||
const struct ssl_sigalg *ssl_sigalg_for_peer(SSL *s, EVP_PKEY *pkey,
|
||||
uint16_t sigalg_value);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
2625
externals/libressl/ssl/ssl_srvr.c
vendored
Normal file
2625
externals/libressl/ssl/ssl_srvr.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
789
externals/libressl/ssl/ssl_stat.c
vendored
Normal file
789
externals/libressl/ssl/ssl_stat.c
vendored
Normal file
@@ -0,0 +1,789 @@
|
||||
/* $OpenBSD: ssl_stat.c,v 1.20 2022/11/26 16:08:56 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 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_local.h"
|
||||
|
||||
const char *
|
||||
SSL_state_string_long(const SSL *s)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
switch (s->s3->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->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 (s->s3->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 SSL_AD_CLOSE_NOTIFY:
|
||||
str = "CN";
|
||||
break;
|
||||
case SSL_AD_UNEXPECTED_MESSAGE:
|
||||
str = "UM";
|
||||
break;
|
||||
case SSL_AD_BAD_RECORD_MAC:
|
||||
str = "BM";
|
||||
break;
|
||||
case SSL_AD_DECOMPRESSION_FAILURE:
|
||||
str = "DF";
|
||||
break;
|
||||
case SSL_AD_HANDSHAKE_FAILURE:
|
||||
str = "HF";
|
||||
break;
|
||||
case SSL_AD_BAD_CERTIFICATE:
|
||||
str = "BC";
|
||||
break;
|
||||
case SSL_AD_UNSUPPORTED_CERTIFICATE:
|
||||
str = "UC";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_REVOKED:
|
||||
str = "CR";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_EXPIRED:
|
||||
str = "CE";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_UNKNOWN:
|
||||
str = "CU";
|
||||
break;
|
||||
case SSL_AD_ILLEGAL_PARAMETER:
|
||||
str = "IP";
|
||||
break;
|
||||
case SSL_AD_RECORD_OVERFLOW:
|
||||
str = "RO";
|
||||
break;
|
||||
case SSL_AD_UNKNOWN_CA:
|
||||
str = "CA";
|
||||
break;
|
||||
case SSL_AD_ACCESS_DENIED:
|
||||
str = "AD";
|
||||
break;
|
||||
case SSL_AD_DECODE_ERROR:
|
||||
str = "DE";
|
||||
break;
|
||||
case SSL_AD_DECRYPT_ERROR:
|
||||
str = "CY";
|
||||
break;
|
||||
case SSL_AD_PROTOCOL_VERSION:
|
||||
str = "PV";
|
||||
break;
|
||||
case SSL_AD_INSUFFICIENT_SECURITY:
|
||||
str = "IS";
|
||||
break;
|
||||
case SSL_AD_INTERNAL_ERROR:
|
||||
str = "IE";
|
||||
break;
|
||||
case SSL_AD_USER_CANCELLED:
|
||||
str = "US";
|
||||
break;
|
||||
case SSL_AD_NO_RENEGOTIATION:
|
||||
str = "NR";
|
||||
break;
|
||||
case SSL_AD_MISSING_EXTENSION:
|
||||
str = "ME";
|
||||
break;
|
||||
case SSL_AD_UNSUPPORTED_EXTENSION:
|
||||
str = "UE";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_UNOBTAINABLE:
|
||||
str = "CO";
|
||||
break;
|
||||
case SSL_AD_UNRECOGNIZED_NAME:
|
||||
str = "UN";
|
||||
break;
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
|
||||
str = "BR";
|
||||
break;
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
|
||||
str = "BH";
|
||||
break;
|
||||
case SSL_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 SSL_AD_CLOSE_NOTIFY:
|
||||
str = "close notify";
|
||||
break;
|
||||
case SSL_AD_UNEXPECTED_MESSAGE:
|
||||
str = "unexpected_message";
|
||||
break;
|
||||
case SSL_AD_BAD_RECORD_MAC:
|
||||
str = "bad record mac";
|
||||
break;
|
||||
case SSL_AD_DECOMPRESSION_FAILURE:
|
||||
str = "decompression failure";
|
||||
break;
|
||||
case SSL_AD_HANDSHAKE_FAILURE:
|
||||
str = "handshake failure";
|
||||
break;
|
||||
case SSL_AD_BAD_CERTIFICATE:
|
||||
str = "bad certificate";
|
||||
break;
|
||||
case SSL_AD_UNSUPPORTED_CERTIFICATE:
|
||||
str = "unsupported certificate";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_REVOKED:
|
||||
str = "certificate revoked";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_EXPIRED:
|
||||
str = "certificate expired";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_UNKNOWN:
|
||||
str = "certificate unknown";
|
||||
break;
|
||||
case SSL_AD_ILLEGAL_PARAMETER:
|
||||
str = "illegal parameter";
|
||||
break;
|
||||
case SSL_AD_RECORD_OVERFLOW:
|
||||
str = "record overflow";
|
||||
break;
|
||||
case SSL_AD_UNKNOWN_CA:
|
||||
str = "unknown CA";
|
||||
break;
|
||||
case SSL_AD_ACCESS_DENIED:
|
||||
str = "access denied";
|
||||
break;
|
||||
case SSL_AD_DECODE_ERROR:
|
||||
str = "decode error";
|
||||
break;
|
||||
case SSL_AD_DECRYPT_ERROR:
|
||||
str = "decrypt error";
|
||||
break;
|
||||
case SSL_AD_PROTOCOL_VERSION:
|
||||
str = "protocol version";
|
||||
break;
|
||||
case SSL_AD_INSUFFICIENT_SECURITY:
|
||||
str = "insufficient security";
|
||||
break;
|
||||
case SSL_AD_INTERNAL_ERROR:
|
||||
str = "internal error";
|
||||
break;
|
||||
case SSL_AD_USER_CANCELLED:
|
||||
str = "user canceled";
|
||||
break;
|
||||
case SSL_AD_NO_RENEGOTIATION:
|
||||
str = "no renegotiation";
|
||||
break;
|
||||
case SSL_AD_MISSING_EXTENSION:
|
||||
str = "missing extension";
|
||||
break;
|
||||
case SSL_AD_UNSUPPORTED_EXTENSION:
|
||||
str = "unsupported extension";
|
||||
break;
|
||||
case SSL_AD_CERTIFICATE_UNOBTAINABLE:
|
||||
str = "certificate unobtainable";
|
||||
break;
|
||||
case SSL_AD_UNRECOGNIZED_NAME:
|
||||
str = "unrecognized name";
|
||||
break;
|
||||
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
|
||||
str = "bad certificate status response";
|
||||
break;
|
||||
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
|
||||
str = "bad certificate hash value";
|
||||
break;
|
||||
case SSL_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->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);
|
||||
}
|
||||
2519
externals/libressl/ssl/ssl_tlsext.c
vendored
Normal file
2519
externals/libressl/ssl/ssl_tlsext.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
48
externals/libressl/ssl/ssl_tlsext.h
vendored
Normal file
48
externals/libressl/ssl/ssl_tlsext.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $OpenBSD: ssl_tlsext.h,v 1.33 2023/04/23 18:51:53 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_check_format(CBS *cbs);
|
||||
int tlsext_sni_is_valid_hostname(CBS *cbs, int *is_ip);
|
||||
|
||||
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);
|
||||
|
||||
int tlsext_extension_seen(SSL *s, uint16_t);
|
||||
int tlsext_randomize_build_order(SSL *s);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
197
externals/libressl/ssl/ssl_transcript.c
vendored
Normal file
197
externals/libressl/ssl/ssl_transcript.c
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/* $OpenBSD: ssl_transcript.c,v 1.9 2022/11/26 16:08:56 tb 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 <openssl/ssl.h>
|
||||
|
||||
#include "ssl_local.h"
|
||||
#include "tls_internal.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 ((s->s3->handshake_hash = EVP_MD_CTX_new()) == NULL) {
|
||||
SSLerror(s, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestInit_ex(s->s3->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 (s->s3->handshake_hash == NULL)
|
||||
return 1;
|
||||
|
||||
return EVP_DigestUpdate(s->s3->handshake_hash, buf, len);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_hash_value(SSL *s, unsigned char *out, size_t len,
|
||||
size_t *outlen)
|
||||
{
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
unsigned int mdlen;
|
||||
int ret = 0;
|
||||
|
||||
if (s->s3->handshake_hash == NULL)
|
||||
goto err;
|
||||
|
||||
if (EVP_MD_CTX_size(s->s3->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, s->s3->handshake_hash)) {
|
||||
SSLerror(s, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(mdctx, 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(s->s3->handshake_hash);
|
||||
s->s3->handshake_hash = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_init(SSL *s)
|
||||
{
|
||||
if (s->s3->handshake_transcript != NULL)
|
||||
return 0;
|
||||
|
||||
if ((s->s3->handshake_transcript = tls_buffer_new(0)) == NULL)
|
||||
return 0;
|
||||
|
||||
tls1_transcript_reset(s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_free(SSL *s)
|
||||
{
|
||||
tls_buffer_free(s->s3->handshake_transcript);
|
||||
s->s3->handshake_transcript = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls1_transcript_reset(SSL *s)
|
||||
{
|
||||
tls_buffer_clear(s->s3->handshake_transcript);
|
||||
|
||||
tls1_transcript_unfreeze(s);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
|
||||
{
|
||||
if (s->s3->handshake_transcript == NULL)
|
||||
return 1;
|
||||
|
||||
if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT)
|
||||
return 1;
|
||||
|
||||
return tls_buffer_append(s->s3->handshake_transcript, buf, len);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len)
|
||||
{
|
||||
CBS cbs;
|
||||
|
||||
if (s->s3->handshake_transcript == NULL)
|
||||
return 0;
|
||||
|
||||
if (!tls_buffer_data(s->s3->handshake_transcript, &cbs))
|
||||
return 0;
|
||||
|
||||
/* XXX - change to caller providing a CBS argument. */
|
||||
*data = CBS_data(&cbs);
|
||||
*len = CBS_len(&cbs);
|
||||
|
||||
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;
|
||||
}
|
||||
200
externals/libressl/ssl/ssl_txt.c
vendored
Normal file
200
externals/libressl/ssl/ssl_txt.c
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/* $OpenBSD: ssl_txt.c,v 1.36 2022/11/26 16:08:56 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 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_local.h"
|
||||
|
||||
int
|
||||
SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b = BIO_new(BIO_s_file())) == 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)
|
||||
{
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
|
||||
if (x == NULL)
|
||||
goto err;
|
||||
|
||||
if (BIO_puts(bp, "SSL-Session:\n") <= 0)
|
||||
goto err;
|
||||
|
||||
if (BIO_printf(bp, " Protocol : %s\n",
|
||||
ssl_version_string(x->ssl_version)) <= 0)
|
||||
goto err;
|
||||
|
||||
if (x->cipher == NULL) {
|
||||
if (BIO_printf(bp, " Cipher : %04lX\n",
|
||||
x->cipher_id & SSL3_CK_VALUE_MASK) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
const char *cipher_name = "unknown";
|
||||
|
||||
if (x->cipher->name != NULL)
|
||||
cipher_name = x->cipher->name;
|
||||
|
||||
if (BIO_printf(bp, " Cipher : %s\n", 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 < x->master_key_length; i++) {
|
||||
if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (x->tlsext_tick_lifetime_hint > 0) {
|
||||
if (BIO_printf(bp,
|
||||
"\n TLS session ticket lifetime hint: %u (seconds)",
|
||||
x->tlsext_tick_lifetime_hint) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (x->tlsext_tick != NULL) {
|
||||
if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0)
|
||||
goto err;
|
||||
if (BIO_dump_indent(bp, 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 != 0) {
|
||||
if (BIO_printf(bp, "\n Timeout : %ld (sec)",
|
||||
x->timeout) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
|
||||
if (BIO_printf(bp, " Verify return code: %ld (%s)\n",
|
||||
x->verify_result,
|
||||
X509_verify_cert_error_string(x->verify_result)) <= 0)
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
381
externals/libressl/ssl/ssl_versions.c
vendored
Normal file
381
externals/libressl/ssl/ssl_versions.c
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
/* $OpenBSD: ssl_versions.c,v 1.26 2022/11/26 16:08:56 tb 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_local.h"
|
||||
|
||||
static uint16_t
|
||||
ssl_dtls_to_tls_version(uint16_t dtls_ver)
|
||||
{
|
||||
if (dtls_ver == DTLS1_VERSION)
|
||||
return TLS1_1_VERSION;
|
||||
if (dtls_ver == DTLS1_2_VERSION)
|
||||
return TLS1_2_VERSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
ssl_tls_to_dtls_version(uint16_t tls_ver)
|
||||
{
|
||||
if (tls_ver == TLS1_1_VERSION)
|
||||
return DTLS1_VERSION;
|
||||
if (tls_ver == TLS1_2_VERSION)
|
||||
return DTLS1_2_VERSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ssl_clamp_tls_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 proto_ver,
|
||||
uint16_t max_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
|
||||
{
|
||||
uint16_t min_proto, min_version, max_version;
|
||||
|
||||
if (proto_ver == 0) {
|
||||
*out_tls_ver = meth->min_tls_version;
|
||||
*out_proto_ver = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
min_version = proto_ver;
|
||||
max_version = max_tls_ver;
|
||||
|
||||
if (meth->dtls) {
|
||||
if ((min_version = ssl_dtls_to_tls_version(proto_ver)) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
|
||||
meth->min_tls_version, meth->max_tls_version))
|
||||
return 0;
|
||||
|
||||
min_proto = min_version;
|
||||
if (meth->dtls) {
|
||||
if ((min_proto = ssl_tls_to_dtls_version(min_version)) == 0)
|
||||
return 0;
|
||||
}
|
||||
*out_tls_ver = min_version;
|
||||
*out_proto_ver = min_proto;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_version_set_max(const SSL_METHOD *meth, uint16_t proto_ver,
|
||||
uint16_t min_tls_ver, uint16_t *out_tls_ver, uint16_t *out_proto_ver)
|
||||
{
|
||||
uint16_t max_proto, min_version, max_version;
|
||||
|
||||
if (proto_ver == 0) {
|
||||
*out_tls_ver = meth->max_tls_version;
|
||||
*out_proto_ver = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
min_version = min_tls_ver;
|
||||
max_version = proto_ver;
|
||||
|
||||
if (meth->dtls) {
|
||||
if ((max_version = ssl_dtls_to_tls_version(proto_ver)) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
|
||||
meth->min_tls_version, meth->max_tls_version))
|
||||
return 0;
|
||||
|
||||
max_proto = max_version;
|
||||
if (meth->dtls) {
|
||||
if ((max_proto = ssl_tls_to_dtls_version(max_version)) == 0)
|
||||
return 0;
|
||||
}
|
||||
*out_tls_ver = max_version;
|
||||
*out_proto_ver = max_proto;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_enabled_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
unsigned long options;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
options = s->options;
|
||||
|
||||
if (SSL_is_dtls(s)) {
|
||||
options = 0;
|
||||
if (s->options & SSL_OP_NO_DTLSv1)
|
||||
options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
|
||||
if (s->options & SSL_OP_NO_DTLSv1_2)
|
||||
options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2;
|
||||
}
|
||||
|
||||
if ((options & SSL_OP_NO_TLSv1) == 0)
|
||||
min_version = TLS1_VERSION;
|
||||
else if ((options & SSL_OP_NO_TLSv1_1) == 0)
|
||||
min_version = TLS1_1_VERSION;
|
||||
else if ((options & SSL_OP_NO_TLSv1_2) == 0)
|
||||
min_version = TLS1_2_VERSION;
|
||||
else if ((options & SSL_OP_NO_TLSv1_3) == 0)
|
||||
min_version = TLS1_3_VERSION;
|
||||
|
||||
if ((options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
|
||||
max_version = TLS1_2_VERSION;
|
||||
if ((options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
|
||||
max_version = TLS1_1_VERSION;
|
||||
if ((options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
|
||||
max_version = TLS1_VERSION;
|
||||
if ((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_tls_version_range(&min_version, &max_version,
|
||||
s->min_tls_version, s->max_tls_version))
|
||||
return 0;
|
||||
|
||||
/* QUIC requires a minimum of TLSv1.3. */
|
||||
if (SSL_is_quic(s)) {
|
||||
if (max_version < TLS1_3_VERSION)
|
||||
return 0;
|
||||
if (min_version < TLS1_3_VERSION)
|
||||
min_version = TLS1_3_VERSION;
|
||||
}
|
||||
|
||||
if (min_ver != NULL)
|
||||
*min_ver = min_version;
|
||||
if (max_ver != NULL)
|
||||
*max_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_supported_tls_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t min_version, max_version;
|
||||
|
||||
if (!ssl_enabled_tls_version_range(s, &min_version, &max_version))
|
||||
return 0;
|
||||
|
||||
/* Limit to the versions supported by this method. */
|
||||
if (!ssl_clamp_tls_version_range(&min_version, &max_version,
|
||||
s->method->min_tls_version, s->method->max_tls_version))
|
||||
return 0;
|
||||
|
||||
if (min_ver != NULL)
|
||||
*min_ver = min_version;
|
||||
if (max_ver != NULL)
|
||||
*max_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ssl_tls_version(uint16_t version)
|
||||
{
|
||||
if (version == TLS1_VERSION || version == TLS1_1_VERSION ||
|
||||
version == TLS1_2_VERSION || version == TLS1_3_VERSION)
|
||||
return version;
|
||||
|
||||
if (version == DTLS1_VERSION)
|
||||
return TLS1_1_VERSION;
|
||||
if (version == DTLS1_2_VERSION)
|
||||
return TLS1_2_VERSION;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ssl_effective_tls_version(SSL *s)
|
||||
{
|
||||
if (s->s3->hs.negotiated_tls_version > 0)
|
||||
return s->s3->hs.negotiated_tls_version;
|
||||
|
||||
return s->s3->hs.our_max_tls_version;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_max_supported_version(SSL *s, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t max_version;
|
||||
|
||||
*max_ver = 0;
|
||||
|
||||
if (!ssl_supported_tls_version_range(s, NULL, &max_version))
|
||||
return 0;
|
||||
|
||||
if (SSL_is_dtls(s)) {
|
||||
if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*max_ver = max_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_max_legacy_version(SSL *s, uint16_t *max_ver)
|
||||
{
|
||||
uint16_t max_version;
|
||||
|
||||
if ((max_version = s->s3->hs.our_max_tls_version) > TLS1_2_VERSION)
|
||||
max_version = TLS1_2_VERSION;
|
||||
|
||||
if (SSL_is_dtls(s)) {
|
||||
if ((max_version = ssl_tls_to_dtls_version(max_version)) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
*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, peer_tls_version, shared_version;
|
||||
|
||||
*max_ver = 0;
|
||||
peer_tls_version = peer_ver;
|
||||
|
||||
if (SSL_is_dtls(s)) {
|
||||
if ((peer_ver >> 8) != DTLS1_VERSION_MAJOR)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Convert the peer version to a TLS version - DTLS versions are
|
||||
* the 1's complement of TLS version numbers (but not the actual
|
||||
* protocol version numbers, that would be too sensible). Not to
|
||||
* mention that DTLSv1.0 is really equivalent to DTLSv1.1.
|
||||
*/
|
||||
peer_tls_version = ssl_dtls_to_tls_version(peer_ver);
|
||||
|
||||
/*
|
||||
* This may be a version that we do not know about, if it is
|
||||
* newer than DTLS1_2_VERSION (yes, less than is correct due
|
||||
* to the "clever" versioning scheme), use TLS1_2_VERSION.
|
||||
*/
|
||||
if (peer_tls_version == 0) {
|
||||
if (peer_ver < DTLS1_2_VERSION)
|
||||
peer_tls_version = TLS1_2_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
if (peer_tls_version >= TLS1_3_VERSION)
|
||||
shared_version = TLS1_3_VERSION;
|
||||
else if (peer_tls_version >= TLS1_2_VERSION)
|
||||
shared_version = TLS1_2_VERSION;
|
||||
else if (peer_tls_version >= TLS1_1_VERSION)
|
||||
shared_version = TLS1_1_VERSION;
|
||||
else if (peer_tls_version >= TLS1_VERSION)
|
||||
shared_version = TLS1_VERSION;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if (!ssl_supported_tls_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;
|
||||
|
||||
if (SSL_is_dtls(s)) {
|
||||
/*
|
||||
* The resulting shared version will by definition be something
|
||||
* that we know about. Switch back from TLS to DTLS.
|
||||
*/
|
||||
shared_version = ssl_tls_to_dtls_version(shared_version);
|
||||
if (shared_version == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_security_version(s, shared_version))
|
||||
return 0;
|
||||
|
||||
*max_ver = shared_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_check_version_from_server(SSL *s, uint16_t server_version)
|
||||
{
|
||||
uint16_t min_tls_version, max_tls_version, server_tls_version;
|
||||
|
||||
/* Ensure that the version selected by the server is valid. */
|
||||
|
||||
server_tls_version = server_version;
|
||||
if (SSL_is_dtls(s)) {
|
||||
server_tls_version = ssl_dtls_to_tls_version(server_version);
|
||||
if (server_tls_version == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ssl_supported_tls_version_range(s, &min_tls_version,
|
||||
&max_tls_version))
|
||||
return 0;
|
||||
|
||||
if (server_tls_version < min_tls_version ||
|
||||
server_tls_version > max_tls_version)
|
||||
return 0;
|
||||
|
||||
return ssl_security_version(s, server_tls_version);
|
||||
}
|
||||
|
||||
int
|
||||
ssl_legacy_stack_version(SSL *s, uint16_t version)
|
||||
{
|
||||
if (SSL_is_dtls(s))
|
||||
return version == DTLS1_VERSION || version == DTLS1_2_VERSION;
|
||||
|
||||
return version == TLS1_VERSION || version == TLS1_1_VERSION ||
|
||||
version == TLS1_2_VERSION;
|
||||
}
|
||||
415
externals/libressl/ssl/t1_enc.c
vendored
Normal file
415
externals/libressl/ssl/t1_enc.c
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
/* $OpenBSD: t1_enc.c,v 1.157 2022/11/26 16:08:56 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-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 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 <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include "dtls_local.h"
|
||||
#include "ssl_local.h"
|
||||
|
||||
void
|
||||
tls1_cleanup_key_block(SSL *s)
|
||||
{
|
||||
tls12_key_block_free(s->s3->hs.tls12.key_block);
|
||||
s->s3->hs.tls12.key_block = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS P_hash() data expansion function - see RFC 5246, section 5.
|
||||
*/
|
||||
static int
|
||||
tls1_P_hash(const EVP_MD *md, const unsigned char *secret, size_t secret_len,
|
||||
const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len,
|
||||
const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len,
|
||||
const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len)
|
||||
{
|
||||
unsigned char A1[EVP_MAX_MD_SIZE], hmac[EVP_MAX_MD_SIZE];
|
||||
size_t A1_len, hmac_len;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
EVP_PKEY *mac_key = NULL;
|
||||
int ret = 0;
|
||||
int chunk;
|
||||
size_t i;
|
||||
|
||||
chunk = EVP_MD_size(md);
|
||||
OPENSSL_assert(chunk >= 0);
|
||||
|
||||
if ((ctx = EVP_MD_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret, secret_len);
|
||||
if (mac_key == NULL)
|
||||
goto err;
|
||||
if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key))
|
||||
goto err;
|
||||
if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
|
||||
goto err;
|
||||
if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
|
||||
goto err;
|
||||
if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
|
||||
goto err;
|
||||
if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
|
||||
goto err;
|
||||
if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
|
||||
goto err;
|
||||
if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key))
|
||||
goto err;
|
||||
if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
|
||||
goto err;
|
||||
if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
|
||||
goto err;
|
||||
if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
|
||||
goto err;
|
||||
if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
|
||||
goto err;
|
||||
if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
|
||||
goto err;
|
||||
if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
|
||||
goto err;
|
||||
if (!EVP_DigestSignFinal(ctx, hmac, &hmac_len))
|
||||
goto err;
|
||||
|
||||
if (hmac_len > out_len)
|
||||
hmac_len = out_len;
|
||||
|
||||
for (i = 0; i < hmac_len; i++)
|
||||
out[i] ^= hmac[i];
|
||||
|
||||
out += hmac_len;
|
||||
out_len -= hmac_len;
|
||||
|
||||
if (out_len == 0)
|
||||
break;
|
||||
|
||||
if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key))
|
||||
goto err;
|
||||
if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
|
||||
goto err;
|
||||
if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(mac_key);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
|
||||
explicit_bzero(A1, sizeof(A1));
|
||||
explicit_bzero(hmac, sizeof(hmac));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len,
|
||||
const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len,
|
||||
const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len,
|
||||
const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
size_t half_len;
|
||||
|
||||
memset(out, 0, out_len);
|
||||
|
||||
if (!ssl_get_handshake_evp_md(s, &md))
|
||||
return (0);
|
||||
|
||||
if (EVP_MD_type(md) == NID_md5_sha1) {
|
||||
/*
|
||||
* Partition secret between MD5 and SHA1, then XOR result.
|
||||
* If the secret length is odd, a one byte overlap is used.
|
||||
*/
|
||||
half_len = secret_len - (secret_len / 2);
|
||||
if (!tls1_P_hash(EVP_md5(), secret, half_len, seed1, seed1_len,
|
||||
seed2, seed2_len, seed3, seed3_len, seed4, seed4_len,
|
||||
seed5, seed5_len, out, out_len))
|
||||
return (0);
|
||||
|
||||
secret += secret_len - half_len;
|
||||
if (!tls1_P_hash(EVP_sha1(), secret, half_len, seed1, seed1_len,
|
||||
seed2, seed2_len, seed3, seed3_len, seed4, seed4_len,
|
||||
seed5, seed5_len, out, out_len))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!tls1_P_hash(md, secret, secret_len, seed1, seed1_len,
|
||||
seed2, seed2_len, seed3, seed3_len, seed4, seed4_len,
|
||||
seed5, seed5_len, out, out_len))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len)
|
||||
{
|
||||
return tls1_PRF(s,
|
||||
s->session->master_key, s->session->master_key_length,
|
||||
TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
|
||||
s->s3->server_random, SSL3_RANDOM_SIZE,
|
||||
s->s3->client_random, SSL3_RANDOM_SIZE,
|
||||
NULL, 0, NULL, 0, key_block, key_block_len);
|
||||
}
|
||||
|
||||
static int
|
||||
tls1_change_cipher_state(SSL *s, int is_write)
|
||||
{
|
||||
CBS mac_key, key, iv;
|
||||
|
||||
/* Use client write keys on client write and server read. */
|
||||
if ((!s->server && is_write) || (s->server && !is_write)) {
|
||||
tls12_key_block_client_write(s->s3->hs.tls12.key_block,
|
||||
&mac_key, &key, &iv);
|
||||
} else {
|
||||
tls12_key_block_server_write(s->s3->hs.tls12.key_block,
|
||||
&mac_key, &key, &iv);
|
||||
}
|
||||
|
||||
if (!is_write) {
|
||||
if (!tls12_record_layer_change_read_cipher_state(s->rl,
|
||||
&mac_key, &key, &iv))
|
||||
goto err;
|
||||
if (SSL_is_dtls(s))
|
||||
dtls1_reset_read_seq_numbers(s);
|
||||
} else {
|
||||
if (!tls12_record_layer_change_write_cipher_state(s->rl,
|
||||
&mac_key, &key, &iv))
|
||||
goto err;
|
||||
}
|
||||
return (1);
|
||||
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_change_read_cipher_state(SSL *s)
|
||||
{
|
||||
return tls1_change_cipher_state(s, 0);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_change_write_cipher_state(SSL *s)
|
||||
{
|
||||
return tls1_change_cipher_state(s, 1);
|
||||
}
|
||||
|
||||
int
|
||||
tls1_setup_key_block(SSL *s)
|
||||
{
|
||||
struct tls12_key_block *key_block;
|
||||
int mac_type = NID_undef, mac_secret_size = 0;
|
||||
const EVP_CIPHER *cipher = NULL;
|
||||
const EVP_AEAD *aead = NULL;
|
||||
const EVP_MD *handshake_hash = NULL;
|
||||
const EVP_MD *mac_hash = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* XXX - callers should be changed so that they only call this
|
||||
* function once.
|
||||
*/
|
||||
if (s->s3->hs.tls12.key_block != NULL)
|
||||
return (1);
|
||||
|
||||
if (s->session->cipher &&
|
||||
(s->session->cipher->algorithm_mac & SSL_AEAD)) {
|
||||
if (!ssl_cipher_get_evp_aead(s->session, &aead)) {
|
||||
SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
/* XXX - mac_type and mac_secret_size are now unused. */
|
||||
if (!ssl_cipher_get_evp(s->session, &cipher, &mac_hash,
|
||||
&mac_type, &mac_secret_size)) {
|
||||
SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ssl_get_handshake_evp_md(s, &handshake_hash))
|
||||
return (0);
|
||||
|
||||
tls12_record_layer_set_aead(s->rl, aead);
|
||||
tls12_record_layer_set_cipher_hash(s->rl, cipher,
|
||||
handshake_hash, mac_hash);
|
||||
|
||||
if ((key_block = tls12_key_block_new()) == NULL)
|
||||
goto err;
|
||||
if (!tls12_key_block_generate(key_block, s, aead, cipher, mac_hash))
|
||||
goto err;
|
||||
|
||||
s->s3->hs.tls12.key_block = key_block;
|
||||
key_block = NULL;
|
||||
|
||||
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) &&
|
||||
s->method->version <= TLS1_VERSION) {
|
||||
/*
|
||||
* Enable vulnerability countermeasure for CBC ciphers with
|
||||
* known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
|
||||
*/
|
||||
s->s3->need_empty_fragments = 1;
|
||||
|
||||
if (s->session->cipher != NULL) {
|
||||
if (s->session->cipher->algorithm_enc == SSL_eNULL)
|
||||
s->s3->need_empty_fragments = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
if (s->session->cipher->algorithm_enc == SSL_RC4)
|
||||
s->s3->need_empty_fragments = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
tls12_key_block_free(key_block);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
1132
externals/libressl/ssl/t1_lib.c
vendored
Normal file
1132
externals/libressl/ssl/t1_lib.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
29
externals/libressl/ssl/tls12_internal.h
vendored
Normal file
29
externals/libressl/ssl/tls12_internal.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/* $OpenBSD: tls12_internal.h,v 1.1 2022/11/07 11:58:45 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 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_TLS12_INTERNAL_H
|
||||
#define HEADER_TLS12_INTERNAL_H
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
int tls12_exporter(SSL *s, const uint8_t *label, size_t label_len,
|
||||
const uint8_t *context_value, size_t context_value_len, int use_context,
|
||||
uint8_t *out, size_t out_len);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
295
externals/libressl/ssl/tls12_key_schedule.c
vendored
Normal file
295
externals/libressl/ssl/tls12_key_schedule.c
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
/* $OpenBSD: tls12_key_schedule.c,v 1.3 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2021 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 "bytestring.h"
|
||||
#include "ssl_local.h"
|
||||
#include "tls12_internal.h"
|
||||
|
||||
struct tls12_key_block {
|
||||
CBS client_write_mac_key;
|
||||
CBS server_write_mac_key;
|
||||
CBS client_write_key;
|
||||
CBS server_write_key;
|
||||
CBS client_write_iv;
|
||||
CBS server_write_iv;
|
||||
|
||||
uint8_t *key_block;
|
||||
size_t key_block_len;
|
||||
};
|
||||
|
||||
struct tls12_key_block *
|
||||
tls12_key_block_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct tls12_key_block));
|
||||
}
|
||||
|
||||
static void
|
||||
tls12_key_block_clear(struct tls12_key_block *kb)
|
||||
{
|
||||
CBS_init(&kb->client_write_mac_key, NULL, 0);
|
||||
CBS_init(&kb->server_write_mac_key, NULL, 0);
|
||||
CBS_init(&kb->client_write_key, NULL, 0);
|
||||
CBS_init(&kb->server_write_key, NULL, 0);
|
||||
CBS_init(&kb->client_write_iv, NULL, 0);
|
||||
CBS_init(&kb->server_write_iv, NULL, 0);
|
||||
|
||||
freezero(kb->key_block, kb->key_block_len);
|
||||
kb->key_block = NULL;
|
||||
kb->key_block_len = 0;
|
||||
}
|
||||
|
||||
void
|
||||
tls12_key_block_free(struct tls12_key_block *kb)
|
||||
{
|
||||
if (kb == NULL)
|
||||
return;
|
||||
|
||||
tls12_key_block_clear(kb);
|
||||
|
||||
freezero(kb, sizeof(struct tls12_key_block));
|
||||
}
|
||||
|
||||
void
|
||||
tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key,
|
||||
CBS *key, CBS *iv)
|
||||
{
|
||||
CBS_dup(&kb->client_write_mac_key, mac_key);
|
||||
CBS_dup(&kb->client_write_key, key);
|
||||
CBS_dup(&kb->client_write_iv, iv);
|
||||
}
|
||||
|
||||
void
|
||||
tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key,
|
||||
CBS *key, CBS *iv)
|
||||
{
|
||||
CBS_dup(&kb->server_write_mac_key, mac_key);
|
||||
CBS_dup(&kb->server_write_key, key);
|
||||
CBS_dup(&kb->server_write_iv, iv);
|
||||
}
|
||||
|
||||
int
|
||||
tls12_key_block_generate(struct tls12_key_block *kb, SSL *s,
|
||||
const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash)
|
||||
{
|
||||
size_t mac_key_len = 0, key_len = 0, iv_len = 0;
|
||||
uint8_t *key_block = NULL;
|
||||
size_t key_block_len = 0;
|
||||
CBS cbs;
|
||||
|
||||
/*
|
||||
* Generate a TLSv1.2 key block and partition into individual secrets,
|
||||
* as per RFC 5246 section 6.3.
|
||||
*/
|
||||
|
||||
tls12_key_block_clear(kb);
|
||||
|
||||
/* Must have AEAD or cipher/MAC pair. */
|
||||
if (aead == NULL && (cipher == NULL || mac_hash == NULL))
|
||||
goto err;
|
||||
|
||||
if (aead != NULL) {
|
||||
key_len = EVP_AEAD_key_length(aead);
|
||||
|
||||
/* AEAD fixed nonce length. */
|
||||
if (aead == EVP_aead_aes_128_gcm() ||
|
||||
aead == EVP_aead_aes_256_gcm())
|
||||
iv_len = 4;
|
||||
else if (aead == EVP_aead_chacha20_poly1305())
|
||||
iv_len = 12;
|
||||
else
|
||||
goto err;
|
||||
} else if (cipher != NULL && mac_hash != NULL) {
|
||||
/*
|
||||
* A negative integer return value will be detected via the
|
||||
* EVP_MAX_* checks against the size_t variables below.
|
||||
*/
|
||||
mac_key_len = EVP_MD_size(mac_hash);
|
||||
key_len = EVP_CIPHER_key_length(cipher);
|
||||
iv_len = EVP_CIPHER_iv_length(cipher);
|
||||
|
||||
/* Special handling for GOST... */
|
||||
if (EVP_MD_type(mac_hash) == NID_id_Gost28147_89_MAC)
|
||||
mac_key_len = 32;
|
||||
}
|
||||
|
||||
if (mac_key_len > EVP_MAX_MD_SIZE)
|
||||
goto err;
|
||||
if (key_len > EVP_MAX_KEY_LENGTH)
|
||||
goto err;
|
||||
if (iv_len > EVP_MAX_IV_LENGTH)
|
||||
goto err;
|
||||
|
||||
key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len;
|
||||
if ((key_block = calloc(1, key_block_len)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!tls1_generate_key_block(s, key_block, key_block_len))
|
||||
goto err;
|
||||
|
||||
kb->key_block = key_block;
|
||||
kb->key_block_len = key_block_len;
|
||||
key_block = NULL;
|
||||
key_block_len = 0;
|
||||
|
||||
/* Partition key block into individual secrets. */
|
||||
CBS_init(&cbs, kb->key_block, kb->key_block_len);
|
||||
if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len))
|
||||
goto err;
|
||||
if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len))
|
||||
goto err;
|
||||
if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len))
|
||||
goto err;
|
||||
if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len))
|
||||
goto err;
|
||||
if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len))
|
||||
goto err;
|
||||
if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len))
|
||||
goto err;
|
||||
if (CBS_len(&cbs) != 0)
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
tls12_key_block_clear(kb);
|
||||
freezero(key_block, key_block_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tls12_reserved_label {
|
||||
const char *label;
|
||||
size_t label_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* RFC 5705 section 6.
|
||||
*/
|
||||
static const struct tls12_reserved_label tls12_reserved_labels[] = {
|
||||
{
|
||||
.label = TLS_MD_CLIENT_FINISH_CONST,
|
||||
.label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE,
|
||||
},
|
||||
{
|
||||
.label = TLS_MD_SERVER_FINISH_CONST,
|
||||
.label_len = TLS_MD_SERVER_FINISH_CONST_SIZE,
|
||||
},
|
||||
{
|
||||
.label = TLS_MD_MASTER_SECRET_CONST,
|
||||
.label_len = TLS_MD_MASTER_SECRET_CONST_SIZE,
|
||||
},
|
||||
{
|
||||
.label = TLS_MD_KEY_EXPANSION_CONST,
|
||||
.label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE,
|
||||
},
|
||||
{
|
||||
.label = NULL,
|
||||
.label_len = 0,
|
||||
},
|
||||
};
|
||||
|
||||
int
|
||||
tls12_exporter(SSL *s, const uint8_t *label, size_t label_len,
|
||||
const uint8_t *context_value, size_t context_value_len, int use_context,
|
||||
uint8_t *out, size_t out_len)
|
||||
{
|
||||
uint8_t *data = NULL;
|
||||
size_t data_len = 0;
|
||||
CBB cbb, context;
|
||||
CBS seed;
|
||||
size_t i;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* RFC 5705 - Key Material Exporters for TLS.
|
||||
*/
|
||||
|
||||
memset(&cbb, 0, sizeof(cbb));
|
||||
|
||||
if (!SSL_is_init_finished(s)) {
|
||||
SSLerror(s, SSL_R_BAD_STATE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Due to exceptional design choices, we need to build a concatenation
|
||||
* of the label and the seed value, before checking for reserved
|
||||
* labels. This prevents a reserved label from being split across the
|
||||
* label and the seed (that includes the client random), which are
|
||||
* concatenated by the PRF.
|
||||
*/
|
||||
if (!CBB_init(&cbb, 0))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, label, label_len))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE))
|
||||
goto err;
|
||||
if (use_context) {
|
||||
if (!CBB_add_u16_length_prefixed(&cbb, &context))
|
||||
goto err;
|
||||
if (context_value_len > 0) {
|
||||
if (!CBB_add_bytes(&context, context_value,
|
||||
context_value_len))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!CBB_finish(&cbb, &data, &data_len))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Ensure that the block (label + seed) does not start with a reserved
|
||||
* label - in an ideal world we would ensure that the label has an
|
||||
* explicitly permitted prefix instead, but of course this also got
|
||||
* messed up by the standards.
|
||||
*/
|
||||
for (i = 0; tls12_reserved_labels[i].label != NULL; i++) {
|
||||
/* XXX - consider adding/using CBS_has_prefix(). */
|
||||
if (tls12_reserved_labels[i].label_len > data_len)
|
||||
goto err;
|
||||
if (memcmp(data, tls12_reserved_labels[i].label,
|
||||
tls12_reserved_labels[i].label_len) == 0) {
|
||||
SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
CBS_init(&seed, data, data_len);
|
||||
if (!CBS_skip(&seed, label_len))
|
||||
goto err;
|
||||
|
||||
if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
|
||||
label, label_len, CBS_data(&seed), CBS_len(&seed), NULL, 0, NULL, 0,
|
||||
NULL, 0, out, out_len))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
freezero(data, data_len);
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
118
externals/libressl/ssl/tls12_lib.c
vendored
Normal file
118
externals/libressl/ssl/tls12_lib.c
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/* $OpenBSD: tls12_lib.c,v 1.6 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2021 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_local.h"
|
||||
|
||||
static int
|
||||
tls12_finished_verify_data(SSL *s, const char *finished_label,
|
||||
size_t finished_label_len, uint8_t *verify_data, size_t verify_data_len,
|
||||
size_t *out_len)
|
||||
{
|
||||
uint8_t transcript_hash[EVP_MAX_MD_SIZE];
|
||||
size_t transcript_hash_len;
|
||||
|
||||
*out_len = 0;
|
||||
|
||||
if (s->session->master_key_length == 0)
|
||||
return 0;
|
||||
|
||||
if (verify_data_len < TLS1_FINISH_MAC_LENGTH)
|
||||
return 0;
|
||||
|
||||
if (!tls1_transcript_hash_value(s, transcript_hash,
|
||||
sizeof(transcript_hash), &transcript_hash_len))
|
||||
return 0;
|
||||
|
||||
if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
|
||||
finished_label, finished_label_len, transcript_hash,
|
||||
transcript_hash_len, NULL, 0, NULL, 0, NULL, 0, verify_data,
|
||||
TLS1_FINISH_MAC_LENGTH))
|
||||
return 0;
|
||||
|
||||
*out_len = TLS1_FINISH_MAC_LENGTH;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_client_finished_verify_data(SSL *s, uint8_t *verify_data,
|
||||
size_t verify_data_len, size_t *out_len)
|
||||
{
|
||||
return tls12_finished_verify_data(s, TLS_MD_CLIENT_FINISH_CONST,
|
||||
TLS_MD_CLIENT_FINISH_CONST_SIZE, verify_data, verify_data_len,
|
||||
out_len);
|
||||
}
|
||||
|
||||
static int
|
||||
tls12_server_finished_verify_data(SSL *s, uint8_t *verify_data,
|
||||
size_t verify_data_len, size_t *out_len)
|
||||
{
|
||||
return tls12_finished_verify_data(s, TLS_MD_SERVER_FINISH_CONST,
|
||||
TLS_MD_SERVER_FINISH_CONST_SIZE, verify_data, verify_data_len,
|
||||
out_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls12_derive_finished(SSL *s)
|
||||
{
|
||||
if (!s->server) {
|
||||
return tls12_client_finished_verify_data(s,
|
||||
s->s3->hs.finished, sizeof(s->s3->hs.finished),
|
||||
&s->s3->hs.finished_len);
|
||||
} else {
|
||||
return tls12_server_finished_verify_data(s,
|
||||
s->s3->hs.finished, sizeof(s->s3->hs.finished),
|
||||
&s->s3->hs.finished_len);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tls12_derive_peer_finished(SSL *s)
|
||||
{
|
||||
if (s->server) {
|
||||
return tls12_client_finished_verify_data(s,
|
||||
s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished),
|
||||
&s->s3->hs.peer_finished_len);
|
||||
} else {
|
||||
return tls12_server_finished_verify_data(s,
|
||||
s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished),
|
||||
&s->s3->hs.peer_finished_len);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret,
|
||||
size_t premaster_secret_len)
|
||||
{
|
||||
s->session->master_key_length = 0;
|
||||
|
||||
if (premaster_secret_len == 0)
|
||||
return 0;
|
||||
|
||||
CTASSERT(sizeof(s->session->master_key) == SSL_MAX_MASTER_KEY_LENGTH);
|
||||
|
||||
if (!tls1_PRF(s, premaster_secret, premaster_secret_len,
|
||||
TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
|
||||
s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0,
|
||||
s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0,
|
||||
s->session->master_key, sizeof(s->session->master_key)))
|
||||
return 0;
|
||||
|
||||
s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH;
|
||||
|
||||
return 1;
|
||||
}
|
||||
1337
externals/libressl/ssl/tls12_record_layer.c
vendored
Normal file
1337
externals/libressl/ssl/tls12_record_layer.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1066
externals/libressl/ssl/tls13_client.c
vendored
Normal file
1066
externals/libressl/ssl/tls13_client.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
99
externals/libressl/ssl/tls13_error.c
vendored
Normal file
99
externals/libressl/ssl/tls13_error.c
vendored
Normal 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);
|
||||
}
|
||||
721
externals/libressl/ssl/tls13_handshake.c
vendored
Normal file
721
externals/libressl/ssl/tls13_handshake.c
vendored
Normal file
@@ -0,0 +1,721 @@
|
||||
/* $OpenBSD: tls13_handshake.c,v 1.72 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018-2021 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_local.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 int tls13_handshake_set_legacy_state(struct tls13_ctx *ctx);
|
||||
static int tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx);
|
||||
|
||||
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";
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_end_of_flight(struct tls13_ctx *ctx,
|
||||
const struct tls13_handshake_action *previous)
|
||||
{
|
||||
const struct tls13_handshake_action *current;
|
||||
|
||||
if ((current = tls13_handshake_active_action(ctx)) == NULL)
|
||||
return 1;
|
||||
|
||||
return current->sender != previous->sender;
|
||||
}
|
||||
|
||||
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 sending;
|
||||
int ret;
|
||||
|
||||
if (!ctx->handshake_started) {
|
||||
/*
|
||||
* Set legacy state to connect/accept and call info callback
|
||||
* to signal that the handshake started.
|
||||
*/
|
||||
if (!tls13_handshake_set_legacy_state(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!tls13_handshake_legacy_info_callback(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
ctx->handshake_started = 1;
|
||||
|
||||
/* Set legacy state for initial ClientHello read or write. */
|
||||
if (!tls13_handshake_set_legacy_state(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((action = tls13_handshake_active_action(ctx)) == NULL)
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (ctx->need_flush) {
|
||||
if ((ret = tls13_record_layer_flush(ctx->rl)) !=
|
||||
TLS13_IO_SUCCESS)
|
||||
return ret;
|
||||
ctx->need_flush = 0;
|
||||
}
|
||||
|
||||
if (action->handshake_complete) {
|
||||
ctx->handshake_completed = 1;
|
||||
tls13_record_layer_handshake_completed(ctx->rl);
|
||||
|
||||
if (!tls13_handshake_set_legacy_state(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
if (!tls13_handshake_legacy_info_callback(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
sending = action->sender == ctx->mode;
|
||||
|
||||
DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode),
|
||||
sending ? "sending" : "receiving",
|
||||
tls13_handshake_message_name(action->handshake_type));
|
||||
|
||||
if (ctx->alert != 0)
|
||||
return tls13_send_alert(ctx->rl, ctx->alert);
|
||||
|
||||
if (sending)
|
||||
ret = tls13_handshake_send_action(ctx, action);
|
||||
else
|
||||
ret = tls13_handshake_recv_action(ctx, action);
|
||||
|
||||
if (ctx->alert != 0)
|
||||
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_legacy_info_callback(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (!tls13_handshake_advance_state_machine(ctx))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
if (sending)
|
||||
ctx->need_flush = tls13_handshake_end_of_flight(ctx,
|
||||
action);
|
||||
|
||||
if (!tls13_handshake_set_legacy_state(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->tls13.transcript_hash,
|
||||
sizeof(ctx->hs->tls13.transcript_hash),
|
||||
&ctx->hs->tls13.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->tls13.transcript_hash,
|
||||
sizeof(ctx->hs->tls13.transcript_hash),
|
||||
&ctx->hs->tls13.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->version < TLS1_3_VERSION)
|
||||
return TLS13_IO_USE_LEGACY;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct tls13_handshake_legacy_state {
|
||||
int recv;
|
||||
int send;
|
||||
};
|
||||
|
||||
static const struct tls13_handshake_legacy_state legacy_states[] = {
|
||||
[CLIENT_HELLO] = {
|
||||
.recv = SSL3_ST_SR_CLNT_HELLO_A,
|
||||
.send = SSL3_ST_CW_CLNT_HELLO_A,
|
||||
},
|
||||
[SERVER_HELLO_RETRY_REQUEST] = {
|
||||
.recv = SSL3_ST_CR_SRVR_HELLO_A,
|
||||
.send = SSL3_ST_SW_SRVR_HELLO_A,
|
||||
},
|
||||
[CLIENT_HELLO_RETRY] = {
|
||||
.recv = SSL3_ST_SR_CLNT_HELLO_A,
|
||||
.send = SSL3_ST_CW_CLNT_HELLO_A,
|
||||
},
|
||||
[SERVER_HELLO] = {
|
||||
.recv = SSL3_ST_CR_SRVR_HELLO_A,
|
||||
.send = SSL3_ST_SW_SRVR_HELLO_A,
|
||||
},
|
||||
[SERVER_ENCRYPTED_EXTENSIONS] = {
|
||||
.send = 0,
|
||||
.recv = 0,
|
||||
},
|
||||
[SERVER_CERTIFICATE_REQUEST] = {
|
||||
.recv = SSL3_ST_CR_CERT_REQ_A,
|
||||
.send = SSL3_ST_SW_CERT_REQ_A,
|
||||
},
|
||||
[SERVER_CERTIFICATE] = {
|
||||
.recv = SSL3_ST_CR_CERT_A,
|
||||
.send = SSL3_ST_SW_CERT_A,
|
||||
},
|
||||
[SERVER_CERTIFICATE_VERIFY] = {
|
||||
.send = 0,
|
||||
.recv = 0,
|
||||
},
|
||||
[SERVER_FINISHED] = {
|
||||
.recv = SSL3_ST_CR_FINISHED_A,
|
||||
.send = SSL3_ST_SW_FINISHED_A,
|
||||
},
|
||||
[CLIENT_END_OF_EARLY_DATA] = {
|
||||
.send = 0,
|
||||
.recv = 0,
|
||||
},
|
||||
[CLIENT_CERTIFICATE] = {
|
||||
.recv = SSL3_ST_SR_CERT_VRFY_A,
|
||||
.send = SSL3_ST_CW_CERT_VRFY_B,
|
||||
},
|
||||
[CLIENT_CERTIFICATE_VERIFY] = {
|
||||
.send = 0,
|
||||
.recv = 0,
|
||||
},
|
||||
[CLIENT_FINISHED] = {
|
||||
.recv = SSL3_ST_SR_FINISHED_A,
|
||||
.send = SSL3_ST_CW_FINISHED_A,
|
||||
},
|
||||
[APPLICATION_DATA] = {
|
||||
.recv = 0,
|
||||
.send = 0,
|
||||
},
|
||||
};
|
||||
|
||||
CTASSERT(sizeof(state_machine) / sizeof(state_machine[0]) ==
|
||||
sizeof(legacy_states) / sizeof(legacy_states[0]));
|
||||
|
||||
static int
|
||||
tls13_handshake_legacy_state(struct tls13_ctx *ctx, int *out_state)
|
||||
{
|
||||
const struct tls13_handshake_action *action;
|
||||
enum tls13_message_type mt;
|
||||
|
||||
*out_state = 0;
|
||||
|
||||
if (!ctx->handshake_started) {
|
||||
if (ctx->mode == TLS13_HS_CLIENT)
|
||||
*out_state = SSL_ST_CONNECT;
|
||||
else
|
||||
*out_state = SSL_ST_ACCEPT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ctx->handshake_completed) {
|
||||
*out_state = SSL_ST_OK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((mt = tls13_handshake_active_state(ctx)) == INVALID)
|
||||
return 0;
|
||||
|
||||
if ((action = tls13_handshake_active_action(ctx)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (action->sender == ctx->mode)
|
||||
*out_state = legacy_states[mt].send;
|
||||
else
|
||||
*out_state = legacy_states[mt].recv;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_info_position(struct tls13_ctx *ctx)
|
||||
{
|
||||
if (!ctx->handshake_started)
|
||||
return TLS13_INFO_HANDSHAKE_STARTED;
|
||||
|
||||
if (ctx->handshake_completed)
|
||||
return TLS13_INFO_HANDSHAKE_COMPLETED;
|
||||
|
||||
if (ctx->mode == TLS13_HS_CLIENT)
|
||||
return TLS13_INFO_CONNECT_LOOP;
|
||||
else
|
||||
return TLS13_INFO_ACCEPT_LOOP;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_legacy_info_callback(struct tls13_ctx *ctx)
|
||||
{
|
||||
int state, where;
|
||||
|
||||
if (!tls13_handshake_legacy_state(ctx, &state))
|
||||
return 0;
|
||||
|
||||
/* Do nothing if there's no corresponding legacy state. */
|
||||
if (state == 0)
|
||||
return 1;
|
||||
|
||||
if (ctx->info_cb != NULL) {
|
||||
where = tls13_handshake_info_position(ctx);
|
||||
ctx->info_cb(ctx, where, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_handshake_set_legacy_state(struct tls13_ctx *ctx)
|
||||
{
|
||||
int state;
|
||||
|
||||
if (!tls13_handshake_legacy_state(ctx, &state))
|
||||
return 0;
|
||||
|
||||
/* Do nothing if there's no corresponding legacy state. */
|
||||
if (state == 0)
|
||||
return 1;
|
||||
|
||||
ctx->hs->state = state;
|
||||
|
||||
return 1;
|
||||
}
|
||||
54
externals/libressl/ssl/tls13_handshake.h
vendored
Normal file
54
externals/libressl/ssl/tls13_handshake.h
vendored
Normal 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 */
|
||||
188
externals/libressl/ssl/tls13_handshake_msg.c
vendored
Normal file
188
externals/libressl/ssl/tls13_handshake_msg.c
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/* $OpenBSD: tls13_handshake_msg.c,v 1.6 2022/07/22 19:33:53 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 "bytestring.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 tls_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 = tls_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;
|
||||
|
||||
tls_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);
|
||||
}
|
||||
|
||||
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 = tls_buffer_extend(msg->buf,
|
||||
TLS13_HANDSHAKE_MSG_HEADER_LEN,
|
||||
tls13_handshake_msg_read_cb, rl)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls_buffer_data(msg->buf, &cbs))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
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 = tls_buffer_extend(msg->buf,
|
||||
TLS13_HANDSHAKE_MSG_HEADER_LEN + msg->msg_len,
|
||||
tls13_handshake_msg_read_cb, rl)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls_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;
|
||||
}
|
||||
443
externals/libressl/ssl/tls13_internal.h
vendored
Normal file
443
externals/libressl/ssl/tls13_internal.h
vendored
Normal file
@@ -0,0 +1,443 @@
|
||||
/* $OpenBSD: tls13_internal.h,v 1.101 2022/07/24 14:28:16 jsing 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"
|
||||
#include "tls_internal.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
|
||||
#define TLS13_INFO_ACCEPT_LOOP SSL_CB_ACCEPT_LOOP
|
||||
#define TLS13_INFO_CONNECT_LOOP SSL_CB_CONNECT_LOOP
|
||||
#define TLS13_INFO_ACCEPT_EXIT SSL_CB_ACCEPT_EXIT
|
||||
#define TLS13_INFO_CONNECT_EXIT SSL_CB_CONNECT_EXIT
|
||||
|
||||
typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg);
|
||||
typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg);
|
||||
typedef void (*tls13_phh_sent_cb)(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);
|
||||
|
||||
/*
|
||||
* PSK support.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Known PskKeyExchangeMode values.
|
||||
* https://www.iana.org/assignments/tls-parameters/#tls-pskkeyexchangemode
|
||||
*/
|
||||
#define TLS13_PSK_KE 0
|
||||
#define TLS13_PSK_DHE_KE 1
|
||||
|
||||
/*
|
||||
* 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;
|
||||
};
|
||||
|
||||
int tls13_secret_init(struct tls13_secret *secret, size_t len);
|
||||
void tls13_secret_cleanup(struct tls13_secret *secret);
|
||||
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_hkdf_expand_label_with_length(struct tls13_secret *out,
|
||||
const EVP_MD *digest, const struct tls13_secret *secret,
|
||||
const uint8_t *label, size_t label_len, const struct tls13_secret *context);
|
||||
|
||||
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);
|
||||
int tls13_derive_secret_with_label_length(struct tls13_secret *out,
|
||||
const EVP_MD *digest, const struct tls13_secret *secret,
|
||||
const uint8_t *label, size_t label_len, 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);
|
||||
|
||||
/*
|
||||
* Record Layer.
|
||||
*/
|
||||
struct tls13_record_layer;
|
||||
|
||||
struct tls13_record_layer_callbacks {
|
||||
/* Wire callbacks. */
|
||||
tls_read_cb wire_read;
|
||||
tls_write_cb wire_write;
|
||||
tls_flush_cb wire_flush;
|
||||
|
||||
/* Interceptors. */
|
||||
tls_handshake_read_cb handshake_read;
|
||||
tls_handshake_write_cb handshake_write;
|
||||
tls_traffic_key_cb set_read_traffic_key;
|
||||
tls_traffic_key_cb set_write_traffic_key;
|
||||
tls_alert_send_cb alert_send;
|
||||
|
||||
/* Notification callbacks. */
|
||||
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_set_callbacks(struct tls13_record_layer *rl,
|
||||
const struct tls13_record_layer_callbacks *callbacks, void *cb_arg);
|
||||
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_rcontent(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, enum ssl_encryption_level_t read_level);
|
||||
int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
|
||||
struct tls13_secret *write_key, enum ssl_encryption_level_t write_level);
|
||||
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_record_layer_flush(struct tls13_record_layer *rl);
|
||||
|
||||
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);
|
||||
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_st *hs;
|
||||
uint8_t mode;
|
||||
struct tls13_handshake_stage handshake_stage;
|
||||
int handshake_started;
|
||||
int handshake_completed;
|
||||
int need_flush;
|
||||
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, SSL *ssl);
|
||||
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);
|
||||
|
||||
void tls13_alert_received_cb(uint8_t alert_desc, void *arg);
|
||||
void tls13_alert_sent_cb(uint8_t alert_desc, void *arg);
|
||||
ssize_t tls13_phh_received_cb(void *cb_arg);
|
||||
void tls13_phh_done_cb(void *cb_arg);
|
||||
|
||||
int tls13_quic_init(struct tls13_ctx *ctx);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
ssize_t tls13_legacy_wire_flush_cb(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__)
|
||||
|
||||
int tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len,
|
||||
const uint8_t *context_value, size_t context_value_len, uint8_t *out,
|
||||
size_t out_len);
|
||||
|
||||
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
|
||||
458
externals/libressl/ssl/tls13_key_schedule.c
vendored
Normal file
458
externals/libressl/ssl/tls13_key_schedule.c
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
/* $OpenBSD: tls13_key_schedule.c,v 1.18 2022/11/26 16:08:56 tb 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 "ssl_local.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
int
|
||||
tls13_secret_init(struct tls13_secret *secret, size_t len)
|
||||
{
|
||||
if (secret->data != NULL)
|
||||
return 0;
|
||||
|
||||
if ((secret->data = calloc(1, len)) == NULL)
|
||||
return 0;
|
||||
secret->len = len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_secret_cleanup(struct tls13_secret *secret)
|
||||
{
|
||||
freezero(secret->data, secret->len);
|
||||
secret->data = NULL;
|
||||
secret->len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 (!tls13_secret_init(&secrets->zeros, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->empty_hash, hash_length))
|
||||
goto err;
|
||||
|
||||
if (!tls13_secret_init(&secrets->extracted_early, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->binder_key, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->client_early_traffic, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->early_exporter_master, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->derived_early, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->extracted_handshake, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->derived_handshake, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->extracted_master, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->client_application_traffic, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->server_application_traffic, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->exporter_master, hash_length))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&secrets->resumption_master, hash_length))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_secrets_destroy(struct tls13_secrets *secrets)
|
||||
{
|
||||
if (secrets == NULL)
|
||||
return;
|
||||
|
||||
/* you can never be too sure :) */
|
||||
tls13_secret_cleanup(&secrets->zeros);
|
||||
tls13_secret_cleanup(&secrets->empty_hash);
|
||||
|
||||
tls13_secret_cleanup(&secrets->extracted_early);
|
||||
tls13_secret_cleanup(&secrets->binder_key);
|
||||
tls13_secret_cleanup(&secrets->client_early_traffic);
|
||||
tls13_secret_cleanup(&secrets->early_exporter_master);
|
||||
tls13_secret_cleanup(&secrets->derived_early);
|
||||
tls13_secret_cleanup(&secrets->extracted_handshake);
|
||||
tls13_secret_cleanup(&secrets->client_handshake_traffic);
|
||||
tls13_secret_cleanup(&secrets->server_handshake_traffic);
|
||||
tls13_secret_cleanup(&secrets->derived_handshake);
|
||||
tls13_secret_cleanup(&secrets->extracted_master);
|
||||
tls13_secret_cleanup(&secrets->client_application_traffic);
|
||||
tls13_secret_cleanup(&secrets->server_application_traffic);
|
||||
tls13_secret_cleanup(&secrets->exporter_master);
|
||||
tls13_secret_cleanup(&secrets->resumption_master);
|
||||
|
||||
freezero(secrets, sizeof(struct tls13_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)
|
||||
{
|
||||
return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
|
||||
strlen(label), context);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_hkdf_expand_label_with_length(struct tls13_secret *out,
|
||||
const EVP_MD *digest, const struct tls13_secret *secret,
|
||||
const uint8_t *label, size_t label_len, const struct tls13_secret *context)
|
||||
{
|
||||
const char tls13_plabel[] = "tls13 ";
|
||||
uint8_t *hkdf_label = NULL;
|
||||
size_t hkdf_label_len;
|
||||
CBB cbb, child;
|
||||
int ret;
|
||||
|
||||
if (!CBB_init(&cbb, 256))
|
||||
goto err;
|
||||
|
||||
if (out->data == NULL || out->len == 0)
|
||||
goto err;
|
||||
|
||||
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, label_len))
|
||||
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);
|
||||
}
|
||||
|
||||
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_secret_with_label_length(struct tls13_secret *out,
|
||||
const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label,
|
||||
size_t label_len, const struct tls13_secret *context)
|
||||
{
|
||||
return tls13_hkdf_expand_label_with_length(out, digest, secret, label,
|
||||
label_len, 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);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_exporter(struct tls13_ctx *ctx, const uint8_t *label, size_t label_len,
|
||||
const uint8_t *context_value, size_t context_value_len, uint8_t *out,
|
||||
size_t out_len)
|
||||
{
|
||||
struct tls13_secret context, export_out, export_secret;
|
||||
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned int md_out_len;
|
||||
int md_len;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* RFC 8446 Section 7.5.
|
||||
*/
|
||||
|
||||
memset(&context, 0, sizeof(context));
|
||||
memset(&export_secret, 0, sizeof(export_secret));
|
||||
|
||||
export_out.data = out;
|
||||
export_out.len = out_len;
|
||||
|
||||
if (!ctx->handshake_completed)
|
||||
return 0;
|
||||
|
||||
md_len = EVP_MD_size(secrets->digest);
|
||||
if (md_len <= 0 || md_len > EVP_MAX_MD_SIZE)
|
||||
goto err;
|
||||
|
||||
if (!tls13_secret_init(&export_secret, md_len))
|
||||
goto err;
|
||||
if (!tls13_secret_init(&context, md_len))
|
||||
goto err;
|
||||
|
||||
/* In TLSv1.3 no context is equivalent to an empty context. */
|
||||
if (context_value == NULL) {
|
||||
context_value = "";
|
||||
context_value_len = 0;
|
||||
}
|
||||
|
||||
if ((md_ctx = EVP_MD_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!EVP_DigestInit_ex(md_ctx, secrets->digest, NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md_ctx, context_value, context_value_len))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(md_ctx, context.data, &md_out_len))
|
||||
goto err;
|
||||
if (md_len != md_out_len)
|
||||
goto err;
|
||||
|
||||
if (!tls13_derive_secret_with_label_length(&export_secret,
|
||||
secrets->digest, &secrets->exporter_master, label, label_len,
|
||||
&secrets->empty_hash))
|
||||
goto err;
|
||||
|
||||
if (!tls13_hkdf_expand_label(&export_out, secrets->digest,
|
||||
&export_secret, "exporter", &context))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
tls13_secret_cleanup(&context);
|
||||
tls13_secret_cleanup(&export_secret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
556
externals/libressl/ssl/tls13_legacy.c
vendored
Normal file
556
externals/libressl/ssl/tls13_legacy.c
vendored
Normal file
@@ -0,0 +1,556 @@
|
||||
/* $OpenBSD: tls13_legacy.c,v 1.40 2022/11/26 16:08:56 tb 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_local.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
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->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 (n == 0)
|
||||
return TLS13_IO_EOF;
|
||||
|
||||
if (ERR_peek_error() == 0 && errno != 0)
|
||||
SYSerror(errno);
|
||||
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
if (n == len)
|
||||
ssl->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->rwstate = SSL_WRITING;
|
||||
errno = 0;
|
||||
|
||||
if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
|
||||
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->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 ssize_t
|
||||
tls13_legacy_wire_flush(SSL *ssl)
|
||||
{
|
||||
if (BIO_flush(ssl->wbio) <= 0) {
|
||||
if (BIO_should_write(ssl->wbio))
|
||||
return TLS13_IO_WANT_POLLOUT;
|
||||
|
||||
if (ERR_peek_error() == 0 && errno != 0)
|
||||
SYSerror(errno);
|
||||
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_legacy_wire_flush_cb(void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
|
||||
return tls13_legacy_wire_flush(ctx->ssl);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_error(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->tls13;
|
||||
int reason = SSL_R_UNKNOWN;
|
||||
|
||||
/* If we received a fatal alert we already put an error on the stack. */
|
||||
if (ssl->s3->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->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->rwstate = SSL_READING;
|
||||
return -1;
|
||||
|
||||
case TLS13_IO_WANT_POLLOUT:
|
||||
BIO_set_retry_write(ssl->wbio);
|
||||
ssl->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->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->tls13;
|
||||
ssize_t ret;
|
||||
|
||||
if (ctx == NULL || !ctx->handshake_completed) {
|
||||
if ((ret = ssl->handshake_func(ssl)) <= 0)
|
||||
return ret;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN);
|
||||
}
|
||||
|
||||
tls13_record_layer_set_retry_after_phh(ctx->rl,
|
||||
(ctx->ssl->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->tls13;
|
||||
const uint8_t *buf = vbuf;
|
||||
size_t n, sent;
|
||||
ssize_t ret;
|
||||
|
||||
if (ctx == NULL || !ctx->handshake_completed) {
|
||||
if ((ret = ssl->handshake_func(ssl)) <= 0)
|
||||
return ret;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
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->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 = ssl->s3->wnum;
|
||||
if (len < sent) {
|
||||
SSLerror(ssl, SSL_R_BAD_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
n = len - sent;
|
||||
for (;;) {
|
||||
if (n == 0) {
|
||||
ssl->s3->wnum = 0;
|
||||
return sent;
|
||||
}
|
||||
if ((ret = tls13_write_application_data(ctx->rl,
|
||||
&buf[sent], n)) <= 0) {
|
||||
ssl->s3->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;
|
||||
CBB cbb, fragment;
|
||||
CBS cbs;
|
||||
|
||||
memset(&cbb, 0, sizeof(cbb));
|
||||
|
||||
s->method = tls_legacy_method();
|
||||
|
||||
if (!ssl3_setup_init_buffer(s))
|
||||
goto err;
|
||||
if (!ssl3_setup_buffers(s))
|
||||
goto err;
|
||||
if (!ssl_init_wbio_buffer(s, 1))
|
||||
goto err;
|
||||
|
||||
/* Stash any unprocessed data from the last record. */
|
||||
tls13_record_layer_rcontent(ctx->rl, &cbs);
|
||||
if (CBS_len(&cbs) > 0) {
|
||||
if (!CBB_init_fixed(&cbb, s->s3->rbuf.buf,
|
||||
s->s3->rbuf.len))
|
||||
goto err;
|
||||
if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
|
||||
goto err;
|
||||
if (!CBB_add_u16(&cbb, TLS1_2_VERSION))
|
||||
goto err;
|
||||
if (!CBB_add_u16_length_prefixed(&cbb, &fragment))
|
||||
goto err;
|
||||
if (!CBB_add_bytes(&fragment, CBS_data(&cbs), CBS_len(&cbs)))
|
||||
goto err;
|
||||
if (!CBB_finish(&cbb, NULL, NULL))
|
||||
goto err;
|
||||
|
||||
s->s3->rbuf.offset = SSL3_RT_HEADER_LENGTH;
|
||||
s->s3->rbuf.left = CBS_len(&cbs);
|
||||
s->s3->rrec.type = SSL3_RT_HANDSHAKE;
|
||||
s->s3->rrec.length = CBS_len(&cbs);
|
||||
s->rstate = SSL_ST_READ_BODY;
|
||||
s->packet = s->s3->rbuf.buf;
|
||||
s->packet_length = SSL3_RT_HEADER_LENGTH;
|
||||
s->mac_packet = 1;
|
||||
}
|
||||
|
||||
/* Stash the current handshake message. */
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
if (!BUF_MEM_grow_clean(s->init_buf, CBS_len(&cbs)))
|
||||
goto err;
|
||||
if (!CBS_write_bytes(&cbs, s->init_buf->data,
|
||||
s->init_buf->length, NULL))
|
||||
goto err;
|
||||
|
||||
s->s3->hs.tls12.reuse_message = 1;
|
||||
s->s3->hs.tls12.message_type = tls13_handshake_msg_type(ctx->hs_msg);
|
||||
s->s3->hs.tls12.message_size = CBS_len(&cbs) - SSL3_HM_HEADER_LENGTH;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
CBB_cleanup(&cbb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_use_legacy_client(struct tls13_ctx *ctx)
|
||||
{
|
||||
SSL *s = ctx->ssl;
|
||||
|
||||
if (!tls13_use_legacy_stack(ctx))
|
||||
return 0;
|
||||
|
||||
s->handshake_func = s->method->ssl_connect;
|
||||
s->version = s->method->max_tls_version;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_use_legacy_server(struct tls13_ctx *ctx)
|
||||
{
|
||||
SSL *s = ctx->ssl;
|
||||
|
||||
if (!tls13_use_legacy_stack(ctx))
|
||||
return 0;
|
||||
|
||||
s->handshake_func = s->method->ssl_accept;
|
||||
s->version = s->method->max_tls_version;
|
||||
s->server = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_accept(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->tls13;
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
if ((ctx = tls13_ctx_new(TLS13_HS_SERVER, ssl)) == NULL) {
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
if (!tls13_server_init(ctx)) {
|
||||
if (ERR_peek_error() == 0)
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
ret = tls13_server_accept(ctx);
|
||||
if (ret == TLS13_IO_USE_LEGACY)
|
||||
return ssl->method->ssl_accept(ssl);
|
||||
|
||||
ret = tls13_legacy_return_code(ssl, ret);
|
||||
|
||||
if (ctx->info_cb != NULL)
|
||||
ctx->info_cb(ctx, TLS13_INFO_ACCEPT_EXIT, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_connect(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->tls13;
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL) {
|
||||
if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT, ssl)) == NULL) {
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
if (!tls13_client_init(ctx)) {
|
||||
if (ERR_peek_error() == 0)
|
||||
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
ret = tls13_client_connect(ctx);
|
||||
if (ret == TLS13_IO_USE_LEGACY)
|
||||
return ssl->method->ssl_connect(ssl);
|
||||
|
||||
ret = tls13_legacy_return_code(ssl, ret);
|
||||
|
||||
if (ctx->info_cb != NULL)
|
||||
ctx->info_cb(ctx, TLS13_INFO_CONNECT_EXIT, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
tls13_legacy_shutdown(SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = ssl->tls13;
|
||||
uint8_t buf[512]; /* XXX */
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
* We need to return 0 at the point that we have completed sending a
|
||||
* close-notify. We return 1 when we have sent and received close-notify
|
||||
* alerts. All other cases, including EOF, return -1 and set internal
|
||||
* state appropriately.
|
||||
*/
|
||||
if (ctx == NULL || ssl->quiet_shutdown) {
|
||||
ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!ctx->close_notify_sent) {
|
||||
/* Enqueue and send close notify. */
|
||||
if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) {
|
||||
ssl->shutdown |= SSL_SENT_SHUTDOWN;
|
||||
if ((ret = tls13_send_alert(ctx->rl,
|
||||
TLS13_ALERT_CLOSE_NOTIFY)) < 0)
|
||||
return tls13_legacy_return_code(ssl, ret);
|
||||
}
|
||||
ret = tls13_record_layer_send_pending(ctx->rl);
|
||||
if (ret == TLS13_IO_EOF)
|
||||
return -1;
|
||||
if (ret != 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;
|
||||
}
|
||||
}
|
||||
|
||||
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 *s = ctx->ssl;
|
||||
|
||||
if (ssl_ctx->tlsext_servername_callback == NULL)
|
||||
ssl_ctx = s->initial_ctx;
|
||||
if (ssl_ctx->tlsext_servername_callback == NULL)
|
||||
return 1;
|
||||
|
||||
ret = ssl_ctx->tlsext_servername_callback(s, &legacy_alert,
|
||||
ssl_ctx->tlsext_servername_arg);
|
||||
|
||||
/*
|
||||
* Ignore SSL_TLSEXT_ERR_ALERT_WARNING returns to match OpenSSL's
|
||||
* behavior: the only warning alerts in TLSv1.3 are close_notify and
|
||||
* user_canceled, neither of which should be returned by the callback.
|
||||
*/
|
||||
if (ret == SSL_TLSEXT_ERR_ALERT_FATAL) {
|
||||
if (legacy_alert >= 0 && legacy_alert <= 255)
|
||||
*alert = legacy_alert;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
701
externals/libressl/ssl/tls13_lib.c
vendored
Normal file
701
externals/libressl/ssl/tls13_lib.c
vendored
Normal file
@@ -0,0 +1,701 @@
|
||||
/* $OpenBSD: tls13_lib.c,v 1.76 2022/11/26 16:08:56 tb 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_local.h"
|
||||
#include "ssl_tlsext.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
/*
|
||||
* RFC 8446, section 4.6.1. Servers must not indicate a lifetime longer than
|
||||
* 7 days and clients must not cache tickets for longer than 7 days.
|
||||
*/
|
||||
|
||||
#define TLS13_MAX_TICKET_LIFETIME (7 * 24 * 3600)
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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->shutdown |= SSL_RECEIVED_SHUTDOWN;
|
||||
ctx->ssl->s3->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. */
|
||||
ctx->ssl->s3->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);
|
||||
}
|
||||
|
||||
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. */
|
||||
if (ctx->error.code == 0)
|
||||
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->msg_callback == NULL)
|
||||
return;
|
||||
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, &cbs);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_handshake_message_sent_cb(void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *s = ctx->ssl;
|
||||
CBS cbs;
|
||||
|
||||
if (s->msg_callback == NULL)
|
||||
return;
|
||||
|
||||
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
|
||||
ssl_msg_callback_cbs(s, 1, SSL3_RT_HANDSHAKE, &cbs);
|
||||
}
|
||||
|
||||
static void
|
||||
tls13_legacy_info_cb(void *arg, int state, int ret)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *s = ctx->ssl;
|
||||
|
||||
ssl_info_callback(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->tlsext_status_cb == NULL)
|
||||
return 1;
|
||||
|
||||
ret = s->ctx->tlsext_status_cb(s,
|
||||
s->ctx->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_read_traffic_secret(struct tls13_ctx *ctx)
|
||||
{
|
||||
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
|
||||
struct tls13_secret *secret;
|
||||
|
||||
if (ctx->mode == TLS13_HS_CLIENT) {
|
||||
secret = &secrets->server_application_traffic;
|
||||
if (!tls13_update_server_traffic_secret(secrets))
|
||||
return 0;
|
||||
} else {
|
||||
secret = &secrets->client_application_traffic;
|
||||
if (!tls13_update_client_traffic_secret(secrets))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tls13_record_layer_set_read_traffic_key(ctx->rl,
|
||||
secret, ssl_encryption_application);
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_phh_update_write_traffic_secret(struct tls13_ctx *ctx)
|
||||
{
|
||||
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
|
||||
struct tls13_secret *secret;
|
||||
|
||||
if (ctx->mode == TLS13_HS_CLIENT) {
|
||||
secret = &secrets->client_application_traffic;
|
||||
if (!tls13_update_client_traffic_secret(secrets))
|
||||
return 0;
|
||||
} else {
|
||||
secret = &secrets->server_application_traffic;
|
||||
if (!tls13_update_server_traffic_secret(secrets))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tls13_record_layer_set_write_traffic_key(ctx->rl,
|
||||
secret, ssl_encryption_application);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_read_traffic_secret(ctx))
|
||||
goto err;
|
||||
|
||||
if (key_update_request == 0)
|
||||
return TLS13_IO_SUCCESS;
|
||||
|
||||
/* Our peer requested that we update our write traffic keys. */
|
||||
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);
|
||||
}
|
||||
|
||||
/* RFC 8446 section 4.6.1 */
|
||||
static ssize_t
|
||||
tls13_new_session_ticket_recv(struct tls13_ctx *ctx, CBS *cbs)
|
||||
{
|
||||
struct tls13_secrets *secrets = ctx->hs->tls13.secrets;
|
||||
struct tls13_secret nonce;
|
||||
uint32_t ticket_lifetime, ticket_age_add;
|
||||
CBS ticket_nonce, ticket;
|
||||
SSL_SESSION *sess = NULL;
|
||||
int alert, session_id_length;
|
||||
ssize_t ret = 0;
|
||||
|
||||
memset(&nonce, 0, sizeof(nonce));
|
||||
|
||||
if (ctx->mode != TLS13_HS_CLIENT) {
|
||||
alert = TLS13_ALERT_UNEXPECTED_MESSAGE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
alert = TLS13_ALERT_DECODE_ERROR;
|
||||
|
||||
if (!CBS_get_u32(cbs, &ticket_lifetime))
|
||||
goto err;
|
||||
if (!CBS_get_u32(cbs, &ticket_age_add))
|
||||
goto err;
|
||||
if (!CBS_get_u8_length_prefixed(cbs, &ticket_nonce))
|
||||
goto err;
|
||||
if (!CBS_get_u16_length_prefixed(cbs, &ticket))
|
||||
goto err;
|
||||
/* Extensions can only contain early_data, which we currently ignore. */
|
||||
if (!tlsext_client_parse(ctx->ssl, SSL_TLSEXT_MSG_NST, cbs, &alert))
|
||||
goto err;
|
||||
|
||||
if (CBS_len(cbs) != 0)
|
||||
goto err;
|
||||
|
||||
/* Zero indicates that the ticket should be discarded immediately. */
|
||||
if (ticket_lifetime == 0) {
|
||||
ret = TLS13_IO_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Servers MUST NOT use any value larger than 7 days. */
|
||||
if (ticket_lifetime > TLS13_MAX_TICKET_LIFETIME) {
|
||||
alert = TLS13_ALERT_ILLEGAL_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
alert = TLS13_ALERT_INTERNAL_ERROR;
|
||||
|
||||
/*
|
||||
* Create new session instead of modifying the current session.
|
||||
* The current session could already be in the session cache.
|
||||
*/
|
||||
if ((sess = ssl_session_dup(ctx->ssl->session, 0)) == NULL)
|
||||
goto err;
|
||||
|
||||
sess->time = time(NULL);
|
||||
|
||||
sess->tlsext_tick_lifetime_hint = ticket_lifetime;
|
||||
sess->tlsext_tick_age_add = ticket_age_add;
|
||||
|
||||
if (!CBS_stow(&ticket, &sess->tlsext_tick, &sess->tlsext_ticklen))
|
||||
goto err;
|
||||
|
||||
/* XXX - ensure this doesn't overflow session_id if hash is changed. */
|
||||
if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket),
|
||||
sess->session_id, &session_id_length, EVP_sha256(), NULL))
|
||||
goto err;
|
||||
sess->session_id_length = session_id_length;
|
||||
|
||||
if (!CBS_stow(&ticket_nonce, &nonce.data, &nonce.len))
|
||||
goto err;
|
||||
|
||||
if (!tls13_secret_init(&sess->resumption_master_secret, 256))
|
||||
goto err;
|
||||
|
||||
if (!tls13_derive_secret(&sess->resumption_master_secret,
|
||||
secrets->digest, &secrets->resumption_master, "resumption",
|
||||
&nonce))
|
||||
goto err;
|
||||
|
||||
SSL_SESSION_free(ctx->ssl->session);
|
||||
ctx->ssl->session = sess;
|
||||
sess = NULL;
|
||||
|
||||
ssl_update_cache(ctx->ssl, SSL_SESS_CACHE_CLIENT);
|
||||
|
||||
ret = TLS13_IO_SUCCESS;
|
||||
goto done;
|
||||
|
||||
err:
|
||||
ret = tls13_send_alert(ctx->rl, alert);
|
||||
|
||||
done:
|
||||
tls13_secret_cleanup(&nonce);
|
||||
SSL_SESSION_free(sess);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls13_phh_received_cb(void *cb_arg)
|
||||
{
|
||||
ssize_t ret = TLS13_IO_FAILURE;
|
||||
struct tls13_ctx *ctx = cb_arg;
|
||||
CBS 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 ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl)) !=
|
||||
TLS13_IO_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
switch(tls13_handshake_msg_type(ctx->hs_msg)) {
|
||||
case TLS13_MT_KEY_UPDATE:
|
||||
ret = tls13_key_update_recv(ctx, &cbs);
|
||||
break;
|
||||
case TLS13_MT_NEW_SESSION_TICKET:
|
||||
ret = tls13_new_session_ticket_recv(ctx, &cbs);
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_phh_done_cb(void *cb_arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = cb_arg;
|
||||
|
||||
if (ctx->key_update_request) {
|
||||
tls13_phh_update_write_traffic_secret(ctx);
|
||||
ctx->key_update_request = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct tls13_record_layer_callbacks tls13_rl_callbacks = {
|
||||
.wire_read = tls13_legacy_wire_read_cb,
|
||||
.wire_write = tls13_legacy_wire_write_cb,
|
||||
.wire_flush = tls13_legacy_wire_flush_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, SSL *ssl)
|
||||
{
|
||||
struct tls13_ctx *ctx = NULL;
|
||||
|
||||
if ((ctx = calloc(sizeof(struct tls13_ctx), 1)) == NULL)
|
||||
goto err;
|
||||
|
||||
ctx->hs = &ssl->s3->hs;
|
||||
ctx->mode = mode;
|
||||
ctx->ssl = ssl;
|
||||
|
||||
if ((ctx->rl = tls13_record_layer_new(&tls13_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;
|
||||
|
||||
ssl->tls13 = ctx;
|
||||
|
||||
if (SSL_is_quic(ssl)) {
|
||||
if (!tls13_quic_init(ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
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, cert_exts;
|
||||
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 {
|
||||
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->tls13.clienthello_md_ctx != NULL)
|
||||
return 0;
|
||||
if ((ctx->hs->tls13.clienthello_md_ctx = EVP_MD_CTX_new()) == NULL)
|
||||
return 0;
|
||||
if (!EVP_DigestInit_ex(ctx->hs->tls13.clienthello_md_ctx,
|
||||
EVP_sha256(), NULL))
|
||||
return 0;
|
||||
|
||||
if ((ctx->hs->tls13.clienthello_hash == NULL) &&
|
||||
(ctx->hs->tls13.clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) ==
|
||||
NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs) /* XXX */
|
||||
{
|
||||
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->tls13.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->tls13.clienthello_md_ctx,
|
||||
ctx->hs->tls13.clienthello_hash,
|
||||
&ctx->hs->tls13.clienthello_hash_len))
|
||||
return 0;
|
||||
EVP_MD_CTX_free(ctx->hs->tls13.clienthello_md_ctx);
|
||||
ctx->hs->tls13.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->tls13.clienthello_hash == NULL)
|
||||
return 0;
|
||||
|
||||
if (!EVP_DigestFinal_ex(ctx->hs->tls13.clienthello_md_ctx,
|
||||
new_ch_hash, &new_ch_hash_len))
|
||||
return 0;
|
||||
EVP_MD_CTX_free(ctx->hs->tls13.clienthello_md_ctx);
|
||||
ctx->hs->tls13.clienthello_md_ctx = NULL;
|
||||
|
||||
if (ctx->hs->tls13.clienthello_hash_len != new_ch_hash_len)
|
||||
return 0;
|
||||
if (memcmp(ctx->hs->tls13.clienthello_hash, new_ch_hash,
|
||||
new_ch_hash_len) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
181
externals/libressl/ssl/tls13_quic.c
vendored
Normal file
181
externals/libressl/ssl/tls13_quic.c
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
/* $OpenBSD: tls13_quic.c,v 1.7 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2022 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_local.h"
|
||||
#include "tls13_internal.h"
|
||||
|
||||
static ssize_t
|
||||
tls13_quic_wire_read_cb(void *buf, size_t n, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_quic_wire_write_cb(const void *buf, size_t n, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_quic_wire_flush_cb(void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
if (!ssl->quic_method->flush_flight(ssl)) {
|
||||
SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_quic_handshake_read_cb(void *buf, size_t n, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
|
||||
if (ctx->hs->tls13.quic_read_buffer == NULL)
|
||||
return TLS13_IO_WANT_POLLIN;
|
||||
|
||||
return tls_buffer_read(ctx->hs->tls13.quic_read_buffer, buf, n);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls13_quic_handshake_write_cb(const void *buf, size_t n, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
if (!ssl->quic_method->add_handshake_data(ssl,
|
||||
ctx->hs->tls13.quic_write_level, buf, n)) {
|
||||
SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_quic_set_read_traffic_key(struct tls13_secret *read_key,
|
||||
enum ssl_encryption_level_t read_level, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
ctx->hs->tls13.quic_read_level = read_level;
|
||||
|
||||
/* Handle both the new (BoringSSL) and old (quictls) APIs. */
|
||||
|
||||
if (ssl->quic_method->set_read_secret != NULL)
|
||||
return ssl->quic_method->set_read_secret(ssl,
|
||||
ctx->hs->tls13.quic_read_level, ctx->hs->cipher,
|
||||
read_key->data, read_key->len);
|
||||
|
||||
if (ssl->quic_method->set_encryption_secrets != NULL)
|
||||
return ssl->quic_method->set_encryption_secrets(ssl,
|
||||
ctx->hs->tls13.quic_read_level, read_key->data, NULL,
|
||||
read_key->len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_quic_set_write_traffic_key(struct tls13_secret *write_key,
|
||||
enum ssl_encryption_level_t write_level, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
ctx->hs->tls13.quic_write_level = write_level;
|
||||
|
||||
/* Handle both the new (BoringSSL) and old (quictls) APIs. */
|
||||
|
||||
if (ssl->quic_method->set_write_secret != NULL)
|
||||
return ssl->quic_method->set_write_secret(ssl,
|
||||
ctx->hs->tls13.quic_write_level, ctx->hs->cipher,
|
||||
write_key->data, write_key->len);
|
||||
|
||||
if (ssl->quic_method->set_encryption_secrets != NULL)
|
||||
return ssl->quic_method->set_encryption_secrets(ssl,
|
||||
ctx->hs->tls13.quic_write_level, NULL, write_key->data,
|
||||
write_key->len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls13_quic_alert_send_cb(int alert_desc, void *arg)
|
||||
{
|
||||
struct tls13_ctx *ctx = arg;
|
||||
SSL *ssl = ctx->ssl;
|
||||
|
||||
if (!ssl->quic_method->send_alert(ssl, ctx->hs->tls13.quic_write_level,
|
||||
alert_desc)) {
|
||||
SSLerror(ssl, SSL_R_QUIC_INTERNAL_ERROR);
|
||||
return TLS13_IO_FAILURE;
|
||||
}
|
||||
|
||||
return TLS13_IO_SUCCESS;
|
||||
}
|
||||
|
||||
static const struct tls13_record_layer_callbacks quic_rl_callbacks = {
|
||||
.wire_read = tls13_quic_wire_read_cb,
|
||||
.wire_write = tls13_quic_wire_write_cb,
|
||||
.wire_flush = tls13_quic_wire_flush_cb,
|
||||
|
||||
.handshake_read = tls13_quic_handshake_read_cb,
|
||||
.handshake_write = tls13_quic_handshake_write_cb,
|
||||
.set_read_traffic_key = tls13_quic_set_read_traffic_key,
|
||||
.set_write_traffic_key = tls13_quic_set_write_traffic_key,
|
||||
.alert_send = tls13_quic_alert_send_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,
|
||||
};
|
||||
|
||||
int
|
||||
tls13_quic_init(struct tls13_ctx *ctx)
|
||||
{
|
||||
BIO *bio;
|
||||
|
||||
tls13_record_layer_set_callbacks(ctx->rl, &quic_rl_callbacks, ctx);
|
||||
|
||||
ctx->middlebox_compat = 0;
|
||||
|
||||
/*
|
||||
* QUIC does not use BIOs, however we currently expect a BIO to exist
|
||||
* for status handling.
|
||||
*/
|
||||
if ((bio = BIO_new(BIO_s_null())) == NULL)
|
||||
return 0;
|
||||
|
||||
SSL_set_bio(ctx->ssl, bio, bio);
|
||||
bio = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
186
externals/libressl/ssl/tls13_record.c
vendored
Normal file
186
externals/libressl/ssl/tls13_record.c
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/* $OpenBSD: tls13_record.c,v 1.10 2022/07/22 19:33:53 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 "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 tls_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 = tls_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;
|
||||
|
||||
tls_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, tls_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 = tls_buffer_extend(rec->buf,
|
||||
TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls_buffer_data(rec->buf, &cbs))
|
||||
return TLS13_IO_FAILURE;
|
||||
|
||||
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 = tls_buffer_extend(rec->buf,
|
||||
TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
|
||||
return ret;
|
||||
|
||||
if (!tls_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, tls_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;
|
||||
}
|
||||
66
externals/libressl/ssl/tls13_record.h
vendored
Normal file
66
externals/libressl/ssl/tls13_record.h
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/* $OpenBSD: tls13_record.h,v 1.5 2021/10/23 13:12:14 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"
|
||||
|
||||
__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, tls_read_cb _wire_read,
|
||||
void *_wire_arg);
|
||||
ssize_t tls13_record_send(struct tls13_record *_rec, tls_write_cb _wire_write,
|
||||
void *_wire_arg);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
1222
externals/libressl/ssl/tls13_record_layer.c
vendored
Normal file
1222
externals/libressl/ssl/tls13_record_layer.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1101
externals/libressl/ssl/tls13_server.c
vendored
Normal file
1101
externals/libressl/ssl/tls13_server.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
257
externals/libressl/ssl/tls_buffer.c
vendored
Normal file
257
externals/libressl/ssl/tls_buffer.c
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
/* $OpenBSD: tls_buffer.c,v 1.4 2022/11/10 18:06:37 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, 2022 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 <string.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "tls_internal.h"
|
||||
|
||||
#define TLS_BUFFER_CAPACITY_LIMIT (1024 * 1024)
|
||||
|
||||
struct tls_buffer {
|
||||
size_t capacity;
|
||||
size_t capacity_limit;
|
||||
uint8_t *data;
|
||||
size_t len;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
static int tls_buffer_resize(struct tls_buffer *buf, size_t capacity);
|
||||
|
||||
struct tls_buffer *
|
||||
tls_buffer_new(size_t init_size)
|
||||
{
|
||||
struct tls_buffer *buf = NULL;
|
||||
|
||||
if ((buf = calloc(1, sizeof(struct tls_buffer))) == NULL)
|
||||
goto err;
|
||||
|
||||
buf->capacity_limit = TLS_BUFFER_CAPACITY_LIMIT;
|
||||
|
||||
if (!tls_buffer_resize(buf, init_size))
|
||||
goto err;
|
||||
|
||||
return buf;
|
||||
|
||||
err:
|
||||
tls_buffer_free(buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tls_buffer_clear(struct tls_buffer *buf)
|
||||
{
|
||||
freezero(buf->data, buf->capacity);
|
||||
|
||||
buf->data = NULL;
|
||||
buf->capacity = 0;
|
||||
buf->len = 0;
|
||||
buf->offset = 0;
|
||||
}
|
||||
|
||||
void
|
||||
tls_buffer_free(struct tls_buffer *buf)
|
||||
{
|
||||
if (buf == NULL)
|
||||
return;
|
||||
|
||||
tls_buffer_clear(buf);
|
||||
|
||||
freezero(buf, sizeof(struct tls_buffer));
|
||||
}
|
||||
|
||||
static int
|
||||
tls_buffer_grow(struct tls_buffer *buf, size_t capacity)
|
||||
{
|
||||
if (buf->capacity >= capacity)
|
||||
return 1;
|
||||
|
||||
return tls_buffer_resize(buf, capacity);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_buffer_resize(struct tls_buffer *buf, size_t capacity)
|
||||
{
|
||||
uint8_t *data;
|
||||
|
||||
/*
|
||||
* XXX - Consider maintaining a minimum size and growing more
|
||||
* intelligently (rather than exactly).
|
||||
*/
|
||||
if (buf->capacity == capacity)
|
||||
return 1;
|
||||
|
||||
if (capacity > buf->capacity_limit)
|
||||
return 0;
|
||||
|
||||
if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL)
|
||||
return 0;
|
||||
|
||||
buf->data = data;
|
||||
buf->capacity = capacity;
|
||||
|
||||
/* Ensure that len and offset are valid if capacity decreased. */
|
||||
if (buf->len > buf->capacity)
|
||||
buf->len = buf->capacity;
|
||||
if (buf->offset > buf->len)
|
||||
buf->offset = buf->len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
tls_buffer_set_capacity_limit(struct tls_buffer *buf, size_t limit)
|
||||
{
|
||||
/*
|
||||
* XXX - do we want to force a resize if this limit is less than current
|
||||
* capacity... and what do we do with existing data? Force a clear?
|
||||
*/
|
||||
buf->capacity_limit = limit;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls_buffer_extend(struct tls_buffer *buf, size_t len,
|
||||
tls_read_cb read_cb, void *cb_arg)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (len == buf->len)
|
||||
return buf->len;
|
||||
|
||||
if (len < buf->len)
|
||||
return TLS_IO_FAILURE;
|
||||
|
||||
if (!tls_buffer_resize(buf, len))
|
||||
return TLS_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 TLS_IO_FAILURE;
|
||||
|
||||
buf->len += ret;
|
||||
|
||||
if (buf->len == buf->capacity)
|
||||
return buf->len;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
tls_buffer_remaining(struct tls_buffer *buf)
|
||||
{
|
||||
if (buf->offset > buf->len)
|
||||
return 0;
|
||||
|
||||
return buf->len - buf->offset;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls_buffer_read(struct tls_buffer *buf, uint8_t *rbuf, size_t n)
|
||||
{
|
||||
if (buf->offset > buf->len)
|
||||
return TLS_IO_FAILURE;
|
||||
|
||||
if (buf->offset == buf->len)
|
||||
return TLS_IO_WANT_POLLIN;
|
||||
|
||||
if (n > buf->len - buf->offset)
|
||||
n = buf->len - buf->offset;
|
||||
|
||||
memcpy(rbuf, &buf->data[buf->offset], n);
|
||||
|
||||
buf->offset += n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls_buffer_write(struct tls_buffer *buf, const uint8_t *wbuf, size_t n)
|
||||
{
|
||||
if (buf->offset > buf->len)
|
||||
return TLS_IO_FAILURE;
|
||||
|
||||
/*
|
||||
* To avoid continually growing the buffer, pull data up to the
|
||||
* start of the buffer. If all data has been read then we can simply
|
||||
* reset, otherwise wait until we're going to save at least 4KB of
|
||||
* memory to reduce overhead.
|
||||
*/
|
||||
if (buf->offset == buf->len) {
|
||||
buf->len = 0;
|
||||
buf->offset = 0;
|
||||
}
|
||||
if (buf->offset >= 4096) {
|
||||
memmove(buf->data, &buf->data[buf->offset],
|
||||
buf->len - buf->offset);
|
||||
buf->len -= buf->offset;
|
||||
buf->offset = 0;
|
||||
}
|
||||
|
||||
if (buf->len > SIZE_MAX - n)
|
||||
return TLS_IO_FAILURE;
|
||||
if (!tls_buffer_grow(buf, buf->len + n))
|
||||
return TLS_IO_FAILURE;
|
||||
|
||||
memcpy(&buf->data[buf->len], wbuf, n);
|
||||
|
||||
buf->len += n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
tls_buffer_append(struct tls_buffer *buf, const uint8_t *wbuf, size_t n)
|
||||
{
|
||||
return tls_buffer_write(buf, wbuf, n) == n;
|
||||
}
|
||||
|
||||
int
|
||||
tls_buffer_data(struct tls_buffer *buf, CBS *out_cbs)
|
||||
{
|
||||
CBS cbs;
|
||||
|
||||
CBS_init(&cbs, buf->data, buf->len);
|
||||
|
||||
if (!CBS_skip(&cbs, buf->offset))
|
||||
return 0;
|
||||
|
||||
CBS_dup(&cbs, out_cbs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls_buffer_finish(struct tls_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->data = NULL;
|
||||
buf->capacity = 0;
|
||||
buf->len = 0;
|
||||
buf->offset = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
164
externals/libressl/ssl/tls_content.c
vendored
Normal file
164
externals/libressl/ssl/tls_content.c
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/* $OpenBSD: tls_content.c,v 1.2 2022/11/11 17:15:27 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 <string.h>
|
||||
|
||||
#include "tls_content.h"
|
||||
|
||||
/* Content from a TLS record. */
|
||||
struct tls_content {
|
||||
uint8_t type;
|
||||
uint16_t epoch;
|
||||
|
||||
const uint8_t *data;
|
||||
size_t data_len;
|
||||
CBS cbs;
|
||||
};
|
||||
|
||||
struct tls_content *
|
||||
tls_content_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct tls_content));
|
||||
}
|
||||
|
||||
void
|
||||
tls_content_clear(struct tls_content *content)
|
||||
{
|
||||
freezero((void *)content->data, content->data_len);
|
||||
memset(content, 0, sizeof(*content));
|
||||
}
|
||||
|
||||
void
|
||||
tls_content_free(struct tls_content *content)
|
||||
{
|
||||
if (content == NULL)
|
||||
return;
|
||||
|
||||
tls_content_clear(content);
|
||||
|
||||
freezero(content, sizeof(struct tls_content));
|
||||
}
|
||||
|
||||
CBS *
|
||||
tls_content_cbs(struct tls_content *content)
|
||||
{
|
||||
return &content->cbs;
|
||||
}
|
||||
|
||||
int
|
||||
tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n)
|
||||
{
|
||||
return CBS_mem_equal(&content->cbs, buf, n);
|
||||
}
|
||||
|
||||
size_t
|
||||
tls_content_remaining(struct tls_content *content)
|
||||
{
|
||||
return CBS_len(&content->cbs);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
tls_content_type(struct tls_content *content)
|
||||
{
|
||||
return content->type;
|
||||
}
|
||||
|
||||
int
|
||||
tls_content_dup_data(struct tls_content *content, uint8_t type,
|
||||
const uint8_t *data, size_t data_len)
|
||||
{
|
||||
uint8_t *dup;
|
||||
|
||||
if ((dup = calloc(1, data_len)) == NULL)
|
||||
return 0;
|
||||
memcpy(dup, data, data_len);
|
||||
|
||||
tls_content_set_data(content, type, dup, data_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
tls_content_epoch(struct tls_content *content)
|
||||
{
|
||||
return content->epoch;
|
||||
}
|
||||
|
||||
void
|
||||
tls_content_set_epoch(struct tls_content *content, uint16_t epoch)
|
||||
{
|
||||
content->epoch = epoch;
|
||||
}
|
||||
|
||||
void
|
||||
tls_content_set_data(struct tls_content *content, uint8_t type,
|
||||
const uint8_t *data, size_t data_len)
|
||||
{
|
||||
tls_content_clear(content);
|
||||
|
||||
content->type = type;
|
||||
content->data = data;
|
||||
content->data_len = data_len;
|
||||
|
||||
CBS_init(&content->cbs, content->data, content->data_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls_content_set_bounds(struct tls_content *content, size_t offset, size_t len)
|
||||
{
|
||||
size_t content_len;
|
||||
|
||||
content_len = offset + len;
|
||||
if (content_len < len)
|
||||
return 0;
|
||||
if (content_len > content->data_len)
|
||||
return 0;
|
||||
|
||||
CBS_init(&content->cbs, content->data, content_len);
|
||||
return CBS_skip(&content->cbs, offset);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
tls_content_read_internal(struct tls_content *content, uint8_t *buf, size_t n,
|
||||
int peek)
|
||||
{
|
||||
if (n > CBS_len(&content->cbs))
|
||||
n = CBS_len(&content->cbs);
|
||||
|
||||
/* XXX - CBS_memcpy? CBS_copy_bytes? */
|
||||
memcpy(buf, CBS_data(&content->cbs), n);
|
||||
|
||||
if (!peek) {
|
||||
if (!CBS_skip(&content->cbs, n))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n)
|
||||
{
|
||||
return tls_content_read_internal(content, buf, n, 1);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tls_content_read(struct tls_content *content, uint8_t *buf, size_t n)
|
||||
{
|
||||
return tls_content_read_internal(content, buf, n, 0);
|
||||
}
|
||||
50
externals/libressl/ssl/tls_content.h
vendored
Normal file
50
externals/libressl/ssl/tls_content.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/* $OpenBSD: tls_content.h,v 1.2 2022/11/11 17:15:27 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.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_TLS_CONTENT_H
|
||||
#define HEADER_TLS_CONTENT_H
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
struct tls_content;
|
||||
|
||||
struct tls_content *tls_content_new(void);
|
||||
void tls_content_clear(struct tls_content *content);
|
||||
void tls_content_free(struct tls_content *content);
|
||||
|
||||
CBS *tls_content_cbs(struct tls_content *content);
|
||||
int tls_content_equal(struct tls_content *content, const uint8_t *buf, size_t n);
|
||||
size_t tls_content_remaining(struct tls_content *content);
|
||||
uint8_t tls_content_type(struct tls_content *content);
|
||||
uint16_t tls_content_epoch(struct tls_content *content);
|
||||
|
||||
int tls_content_dup_data(struct tls_content *content, uint8_t type,
|
||||
const uint8_t *data, size_t data_len);
|
||||
void tls_content_set_data(struct tls_content *content, uint8_t type,
|
||||
const uint8_t *data, size_t data_len);
|
||||
int tls_content_set_bounds(struct tls_content *content, size_t offset,
|
||||
size_t len);
|
||||
void tls_content_set_epoch(struct tls_content *content, uint16_t epoch);
|
||||
|
||||
ssize_t tls_content_peek(struct tls_content *content, uint8_t *buf, size_t n);
|
||||
ssize_t tls_content_read(struct tls_content *content, uint8_t *buf, size_t n);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
101
externals/libressl/ssl/tls_internal.h
vendored
Normal file
101
externals/libressl/ssl/tls_internal.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/* $OpenBSD: tls_internal.h,v 1.10 2022/11/10 18:06:37 jsing Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, 2021 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_TLS_INTERNAL_H
|
||||
#define HEADER_TLS_INTERNAL_H
|
||||
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define TLS_IO_SUCCESS 1
|
||||
#define TLS_IO_EOF 0
|
||||
#define TLS_IO_FAILURE -1
|
||||
#define TLS_IO_ALERT -2
|
||||
#define TLS_IO_WANT_POLLIN -3
|
||||
#define TLS_IO_WANT_POLLOUT -4
|
||||
#define TLS_IO_WANT_RETRY -5 /* Retry the previous call immediately. */
|
||||
|
||||
enum ssl_encryption_level_t;
|
||||
|
||||
struct tls13_secret;
|
||||
|
||||
/*
|
||||
* Callbacks.
|
||||
*/
|
||||
typedef ssize_t (*tls_read_cb)(void *_buf, size_t _buflen, void *_cb_arg);
|
||||
typedef ssize_t (*tls_write_cb)(const void *_buf, size_t _buflen,
|
||||
void *_cb_arg);
|
||||
typedef ssize_t (*tls_flush_cb)(void *_cb_arg);
|
||||
|
||||
typedef ssize_t (*tls_handshake_read_cb)(void *_buf, size_t _buflen,
|
||||
void *_cb_arg);
|
||||
typedef ssize_t (*tls_handshake_write_cb)(const void *_buf, size_t _buflen,
|
||||
void *_cb_arg);
|
||||
typedef int (*tls_traffic_key_cb)(struct tls13_secret *key,
|
||||
enum ssl_encryption_level_t level, void *_cb_arg);
|
||||
typedef int (*tls_alert_send_cb)(int _alert_desc, void *_cb_arg);
|
||||
|
||||
/*
|
||||
* Buffers.
|
||||
*/
|
||||
struct tls_buffer;
|
||||
|
||||
struct tls_buffer *tls_buffer_new(size_t init_size);
|
||||
void tls_buffer_clear(struct tls_buffer *buf);
|
||||
void tls_buffer_free(struct tls_buffer *buf);
|
||||
void tls_buffer_set_capacity_limit(struct tls_buffer *buf, size_t limit);
|
||||
ssize_t tls_buffer_extend(struct tls_buffer *buf, size_t len,
|
||||
tls_read_cb read_cb, void *cb_arg);
|
||||
size_t tls_buffer_remaining(struct tls_buffer *buf);
|
||||
ssize_t tls_buffer_read(struct tls_buffer *buf, uint8_t *rbuf, size_t n);
|
||||
ssize_t tls_buffer_write(struct tls_buffer *buf, const uint8_t *wbuf, size_t n);
|
||||
int tls_buffer_append(struct tls_buffer *buf, const uint8_t *wbuf, size_t n);
|
||||
int tls_buffer_data(struct tls_buffer *buf, CBS *cbs);
|
||||
int tls_buffer_finish(struct tls_buffer *buf, uint8_t **out, size_t *out_len);
|
||||
|
||||
/*
|
||||
* Key shares.
|
||||
*/
|
||||
struct tls_key_share;
|
||||
|
||||
struct tls_key_share *tls_key_share_new(uint16_t group_id);
|
||||
struct tls_key_share *tls_key_share_new_nid(int nid);
|
||||
void tls_key_share_free(struct tls_key_share *ks);
|
||||
|
||||
uint16_t tls_key_share_group(struct tls_key_share *ks);
|
||||
int tls_key_share_nid(struct tls_key_share *ks);
|
||||
void tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits);
|
||||
int tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params);
|
||||
int tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey);
|
||||
int tls_key_share_generate(struct tls_key_share *ks);
|
||||
int tls_key_share_params(struct tls_key_share *ks, CBB *cbb);
|
||||
int tls_key_share_public(struct tls_key_share *ks, CBB *cbb);
|
||||
int tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs,
|
||||
int *decode_error, int *invalid_params);
|
||||
int tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs,
|
||||
int *decode_error, int *invalid_key);
|
||||
int tls_key_share_derive(struct tls_key_share *ks, uint8_t **shared_key,
|
||||
size_t *shared_key_len);
|
||||
int tls_key_share_peer_security(const SSL *ssl, struct tls_key_share *ks);
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif
|
||||
484
externals/libressl/ssl/tls_key_share.c
vendored
Normal file
484
externals/libressl/ssl/tls_key_share.c
vendored
Normal file
@@ -0,0 +1,484 @@
|
||||
/* $OpenBSD: tls_key_share.c,v 1.8 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2020, 2021 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 <openssl/dh.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "bytestring.h"
|
||||
#include "ssl_local.h"
|
||||
#include "tls_internal.h"
|
||||
|
||||
struct tls_key_share {
|
||||
int nid;
|
||||
uint16_t group_id;
|
||||
size_t key_bits;
|
||||
|
||||
DH *dhe;
|
||||
DH *dhe_peer;
|
||||
|
||||
EC_KEY *ecdhe;
|
||||
EC_KEY *ecdhe_peer;
|
||||
|
||||
uint8_t *x25519_public;
|
||||
uint8_t *x25519_private;
|
||||
uint8_t *x25519_peer_public;
|
||||
};
|
||||
|
||||
static struct tls_key_share *
|
||||
tls_key_share_new_internal(int nid, uint16_t group_id)
|
||||
{
|
||||
struct tls_key_share *ks;
|
||||
|
||||
if ((ks = calloc(1, sizeof(struct tls_key_share))) == NULL)
|
||||
return NULL;
|
||||
|
||||
ks->group_id = group_id;
|
||||
ks->nid = nid;
|
||||
|
||||
return ks;
|
||||
}
|
||||
|
||||
struct tls_key_share *
|
||||
tls_key_share_new(uint16_t group_id)
|
||||
{
|
||||
int nid;
|
||||
|
||||
if (!tls1_ec_group_id2nid(group_id, &nid))
|
||||
return NULL;
|
||||
|
||||
return tls_key_share_new_internal(nid, group_id);
|
||||
}
|
||||
|
||||
struct tls_key_share *
|
||||
tls_key_share_new_nid(int nid)
|
||||
{
|
||||
uint16_t group_id = 0;
|
||||
|
||||
if (nid != NID_dhKeyAgreement) {
|
||||
if (!tls1_ec_nid2group_id(nid, &group_id))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tls_key_share_new_internal(nid, group_id);
|
||||
}
|
||||
|
||||
void
|
||||
tls_key_share_free(struct tls_key_share *ks)
|
||||
{
|
||||
if (ks == NULL)
|
||||
return;
|
||||
|
||||
DH_free(ks->dhe);
|
||||
DH_free(ks->dhe_peer);
|
||||
|
||||
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
|
||||
tls_key_share_group(struct tls_key_share *ks)
|
||||
{
|
||||
return ks->group_id;
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_nid(struct tls_key_share *ks)
|
||||
{
|
||||
return ks->nid;
|
||||
}
|
||||
|
||||
void
|
||||
tls_key_share_set_key_bits(struct tls_key_share *ks, size_t key_bits)
|
||||
{
|
||||
ks->key_bits = key_bits;
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_set_dh_params(struct tls_key_share *ks, DH *dh_params)
|
||||
{
|
||||
if (ks->nid != NID_dhKeyAgreement)
|
||||
return 0;
|
||||
if (ks->dhe != NULL || ks->dhe_peer != NULL)
|
||||
return 0;
|
||||
|
||||
if ((ks->dhe = DHparams_dup(dh_params)) == NULL)
|
||||
return 0;
|
||||
if ((ks->dhe_peer = DHparams_dup(dh_params)) == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_peer_pkey(struct tls_key_share *ks, EVP_PKEY *pkey)
|
||||
{
|
||||
if (ks->nid == NID_dhKeyAgreement && ks->dhe_peer != NULL)
|
||||
return EVP_PKEY_set1_DH(pkey, ks->dhe_peer);
|
||||
|
||||
if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL)
|
||||
return ssl_kex_dummy_ecdhe_x25519(pkey);
|
||||
|
||||
if (ks->ecdhe_peer != NULL)
|
||||
return EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_generate_dhe(struct tls_key_share *ks)
|
||||
{
|
||||
/*
|
||||
* If auto params are not being used then we must already have DH
|
||||
* parameters set.
|
||||
*/
|
||||
if (ks->key_bits == 0) {
|
||||
if (ks->dhe == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_generate_dhe(ks->dhe, ks->dhe);
|
||||
}
|
||||
|
||||
if (ks->dhe != NULL || ks->dhe_peer != NULL)
|
||||
return 0;
|
||||
|
||||
if ((ks->dhe = DH_new()) == NULL)
|
||||
return 0;
|
||||
if (!ssl_kex_generate_dhe_params_auto(ks->dhe, ks->key_bits))
|
||||
return 0;
|
||||
if ((ks->dhe_peer = DHparams_dup(ks->dhe)) == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_generate_ecdhe_ecp(struct tls_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
|
||||
tls_key_share_generate_x25519(struct tls_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
|
||||
tls_key_share_generate(struct tls_key_share *ks)
|
||||
{
|
||||
if (ks->nid == NID_dhKeyAgreement)
|
||||
return tls_key_share_generate_dhe(ks);
|
||||
|
||||
if (ks->nid == NID_X25519)
|
||||
return tls_key_share_generate_x25519(ks);
|
||||
|
||||
return tls_key_share_generate_ecdhe_ecp(ks);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_params_dhe(struct tls_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->dhe == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_params_dhe(ks->dhe, cbb);
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_params(struct tls_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->nid == NID_dhKeyAgreement)
|
||||
return tls_key_share_params_dhe(ks, cbb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_public_dhe(struct tls_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->dhe == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_public_dhe(ks->dhe, cbb);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_public_ecdhe_ecp(struct tls_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->ecdhe == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_public_x25519(struct tls_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->x25519_public == NULL)
|
||||
return 0;
|
||||
|
||||
return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH);
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_public(struct tls_key_share *ks, CBB *cbb)
|
||||
{
|
||||
if (ks->nid == NID_dhKeyAgreement)
|
||||
return tls_key_share_public_dhe(ks, cbb);
|
||||
|
||||
if (ks->nid == NID_X25519)
|
||||
return tls_key_share_public_x25519(ks, cbb);
|
||||
|
||||
return tls_key_share_public_ecdhe_ecp(ks, cbb);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_peer_params_dhe(struct tls_key_share *ks, CBS *cbs,
|
||||
int *decode_error, int *invalid_params)
|
||||
{
|
||||
if (ks->dhe != NULL || ks->dhe_peer != NULL)
|
||||
return 0;
|
||||
|
||||
if ((ks->dhe_peer = DH_new()) == NULL)
|
||||
return 0;
|
||||
if (!ssl_kex_peer_params_dhe(ks->dhe_peer, cbs, decode_error,
|
||||
invalid_params))
|
||||
return 0;
|
||||
if ((ks->dhe = DHparams_dup(ks->dhe_peer)) == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_peer_params(struct tls_key_share *ks, CBS *cbs,
|
||||
int *decode_error, int *invalid_params)
|
||||
{
|
||||
if (ks->nid != NID_dhKeyAgreement)
|
||||
return 0;
|
||||
|
||||
return tls_key_share_peer_params_dhe(ks, cbs, decode_error,
|
||||
invalid_params);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_peer_public_dhe(struct tls_key_share *ks, CBS *cbs,
|
||||
int *decode_error, int *invalid_key)
|
||||
{
|
||||
if (ks->dhe_peer == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_peer_public_dhe(ks->dhe_peer, cbs, decode_error,
|
||||
invalid_key);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_peer_public_ecdhe_ecp(struct tls_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
|
||||
tls_key_share_peer_public_x25519(struct tls_key_share *ks, CBS *cbs,
|
||||
int *decode_error)
|
||||
{
|
||||
size_t out_len;
|
||||
|
||||
*decode_error = 0;
|
||||
|
||||
if (ks->x25519_peer_public != NULL)
|
||||
return 0;
|
||||
|
||||
if (CBS_len(cbs) != X25519_KEY_LENGTH) {
|
||||
*decode_error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CBS_stow(cbs, &ks->x25519_peer_public, &out_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_peer_public(struct tls_key_share *ks, CBS *cbs, int *decode_error,
|
||||
int *invalid_key)
|
||||
{
|
||||
*decode_error = 0;
|
||||
|
||||
if (invalid_key != NULL)
|
||||
*invalid_key = 0;
|
||||
|
||||
if (ks->nid == NID_dhKeyAgreement)
|
||||
return tls_key_share_peer_public_dhe(ks, cbs, decode_error,
|
||||
invalid_key);
|
||||
|
||||
if (ks->nid == NID_X25519)
|
||||
return tls_key_share_peer_public_x25519(ks, cbs, decode_error);
|
||||
|
||||
return tls_key_share_peer_public_ecdhe_ecp(ks, cbs);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_derive_dhe(struct tls_key_share *ks,
|
||||
uint8_t **shared_key, size_t *shared_key_len)
|
||||
{
|
||||
if (ks->dhe == NULL || ks->dhe_peer == NULL)
|
||||
return 0;
|
||||
|
||||
return ssl_kex_derive_dhe(ks->dhe, ks->dhe_peer, shared_key,
|
||||
shared_key_len);
|
||||
}
|
||||
|
||||
static int
|
||||
tls_key_share_derive_ecdhe_ecp(struct tls_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
|
||||
tls_key_share_derive_x25519(struct tls_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
|
||||
tls_key_share_derive(struct tls_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_dhKeyAgreement)
|
||||
return tls_key_share_derive_dhe(ks, shared_key,
|
||||
shared_key_len);
|
||||
|
||||
if (ks->nid == NID_X25519)
|
||||
return tls_key_share_derive_x25519(ks, shared_key,
|
||||
shared_key_len);
|
||||
|
||||
return tls_key_share_derive_ecdhe_ecp(ks, shared_key,
|
||||
shared_key_len);
|
||||
}
|
||||
|
||||
int
|
||||
tls_key_share_peer_security(const SSL *ssl, struct tls_key_share *ks)
|
||||
{
|
||||
switch (ks->nid) {
|
||||
case NID_dhKeyAgreement:
|
||||
return ssl_security_dh(ssl, ks->dhe_peer);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
68
externals/libressl/ssl/tls_lib.c
vendored
Normal file
68
externals/libressl/ssl/tls_lib.c
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/* $OpenBSD: tls_lib.c,v 1.3 2022/11/26 16:08:56 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2019, 2021 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_local.h"
|
||||
|
||||
int
|
||||
tls_process_peer_certs(SSL *s, STACK_OF(X509) *peer_certs)
|
||||
{
|
||||
STACK_OF(X509) *peer_certs_no_leaf;
|
||||
X509 *peer_cert = NULL;
|
||||
EVP_PKEY *pkey;
|
||||
int cert_type;
|
||||
int ret = 0;
|
||||
|
||||
if (sk_X509_num(peer_certs) < 1)
|
||||
goto err;
|
||||
peer_cert = sk_X509_value(peer_certs, 0);
|
||||
X509_up_ref(peer_cert);
|
||||
|
||||
if ((pkey = X509_get0_pubkey(peer_cert)) == NULL) {
|
||||
SSLerror(s, SSL_R_NO_PUBLICKEY);
|
||||
goto err;
|
||||
}
|
||||
if (EVP_PKEY_missing_parameters(pkey)) {
|
||||
SSLerror(s, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
|
||||
goto err;
|
||||
}
|
||||
if ((cert_type = ssl_cert_type(pkey)) < 0) {
|
||||
SSLerror(s, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
s->session->peer_cert_type = cert_type;
|
||||
|
||||
X509_free(s->session->peer_cert);
|
||||
s->session->peer_cert = peer_cert;
|
||||
peer_cert = NULL;
|
||||
|
||||
sk_X509_pop_free(s->s3->hs.peer_certs, X509_free);
|
||||
if ((s->s3->hs.peer_certs = X509_chain_up_ref(peer_certs)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((peer_certs_no_leaf = X509_chain_up_ref(peer_certs)) == NULL)
|
||||
goto err;
|
||||
X509_free(sk_X509_shift(peer_certs_no_leaf));
|
||||
sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free);
|
||||
s->s3->hs.peer_certs_no_leaf = peer_certs_no_leaf;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
X509_free(peer_cert);
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user