early-access version 1255

This commit is contained in:
pineappleEA
2020-12-28 15:15:37 +00:00
parent 84b39492d1
commit 78b48028e1
6254 changed files with 1868140 additions and 0 deletions

82
externals/libressl/ssl/CMakeLists.txt vendored Executable file
View File

@@ -0,0 +1,82 @@
set(
SSL_SRC
bio_ssl.c
bs_ber.c
bs_cbb.c
bs_cbs.c
d1_both.c
d1_clnt.c
d1_lib.c
d1_pkt.c
d1_srtp.c
d1_srvr.c
pqueue.c
s3_cbc.c
s3_lib.c
ssl_algs.c
ssl_asn1.c
ssl_both.c
ssl_cert.c
ssl_ciph.c
ssl_ciphers.c
ssl_clnt.c
ssl_err.c
ssl_init.c
ssl_kex.c
ssl_lib.c
ssl_methods.c
ssl_packet.c
ssl_pkt.c
ssl_rsa.c
ssl_sess.c
ssl_sigalgs.c
ssl_srvr.c
ssl_stat.c
ssl_tlsext.c
ssl_transcript.c
ssl_txt.c
ssl_versions.c
t1_enc.c
t1_lib.c
tls12_record_layer.c
tls13_buffer.c
tls13_client.c
tls13_error.c
tls13_handshake.c
tls13_handshake_msg.c
tls13_key_schedule.c
tls13_key_share.c
tls13_legacy.c
tls13_lib.c
tls13_record.c
tls13_record_layer.c
tls13_server.c
)
add_library(ssl ${SSL_SRC})
target_include_directories(ssl
PRIVATE
.
../include/compat
PUBLIC
../include)
export_symbol(ssl ${CMAKE_CURRENT_SOURCE_DIR}/ssl.sym)
target_link_libraries(ssl crypto ${PLATFORM_LIBS})
if (WIN32)
set(SSL_POSTFIX -${SSL_MAJOR_VERSION})
endif()
set_target_properties(ssl PROPERTIES
OUTPUT_NAME ssl${SSL_POSTFIX}
ARCHIVE_OUTPUT_NAME ssl${SSL_POSTFIX})
set_target_properties(ssl PROPERTIES VERSION ${SSL_VERSION}
SOVERSION ${SSL_MAJOR_VERSION})
if(ENABLE_LIBRESSL_INSTALL)
install(
TARGETS ssl
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif(ENABLE_LIBRESSL_INSTALL)

1
externals/libressl/ssl/VERSION vendored Executable file
View File

@@ -0,0 +1 @@
48:1:0

590
externals/libressl/ssl/bio_ssl.c vendored Executable file
View File

@@ -0,0 +1,590 @@
/* $OpenBSD: bio_ssl.c,v 1.29 2018/08/24 20:30:21 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include "ssl_locl.h"
static int ssl_write(BIO *h, const char *buf, int num);
static int ssl_read(BIO *h, char *buf, int size);
static int ssl_puts(BIO *h, const char *str);
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int ssl_new(BIO *h);
static int ssl_free(BIO *data);
static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
typedef struct bio_ssl_st {
SSL *ssl; /* The ssl handle :-) */
/* re-negotiate every time the total number of bytes is this size */
int num_renegotiates;
unsigned long renegotiate_count;
unsigned long byte_count;
unsigned long renegotiate_timeout;
time_t last_time;
} BIO_SSL;
static const BIO_METHOD methods_sslp = {
.type = BIO_TYPE_SSL,
.name = "ssl",
.bwrite = ssl_write,
.bread = ssl_read,
.bputs = ssl_puts,
.ctrl = ssl_ctrl,
.create = ssl_new,
.destroy = ssl_free,
.callback_ctrl = ssl_callback_ctrl,
};
const BIO_METHOD *
BIO_f_ssl(void)
{
return (&methods_sslp);
}
static int
ssl_new(BIO *bi)
{
BIO_SSL *bs;
bs = calloc(1, sizeof(BIO_SSL));
if (bs == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (0);
}
bi->init = 0;
bi->ptr = (char *)bs;
bi->flags = 0;
return (1);
}
static int
ssl_free(BIO *a)
{
BIO_SSL *bs;
if (a == NULL)
return (0);
bs = (BIO_SSL *)a->ptr;
if (bs->ssl != NULL)
SSL_shutdown(bs->ssl);
if (a->shutdown) {
if (a->init && (bs->ssl != NULL))
SSL_free(bs->ssl);
a->init = 0;
a->flags = 0;
}
free(a->ptr);
return (1);
}
static int
ssl_read(BIO *b, char *out, int outl)
{
int ret = 1;
BIO_SSL *sb;
SSL *ssl;
int retry_reason = 0;
int r = 0;
if (out == NULL)
return (0);
sb = (BIO_SSL *)b->ptr;
ssl = sb->ssl;
BIO_clear_retry_flags(b);
ret = SSL_read(ssl, out, outl);
switch (SSL_get_error(ssl, ret)) {
case SSL_ERROR_NONE:
if (ret <= 0)
break;
if (sb->renegotiate_count > 0) {
sb->byte_count += ret;
if (sb->byte_count > sb->renegotiate_count) {
sb->byte_count = 0;
sb->num_renegotiates++;
SSL_renegotiate(ssl);
r = 1;
}
}
if ((sb->renegotiate_timeout > 0) && (!r)) {
time_t tm;
tm = time(NULL);
if (tm > sb->last_time + sb->renegotiate_timeout) {
sb->last_time = tm;
sb->num_renegotiates++;
SSL_renegotiate(ssl);
}
}
break;
case SSL_ERROR_WANT_READ:
BIO_set_retry_read(b);
break;
case SSL_ERROR_WANT_WRITE:
BIO_set_retry_write(b);
break;
case SSL_ERROR_WANT_X509_LOOKUP:
BIO_set_retry_special(b);
retry_reason = BIO_RR_SSL_X509_LOOKUP;
break;
case SSL_ERROR_WANT_ACCEPT:
BIO_set_retry_special(b);
retry_reason = BIO_RR_ACCEPT;
break;
case SSL_ERROR_WANT_CONNECT:
BIO_set_retry_special(b);
retry_reason = BIO_RR_CONNECT;
break;
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
case SSL_ERROR_ZERO_RETURN:
default:
break;
}
b->retry_reason = retry_reason;
return (ret);
}
static int
ssl_write(BIO *b, const char *out, int outl)
{
int ret, r = 0;
int retry_reason = 0;
SSL *ssl;
BIO_SSL *bs;
if (out == NULL)
return (0);
bs = (BIO_SSL *)b->ptr;
ssl = bs->ssl;
BIO_clear_retry_flags(b);
/* ret=SSL_do_handshake(ssl);
if (ret > 0) */
ret = SSL_write(ssl, out, outl);
switch (SSL_get_error(ssl, ret)) {
case SSL_ERROR_NONE:
if (ret <= 0)
break;
if (bs->renegotiate_count > 0) {
bs->byte_count += ret;
if (bs->byte_count > bs->renegotiate_count) {
bs->byte_count = 0;
bs->num_renegotiates++;
SSL_renegotiate(ssl);
r = 1;
}
}
if ((bs->renegotiate_timeout > 0) && (!r)) {
time_t tm;
tm = time(NULL);
if (tm > bs->last_time + bs->renegotiate_timeout) {
bs->last_time = tm;
bs->num_renegotiates++;
SSL_renegotiate(ssl);
}
}
break;
case SSL_ERROR_WANT_WRITE:
BIO_set_retry_write(b);
break;
case SSL_ERROR_WANT_READ:
BIO_set_retry_read(b);
break;
case SSL_ERROR_WANT_X509_LOOKUP:
BIO_set_retry_special(b);
retry_reason = BIO_RR_SSL_X509_LOOKUP;
break;
case SSL_ERROR_WANT_CONNECT:
BIO_set_retry_special(b);
retry_reason = BIO_RR_CONNECT;
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
default:
break;
}
b->retry_reason = retry_reason;
return (ret);
}
static long
ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
{
SSL **sslp, *ssl;
BIO_SSL *bs;
BIO *dbio, *bio;
long ret = 1;
bs = (BIO_SSL *)b->ptr;
ssl = bs->ssl;
if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
return (0);
switch (cmd) {
case BIO_CTRL_RESET:
SSL_shutdown(ssl);
if (ssl->internal->handshake_func ==
ssl->method->internal->ssl_connect)
SSL_set_connect_state(ssl);
else if (ssl->internal->handshake_func ==
ssl->method->internal->ssl_accept)
SSL_set_accept_state(ssl);
SSL_clear(ssl);
if (b->next_bio != NULL)
ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
else if (ssl->rbio != NULL)
ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
else
ret = 1;
break;
case BIO_CTRL_INFO:
ret = 0;
break;
case BIO_C_SSL_MODE:
if (num) /* client mode */
SSL_set_connect_state(ssl);
else
SSL_set_accept_state(ssl);
break;
case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
ret = bs->renegotiate_timeout;
if (num < 60)
num = 5;
bs->renegotiate_timeout = (unsigned long)num;
bs->last_time = time(NULL);
break;
case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
ret = bs->renegotiate_count;
if ((long)num >=512)
bs->renegotiate_count = (unsigned long)num;
break;
case BIO_C_GET_SSL_NUM_RENEGOTIATES:
ret = bs->num_renegotiates;
break;
case BIO_C_SET_SSL:
if (ssl != NULL) {
ssl_free(b);
if (!ssl_new(b))
return 0;
}
b->shutdown = (int)num;
ssl = (SSL *)ptr;
((BIO_SSL *)b->ptr)->ssl = ssl;
bio = SSL_get_rbio(ssl);
if (bio != NULL) {
if (b->next_bio != NULL)
BIO_push(bio, b->next_bio);
b->next_bio = bio;
CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
}
b->init = 1;
break;
case BIO_C_GET_SSL:
if (ptr != NULL) {
sslp = (SSL **)ptr;
*sslp = ssl;
} else
ret = 0;
break;
case BIO_CTRL_GET_CLOSE:
ret = b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_WPENDING:
ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
break;
case BIO_CTRL_PENDING:
ret = SSL_pending(ssl);
if (ret == 0)
ret = BIO_pending(ssl->rbio);
break;
case BIO_CTRL_FLUSH:
BIO_clear_retry_flags(b);
ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
BIO_copy_next_retry(b);
break;
case BIO_CTRL_PUSH:
if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) {
SSL_set_bio(ssl, b->next_bio, b->next_bio);
CRYPTO_add(&b->next_bio->references, 1,
CRYPTO_LOCK_BIO);
}
break;
case BIO_CTRL_POP:
/* Only detach if we are the BIO explicitly being popped */
if (b == ptr) {
/* Shouldn't happen in practice because the
* rbio and wbio are the same when pushed.
*/
if (ssl->rbio != ssl->wbio)
BIO_free_all(ssl->wbio);
if (b->next_bio != NULL)
CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO);
ssl->wbio = NULL;
ssl->rbio = NULL;
}
break;
case BIO_C_DO_STATE_MACHINE:
BIO_clear_retry_flags(b);
b->retry_reason = 0;
ret = (int)SSL_do_handshake(ssl);
switch (SSL_get_error(ssl, (int)ret)) {
case SSL_ERROR_WANT_READ:
BIO_set_flags(b,
BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
break;
case SSL_ERROR_WANT_WRITE:
BIO_set_flags(b,
BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
break;
case SSL_ERROR_WANT_CONNECT:
BIO_set_flags(b,
BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
b->retry_reason = b->next_bio->retry_reason;
break;
default:
break;
}
break;
case BIO_CTRL_DUP:
dbio = (BIO *)ptr;
if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl);
((BIO_SSL *)dbio->ptr)->renegotiate_count =
((BIO_SSL *)b->ptr)->renegotiate_count;
((BIO_SSL *)dbio->ptr)->byte_count =
((BIO_SSL *)b->ptr)->byte_count;
((BIO_SSL *)dbio->ptr)->renegotiate_timeout =
((BIO_SSL *)b->ptr)->renegotiate_timeout;
((BIO_SSL *)dbio->ptr)->last_time =
((BIO_SSL *)b->ptr)->last_time;
ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL);
break;
case BIO_C_GET_FD:
ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
break;
case BIO_CTRL_SET_CALLBACK:
{
ret = 0;
}
break;
case BIO_CTRL_GET_CALLBACK:
{
void (**fptr)(const SSL *xssl, int type, int val);
fptr = (void (**)(const SSL *xssl, int type, int val))
ptr;
*fptr = SSL_get_info_callback(ssl);
}
break;
default:
ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
break;
}
return (ret);
}
static long
ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
SSL *ssl;
BIO_SSL *bs;
long ret = 1;
bs = (BIO_SSL *)b->ptr;
ssl = bs->ssl;
switch (cmd) {
case BIO_CTRL_SET_CALLBACK:
{
/* FIXME: setting this via a completely different prototype
seems like a crap idea */
SSL_set_info_callback(ssl,
(void (*)(const SSL *, int, int))fp);
}
break;
default:
ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);
break;
}
return (ret);
}
static int
ssl_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = BIO_write(bp, str, n);
return (ret);
}
BIO *
BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
{
BIO *ret = NULL, *buf = NULL, *ssl = NULL;
if ((buf = BIO_new(BIO_f_buffer())) == NULL)
goto err;
if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)
goto err;
if ((ret = BIO_push(buf, ssl)) == NULL)
goto err;
return (ret);
err:
BIO_free(buf);
BIO_free(ssl);
return (NULL);
}
BIO *
BIO_new_ssl_connect(SSL_CTX *ctx)
{
BIO *ret = NULL, *con = NULL, *ssl = NULL;
if ((con = BIO_new(BIO_s_connect())) == NULL)
goto err;
if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)
goto err;
if ((ret = BIO_push(ssl, con)) == NULL)
goto err;
return (ret);
err:
BIO_free(con);
BIO_free(ssl);
return (NULL);
}
BIO *
BIO_new_ssl(SSL_CTX *ctx, int client)
{
BIO *ret;
SSL *ssl;
if ((ret = BIO_new(BIO_f_ssl())) == NULL)
goto err;
if ((ssl = SSL_new(ctx)) == NULL)
goto err;
if (client)
SSL_set_connect_state(ssl);
else
SSL_set_accept_state(ssl);
BIO_set_ssl(ret, ssl, BIO_CLOSE);
return (ret);
err:
BIO_free(ret);
return (NULL);
}
int
BIO_ssl_copy_session_id(BIO *t, BIO *f)
{
t = BIO_find_type(t, BIO_TYPE_SSL);
f = BIO_find_type(f, BIO_TYPE_SSL);
if ((t == NULL) || (f == NULL))
return (0);
if ((((BIO_SSL *)t->ptr)->ssl == NULL) ||
(((BIO_SSL *)f->ptr)->ssl == NULL))
return (0);
if (!SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,
((BIO_SSL *)f->ptr)->ssl))
return (0);
return (1);
}
void
BIO_ssl_shutdown(BIO *b)
{
SSL *s;
while (b != NULL) {
if (b->method->type == BIO_TYPE_SSL) {
s = ((BIO_SSL *)b->ptr)->ssl;
SSL_shutdown(s);
break;
}
b = b->next_bio;
}
}

270
externals/libressl/ssl/bs_ber.c vendored Executable file
View File

@@ -0,0 +1,270 @@
/* $OpenBSD: bs_ber.c,v 1.9 2016/12/03 12:34:35 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <string.h>
#include <openssl/opensslconf.h>
#include "bytestring.h"
/*
* kMaxDepth is a just a sanity limit. The code should be such that the length
* of the input being processes always decreases. None the less, a very large
* input could otherwise cause the stack to overflow.
*/
static const unsigned int kMaxDepth = 2048;
/* Non-strict version that allows a relaxed DER with indefinite form. */
static int
cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
size_t *out_header_len)
{
return cbs_get_any_asn1_element_internal(cbs, out,
out_tag, out_header_len, 0);
}
/*
* cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets
* |*indefinite_found| depending on whether an indefinite length element was
* found. The value of |orig_in| is not modified.
*
* Returns one on success (i.e. |*indefinite_found| was set) and zero on error.
*/
static int
cbs_find_indefinite(const CBS *orig_in, char *indefinite_found,
unsigned int depth)
{
CBS in;
if (depth > kMaxDepth)
return 0;
CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
while (CBS_len(&in) > 0) {
CBS contents;
unsigned int tag;
size_t header_len;
if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag,
&header_len))
return 0;
/* Indefinite form not allowed by DER. */
if (CBS_len(&contents) == header_len && header_len > 0 &&
CBS_data(&contents)[header_len - 1] == 0x80) {
*indefinite_found = 1;
return 1;
}
if (tag & CBS_ASN1_CONSTRUCTED) {
if (!CBS_skip(&contents, header_len) ||
!cbs_find_indefinite(&contents, indefinite_found,
depth + 1))
return 0;
}
}
*indefinite_found = 0;
return 1;
}
/*
* is_primitive_type returns true if |tag| likely a primitive type. Normally
* one can just test the "constructed" bit in the tag but, in BER, even
* primitive tags can have the constructed bit if they have indefinite
* length.
*/
static char
is_primitive_type(unsigned int tag)
{
return (tag & 0xc0) == 0 &&
(tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
(tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
}
/*
* is_eoc returns true if |header_len| and |contents|, as returned by
* |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC)
* value.
*/
static char
is_eoc(size_t header_len, CBS *contents)
{
const unsigned char eoc[] = {0x0, 0x0};
return header_len == 2 && CBS_mem_equal(contents, eoc, 2);
}
/*
* cbs_convert_indefinite reads data with DER encoding (but relaxed to allow
* indefinite form) from |in| and writes definite form DER data to |out|. If
* |squash_header| is set then the top-level of elements from |in| will not
* have their headers written. This is used when concatenating the fragments of
* an indefinite length, primitive value. If |looking_for_eoc| is set then any
* EOC elements found will cause the function to return after consuming it.
* It returns one on success and zero on error.
*/
static int
cbs_convert_indefinite(CBS *in, CBB *out, char squash_header,
char looking_for_eoc, unsigned int depth)
{
if (depth > kMaxDepth)
return 0;
while (CBS_len(in) > 0) {
CBS contents;
unsigned int tag;
size_t header_len;
CBB *out_contents, out_contents_storage;
if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag,
&header_len))
return 0;
out_contents = out;
if (CBS_len(&contents) == header_len) {
if (is_eoc(header_len, &contents))
return looking_for_eoc;
if (header_len > 0 &&
CBS_data(&contents)[header_len - 1] == 0x80) {
/*
* This is an indefinite length element. If
* it's a SEQUENCE or SET then we just need to
* write the out the contents as normal, but
* with a concrete length prefix.
*
* If it's a something else then the contents
* will be a series of DER elements of the same
* type which need to be concatenated.
*/
const char context_specific = (tag & 0xc0)
== 0x80;
char squash_child_headers =
is_primitive_type(tag);
/*
* This is a hack, but it sufficies to handle
* NSS's output. If we find an indefinite
* length, context-specific tag with a definite,
* primtive tag inside it, then we assume that
* the context-specific tag is implicit and the
* tags within are fragments of a primitive type
* that need to be concatenated.
*/
if (context_specific &&
(tag & CBS_ASN1_CONSTRUCTED)) {
CBS in_copy, inner_contents;
unsigned int inner_tag;
size_t inner_header_len;
CBS_init(&in_copy, CBS_data(in),
CBS_len(in));
if (!cbs_nonstrict_get_any_asn1_element(
&in_copy, &inner_contents,
&inner_tag, &inner_header_len))
return 0;
if (CBS_len(&inner_contents) >
inner_header_len &&
is_primitive_type(inner_tag))
squash_child_headers = 1;
}
if (!squash_header) {
unsigned int out_tag = tag;
if (squash_child_headers)
out_tag &=
~CBS_ASN1_CONSTRUCTED;
if (!CBB_add_asn1(out,
&out_contents_storage, out_tag))
return 0;
out_contents = &out_contents_storage;
}
if (!cbs_convert_indefinite(in, out_contents,
squash_child_headers,
1 /* looking for eoc */, depth + 1))
return 0;
if (out_contents != out && !CBB_flush(out))
return 0;
continue;
}
}
if (!squash_header) {
if (!CBB_add_asn1(out, &out_contents_storage, tag))
return 0;
out_contents = &out_contents_storage;
}
if (!CBS_skip(&contents, header_len))
return 0;
if (tag & CBS_ASN1_CONSTRUCTED) {
if (!cbs_convert_indefinite(&contents, out_contents,
0 /* don't squash header */,
0 /* not looking for eoc */, depth + 1))
return 0;
} else {
if (!CBB_add_bytes(out_contents, CBS_data(&contents),
CBS_len(&contents)))
return 0;
}
if (out_contents != out && !CBB_flush(out))
return 0;
}
return looking_for_eoc == 0;
}
int
CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len)
{
CBB cbb;
/*
* First, do a quick walk to find any indefinite-length elements. Most
* of the time we hope that there aren't any and thus we can quickly
* return.
*/
char conversion_needed;
if (!cbs_find_indefinite(in, &conversion_needed, 0))
return 0;
if (!conversion_needed) {
*out = NULL;
*out_len = 0;
return 1;
}
if (!CBB_init(&cbb, CBS_len(in)))
return 0;
if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) {
CBB_cleanup(&cbb);
return 0;
}
return CBB_finish(&cbb, out, out_len);
}

468
externals/libressl/ssl/bs_cbb.c vendored Executable file
View File

@@ -0,0 +1,468 @@
/* $OpenBSD: bs_cbb.c,v 1.23 2020/09/16 05:52:04 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include "bytestring.h"
#define CBB_INITIAL_SIZE 64
static int
cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
{
struct cbb_buffer_st *base;
if ((base = calloc(1, sizeof(struct cbb_buffer_st))) == NULL)
return 0;
base->buf = buf;
base->len = 0;
base->cap = cap;
base->can_resize = 1;
cbb->base = base;
cbb->is_top_level = 1;
return 1;
}
int
CBB_init(CBB *cbb, size_t initial_capacity)
{
uint8_t *buf = NULL;
memset(cbb, 0, sizeof(*cbb));
if (initial_capacity == 0)
initial_capacity = CBB_INITIAL_SIZE;
if ((buf = calloc(1, initial_capacity)) == NULL)
return 0;
if (!cbb_init(cbb, buf, initial_capacity)) {
free(buf);
return 0;
}
return 1;
}
int
CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
{
memset(cbb, 0, sizeof(*cbb));
if (!cbb_init(cbb, buf, len))
return 0;
cbb->base->can_resize = 0;
return 1;
}
void
CBB_cleanup(CBB *cbb)
{
if (cbb->base) {
if (cbb->base->can_resize)
freezero(cbb->base->buf, cbb->base->cap);
free(cbb->base);
}
cbb->base = NULL;
cbb->child = NULL;
}
static int
cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
{
size_t newlen;
if (base == NULL)
return 0;
newlen = base->len + len;
if (newlen < base->len)
/* Overflow */
return 0;
if (newlen > base->cap) {
size_t newcap = base->cap * 2;
uint8_t *newbuf;
if (!base->can_resize)
return 0;
if (newcap < base->cap || newcap < newlen)
newcap = newlen;
newbuf = recallocarray(base->buf, base->cap, newcap, 1);
if (newbuf == NULL)
return 0;
base->buf = newbuf;
base->cap = newcap;
}
if (out)
*out = base->buf + base->len;
base->len = newlen;
return 1;
}
static int
cbb_add_u(CBB *cbb, uint32_t v, size_t len_len)
{
uint8_t *buf;
size_t i;
if (len_len == 0)
return 1;
if (len_len > 4)
return 0;
if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &buf, len_len))
return 0;
for (i = len_len - 1; i < len_len; i--) {
buf[i] = v;
v >>= 8;
}
return 1;
}
int
CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
{
if (!cbb->is_top_level)
return 0;
if (!CBB_flush(cbb))
return 0;
if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
/*
* |out_data| and |out_len| can only be NULL if the CBB is
* fixed.
*/
return 0;
if (out_data != NULL)
*out_data = cbb->base->buf;
if (out_len != NULL)
*out_len = cbb->base->len;
cbb->base->buf = NULL;
CBB_cleanup(cbb);
return 1;
}
/*
* CBB_flush recurses and then writes out any pending length prefix. The current
* length of the underlying base is taken to be the length of the
* length-prefixed data.
*/
int
CBB_flush(CBB *cbb)
{
size_t child_start, i, len;
if (cbb->base == NULL)
return 0;
if (cbb->child == NULL || cbb->pending_len_len == 0)
return 1;
child_start = cbb->offset + cbb->pending_len_len;
if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
cbb->base->len < child_start)
return 0;
len = cbb->base->len - child_start;
if (cbb->pending_is_asn1) {
/*
* For ASN.1, we assumed that we were using short form which
* only requires a single byte for the length octet.
*
* If it turns out that we need long form, we have to move
* the contents along in order to make space for more length
* octets.
*/
size_t len_len = 1; /* total number of length octets */
uint8_t initial_length_byte;
/* We already wrote 1 byte for the length. */
if (cbb->pending_len_len != 1)
return 0;
/* Check for long form */
if (len > 0xfffffffe)
return 0; /* 0xffffffff is reserved */
else if (len > 0xffffff)
len_len = 5;
else if (len > 0xffff)
len_len = 4;
else if (len > 0xff)
len_len = 3;
else if (len > 0x7f)
len_len = 2;
if (len_len == 1) {
/* For short form, the initial byte is the length. */
initial_length_byte = len;
len = 0;
} else {
/*
* For long form, the initial byte is the number of
* subsequent length octets (plus bit 8 set).
*/
initial_length_byte = 0x80 | (len_len - 1);
/*
* We need to move the contents along in order to make
* space for the long form length octets.
*/
size_t extra_bytes = len_len - 1;
if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
return 0;
memmove(cbb->base->buf + child_start + extra_bytes,
cbb->base->buf + child_start, len);
}
cbb->base->buf[cbb->offset++] = initial_length_byte;
cbb->pending_len_len = len_len - 1;
}
for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
cbb->base->buf[cbb->offset + i] = len;
len >>= 8;
}
if (len != 0)
return 0;
cbb->child->base = NULL;
cbb->child = NULL;
cbb->pending_len_len = 0;
cbb->pending_is_asn1 = 0;
cbb->offset = 0;
return 1;
}
void
CBB_discard_child(CBB *cbb)
{
if (cbb->child == NULL)
return;
cbb->base->len = cbb->offset;
cbb->child->base = NULL;
cbb->child = NULL;
cbb->pending_len_len = 0;
cbb->pending_is_asn1 = 0;
cbb->offset = 0;
}
static int
cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
{
uint8_t *prefix_bytes;
if (!CBB_flush(cbb))
return 0;
cbb->offset = cbb->base->len;
if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
return 0;
memset(prefix_bytes, 0, len_len);
memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
cbb->pending_len_len = len_len;
cbb->pending_is_asn1 = 0;
return 1;
}
int
CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
{
return cbb_add_length_prefixed(cbb, out_contents, 1);
}
int
CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
{
return cbb_add_length_prefixed(cbb, out_contents, 2);
}
int
CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
{
return cbb_add_length_prefixed(cbb, out_contents, 3);
}
int
CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag)
{
if (tag > UINT8_MAX)
return 0;
/* Long form identifier octets are not supported. */
if ((tag & 0x1f) == 0x1f)
return 0;
/* Short-form identifier octet only needs a single byte */
if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
return 0;
/*
* Add 1 byte to cover the short-form length octet case. If it turns
* out we need long-form, it will be extended later.
*/
cbb->offset = cbb->base->len;
if (!CBB_add_u8(cbb, 0))
return 0;
memset(out_contents, 0, sizeof(CBB));
out_contents->base = cbb->base;
cbb->child = out_contents;
cbb->pending_len_len = 1;
cbb->pending_is_asn1 = 1;
return 1;
}
int
CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
{
uint8_t *dest;
if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len))
return 0;
memcpy(dest, data, len);
return 1;
}
int
CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
{
if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
return 0;
memset(*out_data, 0, len);
return 1;
}
int
CBB_add_u8(CBB *cbb, size_t value)
{
if (value > UINT8_MAX)
return 0;
return cbb_add_u(cbb, (uint32_t)value, 1);
}
int
CBB_add_u16(CBB *cbb, size_t value)
{
if (value > UINT16_MAX)
return 0;
return cbb_add_u(cbb, (uint32_t)value, 2);
}
int
CBB_add_u24(CBB *cbb, size_t value)
{
if (value > 0xffffffUL)
return 0;
return cbb_add_u(cbb, (uint32_t)value, 3);
}
int
CBB_add_u32(CBB *cbb, size_t value)
{
if (value > 0xffffffffUL)
return 0;
return cbb_add_u(cbb, (uint32_t)value, 4);
}
int
CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
{
CBB child;
size_t i;
int started = 0;
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
return 0;
for (i = 0; i < 8; i++) {
uint8_t byte = (value >> 8 * (7 - i)) & 0xff;
/*
* ASN.1 restriction: first 9 bits cannot be all zeroes or
* all ones. Since this function only encodes unsigned
* integers, the only concerns are not encoding leading
* zeros and adding a padding byte if necessary.
*
* In practice, this means:
* 1) Skip leading octets of all zero bits in the value
* 2) After skipping the leading zero octets, if the next 9
* bits are all ones, add an all zero prefix octet (and
* set the high bit of the prefix octet if negative).
*
* Additionally, for an unsigned value, add an all zero
* prefix if the high bit of the first octet would be one.
*/
if (!started) {
if (byte == 0)
/* Don't encode leading zeros. */
continue;
/*
* If the high bit is set, add a padding byte to make it
* unsigned.
*/
if ((byte & 0x80) && !CBB_add_u8(&child, 0))
return 0;
started = 1;
}
if (!CBB_add_u8(&child, byte))
return 0;
}
/* 0 is encoded as a single 0, not the empty string. */
if (!started && !CBB_add_u8(&child, 0))
return 0;
return CBB_flush(cbb);
}

508
externals/libressl/ssl/bs_cbs.c vendored Executable file
View File

@@ -0,0 +1,508 @@
/* $OpenBSD: bs_cbs.c,v 1.18 2019/01/23 22:20:40 beck Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdlib.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/buffer.h>
#include <openssl/crypto.h>
#include "bytestring.h"
void
CBS_init(CBS *cbs, const uint8_t *data, size_t len)
{
cbs->data = data;
cbs->initial_len = len;
cbs->len = len;
}
void
CBS_dup(const CBS *cbs, CBS *out)
{
CBS_init(out, CBS_data(cbs), CBS_len(cbs));
out->initial_len = cbs->initial_len;
}
static int
cbs_get(CBS *cbs, const uint8_t **p, size_t n)
{
if (cbs->len < n)
return 0;
*p = cbs->data;
cbs->data += n;
cbs->len -= n;
return 1;
}
size_t
CBS_offset(const CBS *cbs)
{
return cbs->initial_len - cbs->len;
}
int
CBS_skip(CBS *cbs, size_t len)
{
const uint8_t *dummy;
return cbs_get(cbs, &dummy, len);
}
const uint8_t *
CBS_data(const CBS *cbs)
{
return cbs->data;
}
size_t
CBS_len(const CBS *cbs)
{
return cbs->len;
}
int
CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
{
free(*out_ptr);
*out_ptr = NULL;
*out_len = 0;
if (cbs->len == 0)
return 1;
if ((*out_ptr = malloc(cbs->len)) == NULL)
return 0;
memcpy(*out_ptr, cbs->data, cbs->len);
*out_len = cbs->len;
return 1;
}
int
CBS_strdup(const CBS *cbs, char **out_ptr)
{
free(*out_ptr);
*out_ptr = strndup((const char *)cbs->data, cbs->len);
return (*out_ptr != NULL);
}
int
CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied)
{
if (dst_len < cbs->len)
return 0;
memmove(dst, cbs->data, cbs->len);
if (copied != NULL)
*copied = cbs->len;
return 1;
}
int
CBS_contains_zero_byte(const CBS *cbs)
{
return memchr(cbs->data, 0, cbs->len) != NULL;
}
int
CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
{
if (len != cbs->len)
return 0;
return timingsafe_memcmp(cbs->data, data, len) == 0;
}
static int
cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
{
uint32_t result = 0;
size_t i;
const uint8_t *data;
if (len < 1 || len > 4)
return 0;
if (!cbs_get(cbs, &data, len))
return 0;
for (i = 0; i < len; i++) {
result <<= 8;
result |= data[i];
}
*out = result;
return 1;
}
int
CBS_get_u8(CBS *cbs, uint8_t *out)
{
const uint8_t *v;
if (!cbs_get(cbs, &v, 1))
return 0;
*out = *v;
return 1;
}
int
CBS_get_u16(CBS *cbs, uint16_t *out)
{
uint32_t v;
if (!cbs_get_u(cbs, &v, 2))
return 0;
*out = v;
return 1;
}
int
CBS_get_u24(CBS *cbs, uint32_t *out)
{
return cbs_get_u(cbs, out, 3);
}
int
CBS_get_u32(CBS *cbs, uint32_t *out)
{
return cbs_get_u(cbs, out, 4);
}
int
CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
{
const uint8_t *v;
if (!cbs_get(cbs, &v, len))
return 0;
CBS_init(out, v, len);
return 1;
}
static int
cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
{
uint32_t len;
if (!cbs_get_u(cbs, &len, len_len))
return 0;
return CBS_get_bytes(cbs, out, len);
}
int
CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
{
return cbs_get_length_prefixed(cbs, out, 1);
}
int
CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
{
return cbs_get_length_prefixed(cbs, out, 2);
}
int
CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
{
return cbs_get_length_prefixed(cbs, out, 3);
}
int
CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
size_t *out_header_len)
{
return cbs_get_any_asn1_element_internal(cbs, out, out_tag,
out_header_len, 1);
}
/*
* Review X.690 for details on ASN.1 DER encoding.
*
* If non-strict mode is enabled, then DER rules are relaxed
* for indefinite constructs (violates DER but a little closer to BER).
* Non-strict mode should only be used by bs_ber.c
*
* Sections 8, 10 and 11 for DER encoding
*/
int
cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag,
size_t *out_header_len, int strict)
{
uint8_t tag, length_byte;
CBS header = *cbs;
CBS throwaway;
size_t len;
if (out == NULL)
out = &throwaway;
/*
* Get identifier octet and length octet. Only 1 octet for each
* is a CBS limitation.
*/
if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
return 0;
/* CBS limitation: long form tags are not supported. */
if ((tag & 0x1f) == 0x1f)
return 0;
if (out_tag != NULL)
*out_tag = tag;
if ((length_byte & 0x80) == 0) {
/* Short form length. */
len = ((size_t) length_byte) + 2;
if (out_header_len != NULL)
*out_header_len = 2;
} else {
/* Long form length. */
const size_t num_bytes = length_byte & 0x7f;
uint32_t len32;
/* ASN.1 reserved value for future extensions */
if (num_bytes == 0x7f)
return 0;
/* Handle indefinite form length */
if (num_bytes == 0) {
/* DER encoding doesn't allow for indefinite form. */
if (strict)
return 0;
/* Primitive cannot use indefinite in BER or DER. */
if ((tag & CBS_ASN1_CONSTRUCTED) == 0)
return 0;
/* Constructed, indefinite length allowed in BER. */
if (out_header_len != NULL)
*out_header_len = 2;
return CBS_get_bytes(cbs, out, 2);
}
/* CBS limitation. */
if (num_bytes > 4)
return 0;
if (!cbs_get_u(&header, &len32, num_bytes))
return 0;
/* DER has a minimum length octet requirement. */
if (len32 < 128)
/* Should have used short form instead */
return 0;
if ((len32 >> ((num_bytes - 1) * 8)) == 0)
/* Length should have been at least one byte shorter. */
return 0;
len = len32;
if (len + 2 + num_bytes < len)
/* Overflow. */
return 0;
len += 2 + num_bytes;
if (out_header_len != NULL)
*out_header_len = 2 + num_bytes;
}
return CBS_get_bytes(cbs, out, len);
}
static int
cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header)
{
size_t header_len;
unsigned int tag;
CBS throwaway;
if (out == NULL)
out = &throwaway;
if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
tag != tag_value)
return 0;
if (skip_header && !CBS_skip(out, header_len))
return 0;
return 1;
}
int
CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value)
{
return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
}
int
CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value)
{
return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
}
int
CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value)
{
if (CBS_len(cbs) < 1)
return 0;
/*
* Tag number 31 indicates the start of a long form number.
* This is valid in ASN.1, but CBS only supports short form.
*/
if ((tag_value & 0x1f) == 0x1f)
return 0;
return CBS_data(cbs)[0] == tag_value;
}
/* Encoding details are in ASN.1: X.690 section 8.3 */
int
CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
{
CBS bytes;
const uint8_t *data;
size_t i, len;
if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
return 0;
*out = 0;
data = CBS_data(&bytes);
len = CBS_len(&bytes);
if (len == 0)
/* An INTEGER is encoded with at least one content octet. */
return 0;
if ((data[0] & 0x80) != 0)
/* Negative number. */
return 0;
if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0)
/* Violates smallest encoding rule: excessive leading zeros. */
return 0;
for (i = 0; i < len; i++) {
if ((*out >> 56) != 0)
/* Too large to represent as a uint64_t. */
return 0;
*out <<= 8;
*out |= data[i];
}
return 1;
}
int
CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag)
{
if (CBS_peek_asn1_tag(cbs, tag)) {
if (!CBS_get_asn1(cbs, out, tag))
return 0;
*out_present = 1;
} else {
*out_present = 0;
}
return 1;
}
int
CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
unsigned int tag)
{
CBS child;
int present;
if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
return 0;
if (present) {
if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
CBS_len(&child) != 0)
return 0;
} else {
CBS_init(out, NULL, 0);
}
if (out_present)
*out_present = present;
return 1;
}
int
CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
uint64_t default_value)
{
CBS child;
int present;
if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
return 0;
if (present) {
if (!CBS_get_asn1_uint64(&child, out) ||
CBS_len(&child) != 0)
return 0;
} else {
*out = default_value;
}
return 1;
}
int
CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
int default_value)
{
CBS child, child2;
int present;
if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
return 0;
if (present) {
uint8_t boolean;
if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
CBS_len(&child2) != 1 || CBS_len(&child) != 0)
return 0;
boolean = CBS_data(&child2)[0];
if (boolean == 0)
*out = 0;
else if (boolean == 0xff)
*out = 1;
else
return 0;
} else {
*out = default_value;
}
return 1;
}

519
externals/libressl/ssl/bytestring.h vendored Executable file
View File

@@ -0,0 +1,519 @@
/* $OpenBSD: bytestring.h,v 1.17 2018/08/16 18:39:37 jsing Exp $ */
/*
* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef OPENSSL_HEADER_BYTESTRING_H
#define OPENSSL_HEADER_BYTESTRING_H
#include <sys/types.h>
#include <stdint.h>
#include <openssl/opensslconf.h>
__BEGIN_HIDDEN_DECLS
/*
* Bytestrings are used for parsing and building TLS and ASN.1 messages.
*
* A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and
* provides utility functions for safely parsing length-prefixed structures
* like TLS and ASN.1 from it.
*
* A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and
* provides utility functions for building length-prefixed messages.
*/
/* CRYPTO ByteString */
typedef struct cbs_st {
const uint8_t *data;
size_t initial_len;
size_t len;
} CBS;
/*
* CBS_init sets |cbs| to point to |data|. It does not take ownership of
* |data|.
*/
void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
/*
* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
* otherwise.
*/
int CBS_skip(CBS *cbs, size_t len);
/*
* CBS_data returns a pointer to the contents of |cbs|.
*/
const uint8_t *CBS_data(const CBS *cbs);
/*
* CBS_len returns the number of bytes remaining in |cbs|.
*/
size_t CBS_len(const CBS *cbs);
/*
* CBS_offset returns the current offset into the original data of |cbs|.
*/
size_t CBS_offset(const CBS *cbs);
/*
* CBS_stow copies the current contents of |cbs| into |*out_ptr| and
* |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
* free. It returns one on success and zero on allocation failure. On
* success, |*out_ptr| should be freed with free. If |cbs| is empty,
* |*out_ptr| will be NULL.
*/
int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
/*
* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
* NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
* with free. It returns one on success and zero on allocation
* failure. On success, |*out_ptr| should be freed with free.
*
* NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
* |CBS_contains_zero_byte(cbs)| to check for NUL bytes.
*/
int CBS_strdup(const CBS *cbs, char **out_ptr);
/*
* CBS_write_bytes writes all of the remaining data from |cbs| into |dst|
* if it is at most |dst_len| bytes. If |copied| is not NULL, it will be set
* to the amount copied. It returns one on success and zero otherwise.
*/
int CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len,
size_t *copied);
/*
* CBS_contains_zero_byte returns one if the current contents of |cbs| contains
* a NUL byte and zero otherwise.
*/
int CBS_contains_zero_byte(const CBS *cbs);
/*
* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
* starting at |data|. If they're equal, it returns one, otherwise zero. If the
* lengths match, it uses a constant-time comparison.
*/
int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len);
/*
* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
* returns one on success and zero on error.
*/
int CBS_get_u8(CBS *cbs, uint8_t *out);
/*
* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
* advances |cbs|. It returns one on success and zero on error.
*/
int CBS_get_u16(CBS *cbs, uint16_t *out);
/*
* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
* advances |cbs|. It returns one on success and zero on error.
*/
int CBS_get_u24(CBS *cbs, uint32_t *out);
/*
* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
* and advances |cbs|. It returns one on success and zero on error.
*/
int CBS_get_u32(CBS *cbs, uint32_t *out);
/*
* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
* |cbs|. It returns one on success and zero on error.
*/
int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
/*
* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
* length-prefixed value from |cbs| and advances |cbs| over it. It returns one
* on success and zero on error.
*/
int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
/*
* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
* big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
* returns one on success and zero on error.
*/
int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
/*
* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
* big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
* returns one on success and zero on error.
*/
int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
/* Parsing ASN.1 */
/*
* While an identifier can be multiple octets, this library only handles the
* single octet variety currently. This limits support up to tag number 30
* since tag number 31 is a reserved value to indicate multiple octets.
*/
/* Bits 8 and 7: class tag type: See X.690 section 8.1.2.2. */
#define CBS_ASN1_UNIVERSAL 0x00
#define CBS_ASN1_APPLICATION 0x40
#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
#define CBS_ASN1_PRIVATE 0xc0
/* Bit 6: Primitive or constructed: See X.690 section 8.1.2.3. */
#define CBS_ASN1_PRIMITIVE 0x00
#define CBS_ASN1_CONSTRUCTED 0x20
/*
* Bits 5 to 1 are the tag number. See X.680 section 8.6 for tag numbers of
* the universal class.
*/
/*
* Common universal identifier octets.
* See X.690 section 8.1 and X.680 section 8.6 for universal tag numbers.
*
* Note: These definitions are the cause of some of the strange behavior in
* CBS's bs_ber.c.
*
* In BER, it is the sender's option to use primitive or constructed for
* bitstring (X.690 section 8.6.1) and octetstring (X.690 section 8.7.1).
*
* In DER, bitstring and octetstring are required to be primitive
* (X.690 section 10.2).
*/
#define CBS_ASN1_BOOLEAN (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x1)
#define CBS_ASN1_INTEGER (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x2)
#define CBS_ASN1_BITSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x3)
#define CBS_ASN1_OCTETSTRING (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x4)
#define CBS_ASN1_OBJECT (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0x6)
#define CBS_ASN1_ENUMERATED (CBS_ASN1_UNIVERSAL | CBS_ASN1_PRIMITIVE | 0xa)
#define CBS_ASN1_SEQUENCE (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x10)
#define CBS_ASN1_SET (CBS_ASN1_UNIVERSAL | CBS_ASN1_CONSTRUCTED | 0x11)
/*
* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
* including tag and length bytes) and advances |cbs| over it. The ASN.1
* element must match |tag_value|. It returns one on success and zero
* on error.
*
* Tag numbers greater than 30 are not supported (i.e. short form only).
*/
int CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value);
/*
* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
* ASN.1 header bytes too.
*/
int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value);
/*
* CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
* if the next ASN.1 element on |cbs| would have tag |tag_value|. If
* |cbs| is empty or the tag does not match, it returns zero. Note: if
* it returns one, CBS_get_asn1 may still fail if the rest of the
* element is malformed.
*/
int CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value);
/*
* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
* |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
* the tag number and |*out_header_len| to the length of the ASN.1 header.
* Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
* the value.
*
* Tag numbers greater than 30 are not supported (i.e. short form only).
*/
int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
size_t *out_header_len);
/*
* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
* and sets |*out| to its value. It returns one on success and zero on error,
* where error includes the integer being negative, or too large to represent
* in 64 bits.
*/
int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
/*
* CBS_get_optional_asn1 gets an optional explicitly-tagged element
* from |cbs| tagged with |tag| and sets |*out| to its contents. If
* present, it sets |*out_present| to one, otherwise zero. It returns
* one on success, whether or not the element was present, and zero on
* decode failure.
*/
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
unsigned int tag);
/*
* CBS_get_optional_asn1_octet_string gets an optional
* explicitly-tagged OCTET STRING from |cbs|. If present, it sets
* |*out| to the string and |*out_present| to one. Otherwise, it sets
* |*out| to empty and |*out_present| to zero. |out_present| may be
* NULL. It returns one on success, whether or not the element was
* present, and zero on decode failure.
*/
int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
unsigned int tag);
/*
* CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
* INTEGER from |cbs|. If present, it sets |*out| to the
* value. Otherwise, it sets |*out| to |default_value|. It returns one
* on success, whether or not the element was present, and zero on
* decode failure.
*/
int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
uint64_t default_value);
/*
* CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
* |cbs|. If present, it sets |*out| to either zero or one, based on the
* boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
* success, whether or not the element was present, and zero on decode
* failure.
*/
int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
int default_value);
/*
* CRYPTO ByteBuilder.
*
* |CBB| objects allow one to build length-prefixed serialisations. A |CBB|
* object is associated with a buffer and new buffers are created with
* |CBB_init|. Several |CBB| objects can point at the same buffer when a
* length-prefix is pending, however only a single |CBB| can be 'current' at
* any one time. For example, if one calls |CBB_add_u8_length_prefixed| then
* the new |CBB| points at the same buffer as the original. But if the original
* |CBB| is used then the length prefix is written out and the new |CBB| must
* not be used again.
*
* If one needs to force a length prefix to be written out because a |CBB| is
* going out of scope, use |CBB_flush|.
*/
struct cbb_buffer_st {
uint8_t *buf;
/* The number of valid bytes. */
size_t len;
/* The size of buf. */
size_t cap;
/*
* One iff |buf| is owned by this object. If not then |buf| cannot be
* resized.
*/
char can_resize;
};
typedef struct cbb_st {
struct cbb_buffer_st *base;
/*
* offset is the offset from the start of |base->buf| to the position of any
* pending length-prefix.
*/
size_t offset;
/* child points to a child CBB if a length-prefix is pending. */
struct cbb_st *child;
/*
* pending_len_len contains the number of bytes in a pending length-prefix,
* or zero if no length-prefix is pending.
*/
uint8_t pending_len_len;
char pending_is_asn1;
/*
* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
* |CBB|). Top-level objects are valid arguments for |CBB_finish|.
*/
char is_top_level;
} CBB;
/*
* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
* needed, the |initial_capacity| is just a hint. It returns one on success or
* zero on error.
*/
int CBB_init(CBB *cbb, size_t initial_capacity);
/*
* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
* |buf| cannot grow, trying to write more than |len| bytes will cause CBB
* functions to fail. It returns one on success or zero on error.
*/
int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
/*
* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
* writing to the same buffer. This should be used in an error case where a
* serialisation is abandoned.
*/
void CBB_cleanup(CBB *cbb);
/*
* CBB_finish completes any pending length prefix and sets |*out_data| to a
* malloced buffer and |*out_len| to the length of that buffer. The caller
* takes ownership of the buffer and, unless the buffer was fixed with
* |CBB_init_fixed|, must call |free| when done.
*
* It can only be called on a "top level" |CBB|, i.e. one initialised with
* |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
* error.
*/
int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
/*
* CBB_flush causes any pending length prefixes to be written out and any child
* |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
* on error.
*/
int CBB_flush(CBB *cbb);
/*
* CBB_discard_child discards the current unflushed child of |cbb|. Neither the
* child's contents nor the length prefix will be included in the output.
*/
void CBB_discard_child(CBB *cbb);
/*
* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
* data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
* length. It returns one on success or zero on error.
*/
int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
/*
* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
* The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
* big-endian length. It returns one on success or zero on error.
*/
int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
/*
* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
* The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
* big-endian length. It returns one on success or zero on error.
*/
int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
/*
* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
* ASN.1 object can be written. The |tag| argument will be used as the tag for
* the object. Passing in |tag| number 31 will return in an error since only
* single octet identifiers are supported. It returns one on success or zero
* on error.
*/
int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned int tag);
/*
* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
* success and zero otherwise.
*/
int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
/*
* CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
* the beginning of that space. The caller must then write |len| bytes of
* actual contents to |*out_data|. It returns one on success and zero
* otherwise.
*/
int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
/*
* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
* success and zero otherwise.
*/
int CBB_add_u8(CBB *cbb, size_t value);
/*
* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
* returns one on success and zero otherwise.
*/
int CBB_add_u16(CBB *cbb, size_t value);
/*
* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
* returns one on success and zero otherwise.
*/
int CBB_add_u24(CBB *cbb, size_t value);
/*
* CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It
* returns one on success and zero otherwise.
*/
int CBB_add_u32(CBB *cbb, size_t value);
/*
* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
* and writes |value| in its contents. It returns one on success and zero on
* error.
*/
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
#ifdef LIBRESSL_INTERNAL
/*
* CBS_dup sets |out| to point to cbs's |data| and |len|. It results in two
* CBS that point to the same buffer.
*/
void CBS_dup(const CBS *cbs, CBS *out);
/*
* cbs_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
* |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
* the tag number and |*out_header_len| to the length of the ASN.1 header. If
* strict mode is disabled and the element has indefinite length then |*out|
* will only contain the header. Each of |out|, |out_tag|, and
* |out_header_len| may be NULL to ignore the value.
*
* Tag numbers greater than 30 are not supported (i.e. short form only).
*/
int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag,
size_t *out_header_len, int strict);
/*
* CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it
* finds indefinite-length elements that otherwise appear to be valid DER, it
* attempts to convert the DER-like data to DER and sets |*out| and
* |*out_length| to describe a malloced buffer containing the DER data.
* Additionally, |*in| will be advanced over the ASN.1 data.
*
* If it doesn't find any indefinite-length elements then it sets |*out| to
* NULL and |*in| is unmodified.
*
* This is NOT a conversion from BER to DER. There are many restrictions when
* dealing with DER data. This is only concerned with one: indefinite vs.
* definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output
* from NSS.
*
* It returns one on success and zero otherwise.
*/
int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len);
#endif /* LIBRESSL_INTERNAL */
__END_HIDDEN_DECLS
#endif /* OPENSSL_HEADER_BYTESTRING_H */

1246
externals/libressl/ssl/d1_both.c vendored Executable file

File diff suppressed because it is too large Load Diff

184
externals/libressl/ssl/d1_clnt.c vendored Executable file
View File

@@ -0,0 +1,184 @@
/* $OpenBSD: d1_clnt.c,v 1.83 2020/01/23 10:48:37 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include "ssl_locl.h"
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/objects.h>
#include "bytestring.h"
int
dtls1_get_hello_verify(SSL *s)
{
long n;
int al, ok = 0;
size_t cookie_len;
uint16_t ssl_version;
CBS hello_verify_request, cookie;
n = ssl3_get_message(s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1, s->internal->max_cert_list, &ok);
if (!ok)
return ((int)n);
if (S3I(s)->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
D1I(s)->send_cookie = 0;
S3I(s)->tmp.reuse_message = 1;
return (1);
}
if (n < 0)
goto truncated;
CBS_init(&hello_verify_request, s->internal->init_msg, n);
if (!CBS_get_u16(&hello_verify_request, &ssl_version))
goto truncated;
if (ssl_version != s->version) {
SSLerror(s, SSL_R_WRONG_SSL_VERSION);
s->version = (s->version & 0xff00) | (ssl_version & 0xff);
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
if (!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie))
goto truncated;
if (!CBS_write_bytes(&cookie, D1I(s)->cookie,
sizeof(D1I(s)->cookie), &cookie_len)) {
D1I(s)->cookie_len = 0;
al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
}
D1I(s)->cookie_len = cookie_len;
D1I(s)->send_cookie = 1;
return 1;
truncated:
al = SSL_AD_DECODE_ERROR;
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
return -1;
}

450
externals/libressl/ssl/d1_lib.c vendored Executable file
View File

@@ -0,0 +1,450 @@
/* $OpenBSD: d1_lib.c,v 1.50 2020/09/26 14:43:17 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdio.h>
#include <openssl/objects.h>
#include "pqueue.h"
#include "ssl_locl.h"
void dtls1_hm_fragment_free(hm_fragment *frag);
static int dtls1_listen(SSL *s, struct sockaddr *client);
SSL3_ENC_METHOD DTLSv1_enc_data = {
.enc_flags = SSL_ENC_FLAG_EXPLICIT_IV,
};
int
dtls1_new(SSL *s)
{
if (!ssl3_new(s))
goto err;
if ((s->d1 = calloc(1, sizeof(*s->d1))) == NULL)
goto err;
if ((s->d1->internal = calloc(1, sizeof(*s->d1->internal))) == NULL)
goto err;
if ((s->d1->internal->unprocessed_rcds.q = pqueue_new()) == NULL)
goto err;
if ((s->d1->internal->processed_rcds.q = pqueue_new()) == NULL)
goto err;
if ((s->d1->internal->buffered_messages = pqueue_new()) == NULL)
goto err;
if ((s->d1->sent_messages = pqueue_new()) == NULL)
goto err;
if ((s->d1->internal->buffered_app_data.q = pqueue_new()) == NULL)
goto err;
if (s->server)
s->d1->internal->cookie_len = sizeof(D1I(s)->cookie);
s->method->internal->ssl_clear(s);
return (1);
err:
dtls1_free(s);
return (0);
}
static void
dtls1_drain_records(pqueue queue)
{
pitem *item;
DTLS1_RECORD_DATA_INTERNAL *rdata;
if (queue == NULL)
return;
while ((item = pqueue_pop(queue)) != NULL) {
rdata = (DTLS1_RECORD_DATA_INTERNAL *)item->data;
ssl3_release_buffer(&rdata->rbuf);
free(item->data);
pitem_free(item);
}
}
static void
dtls1_drain_fragments(pqueue queue)
{
pitem *item;
if (queue == NULL)
return;
while ((item = pqueue_pop(queue)) != NULL) {
dtls1_hm_fragment_free(item->data);
pitem_free(item);
}
}
static void
dtls1_clear_queues(SSL *s)
{
dtls1_drain_records(D1I(s)->unprocessed_rcds.q);
dtls1_drain_records(D1I(s)->processed_rcds.q);
dtls1_drain_fragments(D1I(s)->buffered_messages);
dtls1_drain_fragments(s->d1->sent_messages);
dtls1_drain_records(D1I(s)->buffered_app_data.q);
}
void
dtls1_free(SSL *s)
{
if (s == NULL)
return;
ssl3_free(s);
dtls1_clear_queues(s);
pqueue_free(D1I(s)->unprocessed_rcds.q);
pqueue_free(D1I(s)->processed_rcds.q);
pqueue_free(D1I(s)->buffered_messages);
pqueue_free(s->d1->sent_messages);
pqueue_free(D1I(s)->buffered_app_data.q);
freezero(s->d1->internal, sizeof(*s->d1->internal));
freezero(s->d1, sizeof(*s->d1));
s->d1 = NULL;
}
void
dtls1_clear(SSL *s)
{
struct dtls1_state_internal_st *internal;
pqueue unprocessed_rcds;
pqueue processed_rcds;
pqueue buffered_messages;
pqueue sent_messages;
pqueue buffered_app_data;
unsigned int mtu;
if (s->d1) {
unprocessed_rcds = D1I(s)->unprocessed_rcds.q;
processed_rcds = D1I(s)->processed_rcds.q;
buffered_messages = D1I(s)->buffered_messages;
sent_messages = s->d1->sent_messages;
buffered_app_data = D1I(s)->buffered_app_data.q;
mtu = D1I(s)->mtu;
dtls1_clear_queues(s);
memset(s->d1->internal, 0, sizeof(*s->d1->internal));
internal = s->d1->internal;
memset(s->d1, 0, sizeof(*s->d1));
s->d1->internal = internal;
if (s->server) {
D1I(s)->cookie_len = sizeof(D1I(s)->cookie);
}
if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
D1I(s)->mtu = mtu;
}
D1I(s)->unprocessed_rcds.q = unprocessed_rcds;
D1I(s)->processed_rcds.q = processed_rcds;
D1I(s)->buffered_messages = buffered_messages;
s->d1->sent_messages = sent_messages;
D1I(s)->buffered_app_data.q = buffered_app_data;
}
ssl3_clear(s);
s->version = DTLS1_VERSION;
}
long
dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
{
int ret = 0;
switch (cmd) {
case DTLS_CTRL_GET_TIMEOUT:
if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) {
ret = 1;
}
break;
case DTLS_CTRL_HANDLE_TIMEOUT:
ret = dtls1_handle_timeout(s);
break;
case DTLS_CTRL_LISTEN:
ret = dtls1_listen(s, parg);
break;
default:
ret = ssl3_ctrl(s, cmd, larg, parg);
break;
}
return (ret);
}
/*
* As it's impossible to use stream ciphers in "datagram" mode, this
* simple filter is designed to disengage them in DTLS. Unfortunately
* there is no universal way to identify stream SSL_CIPHER, so we have
* to explicitly list their SSL_* codes. Currently RC4 is the only one
* available, but if new ones emerge, they will have to be added...
*/
const SSL_CIPHER *
dtls1_get_cipher(unsigned int u)
{
const SSL_CIPHER *ciph = ssl3_get_cipher(u);
if (ciph != NULL) {
if (ciph->algorithm_enc == SSL_RC4)
return NULL;
}
return ciph;
}
void
dtls1_start_timer(SSL *s)
{
/* If timer is not set, initialize duration with 1 second */
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
s->d1->timeout_duration = 1;
}
/* Set timeout to current time */
gettimeofday(&(s->d1->next_timeout), NULL);
/* Add duration to current time */
s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
&s->d1->next_timeout);
}
struct timeval*
dtls1_get_timeout(SSL *s, struct timeval* timeleft)
{
struct timeval timenow;
/* If no timeout is set, just return NULL */
if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
return NULL;
}
/* Get current time */
gettimeofday(&timenow, NULL);
/* If timer already expired, set remaining time to 0 */
if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
(s->d1->next_timeout.tv_sec == timenow.tv_sec &&
s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
memset(timeleft, 0, sizeof(struct timeval));
return timeleft;
}
/* Calculate time left until timer expires */
memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
timeleft->tv_sec -= timenow.tv_sec;
timeleft->tv_usec -= timenow.tv_usec;
if (timeleft->tv_usec < 0) {
timeleft->tv_sec--;
timeleft->tv_usec += 1000000;
}
/* If remaining time is less than 15 ms, set it to 0
* to prevent issues because of small devergences with
* socket timeouts.
*/
if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
memset(timeleft, 0, sizeof(struct timeval));
}
return timeleft;
}
int
dtls1_is_timer_expired(SSL *s)
{
struct timeval timeleft;
/* Get time left until timeout, return false if no timer running */
if (dtls1_get_timeout(s, &timeleft) == NULL) {
return 0;
}
/* Return false if timer is not expired yet */
if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
return 0;
}
/* Timer expired, so return true */
return 1;
}
void
dtls1_double_timeout(SSL *s)
{
s->d1->timeout_duration *= 2;
if (s->d1->timeout_duration > 60)
s->d1->timeout_duration = 60;
dtls1_start_timer(s);
}
void
dtls1_stop_timer(SSL *s)
{
/* Reset everything */
memset(&(D1I(s)->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
&(s->d1->next_timeout));
/* Clear retransmission buffer */
dtls1_clear_record_buffer(s);
}
int
dtls1_check_timeout_num(SSL *s)
{
D1I(s)->timeout.num_alerts++;
/* Reduce MTU after 2 unsuccessful retransmissions */
if (D1I(s)->timeout.num_alerts > 2) {
D1I(s)->mtu = BIO_ctrl(SSL_get_wbio(s),
BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
}
if (D1I(s)->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
/* fail the connection, enough alerts have been sent */
SSLerror(s, SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
}
return 0;
}
int
dtls1_handle_timeout(SSL *s)
{
/* if no timer is expired, don't do anything */
if (!dtls1_is_timer_expired(s)) {
return 0;
}
dtls1_double_timeout(s);
if (dtls1_check_timeout_num(s) < 0)
return -1;
D1I(s)->timeout.read_timeouts++;
if (D1I(s)->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
D1I(s)->timeout.read_timeouts = 1;
}
dtls1_start_timer(s);
return dtls1_retransmit_buffered_messages(s);
}
int
dtls1_listen(SSL *s, struct sockaddr *client)
{
int ret;
/* Ensure there is no state left over from a previous invocation */
SSL_clear(s);
SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
D1I(s)->listen = 1;
ret = SSL_accept(s);
if (ret <= 0)
return ret;
(void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
return 1;
}
void
dtls1_build_sequence_number(unsigned char *dst, unsigned char *seq,
unsigned short epoch)
{
CBB cbb;
if (!CBB_init_fixed(&cbb, dst, SSL3_SEQUENCE_SIZE))
goto err;
if (!CBB_add_u16(&cbb, epoch))
goto err;
if (!CBB_add_bytes(&cbb, &seq[2], SSL3_SEQUENCE_SIZE - 2))
goto err;
if (!CBB_finish(&cbb, NULL, NULL))
goto err;
return;
err:
CBB_cleanup(&cbb);
}

1361
externals/libressl/ssl/d1_pkt.c vendored Executable file

File diff suppressed because it is too large Load Diff

251
externals/libressl/ssl/d1_srtp.c vendored Executable file
View File

@@ -0,0 +1,251 @@
/* $OpenBSD: d1_srtp.c,v 1.24 2020/03/16 15:25:13 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/*
* DTLS code by Eric Rescorla <ekr@rtfm.com>
*
* Copyright (C) 2006, Network Resonance, Inc.
* Copyright (C) 2011, RTFM, Inc.
*/
#include <stdio.h>
#include <openssl/objects.h>
#include "ssl_locl.h"
#ifndef OPENSSL_NO_SRTP
#include "bytestring.h"
#include "srtp.h"
static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
{
"SRTP_AES128_CM_SHA1_80",
SRTP_AES128_CM_SHA1_80,
},
{
"SRTP_AES128_CM_SHA1_32",
SRTP_AES128_CM_SHA1_32,
},
{0}
};
int
srtp_find_profile_by_name(char *profile_name, SRTP_PROTECTION_PROFILE **pptr,
unsigned int len)
{
SRTP_PROTECTION_PROFILE *p;
p = srtp_known_profiles;
while (p->name) {
if ((len == strlen(p->name)) &&
!strncmp(p->name, profile_name, len)) {
*pptr = p;
return 0;
}
p++;
}
return 1;
}
int
srtp_find_profile_by_num(unsigned int profile_num,
SRTP_PROTECTION_PROFILE **pptr)
{
SRTP_PROTECTION_PROFILE *p;
p = srtp_known_profiles;
while (p->name) {
if (p->id == profile_num) {
*pptr = p;
return 0;
}
p++;
}
return 1;
}
static int
ssl_ctx_make_profiles(const char *profiles_string,
STACK_OF(SRTP_PROTECTION_PROFILE) **out)
{
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
char *col;
char *ptr = (char *)profiles_string;
SRTP_PROTECTION_PROFILE *p;
if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) {
SSLerrorx(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
return 1;
}
do {
col = strchr(ptr, ':');
if (!srtp_find_profile_by_name(ptr, &p,
col ? col - ptr : (int)strlen(ptr))) {
sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
} else {
SSLerrorx(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
sk_SRTP_PROTECTION_PROFILE_free(profiles);
return 1;
}
if (col)
ptr = col + 1;
} while (col);
sk_SRTP_PROTECTION_PROFILE_free(*out);
*out = profiles;
return 0;
}
int
SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
{
return ssl_ctx_make_profiles(profiles, &ctx->internal->srtp_profiles);
}
int
SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
{
return ssl_ctx_make_profiles(profiles, &s->internal->srtp_profiles);
}
STACK_OF(SRTP_PROTECTION_PROFILE) *
SSL_get_srtp_profiles(SSL *s)
{
if (s != NULL) {
if (s->internal->srtp_profiles != NULL) {
return s->internal->srtp_profiles;
} else if ((s->ctx != NULL) &&
(s->ctx->internal->srtp_profiles != NULL)) {
return s->ctx->internal->srtp_profiles;
}
}
return NULL;
}
SRTP_PROTECTION_PROFILE *
SSL_get_selected_srtp_profile(SSL *s)
{
return s->internal->srtp_profile;
}
#endif

165
externals/libressl/ssl/d1_srvr.c vendored Executable file
View File

@@ -0,0 +1,165 @@
/* $OpenBSD: d1_srvr.c,v 1.95 2018/11/05 05:45:15 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "ssl_locl.h"
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
int
dtls1_send_hello_verify_request(SSL *s)
{
CBB cbb, verify, cookie;
memset(&cbb, 0, sizeof(cbb));
if (S3I(s)->hs.state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) {
if (s->ctx->internal->app_gen_cookie_cb == NULL ||
s->ctx->internal->app_gen_cookie_cb(s, D1I(s)->cookie,
&(D1I(s)->cookie_len)) == 0) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
return 0;
}
if (!ssl3_handshake_msg_start(s, &cbb, &verify,
DTLS1_MT_HELLO_VERIFY_REQUEST))
goto err;
if (!CBB_add_u16(&verify, s->version))
goto err;
if (!CBB_add_u8_length_prefixed(&verify, &cookie))
goto err;
if (!CBB_add_bytes(&cookie, D1I(s)->cookie, D1I(s)->cookie_len))
goto err;
if (!ssl3_handshake_msg_finish(s, &cbb))
goto err;
S3I(s)->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
}
/* S3I(s)->hs.state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
return (ssl3_handshake_write(s));
err:
CBB_cleanup(&cbb);
return (-1);
}

201
externals/libressl/ssl/pqueue.c vendored Executable file
View File

@@ -0,0 +1,201 @@
/* $OpenBSD: pqueue.c,v 1.5 2014/06/12 15:49:31 deraadt Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdlib.h>
#include <string.h>
#include "pqueue.h"
typedef struct _pqueue {
pitem *items;
int count;
} pqueue_s;
pitem *
pitem_new(unsigned char *prio64be, void *data)
{
pitem *item = malloc(sizeof(pitem));
if (item == NULL)
return NULL;
memcpy(item->priority, prio64be, sizeof(item->priority));
item->data = data;
item->next = NULL;
return item;
}
void
pitem_free(pitem *item)
{
free(item);
}
pqueue_s *
pqueue_new(void)
{
return calloc(1, sizeof(pqueue_s));
}
void
pqueue_free(pqueue_s *pq)
{
free(pq);
}
pitem *
pqueue_insert(pqueue_s *pq, pitem *item)
{
pitem *curr, *next;
if (pq->items == NULL) {
pq->items = item;
return item;
}
for (curr = NULL, next = pq->items; next != NULL;
curr = next, next = next->next) {
/* we can compare 64-bit value in big-endian encoding
* with memcmp:-) */
int cmp = memcmp(next->priority, item->priority,
sizeof(item->priority));
if (cmp > 0) { /* next > item */
item->next = next;
if (curr == NULL)
pq->items = item;
else
curr->next = item;
return item;
} else if (cmp == 0) /* duplicates not allowed */
return NULL;
}
item->next = NULL;
curr->next = item;
return item;
}
pitem *
pqueue_peek(pqueue_s *pq)
{
return pq->items;
}
pitem *
pqueue_pop(pqueue_s *pq)
{
pitem *item = pq->items;
if (pq->items != NULL)
pq->items = pq->items->next;
return item;
}
pitem *
pqueue_find(pqueue_s *pq, unsigned char *prio64be)
{
pitem *next;
for (next = pq->items; next != NULL; next = next->next)
if (memcmp(next->priority, prio64be,
sizeof(next->priority)) == 0)
return next;
return NULL;
}
pitem *
pqueue_iterator(pqueue_s *pq)
{
return pqueue_peek(pq);
}
pitem *
pqueue_next(pitem **item)
{
pitem *ret;
if (item == NULL || *item == NULL)
return NULL;
/* *item != NULL */
ret = *item;
*item = (*item)->next;
return ret;
}
int
pqueue_size(pqueue_s *pq)
{
pitem *item = pq->items;
int count = 0;
while (item != NULL) {
count++;
item = item->next;
}
return count;
}

629
externals/libressl/ssl/s3_cbc.c vendored Executable file
View File

@@ -0,0 +1,629 @@
/* $OpenBSD: s3_cbc.c,v 1.22 2020/06/19 21:26:40 tb Exp $ */
/* ====================================================================
* Copyright (c) 2012 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "ssl_locl.h"
#include <openssl/md5.h>
#include <openssl/sha.h>
/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
* field. (SHA-384/512 have 128-bit length.) */
#define MAX_HASH_BIT_COUNT_BYTES 16
/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
* Currently SHA-384/512 has a 128-byte block size and that's the largest
* supported by TLS.) */
#define MAX_HASH_BLOCK_SIZE 128
/* Some utility functions are needed:
*
* These macros return the given value with the MSB copied to all the other
* bits. They use the fact that arithmetic shift shifts-in the sign bit.
* However, this is not ensured by the C standard so you may need to replace
* them with something else on odd CPUs. */
#define DUPLICATE_MSB_TO_ALL(x) ((unsigned int)((int)(x) >> (sizeof(int) * 8 - 1)))
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
static unsigned int
constant_time_lt(unsigned int a, unsigned int b)
{
a -= b;
return DUPLICATE_MSB_TO_ALL(a);
}
/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
static unsigned int
constant_time_ge(unsigned int a, unsigned int b)
{
a -= b;
return DUPLICATE_MSB_TO_ALL(~a);
}
/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
static unsigned char
constant_time_eq_8(unsigned int a, unsigned int b)
{
unsigned int c = a ^ b;
c--;
return DUPLICATE_MSB_TO_ALL_8(c);
}
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
* record in |rec| in constant time and returns 1 if the padding is valid and
* -1 otherwise. It also removes any explicit IV from the start of the record
* without leaking any timing about whether there was enough space after the
* padding was removed.
*
* block_size: the block size of the cipher used to encrypt the record.
* returns:
* 0: (in non-constant time) if the record is publicly invalid.
* 1: if the padding was valid
* -1: otherwise. */
int
tls1_cbc_remove_padding(const SSL* s, SSL3_RECORD_INTERNAL *rec,
unsigned int block_size, unsigned int mac_size)
{
unsigned int padding_length, good, to_check, i;
const unsigned int overhead = 1 /* padding length byte */ + mac_size;
/* Check if version requires explicit IV */
if (SSL_USE_EXPLICIT_IV(s)) {
/* These lengths are all public so we can test them in
* non-constant time.
*/
if (overhead + block_size > rec->length)
return 0;
/* We can now safely skip explicit IV */
rec->data += block_size;
rec->input += block_size;
rec->length -= block_size;
} else if (overhead > rec->length)
return 0;
padding_length = rec->data[rec->length - 1];
good = constant_time_ge(rec->length, overhead + padding_length);
/* The padding consists of a length byte at the end of the record and
* then that many bytes of padding, all with the same value as the
* length byte. Thus, with the length byte included, there are i+1
* bytes of padding.
*
* We can't check just |padding_length+1| bytes because that leaks
* decrypted information. Therefore we always have to check the maximum
* amount of padding possible. (Again, the length of the record is
* public information so we can use it.) */
to_check = 256; /* maximum amount of padding, inc length byte. */
if (to_check > rec->length)
to_check = rec->length;
for (i = 0; i < to_check; i++) {
unsigned char mask = constant_time_ge(padding_length, i);
unsigned char b = rec->data[rec->length - 1 - i];
/* The final |padding_length+1| bytes should all have the value
* |padding_length|. Therefore the XOR should be zero. */
good &= ~(mask&(padding_length ^ b));
}
/* If any of the final |padding_length+1| bytes had the wrong value,
* one or more of the lower eight bits of |good| will be cleared. We
* AND the bottom 8 bits together and duplicate the result to all the
* bits. */
good &= good >> 4;
good &= good >> 2;
good &= good >> 1;
good <<= sizeof(good)*8 - 1;
good = DUPLICATE_MSB_TO_ALL(good);
padding_length = good & (padding_length + 1);
rec->length -= padding_length;
rec->padding_length = padding_length;
return (int)((good & 1) | (~good & -1));
}
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
* constant time (independent of the concrete value of rec->length, which may
* vary within a 256-byte window).
*
* ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
* this function.
*
* On entry:
* rec->orig_len >= md_size
* md_size <= EVP_MAX_MD_SIZE
*
* If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
* variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
* a single or pair of cache-lines, then the variable memory accesses don't
* actually affect the timing. CPUs with smaller cache-lines [if any] are
* not multi-core and are not considered vulnerable to cache-timing attacks.
*/
#define CBC_MAC_ROTATE_IN_PLACE
void
ssl3_cbc_copy_mac(unsigned char* out, const SSL3_RECORD_INTERNAL *rec,
unsigned int md_size, unsigned int orig_len)
{
#if defined(CBC_MAC_ROTATE_IN_PLACE)
unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
unsigned char *rotated_mac;
#else
unsigned char rotated_mac[EVP_MAX_MD_SIZE];
#endif
/* mac_end is the index of |rec->data| just after the end of the MAC. */
unsigned int mac_end = rec->length;
unsigned int mac_start = mac_end - md_size;
/* scan_start contains the number of bytes that we can ignore because
* the MAC's position can only vary by 255 bytes. */
unsigned int scan_start = 0;
unsigned int i, j;
unsigned int div_spoiler;
unsigned int rotate_offset;
OPENSSL_assert(orig_len >= md_size);
OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
#if defined(CBC_MAC_ROTATE_IN_PLACE)
rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf)&63);
#endif
/* This information is public so it's safe to branch based on it. */
if (orig_len > md_size + 255 + 1)
scan_start = orig_len - (md_size + 255 + 1);
/* div_spoiler contains a multiple of md_size that is used to cause the
* modulo operation to be constant time. Without this, the time varies
* based on the amount of padding when running on Intel chips at least.
*
* The aim of right-shifting md_size is so that the compiler doesn't
* figure out that it can remove div_spoiler as that would require it
* to prove that md_size is always even, which I hope is beyond it. */
div_spoiler = md_size >> 1;
div_spoiler <<= (sizeof(div_spoiler) - 1) * 8;
rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
memset(rotated_mac, 0, md_size);
for (i = scan_start, j = 0; i < orig_len; i++) {
unsigned char mac_started = constant_time_ge(i, mac_start);
unsigned char mac_ended = constant_time_ge(i, mac_end);
unsigned char b = rec->data[i];
rotated_mac[j++] |= b & mac_started & ~mac_ended;
j &= constant_time_lt(j, md_size);
}
/* Now rotate the MAC */
#if defined(CBC_MAC_ROTATE_IN_PLACE)
j = 0;
for (i = 0; i < md_size; i++) {
/* in case cache-line is 32 bytes, touch second line */
((volatile unsigned char *)rotated_mac)[rotate_offset^32];
out[j++] = rotated_mac[rotate_offset++];
rotate_offset &= constant_time_lt(rotate_offset, md_size);
}
#else
memset(out, 0, md_size);
rotate_offset = md_size - rotate_offset;
rotate_offset &= constant_time_lt(rotate_offset, md_size);
for (i = 0; i < md_size; i++) {
for (j = 0; j < md_size; j++)
out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
rotate_offset++;
rotate_offset &= constant_time_lt(rotate_offset, md_size);
}
#endif
}
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
*((c)++)=(unsigned char)(((l)>>48)&0xff), \
*((c)++)=(unsigned char)(((l)>>40)&0xff), \
*((c)++)=(unsigned char)(((l)>>32)&0xff), \
*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
* little-endian order. The value of p is advanced by four. */
#define u32toLE(n, p) \
(*((p)++)=(unsigned char)(n), \
*((p)++)=(unsigned char)(n>>8), \
*((p)++)=(unsigned char)(n>>16), \
*((p)++)=(unsigned char)(n>>24))
/* These functions serialize the state of a hash and thus perform the standard
* "final" operation without adding the padding and length that such a function
* typically does. */
static void
tls1_md5_final_raw(void* ctx, unsigned char *md_out)
{
MD5_CTX *md5 = ctx;
u32toLE(md5->A, md_out);
u32toLE(md5->B, md_out);
u32toLE(md5->C, md_out);
u32toLE(md5->D, md_out);
}
static void
tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
{
SHA_CTX *sha1 = ctx;
l2n(sha1->h0, md_out);
l2n(sha1->h1, md_out);
l2n(sha1->h2, md_out);
l2n(sha1->h3, md_out);
l2n(sha1->h4, md_out);
}
static void
tls1_sha256_final_raw(void* ctx, unsigned char *md_out)
{
SHA256_CTX *sha256 = ctx;
unsigned int i;
for (i = 0; i < 8; i++) {
l2n(sha256->h[i], md_out);
}
}
static void
tls1_sha512_final_raw(void* ctx, unsigned char *md_out)
{
SHA512_CTX *sha512 = ctx;
unsigned int i;
for (i = 0; i < 8; i++) {
l2n8(sha512->h[i], md_out);
}
}
/* Largest hash context ever used by the functions above. */
#define LARGEST_DIGEST_CTX SHA512_CTX
/* Type giving the alignment needed by the above */
#define LARGEST_DIGEST_CTX_ALIGNMENT SHA_LONG64
/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
* which ssl3_cbc_digest_record supports. */
char
ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
{
switch (EVP_MD_CTX_type(ctx)) {
case NID_md5:
case NID_sha1:
case NID_sha224:
case NID_sha256:
case NID_sha384:
case NID_sha512:
return 1;
default:
return 0;
}
}
/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded TLS
* record.
*
* ctx: the EVP_MD_CTX from which we take the hash function.
* ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
* md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
* md_out_size: if non-NULL, the number of output bytes is written here.
* header: the 13-byte, TLS record header.
* data: the record data itself, less any preceeding explicit IV.
* data_plus_mac_size: the secret, reported length of the data and MAC
* once the padding has been removed.
* data_plus_mac_plus_padding_size: the public length of the whole
* record, including padding.
*
* On entry: by virtue of having been through one of the remove_padding
* functions, above, we know that data_plus_mac_size is large enough to contain
* a padding byte and MAC. (If the padding was invalid, it might contain the
* padding too. )
*/
int
ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char* md_out,
size_t* md_out_size, const unsigned char header[13],
const unsigned char *data, size_t data_plus_mac_size,
size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret,
unsigned int mac_secret_length)
{
union {
/*
* Alignment here is to allow this to be cast as SHA512_CTX
* without losing alignment required by the 64-bit SHA_LONG64
* integer it contains.
*/
LARGEST_DIGEST_CTX_ALIGNMENT align;
unsigned char c[sizeof(LARGEST_DIGEST_CTX)];
} md_state;
void (*md_final_raw)(void *ctx, unsigned char *md_out);
void (*md_transform)(void *ctx, const unsigned char *block);
unsigned int md_size, md_block_size = 64;
unsigned int header_length, variance_blocks,
len, max_mac_bytes, num_blocks,
num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
unsigned int bits; /* at most 18 bits */
unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
/* hmac_pad is the masked HMAC key. */
unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
unsigned char first_block[MAX_HASH_BLOCK_SIZE];
unsigned char mac_out[EVP_MAX_MD_SIZE];
unsigned int i, j, md_out_size_u;
EVP_MD_CTX md_ctx;
/* mdLengthSize is the number of bytes in the length field that terminates
* the hash. */
unsigned int md_length_size = 8;
char length_is_big_endian = 1;
/* This is a, hopefully redundant, check that allows us to forget about
* many possible overflows later in this function. */
OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024);
switch (EVP_MD_CTX_type(ctx)) {
case NID_md5:
MD5_Init((MD5_CTX*)md_state.c);
md_final_raw = tls1_md5_final_raw;
md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
md_size = 16;
length_is_big_endian = 0;
break;
case NID_sha1:
SHA1_Init((SHA_CTX*)md_state.c);
md_final_raw = tls1_sha1_final_raw;
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform;
md_size = 20;
break;
case NID_sha224:
SHA224_Init((SHA256_CTX*)md_state.c);
md_final_raw = tls1_sha256_final_raw;
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
md_size = 224/8;
break;
case NID_sha256:
SHA256_Init((SHA256_CTX*)md_state.c);
md_final_raw = tls1_sha256_final_raw;
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform;
md_size = 32;
break;
case NID_sha384:
SHA384_Init((SHA512_CTX*)md_state.c);
md_final_raw = tls1_sha512_final_raw;
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
md_size = 384/8;
md_block_size = 128;
md_length_size = 16;
break;
case NID_sha512:
SHA512_Init((SHA512_CTX*)md_state.c);
md_final_raw = tls1_sha512_final_raw;
md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform;
md_size = 64;
md_block_size = 128;
md_length_size = 16;
break;
default:
/* ssl3_cbc_record_digest_supported should have been
* called first to check that the hash function is
* supported. */
OPENSSL_assert(0);
if (md_out_size)
*md_out_size = 0;
return 0;
}
OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
header_length = 13;
/* variance_blocks is the number of blocks of the hash that we have to
* calculate in constant time because they could be altered by the
* padding value.
*
* TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
* required to be minimal. Therefore we say that the final six blocks
* can vary based on the padding.
*
* Later in the function, if the message is short and there obviously
* cannot be this many blocks then variance_blocks can be reduced. */
variance_blocks = 6;
/* From now on we're dealing with the MAC, which conceptually has 13
* bytes of `header' before the start of the data (TLS) */
len = data_plus_mac_plus_padding_size + header_length;
/* max_mac_bytes contains the maximum bytes of bytes in the MAC, including
* |header|, assuming that there's no padding. */
max_mac_bytes = len - md_size - 1;
/* num_blocks is the maximum number of hash blocks. */
num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
/* In order to calculate the MAC in constant time we have to handle
* the final blocks specially because the padding value could cause the
* end to appear somewhere in the final |variance_blocks| blocks and we
* can't leak where. However, |num_starting_blocks| worth of data can
* be hashed right away because no padding value can affect whether
* they are plaintext. */
num_starting_blocks = 0;
/* k is the starting byte offset into the conceptual header||data where
* we start processing. */
k = 0;
/* mac_end_offset is the index just past the end of the data to be
* MACed. */
mac_end_offset = data_plus_mac_size + header_length - md_size;
/* c is the index of the 0x80 byte in the final hash block that
* contains application data. */
c = mac_end_offset % md_block_size;
/* index_a is the hash block number that contains the 0x80 terminating
* value. */
index_a = mac_end_offset / md_block_size;
/* index_b is the hash block number that contains the 64-bit hash
* length, in bits. */
index_b = (mac_end_offset + md_length_size) / md_block_size;
/* bits is the hash-length in bits. It includes the additional hash
* block for the masked HMAC key. */
if (num_blocks > variance_blocks) {
num_starting_blocks = num_blocks - variance_blocks;
k = md_block_size*num_starting_blocks;
}
bits = 8*mac_end_offset;
/* Compute the initial HMAC block. */
bits += 8*md_block_size;
memset(hmac_pad, 0, md_block_size);
OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
memcpy(hmac_pad, mac_secret, mac_secret_length);
for (i = 0; i < md_block_size; i++)
hmac_pad[i] ^= 0x36;
md_transform(md_state.c, hmac_pad);
if (length_is_big_endian) {
memset(length_bytes, 0, md_length_size - 4);
length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24);
length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16);
length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8);
length_bytes[md_length_size - 1] = (unsigned char)bits;
} else {
memset(length_bytes, 0, md_length_size);
length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24);
length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16);
length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8);
length_bytes[md_length_size - 8] = (unsigned char)bits;
}
if (k > 0) {
/* k is a multiple of md_block_size. */
memcpy(first_block, header, 13);
memcpy(first_block + 13, data, md_block_size - 13);
md_transform(md_state.c, first_block);
for (i = 1; i < k/md_block_size; i++)
md_transform(md_state.c, data + md_block_size*i - 13);
}
memset(mac_out, 0, sizeof(mac_out));
/* We now process the final hash blocks. For each block, we construct
* it in constant time. If the |i==index_a| then we'll include the 0x80
* bytes and zero pad etc. For each block we selectively copy it, in
* constant time, to |mac_out|. */
for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; i++) {
unsigned char block[MAX_HASH_BLOCK_SIZE];
unsigned char is_block_a = constant_time_eq_8(i, index_a);
unsigned char is_block_b = constant_time_eq_8(i, index_b);
for (j = 0; j < md_block_size; j++) {
unsigned char b = 0, is_past_c, is_past_cp1;
if (k < header_length)
b = header[k];
else if (k < data_plus_mac_plus_padding_size + header_length)
b = data[k - header_length];
k++;
is_past_c = is_block_a & constant_time_ge(j, c);
is_past_cp1 = is_block_a & constant_time_ge(j, c + 1);
/* If this is the block containing the end of the
* application data, and we are at the offset for the
* 0x80 value, then overwrite b with 0x80. */
b = (b&~is_past_c) | (0x80&is_past_c);
/* If this is the block containing the end of the
* application data and we're past the 0x80 value then
* just write zero. */
b = b&~is_past_cp1;
/* If this is index_b (the final block), but not
* index_a (the end of the data), then the 64-bit
* length didn't fit into index_a and we're having to
* add an extra block of zeros. */
b &= ~is_block_b | is_block_a;
/* The final bytes of one of the blocks contains the
* length. */
if (j >= md_block_size - md_length_size) {
/* If this is index_b, write a length byte. */
b = (b&~is_block_b) | (is_block_b&length_bytes[j - (md_block_size - md_length_size)]);
}
block[j] = b;
}
md_transform(md_state.c, block);
md_final_raw(md_state.c, block);
/* If this is index_b, copy the hash value to |mac_out|. */
for (j = 0; j < md_size; j++)
mac_out[j] |= block[j]&is_block_b;
}
EVP_MD_CTX_init(&md_ctx);
if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) {
EVP_MD_CTX_cleanup(&md_ctx);
return 0;
}
/* Complete the HMAC in the standard manner. */
for (i = 0; i < md_block_size; i++)
hmac_pad[i] ^= 0x6a;
EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
EVP_DigestUpdate(&md_ctx, mac_out, md_size);
EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
if (md_out_size)
*md_out_size = md_out_size_u;
EVP_MD_CTX_cleanup(&md_ctx);
return 1;
}

2738
externals/libressl/ssl/s3_lib.c vendored Executable file

File diff suppressed because it is too large Load Diff

142
externals/libressl/ssl/srtp.h vendored Executable file
View File

@@ -0,0 +1,142 @@
/* $OpenBSD: srtp.h,v 1.6 2015/09/01 15:18:23 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/*
* DTLS code by Eric Rescorla <ekr@rtfm.com>
*
* Copyright (C) 2006, Network Resonance, Inc.
* Copyright (C) 2011, RTFM, Inc.
*/
#ifndef HEADER_D1_SRTP_H
#define HEADER_D1_SRTP_H
#ifdef __cplusplus
extern "C" {
#endif
#define SRTP_AES128_CM_SHA1_80 0x0001
#define SRTP_AES128_CM_SHA1_32 0x0002
#define SRTP_AES128_F8_SHA1_80 0x0003
#define SRTP_AES128_F8_SHA1_32 0x0004
#define SRTP_NULL_SHA1_80 0x0005
#define SRTP_NULL_SHA1_32 0x0006
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
#ifdef __cplusplus
}
#endif
#endif

311
externals/libressl/ssl/ssl.sym vendored Executable file
View File

@@ -0,0 +1,311 @@
BIO_f_ssl
BIO_new_buffer_ssl_connect
BIO_new_ssl
BIO_new_ssl_connect
BIO_ssl_copy_session_id
BIO_ssl_shutdown
DTLS_client_method
DTLS_method
DTLS_server_method
DTLSv1_client_method
DTLSv1_method
DTLSv1_server_method
SSLv23_client_method
SSLv23_method
SSLv23_server_method
TLS_client_method
TLS_method
TLS_server_method
TLSv1_1_client_method
TLSv1_1_method
TLSv1_1_server_method
TLSv1_2_client_method
TLSv1_2_method
TLSv1_2_server_method
TLSv1_client_method
TLSv1_method
TLSv1_server_method
PEM_read_SSL_SESSION
PEM_read_bio_SSL_SESSION
PEM_write_SSL_SESSION
PEM_write_bio_SSL_SESSION
d2i_SSL_SESSION
i2d_SSL_SESSION
ERR_load_SSL_strings
SSL_CIPHER_description
SSL_CIPHER_get_auth_nid
SSL_CIPHER_get_bits
SSL_CIPHER_get_by_id
SSL_CIPHER_get_by_value
SSL_CIPHER_get_cipher_nid
SSL_CIPHER_get_digest_nid
SSL_CIPHER_get_id
SSL_CIPHER_get_kx_nid
SSL_CIPHER_get_name
SSL_CIPHER_get_value
SSL_CIPHER_get_version
SSL_CIPHER_is_aead
SSL_COMP_add_compression_method
SSL_COMP_get_compression_methods
SSL_COMP_get_name
SSL_CTX_add0_chain_cert
SSL_CTX_add1_chain_cert
SSL_CTX_add_client_CA
SSL_CTX_add_session
SSL_CTX_callback_ctrl
SSL_CTX_check_private_key
SSL_CTX_clear_chain_certs
SSL_CTX_ctrl
SSL_CTX_flush_sessions
SSL_CTX_free
SSL_CTX_get0_certificate
SSL_CTX_get0_chain_certs
SSL_CTX_get0_param
SSL_CTX_get_cert_store
SSL_CTX_get_ciphers
SSL_CTX_get_client_CA_list
SSL_CTX_get_client_cert_cb
SSL_CTX_get_default_passwd_cb
SSL_CTX_get_default_passwd_cb_userdata
SSL_CTX_get_ex_data
SSL_CTX_get_ex_new_index
SSL_CTX_get_info_callback
SSL_CTX_get_max_proto_version
SSL_CTX_get_min_proto_version
SSL_CTX_get_quiet_shutdown
SSL_CTX_get_timeout
SSL_CTX_get_verify_callback
SSL_CTX_get_verify_depth
SSL_CTX_get_verify_mode
SSL_CTX_load_verify_locations
SSL_CTX_load_verify_mem
SSL_CTX_new
SSL_CTX_remove_session
SSL_CTX_sess_get_get_cb
SSL_CTX_sess_get_new_cb
SSL_CTX_sess_get_remove_cb
SSL_CTX_sess_set_get_cb
SSL_CTX_sess_set_new_cb
SSL_CTX_sess_set_remove_cb
SSL_CTX_sessions
SSL_CTX_set0_chain
SSL_CTX_set1_chain
SSL_CTX_set1_groups
SSL_CTX_set1_groups_list
SSL_CTX_set1_param
SSL_CTX_set_alpn_protos
SSL_CTX_set_alpn_select_cb
SSL_CTX_set_cert_store
SSL_CTX_set_cert_verify_callback
SSL_CTX_set_cipher_list
SSL_CTX_set_client_CA_list
SSL_CTX_set_client_cert_cb
SSL_CTX_set_client_cert_engine
SSL_CTX_set_cookie_generate_cb
SSL_CTX_set_cookie_verify_cb
SSL_CTX_set_default_passwd_cb
SSL_CTX_set_default_passwd_cb_userdata
SSL_CTX_set_default_verify_paths
SSL_CTX_set_ex_data
SSL_CTX_set_generate_session_id
SSL_CTX_set_info_callback
SSL_CTX_set_max_proto_version
SSL_CTX_set_min_proto_version
SSL_CTX_set_msg_callback
SSL_CTX_set_next_proto_select_cb
SSL_CTX_set_next_protos_advertised_cb
SSL_CTX_set_purpose
SSL_CTX_set_quiet_shutdown
SSL_CTX_set_session_id_context
SSL_CTX_set_ssl_version
SSL_CTX_set_timeout
SSL_CTX_set_tlsext_use_srtp
SSL_CTX_set_tmp_dh_callback
SSL_CTX_set_tmp_ecdh_callback
SSL_CTX_set_tmp_rsa_callback
SSL_CTX_set_trust
SSL_CTX_set_verify
SSL_CTX_set_verify_depth
SSL_CTX_up_ref
SSL_CTX_use_PrivateKey
SSL_CTX_use_PrivateKey_ASN1
SSL_CTX_use_PrivateKey_file
SSL_CTX_use_RSAPrivateKey
SSL_CTX_use_RSAPrivateKey_ASN1
SSL_CTX_use_RSAPrivateKey_file
SSL_CTX_use_certificate
SSL_CTX_use_certificate_ASN1
SSL_CTX_use_certificate_chain_file
SSL_CTX_use_certificate_chain_mem
SSL_CTX_use_certificate_file
SSL_SESSION_free
SSL_SESSION_get0_id_context
SSL_SESSION_get0_peer
SSL_SESSION_get_compress_id
SSL_SESSION_get_ex_data
SSL_SESSION_get_ex_new_index
SSL_SESSION_get_id
SSL_SESSION_get_master_key
SSL_SESSION_get_protocol_version
SSL_SESSION_get_ticket_lifetime_hint
SSL_SESSION_get_time
SSL_SESSION_get_timeout
SSL_SESSION_has_ticket
SSL_SESSION_new
SSL_SESSION_print
SSL_SESSION_print_fp
SSL_SESSION_set1_id
SSL_SESSION_set1_id_context
SSL_SESSION_set_ex_data
SSL_SESSION_set_time
SSL_SESSION_set_timeout
SSL_SESSION_up_ref
SSL_accept
SSL_add0_chain_cert
SSL_add1_chain_cert
SSL_add_client_CA
SSL_add_dir_cert_subjects_to_stack
SSL_add_file_cert_subjects_to_stack
SSL_alert_desc_string
SSL_alert_desc_string_long
SSL_alert_type_string
SSL_alert_type_string_long
SSL_cache_hit
SSL_callback_ctrl
SSL_check_private_key
SSL_clear
SSL_clear_chain_certs
SSL_connect
SSL_copy_session_id
SSL_ctrl
SSL_do_handshake
SSL_dup
SSL_dup_CA_list
SSL_export_keying_material
SSL_free
SSL_get0_alpn_selected
SSL_get0_chain_certs
SSL_get0_next_proto_negotiated
SSL_get0_param
SSL_get1_session
SSL_get1_supported_ciphers
SSL_get_SSL_CTX
SSL_get_certificate
SSL_get_cipher_list
SSL_get_ciphers
SSL_get_client_CA_list
SSL_get_client_ciphers
SSL_get_client_random
SSL_get_current_cipher
SSL_get_current_compression
SSL_get_current_expansion
SSL_get_default_timeout
SSL_get_error
SSL_get_ex_data
SSL_get_ex_data_X509_STORE_CTX_idx
SSL_get_ex_new_index
SSL_get_fd
SSL_get_finished
SSL_get_info_callback
SSL_get_max_proto_version
SSL_get_min_proto_version
SSL_get_peer_cert_chain
SSL_get_peer_certificate
SSL_get_peer_finished
SSL_get_privatekey
SSL_get_quiet_shutdown
SSL_get_rbio
SSL_get_read_ahead
SSL_get_rfd
SSL_get_selected_srtp_profile
SSL_get_server_random
SSL_get_servername
SSL_get_servername_type
SSL_get_session
SSL_get_shared_ciphers
SSL_get_shutdown
SSL_get_srtp_profiles
SSL_get_ssl_method
SSL_get_verify_callback
SSL_get_verify_depth
SSL_get_verify_mode
SSL_get_verify_result
SSL_get_version
SSL_get_wbio
SSL_get_wfd
SSL_has_matching_session_id
SSL_is_server
SSL_library_init
SSL_load_client_CA_file
SSL_load_error_strings
SSL_new
SSL_peek
SSL_pending
SSL_read
SSL_renegotiate
SSL_renegotiate_abbreviated
SSL_renegotiate_pending
SSL_rstate_string
SSL_rstate_string_long
SSL_select_next_proto
SSL_set0_chain
SSL_set1_chain
SSL_set1_groups
SSL_set1_groups_list
SSL_set1_host
SSL_set1_param
SSL_set_SSL_CTX
SSL_set_accept_state
SSL_set_alpn_protos
SSL_set_bio
SSL_set_cipher_list
SSL_set_client_CA_list
SSL_set_connect_state
SSL_set_debug
SSL_set_ex_data
SSL_set_fd
SSL_set_generate_session_id
SSL_set_info_callback
SSL_set_max_proto_version
SSL_set_min_proto_version
SSL_set_msg_callback
SSL_set_purpose
SSL_set_quiet_shutdown
SSL_set_read_ahead
SSL_set_rfd
SSL_set_session
SSL_set_session_id_context
SSL_set_session_secret_cb
SSL_set_session_ticket_ext
SSL_set_session_ticket_ext_cb
SSL_set_shutdown
SSL_set_ssl_method
SSL_set_state
SSL_set_tlsext_use_srtp
SSL_set_tmp_dh_callback
SSL_set_tmp_ecdh_callback
SSL_set_tmp_rsa_callback
SSL_set_trust
SSL_set_verify
SSL_set_verify_depth
SSL_set_verify_result
SSL_set_wfd
SSL_shutdown
SSL_state
SSL_state_string
SSL_state_string_long
SSL_up_ref
SSL_use_PrivateKey
SSL_use_PrivateKey_ASN1
SSL_use_PrivateKey_file
SSL_use_RSAPrivateKey
SSL_use_RSAPrivateKey_ASN1
SSL_use_RSAPrivateKey_file
SSL_use_certificate
SSL_use_certificate_ASN1
SSL_use_certificate_file
SSL_version
SSL_version_str
SSL_want
SSL_write
OPENSSL_init_ssl

125
externals/libressl/ssl/ssl_algs.c vendored Executable file
View File

@@ -0,0 +1,125 @@
/* $OpenBSD: ssl_algs.c,v 1.28 2019/04/04 16:44:24 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/lhash.h>
#include <openssl/objects.h>
#include "ssl_locl.h"
int
SSL_library_init(void)
{
#ifndef OPENSSL_NO_DES
EVP_add_cipher(EVP_des_cbc());
EVP_add_cipher(EVP_des_ede3_cbc());
#endif
#ifndef OPENSSL_NO_RC4
EVP_add_cipher(EVP_rc4());
#if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__))
EVP_add_cipher(EVP_rc4_hmac_md5());
#endif
#endif
#ifndef OPENSSL_NO_RC2
EVP_add_cipher(EVP_rc2_cbc());
/* Not actually used for SSL/TLS but this makes PKCS#12 work
* if an application only calls SSL_library_init().
*/
EVP_add_cipher(EVP_rc2_40_cbc());
#endif
EVP_add_cipher(EVP_aes_128_cbc());
EVP_add_cipher(EVP_aes_192_cbc());
EVP_add_cipher(EVP_aes_256_cbc());
EVP_add_cipher(EVP_aes_128_gcm());
EVP_add_cipher(EVP_aes_256_gcm());
EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
#ifndef OPENSSL_NO_CAMELLIA
EVP_add_cipher(EVP_camellia_128_cbc());
EVP_add_cipher(EVP_camellia_256_cbc());
#endif
#ifndef OPENSSL_NO_GOST
EVP_add_cipher(EVP_gost2814789_cfb64());
EVP_add_cipher(EVP_gost2814789_cnt());
#endif
EVP_add_digest(EVP_md5());
EVP_add_digest(EVP_md5_sha1());
EVP_add_digest_alias(SN_md5, "ssl2-md5");
EVP_add_digest_alias(SN_md5, "ssl3-md5");
EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
EVP_add_digest(EVP_sha224());
EVP_add_digest(EVP_sha256());
EVP_add_digest(EVP_sha384());
EVP_add_digest(EVP_sha512());
EVP_add_digest(EVP_ecdsa());
#ifndef OPENSSL_NO_GOST
EVP_add_digest(EVP_gostr341194());
EVP_add_digest(EVP_gost2814789imit());
EVP_add_digest(EVP_streebog256());
EVP_add_digest(EVP_streebog512());
#endif
return (1);
}

431
externals/libressl/ssl/ssl_asn1.c vendored Executable file
View File

@@ -0,0 +1,431 @@
/* $OpenBSD: ssl_asn1.c,v 1.57 2018/08/27 16:42:48 jsing Exp $ */
/*
* Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <limits.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "ssl_locl.h"
#include "bytestring.h"
#define SSLASN1_TAG (CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)
#define SSLASN1_TIME_TAG (SSLASN1_TAG | 1)
#define SSLASN1_TIMEOUT_TAG (SSLASN1_TAG | 2)
#define SSLASN1_PEER_CERT_TAG (SSLASN1_TAG | 3)
#define SSLASN1_SESSION_ID_CTX_TAG (SSLASN1_TAG | 4)
#define SSLASN1_VERIFY_RESULT_TAG (SSLASN1_TAG | 5)
#define SSLASN1_HOSTNAME_TAG (SSLASN1_TAG | 6)
#define SSLASN1_LIFETIME_TAG (SSLASN1_TAG | 9)
#define SSLASN1_TICKET_TAG (SSLASN1_TAG | 10)
static uint64_t
time_max(void)
{
if (sizeof(time_t) == sizeof(int32_t))
return INT32_MAX;
if (sizeof(time_t) == sizeof(int64_t))
return INT64_MAX;
return 0;
}
static int
SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len,
int ticket_encoding)
{
CBB cbb, session, cipher_suite, session_id, master_key, time, timeout;
CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket, value;
unsigned char *peer_cert_bytes = NULL;
int len, rv = 0;
uint16_t cid;
if (!CBB_init(&cbb, 0))
goto err;
if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE))
goto err;
/* Session ASN1 version. */
if (!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION))
goto err;
/* TLS/SSL protocol version. */
if (s->ssl_version < 0)
goto err;
if (!CBB_add_asn1_uint64(&session, s->ssl_version))
goto err;
/* Cipher suite ID. */
/* XXX - require cipher to be non-NULL or always/only use cipher_id. */
cid = (uint16_t)(s->cipher_id & 0xffff);
if (s->cipher != NULL)
cid = ssl3_cipher_get_value(s->cipher);
if (!CBB_add_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBB_add_u16(&cipher_suite, cid))
goto err;
/* Session ID - zero length for a ticket. */
if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBB_add_bytes(&session_id, s->session_id,
ticket_encoding ? 0 : s->session_id_length))
goto err;
/* Master key. */
if (!CBB_add_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBB_add_bytes(&master_key, s->master_key, s->master_key_length))
goto err;
/* Time [1]. */
if (s->time != 0) {
if (s->time < 0)
goto err;
if (!CBB_add_asn1(&session, &time, SSLASN1_TIME_TAG))
goto err;
if (!CBB_add_asn1_uint64(&time, s->time))
goto err;
}
/* Timeout [2]. */
if (s->timeout != 0) {
if (s->timeout < 0)
goto err;
if (!CBB_add_asn1(&session, &timeout, SSLASN1_TIMEOUT_TAG))
goto err;
if (!CBB_add_asn1_uint64(&timeout, s->timeout))
goto err;
}
/* Peer certificate [3]. */
if (s->peer != NULL) {
if ((len = i2d_X509(s->peer, &peer_cert_bytes)) <= 0)
goto err;
if (!CBB_add_asn1(&session, &peer_cert, SSLASN1_PEER_CERT_TAG))
goto err;
if (!CBB_add_bytes(&peer_cert, peer_cert_bytes, len))
goto err;
}
/* Session ID context [4]. */
/* XXX - Actually handle this as optional? */
if (!CBB_add_asn1(&session, &sidctx, SSLASN1_SESSION_ID_CTX_TAG))
goto err;
if (!CBB_add_asn1(&sidctx, &value, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBB_add_bytes(&value, s->sid_ctx, s->sid_ctx_length))
goto err;
/* Verify result [5]. */
if (s->verify_result != X509_V_OK) {
if (s->verify_result < 0)
goto err;
if (!CBB_add_asn1(&session, &verify_result,
SSLASN1_VERIFY_RESULT_TAG))
goto err;
if (!CBB_add_asn1_uint64(&verify_result, s->verify_result))
goto err;
}
/* Hostname [6]. */
if (s->tlsext_hostname != NULL) {
if (!CBB_add_asn1(&session, &hostname, SSLASN1_HOSTNAME_TAG))
goto err;
if (!CBB_add_asn1(&hostname, &value, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBB_add_bytes(&value, (const uint8_t *)s->tlsext_hostname,
strlen(s->tlsext_hostname)))
goto err;
}
/* PSK identity hint [7]. */
/* PSK identity [8]. */
/* Ticket lifetime hint [9]. */
if (s->tlsext_tick_lifetime_hint > 0) {
if (!CBB_add_asn1(&session, &lifetime, SSLASN1_LIFETIME_TAG))
goto err;
if (!CBB_add_asn1_uint64(&lifetime,
s->tlsext_tick_lifetime_hint))
goto err;
}
/* Ticket [10]. */
if (s->tlsext_tick != NULL) {
if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG))
goto err;
if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBB_add_bytes(&value, s->tlsext_tick, s->tlsext_ticklen))
goto err;
}
/* Compression method [11]. */
/* SRP username [12]. */
if (!CBB_finish(&cbb, out, out_len))
goto err;
rv = 1;
err:
CBB_cleanup(&cbb);
free(peer_cert_bytes);
return rv;
}
int
SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len)
{
if (ss == NULL)
return 0;
if (ss->cipher == NULL && ss->cipher_id == 0)
return 0;
return SSL_SESSION_encode(ss, out, out_len, 1);
}
int
i2d_SSL_SESSION(SSL_SESSION *ss, unsigned char **pp)
{
unsigned char *data = NULL;
size_t data_len = 0;
int rv = -1;
if (ss == NULL)
return 0;
if (ss->cipher == NULL && ss->cipher_id == 0)
return 0;
if (!SSL_SESSION_encode(ss, &data, &data_len, 0))
goto err;
if (data_len > INT_MAX)
goto err;
if (pp != NULL) {
if (*pp == NULL) {
*pp = data;
data = NULL;
} else {
memcpy(*pp, data, data_len);
*pp += data_len;
}
}
rv = (int)data_len;
err:
freezero(data, data_len);
return rv;
}
SSL_SESSION *
d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length)
{
CBS cbs, session, cipher_suite, session_id, master_key, peer_cert;
CBS hostname, ticket;
uint64_t version, tls_version, stime, timeout, verify_result, lifetime;
const unsigned char *peer_cert_bytes;
uint16_t cipher_value;
SSL_SESSION *s = NULL;
size_t data_len;
int present;
if (a != NULL)
s = *a;
if (s == NULL) {
if ((s = SSL_SESSION_new()) == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
}
}
CBS_init(&cbs, *pp, length);
if (!CBS_get_asn1(&cbs, &session, CBS_ASN1_SEQUENCE))
goto err;
/* Session ASN1 version. */
if (!CBS_get_asn1_uint64(&session, &version))
goto err;
if (version != SSL_SESSION_ASN1_VERSION)
goto err;
/* TLS/SSL Protocol Version. */
if (!CBS_get_asn1_uint64(&session, &tls_version))
goto err;
if (tls_version > INT_MAX)
goto err;
s->ssl_version = (int)tls_version;
/* Cipher suite. */
if (!CBS_get_asn1(&session, &cipher_suite, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBS_get_u16(&cipher_suite, &cipher_value))
goto err;
if (CBS_len(&cipher_suite) != 0)
goto err;
/* XXX - populate cipher instead? */
s->cipher = NULL;
s->cipher_id = SSL3_CK_ID | cipher_value;
/* Session ID. */
if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBS_write_bytes(&session_id, s->session_id, sizeof(s->session_id),
&data_len))
goto err;
if (data_len > UINT_MAX)
goto err;
s->session_id_length = (unsigned int)data_len;
/* Master key. */
if (!CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING))
goto err;
if (!CBS_write_bytes(&master_key, s->master_key, sizeof(s->master_key),
&data_len))
goto err;
if (data_len > INT_MAX)
goto err;
s->master_key_length = (int)data_len;
/* Time [1]. */
s->time = time(NULL);
if (!CBS_get_optional_asn1_uint64(&session, &stime, SSLASN1_TIME_TAG,
0))
goto err;
if (stime > time_max())
goto err;
if (stime != 0)
s->time = (time_t)stime;
/* Timeout [2]. */
s->timeout = 3;
if (!CBS_get_optional_asn1_uint64(&session, &timeout,
SSLASN1_TIMEOUT_TAG, 0))
goto err;
if (timeout > LONG_MAX)
goto err;
if (timeout != 0)
s->timeout = (long)timeout;
/* Peer certificate [3]. */
X509_free(s->peer);
s->peer = NULL;
if (!CBS_get_optional_asn1(&session, &peer_cert, &present,
SSLASN1_PEER_CERT_TAG))
goto err;
if (present) {
data_len = CBS_len(&peer_cert);
if (data_len > LONG_MAX)
goto err;
peer_cert_bytes = CBS_data(&peer_cert);
if (d2i_X509(&s->peer, &peer_cert_bytes,
(long)data_len) == NULL)
goto err;
}
/* Session ID context [4]. */
s->sid_ctx_length = 0;
if (!CBS_get_optional_asn1_octet_string(&session, &session_id, &present,
SSLASN1_SESSION_ID_CTX_TAG))
goto err;
if (present) {
if (!CBS_write_bytes(&session_id, (uint8_t *)&s->sid_ctx,
sizeof(s->sid_ctx), &data_len))
goto err;
if (data_len > UINT_MAX)
goto err;
s->sid_ctx_length = (unsigned int)data_len;
}
/* Verify result [5]. */
s->verify_result = X509_V_OK;
if (!CBS_get_optional_asn1_uint64(&session, &verify_result,
SSLASN1_VERIFY_RESULT_TAG, X509_V_OK))
goto err;
if (verify_result > LONG_MAX)
goto err;
s->verify_result = (long)verify_result;
/* Hostname [6]. */
free(s->tlsext_hostname);
s->tlsext_hostname = NULL;
if (!CBS_get_optional_asn1_octet_string(&session, &hostname, &present,
SSLASN1_HOSTNAME_TAG))
goto err;
if (present) {
if (CBS_contains_zero_byte(&hostname))
goto err;
if (!CBS_strdup(&hostname, &s->tlsext_hostname))
goto err;
}
/* PSK identity hint [7]. */
/* PSK identity [8]. */
/* Ticket lifetime [9]. */
s->tlsext_tick_lifetime_hint = 0;
/* XXX - tlsext_ticklen is not yet set... */
if (s->tlsext_ticklen > 0 && s->session_id_length > 0)
s->tlsext_tick_lifetime_hint = -1;
if (!CBS_get_optional_asn1_uint64(&session, &lifetime,
SSLASN1_LIFETIME_TAG, 0))
goto err;
if (lifetime > LONG_MAX)
goto err;
if (lifetime > 0)
s->tlsext_tick_lifetime_hint = (long)lifetime;
/* Ticket [10]. */
free(s->tlsext_tick);
s->tlsext_tick = NULL;
if (!CBS_get_optional_asn1_octet_string(&session, &ticket, &present,
SSLASN1_TICKET_TAG))
goto err;
if (present) {
if (!CBS_stow(&ticket, &s->tlsext_tick, &s->tlsext_ticklen))
goto err;
}
/* Compression method [11]. */
/* SRP username [12]. */
*pp = CBS_data(&cbs);
if (a != NULL)
*a = s;
return (s);
err:
ERR_asprintf_error_data("offset=%d", (int)(CBS_data(&cbs) - *pp));
if (s != NULL && (a == NULL || *a != s))
SSL_SESSION_free(s);
return (NULL);
}

790
externals/libressl/ssl/ssl_both.c vendored Executable file
View File

@@ -0,0 +1,790 @@
/* $OpenBSD: ssl_both.c,v 1.20 2020/09/24 18:12:00 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "ssl_locl.h"
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "bytestring.h"
/*
* Send s->internal->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
* SSL3_RT_CHANGE_CIPHER_SPEC).
*/
int
ssl3_do_write(SSL *s, int type)
{
int ret;
ret = ssl3_write_bytes(s, type, &s->internal->init_buf->data[s->internal->init_off],
s->internal->init_num);
if (ret < 0)
return (-1);
if (type == SSL3_RT_HANDSHAKE)
/*
* Should not be done for 'Hello Request's, but in that case
* we'll ignore the result anyway.
*/
tls1_transcript_record(s,
(unsigned char *)&s->internal->init_buf->data[s->internal->init_off], ret);
if (ret == s->internal->init_num) {
if (s->internal->msg_callback)
s->internal->msg_callback(1, s->version, type, s->internal->init_buf->data,
(size_t)(s->internal->init_off + s->internal->init_num), s,
s->internal->msg_callback_arg);
return (1);
}
s->internal->init_off += ret;
s->internal->init_num -= ret;
return (0);
}
int
ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
{
CBB cbb, finished;
int md_len;
memset(&cbb, 0, sizeof(cbb));
if (S3I(s)->hs.state == a) {
md_len = TLS1_FINISH_MAC_LENGTH;
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
if (tls1_final_finish_mac(s, sender, slen,
S3I(s)->tmp.finish_md) != md_len)
return (0);
S3I(s)->tmp.finish_md_len = md_len;
/* Copy finished so we can use it for renegotiation checks. */
if (s->internal->type == SSL_ST_CONNECT) {
memcpy(S3I(s)->previous_client_finished,
S3I(s)->tmp.finish_md, md_len);
S3I(s)->previous_client_finished_len = md_len;
} else {
memcpy(S3I(s)->previous_server_finished,
S3I(s)->tmp.finish_md, md_len);
S3I(s)->previous_server_finished_len = md_len;
}
if (!ssl3_handshake_msg_start(s, &cbb, &finished,
SSL3_MT_FINISHED))
goto err;
if (!CBB_add_bytes(&finished, S3I(s)->tmp.finish_md, md_len))
goto err;
if (!ssl3_handshake_msg_finish(s, &cbb))
goto err;
S3I(s)->hs.state = b;
}
return (ssl3_handshake_write(s));
err:
CBB_cleanup(&cbb);
return (-1);
}
/*
* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
* so far.
*/
static void
ssl3_take_mac(SSL *s)
{
const char *sender;
int slen;
/*
* If no new cipher setup return immediately: other functions will
* set the appropriate error.
*/
if (S3I(s)->hs.new_cipher == NULL)
return;
if (S3I(s)->hs.state & SSL_ST_CONNECT) {
sender = TLS_MD_SERVER_FINISH_CONST;
slen = TLS_MD_SERVER_FINISH_CONST_SIZE;
} else {
sender = TLS_MD_CLIENT_FINISH_CONST;
slen = TLS_MD_CLIENT_FINISH_CONST_SIZE;
}
S3I(s)->tmp.peer_finish_md_len =
tls1_final_finish_mac(s, sender, slen,
S3I(s)->tmp.peer_finish_md);
}
int
ssl3_get_finished(SSL *s, int a, int b)
{
int al, ok, md_len;
long n;
CBS cbs;
/* should actually be 36+4 :-) */
n = ssl3_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
if (!ok)
return ((int)n);
/* If this occurs, we have missed a message */
if (!S3I(s)->change_cipher_spec) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
goto f_err;
}
S3I(s)->change_cipher_spec = 0;
md_len = TLS1_FINISH_MAC_LENGTH;
if (n < 0) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
}
CBS_init(&cbs, s->internal->init_msg, n);
if (S3I(s)->tmp.peer_finish_md_len != md_len ||
CBS_len(&cbs) != md_len) {
al = SSL_AD_DECODE_ERROR;
SSLerror(s, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
}
if (!CBS_mem_equal(&cbs, S3I(s)->tmp.peer_finish_md, CBS_len(&cbs))) {
al = SSL_AD_DECRYPT_ERROR;
SSLerror(s, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
}
/* Copy finished so we can use it for renegotiation checks. */
OPENSSL_assert(md_len <= EVP_MAX_MD_SIZE);
if (s->internal->type == SSL_ST_ACCEPT) {
memcpy(S3I(s)->previous_client_finished,
S3I(s)->tmp.peer_finish_md, md_len);
S3I(s)->previous_client_finished_len = md_len;
} else {
memcpy(S3I(s)->previous_server_finished,
S3I(s)->tmp.peer_finish_md, md_len);
S3I(s)->previous_server_finished_len = md_len;
}
return (1);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
return (0);
}
/* for these 2 messages, we need to
* ssl->enc_read_ctx re-init
* ssl->s3->internal->read_sequence zero
* ssl->s3->internal->read_mac_secret re-init
* ssl->session->read_sym_enc assign
* ssl->session->read_hash assign
*/
int
ssl3_send_change_cipher_spec(SSL *s, int a, int b)
{
size_t outlen;
CBB cbb;
memset(&cbb, 0, sizeof(cbb));
if (S3I(s)->hs.state == a) {
if (!CBB_init_fixed(&cbb, s->internal->init_buf->data,
s->internal->init_buf->length))
goto err;
if (!CBB_add_u8(&cbb, SSL3_MT_CCS))
goto err;
if (!CBB_finish(&cbb, NULL, &outlen))
goto err;
if (outlen > INT_MAX)
goto err;
s->internal->init_num = (int)outlen;
s->internal->init_off = 0;
if (SSL_IS_DTLS(s)) {
D1I(s)->handshake_write_seq =
D1I(s)->next_handshake_write_seq;
dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
D1I(s)->handshake_write_seq, 0, 0);
dtls1_buffer_message(s, 1);
}
S3I(s)->hs.state = b;
}
/* SSL3_ST_CW_CHANGE_B */
return ssl3_record_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
err:
CBB_cleanup(&cbb);
return -1;
}
static int
ssl3_add_cert(CBB *cbb, X509 *x)
{
unsigned char *data;
int cert_len;
int ret = 0;
CBB cert;
if ((cert_len = i2d_X509(x, NULL)) < 0)
goto err;
if (!CBB_add_u24_length_prefixed(cbb, &cert))
goto err;
if (!CBB_add_space(&cert, &data, cert_len))
goto err;
if (i2d_X509(x, &data) < 0)
goto err;
if (!CBB_flush(cbb))
goto err;
ret = 1;
err:
return (ret);
}
int
ssl3_output_cert_chain(SSL *s, CBB *cbb, CERT_PKEY *cpk)
{
X509_STORE_CTX *xs_ctx = NULL;
STACK_OF(X509) *chain;
CBB cert_list;
X509 *x;
int ret = 0;
int i;
if (!CBB_add_u24_length_prefixed(cbb, &cert_list))
goto err;
/* Send an empty certificate list when no certificate is available. */
if (cpk == NULL)
goto done;
if ((chain = cpk->chain) == NULL)
chain = s->ctx->extra_certs;
if (chain != NULL || (s->internal->mode & SSL_MODE_NO_AUTO_CHAIN)) {
if (!ssl3_add_cert(&cert_list, cpk->x509))
goto err;
} else {
if ((xs_ctx = X509_STORE_CTX_new()) == NULL)
goto err;
if (!X509_STORE_CTX_init(xs_ctx, s->ctx->cert_store,
cpk->x509, NULL)) {
SSLerror(s, ERR_R_X509_LIB);
goto err;
}
X509_verify_cert(xs_ctx);
ERR_clear_error();
chain = xs_ctx->chain;
}
for (i = 0; i < sk_X509_num(chain); i++) {
x = sk_X509_value(chain, i);
if (!ssl3_add_cert(&cert_list, x))
goto err;
}
done:
if (!CBB_flush(cbb))
goto err;
ret = 1;
err:
X509_STORE_CTX_free(xs_ctx);
return (ret);
}
/*
* Obtain handshake message of message type 'mt' (any if mt == -1),
* maximum acceptable body length 'max'.
* The first four bytes (msg_type and length) are read in state 'st1',
* the body is read in state 'stn'.
*/
long
ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
{
unsigned char *p;
uint32_t l;
long n;
int i, al;
CBS cbs;
uint8_t u8;
if (SSL_IS_DTLS(s))
return (dtls1_get_message(s, st1, stn, mt, max, ok));
if (S3I(s)->tmp.reuse_message) {
S3I(s)->tmp.reuse_message = 0;
if ((mt >= 0) && (S3I(s)->tmp.message_type != mt)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
*ok = 1;
s->internal->init_msg = s->internal->init_buf->data + 4;
s->internal->init_num = (int)S3I(s)->tmp.message_size;
return s->internal->init_num;
}
p = (unsigned char *)s->internal->init_buf->data;
/* s->internal->init_num < 4 */
if (S3I(s)->hs.state == st1) {
int skip_message;
do {
while (s->internal->init_num < 4) {
i = s->method->internal->ssl_read_bytes(s,
SSL3_RT_HANDSHAKE, &p[s->internal->init_num],
4 - s->internal->init_num, 0);
if (i <= 0) {
s->internal->rwstate = SSL_READING;
*ok = 0;
return i;
}
s->internal->init_num += i;
}
skip_message = 0;
if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) {
/*
* The server may always send 'Hello Request'
* messages -- we are doing a handshake anyway
* now, so ignore them if their format is
* correct. Does not count for 'Finished' MAC.
*/
if (p[1] == 0 && p[2] == 0 &&p[3] == 0) {
s->internal->init_num = 0;
skip_message = 1;
if (s->internal->msg_callback)
s->internal->msg_callback(0, s->version,
SSL3_RT_HANDSHAKE, p, 4, s,
s->internal->msg_callback_arg);
}
}
} while (skip_message);
/* s->internal->init_num == 4 */
if ((mt >= 0) && (*p != mt)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
CBS_init(&cbs, p, 4);
if (!CBS_get_u8(&cbs, &u8) ||
!CBS_get_u24(&cbs, &l)) {
SSLerror(s, ERR_R_BUF_LIB);
goto err;
}
S3I(s)->tmp.message_type = u8;
if (l > (unsigned long)max) {
al = SSL_AD_ILLEGAL_PARAMETER;
SSLerror(s, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto f_err;
}
if (l && !BUF_MEM_grow_clean(s->internal->init_buf, l + 4)) {
SSLerror(s, ERR_R_BUF_LIB);
goto err;
}
S3I(s)->tmp.message_size = l;
S3I(s)->hs.state = stn;
s->internal->init_msg = s->internal->init_buf->data + 4;
s->internal->init_num = 0;
}
/* next state (stn) */
p = s->internal->init_msg;
n = S3I(s)->tmp.message_size - s->internal->init_num;
while (n > 0) {
i = s->method->internal->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
&p[s->internal->init_num], n, 0);
if (i <= 0) {
s->internal->rwstate = SSL_READING;
*ok = 0;
return i;
}
s->internal->init_num += i;
n -= i;
}
/* If receiving Finished, record MAC of prior handshake messages for
* Finished verification. */
if (*s->internal->init_buf->data == SSL3_MT_FINISHED)
ssl3_take_mac(s);
/* Feed this message into MAC computation. */
if (s->internal->mac_packet) {
tls1_transcript_record(s, (unsigned char *)s->internal->init_buf->data,
s->internal->init_num + 4);
if (s->internal->msg_callback)
s->internal->msg_callback(0, s->version,
SSL3_RT_HANDSHAKE, s->internal->init_buf->data,
(size_t)s->internal->init_num + 4, s,
s->internal->msg_callback_arg);
}
*ok = 1;
return (s->internal->init_num);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
err:
*ok = 0;
return (-1);
}
int
ssl_cert_type(X509 *x, EVP_PKEY *pkey)
{
EVP_PKEY *pk;
int ret = -1, i;
if (pkey == NULL)
pk = X509_get_pubkey(x);
else
pk = pkey;
if (pk == NULL)
goto err;
i = pk->type;
if (i == EVP_PKEY_RSA) {
ret = SSL_PKEY_RSA;
} else if (i == EVP_PKEY_EC) {
ret = SSL_PKEY_ECC;
} else if (i == NID_id_GostR3410_2001 ||
i == NID_id_GostR3410_2001_cc) {
ret = SSL_PKEY_GOST01;
}
err:
if (!pkey)
EVP_PKEY_free(pk);
return (ret);
}
int
ssl_verify_alarm_type(long type)
{
int al;
switch (type) {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
case X509_V_ERR_UNABLE_TO_GET_CRL:
case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
al = SSL_AD_UNKNOWN_CA;
break;
case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_CRL_NOT_YET_VALID:
case X509_V_ERR_CERT_UNTRUSTED:
case X509_V_ERR_CERT_REJECTED:
al = SSL_AD_BAD_CERTIFICATE;
break;
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
case X509_V_ERR_CRL_SIGNATURE_FAILURE:
al = SSL_AD_DECRYPT_ERROR;
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_CRL_HAS_EXPIRED:
al = SSL_AD_CERTIFICATE_EXPIRED;
break;
case X509_V_ERR_CERT_REVOKED:
al = SSL_AD_CERTIFICATE_REVOKED;
break;
case X509_V_ERR_OUT_OF_MEM:
al = SSL_AD_INTERNAL_ERROR;
break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
case X509_V_ERR_INVALID_CA:
al = SSL_AD_UNKNOWN_CA;
break;
case X509_V_ERR_APPLICATION_VERIFICATION:
al = SSL_AD_HANDSHAKE_FAILURE;
break;
case X509_V_ERR_INVALID_PURPOSE:
al = SSL_AD_UNSUPPORTED_CERTIFICATE;
break;
default:
al = SSL_AD_CERTIFICATE_UNKNOWN;
break;
}
return (al);
}
int
ssl3_setup_init_buffer(SSL *s)
{
BUF_MEM *buf = NULL;
if (s->internal->init_buf != NULL)
return (1);
if ((buf = BUF_MEM_new()) == NULL)
goto err;
if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH))
goto err;
s->internal->init_buf = buf;
return (1);
err:
BUF_MEM_free(buf);
return (0);
}
void
ssl3_release_init_buffer(SSL *s)
{
BUF_MEM_free(s->internal->init_buf);
s->internal->init_buf = NULL;
s->internal->init_msg = NULL;
s->internal->init_num = 0;
s->internal->init_off = 0;
}
int
ssl3_setup_read_buffer(SSL *s)
{
unsigned char *p;
size_t len, align, headerlen;
if (SSL_IS_DTLS(s))
headerlen = DTLS1_RT_HEADER_LENGTH;
else
headerlen = SSL3_RT_HEADER_LENGTH;
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
if (S3I(s)->rbuf.buf == NULL) {
len = SSL3_RT_MAX_PLAIN_LENGTH +
SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
if ((p = calloc(1, len)) == NULL)
goto err;
S3I(s)->rbuf.buf = p;
S3I(s)->rbuf.len = len;
}
s->internal->packet = S3I(s)->rbuf.buf;
return 1;
err:
SSLerror(s, ERR_R_MALLOC_FAILURE);
return 0;
}
int
ssl3_setup_write_buffer(SSL *s)
{
unsigned char *p;
size_t len, align, headerlen;
if (SSL_IS_DTLS(s))
headerlen = DTLS1_RT_HEADER_LENGTH + 1;
else
headerlen = SSL3_RT_HEADER_LENGTH;
align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
if (S3I(s)->wbuf.buf == NULL) {
len = s->max_send_fragment +
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
if (!(s->internal->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
len += headerlen + align +
SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
if ((p = calloc(1, len)) == NULL)
goto err;
S3I(s)->wbuf.buf = p;
S3I(s)->wbuf.len = len;
}
return 1;
err:
SSLerror(s, ERR_R_MALLOC_FAILURE);
return 0;
}
int
ssl3_setup_buffers(SSL *s)
{
if (!ssl3_setup_read_buffer(s))
return 0;
if (!ssl3_setup_write_buffer(s))
return 0;
return 1;
}
void
ssl3_release_buffer(SSL3_BUFFER_INTERNAL *b)
{
freezero(b->buf, b->len);
b->buf = NULL;
b->len = 0;
}
void
ssl3_release_read_buffer(SSL *s)
{
ssl3_release_buffer(&S3I(s)->rbuf);
}
void
ssl3_release_write_buffer(SSL *s)
{
ssl3_release_buffer(&S3I(s)->wbuf);
}

721
externals/libressl/ssl/ssl_cert.c vendored Executable file
View File

@@ -0,0 +1,721 @@
/* $OpenBSD: ssl_cert.c,v 1.78 2020/06/05 17:55:24 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/objects.h>
#include <openssl/opensslconf.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include "ssl_locl.h"
int
SSL_get_ex_data_X509_STORE_CTX_idx(void)
{
static volatile int ssl_x509_store_ctx_idx = -1;
int got_write_lock = 0;
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
if (ssl_x509_store_ctx_idx < 0) {
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
got_write_lock = 1;
if (ssl_x509_store_ctx_idx < 0) {
ssl_x509_store_ctx_idx =
X509_STORE_CTX_get_ex_new_index(
0, "SSL for verify callback", NULL, NULL, NULL);
}
}
if (got_write_lock)
CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
else
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
return ssl_x509_store_ctx_idx;
}
CERT *
ssl_cert_new(void)
{
CERT *ret;
ret = calloc(1, sizeof(CERT));
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->key = &(ret->pkeys[SSL_PKEY_RSA]);
ret->references = 1;
return (ret);
}
CERT *
ssl_cert_dup(CERT *cert)
{
CERT *ret;
int i;
ret = calloc(1, sizeof(CERT));
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return (NULL);
}
/*
* same as ret->key = ret->pkeys + (cert->key - cert->pkeys),
* if you find that more readable
*/
ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
ret->valid = cert->valid;
ret->mask_k = cert->mask_k;
ret->mask_a = cert->mask_a;
if (cert->dh_tmp != NULL) {
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
if (ret->dh_tmp == NULL) {
SSLerrorx(ERR_R_DH_LIB);
goto err;
}
if (cert->dh_tmp->priv_key) {
BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
if (!b) {
SSLerrorx(ERR_R_BN_LIB);
goto err;
}
ret->dh_tmp->priv_key = b;
}
if (cert->dh_tmp->pub_key) {
BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
if (!b) {
SSLerrorx(ERR_R_BN_LIB);
goto err;
}
ret->dh_tmp->pub_key = b;
}
}
ret->dh_tmp_cb = cert->dh_tmp_cb;
ret->dh_tmp_auto = cert->dh_tmp_auto;
for (i = 0; i < SSL_PKEY_NUM; i++) {
if (cert->pkeys[i].x509 != NULL) {
ret->pkeys[i].x509 = cert->pkeys[i].x509;
CRYPTO_add(&ret->pkeys[i].x509->references, 1,
CRYPTO_LOCK_X509);
}
if (cert->pkeys[i].privatekey != NULL) {
ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
CRYPTO_LOCK_EVP_PKEY);
switch (i) {
/*
* If there was anything special to do for
* certain types of keys, we'd do it here.
* (Nothing at the moment, I think.)
*/
case SSL_PKEY_RSA:
/* We have an RSA key. */
break;
case SSL_PKEY_ECC:
/* We have an ECC key */
break;
case SSL_PKEY_GOST01:
/* We have a GOST key */
break;
default:
/* Can't happen. */
SSLerrorx(SSL_R_LIBRARY_BUG);
}
}
if (cert->pkeys[i].chain != NULL) {
if ((ret->pkeys[i].chain =
X509_chain_up_ref(cert->pkeys[i].chain)) == NULL)
goto err;
}
}
/*
* ret->extra_certs *should* exist, but currently the own certificate
* chain is held inside SSL_CTX
*/
ret->references = 1;
return (ret);
err:
DH_free(ret->dh_tmp);
for (i = 0; i < SSL_PKEY_NUM; i++) {
X509_free(ret->pkeys[i].x509);
EVP_PKEY_free(ret->pkeys[i].privatekey);
sk_X509_pop_free(ret->pkeys[i].chain, X509_free);
}
free (ret);
return NULL;
}
void
ssl_cert_free(CERT *c)
{
int i;
if (c == NULL)
return;
i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
if (i > 0)
return;
DH_free(c->dh_tmp);
for (i = 0; i < SSL_PKEY_NUM; i++) {
X509_free(c->pkeys[i].x509);
EVP_PKEY_free(c->pkeys[i].privatekey);
sk_X509_pop_free(c->pkeys[i].chain, X509_free);
}
free(c);
}
int
ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
{
if (c->key == NULL)
return 0;
sk_X509_pop_free(c->key->chain, X509_free);
c->key->chain = chain;
return 1;
}
int
ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
{
STACK_OF(X509) *new_chain = NULL;
if (chain != NULL) {
if ((new_chain = X509_chain_up_ref(chain)) == NULL)
return 0;
}
if (!ssl_cert_set0_chain(c, new_chain)) {
sk_X509_pop_free(new_chain, X509_free);
return 0;
}
return 1;
}
int
ssl_cert_add0_chain_cert(CERT *c, X509 *cert)
{
if (c->key == NULL)
return 0;
if (c->key->chain == NULL) {
if ((c->key->chain = sk_X509_new_null()) == NULL)
return 0;
}
if (!sk_X509_push(c->key->chain, cert))
return 0;
return 1;
}
int
ssl_cert_add1_chain_cert(CERT *c, X509 *cert)
{
if (!ssl_cert_add0_chain_cert(c, cert))
return 0;
X509_up_ref(cert);
return 1;
}
SESS_CERT *
ssl_sess_cert_new(void)
{
SESS_CERT *ret;
ret = calloc(1, sizeof *ret);
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA]);
ret->references = 1;
return ret;
}
void
ssl_sess_cert_free(SESS_CERT *sc)
{
int i;
if (sc == NULL)
return;
i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
if (i > 0)
return;
sk_X509_pop_free(sc->cert_chain, X509_free);
for (i = 0; i < SSL_PKEY_NUM; i++)
X509_free(sc->peer_pkeys[i].x509);
DH_free(sc->peer_dh_tmp);
EC_KEY_free(sc->peer_ecdh_tmp);
free(sc->peer_x25519_tmp);
free(sc);
}
int
ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
{
X509_STORE_CTX ctx;
X509 *x;
int ret;
if ((sk == NULL) || (sk_X509_num(sk) == 0))
return (0);
x = sk_X509_value(sk, 0);
if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
SSLerror(s, ERR_R_X509_LIB);
return (0);
}
X509_STORE_CTX_set_ex_data(&ctx,
SSL_get_ex_data_X509_STORE_CTX_idx(), s);
/*
* We need to inherit the verify parameters. These can be
* determined by the context: if its a server it will verify
* SSL client certificates or vice versa.
*/
X509_STORE_CTX_set_default(&ctx,
s->server ? "ssl_client" : "ssl_server");
/*
* Anything non-default in "param" should overwrite anything
* in the ctx.
*/
X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
if (s->internal->verify_callback)
X509_STORE_CTX_set_verify_cb(&ctx, s->internal->verify_callback);
if (s->ctx->internal->app_verify_callback != NULL)
ret = s->ctx->internal->app_verify_callback(&ctx,
s->ctx->internal->app_verify_arg);
else
ret = X509_verify_cert(&ctx);
s->verify_result = ctx.error;
X509_STORE_CTX_cleanup(&ctx);
return (ret);
}
static void
set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
STACK_OF(X509_NAME) *name_list)
{
sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
*ca_list = name_list;
}
STACK_OF(X509_NAME) *
SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk)
{
int i;
STACK_OF(X509_NAME) *ret;
X509_NAME *name = NULL;
if ((ret = sk_X509_NAME_new_null()) == NULL)
goto err;
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
if ((name = X509_NAME_dup(sk_X509_NAME_value(sk, i))) == NULL)
goto err;
if (!sk_X509_NAME_push(ret, name))
goto err;
}
return (ret);
err:
X509_NAME_free(name);
sk_X509_NAME_pop_free(ret, X509_NAME_free);
return NULL;
}
void
SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
{
set_client_CA_list(&(s->internal->client_CA), name_list);
}
void
SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
{
set_client_CA_list(&(ctx->internal->client_CA), name_list);
}
STACK_OF(X509_NAME) *
SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
{
return (ctx->internal->client_CA);
}
STACK_OF(X509_NAME) *
SSL_get_client_CA_list(const SSL *s)
{
if (s->internal->type == SSL_ST_CONNECT) {
/* We are in the client. */
if ((s->version >> 8) == SSL3_VERSION_MAJOR)
return (S3I(s)->tmp.ca_names);
else
return (NULL);
} else {
if (s->internal->client_CA != NULL)
return (s->internal->client_CA);
else
return (s->ctx->internal->client_CA);
}
}
static int
add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
{
X509_NAME *name;
if (x == NULL)
return (0);
if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
return (0);
if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
return (0);
if (!sk_X509_NAME_push(*sk, name)) {
X509_NAME_free(name);
return (0);
}
return (1);
}
int
SSL_add_client_CA(SSL *ssl, X509 *x)
{
return (add_client_CA(&(ssl->internal->client_CA), x));
}
int
SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
{
return (add_client_CA(&(ctx->internal->client_CA), x));
}
static int
xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
{
return (X509_NAME_cmp(*a, *b));
}
/*!
* Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
* it doesn't really have anything to do with clients (except that a common use
* for a stack of CAs is to send it to the client). Actually, it doesn't have
* much to do with CAs, either, since it will load any old cert.
* \param file the file containing one or more certs.
* \return a ::STACK containing the certs.
*/
STACK_OF(X509_NAME) *
SSL_load_client_CA_file(const char *file)
{
BIO *in;
X509 *x = NULL;
X509_NAME *xn = NULL;
STACK_OF(X509_NAME) *ret = NULL, *sk;
sk = sk_X509_NAME_new(xname_cmp);
in = BIO_new(BIO_s_file_internal());
if ((sk == NULL) || (in == NULL)) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BIO_read_filename(in, file))
goto err;
for (;;) {
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
break;
if (ret == NULL) {
ret = sk_X509_NAME_new_null();
if (ret == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
goto err;
}
}
if ((xn = X509_get_subject_name(x)) == NULL) goto err;
/* check for duplicates */
xn = X509_NAME_dup(xn);
if (xn == NULL)
goto err;
if (sk_X509_NAME_find(sk, xn) >= 0)
X509_NAME_free(xn);
else {
sk_X509_NAME_push(sk, xn);
sk_X509_NAME_push(ret, xn);
}
}
if (0) {
err:
sk_X509_NAME_pop_free(ret, X509_NAME_free);
ret = NULL;
}
sk_X509_NAME_free(sk);
BIO_free(in);
X509_free(x);
if (ret != NULL)
ERR_clear_error();
return (ret);
}
/*!
* Add a file of certs to a stack.
* \param stack the stack to add to.
* \param file the file to add from. All certs in this file that are not
* already in the stack will be added.
* \return 1 for success, 0 for failure. Note that in the case of failure some
* certs may have been added to \c stack.
*/
int
SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
const char *file)
{
BIO *in;
X509 *x = NULL;
X509_NAME *xn = NULL;
int ret = 1;
int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerrorx(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BIO_read_filename(in, file))
goto err;
for (;;) {
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
break;
if ((xn = X509_get_subject_name(x)) == NULL) goto err;
xn = X509_NAME_dup(xn);
if (xn == NULL)
goto err;
if (sk_X509_NAME_find(stack, xn) >= 0)
X509_NAME_free(xn);
else
sk_X509_NAME_push(stack, xn);
}
ERR_clear_error();
if (0) {
err:
ret = 0;
}
BIO_free(in);
X509_free(x);
(void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
return ret;
}
/*!
* Add a directory of certs to a stack.
* \param stack the stack to append to.
* \param dir the directory to append from. All files in this directory will be
* examined as potential certs. Any that are acceptable to
* SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
* be included.
* \return 1 for success, 0 for failure. Note that in the case of failure some
* certs may have been added to \c stack.
*/
int
SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir)
{
DIR *dirp = NULL;
char *path = NULL;
int ret = 0;
dirp = opendir(dir);
if (dirp) {
struct dirent *dp;
while ((dp = readdir(dirp)) != NULL) {
if (asprintf(&path, "%s/%s", dir, dp->d_name) != -1) {
ret = SSL_add_file_cert_subjects_to_stack(
stack, path);
free(path);
}
if (!ret)
break;
}
(void) closedir(dirp);
}
if (!ret) {
SYSerror(errno);
ERR_asprintf_error_data("opendir ('%s')", dir);
SSLerrorx(ERR_R_SYS_LIB);
}
return ret;
}

1704
externals/libressl/ssl/ssl_ciph.c vendored Executable file

File diff suppressed because it is too large Load Diff

296
externals/libressl/ssl/ssl_ciphers.c vendored Executable file
View File

@@ -0,0 +1,296 @@
/* $OpenBSD: ssl_ciphers.c,v 1.9 2020/09/15 15:28:38 schwarze Exp $ */
/*
* Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org>
* Copyright (c) 2015-2018, 2020 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <openssl/safestack.h>
#include "bytestring.h"
#include "ssl_locl.h"
int
ssl_cipher_in_list(STACK_OF(SSL_CIPHER) *ciphers, const SSL_CIPHER *cipher)
{
int i;
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
if (sk_SSL_CIPHER_value(ciphers, i)->id == cipher->id)
return 1;
}
return 0;
}
int
ssl_cipher_allowed_in_version_range(const SSL_CIPHER *cipher, uint16_t min_ver,
uint16_t max_ver)
{
/* XXX: We only support DTLSv1 which is effectively TLSv1.1 */
if (min_ver == DTLS1_VERSION || max_ver == DTLS1_VERSION)
min_ver = max_ver = TLS1_1_VERSION;
switch(cipher->algorithm_ssl) {
case SSL_SSLV3:
if (min_ver <= TLS1_2_VERSION)
return 1;
break;
case SSL_TLSV1_2:
if (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver)
return 1;
break;
case SSL_TLSV1_3:
if (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver)
return 1;
break;
}
return 0;
}
int
ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb)
{
SSL_CIPHER *cipher;
int num_ciphers = 0;
uint16_t min_vers, max_vers;
int i;
if (ciphers == NULL)
return 0;
if (!ssl_supported_version_range(s, &min_vers, &max_vers))
return 0;
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL)
return 0;
if (!ssl_cipher_allowed_in_version_range(cipher, min_vers,
max_vers))
continue;
if (!CBB_add_u16(cbb, ssl3_cipher_get_value(cipher)))
return 0;
num_ciphers++;
}
/* Add SCSV if there are other ciphers and we're not renegotiating. */
if (num_ciphers > 0 && !s->internal->renegotiate) {
if (!CBB_add_u16(cbb, SSL3_CK_SCSV & SSL3_CK_VALUE_MASK))
return 0;
}
if (!CBB_flush(cbb))
return 0;
return 1;
}
STACK_OF(SSL_CIPHER) *
ssl_bytes_to_cipher_list(SSL *s, CBS *cbs)
{
STACK_OF(SSL_CIPHER) *ciphers = NULL;
const SSL_CIPHER *cipher;
uint16_t cipher_value, max_version;
unsigned long cipher_id;
S3I(s)->send_connection_binding = 0;
if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
while (CBS_len(cbs) > 0) {
if (!CBS_get_u16(cbs, &cipher_value)) {
SSLerror(s, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
goto err;
}
cipher_id = SSL3_CK_ID | cipher_value;
if (cipher_id == SSL3_CK_SCSV) {
/*
* TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if
* renegotiating.
*/
if (s->internal->renegotiate) {
SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
ssl3_send_alert(s, SSL3_AL_FATAL,
SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
S3I(s)->send_connection_binding = 1;
continue;
}
if (cipher_id == SSL3_CK_FALLBACK_SCSV) {
/*
* TLS_FALLBACK_SCSV indicates that the client
* previously tried a higher protocol version.
* Fail if the current version is an unexpected
* downgrade.
*/
if (!ssl_downgrade_max_version(s, &max_version))
goto err;
if (s->version < max_version) {
SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK);
ssl3_send_alert(s, SSL3_AL_FATAL,
SSL_AD_INAPPROPRIATE_FALLBACK);
goto err;
}
continue;
}
if ((cipher = ssl3_get_cipher_by_value(cipher_value)) != NULL) {
if (!sk_SSL_CIPHER_push(ciphers, cipher)) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
}
}
return (ciphers);
err:
sk_SSL_CIPHER_free(ciphers);
return (NULL);
}
struct ssl_tls13_ciphersuite {
const char *name;
const char *alias;
unsigned long cid;
};
static const struct ssl_tls13_ciphersuite ssl_tls13_ciphersuites[] = {
{
.name = TLS1_3_TXT_AES_128_GCM_SHA256,
.alias = "TLS_AES_128_GCM_SHA256",
.cid = TLS1_3_CK_AES_128_GCM_SHA256,
},
{
.name = TLS1_3_TXT_AES_256_GCM_SHA384,
.alias = "TLS_AES_256_GCM_SHA384",
.cid = TLS1_3_CK_AES_256_GCM_SHA384,
},
{
.name = TLS1_3_TXT_CHACHA20_POLY1305_SHA256,
.alias = "TLS_CHACHA20_POLY1305_SHA256",
.cid = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
},
{
.name = TLS1_3_TXT_AES_128_CCM_SHA256,
.alias = "TLS_AES_128_CCM_SHA256",
.cid = TLS1_3_CK_AES_128_CCM_SHA256,
},
{
.name = TLS1_3_TXT_AES_128_CCM_8_SHA256,
.alias = "TLS_AES_128_CCM_8_SHA256",
.cid = TLS1_3_CK_AES_128_CCM_8_SHA256,
},
{
.name = NULL,
},
};
int
ssl_parse_ciphersuites(STACK_OF(SSL_CIPHER) **out_ciphers, const char *str)
{
const struct ssl_tls13_ciphersuite *ciphersuite;
STACK_OF(SSL_CIPHER) *ciphers;
const SSL_CIPHER *cipher;
char *s = NULL;
char *p, *q;
int i;
int ret = 0;
if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL)
goto err;
/* An empty string is valid and means no ciphers. */
if (strcmp(str, "") == 0)
goto done;
if ((s = strdup(str)) == NULL)
goto err;
q = s;
while ((p = strsep(&q, ":")) != NULL) {
ciphersuite = &ssl_tls13_ciphersuites[0];
for (i = 0; ciphersuite->name != NULL; i++) {
if (strcmp(p, ciphersuite->name) == 0)
break;
if (strcmp(p, ciphersuite->alias) == 0)
break;
ciphersuite = &ssl_tls13_ciphersuites[i];
}
if (ciphersuite->name == NULL)
goto err;
/* We know about the cipher suite, but it is not supported. */
if ((cipher = ssl3_get_cipher_by_id(ciphersuite->cid)) == NULL)
continue;
if (!sk_SSL_CIPHER_push(ciphers, cipher))
goto err;
}
done:
sk_SSL_CIPHER_free(*out_ciphers);
*out_ciphers = ciphers;
ciphers = NULL;
ret = 1;
err:
sk_SSL_CIPHER_free(ciphers);
free(s);
return ret;
}
int
ssl_merge_cipherlists(STACK_OF(SSL_CIPHER) *cipherlist,
STACK_OF(SSL_CIPHER) *cipherlist_tls13,
STACK_OF(SSL_CIPHER) **out_cipherlist)
{
STACK_OF(SSL_CIPHER) *ciphers = NULL;
const SSL_CIPHER *cipher;
int i, ret = 0;
if ((ciphers = sk_SSL_CIPHER_dup(cipherlist_tls13)) == NULL)
goto err;
for (i = 0; i < sk_SSL_CIPHER_num(cipherlist); i++) {
cipher = sk_SSL_CIPHER_value(cipherlist, i);
if (cipher->algorithm_ssl == SSL_TLSV1_3)
continue;
if (!sk_SSL_CIPHER_push(ciphers, cipher))
goto err;
}
sk_SSL_CIPHER_free(*out_cipherlist);
*out_cipherlist = ciphers;
ciphers = NULL;
ret = 1;
err:
sk_SSL_CIPHER_free(ciphers);
return ret;
}

2768
externals/libressl/ssl/ssl_clnt.c vendored Executable file

File diff suppressed because it is too large Load Diff

668
externals/libressl/ssl/ssl_err.c vendored Executable file
View File

@@ -0,0 +1,668 @@
/* $OpenBSD: ssl_err.c,v 1.37 2020/01/21 05:19:02 jsing Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include "ssl_locl.h"
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason)
/* See SSL_state_func_code below */
static ERR_STRING_DATA SSL_str_functs[]= {
{ERR_FUNC(1), "CONNECT_CW_FLUSH"},
{ERR_FUNC(2), "CONNECT_CW_CLNT_HELLO"},
{ERR_FUNC(3), "CONNECT_CW_CLNT_HELLO"},
{ERR_FUNC(4), "CONNECT_CR_SRVR_HELLO"},
{ERR_FUNC(5), "CONNECT_CR_SRVR_HELLO"},
{ERR_FUNC(6), "CONNECT_CR_CERT"},
{ERR_FUNC(7), "CONNECT_CR_CERT"},
{ERR_FUNC(8), "CONNECT_CR_KEY_EXCH"},
{ERR_FUNC(9), "CONNECT_CR_KEY_EXCH"},
{ERR_FUNC(10), "CONNECT_CR_CERT_REQ"},
{ERR_FUNC(11), "CONNECT_CR_CERT_REQ"},
{ERR_FUNC(12), "CONNECT_CR_SRVR_DONE"},
{ERR_FUNC(13), "CONNECT_CR_SRVR_DONE"},
{ERR_FUNC(14), "CONNECT_CW_CERT"},
{ERR_FUNC(15), "CONNECT_CW_CERT"},
{ERR_FUNC(16), "CONNECT_CW_CERT_C"},
{ERR_FUNC(17), "CONNECT_CW_CERT_D"},
{ERR_FUNC(18), "CONNECT_CW_KEY_EXCH"},
{ERR_FUNC(19), "CONNECT_CW_KEY_EXCH"},
{ERR_FUNC(20), "CONNECT_CW_CERT_VRFY"},
{ERR_FUNC(21), "CONNECT_CW_CERT_VRFY"},
{ERR_FUNC(22), "CONNECT_CW_CHANGE"},
{ERR_FUNC(23), "CONNECT_CW_CHANGE"},
{ERR_FUNC(26), "CONNECT_CW_FINISHED"},
{ERR_FUNC(27), "CONNECT_CW_FINISHED"},
{ERR_FUNC(28), "CONNECT_CR_CHANGE"},
{ERR_FUNC(29), "CONNECT_CR_CHANGE"},
{ERR_FUNC(30), "CONNECT_CR_FINISHED"},
{ERR_FUNC(31), "CONNECT_CR_FINISHED"},
{ERR_FUNC(32), "CONNECT_CR_SESSION_TICKET"},
{ERR_FUNC(33), "CONNECT_CR_SESSION_TICKET"},
{ERR_FUNC(34), "CONNECT_CR_CERT_STATUS"},
{ERR_FUNC(35), "CONNECT_CR_CERT_STATUS"},
{ERR_FUNC(36), "ACCEPT_SW_FLUSH"},
{ERR_FUNC(37), "ACCEPT_SR_CLNT_HELLO"},
{ERR_FUNC(38), "ACCEPT_SR_CLNT_HELLO"},
{ERR_FUNC(39), "ACCEPT_SR_CLNT_HELLO_C"},
{ERR_FUNC(40), "ACCEPT_SW_HELLO_REQ"},
{ERR_FUNC(41), "ACCEPT_SW_HELLO_REQ"},
{ERR_FUNC(42), "ACCEPT_SW_HELLO_REQ_C"},
{ERR_FUNC(43), "ACCEPT_SW_SRVR_HELLO"},
{ERR_FUNC(44), "ACCEPT_SW_SRVR_HELLO"},
{ERR_FUNC(45), "ACCEPT_SW_CERT"},
{ERR_FUNC(46), "ACCEPT_SW_CERT"},
{ERR_FUNC(47), "ACCEPT_SW_KEY_EXCH"},
{ERR_FUNC(48), "ACCEPT_SW_KEY_EXCH"},
{ERR_FUNC(49), "ACCEPT_SW_CERT_REQ"},
{ERR_FUNC(50), "ACCEPT_SW_CERT_REQ"},
{ERR_FUNC(51), "ACCEPT_SW_SRVR_DONE"},
{ERR_FUNC(52), "ACCEPT_SW_SRVR_DONE"},
{ERR_FUNC(53), "ACCEPT_SR_CERT"},
{ERR_FUNC(54), "ACCEPT_SR_CERT"},
{ERR_FUNC(55), "ACCEPT_SR_KEY_EXCH"},
{ERR_FUNC(56), "ACCEPT_SR_KEY_EXCH"},
{ERR_FUNC(57), "ACCEPT_SR_CERT_VRFY"},
{ERR_FUNC(58), "ACCEPT_SR_CERT_VRFY"},
{ERR_FUNC(59), "ACCEPT_SR_CHANGE"},
{ERR_FUNC(60), "ACCEPT_SR_CHANGE"},
{ERR_FUNC(63), "ACCEPT_SR_FINISHED"},
{ERR_FUNC(64), "ACCEPT_SR_FINISHED"},
{ERR_FUNC(65), "ACCEPT_SW_CHANGE"},
{ERR_FUNC(66), "ACCEPT_SW_CHANGE"},
{ERR_FUNC(67), "ACCEPT_SW_FINISHED"},
{ERR_FUNC(68), "ACCEPT_SW_FINISHED"},
{ERR_FUNC(69), "ACCEPT_SW_SESSION_TICKET"},
{ERR_FUNC(70), "ACCEPT_SW_SESSION_TICKET"},
{ERR_FUNC(71), "ACCEPT_SW_CERT_STATUS"},
{ERR_FUNC(72), "ACCEPT_SW_CERT_STATUS"},
{ERR_FUNC(73), "ST_BEFORE"},
{ERR_FUNC(74), "ST_ACCEPT"},
{ERR_FUNC(75), "ST_CONNECT"},
{ERR_FUNC(76), "ST_OK"},
{ERR_FUNC(77), "ST_RENEGOTIATE"},
{ERR_FUNC(78), "ST_BEFORE_CONNECT"},
{ERR_FUNC(79), "ST_OK_CONNECT"},
{ERR_FUNC(80), "ST_BEFORE_ACCEPT"},
{ERR_FUNC(81), "ST_OK_ACCEPT"},
{ERR_FUNC(83), "DTLS1_ST_CR_HELLO_VERIFY_REQUEST"},
{ERR_FUNC(84), "DTLS1_ST_CR_HELLO_VERIFY_REQUEST"},
{ERR_FUNC(85), "DTLS1_ST_SW_HELLO_VERIFY_REQUEST"},
{ERR_FUNC(86), "DTLS1_ST_SW_HELLO_VERIFY_REQUEST"},
{ERR_FUNC(0xfff), "(UNKNOWN)SSL_internal"},
{0, NULL}
};
static ERR_STRING_DATA SSL_str_reasons[]= {
{ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE) , "app data in handshake"},
{ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), "attempt to reuse session in different context"},
{ERR_REASON(SSL_R_BAD_ALERT_RECORD) , "bad alert record"},
{ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"},
{ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"},
{ERR_REASON(SSL_R_BAD_CHECKSUM) , "bad checksum"},
{ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), "bad data returned by callback"},
{ERR_REASON(SSL_R_BAD_DECOMPRESSION) , "bad decompression"},
{ERR_REASON(SSL_R_BAD_DH_G_LENGTH) , "bad dh g length"},
{ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH) , "bad dh pub key length"},
{ERR_REASON(SSL_R_BAD_DH_P_LENGTH) , "bad dh p length"},
{ERR_REASON(SSL_R_BAD_DIGEST_LENGTH) , "bad digest length"},
{ERR_REASON(SSL_R_BAD_DSA_SIGNATURE) , "bad dsa signature"},
{ERR_REASON(SSL_R_BAD_ECC_CERT) , "bad ecc cert"},
{ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE) , "bad ecdsa signature"},
{ERR_REASON(SSL_R_BAD_ECPOINT) , "bad ecpoint"},
{ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH) , "bad handshake length"},
{ERR_REASON(SSL_R_BAD_HELLO_REQUEST) , "bad hello request"},
{ERR_REASON(SSL_R_BAD_LENGTH) , "bad length"},
{ERR_REASON(SSL_R_BAD_MAC_DECODE) , "bad mac decode"},
{ERR_REASON(SSL_R_BAD_MAC_LENGTH) , "bad mac length"},
{ERR_REASON(SSL_R_BAD_MESSAGE_TYPE) , "bad message type"},
{ERR_REASON(SSL_R_BAD_PACKET_LENGTH) , "bad packet length"},
{ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), "bad protocol version number"},
{ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), "bad psk identity hint length"},
{ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT) , "bad response argument"},
{ERR_REASON(SSL_R_BAD_RSA_DECRYPT) , "bad rsa decrypt"},
{ERR_REASON(SSL_R_BAD_RSA_ENCRYPT) , "bad rsa encrypt"},
{ERR_REASON(SSL_R_BAD_RSA_E_LENGTH) , "bad rsa e length"},
{ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"},
{ERR_REASON(SSL_R_BAD_RSA_SIGNATURE) , "bad rsa signature"},
{ERR_REASON(SSL_R_BAD_SIGNATURE) , "bad signature"},
{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH) , "bad srp a length"},
{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH) , "bad srp b length"},
{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH) , "bad srp g length"},
{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH) , "bad srp n length"},
{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH) , "bad srp s length"},
{ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE) , "bad srtp mki value"},
{ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), "bad srtp protection profile list"},
{ERR_REASON(SSL_R_BAD_SSL_FILETYPE) , "bad ssl filetype"},
{ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), "bad ssl session id length"},
{ERR_REASON(SSL_R_BAD_STATE) , "bad state"},
{ERR_REASON(SSL_R_BAD_WRITE_RETRY) , "bad write retry"},
{ERR_REASON(SSL_R_BIO_NOT_SET) , "bio not set"},
{ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), "block cipher pad is wrong"},
{ERR_REASON(SSL_R_BN_LIB) , "bn lib"},
{ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) , "ca dn length mismatch"},
{ERR_REASON(SSL_R_CA_DN_TOO_LONG) , "ca dn too long"},
{ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) , "ccs received early"},
{ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), "certificate verify failed"},
{ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) , "cert length mismatch"},
{ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"},
{ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"},
{ERR_REASON(SSL_R_CIPHER_COMPRESSION_UNAVAILABLE), "cipher compression unavailable"},
{ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), "cipher or hash unavailable"},
{ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"},
{ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT) , "clienthello tlsext"},
{ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), "compressed length too long"},
{ERR_REASON(SSL_R_COMPRESSION_DISABLED) , "compression disabled"},
{ERR_REASON(SSL_R_COMPRESSION_FAILURE) , "compression failure"},
{ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), "compression id not within private range"},
{ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), "compression library error"},
{ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), "connection id is different"},
{ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"},
{ERR_REASON(SSL_R_COOKIE_MISMATCH) , "cookie mismatch"},
{ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), "data between ccs and finished"},
{ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) , "data length too long"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED) , "decryption failed"},
{ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), "decryption failed or bad record mac"},
{ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), "dh public value length is wrong"},
{ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) , "digest check failed"},
{ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) , "dtls message too big"},
{ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"},
{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), "ecc cert not for key agreement"},
{ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"},
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), "ecc cert should have rsa signature"},
{ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), "ecc cert should have sha1 signature"},
{ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), "ecgroup too large for cipher"},
{ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), "empty srtp protection profile list"},
{ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), "encrypted length too long"},
{ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), "error generating tmp rsa key"},
{ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), "error in received cipher list"},
{ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
{ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) , "extra data in message"},
{ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"},
{ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), "got next proto before a ccs"},
{ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), "got next proto without seeing extension"},
{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) , "https proxy request"},
{ERR_REASON(SSL_R_HTTP_REQUEST) , "http request"},
{ERR_REASON(SSL_R_ILLEGAL_PADDING) , "illegal padding"},
{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"},
{ERR_REASON(SSL_R_INVALID_COMMAND) , "invalid command"},
{ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), "invalid compression algorithm"},
{ERR_REASON(SSL_R_INVALID_PURPOSE) , "invalid purpose"},
{ERR_REASON(SSL_R_INVALID_SRP_USERNAME) , "invalid srp username"},
{ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"},
{ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), "invalid ticket keys length"},
{ERR_REASON(SSL_R_INVALID_TRUST) , "invalid trust"},
{ERR_REASON(SSL_R_KEY_ARG_TOO_LONG) , "key arg too long"},
{ERR_REASON(SSL_R_KRB5) , "krb5"},
{ERR_REASON(SSL_R_KRB5_C_CC_PRINC) , "krb5 client cc principal (no tkt?)"},
{ERR_REASON(SSL_R_KRB5_C_GET_CRED) , "krb5 client get cred"},
{ERR_REASON(SSL_R_KRB5_C_INIT) , "krb5 client init"},
{ERR_REASON(SSL_R_KRB5_C_MK_REQ) , "krb5 client mk_req (expired tkt?)"},
{ERR_REASON(SSL_R_KRB5_S_BAD_TICKET) , "krb5 server bad ticket"},
{ERR_REASON(SSL_R_KRB5_S_INIT) , "krb5 server init"},
{ERR_REASON(SSL_R_KRB5_S_RD_REQ) , "krb5 server rd_req (keytab perms?)"},
{ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED) , "krb5 server tkt expired"},
{ERR_REASON(SSL_R_KRB5_S_TKT_NYV) , "krb5 server tkt not yet valid"},
{ERR_REASON(SSL_R_KRB5_S_TKT_SKEW) , "krb5 server tkt skew"},
{ERR_REASON(SSL_R_LENGTH_MISMATCH) , "length mismatch"},
{ERR_REASON(SSL_R_LENGTH_TOO_SHORT) , "length too short"},
{ERR_REASON(SSL_R_LIBRARY_BUG) , "library bug"},
{ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"},
{ERR_REASON(SSL_R_MESSAGE_TOO_LONG) , "message too long"},
{ERR_REASON(SSL_R_MISSING_DH_DSA_CERT) , "missing dh dsa cert"},
{ERR_REASON(SSL_R_MISSING_DH_KEY) , "missing dh key"},
{ERR_REASON(SSL_R_MISSING_DH_RSA_CERT) , "missing dh rsa cert"},
{ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"},
{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), "missing export tmp dh key"},
{ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), "missing export tmp rsa key"},
{ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"},
{ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), "missing rsa encrypting cert"},
{ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"},
{ERR_REASON(SSL_R_MISSING_SRP_PARAM) , "can't find SRP server param"},
{ERR_REASON(SSL_R_MISSING_TMP_DH_KEY) , "missing tmp dh key"},
{ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY) , "missing tmp ecdh key"},
{ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY) , "missing tmp rsa key"},
{ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY) , "missing tmp rsa pkey"},
{ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"},
{ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS) , "multiple sgc restarts"},
{ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"},
{ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_SET) , "no certificate set"},
{ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"},
{ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE) , "no ciphers available"},
{ERR_REASON(SSL_R_NO_CIPHERS_PASSED) , "no ciphers passed"},
{ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED) , "no ciphers specified"},
{ERR_REASON(SSL_R_NO_CIPHER_LIST) , "no cipher list"},
{ERR_REASON(SSL_R_NO_CIPHER_MATCH) , "no cipher match"},
{ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) , "no client cert method"},
{ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"},
{ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"},
{ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), "Peer haven't sent GOST certificate, required for selected ciphersuite"},
{ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) , "no method specified"},
{ERR_REASON(SSL_R_NO_PRIVATEKEY) , "no privatekey"},
{ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"},
{ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"},
{ERR_REASON(SSL_R_NO_PUBLICKEY) , "no publickey"},
{ERR_REASON(SSL_R_NO_RENEGOTIATION) , "no renegotiation"},
{ERR_REASON(SSL_R_NO_REQUIRED_DIGEST) , "digest requred for handshake isn't computed"},
{ERR_REASON(SSL_R_NO_SHARED_CIPHER) , "no shared cipher"},
{ERR_REASON(SSL_R_NO_SRTP_PROFILES) , "no srtp profiles"},
{ERR_REASON(SSL_R_NO_VERIFY_CALLBACK) , "no verify callback"},
{ERR_REASON(SSL_R_NULL_SSL_CTX) , "null ssl ctx"},
{ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"},
{ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), "old session cipher not returned"},
{ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), "old session compression algorithm not returned"},
{ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), "only tls allowed in fips mode"},
{ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"},
{ERR_REASON(SSL_R_PARSE_TLSEXT) , "parse tlsext"},
{ERR_REASON(SSL_R_PATH_TOO_LONG) , "path too long"},
{ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), "peer did not return a certificate"},
{ERR_REASON(SSL_R_PEER_ERROR) , "peer error"},
{ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"},
{ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), "peer error no certificate"},
{ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER) , "peer error no cipher"},
{ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), "peer error unsupported certificate type"},
{ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"},
{ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), "problems mapping cipher functions"},
{ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN) , "protocol is shutdown"},
{ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"},
{ERR_REASON(SSL_R_PSK_NO_CLIENT_CB) , "psk no client cb"},
{ERR_REASON(SSL_R_PSK_NO_SERVER_CB) , "psk no server cb"},
{ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"},
{ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA) , "public key is not rsa"},
{ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA) , "public key not rsa"},
{ERR_REASON(SSL_R_READ_BIO_NOT_SET) , "read bio not set"},
{ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED) , "read timeout expired"},
{ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"},
{ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"},
{ERR_REASON(SSL_R_RECORD_TOO_LARGE) , "record too large"},
{ERR_REASON(SSL_R_RECORD_TOO_SMALL) , "record too small"},
{ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"},
{ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), "renegotiation encoding err"},
{ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"},
{ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"},
{ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), "required compresssion algorithm missing"},
{ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), "reuse cert length not zero"},
{ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"},
{ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), "reuse cipher list not zero"},
{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), "scsv received when renegotiating"},
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) , "serverhello tlsext"},
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), "session id context uninitialized"},
{ERR_REASON(SSL_R_SHORT_READ) , "short read"},
{ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), "signature algorithms error"},
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), "signature for non signing certificate"},
{ERR_REASON(SSL_R_SRP_A_CALC) , "error with the srp params"},
{ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), "srtp could not allocate profiles"},
{ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), "srtp protection profile list too long"},
{ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), "srtp unknown protection profile"},
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), "ssl23 doing session id reuse"},
{ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), "ssl2 connection id too long"},
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), "ssl3 ext invalid ecpointformat"},
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), "ssl3 ext invalid servername"},
{ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), "ssl3 ext invalid servername type"},
{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"},
{ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), "ssl3 session id too short"},
{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), "sslv3 alert bad certificate"},
{ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), "sslv3 alert bad record mac"},
{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), "sslv3 alert certificate expired"},
{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), "sslv3 alert certificate revoked"},
{ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), "sslv3 alert certificate unknown"},
{ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), "sslv3 alert decompression failure"},
{ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), "sslv3 alert handshake failure"},
{ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), "sslv3 alert illegal parameter"},
{ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), "sslv3 alert no certificate"},
{ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), "sslv3 alert unexpected message"},
{ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), "sslv3 alert unsupported certificate"},
{ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), "ssl ctx has no default ssl version"},
{ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE) , "ssl handshake failure"},
{ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), "ssl library has no ciphers"},
{ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), "ssl session id callback failed"},
{ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"},
{ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), "ssl session id context too long"},
{ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), "ssl session id has bad length"},
{ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), "ssl session id is different"},
{ERR_REASON(SSL_R_SSL_SESSION_ID_TOO_LONG), "ssl session id is too long"},
{ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), "tlsv1 alert access denied"},
{ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"},
{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), "tlsv1 alert decryption failed"},
{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), "tlsv1 alert decrypt error"},
{ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), "tlsv1 alert export restriction"},
{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), "tlsv1 alert inappropriate fallback"},
{ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), "tlsv1 alert insufficient security"},
{ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), "tlsv1 alert internal error"},
{ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), "tlsv1 alert no renegotiation"},
{ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), "tlsv1 alert protocol version"},
{ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), "tlsv1 alert record overflow"},
{ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"},
{ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), "tlsv1 alert user cancelled"},
{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), "tlsv1 bad certificate hash value"},
{ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), "tlsv1 bad certificate status response"},
{ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), "tlsv1 certificate unobtainable"},
{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"},
{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), "tlsv1 unsupported extension"},
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), "tls client cert req with anon cipher"},
{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), "peer does not accept heartbeats"},
{ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) , "heartbeat request already pending"},
{ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), "tls illegal exporter label"},
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), "tls invalid ecpointformat list"},
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), "tls peer did not respond with certificate list"},
{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), "tls rsa encrypted value length is wrong"},
{ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), "tried to use unsupported cipher"},
{ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), "unable to decode dh certs"},
{ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), "unable to decode ecdh certs"},
{ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), "unable to extract public key"},
{ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), "unable to find dh parameters"},
{ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), "unable to find ecdh parameters"},
{ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), "unable to find public key parameters"},
{ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), "unable to find ssl method"},
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), "unable to load ssl2 md5 routines"},
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), "unable to load ssl3 md5 routines"},
{ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), "unable to load ssl3 sha1 routines"},
{ERR_REASON(SSL_R_UNEXPECTED_MESSAGE) , "unexpected message"},
{ERR_REASON(SSL_R_UNEXPECTED_RECORD) , "unexpected record"},
{ERR_REASON(SSL_R_UNINITIALIZED) , "uninitialized"},
{ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE) , "unknown alert type"},
{ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"},
{ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) , "unknown cipher type"},
{ERR_REASON(SSL_R_UNKNOWN_DIGEST) , "unknown digest"},
{ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), "unknown key exchange type"},
{ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) , "unknown pkey type"},
{ERR_REASON(SSL_R_UNKNOWN_PROTOCOL) , "unknown protocol"},
{ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), "unknown remote error type"},
{ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION) , "unknown ssl version"},
{ERR_REASON(SSL_R_UNKNOWN_STATE) , "unknown state"},
{ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), "unsafe legacy renegotiation disabled"},
{ERR_REASON(SSL_R_UNSUPPORTED_CIPHER) , "unsupported cipher"},
{ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), "unsupported compression algorithm"},
{ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"},
{ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), "unsupported elliptic curve"},
{ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL) , "unsupported protocol"},
{ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"},
{ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"},
{ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"},
{ERR_REASON(SSL_R_WRITE_BIO_NOT_SET) , "write bio not set"},
{ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED) , "wrong cipher returned"},
{ERR_REASON(SSL_R_WRONG_CURVE) , "wrong curve"},
{ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE) , "wrong message type"},
{ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE) , "wrong signature size"},
{ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE) , "wrong signature type"},
{ERR_REASON(SSL_R_WRONG_SSL_VERSION) , "wrong ssl version"},
{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) , "wrong version number"},
{ERR_REASON(SSL_R_X509_LIB) , "x509 lib"},
{ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), "x509 verification setup problems"},
{ERR_REASON(SSL_R_PEER_BEHAVING_BADLY), "peer is doing strange or hostile things"},
{ERR_REASON(SSL_R_UNKNOWN), "unknown failure occurred"},
{0, NULL}
};
#endif
void
ERR_load_SSL_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) {
ERR_load_strings(0, SSL_str_functs);
ERR_load_strings(0, SSL_str_reasons);
}
#endif
}
void
SSL_load_error_strings(void)
{
#ifndef OPENSSL_NO_ERR
ERR_load_crypto_strings();
ERR_load_SSL_strings();
#endif
}
int
SSL_state_func_code(int state) {
switch (state) {
case SSL3_ST_CW_FLUSH:
return 1;
case SSL3_ST_CW_CLNT_HELLO_A:
return 2;
case SSL3_ST_CW_CLNT_HELLO_B:
return 3;
case SSL3_ST_CR_SRVR_HELLO_A:
return 4;
case SSL3_ST_CR_SRVR_HELLO_B:
return 5;
case SSL3_ST_CR_CERT_A:
return 6;
case SSL3_ST_CR_CERT_B:
return 7;
case SSL3_ST_CR_KEY_EXCH_A:
return 8;
case SSL3_ST_CR_KEY_EXCH_B:
return 9;
case SSL3_ST_CR_CERT_REQ_A:
return 10;
case SSL3_ST_CR_CERT_REQ_B:
return 11;
case SSL3_ST_CR_SRVR_DONE_A:
return 12;
case SSL3_ST_CR_SRVR_DONE_B:
return 13;
case SSL3_ST_CW_CERT_A:
return 14;
case SSL3_ST_CW_CERT_B:
return 15;
case SSL3_ST_CW_CERT_C:
return 16;
case SSL3_ST_CW_CERT_D:
return 17;
case SSL3_ST_CW_KEY_EXCH_A:
return 18;
case SSL3_ST_CW_KEY_EXCH_B:
return 19;
case SSL3_ST_CW_CERT_VRFY_A:
return 20;
case SSL3_ST_CW_CERT_VRFY_B:
return 21;
case SSL3_ST_CW_CHANGE_A:
return 22;
case SSL3_ST_CW_CHANGE_B:
return 23;
case SSL3_ST_CW_FINISHED_A:
return 26;
case SSL3_ST_CW_FINISHED_B:
return 27;
case SSL3_ST_CR_CHANGE_A:
return 28;
case SSL3_ST_CR_CHANGE_B:
return 29;
case SSL3_ST_CR_FINISHED_A:
return 30;
case SSL3_ST_CR_FINISHED_B:
return 31;
case SSL3_ST_CR_SESSION_TICKET_A:
return 32;
case SSL3_ST_CR_SESSION_TICKET_B:
return 33;
case SSL3_ST_CR_CERT_STATUS_A:
return 34;
case SSL3_ST_CR_CERT_STATUS_B:
return 35;
case SSL3_ST_SW_FLUSH:
return 36;
case SSL3_ST_SR_CLNT_HELLO_A:
return 37;
case SSL3_ST_SR_CLNT_HELLO_B:
return 38;
case SSL3_ST_SR_CLNT_HELLO_C:
return 39;
case SSL3_ST_SW_HELLO_REQ_A:
return 40;
case SSL3_ST_SW_HELLO_REQ_B:
return 41;
case SSL3_ST_SW_HELLO_REQ_C:
return 42;
case SSL3_ST_SW_SRVR_HELLO_A:
return 43;
case SSL3_ST_SW_SRVR_HELLO_B:
return 44;
case SSL3_ST_SW_CERT_A:
return 45;
case SSL3_ST_SW_CERT_B:
return 46;
case SSL3_ST_SW_KEY_EXCH_A:
return 47;
case SSL3_ST_SW_KEY_EXCH_B:
return 48;
case SSL3_ST_SW_CERT_REQ_A:
return 49;
case SSL3_ST_SW_CERT_REQ_B:
return 50;
case SSL3_ST_SW_SRVR_DONE_A:
return 51;
case SSL3_ST_SW_SRVR_DONE_B:
return 52;
case SSL3_ST_SR_CERT_A:
return 53;
case SSL3_ST_SR_CERT_B:
return 54;
case SSL3_ST_SR_KEY_EXCH_A:
return 55;
case SSL3_ST_SR_KEY_EXCH_B:
return 56;
case SSL3_ST_SR_CERT_VRFY_A:
return 57;
case SSL3_ST_SR_CERT_VRFY_B:
return 58;
case SSL3_ST_SR_CHANGE_A:
return 59;
case SSL3_ST_SR_CHANGE_B:
return 60;
case SSL3_ST_SR_FINISHED_A:
return 63;
case SSL3_ST_SR_FINISHED_B:
return 64;
case SSL3_ST_SW_CHANGE_A:
return 65;
case SSL3_ST_SW_CHANGE_B:
return 66;
case SSL3_ST_SW_FINISHED_A:
return 67;
case SSL3_ST_SW_FINISHED_B:
return 68;
case SSL3_ST_SW_SESSION_TICKET_A:
return 69;
case SSL3_ST_SW_SESSION_TICKET_B:
return 70;
case SSL3_ST_SW_CERT_STATUS_A:
return 71;
case SSL3_ST_SW_CERT_STATUS_B:
return 72;
case SSL_ST_BEFORE:
return 73;
case SSL_ST_ACCEPT:
return 74;
case SSL_ST_CONNECT:
return 75;
case SSL_ST_OK:
return 76;
case SSL_ST_RENEGOTIATE:
return 77;
case SSL_ST_BEFORE|SSL_ST_CONNECT:
return 78;
case SSL_ST_OK|SSL_ST_CONNECT:
return 79;
case SSL_ST_BEFORE|SSL_ST_ACCEPT:
return 80;
case SSL_ST_OK|SSL_ST_ACCEPT:
return 81;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
return 83;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
return 84;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
return 85;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
return 86;
default:
break;
}
return 0xfff;
}
void
SSL_error_internal(const SSL *s, int r, char *f, int l)
{
ERR_PUT_error(ERR_LIB_SSL,
(SSL_state_func_code(S3I(s)->hs.state)), r, f, l);
}

51
externals/libressl/ssl/ssl_init.c vendored Executable file
View File

@@ -0,0 +1,51 @@
/* $OpenBSD: ssl_init.c,v 1.2 2018/03/30 14:59:46 jsing Exp $ */
/*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OpenSSL style init */
#include <pthread.h>
#include <stdio.h>
#include <openssl/objects.h>
#include "ssl_locl.h"
static pthread_t ssl_init_thread;
static void
OPENSSL_init_ssl_internal(void)
{
ssl_init_thread = pthread_self();
SSL_load_error_strings();
SSL_library_init();
}
int
OPENSSL_init_ssl(uint64_t opts, const void *settings)
{
static pthread_once_t once = PTHREAD_ONCE_INIT;
if (pthread_equal(pthread_self(), ssl_init_thread))
return 1; /* don't recurse */
OPENSSL_init_crypto(opts, settings);
if (pthread_once(&once, OPENSSL_init_ssl_internal) != 0)
return 0;
return 1;
}

182
externals/libressl/ssl/ssl_kex.c vendored Executable file
View File

@@ -0,0 +1,182 @@
/* $OpenBSD: ssl_kex.c,v 1.2 2020/04/18 14:07:56 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "bytestring.h"
int
ssl_kex_dummy_ecdhe_x25519(EVP_PKEY *pkey)
{
EC_GROUP *group = NULL;
EC_POINT *point = NULL;
EC_KEY *ec_key = NULL;
BIGNUM *order = NULL;
int ret = 0;
/* Fudge up an EC_KEY that looks like X25519... */
if ((group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL)
goto err;
if ((point = EC_POINT_new(group)) == NULL)
goto err;
if ((order = BN_new()) == NULL)
goto err;
if (!BN_set_bit(order, 252))
goto err;
if (!EC_GROUP_set_generator(group, point, order, NULL))
goto err;
EC_GROUP_set_curve_name(group, NID_X25519);
if ((ec_key = EC_KEY_new()) == NULL)
goto err;
if (!EC_KEY_set_group(ec_key, group))
goto err;
if (!EVP_PKEY_set1_EC_KEY(pkey, ec_key))
goto err;
ret = 1;
err:
EC_GROUP_free(group);
EC_POINT_free(point);
EC_KEY_free(ec_key);
BN_free(order);
return ret;
}
int
ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid)
{
EC_GROUP *group;
int ret = 0;
if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
goto err;
if (!EC_KEY_set_group(ecdh, group))
goto err;
if (!EC_KEY_generate_key(ecdh))
goto err;
ret = 1;
err:
EC_GROUP_free(group);
return ret;
}
int
ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb)
{
const EC_GROUP *group;
const EC_POINT *point;
uint8_t *ecp;
size_t ecp_len;
int ret = 0;
if ((group = EC_KEY_get0_group(ecdh)) == NULL)
goto err;
if ((point = EC_KEY_get0_public_key(ecdh)) == NULL)
goto err;
if ((ecp_len = EC_POINT_point2oct(group, point,
POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)) == 0)
goto err;
if (!CBB_add_space(cbb, &ecp, ecp_len))
goto err;
if ((EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED,
ecp, ecp_len, NULL)) == 0)
goto err;
ret = 1;
err:
return ret;
}
int
ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs)
{
EC_GROUP *group = NULL;
EC_POINT *point = NULL;
int ret = 0;
if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL)
goto err;
if (!EC_KEY_set_group(ecdh, group))
goto err;
if ((point = EC_POINT_new(group)) == NULL)
goto err;
if (EC_POINT_oct2point(group, point, CBS_data(cbs), CBS_len(cbs),
NULL) == 0)
goto err;
if (!EC_KEY_set_public_key(ecdh, point))
goto err;
ret = 1;
err:
EC_GROUP_free(group);
EC_POINT_free(point);
return ret;
}
int
ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer,
uint8_t **shared_key, size_t *shared_key_len)
{
const EC_POINT *point;
uint8_t *sk = NULL;
int sk_len = 0;
int ret = 0;
if (!EC_GROUP_check(EC_KEY_get0_group(ecdh), NULL))
goto err;
if (!EC_GROUP_check(EC_KEY_get0_group(ecdh_peer), NULL))
goto err;
if ((point = EC_KEY_get0_public_key(ecdh_peer)) == NULL)
goto err;
if ((sk_len = ECDH_size(ecdh)) <= 0)
goto err;
if ((sk = calloc(1, sk_len)) == NULL)
goto err;
if (ECDH_compute_key(sk, sk_len, point, ecdh, NULL) <= 0)
goto err;
*shared_key = sk;
*shared_key_len = sk_len;
sk = NULL;
ret = 1;
err:
freezero(sk, sk_len);
return ret;
}

3067
externals/libressl/ssl/ssl_lib.c vendored Executable file

File diff suppressed because it is too large Load Diff

1439
externals/libressl/ssl/ssl_locl.h vendored Executable file

File diff suppressed because it is too large Load Diff

742
externals/libressl/ssl/ssl_methods.c vendored Executable file
View File

@@ -0,0 +1,742 @@
/* $OpenBSD: ssl_methods.c,v 1.16 2020/09/17 15:23:29 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "ssl_locl.h"
#include "tls13_internal.h"
static const SSL_METHOD_INTERNAL DTLSv1_client_method_internal_data = {
.version = DTLS1_VERSION,
.min_version = DTLS1_VERSION,
.max_version = DTLS1_VERSION,
.ssl_new = dtls1_new,
.ssl_clear = dtls1_clear,
.ssl_free = dtls1_free,
.ssl_accept = ssl_undefined_function,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = dtls1_read_bytes,
.ssl_write_bytes = dtls1_write_app_data_bytes,
.ssl3_enc = &DTLSv1_enc_data,
};
static const SSL_METHOD DTLSv1_client_method_data = {
.ssl_dispatch_alert = dtls1_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = dtls1_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &DTLSv1_client_method_internal_data,
};
const SSL_METHOD *
DTLSv1_client_method(void)
{
return &DTLSv1_client_method_data;
}
const SSL_METHOD *
DTLS_client_method(void)
{
return DTLSv1_client_method();
}
static const SSL_METHOD_INTERNAL DTLSv1_method_internal_data = {
.version = DTLS1_VERSION,
.min_version = DTLS1_VERSION,
.max_version = DTLS1_VERSION,
.ssl_new = dtls1_new,
.ssl_clear = dtls1_clear,
.ssl_free = dtls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = dtls1_read_bytes,
.ssl_write_bytes = dtls1_write_app_data_bytes,
.ssl3_enc = &DTLSv1_enc_data,
};
static const SSL_METHOD DTLSv1_method_data = {
.ssl_dispatch_alert = dtls1_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = dtls1_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &DTLSv1_method_internal_data,
};
const SSL_METHOD *
DTLSv1_method(void)
{
return &DTLSv1_method_data;
}
const SSL_METHOD *
DTLS_method(void)
{
return DTLSv1_method();
}
static const SSL_METHOD_INTERNAL DTLSv1_server_method_internal_data = {
.version = DTLS1_VERSION,
.min_version = DTLS1_VERSION,
.max_version = DTLS1_VERSION,
.ssl_new = dtls1_new,
.ssl_clear = dtls1_clear,
.ssl_free = dtls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl_undefined_function,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = dtls1_read_bytes,
.ssl_write_bytes = dtls1_write_app_data_bytes,
.ssl3_enc = &DTLSv1_enc_data,
};
static const SSL_METHOD DTLSv1_server_method_data = {
.ssl_dispatch_alert = dtls1_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = dtls1_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &DTLSv1_server_method_internal_data,
};
const SSL_METHOD *
DTLSv1_server_method(void)
{
return &DTLSv1_server_method_data;
}
const SSL_METHOD *
DTLS_server_method(void)
{
return DTLSv1_server_method();
}
#ifdef LIBRESSL_HAS_TLS1_3_CLIENT
static const SSL_METHOD_INTERNAL TLS_client_method_internal_data = {
.version = TLS1_3_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_3_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl_undefined_function,
.ssl_connect = tls13_legacy_connect,
.ssl_shutdown = tls13_legacy_shutdown,
.ssl_renegotiate = ssl_undefined_function,
.ssl_renegotiate_check = ssl_ok,
.ssl_pending = tls13_legacy_pending,
.ssl_read_bytes = tls13_legacy_read_bytes,
.ssl_write_bytes = tls13_legacy_write_bytes,
.ssl3_enc = &TLSv1_3_enc_data,
};
static const SSL_METHOD TLS_client_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLS_client_method_internal_data,
};
#endif
static const SSL_METHOD_INTERNAL TLS_legacy_client_method_internal_data = {
.version = TLS1_2_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_2_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl_undefined_function,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl_undefined_function,
.ssl_renegotiate_check = ssl_ok,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_2_enc_data,
};
static const SSL_METHOD TLS_legacy_client_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLS_legacy_client_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_client_method_internal_data = {
.version = TLS1_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl_undefined_function,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_enc_data,
};
static const SSL_METHOD TLSv1_client_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_client_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_1_client_method_internal_data = {
.version = TLS1_1_VERSION,
.min_version = TLS1_1_VERSION,
.max_version = TLS1_1_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl_undefined_function,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_1_enc_data,
};
static const SSL_METHOD TLSv1_1_client_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_1_client_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_2_client_method_internal_data = {
.version = TLS1_2_VERSION,
.min_version = TLS1_2_VERSION,
.max_version = TLS1_2_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl_undefined_function,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_2_enc_data,
};
static const SSL_METHOD TLSv1_2_client_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_2_client_method_internal_data,
};
const SSL_METHOD *
SSLv23_client_method(void)
{
return (TLS_client_method());
}
const SSL_METHOD *
TLS_client_method(void)
{
#ifdef LIBRESSL_HAS_TLS1_3_CLIENT
return (&TLS_client_method_data);
#else
return tls_legacy_client_method();
#endif
}
const SSL_METHOD *
tls_legacy_client_method(void)
{
return (&TLS_legacy_client_method_data);
}
const SSL_METHOD *
TLSv1_client_method(void)
{
return (&TLSv1_client_method_data);
}
const SSL_METHOD *
TLSv1_1_client_method(void)
{
return (&TLSv1_1_client_method_data);
}
const SSL_METHOD *
TLSv1_2_client_method(void)
{
return (&TLSv1_2_client_method_data);
}
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT) && defined(LIBRESSL_HAS_TLS1_3_SERVER)
static const SSL_METHOD_INTERNAL TLS_method_internal_data = {
.version = TLS1_3_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_3_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = tls13_legacy_accept,
.ssl_connect = tls13_legacy_connect,
.ssl_shutdown = tls13_legacy_shutdown,
.ssl_renegotiate = ssl_undefined_function,
.ssl_renegotiate_check = ssl_ok,
.ssl_pending = tls13_legacy_pending,
.ssl_read_bytes = tls13_legacy_read_bytes,
.ssl_write_bytes = tls13_legacy_write_bytes,
.ssl3_enc = &TLSv1_3_enc_data,
};
static const SSL_METHOD TLS_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLS_method_internal_data,
};
#endif
static const SSL_METHOD_INTERNAL TLS_legacy_method_internal_data = {
.version = TLS1_2_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_2_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl_undefined_function,
.ssl_renegotiate_check = ssl_ok,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_2_enc_data,
};
static const SSL_METHOD TLS_legacy_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLS_legacy_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_method_internal_data = {
.version = TLS1_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_enc_data,
};
static const SSL_METHOD TLSv1_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_1_method_internal_data = {
.version = TLS1_1_VERSION,
.min_version = TLS1_1_VERSION,
.max_version = TLS1_1_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_1_enc_data,
};
static const SSL_METHOD TLSv1_1_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_1_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_2_method_internal_data = {
.version = TLS1_2_VERSION,
.min_version = TLS1_2_VERSION,
.max_version = TLS1_2_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl3_connect,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_2_enc_data,
};
static const SSL_METHOD TLSv1_2_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_2_method_internal_data,
};
const SSL_METHOD *
SSLv23_method(void)
{
return (TLS_method());
}
const SSL_METHOD *
TLS_method(void)
{
#if defined(LIBRESSL_HAS_TLS1_3_CLIENT) && defined(LIBRESSL_HAS_TLS1_3_SERVER)
return (&TLS_method_data);
#else
return tls_legacy_method();
#endif
}
const SSL_METHOD *
tls_legacy_method(void)
{
return (&TLS_legacy_method_data);
}
const SSL_METHOD *
TLSv1_method(void)
{
return (&TLSv1_method_data);
}
const SSL_METHOD *
TLSv1_1_method(void)
{
return (&TLSv1_1_method_data);
}
const SSL_METHOD *
TLSv1_2_method(void)
{
return (&TLSv1_2_method_data);
}
#ifdef LIBRESSL_HAS_TLS1_3_SERVER
static const SSL_METHOD_INTERNAL TLS_server_method_internal_data = {
.version = TLS1_3_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_3_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = tls13_legacy_accept,
.ssl_connect = ssl_undefined_function,
.ssl_shutdown = tls13_legacy_shutdown,
.ssl_renegotiate = ssl_undefined_function,
.ssl_renegotiate_check = ssl_ok,
.ssl_pending = tls13_legacy_pending,
.ssl_read_bytes = tls13_legacy_read_bytes,
.ssl_write_bytes = tls13_legacy_write_bytes,
.ssl3_enc = &TLSv1_3_enc_data,
};
static const SSL_METHOD TLS_server_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLS_server_method_internal_data,
};
#endif
static const SSL_METHOD_INTERNAL TLS_legacy_server_method_internal_data = {
.version = TLS1_2_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_2_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl_undefined_function,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl_undefined_function,
.ssl_renegotiate_check = ssl_ok,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_2_enc_data,
};
static const SSL_METHOD TLS_legacy_server_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLS_legacy_server_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_server_method_internal_data = {
.version = TLS1_VERSION,
.min_version = TLS1_VERSION,
.max_version = TLS1_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl_undefined_function,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_enc_data,
};
static const SSL_METHOD TLSv1_server_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_server_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_1_server_method_internal_data = {
.version = TLS1_1_VERSION,
.min_version = TLS1_1_VERSION,
.max_version = TLS1_1_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl_undefined_function,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_1_enc_data,
};
static const SSL_METHOD TLSv1_1_server_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_1_server_method_internal_data,
};
static const SSL_METHOD_INTERNAL TLSv1_2_server_method_internal_data = {
.version = TLS1_2_VERSION,
.min_version = TLS1_2_VERSION,
.max_version = TLS1_2_VERSION,
.ssl_new = tls1_new,
.ssl_clear = tls1_clear,
.ssl_free = tls1_free,
.ssl_accept = ssl3_accept,
.ssl_connect = ssl_undefined_function,
.ssl_shutdown = ssl3_shutdown,
.ssl_renegotiate = ssl3_renegotiate,
.ssl_renegotiate_check = ssl3_renegotiate_check,
.ssl_pending = ssl3_pending,
.ssl_read_bytes = ssl3_read_bytes,
.ssl_write_bytes = ssl3_write_bytes,
.ssl3_enc = &TLSv1_2_enc_data,
};
static const SSL_METHOD TLSv1_2_server_method_data = {
.ssl_dispatch_alert = ssl3_dispatch_alert,
.num_ciphers = ssl3_num_ciphers,
.get_cipher = ssl3_get_cipher,
.get_cipher_by_char = ssl3_get_cipher_by_char,
.put_cipher_by_char = ssl3_put_cipher_by_char,
.internal = &TLSv1_2_server_method_internal_data,
};
const SSL_METHOD *
SSLv23_server_method(void)
{
return (TLS_server_method());
}
const SSL_METHOD *
TLS_server_method(void)
{
#ifdef LIBRESSL_HAS_TLS1_3_SERVER
return (&TLS_server_method_data);
#else
return tls_legacy_server_method();
#endif
}
const SSL_METHOD *
tls_legacy_server_method(void)
{
return (&TLS_legacy_server_method_data);
}
const SSL_METHOD *
TLSv1_server_method(void)
{
return (&TLSv1_server_method_data);
}
const SSL_METHOD *
TLSv1_1_server_method(void)
{
return (&TLSv1_1_server_method_data);
}
const SSL_METHOD *
TLSv1_2_server_method(void)
{
return (&TLSv1_2_server_method_data);
}
const SSL_METHOD *
ssl_get_client_method(uint16_t version)
{
if (version == TLS1_3_VERSION)
return (TLS_client_method());
if (version == TLS1_2_VERSION)
return (TLSv1_2_client_method());
if (version == TLS1_1_VERSION)
return (TLSv1_1_client_method());
if (version == TLS1_VERSION)
return (TLSv1_client_method());
if (version == DTLS1_VERSION)
return (DTLSv1_client_method());
return (NULL);
}
const SSL_METHOD *
ssl_get_server_method(uint16_t version)
{
if (version == TLS1_3_VERSION)
return (TLS_server_method());
if (version == TLS1_2_VERSION)
return (TLSv1_2_server_method());
if (version == TLS1_1_VERSION)
return (TLSv1_1_server_method());
if (version == TLS1_VERSION)
return (TLSv1_server_method());
if (version == DTLS1_VERSION)
return (DTLSv1_server_method());
return (NULL);
}

293
externals/libressl/ssl/ssl_packet.c vendored Executable file
View File

@@ -0,0 +1,293 @@
/* $OpenBSD: ssl_packet.c,v 1.8 2018/11/08 22:28:52 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include "bytestring.h"
static int
ssl_is_sslv2_client_hello(CBS *header)
{
uint16_t record_length;
uint8_t message_type;
CBS cbs;
CBS_dup(header, &cbs);
if (!CBS_get_u16(&cbs, &record_length) ||
!CBS_get_u8(&cbs, &message_type))
return 0;
/*
* The SSLv2 record length field uses variable length (2 or 3 byte)
* encoding. Given the size of a client hello, we expect/require the
* 2-byte form which is indicated by a one in the most significant bit.
*/
if ((record_length & 0x8000) == 0)
return 0;
if ((record_length & ~0x8000) < 3)
return 0;
if (message_type != SSL2_MT_CLIENT_HELLO)
return 0;
return 1;
}
static int
ssl_is_sslv3_handshake(CBS *header)
{
uint16_t record_version;
uint8_t record_type;
CBS cbs;
CBS_dup(header, &cbs);
if (!CBS_get_u8(&cbs, &record_type) ||
!CBS_get_u16(&cbs, &record_version))
return 0;
if (record_type != SSL3_RT_HANDSHAKE)
return 0;
if ((record_version >> 8) != SSL3_VERSION_MAJOR)
return 0;
return 1;
}
static int
ssl_convert_sslv2_client_hello(SSL *s)
{
CBB cbb, handshake, client_hello, cipher_suites, compression, session_id;
CBS cbs, challenge, cipher_specs, session;
uint16_t record_length, client_version, cipher_specs_length;
uint16_t session_id_length, challenge_length;
unsigned char *client_random = NULL, *data = NULL;
size_t data_len, pad_len, len;
uint32_t cipher_spec;
uint8_t message_type;
unsigned char *pad;
int ret = -1;
int n;
memset(&cbb, 0, sizeof(cbb));
CBS_init(&cbs, s->internal->packet, SSL3_RT_HEADER_LENGTH);
if (!CBS_get_u16(&cbs, &record_length) ||
!CBS_get_u8(&cbs, &message_type) ||
!CBS_get_u16(&cbs, &client_version))
return -1;
/*
* The SSLv2 record length field uses variable length (2 or 3 byte)
* encoding. Given the size of a client hello, we expect/require the
* 2-byte form which is indicated by a one in the most significant bit.
* Also note that the record length value does not include the bytes
* used for the record length field.
*/
if ((record_length & 0x8000) == 0)
return -1;
record_length &= ~0x8000;
if (record_length < SSL3_RT_HEADER_LENGTH - 2)
return -1;
if (message_type != SSL2_MT_CLIENT_HELLO)
return -1;
if (record_length < 9) {
SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
return -1;
}
if (record_length > 4096) {
SSLerror(s, SSL_R_RECORD_TOO_LARGE);
return -1;
}
n = ssl3_packet_extend(s, record_length + 2);
if (n != record_length + 2)
return n;
tls1_transcript_record(s, s->internal->packet + 2,
s->internal->packet_length - 2);
s->internal->mac_packet = 0;
if (s->internal->msg_callback)
s->internal->msg_callback(0, SSL2_VERSION, 0,
s->internal->packet + 2, s->internal->packet_length - 2, s,
s->internal->msg_callback_arg);
/* Decode the SSLv2 record containing the client hello. */
CBS_init(&cbs, s->internal->packet, s->internal->packet_length);
if (!CBS_get_u16(&cbs, &record_length))
return -1;
if (!CBS_get_u8(&cbs, &message_type))
return -1;
if (!CBS_get_u16(&cbs, &client_version))
return -1;
if (!CBS_get_u16(&cbs, &cipher_specs_length))
return -1;
if (!CBS_get_u16(&cbs, &session_id_length))
return -1;
if (!CBS_get_u16(&cbs, &challenge_length))
return -1;
if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length))
return -1;
if (!CBS_get_bytes(&cbs, &session, session_id_length))
return -1;
if (!CBS_get_bytes(&cbs, &challenge, challenge_length))
return -1;
if (CBS_len(&cbs) != 0) {
SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
return -1;
}
/*
* Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
* left-padding with zero bytes.
*/
if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL)
goto err;
if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE))
goto err;
if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE)
len = SSL3_RANDOM_SIZE;
pad_len = SSL3_RANDOM_SIZE - len;
if (!CBB_add_space(&cbb, &pad, pad_len))
goto err;
memset(pad, 0, pad_len);
if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len))
goto err;
if (!CBB_finish(&cbb, NULL, NULL))
goto err;
/* Build SSLv3/TLS record with client hello. */
if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
goto err;
if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
goto err;
if (!CBB_add_u16(&cbb, 0x0301))
goto err;
if (!CBB_add_u16_length_prefixed(&cbb, &handshake))
goto err;
if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO))
goto err;
if (!CBB_add_u24_length_prefixed(&handshake, &client_hello))
goto err;
if (!CBB_add_u16(&client_hello, client_version))
goto err;
if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE))
goto err;
if (!CBB_add_u8_length_prefixed(&client_hello, &session_id))
goto err;
if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites))
goto err;
while (CBS_len(&cipher_specs) > 0) {
if (!CBS_get_u24(&cipher_specs, &cipher_spec))
goto err;
if ((cipher_spec & 0xff0000) != 0)
continue;
if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff))
goto err;
}
if (!CBB_add_u8_length_prefixed(&client_hello, &compression))
goto err;
if (!CBB_add_u8(&compression, 0))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > S3I(s)->rbuf.len)
goto err;
s->internal->packet = S3I(s)->rbuf.buf;
s->internal->packet_length = data_len;
memcpy(s->internal->packet, data, data_len);
ret = 1;
err:
CBB_cleanup(&cbb);
free(client_random);
free(data);
return (ret);
}
/*
* Potentially do legacy processing on the first packet received by a TLS
* server. We return 1 if we want SSLv3/TLS record processing to continue
* normally, otherwise we must set an SSLerr and return -1.
*/
int
ssl_server_legacy_first_packet(SSL *s)
{
uint16_t min_version;
const char *data;
CBS header;
if (SSL_IS_DTLS(s))
return 1;
CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
if (ssl_is_sslv3_handshake(&header) == 1)
return 1;
/* Only continue if this is not a version locked method. */
if (s->method->internal->min_version == s->method->internal->max_version)
return 1;
if (ssl_is_sslv2_client_hello(&header) == 1) {
/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
if (ssl_enabled_version_range(s, &min_version, NULL) != 1) {
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
return -1;
}
if (min_version > TLS1_VERSION)
return 1;
if (ssl_convert_sslv2_client_hello(s) != 1) {
SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
return -1;
}
return 1;
}
/* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
SSLerror(s, ERR_R_INTERNAL_ERROR);
return -1;
}
data = (const char *)CBS_data(&header);
/* Is this a cleartext protocol? */
if (strncmp("GET ", data, 4) == 0 ||
strncmp("POST ", data, 5) == 0 ||
strncmp("HEAD ", data, 5) == 0 ||
strncmp("PUT ", data, 4) == 0) {
SSLerror(s, SSL_R_HTTP_REQUEST);
return -1;
}
if (strncmp("CONNE", data, 5) == 0) {
SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST);
return -1;
}
SSLerror(s, SSL_R_UNKNOWN_PROTOCOL);
return -1;
}

1356
externals/libressl/ssl/ssl_pkt.c vendored Executable file

File diff suppressed because it is too large Load Diff

695
externals/libressl/ssl/ssl_rsa.c vendored Executable file
View File

@@ -0,0 +1,695 @@
/* $OpenBSD: ssl_rsa.c,v 1.31 2019/03/25 16:46:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "ssl_locl.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
static int ssl_ctx_use_certificate_chain_bio(SSL_CTX *, BIO *);
int
SSL_use_certificate(SSL *ssl, X509 *x)
{
if (x == NULL) {
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
return (ssl_set_cert(ssl->cert, x));
}
int
SSL_use_certificate_file(SSL *ssl, const char *file, int type)
{
int j;
BIO *in;
int ret = 0;
X509 *x = NULL;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerror(ssl, ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerror(ssl, ERR_R_SYS_LIB);
goto end;
}
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
x = d2i_X509_bio(in, NULL);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
x = PEM_read_bio_X509(in, NULL,
ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata);
} else {
SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (x == NULL) {
SSLerror(ssl, j);
goto end;
}
ret = SSL_use_certificate(ssl, x);
end:
X509_free(x);
BIO_free(in);
return (ret);
}
int
SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
{
X509 *x;
int ret;
x = d2i_X509(NULL, &d, (long)len);
if (x == NULL) {
SSLerror(ssl, ERR_R_ASN1_LIB);
return (0);
}
ret = SSL_use_certificate(ssl, x);
X509_free(x);
return (ret);
}
int
SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
{
EVP_PKEY *pkey;
int ret;
if (rsa == NULL) {
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
if ((pkey = EVP_PKEY_new()) == NULL) {
SSLerror(ssl, ERR_R_EVP_LIB);
return (0);
}
RSA_up_ref(rsa);
EVP_PKEY_assign_RSA(pkey, rsa);
ret = ssl_set_pkey(ssl->cert, pkey);
EVP_PKEY_free(pkey);
return (ret);
}
static int
ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
{
int i;
i = ssl_cert_type(NULL, pkey);
if (i < 0) {
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return (0);
}
if (c->pkeys[i].x509 != NULL) {
EVP_PKEY *pktmp;
pktmp = X509_get_pubkey(c->pkeys[i].x509);
EVP_PKEY_copy_parameters(pktmp, pkey);
EVP_PKEY_free(pktmp);
ERR_clear_error();
/*
* Don't check the public/private key, this is mostly
* for smart cards.
*/
if ((pkey->type == EVP_PKEY_RSA) &&
(RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK))
;
else
if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
X509_free(c->pkeys[i].x509);
c->pkeys[i].x509 = NULL;
return 0;
}
}
EVP_PKEY_free(c->pkeys[i].privatekey);
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
c->pkeys[i].privatekey = pkey;
c->key = &(c->pkeys[i]);
c->valid = 0;
return (1);
}
int
SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
{
int j, ret = 0;
BIO *in;
RSA *rsa = NULL;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerror(ssl, ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerror(ssl, ERR_R_SYS_LIB);
goto end;
}
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
rsa = d2i_RSAPrivateKey_bio(in, NULL);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata);
} else {
SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (rsa == NULL) {
SSLerror(ssl, j);
goto end;
}
ret = SSL_use_RSAPrivateKey(ssl, rsa);
RSA_free(rsa);
end:
BIO_free(in);
return (ret);
}
int
SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
{
int ret;
RSA *rsa;
if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
SSLerror(ssl, ERR_R_ASN1_LIB);
return (0);
}
ret = SSL_use_RSAPrivateKey(ssl, rsa);
RSA_free(rsa);
return (ret);
}
int
SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
{
int ret;
if (pkey == NULL) {
SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
ret = ssl_set_pkey(ssl->cert, pkey);
return (ret);
}
int
SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
{
int j, ret = 0;
BIO *in;
EVP_PKEY *pkey = NULL;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerror(ssl, ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerror(ssl, ERR_R_SYS_LIB);
goto end;
}
if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
pkey = PEM_read_bio_PrivateKey(in, NULL,
ssl->ctx->default_passwd_callback,
ssl->ctx->default_passwd_callback_userdata);
} else if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
pkey = d2i_PrivateKey_bio(in, NULL);
} else {
SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (pkey == NULL) {
SSLerror(ssl, j);
goto end;
}
ret = SSL_use_PrivateKey(ssl, pkey);
EVP_PKEY_free(pkey);
end:
BIO_free(in);
return (ret);
}
int
SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
{
int ret;
EVP_PKEY *pkey;
if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
SSLerror(ssl, ERR_R_ASN1_LIB);
return (0);
}
ret = SSL_use_PrivateKey(ssl, pkey);
EVP_PKEY_free(pkey);
return (ret);
}
int
SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
{
if (x == NULL) {
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
return (ssl_set_cert(ctx->internal->cert, x));
}
static int
ssl_set_cert(CERT *c, X509 *x)
{
EVP_PKEY *pkey;
int i;
pkey = X509_get_pubkey(x);
if (pkey == NULL) {
SSLerrorx(SSL_R_X509_LIB);
return (0);
}
i = ssl_cert_type(x, pkey);
if (i < 0) {
SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
EVP_PKEY_free(pkey);
return (0);
}
if (c->pkeys[i].privatekey != NULL) {
EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
ERR_clear_error();
/*
* Don't check the public/private key, this is mostly
* for smart cards.
*/
if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) &&
(RSA_flags(c->pkeys[i].privatekey->pkey.rsa) &
RSA_METHOD_FLAG_NO_CHECK))
;
else
if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
/*
* don't fail for a cert/key mismatch, just free
* current private key (when switching to a different
* cert & key, first this function should be used,
* then ssl_set_pkey
*/
EVP_PKEY_free(c->pkeys[i].privatekey);
c->pkeys[i].privatekey = NULL;
/* clear error queue */
ERR_clear_error();
}
}
EVP_PKEY_free(pkey);
X509_free(c->pkeys[i].x509);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
c->pkeys[i].x509 = x;
c->key = &(c->pkeys[i]);
c->valid = 0;
return (1);
}
int
SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
{
int j;
BIO *in;
int ret = 0;
X509 *x = NULL;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerrorx(ERR_R_SYS_LIB);
goto end;
}
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
x = d2i_X509_bio(in, NULL);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata);
} else {
SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (x == NULL) {
SSLerrorx(j);
goto end;
}
ret = SSL_CTX_use_certificate(ctx, x);
end:
X509_free(x);
BIO_free(in);
return (ret);
}
int
SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
{
X509 *x;
int ret;
x = d2i_X509(NULL, &d, (long)len);
if (x == NULL) {
SSLerrorx(ERR_R_ASN1_LIB);
return (0);
}
ret = SSL_CTX_use_certificate(ctx, x);
X509_free(x);
return (ret);
}
int
SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
{
int ret;
EVP_PKEY *pkey;
if (rsa == NULL) {
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
if ((pkey = EVP_PKEY_new()) == NULL) {
SSLerrorx(ERR_R_EVP_LIB);
return (0);
}
RSA_up_ref(rsa);
EVP_PKEY_assign_RSA(pkey, rsa);
ret = ssl_set_pkey(ctx->internal->cert, pkey);
EVP_PKEY_free(pkey);
return (ret);
}
int
SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
{
int j, ret = 0;
BIO *in;
RSA *rsa = NULL;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerrorx(ERR_R_SYS_LIB);
goto end;
}
if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
rsa = d2i_RSAPrivateKey_bio(in, NULL);
} else if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata);
} else {
SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (rsa == NULL) {
SSLerrorx(j);
goto end;
}
ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
RSA_free(rsa);
end:
BIO_free(in);
return (ret);
}
int
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
{
int ret;
RSA *rsa;
if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
SSLerrorx(ERR_R_ASN1_LIB);
return (0);
}
ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
RSA_free(rsa);
return (ret);
}
int
SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
{
if (pkey == NULL) {
SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
return (ssl_set_pkey(ctx->internal->cert, pkey));
}
int
SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
{
int j, ret = 0;
BIO *in;
EVP_PKEY *pkey = NULL;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerrorx(ERR_R_SYS_LIB);
goto end;
}
if (type == SSL_FILETYPE_PEM) {
j = ERR_R_PEM_LIB;
pkey = PEM_read_bio_PrivateKey(in, NULL,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata);
} else if (type == SSL_FILETYPE_ASN1) {
j = ERR_R_ASN1_LIB;
pkey = d2i_PrivateKey_bio(in, NULL);
} else {
SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
goto end;
}
if (pkey == NULL) {
SSLerrorx(j);
goto end;
}
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
end:
BIO_free(in);
return (ret);
}
int
SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
long len)
{
int ret;
EVP_PKEY *pkey;
if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
SSLerrorx(ERR_R_ASN1_LIB);
return (0);
}
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
return (ret);
}
/*
* Read a bio that contains our certificate in "PEM" format,
* possibly followed by a sequence of CA certificates that should be
* sent to the peer in the Certificate message.
*/
static int
ssl_ctx_use_certificate_chain_bio(SSL_CTX *ctx, BIO *in)
{
X509 *ca, *x = NULL;
unsigned long err;
int ret = 0;
if ((x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata)) == NULL) {
SSLerrorx(ERR_R_PEM_LIB);
goto err;
}
if (!SSL_CTX_use_certificate(ctx, x))
goto err;
if (!ssl_cert_set0_chain(ctx->internal->cert, NULL))
goto err;
/* Process any additional CA certificates. */
while ((ca = PEM_read_bio_X509(in, NULL,
ctx->default_passwd_callback,
ctx->default_passwd_callback_userdata)) != NULL) {
if (!ssl_cert_add0_chain_cert(ctx->internal->cert, ca)) {
X509_free(ca);
goto err;
}
}
/* When the while loop ends, it's usually just EOF. */
err = ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
ERR_clear_error();
ret = 1;
}
err:
X509_free(x);
return (ret);
}
int
SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
{
BIO *in;
int ret = 0;
in = BIO_new(BIO_s_file_internal());
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
}
if (BIO_read_filename(in, file) <= 0) {
SSLerrorx(ERR_R_SYS_LIB);
goto end;
}
ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
end:
BIO_free(in);
return (ret);
}
int
SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
{
BIO *in;
int ret = 0;
in = BIO_new_mem_buf(buf, len);
if (in == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
goto end;
}
ret = ssl_ctx_use_certificate_chain_bio(ctx, in);
end:
BIO_free(in);
return (ret);
}

1220
externals/libressl/ssl/ssl_sess.c vendored Executable file

File diff suppressed because it is too large Load Diff

337
externals/libressl/ssl/ssl_sigalgs.c vendored Executable file
View File

@@ -0,0 +1,337 @@
/* $OpenBSD: ssl_sigalgs.c,v 1.21 2020/05/09 16:52:15 beck Exp $ */
/*
* Copyright (c) 2018-2020 Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include "bytestring.h"
#include "ssl_locl.h"
#include "ssl_sigalgs.h"
#include "tls13_internal.h"
const struct ssl_sigalg sigalgs[] = {
{
.value = SIGALG_RSA_PKCS1_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_RSA,
},
{
.value = SIGALG_ECDSA_SECP521R1_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_EC,
.curve_nid = NID_secp521r1,
},
#ifndef OPENSSL_NO_GOST
{
.value = SIGALG_GOSTR12_512_STREEBOG_512,
.md = EVP_streebog512,
.key_type = EVP_PKEY_GOSTR12_512,
},
#endif
{
.value = SIGALG_RSA_PKCS1_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_RSA,
},
{
.value = SIGALG_ECDSA_SECP384R1_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_EC,
.curve_nid = NID_secp384r1,
},
{
.value = SIGALG_RSA_PKCS1_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_RSA,
},
{
.value = SIGALG_ECDSA_SECP256R1_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_EC,
.curve_nid = NID_X9_62_prime256v1,
},
#ifndef OPENSSL_NO_GOST
{
.value = SIGALG_GOSTR12_256_STREEBOG_256,
.md = EVP_streebog256,
.key_type = EVP_PKEY_GOSTR12_256,
},
{
.value = SIGALG_GOSTR01_GOST94,
.md = EVP_gostr341194,
.key_type = EVP_PKEY_GOSTR01,
},
#endif
{
.value = SIGALG_RSA_PSS_RSAE_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_RSA,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_RSAE_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_RSA,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_RSAE_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_RSA,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_PSS_SHA256,
.md = EVP_sha256,
.key_type = EVP_PKEY_RSA,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_PSS_SHA384,
.md = EVP_sha384,
.key_type = EVP_PKEY_RSA,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PSS_PSS_SHA512,
.md = EVP_sha512,
.key_type = EVP_PKEY_RSA,
.flags = SIGALG_FLAG_RSA_PSS,
},
{
.value = SIGALG_RSA_PKCS1_SHA224,
.md = EVP_sha224,
.key_type = EVP_PKEY_RSA,
},
{
.value = SIGALG_ECDSA_SECP224R1_SHA224,
.md = EVP_sha224,
.key_type = EVP_PKEY_EC,
},
{
.value = SIGALG_RSA_PKCS1_SHA1,
.key_type = EVP_PKEY_RSA,
.md = EVP_sha1,
},
{
.value = SIGALG_ECDSA_SHA1,
.key_type = EVP_PKEY_EC,
.md = EVP_sha1,
},
{
.value = SIGALG_RSA_PKCS1_MD5_SHA1,
.key_type = EVP_PKEY_RSA,
.md = EVP_md5_sha1,
},
{
.value = SIGALG_NONE,
},
};
/* Sigalgs for tls 1.3, in preference order, */
uint16_t tls13_sigalgs[] = {
SIGALG_RSA_PSS_RSAE_SHA512,
SIGALG_RSA_PKCS1_SHA512,
SIGALG_ECDSA_SECP521R1_SHA512,
SIGALG_RSA_PSS_RSAE_SHA384,
SIGALG_RSA_PKCS1_SHA384,
SIGALG_ECDSA_SECP384R1_SHA384,
SIGALG_RSA_PSS_RSAE_SHA256,
SIGALG_RSA_PKCS1_SHA256,
SIGALG_ECDSA_SECP256R1_SHA256,
};
size_t tls13_sigalgs_len = (sizeof(tls13_sigalgs) / sizeof(tls13_sigalgs[0]));
/* Sigalgs for tls 1.2, in preference order, */
uint16_t tls12_sigalgs[] = {
SIGALG_RSA_PSS_RSAE_SHA512,
SIGALG_RSA_PKCS1_SHA512,
SIGALG_ECDSA_SECP521R1_SHA512,
SIGALG_RSA_PSS_RSAE_SHA384,
SIGALG_RSA_PKCS1_SHA384,
SIGALG_ECDSA_SECP384R1_SHA384,
SIGALG_RSA_PSS_RSAE_SHA256,
SIGALG_RSA_PKCS1_SHA256,
SIGALG_ECDSA_SECP256R1_SHA256,
SIGALG_RSA_PKCS1_SHA1, /* XXX */
SIGALG_ECDSA_SHA1, /* XXX */
};
size_t tls12_sigalgs_len = (sizeof(tls12_sigalgs) / sizeof(tls12_sigalgs[0]));
const struct ssl_sigalg *
ssl_sigalg_lookup(uint16_t sigalg)
{
int i;
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++) {
if (sigalgs[i].value == sigalg)
return &sigalgs[i];
}
return NULL;
}
const struct ssl_sigalg *
ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len)
{
int i;
for (i = 0; i < len; i++) {
if (values[i] == sigalg)
return ssl_sigalg_lookup(sigalg);
}
return NULL;
}
int
ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len)
{
size_t i;
for (i = 0; sigalgs[i].value != SIGALG_NONE; i++);
if (len > i)
return 0;
/* XXX check for duplicates and other sanity BS? */
/* Add values in order as long as they are supported. */
for (i = 0; i < len; i++) {
/* Do not allow the legacy value for < 1.2 to be used */
if (values[i] == SIGALG_RSA_PKCS1_MD5_SHA1)
return 0;
if (ssl_sigalg_lookup(values[i]) != NULL) {
if (!CBB_add_u16(cbb, values[i]))
return 0;
} else
return 0;
}
return 1;
}
int
ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
int check_curve)
{
if (sigalg == NULL || pkey == NULL)
return 0;
if (sigalg->key_type != pkey->type)
return 0;
if ((sigalg->flags & SIGALG_FLAG_RSA_PSS)) {
/*
* RSA PSS Must have an RSA key that needs to be at
* least as big as twice the size of the hash + 2
*/
if (pkey->type != EVP_PKEY_RSA ||
EVP_PKEY_size(pkey) < (2 * EVP_MD_size(sigalg->md()) + 2))
return 0;
}
if (pkey->type == EVP_PKEY_EC && check_curve) {
/* Curve must match for EC keys. */
if (sigalg->curve_nid == 0)
return 0;
if (EC_GROUP_get_curve_name(EC_KEY_get0_group
(EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) {
return 0;
}
}
return 1;
}
const struct ssl_sigalg *
ssl_sigalg_select(SSL *s, EVP_PKEY *pkey)
{
uint16_t *tls_sigalgs = tls12_sigalgs;
size_t tls_sigalgs_len = tls12_sigalgs_len;
int check_curve = 0;
CBS cbs;
if (TLS1_get_version(s) >= TLS1_3_VERSION) {
tls_sigalgs = tls13_sigalgs;
tls_sigalgs_len = tls13_sigalgs_len;
check_curve = 1;
}
/* Pre TLS 1.2 defaults */
if (!SSL_USE_SIGALGS(s)) {
switch (pkey->type) {
case EVP_PKEY_RSA:
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1);
case EVP_PKEY_EC:
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
#ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
#endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return (NULL);
}
/*
* RFC 5246 allows a TLS 1.2 client to send no sigalgs, in
* which case the server must use the the default.
*/
if (TLS1_get_version(s) < TLS1_3_VERSION &&
S3I(s)->hs.sigalgs == NULL) {
switch (pkey->type) {
case EVP_PKEY_RSA:
return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1);
case EVP_PKEY_EC:
return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1);
#ifndef OPENSSL_NO_GOST
case EVP_PKEY_GOSTR01:
return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94);
#endif
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return (NULL);
}
/*
* If we get here, we have client or server sent sigalgs, use one.
*/
CBS_init(&cbs, S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len);
while (CBS_len(&cbs) > 0) {
uint16_t sig_alg;
const struct ssl_sigalg *sigalg;
if (!CBS_get_u16(&cbs, &sig_alg))
return 0;
if ((sigalg = ssl_sigalg(sig_alg, tls_sigalgs,
tls_sigalgs_len)) == NULL)
continue;
/* RSA cannot be used without PSS in TLSv1.3. */
if (TLS1_get_version(s) >= TLS1_3_VERSION &&
sigalg->key_type == EVP_PKEY_RSA &&
(sigalg->flags & SIGALG_FLAG_RSA_PSS) == 0)
continue;
if (ssl_sigalg_pkey_ok(sigalg, pkey, check_curve))
return sigalg;
}
SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE);
return NULL;
}

86
externals/libressl/ssl/ssl_sigalgs.h vendored Executable file
View File

@@ -0,0 +1,86 @@
/* $OpenBSD: ssl_sigalgs.h,v 1.14 2019/03/25 17:33:26 jsing Exp $ */
/*
* Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_SSL_SIGALGS_H
#define HEADER_SSL_SIGALGS_H
__BEGIN_HIDDEN_DECLS
#define SIGALG_NONE 0x0000
/*
* RFC 8446 Section 4.2.3
* RFC 5246 Section 7.4.1.4.1
*/
#define SIGALG_RSA_PKCS1_SHA224 0x0301
#define SIGALG_RSA_PKCS1_SHA256 0x0401
#define SIGALG_RSA_PKCS1_SHA384 0x0501
#define SIGALG_RSA_PKCS1_SHA512 0x0601
#define SIGALG_ECDSA_SECP224R1_SHA224 0x0303
#define SIGALG_ECDSA_SECP256R1_SHA256 0x0403
#define SIGALG_ECDSA_SECP384R1_SHA384 0x0503
#define SIGALG_ECDSA_SECP521R1_SHA512 0x0603
#define SIGALG_RSA_PSS_RSAE_SHA256 0x0804
#define SIGALG_RSA_PSS_RSAE_SHA384 0x0805
#define SIGALG_RSA_PSS_RSAE_SHA512 0x0806
#define SIGALG_ED25519 0x0807
#define SIGALG_ED448 0x0808
#define SIGALG_RSA_PSS_PSS_SHA256 0x0809
#define SIGALG_RSA_PSS_PSS_SHA384 0x080a
#define SIGALG_RSA_PSS_PSS_SHA512 0x080b
#define SIGALG_RSA_PKCS1_SHA1 0x0201
#define SIGALG_ECDSA_SHA1 0x0203
#define SIGALG_PRIVATE_START 0xFE00
#define SIGALG_PRIVATE_END 0xFFFF
/*
* If Russia can elect the US President, surely
* IANA could fix this problem.
*/
#define SIGALG_GOSTR12_512_STREEBOG_512 0xEFEF
#define SIGALG_GOSTR12_256_STREEBOG_256 0xEEEE
#define SIGALG_GOSTR01_GOST94 0xEDED
/* Legacy sigalg for < 1.2 same value as boring uses*/
#define SIGALG_RSA_PKCS1_MD5_SHA1 0xFF01
#define SIGALG_FLAG_RSA_PSS 0x00000001
struct ssl_sigalg{
uint16_t value;
const EVP_MD *(*md)(void);
int key_type;
int curve_nid;
int flags;
};
extern uint16_t tls12_sigalgs[];
extern size_t tls12_sigalgs_len;
extern uint16_t tls13_sigalgs[];
extern size_t tls13_sigalgs_len;
const struct ssl_sigalg *ssl_sigalg_lookup(uint16_t sigalg);
const struct ssl_sigalg *ssl_sigalg(uint16_t sigalg, uint16_t *values, size_t len);
int ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len);
int ssl_sigalg_pkey_check(uint16_t sigalg, EVP_PKEY *pk);
int ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey,
int check_curve);
const struct ssl_sigalg *ssl_sigalg_select(SSL *s, EVP_PKEY *pkey);
__END_HIDDEN_DECLS
#endif

2653
externals/libressl/ssl/ssl_srvr.c vendored Executable file

File diff suppressed because it is too large Load Diff

801
externals/libressl/ssl/ssl_stat.c vendored Executable file
View File

@@ -0,0 +1,801 @@
/* $OpenBSD: ssl_stat.c,v 1.14 2017/05/07 04:22:24 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2005 Nokia. All rights reserved.
*
* The portions of the attached software ("Contribution") is developed by
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
* license.
*
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
* support (see RFC 4279) to OpenSSL.
*
* No patent licenses or other rights except those expressly stated in
* the OpenSSL open source license shall be deemed granted or received
* expressly, by implication, estoppel, or otherwise.
*
* No assurances are provided by Nokia that the Contribution does not
* infringe the patent or other intellectual property rights of any third
* party or that the license provides you with all the necessary rights
* to make use of the Contribution.
*
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE.
*/
#include <stdio.h>
#include "ssl_locl.h"
const char *
SSL_state_string_long(const SSL *s)
{
const char *str;
switch (S3I(s)->hs.state) {
case SSL_ST_BEFORE:
str = "before SSL initialization";
break;
case SSL_ST_ACCEPT:
str = "before accept initialization";
break;
case SSL_ST_CONNECT:
str = "before connect initialization";
break;
case SSL_ST_OK:
str = "SSL negotiation finished successfully";
break;
case SSL_ST_RENEGOTIATE:
str = "SSL renegotiate ciphers";
break;
case SSL_ST_BEFORE|SSL_ST_CONNECT:
str = "before/connect initialization";
break;
case SSL_ST_OK|SSL_ST_CONNECT:
str = "ok/connect SSL initialization";
break;
case SSL_ST_BEFORE|SSL_ST_ACCEPT:
str = "before/accept initialization";
break;
case SSL_ST_OK|SSL_ST_ACCEPT:
str = "ok/accept SSL initialization";
break;
/* SSLv3 additions */
case SSL3_ST_CW_CLNT_HELLO_A:
str = "SSLv3 write client hello A";
break;
case SSL3_ST_CW_CLNT_HELLO_B:
str = "SSLv3 write client hello B";
break;
case SSL3_ST_CR_SRVR_HELLO_A:
str = "SSLv3 read server hello A";
break;
case SSL3_ST_CR_SRVR_HELLO_B:
str = "SSLv3 read server hello B";
break;
case SSL3_ST_CR_CERT_A:
str = "SSLv3 read server certificate A";
break;
case SSL3_ST_CR_CERT_B:
str = "SSLv3 read server certificate B";
break;
case SSL3_ST_CR_KEY_EXCH_A:
str = "SSLv3 read server key exchange A";
break;
case SSL3_ST_CR_KEY_EXCH_B:
str = "SSLv3 read server key exchange B";
break;
case SSL3_ST_CR_CERT_REQ_A:
str = "SSLv3 read server certificate request A";
break;
case SSL3_ST_CR_CERT_REQ_B:
str = "SSLv3 read server certificate request B";
break;
case SSL3_ST_CR_SESSION_TICKET_A:
str = "SSLv3 read server session ticket A";
break;
case SSL3_ST_CR_SESSION_TICKET_B:
str = "SSLv3 read server session ticket B";
break;
case SSL3_ST_CR_SRVR_DONE_A:
str = "SSLv3 read server done A";
break;
case SSL3_ST_CR_SRVR_DONE_B:
str = "SSLv3 read server done B";
break;
case SSL3_ST_CW_CERT_A:
str = "SSLv3 write client certificate A";
break;
case SSL3_ST_CW_CERT_B:
str = "SSLv3 write client certificate B";
break;
case SSL3_ST_CW_CERT_C:
str = "SSLv3 write client certificate C";
break;
case SSL3_ST_CW_CERT_D:
str = "SSLv3 write client certificate D";
break;
case SSL3_ST_CW_KEY_EXCH_A:
str = "SSLv3 write client key exchange A";
break;
case SSL3_ST_CW_KEY_EXCH_B:
str = "SSLv3 write client key exchange B";
break;
case SSL3_ST_CW_CERT_VRFY_A:
str = "SSLv3 write certificate verify A";
break;
case SSL3_ST_CW_CERT_VRFY_B:
str = "SSLv3 write certificate verify B";
break;
case SSL3_ST_CW_CHANGE_A:
case SSL3_ST_SW_CHANGE_A:
str = "SSLv3 write change cipher spec A";
break;
case SSL3_ST_CW_CHANGE_B:
case SSL3_ST_SW_CHANGE_B:
str = "SSLv3 write change cipher spec B";
break;
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_SW_FINISHED_A:
str = "SSLv3 write finished A";
break;
case SSL3_ST_CW_FINISHED_B:
case SSL3_ST_SW_FINISHED_B:
str = "SSLv3 write finished B";
break;
case SSL3_ST_CR_CHANGE_A:
case SSL3_ST_SR_CHANGE_A:
str = "SSLv3 read change cipher spec A";
break;
case SSL3_ST_CR_CHANGE_B:
case SSL3_ST_SR_CHANGE_B:
str = "SSLv3 read change cipher spec B";
break;
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_SR_FINISHED_A:
str = "SSLv3 read finished A";
break;
case SSL3_ST_CR_FINISHED_B:
case SSL3_ST_SR_FINISHED_B:
str = "SSLv3 read finished B";
break;
case SSL3_ST_CW_FLUSH:
case SSL3_ST_SW_FLUSH:
str = "SSLv3 flush data";
break;
case SSL3_ST_SR_CLNT_HELLO_A:
str = "SSLv3 read client hello A";
break;
case SSL3_ST_SR_CLNT_HELLO_B:
str = "SSLv3 read client hello B";
break;
case SSL3_ST_SR_CLNT_HELLO_C:
str = "SSLv3 read client hello C";
break;
case SSL3_ST_SW_HELLO_REQ_A:
str = "SSLv3 write hello request A";
break;
case SSL3_ST_SW_HELLO_REQ_B:
str = "SSLv3 write hello request B";
break;
case SSL3_ST_SW_HELLO_REQ_C:
str = "SSLv3 write hello request C";
break;
case SSL3_ST_SW_SRVR_HELLO_A:
str = "SSLv3 write server hello A";
break;
case SSL3_ST_SW_SRVR_HELLO_B:
str = "SSLv3 write server hello B";
break;
case SSL3_ST_SW_CERT_A:
str = "SSLv3 write certificate A";
break;
case SSL3_ST_SW_CERT_B:
str = "SSLv3 write certificate B";
break;
case SSL3_ST_SW_KEY_EXCH_A:
str = "SSLv3 write key exchange A";
break;
case SSL3_ST_SW_KEY_EXCH_B:
str = "SSLv3 write key exchange B";
break;
case SSL3_ST_SW_CERT_REQ_A:
str = "SSLv3 write certificate request A";
break;
case SSL3_ST_SW_CERT_REQ_B:
str = "SSLv3 write certificate request B";
break;
case SSL3_ST_SW_SESSION_TICKET_A:
str = "SSLv3 write session ticket A";
break;
case SSL3_ST_SW_SESSION_TICKET_B:
str = "SSLv3 write session ticket B";
break;
case SSL3_ST_SW_SRVR_DONE_A:
str = "SSLv3 write server done A";
break;
case SSL3_ST_SW_SRVR_DONE_B:
str = "SSLv3 write server done B";
break;
case SSL3_ST_SR_CERT_A:
str = "SSLv3 read client certificate A";
break;
case SSL3_ST_SR_CERT_B:
str = "SSLv3 read client certificate B";
break;
case SSL3_ST_SR_KEY_EXCH_A:
str = "SSLv3 read client key exchange A";
break;
case SSL3_ST_SR_KEY_EXCH_B:
str = "SSLv3 read client key exchange B";
break;
case SSL3_ST_SR_CERT_VRFY_A:
str = "SSLv3 read certificate verify A";
break;
case SSL3_ST_SR_CERT_VRFY_B:
str = "SSLv3 read certificate verify B";
break;
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
str = "DTLS1 read hello verify request A";
break;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
str = "DTLS1 read hello verify request B";
break;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
str = "DTLS1 write hello verify request A";
break;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
str = "DTLS1 write hello verify request B";
break;
default:
str = "unknown state";
break;
}
return (str);
}
const char *
SSL_rstate_string_long(const SSL *s)
{
const char *str;
switch (s->internal->rstate) {
case SSL_ST_READ_HEADER:
str = "read header";
break;
case SSL_ST_READ_BODY:
str = "read body";
break;
case SSL_ST_READ_DONE:
str = "read done";
break;
default:
str = "unknown";
break;
}
return (str);
}
const char *
SSL_state_string(const SSL *s)
{
const char *str;
switch (S3I(s)->hs.state) {
case SSL_ST_BEFORE:
str = "PINIT ";
break;
case SSL_ST_ACCEPT:
str = "AINIT ";
break;
case SSL_ST_CONNECT:
str = "CINIT ";
break;
case SSL_ST_OK:
str = "SSLOK ";
break;
/* SSLv3 additions */
case SSL3_ST_SW_FLUSH:
case SSL3_ST_CW_FLUSH:
str = "3FLUSH";
break;
case SSL3_ST_CW_CLNT_HELLO_A:
str = "3WCH_A";
break;
case SSL3_ST_CW_CLNT_HELLO_B:
str = "3WCH_B";
break;
case SSL3_ST_CR_SRVR_HELLO_A:
str = "3RSH_A";
break;
case SSL3_ST_CR_SRVR_HELLO_B:
str = "3RSH_B";
break;
case SSL3_ST_CR_CERT_A:
str = "3RSC_A";
break;
case SSL3_ST_CR_CERT_B:
str = "3RSC_B";
break;
case SSL3_ST_CR_KEY_EXCH_A:
str = "3RSKEA";
break;
case SSL3_ST_CR_KEY_EXCH_B:
str = "3RSKEB";
break;
case SSL3_ST_CR_CERT_REQ_A:
str = "3RCR_A";
break;
case SSL3_ST_CR_CERT_REQ_B:
str = "3RCR_B";
break;
case SSL3_ST_CR_SRVR_DONE_A:
str = "3RSD_A";
break;
case SSL3_ST_CR_SRVR_DONE_B:
str = "3RSD_B";
break;
case SSL3_ST_CW_CERT_A:
str = "3WCC_A";
break;
case SSL3_ST_CW_CERT_B:
str = "3WCC_B";
break;
case SSL3_ST_CW_CERT_C:
str = "3WCC_C";
break;
case SSL3_ST_CW_CERT_D:
str = "3WCC_D";
break;
case SSL3_ST_CW_KEY_EXCH_A:
str = "3WCKEA";
break;
case SSL3_ST_CW_KEY_EXCH_B:
str = "3WCKEB";
break;
case SSL3_ST_CW_CERT_VRFY_A:
str = "3WCV_A";
break;
case SSL3_ST_CW_CERT_VRFY_B:
str = "3WCV_B";
break;
case SSL3_ST_SW_CHANGE_A:
case SSL3_ST_CW_CHANGE_A:
str = "3WCCSA";
break;
case SSL3_ST_SW_CHANGE_B:
case SSL3_ST_CW_CHANGE_B:
str = "3WCCSB";
break;
case SSL3_ST_SW_FINISHED_A:
case SSL3_ST_CW_FINISHED_A:
str = "3WFINA";
break;
case SSL3_ST_SW_FINISHED_B:
case SSL3_ST_CW_FINISHED_B:
str = "3WFINB";
break;
case SSL3_ST_SR_CHANGE_A:
case SSL3_ST_CR_CHANGE_A:
str = "3RCCSA";
break;
case SSL3_ST_SR_CHANGE_B:
case SSL3_ST_CR_CHANGE_B:
str = "3RCCSB";
break;
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_CR_FINISHED_A:
str = "3RFINA";
break;
case SSL3_ST_SR_FINISHED_B:
case SSL3_ST_CR_FINISHED_B:
str = "3RFINB";
break;
case SSL3_ST_SW_HELLO_REQ_A:
str = "3WHR_A";
break;
case SSL3_ST_SW_HELLO_REQ_B:
str = "3WHR_B";
break;
case SSL3_ST_SW_HELLO_REQ_C:
str = "3WHR_C";
break;
case SSL3_ST_SR_CLNT_HELLO_A:
str = "3RCH_A";
break;
case SSL3_ST_SR_CLNT_HELLO_B:
str = "3RCH_B";
break;
case SSL3_ST_SR_CLNT_HELLO_C:
str = "3RCH_C";
break;
case SSL3_ST_SW_SRVR_HELLO_A:
str = "3WSH_A";
break;
case SSL3_ST_SW_SRVR_HELLO_B:
str = "3WSH_B";
break;
case SSL3_ST_SW_CERT_A:
str = "3WSC_A";
break;
case SSL3_ST_SW_CERT_B:
str = "3WSC_B";
break;
case SSL3_ST_SW_KEY_EXCH_A:
str = "3WSKEA";
break;
case SSL3_ST_SW_KEY_EXCH_B:
str = "3WSKEB";
break;
case SSL3_ST_SW_CERT_REQ_A:
str = "3WCR_A";
break;
case SSL3_ST_SW_CERT_REQ_B:
str = "3WCR_B";
break;
case SSL3_ST_SW_SRVR_DONE_A:
str = "3WSD_A";
break;
case SSL3_ST_SW_SRVR_DONE_B:
str = "3WSD_B";
break;
case SSL3_ST_SR_CERT_A:
str = "3RCC_A";
break;
case SSL3_ST_SR_CERT_B:
str = "3RCC_B";
break;
case SSL3_ST_SR_KEY_EXCH_A:
str = "3RCKEA";
break;
case SSL3_ST_SR_KEY_EXCH_B:
str = "3RCKEB";
break;
case SSL3_ST_SR_CERT_VRFY_A:
str = "3RCV_A";
break;
case SSL3_ST_SR_CERT_VRFY_B:
str = "3RCV_B";
break;
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
str = "DRCHVA";
break;
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
str = "DRCHVB";
break;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
str = "DWCHVA";
break;
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
str = "DWCHVB";
break;
default:
str = "UNKWN ";
break;
}
return (str);
}
const char *
SSL_alert_type_string_long(int value)
{
value >>= 8;
if (value == SSL3_AL_WARNING)
return ("warning");
else if (value == SSL3_AL_FATAL)
return ("fatal");
else
return ("unknown");
}
const char *
SSL_alert_type_string(int value)
{
value >>= 8;
if (value == SSL3_AL_WARNING)
return ("W");
else if (value == SSL3_AL_FATAL)
return ("F");
else
return ("U");
}
const char *
SSL_alert_desc_string(int value)
{
const char *str;
switch (value & 0xff) {
case SSL3_AD_CLOSE_NOTIFY:
str = "CN";
break;
case SSL3_AD_UNEXPECTED_MESSAGE:
str = "UM";
break;
case SSL3_AD_BAD_RECORD_MAC:
str = "BM";
break;
case SSL3_AD_DECOMPRESSION_FAILURE:
str = "DF";
break;
case SSL3_AD_HANDSHAKE_FAILURE:
str = "HF";
break;
case SSL3_AD_NO_CERTIFICATE:
str = "NC";
break;
case SSL3_AD_BAD_CERTIFICATE:
str = "BC";
break;
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
str = "UC";
break;
case SSL3_AD_CERTIFICATE_REVOKED:
str = "CR";
break;
case SSL3_AD_CERTIFICATE_EXPIRED:
str = "CE";
break;
case SSL3_AD_CERTIFICATE_UNKNOWN:
str = "CU";
break;
case SSL3_AD_ILLEGAL_PARAMETER:
str = "IP";
break;
case TLS1_AD_DECRYPTION_FAILED:
str = "DC";
break;
case TLS1_AD_RECORD_OVERFLOW:
str = "RO";
break;
case TLS1_AD_UNKNOWN_CA:
str = "CA";
break;
case TLS1_AD_ACCESS_DENIED:
str = "AD";
break;
case TLS1_AD_DECODE_ERROR:
str = "DE";
break;
case TLS1_AD_DECRYPT_ERROR:
str = "CY";
break;
case TLS1_AD_EXPORT_RESTRICTION:
str = "ER";
break;
case TLS1_AD_PROTOCOL_VERSION:
str = "PV";
break;
case TLS1_AD_INSUFFICIENT_SECURITY:
str = "IS";
break;
case TLS1_AD_INTERNAL_ERROR:
str = "IE";
break;
case TLS1_AD_USER_CANCELLED:
str = "US";
break;
case TLS1_AD_NO_RENEGOTIATION:
str = "NR";
break;
case TLS1_AD_UNSUPPORTED_EXTENSION:
str = "UE";
break;
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
str = "CO";
break;
case TLS1_AD_UNRECOGNIZED_NAME:
str = "UN";
break;
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
str = "BR";
break;
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
str = "BH";
break;
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
str = "UP";
break;
default:
str = "UK";
break;
}
return (str);
}
const char *
SSL_alert_desc_string_long(int value)
{
const char *str;
switch (value & 0xff) {
case SSL3_AD_CLOSE_NOTIFY:
str = "close notify";
break;
case SSL3_AD_UNEXPECTED_MESSAGE:
str = "unexpected_message";
break;
case SSL3_AD_BAD_RECORD_MAC:
str = "bad record mac";
break;
case SSL3_AD_DECOMPRESSION_FAILURE:
str = "decompression failure";
break;
case SSL3_AD_HANDSHAKE_FAILURE:
str = "handshake failure";
break;
case SSL3_AD_NO_CERTIFICATE:
str = "no certificate";
break;
case SSL3_AD_BAD_CERTIFICATE:
str = "bad certificate";
break;
case SSL3_AD_UNSUPPORTED_CERTIFICATE:
str = "unsupported certificate";
break;
case SSL3_AD_CERTIFICATE_REVOKED:
str = "certificate revoked";
break;
case SSL3_AD_CERTIFICATE_EXPIRED:
str = "certificate expired";
break;
case SSL3_AD_CERTIFICATE_UNKNOWN:
str = "certificate unknown";
break;
case SSL3_AD_ILLEGAL_PARAMETER:
str = "illegal parameter";
break;
case TLS1_AD_DECRYPTION_FAILED:
str = "decryption failed";
break;
case TLS1_AD_RECORD_OVERFLOW:
str = "record overflow";
break;
case TLS1_AD_UNKNOWN_CA:
str = "unknown CA";
break;
case TLS1_AD_ACCESS_DENIED:
str = "access denied";
break;
case TLS1_AD_DECODE_ERROR:
str = "decode error";
break;
case TLS1_AD_DECRYPT_ERROR:
str = "decrypt error";
break;
case TLS1_AD_EXPORT_RESTRICTION:
str = "export restriction";
break;
case TLS1_AD_PROTOCOL_VERSION:
str = "protocol version";
break;
case TLS1_AD_INSUFFICIENT_SECURITY:
str = "insufficient security";
break;
case TLS1_AD_INTERNAL_ERROR:
str = "internal error";
break;
case TLS1_AD_USER_CANCELLED:
str = "user canceled";
break;
case TLS1_AD_NO_RENEGOTIATION:
str = "no renegotiation";
break;
case TLS1_AD_UNSUPPORTED_EXTENSION:
str = "unsupported extension";
break;
case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
str = "certificate unobtainable";
break;
case TLS1_AD_UNRECOGNIZED_NAME:
str = "unrecognized name";
break;
case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
str = "bad certificate status response";
break;
case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
str = "bad certificate hash value";
break;
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
str = "unknown PSK identity";
break;
default:
str = "unknown";
break;
}
return (str);
}
const char *
SSL_rstate_string(const SSL *s)
{
const char *str;
switch (s->internal->rstate) {
case SSL_ST_READ_HEADER:
str = "RH";
break;
case SSL_ST_READ_BODY:
str = "RB";
break;
case SSL_ST_READ_DONE:
str = "RD";
break;
default:
str = "unknown";
break;
}
return (str);
}

2240
externals/libressl/ssl/ssl_tlsext.c vendored Executable file

File diff suppressed because it is too large Load Diff

141
externals/libressl/ssl/ssl_tlsext.h vendored Executable file
View File

@@ -0,0 +1,141 @@
/* $OpenBSD: ssl_tlsext.h,v 1.25 2020/07/03 04:51:59 tb Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
* Copyright (c) 2019 Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_SSL_TLSEXT_H
#define HEADER_SSL_TLSEXT_H
/* TLSv1.3 - RFC 8446 Section 4.2. */
#define SSL_TLSEXT_MSG_CH 0x0001 /* ClientHello */
#define SSL_TLSEXT_MSG_SH 0x0002 /* ServerHello */
#define SSL_TLSEXT_MSG_EE 0x0004 /* EncryptedExtension */
#define SSL_TLSEXT_MSG_CT 0x0008 /* Certificate */
#define SSL_TLSEXT_MSG_CR 0x0010 /* CertificateRequest */
#define SSL_TLSEXT_MSG_NST 0x0020 /* NewSessionTicket */
#define SSL_TLSEXT_MSG_HRR 0x0040 /* HelloRetryRequest */
__BEGIN_HIDDEN_DECLS
int tlsext_alpn_client_needs(SSL *s, uint16_t msg_type);
int tlsext_alpn_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_alpn_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_alpn_server_needs(SSL *s, uint16_t msg_type);
int tlsext_alpn_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_alpn_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_ri_client_needs(SSL *s, uint16_t msg_type);
int tlsext_ri_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_ri_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_ri_server_needs(SSL *s, uint16_t msg_type);
int tlsext_ri_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_ri_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_sigalgs_client_needs(SSL *s, uint16_t msg_type);
int tlsext_sigalgs_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sigalgs_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_sigalgs_server_needs(SSL *s, uint16_t msg_type);
int tlsext_sigalgs_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sigalgs_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_sni_client_needs(SSL *s, uint16_t msg_type);
int tlsext_sni_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sni_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_sni_server_needs(SSL *s, uint16_t msg_type);
int tlsext_sni_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sni_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_sni_is_valid_hostname(CBS *cbs);
int tlsext_supportedgroups_client_needs(SSL *s, uint16_t msg_type);
int tlsext_supportedgroups_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_supportedgroups_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_supportedgroups_server_needs(SSL *s, uint16_t msg_type);
int tlsext_supportedgroups_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_supportedgroups_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_ecpf_client_needs(SSL *s, uint16_t msg_type);
int tlsext_ecpf_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_ecpf_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_ecpf_server_needs(SSL *s, uint16_t msg_type);
int tlsext_ecpf_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_ecpf_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_ocsp_client_needs(SSL *s, uint16_t msg_type);
int tlsext_ocsp_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_ocsp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_ocsp_server_needs(SSL *s, uint16_t msg_type);
int tlsext_ocsp_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_ocsp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_sessionticket_client_needs(SSL *s, uint16_t msg_type);
int tlsext_sessionticket_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sessionticket_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_sessionticket_server_needs(SSL *s, uint16_t msg_type);
int tlsext_sessionticket_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_sessionticket_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_versions_client_needs(SSL *s, uint16_t msg_type);
int tlsext_versions_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_versions_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_versions_server_needs(SSL *s, uint16_t msg_type);
int tlsext_versions_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_versions_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_keyshare_client_needs(SSL *s, uint16_t msg_type);
int tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_keyshare_client_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_keyshare_server_needs(SSL *s, uint16_t msg_type);
int tlsext_keyshare_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_keyshare_server_parse(SSL *s, uint16_t msg_type, CBS *cbs,
int *alert);
int tlsext_cookie_client_needs(SSL *s, uint16_t msg_type);
int tlsext_cookie_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_cookie_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_cookie_server_needs(SSL *s, uint16_t msg_type);
int tlsext_cookie_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_cookie_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
#ifndef OPENSSL_NO_SRTP
int tlsext_srtp_client_needs(SSL *s, uint16_t msg_type);
int tlsext_srtp_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_srtp_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_srtp_server_needs(SSL *s, uint16_t msg_type);
int tlsext_srtp_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_srtp_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
#endif
int tlsext_client_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_client_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
int tlsext_server_build(SSL *s, uint16_t msg_type, CBB *cbb);
int tlsext_server_parse(SSL *s, uint16_t msg_type, CBS *cbs, int *alert);
struct tls_extension *tls_extension_find(uint16_t, size_t *);
int tlsext_extension_seen(SSL *s, uint16_t);
__END_HIDDEN_DECLS
#endif

207
externals/libressl/ssl/ssl_transcript.c vendored Executable file
View File

@@ -0,0 +1,207 @@
/* $OpenBSD: ssl_transcript.c,v 1.2 2020/02/05 16:47:34 jsing Exp $ */
/*
* Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include <openssl/ssl.h>
int
tls1_transcript_hash_init(SSL *s)
{
const unsigned char *data;
const EVP_MD *md;
size_t len;
tls1_transcript_hash_free(s);
if (!ssl_get_handshake_evp_md(s, &md)) {
SSLerrorx(ERR_R_INTERNAL_ERROR);
goto err;
}
if ((S3I(s)->handshake_hash = EVP_MD_CTX_new()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_DigestInit_ex(S3I(s)->handshake_hash, md, NULL)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
if (!tls1_transcript_data(s, &data, &len)) {
SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH);
goto err;
}
if (!tls1_transcript_hash_update(s, data, len)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
return 1;
err:
tls1_transcript_hash_free(s);
return 0;
}
int
tls1_transcript_hash_update(SSL *s, const unsigned char *buf, size_t len)
{
if (S3I(s)->handshake_hash == NULL)
return 1;
return EVP_DigestUpdate(S3I(s)->handshake_hash, buf, len);
}
int
tls1_transcript_hash_value(SSL *s, const unsigned char *out, size_t len,
size_t *outlen)
{
EVP_MD_CTX *mdctx = NULL;
unsigned int mdlen;
int ret = 0;
if (EVP_MD_CTX_size(S3I(s)->handshake_hash) > len)
goto err;
if ((mdctx = EVP_MD_CTX_new()) == NULL) {
SSLerror(s, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_MD_CTX_copy_ex(mdctx, S3I(s)->handshake_hash)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
if (!EVP_DigestFinal_ex(mdctx, (unsigned char *)out, &mdlen)) {
SSLerror(s, ERR_R_EVP_LIB);
goto err;
}
if (outlen != NULL)
*outlen = mdlen;
ret = 1;
err:
EVP_MD_CTX_free(mdctx);
return (ret);
}
void
tls1_transcript_hash_free(SSL *s)
{
EVP_MD_CTX_free(S3I(s)->handshake_hash);
S3I(s)->handshake_hash = NULL;
}
int
tls1_transcript_init(SSL *s)
{
if (S3I(s)->handshake_transcript != NULL)
return 0;
if ((S3I(s)->handshake_transcript = BUF_MEM_new()) == NULL)
return 0;
tls1_transcript_reset(s);
return 1;
}
void
tls1_transcript_free(SSL *s)
{
BUF_MEM_free(S3I(s)->handshake_transcript);
S3I(s)->handshake_transcript = NULL;
}
void
tls1_transcript_reset(SSL *s)
{
/*
* We should check the return value of BUF_MEM_grow_clean(), however
* due to yet another bad API design, when called with a length of zero
* it is impossible to tell if it succeeded (returning a length of zero)
* or if it failed (and returned zero)... our implementation never
* fails with a length of zero, so we trust all is okay...
*/
(void)BUF_MEM_grow_clean(S3I(s)->handshake_transcript, 0);
tls1_transcript_unfreeze(s);
}
int
tls1_transcript_append(SSL *s, const unsigned char *buf, size_t len)
{
size_t olen, nlen;
if (S3I(s)->handshake_transcript == NULL)
return 1;
if (s->s3->flags & TLS1_FLAGS_FREEZE_TRANSCRIPT)
return 1;
olen = S3I(s)->handshake_transcript->length;
nlen = olen + len;
if (nlen < olen)
return 0;
if (BUF_MEM_grow(S3I(s)->handshake_transcript, nlen) == 0)
return 0;
memcpy(S3I(s)->handshake_transcript->data + olen, buf, len);
return 1;
}
int
tls1_transcript_data(SSL *s, const unsigned char **data, size_t *len)
{
if (S3I(s)->handshake_transcript == NULL)
return 0;
*data = S3I(s)->handshake_transcript->data;
*len = S3I(s)->handshake_transcript->length;
return 1;
}
void
tls1_transcript_freeze(SSL *s)
{
s->s3->flags |= TLS1_FLAGS_FREEZE_TRANSCRIPT;
}
void
tls1_transcript_unfreeze(SSL *s)
{
s->s3->flags &= ~TLS1_FLAGS_FREEZE_TRANSCRIPT;
}
int
tls1_transcript_record(SSL *s, const unsigned char *buf, size_t len)
{
if (!tls1_transcript_hash_update(s, buf, len))
return 0;
if (!tls1_transcript_append(s, buf, len))
return 0;
return 1;
}

188
externals/libressl/ssl/ssl_txt.c vendored Executable file
View File

@@ -0,0 +1,188 @@
/* $OpenBSD: ssl_txt.c,v 1.28 2017/02/07 02:08:38 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2005 Nokia. All rights reserved.
*
* The portions of the attached software ("Contribution") is developed by
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
* license.
*
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
* support (see RFC 4279) to OpenSSL.
*
* No patent licenses or other rights except those expressly stated in
* the OpenSSL open source license shall be deemed granted or received
* expressly, by implication, estoppel, or otherwise.
*
* No assurances are provided by Nokia that the Contribution does not
* infringe the patent or other intellectual property rights of any third
* party or that the license provides you with all the necessary rights
* to make use of the Contribution.
*
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE.
*/
#include <inttypes.h>
#include <stdio.h>
#include <openssl/buffer.h>
#include "ssl_locl.h"
int
SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file_internal())) == NULL) {
SSLerrorx(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = SSL_SESSION_print(b, x);
BIO_free(b);
return (ret);
}
int
SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
{
unsigned int i;
const char *s;
if (x == NULL)
goto err;
if (BIO_puts(bp, "SSL-Session:\n") <= 0)
goto err;
s = ssl_version_string(x->ssl_version);
if (BIO_printf(bp, " Protocol : %s\n", s) <= 0)
goto err;
if (x->cipher == NULL) {
if (((x->cipher_id) & 0xff000000) == 0x02000000) {
if (BIO_printf(bp, " Cipher : %06lX\n", x->cipher_id&0xffffff) <= 0)
goto err;
} else {
if (BIO_printf(bp, " Cipher : %04lX\n", x->cipher_id&0xffff) <= 0)
goto err;
}
} else {
if (BIO_printf(bp, " Cipher : %s\n",((x->cipher == NULL)?"unknown":x->cipher->name)) <= 0)
goto err;
}
if (BIO_puts(bp, " Session-ID: ") <= 0)
goto err;
for (i = 0; i < x->session_id_length; i++) {
if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0)
goto err;
}
if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0)
goto err;
for (i = 0; i < x->sid_ctx_length; i++) {
if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0)
goto err;
}
if (BIO_puts(bp, "\n Master-Key: ") <= 0)
goto err;
for (i = 0; i < (unsigned int)x->master_key_length; i++) {
if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
goto err;
}
if (x->tlsext_tick_lifetime_hint) {
if (BIO_printf(bp,
"\n TLS session ticket lifetime hint: %ld (seconds)",
x->tlsext_tick_lifetime_hint) <= 0)
goto err;
}
if (x->tlsext_tick) {
if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0)
goto err;
if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) <= 0)
goto err;
}
if (x->time != 0) {
if (BIO_printf(bp, "\n Start Time: %"PRId64, (int64_t)x->time) <= 0)
goto err;
}
if (x->timeout != 0L) {
if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0)
goto err;
}
if (BIO_puts(bp, "\n") <= 0)
goto err;
if (BIO_puts(bp, " Verify return code: ") <= 0)
goto err;
if (BIO_printf(bp, "%ld (%s)\n", x->verify_result,
X509_verify_cert_error_string(x->verify_result)) <= 0)
goto err;
return (1);
err:
return (0);
}

233
externals/libressl/ssl/ssl_versions.c vendored Executable file
View File

@@ -0,0 +1,233 @@
/* $OpenBSD: ssl_versions.c,v 1.6 2020/05/31 18:03:32 jsing Exp $ */
/*
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
static int
ssl_clamp_version_range(uint16_t *min_ver, uint16_t *max_ver,
uint16_t clamp_min, uint16_t clamp_max)
{
if (clamp_min > clamp_max || *min_ver > *max_ver)
return 0;
if (clamp_max < *min_ver || clamp_min > *max_ver)
return 0;
if (*min_ver < clamp_min)
*min_ver = clamp_min;
if (*max_ver > clamp_max)
*max_ver = clamp_max;
return 1;
}
int
ssl_version_set_min(const SSL_METHOD *meth, uint16_t ver, uint16_t max_ver,
uint16_t *out_ver)
{
uint16_t min_version, max_version;
if (ver == 0) {
*out_ver = meth->internal->min_version;
return 1;
}
min_version = ver;
max_version = max_ver;
if (!ssl_clamp_version_range(&min_version, &max_version,
meth->internal->min_version, meth->internal->max_version))
return 0;
*out_ver = min_version;
return 1;
}
int
ssl_version_set_max(const SSL_METHOD *meth, uint16_t ver, uint16_t min_ver,
uint16_t *out_ver)
{
uint16_t min_version, max_version;
if (ver == 0) {
*out_ver = meth->internal->max_version;
return 1;
}
min_version = min_ver;
max_version = ver;
if (!ssl_clamp_version_range(&min_version, &max_version,
meth->internal->min_version, meth->internal->max_version))
return 0;
*out_ver = max_version;
return 1;
}
int
ssl_enabled_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
{
uint16_t min_version, max_version;
/*
* The enabled versions have to be a contiguous range, which means we
* cannot enable and disable single versions at our whim, even though
* this is what the OpenSSL flags allow. The historical way this has
* been handled is by making a flag mean that all higher versions
* are disabled, if any version lower than the flag is enabled.
*/
min_version = 0;
max_version = TLS1_3_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1) == 0)
min_version = TLS1_VERSION;
else if ((s->internal->options & SSL_OP_NO_TLSv1_1) == 0)
min_version = TLS1_1_VERSION;
else if ((s->internal->options & SSL_OP_NO_TLSv1_2) == 0)
min_version = TLS1_2_VERSION;
else if ((s->internal->options & SSL_OP_NO_TLSv1_3) == 0)
min_version = TLS1_3_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1_3) && min_version < TLS1_3_VERSION)
max_version = TLS1_2_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1_2) && min_version < TLS1_2_VERSION)
max_version = TLS1_1_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1_1) && min_version < TLS1_1_VERSION)
max_version = TLS1_VERSION;
if ((s->internal->options & SSL_OP_NO_TLSv1) && min_version < TLS1_VERSION)
max_version = 0;
/* Everything has been disabled... */
if (min_version == 0 || max_version == 0)
return 0;
/* Limit to configured version range. */
if (!ssl_clamp_version_range(&min_version, &max_version,
s->internal->min_version, s->internal->max_version))
return 0;
if (min_ver != NULL)
*min_ver = min_version;
if (max_ver != NULL)
*max_ver = max_version;
return 1;
}
int
ssl_supported_version_range(SSL *s, uint16_t *min_ver, uint16_t *max_ver)
{
uint16_t min_version, max_version;
/* DTLS cannot currently be disabled... */
if (SSL_IS_DTLS(s)) {
min_version = max_version = DTLS1_VERSION;
goto done;
}
if (!ssl_enabled_version_range(s, &min_version, &max_version))
return 0;
/* Limit to the versions supported by this method. */
if (!ssl_clamp_version_range(&min_version, &max_version,
s->method->internal->min_version,
s->method->internal->max_version))
return 0;
done:
if (min_ver != NULL)
*min_ver = min_version;
if (max_ver != NULL)
*max_ver = max_version;
return 1;
}
int
ssl_max_shared_version(SSL *s, uint16_t peer_ver, uint16_t *max_ver)
{
uint16_t min_version, max_version, shared_version;
*max_ver = 0;
if (SSL_IS_DTLS(s)) {
if (peer_ver >= DTLS1_VERSION) {
*max_ver = DTLS1_VERSION;
return 1;
}
return 0;
}
if (peer_ver >= TLS1_3_VERSION)
shared_version = TLS1_3_VERSION;
else if (peer_ver >= TLS1_2_VERSION)
shared_version = TLS1_2_VERSION;
else if (peer_ver >= TLS1_1_VERSION)
shared_version = TLS1_1_VERSION;
else if (peer_ver >= TLS1_VERSION)
shared_version = TLS1_VERSION;
else
return 0;
if (!ssl_supported_version_range(s, &min_version, &max_version))
return 0;
if (shared_version < min_version)
return 0;
if (shared_version > max_version)
shared_version = max_version;
*max_ver = shared_version;
return 1;
}
int
ssl_downgrade_max_version(SSL *s, uint16_t *max_ver)
{
uint16_t min_version, max_version;
/*
* The downgrade maximum version is based on the versions that are
* enabled, however we also have to then limit to the versions
* supported by the method. The SSL method will be changed during
* version negotiation and when switching from the new stack to
* the legacy context, as such we want to use the method from the
* context.
*/
if (SSL_IS_DTLS(s)) {
*max_ver = DTLS1_VERSION;
return 1;
}
if (!ssl_enabled_version_range(s, &min_version, &max_version))
return 0;
if (!ssl_clamp_version_range(&min_version, &max_version,
s->ctx->method->internal->min_version,
s->ctx->method->internal->max_version))
return 0;
*max_ver = max_version;
return 1;
}

1189
externals/libressl/ssl/t1_enc.c vendored Executable file

File diff suppressed because it is too large Load Diff

1008
externals/libressl/ssl/t1_lib.c vendored Executable file

File diff suppressed because it is too large Load Diff

542
externals/libressl/ssl/tls12_record_layer.c vendored Executable file
View File

@@ -0,0 +1,542 @@
/* $OpenBSD: tls12_record_layer.c,v 1.4 2020/09/16 17:15:01 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <openssl/evp.h>
#include "ssl_locl.h"
struct tls12_record_layer {
uint16_t version;
int dtls;
uint16_t read_epoch;
uint16_t write_epoch;
int read_stream_mac;
int write_stream_mac;
/*
* XXX - for now these are just pointers to externally managed
* structs/memory. These should eventually be owned by the record layer.
*/
SSL_AEAD_CTX *read_aead_ctx;
SSL_AEAD_CTX *write_aead_ctx;
EVP_CIPHER_CTX *read_cipher_ctx;
EVP_MD_CTX *read_hash_ctx;
EVP_CIPHER_CTX *write_cipher_ctx;
EVP_MD_CTX *write_hash_ctx;
uint8_t *read_seq_num;
uint8_t *write_seq_num;
};
struct tls12_record_layer *
tls12_record_layer_new(void)
{
struct tls12_record_layer *rl;
if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL)
return NULL;
return rl;
}
void
tls12_record_layer_free(struct tls12_record_layer *rl)
{
freezero(rl, sizeof(struct tls12_record_layer));
}
void
tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version)
{
rl->version = version;
rl->dtls = (version == DTLS1_VERSION);
}
void
tls12_record_layer_set_read_epoch(struct tls12_record_layer *rl, uint16_t epoch)
{
rl->read_epoch = epoch;
}
void
tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch)
{
rl->write_epoch = epoch;
}
static void
tls12_record_layer_set_read_state(struct tls12_record_layer *rl,
SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx,
int stream_mac)
{
rl->read_aead_ctx = aead_ctx;
rl->read_cipher_ctx = cipher_ctx;
rl->read_hash_ctx = hash_ctx;
rl->read_stream_mac = stream_mac;
}
static void
tls12_record_layer_set_write_state(struct tls12_record_layer *rl,
SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx,
int stream_mac)
{
rl->write_aead_ctx = aead_ctx;
rl->write_cipher_ctx = cipher_ctx;
rl->write_hash_ctx = hash_ctx;
rl->write_stream_mac = stream_mac;
}
void
tls12_record_layer_clear_read_state(struct tls12_record_layer *rl)
{
tls12_record_layer_set_read_state(rl, NULL, NULL, NULL, 0);
rl->read_seq_num = NULL;
}
void
tls12_record_layer_clear_write_state(struct tls12_record_layer *rl)
{
tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0);
rl->write_seq_num = NULL;
}
void
tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl,
uint8_t *seq_num)
{
rl->read_seq_num = seq_num;
}
void
tls12_record_layer_set_write_seq_num(struct tls12_record_layer *rl,
uint8_t *seq_num)
{
rl->write_seq_num = seq_num;
}
int
tls12_record_layer_set_read_aead(struct tls12_record_layer *rl,
SSL_AEAD_CTX *aead_ctx)
{
tls12_record_layer_set_read_state(rl, aead_ctx, NULL, NULL, 0);
return 1;
}
int
tls12_record_layer_set_write_aead(struct tls12_record_layer *rl,
SSL_AEAD_CTX *aead_ctx)
{
tls12_record_layer_set_write_state(rl, aead_ctx, NULL, NULL, 0);
return 1;
}
int
tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl,
EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac)
{
tls12_record_layer_set_read_state(rl, NULL, cipher_ctx, hash_ctx,
stream_mac);
return 1;
}
int
tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl,
EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac)
{
tls12_record_layer_set_write_state(rl, NULL, cipher_ctx, hash_ctx,
stream_mac);
return 1;
}
static int
tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb,
uint16_t epoch, uint8_t *seq_num, size_t seq_num_len)
{
CBS seq;
CBS_init(&seq, seq_num, seq_num_len);
if (rl->dtls) {
if (!CBB_add_u16(cbb, epoch))
return 0;
if (!CBS_skip(&seq, 2))
return 0;
}
return CBB_add_bytes(cbb, CBS_data(&seq), CBS_len(&seq));
}
static int
tls12_record_layer_pseudo_header(struct tls12_record_layer *rl,
uint8_t content_type, uint16_t record_len, uint16_t epoch, uint8_t *seq_num,
size_t seq_num_len, uint8_t **out, size_t *out_len)
{
CBB cbb;
*out = NULL;
*out_len = 0;
/* Build the pseudo-header used for MAC/AEAD. */
if (!CBB_init(&cbb, 13))
goto err;
if (!tls12_record_layer_build_seq_num(rl, &cbb, epoch,
seq_num, seq_num_len))
goto err;
if (!CBB_add_u8(&cbb, content_type))
goto err;
if (!CBB_add_u16(&cbb, rl->version))
goto err;
if (!CBB_add_u16(&cbb, record_len))
goto err;
if (!CBB_finish(&cbb, out, out_len))
goto err;
return 1;
err:
CBB_cleanup(&cbb);
return 0;
}
static int
tls12_record_layer_mac(struct tls12_record_layer *rl, CBB *cbb,
EVP_MD_CTX *hash_ctx, int stream_mac, uint16_t epoch, uint8_t *seq_num,
size_t seq_num_len, uint8_t content_type, const uint8_t *content,
size_t content_len, size_t *out_len)
{
EVP_MD_CTX *mac_ctx = NULL;
uint8_t *header = NULL;
size_t header_len;
size_t mac_len;
uint8_t *mac;
int ret = 0;
if ((mac_ctx = EVP_MD_CTX_new()) == NULL)
goto err;
if (!EVP_MD_CTX_copy(mac_ctx, hash_ctx))
goto err;
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
epoch, seq_num, seq_num_len, &header, &header_len))
goto err;
if (EVP_DigestSignUpdate(mac_ctx, header, header_len) <= 0)
goto err;
if (EVP_DigestSignUpdate(mac_ctx, content, content_len) <= 0)
goto err;
if (EVP_DigestSignFinal(mac_ctx, NULL, &mac_len) <= 0)
goto err;
if (!CBB_add_space(cbb, &mac, mac_len))
goto err;
if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0)
goto err;
if (stream_mac) {
if (!EVP_MD_CTX_copy(hash_ctx, mac_ctx))
goto err;
}
*out_len = mac_len;
ret = 1;
err:
EVP_MD_CTX_free(mac_ctx);
free(header);
return ret;
}
static int
tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb,
uint8_t content_type, const uint8_t *content, size_t content_len,
size_t *out_len)
{
return tls12_record_layer_mac(rl, cbb, rl->write_hash_ctx,
rl->write_stream_mac, rl->write_epoch, rl->write_seq_num,
SSL3_SEQUENCE_SIZE, content_type, content, content_len, out_len);
}
static int
tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl,
const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len)
{
CBB cbb;
if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE)
return 0;
/* Fixed nonce and variable nonce (sequence number) are concatenated. */
if (!CBB_init(&cbb, 16))
goto err;
if (!CBB_add_bytes(&cbb, aead->fixed_nonce,
aead->fixed_nonce_len))
goto err;
if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len))
goto err;
if (!CBB_finish(&cbb, out, out_len))
goto err;
return 1;
err:
CBB_cleanup(&cbb);
return 0;
}
static int
tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl,
const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len)
{
uint8_t *nonce = NULL;
size_t nonce_len = 0;
uint8_t *pad;
CBB cbb;
int i;
if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE)
return 0;
if (aead->fixed_nonce_len < aead->variable_nonce_len)
return 0;
/*
* Variable nonce (sequence number) is right padded, before the fixed
* nonce is XOR'd in.
*/
if (!CBB_init(&cbb, 16))
goto err;
if (!CBB_add_space(&cbb, &pad,
aead->fixed_nonce_len - aead->variable_nonce_len))
goto err;
if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len))
goto err;
if (!CBB_finish(&cbb, &nonce, &nonce_len))
goto err;
for (i = 0; i < aead->fixed_nonce_len; i++)
nonce[i] ^= aead->fixed_nonce[i];
*out = nonce;
*out_len = nonce_len;
return 1;
err:
CBB_cleanup(&cbb);
freezero(nonce, nonce_len);
return 0;
}
static int
tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl,
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
{
if (rl->write_aead_ctx != NULL || rl->write_cipher_ctx != NULL)
return 0;
return CBB_add_bytes(out, content, content_len);
}
static int
tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl,
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
{
const SSL_AEAD_CTX *aead = rl->write_aead_ctx;
uint8_t *header = NULL, *nonce = NULL;
size_t header_len = 0, nonce_len = 0;
size_t enc_record_len, out_len;
uint16_t epoch = 0;
uint8_t *enc_data;
int ret = 0;
/* XXX - move to nonce allocated in record layer, matching TLSv1.3 */
if (aead->xor_fixed_nonce) {
if (!tls12_record_layer_aead_xored_nonce(rl, aead,
rl->write_seq_num, &nonce, &nonce_len))
goto err;
} else {
if (!tls12_record_layer_aead_concat_nonce(rl, aead,
rl->write_seq_num, &nonce, &nonce_len))
goto err;
}
if (aead->variable_nonce_in_record) {
/* XXX - length check? */
if (!CBB_add_bytes(out, rl->write_seq_num, aead->variable_nonce_len))
goto err;
}
if (!tls12_record_layer_pseudo_header(rl, content_type, content_len,
epoch, rl->write_seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len))
goto err;
/* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */
enc_record_len = content_len + aead->tag_len;
if (enc_record_len > SSL3_RT_MAX_ENCRYPTED_LENGTH)
goto err;
if (!CBB_add_space(out, &enc_data, enc_record_len))
goto err;
if (!EVP_AEAD_CTX_seal(&aead->ctx, enc_data, &out_len, enc_record_len,
nonce, nonce_len, content, content_len, header, header_len))
goto err;
if (out_len != enc_record_len)
goto err;
ret = 1;
err:
freezero(header, header_len);
freezero(nonce, nonce_len);
return ret;
}
static int
tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl,
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out)
{
EVP_CIPHER_CTX *enc = rl->write_cipher_ctx;
size_t mac_len, pad_len;
int block_size, eiv_len;
uint8_t *enc_data, *eiv, *pad, pad_val;
uint8_t *plain = NULL;
size_t plain_len = 0;
int ret = 0;
CBB cbb;
if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
goto err;
/* Add explicit IV if necessary. */
eiv_len = 0;
if (rl->version != TLS1_VERSION &&
EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE)
eiv_len = EVP_CIPHER_CTX_iv_length(enc);
if (eiv_len < 0 || eiv_len > EVP_MAX_IV_LENGTH)
goto err;
if (eiv_len > 0) {
if (!CBB_add_space(&cbb, &eiv, eiv_len))
goto err;
arc4random_buf(eiv, eiv_len);
}
if (!CBB_add_bytes(&cbb, content, content_len))
goto err;
mac_len = 0;
if (rl->write_hash_ctx != NULL) {
if (!tls12_record_layer_write_mac(rl, &cbb, content_type,
content, content_len, &mac_len))
goto err;
}
plain_len = (size_t)eiv_len + content_len + mac_len;
/* Add padding to block size, if necessary. */
block_size = EVP_CIPHER_CTX_block_size(enc);
if (block_size < 0 || block_size > EVP_MAX_BLOCK_LENGTH)
goto err;
if (block_size > 1) {
pad_len = block_size - (plain_len % block_size);
pad_val = pad_len - 1;
if (pad_len > 255)
goto err;
if (!CBB_add_space(&cbb, &pad, pad_len))
goto err;
memset(pad, pad_val, pad_len);
}
if (!CBB_finish(&cbb, &plain, &plain_len))
goto err;
if (plain_len % block_size != 0)
goto err;
if (plain_len > SSL3_RT_MAX_ENCRYPTED_LENGTH)
goto err;
if (!CBB_add_space(out, &enc_data, plain_len))
goto err;
if (!EVP_Cipher(enc, enc_data, plain, plain_len))
goto err;
ret = 1;
err:
CBB_cleanup(&cbb);
freezero(plain, plain_len);
return ret;
}
int
tls12_record_layer_seal_record(struct tls12_record_layer *rl,
uint8_t content_type, const uint8_t *content, size_t content_len, CBB *cbb)
{
CBB fragment;
if (!CBB_add_u8(cbb, content_type))
return 0;
if (!CBB_add_u16(cbb, rl->version))
return 0;
if (rl->dtls) {
if (!tls12_record_layer_build_seq_num(rl, cbb,
rl->write_epoch, rl->write_seq_num,
SSL3_SEQUENCE_SIZE))
return 0;
}
if (!CBB_add_u16_length_prefixed(cbb, &fragment))
return 0;
if (rl->write_aead_ctx != NULL) {
if (!tls12_record_layer_seal_record_protected_aead(rl,
content_type, content, content_len, &fragment))
return 0;
} else if (rl->write_cipher_ctx != NULL) {
if (!tls12_record_layer_seal_record_protected_cipher(rl,
content_type, content, content_len, &fragment))
return 0;
} else {
if (!tls12_record_layer_seal_record_plaintext(rl,
content_type, content, content_len, &fragment))
return 0;
}
if (!CBB_flush(cbb))
return 0;
tls1_record_sequence_increment(rl->write_seq_num);
return 1;
}

137
externals/libressl/ssl/tls13_buffer.c vendored Executable file
View File

@@ -0,0 +1,137 @@
/* $OpenBSD: tls13_buffer.c,v 1.3 2020/03/10 17:11:25 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include "bytestring.h"
#include "tls13_internal.h"
struct tls13_buffer {
size_t capacity;
uint8_t *data;
size_t len;
size_t offset;
};
static int tls13_buffer_resize(struct tls13_buffer *buf, size_t capacity);
struct tls13_buffer *
tls13_buffer_new(size_t init_size)
{
struct tls13_buffer *buf = NULL;
if ((buf = calloc(1, sizeof(struct tls13_buffer))) == NULL)
goto err;
if (!tls13_buffer_resize(buf, init_size))
goto err;
return buf;
err:
tls13_buffer_free(buf);
return NULL;
}
void
tls13_buffer_free(struct tls13_buffer *buf)
{
if (buf == NULL)
return;
freezero(buf->data, buf->capacity);
freezero(buf, sizeof(struct tls13_buffer));
}
static int
tls13_buffer_resize(struct tls13_buffer *buf, size_t capacity)
{
uint8_t *data;
if (buf->capacity == capacity)
return 1;
if ((data = recallocarray(buf->data, buf->capacity, capacity, 1)) == NULL)
return 0;
buf->data = data;
buf->capacity = capacity;
return 1;
}
int
tls13_buffer_set_data(struct tls13_buffer *buf, CBS *data)
{
if (!tls13_buffer_resize(buf, CBS_len(data)))
return 0;
memcpy(buf->data, CBS_data(data), CBS_len(data));
return 1;
}
ssize_t
tls13_buffer_extend(struct tls13_buffer *buf, size_t len,
tls13_read_cb read_cb, void *cb_arg)
{
ssize_t ret;
if (len == buf->len)
return buf->len;
if (len < buf->len)
return TLS13_IO_FAILURE;
if (!tls13_buffer_resize(buf, len))
return TLS13_IO_FAILURE;
for (;;) {
if ((ret = read_cb(&buf->data[buf->len],
buf->capacity - buf->len, cb_arg)) <= 0)
return ret;
if (ret > buf->capacity - buf->len)
return TLS13_IO_FAILURE;
buf->len += ret;
if (buf->len == buf->capacity)
return buf->len;
}
}
void
tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs)
{
CBS_init(cbs, buf->data, buf->len);
}
int
tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out, size_t *out_len)
{
if (out == NULL || out_len == NULL)
return 0;
*out = buf->data;
*out_len = buf->len;
buf->capacity = 0;
buf->data = NULL;
buf->len = 0;
return 1;
}

1088
externals/libressl/ssl/tls13_client.c vendored Executable file

File diff suppressed because it is too large Load Diff

99
externals/libressl/ssl/tls13_error.c vendored Executable file
View File

@@ -0,0 +1,99 @@
/* $OpenBSD: tls13_error.c,v 1.1 2020/01/20 13:10:37 jsing Exp $ */
/*
* Copyright (c) 2014,2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include "tls13_internal.h"
void
tls13_error_clear(struct tls13_error *error)
{
error->code = 0;
error->subcode = 0;
error->errnum = 0;
error->file = NULL;
error->line = 0;
free(error->msg);
error->msg = NULL;
}
static int
tls13_error_vset(struct tls13_error *error, int code, int subcode, int errnum,
const char *file, int line, const char *fmt, va_list ap)
{
char *errmsg = NULL;
int rv = -1;
tls13_error_clear(error);
error->code = code;
error->subcode = subcode;
error->errnum = errnum;
error->file = file;
error->line = line;
if (vasprintf(&errmsg, fmt, ap) == -1) {
errmsg = NULL;
goto err;
}
if (errnum == -1) {
error->msg = errmsg;
return 0;
}
if (asprintf(&error->msg, "%s: %s", errmsg, strerror(errnum)) == -1) {
error->msg = NULL;
goto err;
}
rv = 0;
err:
free(errmsg);
return rv;
}
int
tls13_error_set(struct tls13_error *error, int code, int subcode,
const char *file, int line, const char *fmt, ...)
{
va_list ap;
int errnum, rv;
errnum = errno;
va_start(ap, fmt);
rv = tls13_error_vset(error, code, subcode, errnum, file, line, fmt, ap);
va_end(ap);
return (rv);
}
int
tls13_error_setx(struct tls13_error *error, int code, int subcode,
const char *file, int line, const char *fmt, ...)
{
va_list ap;
int rv;
va_start(ap, fmt);
rv = tls13_error_vset(error, code, subcode, -1, file, line, fmt, ap);
va_end(ap);
return (rv);
}

517
externals/libressl/ssl/tls13_handshake.c vendored Executable file
View File

@@ -0,0 +1,517 @@
/* $OpenBSD: tls13_handshake.c,v 1.64 2020/07/30 16:23:17 tb Exp $ */
/*
* Copyright (c) 2018-2019 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stddef.h>
#include "ssl_locl.h"
#include "tls13_handshake.h"
#include "tls13_internal.h"
/* Based on RFC 8446 and inspired by s2n's TLS 1.2 state machine. */
struct tls13_handshake_action {
uint8_t handshake_type;
uint8_t sender;
uint8_t handshake_complete;
uint8_t send_preserve_transcript_hash;
uint8_t recv_preserve_transcript_hash;
int (*send)(struct tls13_ctx *ctx, CBB *cbb);
int (*sent)(struct tls13_ctx *ctx);
int (*recv)(struct tls13_ctx *ctx, CBS *cbs);
};
static enum tls13_message_type
tls13_handshake_active_state(struct tls13_ctx *ctx);
static const struct tls13_handshake_action *
tls13_handshake_active_action(struct tls13_ctx *ctx);
static int tls13_handshake_advance_state_machine(struct tls13_ctx *ctx);
static int tls13_handshake_send_action(struct tls13_ctx *ctx,
const struct tls13_handshake_action *action);
static int tls13_handshake_recv_action(struct tls13_ctx *ctx,
const struct tls13_handshake_action *action);
static const struct tls13_handshake_action state_machine[] = {
[CLIENT_HELLO] = {
.handshake_type = TLS13_MT_CLIENT_HELLO,
.sender = TLS13_HS_CLIENT,
.send = tls13_client_hello_send,
.sent = tls13_client_hello_sent,
.recv = tls13_client_hello_recv,
},
[CLIENT_HELLO_RETRY] = {
.handshake_type = TLS13_MT_CLIENT_HELLO,
.sender = TLS13_HS_CLIENT,
.send = tls13_client_hello_retry_send,
.recv = tls13_client_hello_retry_recv,
},
[CLIENT_END_OF_EARLY_DATA] = {
.handshake_type = TLS13_MT_END_OF_EARLY_DATA,
.sender = TLS13_HS_CLIENT,
.send = tls13_client_end_of_early_data_send,
.recv = tls13_client_end_of_early_data_recv,
},
[CLIENT_CERTIFICATE] = {
.handshake_type = TLS13_MT_CERTIFICATE,
.sender = TLS13_HS_CLIENT,
.send_preserve_transcript_hash = 1,
.send = tls13_client_certificate_send,
.recv = tls13_client_certificate_recv,
},
[CLIENT_CERTIFICATE_VERIFY] = {
.handshake_type = TLS13_MT_CERTIFICATE_VERIFY,
.sender = TLS13_HS_CLIENT,
.recv_preserve_transcript_hash = 1,
.send = tls13_client_certificate_verify_send,
.recv = tls13_client_certificate_verify_recv,
},
[CLIENT_FINISHED] = {
.handshake_type = TLS13_MT_FINISHED,
.sender = TLS13_HS_CLIENT,
.recv_preserve_transcript_hash = 1,
.send = tls13_client_finished_send,
.sent = tls13_client_finished_sent,
.recv = tls13_client_finished_recv,
},
[SERVER_HELLO] = {
.handshake_type = TLS13_MT_SERVER_HELLO,
.sender = TLS13_HS_SERVER,
.send = tls13_server_hello_send,
.sent = tls13_server_hello_sent,
.recv = tls13_server_hello_recv,
},
[SERVER_HELLO_RETRY_REQUEST] = {
.handshake_type = TLS13_MT_SERVER_HELLO,
.sender = TLS13_HS_SERVER,
.send = tls13_server_hello_retry_request_send,
.recv = tls13_server_hello_retry_request_recv,
.sent = tls13_server_hello_retry_request_sent,
},
[SERVER_ENCRYPTED_EXTENSIONS] = {
.handshake_type = TLS13_MT_ENCRYPTED_EXTENSIONS,
.sender = TLS13_HS_SERVER,
.send = tls13_server_encrypted_extensions_send,
.recv = tls13_server_encrypted_extensions_recv,
},
[SERVER_CERTIFICATE] = {
.handshake_type = TLS13_MT_CERTIFICATE,
.sender = TLS13_HS_SERVER,
.send_preserve_transcript_hash = 1,
.send = tls13_server_certificate_send,
.recv = tls13_server_certificate_recv,
},
[SERVER_CERTIFICATE_REQUEST] = {
.handshake_type = TLS13_MT_CERTIFICATE_REQUEST,
.sender = TLS13_HS_SERVER,
.send = tls13_server_certificate_request_send,
.recv = tls13_server_certificate_request_recv,
},
[SERVER_CERTIFICATE_VERIFY] = {
.handshake_type = TLS13_MT_CERTIFICATE_VERIFY,
.sender = TLS13_HS_SERVER,
.recv_preserve_transcript_hash = 1,
.send = tls13_server_certificate_verify_send,
.recv = tls13_server_certificate_verify_recv,
},
[SERVER_FINISHED] = {
.handshake_type = TLS13_MT_FINISHED,
.sender = TLS13_HS_SERVER,
.recv_preserve_transcript_hash = 1,
.send_preserve_transcript_hash = 1,
.send = tls13_server_finished_send,
.sent = tls13_server_finished_sent,
.recv = tls13_server_finished_recv,
},
[APPLICATION_DATA] = {
.handshake_complete = 1,
},
};
const enum tls13_message_type handshakes[][TLS13_NUM_MESSAGE_TYPES] = {
[INITIAL] = {
CLIENT_HELLO,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_RETRY,
SERVER_HELLO,
},
[NEGOTIATED] = {
CLIENT_HELLO,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_RETRY,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE_REQUEST,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_CERTIFICATE,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITHOUT_HRR] = {
CLIENT_HELLO,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE_REQUEST,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_CERTIFICATE,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITHOUT_CR] = {
CLIENT_HELLO,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_RETRY,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITHOUT_HRR | WITHOUT_CR] = {
CLIENT_HELLO,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITH_PSK] = {
CLIENT_HELLO,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_RETRY,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_FINISHED,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITHOUT_HRR | WITH_PSK] = {
CLIENT_HELLO,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_FINISHED,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITH_CCV] = {
CLIENT_HELLO,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_RETRY,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE_REQUEST,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_CERTIFICATE,
CLIENT_CERTIFICATE_VERIFY,
CLIENT_FINISHED,
APPLICATION_DATA,
},
[NEGOTIATED | WITHOUT_HRR | WITH_CCV] = {
CLIENT_HELLO,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE_REQUEST,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_CERTIFICATE,
CLIENT_CERTIFICATE_VERIFY,
CLIENT_FINISHED,
APPLICATION_DATA,
},
};
const size_t handshake_count = sizeof(handshakes) / sizeof(handshakes[0]);
#ifndef TLS13_DEBUG
#define DEBUGF(...)
#else
#define DEBUGF(...) fprintf(stderr, __VA_ARGS__)
static const char *
tls13_handshake_mode_name(uint8_t mode)
{
switch (mode) {
case TLS13_HS_CLIENT:
return "Client";
case TLS13_HS_SERVER:
return "Server";
}
return "Unknown";
}
static const char *
tls13_handshake_message_name(uint8_t msg_type)
{
switch (msg_type) {
case TLS13_MT_CLIENT_HELLO:
return "ClientHello";
case TLS13_MT_SERVER_HELLO:
return "ServerHello";
case TLS13_MT_NEW_SESSION_TICKET:
return "NewSessionTicket";
case TLS13_MT_END_OF_EARLY_DATA:
return "EndOfEarlyData";
case TLS13_MT_ENCRYPTED_EXTENSIONS:
return "EncryptedExtensions";
case TLS13_MT_CERTIFICATE:
return "Certificate";
case TLS13_MT_CERTIFICATE_REQUEST:
return "CertificateRequest";
case TLS13_MT_CERTIFICATE_VERIFY:
return "CertificateVerify";
case TLS13_MT_FINISHED:
return "Finished";
case TLS13_MT_KEY_UPDATE:
return "KeyUpdate";
}
return "Unknown";
}
#endif
static enum tls13_message_type
tls13_handshake_active_state(struct tls13_ctx *ctx)
{
struct tls13_handshake_stage hs = ctx->handshake_stage;
if (hs.hs_type >= handshake_count)
return INVALID;
if (hs.message_number >= TLS13_NUM_MESSAGE_TYPES)
return INVALID;
return handshakes[hs.hs_type][hs.message_number];
}
static const struct tls13_handshake_action *
tls13_handshake_active_action(struct tls13_ctx *ctx)
{
enum tls13_message_type mt = tls13_handshake_active_state(ctx);
if (mt == INVALID)
return NULL;
return &state_machine[mt];
}
static int
tls13_handshake_advance_state_machine(struct tls13_ctx *ctx)
{
if (++ctx->handshake_stage.message_number >= TLS13_NUM_MESSAGE_TYPES)
return 0;
return 1;
}
int
tls13_handshake_msg_record(struct tls13_ctx *ctx)
{
CBS cbs;
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
return tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs));
}
int
tls13_handshake_perform(struct tls13_ctx *ctx)
{
const struct tls13_handshake_action *action;
int ret;
if (!ctx->handshake_started) {
ctx->handshake_started = 1;
if (ctx->info_cb != NULL)
ctx->info_cb(ctx, TLS13_INFO_HANDSHAKE_STARTED, 1);
}
for (;;) {
if ((action = tls13_handshake_active_action(ctx)) == NULL)
return TLS13_IO_FAILURE;
if (action->handshake_complete) {
ctx->handshake_completed = 1;
tls13_record_layer_handshake_completed(ctx->rl);
if (ctx->info_cb != NULL)
ctx->info_cb(ctx,
TLS13_INFO_HANDSHAKE_COMPLETED, 1);
return TLS13_IO_SUCCESS;
}
DEBUGF("%s %s %s\n", tls13_handshake_mode_name(ctx->mode),
(action->sender == ctx->mode) ? "sending" : "receiving",
tls13_handshake_message_name(action->handshake_type));
if (ctx->alert)
return tls13_send_alert(ctx->rl, ctx->alert);
if (action->sender == ctx->mode)
ret = tls13_handshake_send_action(ctx, action);
else
ret = tls13_handshake_recv_action(ctx, action);
if (ctx->alert)
return tls13_send_alert(ctx->rl, ctx->alert);
if (ret <= 0) {
DEBUGF("%s %s returned %d\n",
tls13_handshake_mode_name(ctx->mode),
(action->sender == ctx->mode) ? "send" : "recv",
ret);
return ret;
}
if (!tls13_handshake_advance_state_machine(ctx))
return TLS13_IO_FAILURE;
}
}
static int
tls13_handshake_send_action(struct tls13_ctx *ctx,
const struct tls13_handshake_action *action)
{
ssize_t ret;
CBB cbb;
if (ctx->send_dummy_ccs) {
if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS)
return ret;
ctx->send_dummy_ccs = 0;
if (ctx->send_dummy_ccs_after) {
ctx->send_dummy_ccs_after = 0;
return TLS13_IO_SUCCESS;
}
}
/* If we have no handshake message, we need to build one. */
if (ctx->hs_msg == NULL) {
if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)
return TLS13_IO_FAILURE;
if (!tls13_handshake_msg_start(ctx->hs_msg, &cbb,
action->handshake_type))
return TLS13_IO_FAILURE;
if (!action->send(ctx, &cbb))
return TLS13_IO_FAILURE;
if (!tls13_handshake_msg_finish(ctx->hs_msg))
return TLS13_IO_FAILURE;
}
if ((ret = tls13_handshake_msg_send(ctx->hs_msg, ctx->rl)) <= 0)
return ret;
if (!tls13_handshake_msg_record(ctx))
return TLS13_IO_FAILURE;
if (action->send_preserve_transcript_hash) {
if (!tls1_transcript_hash_value(ctx->ssl,
ctx->hs->transcript_hash, sizeof(ctx->hs->transcript_hash),
&ctx->hs->transcript_hash_len))
return TLS13_IO_FAILURE;
}
if (ctx->handshake_message_sent_cb != NULL)
ctx->handshake_message_sent_cb(ctx);
tls13_handshake_msg_free(ctx->hs_msg);
ctx->hs_msg = NULL;
if (action->sent != NULL && !action->sent(ctx))
return TLS13_IO_FAILURE;
if (ctx->send_dummy_ccs_after) {
ctx->send_dummy_ccs = 1;
if ((ret = tls13_send_dummy_ccs(ctx->rl)) != TLS13_IO_SUCCESS)
return ret;
ctx->send_dummy_ccs = 0;
ctx->send_dummy_ccs_after = 0;
}
return TLS13_IO_SUCCESS;
}
static int
tls13_handshake_recv_action(struct tls13_ctx *ctx,
const struct tls13_handshake_action *action)
{
uint8_t msg_type;
ssize_t ret;
CBS cbs;
if (ctx->hs_msg == NULL) {
if ((ctx->hs_msg = tls13_handshake_msg_new()) == NULL)
return TLS13_IO_FAILURE;
}
if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl)) <= 0)
return ret;
if (action->recv_preserve_transcript_hash) {
if (!tls1_transcript_hash_value(ctx->ssl,
ctx->hs->transcript_hash, sizeof(ctx->hs->transcript_hash),
&ctx->hs->transcript_hash_len))
return TLS13_IO_FAILURE;
}
if (!tls13_handshake_msg_record(ctx))
return TLS13_IO_FAILURE;
if (ctx->handshake_message_recv_cb != NULL)
ctx->handshake_message_recv_cb(ctx);
/*
* In TLSv1.3 there is no way to know if you're going to receive a
* certificate request message or not, hence we have to special case it
* here. The receive handler also knows how to deal with this situation.
*/
msg_type = tls13_handshake_msg_type(ctx->hs_msg);
if (msg_type != action->handshake_type &&
(msg_type != TLS13_MT_CERTIFICATE ||
action->handshake_type != TLS13_MT_CERTIFICATE_REQUEST))
return tls13_send_alert(ctx->rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
if (!tls13_handshake_msg_content(ctx->hs_msg, &cbs))
return TLS13_IO_FAILURE;
ret = TLS13_IO_FAILURE;
if (action->recv(ctx, &cbs)) {
if (CBS_len(&cbs) != 0) {
tls13_set_errorx(ctx, TLS13_ERR_TRAILING_DATA, 0,
"trailing data in handshake message", NULL);
ctx->alert = TLS13_ALERT_DECODE_ERROR;
} else {
ret = TLS13_IO_SUCCESS;
}
}
tls13_handshake_msg_free(ctx->hs_msg);
ctx->hs_msg = NULL;
if (ctx->ssl->method->internal->version < TLS1_3_VERSION)
return TLS13_IO_USE_LEGACY;
return ret;
}

54
externals/libressl/ssl/tls13_handshake.h vendored Executable file
View File

@@ -0,0 +1,54 @@
/* $OpenBSD: tls13_handshake.h,v 1.5 2020/04/22 17:05:07 jsing Exp $ */
/*
* Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_TLS13_HANDSHAKE_H
#define HEADER_TLS13_HANDSHAKE_H
#include <stddef.h> /* for NULL */
__BEGIN_HIDDEN_DECLS
#define INITIAL 0x00
#define NEGOTIATED 0x01
#define WITHOUT_HRR 0x02
#define WITHOUT_CR 0x04
#define WITH_PSK 0x08
#define WITH_CCV 0x10
#define WITH_0RTT 0x20
enum tls13_message_type {
INVALID,
CLIENT_HELLO,
SERVER_HELLO_RETRY_REQUEST,
CLIENT_HELLO_RETRY,
SERVER_HELLO,
SERVER_ENCRYPTED_EXTENSIONS,
SERVER_CERTIFICATE_REQUEST,
SERVER_CERTIFICATE,
SERVER_CERTIFICATE_VERIFY,
SERVER_FINISHED,
CLIENT_END_OF_EARLY_DATA,
CLIENT_CERTIFICATE,
CLIENT_CERTIFICATE_VERIFY,
CLIENT_FINISHED,
APPLICATION_DATA,
TLS13_NUM_MESSAGE_TYPES,
};
__END_HIDDEN_DECLS
#endif /* !HEADER_TLS13_HANDSHAKE_H */

194
externals/libressl/ssl/tls13_handshake_msg.c vendored Executable file
View File

@@ -0,0 +1,194 @@
/* $OpenBSD: tls13_handshake_msg.c,v 1.2 2019/11/20 16:21:20 beck Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "bytestring.h"
#include "ssl_locl.h"
#include "tls13_internal.h"
#define TLS13_HANDSHAKE_MSG_HEADER_LEN 4
#define TLS13_HANDSHAKE_MSG_INITIAL_LEN 256
#define TLS13_HANDSHAKE_MSG_MAX_LEN (256 * 1024)
struct tls13_handshake_msg {
uint8_t msg_type;
uint32_t msg_len;
uint8_t *data;
size_t data_len;
struct tls13_buffer *buf;
CBS cbs;
CBB cbb;
};
struct tls13_handshake_msg *
tls13_handshake_msg_new()
{
struct tls13_handshake_msg *msg = NULL;
if ((msg = calloc(1, sizeof(struct tls13_handshake_msg))) == NULL)
goto err;
if ((msg->buf = tls13_buffer_new(0)) == NULL)
goto err;
return msg;
err:
tls13_handshake_msg_free(msg);
return NULL;
}
void
tls13_handshake_msg_free(struct tls13_handshake_msg *msg)
{
if (msg == NULL)
return;
tls13_buffer_free(msg->buf);
CBB_cleanup(&msg->cbb);
freezero(msg->data, msg->data_len);
freezero(msg, sizeof(struct tls13_handshake_msg));
}
void
tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs)
{
CBS_init(cbs, msg->data, msg->data_len);
}
int
tls13_handshake_msg_set_buffer(struct tls13_handshake_msg *msg, CBS *cbs)
{
return tls13_buffer_set_data(msg->buf, cbs);
}
uint8_t
tls13_handshake_msg_type(struct tls13_handshake_msg *msg)
{
return msg->msg_type;
}
int
tls13_handshake_msg_content(struct tls13_handshake_msg *msg, CBS *cbs)
{
tls13_handshake_msg_data(msg, cbs);
return CBS_skip(cbs, TLS13_HANDSHAKE_MSG_HEADER_LEN);
}
int
tls13_handshake_msg_start(struct tls13_handshake_msg *msg, CBB *body,
uint8_t msg_type)
{
if (!CBB_init(&msg->cbb, TLS13_HANDSHAKE_MSG_INITIAL_LEN))
return 0;
if (!CBB_add_u8(&msg->cbb, msg_type))
return 0;
if (!CBB_add_u24_length_prefixed(&msg->cbb, body))
return 0;
return 1;
}
int
tls13_handshake_msg_finish(struct tls13_handshake_msg *msg)
{
if (!CBB_finish(&msg->cbb, &msg->data, &msg->data_len))
return 0;
CBS_init(&msg->cbs, msg->data, msg->data_len);
return 1;
}
static ssize_t
tls13_handshake_msg_read_cb(void *buf, size_t n, void *cb_arg)
{
struct tls13_record_layer *rl = cb_arg;
return tls13_read_handshake_data(rl, buf, n);
}
int
tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
struct tls13_record_layer *rl)
{
uint8_t msg_type;
uint32_t msg_len;
CBS cbs;
int ret;
if (msg->data != NULL)
return TLS13_IO_FAILURE;
if (msg->msg_type == 0) {
if ((ret = tls13_buffer_extend(msg->buf,
TLS13_HANDSHAKE_MSG_HEADER_LEN,
tls13_handshake_msg_read_cb, rl)) <= 0)
return ret;
tls13_buffer_cbs(msg->buf, &cbs);
if (!CBS_get_u8(&cbs, &msg_type))
return TLS13_IO_FAILURE;
if (!CBS_get_u24(&cbs, &msg_len))
return TLS13_IO_FAILURE;
/* XXX - do we want to make this variable on message type? */
if (msg_len > TLS13_HANDSHAKE_MSG_MAX_LEN)
return TLS13_IO_FAILURE;
msg->msg_type = msg_type;
msg->msg_len = msg_len;
}
if ((ret = tls13_buffer_extend(msg->buf,
TLS13_HANDSHAKE_MSG_HEADER_LEN + msg->msg_len,
tls13_handshake_msg_read_cb, rl)) <= 0)
return ret;
if (!tls13_buffer_finish(msg->buf, &msg->data, &msg->data_len))
return TLS13_IO_FAILURE;
return TLS13_IO_SUCCESS;
}
int
tls13_handshake_msg_send(struct tls13_handshake_msg *msg,
struct tls13_record_layer *rl)
{
ssize_t ret;
if (msg->data == NULL)
return TLS13_IO_FAILURE;
if (CBS_len(&msg->cbs) == 0)
return TLS13_IO_FAILURE;
while (CBS_len(&msg->cbs) > 0) {
if ((ret = tls13_write_handshake_data(rl, CBS_data(&msg->cbs),
CBS_len(&msg->cbs))) <= 0)
return ret;
if (!CBS_skip(&msg->cbs, ret))
return TLS13_IO_FAILURE;
}
return TLS13_IO_SUCCESS;
}

424
externals/libressl/ssl/tls13_internal.h vendored Executable file
View File

@@ -0,0 +1,424 @@
/* $OpenBSD: tls13_internal.h,v 1.86 2020/07/30 16:23:17 tb Exp $ */
/*
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_TLS13_INTERNAL_H
#define HEADER_TLS13_INTERNAL_H
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include "bytestring.h"
__BEGIN_HIDDEN_DECLS
#define TLS13_HS_CLIENT 1
#define TLS13_HS_SERVER 2
#define TLS13_IO_SUCCESS 1
#define TLS13_IO_EOF 0
#define TLS13_IO_FAILURE -1
#define TLS13_IO_ALERT -2
#define TLS13_IO_WANT_POLLIN -3
#define TLS13_IO_WANT_POLLOUT -4
#define TLS13_IO_WANT_RETRY -5 /* Retry the previous call immediately. */
#define TLS13_IO_USE_LEGACY -6
#define TLS13_IO_RECORD_VERSION -7
#define TLS13_IO_RECORD_OVERFLOW -8
#define TLS13_ERR_VERIFY_FAILED 16
#define TLS13_ERR_HRR_FAILED 17
#define TLS13_ERR_TRAILING_DATA 18
#define TLS13_ERR_NO_SHARED_CIPHER 19
#define TLS13_ERR_NO_CERTIFICATE 20
#define TLS13_ERR_NO_PEER_CERTIFICATE 21
#define TLS13_ALERT_LEVEL_WARNING 1
#define TLS13_ALERT_LEVEL_FATAL 2
#define TLS13_ALERT_CLOSE_NOTIFY 0
#define TLS13_ALERT_UNEXPECTED_MESSAGE 10
#define TLS13_ALERT_BAD_RECORD_MAC 20
#define TLS13_ALERT_RECORD_OVERFLOW 22
#define TLS13_ALERT_HANDSHAKE_FAILURE 40
#define TLS13_ALERT_BAD_CERTIFICATE 42
#define TLS13_ALERT_UNSUPPORTED_CERTIFICATE 43
#define TLS13_ALERT_CERTIFICATE_REVOKED 44
#define TLS13_ALERT_CERTIFICATE_EXPIRED 45
#define TLS13_ALERT_CERTIFICATE_UNKNOWN 46
#define TLS13_ALERT_ILLEGAL_PARAMETER 47
#define TLS13_ALERT_UNKNOWN_CA 48
#define TLS13_ALERT_ACCESS_DENIED 49
#define TLS13_ALERT_DECODE_ERROR 50
#define TLS13_ALERT_DECRYPT_ERROR 51
#define TLS13_ALERT_PROTOCOL_VERSION 70
#define TLS13_ALERT_INSUFFICIENT_SECURITY 71
#define TLS13_ALERT_INTERNAL_ERROR 80
#define TLS13_ALERT_INAPPROPRIATE_FALLBACK 86
#define TLS13_ALERT_USER_CANCELED 90
#define TLS13_ALERT_MISSING_EXTENSION 109
#define TLS13_ALERT_UNSUPPORTED_EXTENSION 110
#define TLS13_ALERT_UNRECOGNIZED_NAME 112
#define TLS13_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113
#define TLS13_ALERT_UNKNOWN_PSK_IDENTITY 115
#define TLS13_ALERT_CERTIFICATE_REQUIRED 116
#define TLS13_ALERT_NO_APPLICATION_PROTOCOL 120
#define TLS13_INFO_HANDSHAKE_STARTED SSL_CB_HANDSHAKE_START
#define TLS13_INFO_HANDSHAKE_COMPLETED SSL_CB_HANDSHAKE_DONE
typedef void (*tls13_alert_cb)(uint8_t _alert_desc, void *_cb_arg);
typedef ssize_t (*tls13_phh_recv_cb)(void *_cb_arg, CBS *_cbs);
typedef void (*tls13_phh_sent_cb)(void *_cb_arg);
typedef ssize_t (*tls13_read_cb)(void *_buf, size_t _buflen, void *_cb_arg);
typedef ssize_t (*tls13_write_cb)(const void *_buf, size_t _buflen,
void *_cb_arg);
typedef void (*tls13_handshake_message_cb)(void *_cb_arg);
typedef void (*tls13_info_cb)(void *_cb_arg, int _state, int _ret);
typedef int (*tls13_ocsp_status_cb)(void *_cb_arg);
/*
* Buffers.
*/
struct tls13_buffer;
struct tls13_buffer *tls13_buffer_new(size_t init_size);
int tls13_buffer_set_data(struct tls13_buffer *buf, CBS *data);
void tls13_buffer_free(struct tls13_buffer *buf);
ssize_t tls13_buffer_extend(struct tls13_buffer *buf, size_t len,
tls13_read_cb read_cb, void *cb_arg);
void tls13_buffer_cbs(struct tls13_buffer *buf, CBS *cbs);
int tls13_buffer_finish(struct tls13_buffer *buf, uint8_t **out,
size_t *out_len);
/*
* Secrets.
*/
struct tls13_secret {
uint8_t *data;
size_t len;
};
/* RFC 8446 Section 7.1 Page 92 */
struct tls13_secrets {
const EVP_MD *digest;
int resumption;
int init_done;
int early_done;
int handshake_done;
int schedule_done;
int insecure; /* Set by tests */
struct tls13_secret zeros;
struct tls13_secret empty_hash;
struct tls13_secret extracted_early;
struct tls13_secret binder_key;
struct tls13_secret client_early_traffic;
struct tls13_secret early_exporter_master;
struct tls13_secret derived_early;
struct tls13_secret extracted_handshake;
struct tls13_secret client_handshake_traffic;
struct tls13_secret server_handshake_traffic;
struct tls13_secret derived_handshake;
struct tls13_secret extracted_master;
struct tls13_secret client_application_traffic;
struct tls13_secret server_application_traffic;
struct tls13_secret exporter_master;
struct tls13_secret resumption_master;
};
struct tls13_secrets *tls13_secrets_create(const EVP_MD *digest,
int resumption);
void tls13_secrets_destroy(struct tls13_secrets *secrets);
int tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context);
int tls13_derive_early_secrets(struct tls13_secrets *secrets, uint8_t *psk,
size_t psk_len, const struct tls13_secret *context);
int tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
const uint8_t *ecdhe, size_t ecdhe_len, const struct tls13_secret *context);
int tls13_derive_application_secrets(struct tls13_secrets *secrets,
const struct tls13_secret *context);
int tls13_update_client_traffic_secret(struct tls13_secrets *secrets);
int tls13_update_server_traffic_secret(struct tls13_secrets *secrets);
/*
* Key shares.
*/
struct tls13_key_share;
struct tls13_key_share *tls13_key_share_new(uint16_t group_id);
struct tls13_key_share *tls13_key_share_new_nid(int nid);
void tls13_key_share_free(struct tls13_key_share *ks);
uint16_t tls13_key_share_group(struct tls13_key_share *ks);
int tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey);
int tls13_key_share_generate(struct tls13_key_share *ks);
int tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb);
int tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
CBS *cbs);
int tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
size_t *shared_key_len);
/*
* Record Layer.
*/
struct tls13_record_layer;
struct tls13_record_layer_callbacks {
tls13_read_cb wire_read;
tls13_write_cb wire_write;
tls13_alert_cb alert_recv;
tls13_alert_cb alert_sent;
tls13_phh_recv_cb phh_recv;
tls13_phh_sent_cb phh_sent;
};
struct tls13_record_layer *tls13_record_layer_new(
const struct tls13_record_layer_callbacks *callbacks, void *cb_arg);
void tls13_record_layer_free(struct tls13_record_layer *rl);
void tls13_record_layer_allow_ccs(struct tls13_record_layer *rl, int allow);
void tls13_record_layer_allow_legacy_alerts(struct tls13_record_layer *rl, int allow);
void tls13_record_layer_rbuf(struct tls13_record_layer *rl, CBS *cbs);
void tls13_record_layer_set_aead(struct tls13_record_layer *rl,
const EVP_AEAD *aead);
void tls13_record_layer_set_hash(struct tls13_record_layer *rl,
const EVP_MD *hash);
void tls13_record_layer_set_legacy_version(struct tls13_record_layer *rl,
uint16_t version);
void tls13_record_layer_set_retry_after_phh(struct tls13_record_layer *rl, int retry);
void tls13_record_layer_handshake_completed(struct tls13_record_layer *rl);
int tls13_record_layer_set_read_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *read_key);
int tls13_record_layer_set_write_traffic_key(struct tls13_record_layer *rl,
struct tls13_secret *write_key);
ssize_t tls13_record_layer_send_pending(struct tls13_record_layer *rl);
ssize_t tls13_record_layer_phh(struct tls13_record_layer *rl, CBS *cbs);
ssize_t tls13_read_handshake_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
ssize_t tls13_write_handshake_data(struct tls13_record_layer *rl, const uint8_t *buf,
size_t n);
ssize_t tls13_pending_application_data(struct tls13_record_layer *rl);
ssize_t tls13_peek_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
ssize_t tls13_read_application_data(struct tls13_record_layer *rl, uint8_t *buf, size_t n);
ssize_t tls13_write_application_data(struct tls13_record_layer *rl, const uint8_t *buf,
size_t n);
ssize_t tls13_send_alert(struct tls13_record_layer *rl, uint8_t alert_desc);
ssize_t tls13_send_dummy_ccs(struct tls13_record_layer *rl);
/*
* Handshake Messages.
*/
struct tls13_handshake_msg;
struct tls13_handshake_msg *tls13_handshake_msg_new(void);
void tls13_handshake_msg_free(struct tls13_handshake_msg *msg);
void tls13_handshake_msg_data(struct tls13_handshake_msg *msg, CBS *cbs);
int tls13_handshake_msg_set_buffer(struct tls13_handshake_msg *msg, CBS *cbs);
uint8_t tls13_handshake_msg_type(struct tls13_handshake_msg *msg);
int tls13_handshake_msg_content(struct tls13_handshake_msg *msg, CBS *cbs);
int tls13_handshake_msg_start(struct tls13_handshake_msg *msg, CBB *body,
uint8_t msg_type);
int tls13_handshake_msg_finish(struct tls13_handshake_msg *msg);
int tls13_handshake_msg_recv(struct tls13_handshake_msg *msg,
struct tls13_record_layer *rl);
int tls13_handshake_msg_send(struct tls13_handshake_msg *msg,
struct tls13_record_layer *rl);
struct tls13_handshake_stage {
uint8_t hs_type;
uint8_t message_number;
};
struct ssl_handshake_tls13_st;
struct tls13_error {
int code;
int subcode;
int errnum;
const char *file;
int line;
char *msg;
};
struct tls13_ctx {
struct tls13_error error;
SSL *ssl;
struct ssl_handshake_tls13_st *hs;
uint8_t mode;
struct tls13_handshake_stage handshake_stage;
int handshake_started;
int handshake_completed;
int middlebox_compat;
int send_dummy_ccs;
int send_dummy_ccs_after;
int close_notify_sent;
int close_notify_recv;
const EVP_AEAD *aead;
const EVP_MD *hash;
struct tls13_record_layer *rl;
struct tls13_handshake_msg *hs_msg;
uint8_t key_update_request;
uint8_t alert;
int phh_count;
time_t phh_last_seen;
tls13_handshake_message_cb handshake_message_sent_cb;
tls13_handshake_message_cb handshake_message_recv_cb;
tls13_info_cb info_cb;
tls13_ocsp_status_cb ocsp_status_recv_cb;
};
#ifndef TLS13_PHH_LIMIT_TIME
#define TLS13_PHH_LIMIT_TIME 3600
#endif
#ifndef TLS13_PHH_LIMIT
#define TLS13_PHH_LIMIT 100
#endif
struct tls13_ctx *tls13_ctx_new(int mode);
void tls13_ctx_free(struct tls13_ctx *ctx);
const EVP_AEAD *tls13_cipher_aead(const SSL_CIPHER *cipher);
const EVP_MD *tls13_cipher_hash(const SSL_CIPHER *cipher);
/*
* Legacy interfaces.
*/
int tls13_use_legacy_client(struct tls13_ctx *ctx);
int tls13_use_legacy_server(struct tls13_ctx *ctx);
int tls13_legacy_accept(SSL *ssl);
int tls13_legacy_connect(SSL *ssl);
int tls13_legacy_return_code(SSL *ssl, ssize_t ret);
ssize_t tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg);
ssize_t tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg);
int tls13_legacy_pending(const SSL *ssl);
int tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len,
int peek);
int tls13_legacy_write_bytes(SSL *ssl, int type, const void *buf, int len);
int tls13_legacy_shutdown(SSL *ssl);
int tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert);
/*
* Message Types - RFC 8446, Section B.3.
*
* Values listed as "_RESERVED" were used in previous versions of TLS and are
* listed here for completeness. TLS 1.3 implementations MUST NOT send them but
* might receive them from older TLS implementations.
*/
#define TLS13_MT_HELLO_REQUEST_RESERVED 0
#define TLS13_MT_CLIENT_HELLO 1
#define TLS13_MT_SERVER_HELLO 2
#define TLS13_MT_HELLO_VERIFY_REQUEST_RESERVED 3
#define TLS13_MT_NEW_SESSION_TICKET 4
#define TLS13_MT_END_OF_EARLY_DATA 5
#define TLS13_MT_HELLO_RETRY_REQUEST_RESERVED 6
#define TLS13_MT_ENCRYPTED_EXTENSIONS 8
#define TLS13_MT_CERTIFICATE 11
#define TLS13_MT_SERVER_KEY_EXCHANGE_RESERVED 12
#define TLS13_MT_CERTIFICATE_REQUEST 13
#define TLS13_MT_SERVER_HELLO_DONE_RESERVED 14
#define TLS13_MT_CERTIFICATE_VERIFY 15
#define TLS13_MT_CLIENT_KEY_EXCHANGE_RESERVED 16
#define TLS13_MT_FINISHED 20
#define TLS13_MT_CERTIFICATE_URL_RESERVED 21
#define TLS13_MT_CERTIFICATE_STATUS_RESERVED 22
#define TLS13_MT_SUPPLEMENTAL_DATA_RESERVED 23
#define TLS13_MT_KEY_UPDATE 24
#define TLS13_MT_MESSAGE_HASH 254
int tls13_handshake_msg_record(struct tls13_ctx *ctx);
int tls13_handshake_perform(struct tls13_ctx *ctx);
int tls13_client_init(struct tls13_ctx *ctx);
int tls13_server_init(struct tls13_ctx *ctx);
int tls13_client_connect(struct tls13_ctx *ctx);
int tls13_server_accept(struct tls13_ctx *ctx);
int tls13_client_hello_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_client_hello_sent(struct tls13_ctx *ctx);
int tls13_client_hello_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_client_hello_retry_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_client_hello_retry_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_client_end_of_early_data_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_client_end_of_early_data_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_client_certificate_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_client_certificate_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_client_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_client_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_client_finished_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_client_finished_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_client_finished_sent(struct tls13_ctx *ctx);
int tls13_server_hello_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_hello_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_hello_sent(struct tls13_ctx *ctx);
int tls13_server_hello_retry_request_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_hello_retry_request_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_hello_retry_request_sent(struct tls13_ctx *ctx);
int tls13_server_encrypted_extensions_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_encrypted_extensions_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_certificate_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_certificate_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_certificate_request_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_certificate_request_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_certificate_verify_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_certificate_verify_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_finished_recv(struct tls13_ctx *ctx, CBS *cbs);
int tls13_server_finished_send(struct tls13_ctx *ctx, CBB *cbb);
int tls13_server_finished_sent(struct tls13_ctx *ctx);
void tls13_error_clear(struct tls13_error *error);
int tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert,
int(*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb));
int tls13_synthetic_handshake_message(struct tls13_ctx *ctx);
int tls13_clienthello_hash_init(struct tls13_ctx *ctx);
void tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs);
int tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data,
size_t len);
int tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs);
int tls13_clienthello_hash_finalize(struct tls13_ctx *ctx);
int tls13_clienthello_hash_validate(struct tls13_ctx *ctx);
int tls13_error_set(struct tls13_error *error, int code, int subcode,
const char *file, int line, const char *fmt, ...);
int tls13_error_setx(struct tls13_error *error, int code, int subcode,
const char *file, int line, const char *fmt, ...);
#define tls13_set_error(ctx, code, subcode, fmt, ...) \
tls13_error_set(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \
(fmt), __VA_ARGS__)
#define tls13_set_errorx(ctx, code, subcode, fmt, ...) \
tls13_error_setx(&(ctx)->error, (code), (subcode), __FILE__, __LINE__, \
(fmt), __VA_ARGS__)
extern const uint8_t tls13_downgrade_12[8];
extern const uint8_t tls13_downgrade_11[8];
extern const uint8_t tls13_hello_retry_request_hash[32];
extern const uint8_t tls13_cert_verify_pad[64];
extern const uint8_t tls13_cert_client_verify_context[];
extern const uint8_t tls13_cert_server_verify_context[];
__END_HIDDEN_DECLS
#endif

380
externals/libressl/ssl/tls13_key_schedule.c vendored Executable file
View File

@@ -0,0 +1,380 @@
/* $OpenBSD: tls13_key_schedule.c,v 1.8 2019/11/17 21:01:08 beck Exp $ */
/* Copyright (c) 2018, Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <stdlib.h>
#include <openssl/hkdf.h>
#include "bytestring.h"
#include "tls13_internal.h"
void
tls13_secrets_destroy(struct tls13_secrets *secrets)
{
if (secrets == NULL)
return;
/* you can never be too sure :) */
freezero(secrets->zeros.data, secrets->zeros.len);
freezero(secrets->empty_hash.data, secrets->empty_hash.len);
freezero(secrets->extracted_early.data,
secrets->extracted_early.len);
freezero(secrets->binder_key.data,
secrets->binder_key.len);
freezero(secrets->client_early_traffic.data,
secrets->client_early_traffic.len);
freezero(secrets->early_exporter_master.data,
secrets->early_exporter_master.len);
freezero(secrets->derived_early.data,
secrets->derived_early.len);
freezero(secrets->extracted_handshake.data,
secrets->extracted_handshake.len);
freezero(secrets->client_handshake_traffic.data,
secrets->client_handshake_traffic.len);
freezero(secrets->server_handshake_traffic.data,
secrets->server_handshake_traffic.len);
freezero(secrets->derived_handshake.data,
secrets->derived_handshake.len);
freezero(secrets->extracted_master.data,
secrets->extracted_master.len);
freezero(secrets->client_application_traffic.data,
secrets->client_application_traffic.len);
freezero(secrets->server_application_traffic.data,
secrets->server_application_traffic.len);
freezero(secrets->exporter_master.data,
secrets->exporter_master.len);
freezero(secrets->resumption_master.data,
secrets->resumption_master.len);
freezero(secrets, sizeof(struct tls13_secrets));
}
/*
* Allocate a set of secrets for a key schedule using
* a size of hash_length from RFC 8446 section 7.1.
*/
struct tls13_secrets *
tls13_secrets_create(const EVP_MD *digest, int resumption)
{
struct tls13_secrets *secrets = NULL;
EVP_MD_CTX *mdctx = NULL;
unsigned int mdlen;
size_t hash_length;
hash_length = EVP_MD_size(digest);
if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL)
goto err;
if ((secrets->zeros.data = calloc(hash_length, sizeof(uint8_t))) ==
NULL)
goto err;
secrets->zeros.len = hash_length;
if ((secrets->empty_hash.data = malloc(hash_length)) == NULL)
goto err;
secrets->empty_hash.len = hash_length;
if ((secrets->extracted_early.data = malloc(hash_length)) == NULL)
goto err;
secrets->extracted_early.len = hash_length;
if ((secrets->binder_key.data = malloc(hash_length)) == NULL)
goto err;
secrets->binder_key.len = hash_length;
if ((secrets->client_early_traffic.data = malloc(hash_length)) == NULL)
goto err;
secrets->client_early_traffic.len = hash_length;
if ((secrets->early_exporter_master.data = malloc(hash_length)) ==
NULL)
goto err;
secrets->early_exporter_master.len = hash_length;
if ((secrets->derived_early.data = malloc(hash_length)) == NULL)
goto err;
secrets->derived_early.len = hash_length;
if ((secrets->extracted_handshake.data = malloc(hash_length)) == NULL)
goto err;
secrets->extracted_handshake.len = hash_length;
if ((secrets->client_handshake_traffic.data = malloc(hash_length))
== NULL)
goto err;
secrets->client_handshake_traffic.len = hash_length;
if ((secrets->server_handshake_traffic.data = malloc(hash_length))
== NULL)
goto err;
secrets->server_handshake_traffic.len = hash_length;
if ((secrets->derived_handshake.data = malloc(hash_length)) == NULL)
goto err;
secrets->derived_handshake.len = hash_length;
if ((secrets->extracted_master.data = malloc(hash_length)) == NULL)
goto err;
secrets->extracted_master.len = hash_length;
if ((secrets->client_application_traffic.data = malloc(hash_length)) ==
NULL)
goto err;
secrets->client_application_traffic.len = hash_length;
if ((secrets->server_application_traffic.data = malloc(hash_length)) ==
NULL)
goto err;
secrets->server_application_traffic.len = hash_length;
if ((secrets->exporter_master.data = malloc(hash_length)) == NULL)
goto err;
secrets->exporter_master.len = hash_length;
if ((secrets->resumption_master.data = malloc(hash_length)) == NULL)
goto err;
secrets->resumption_master.len = hash_length;
/*
* Calculate the hash of a zero-length string - this is needed during
* the "derived" step for key extraction.
*/
if ((mdctx = EVP_MD_CTX_new()) == NULL)
goto err;
if (!EVP_DigestInit_ex(mdctx, digest, NULL))
goto err;
if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0))
goto err;
if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen))
goto err;
EVP_MD_CTX_free(mdctx);
mdctx = NULL;
if (secrets->empty_hash.len != mdlen)
goto err;
secrets->digest = digest;
secrets->resumption = resumption;
secrets->init_done = 1;
return secrets;
err:
tls13_secrets_destroy(secrets);
EVP_MD_CTX_free(mdctx);
return NULL;
}
int
tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context)
{
const char tls13_plabel[] = "tls13 ";
uint8_t *hkdf_label;
size_t hkdf_label_len;
CBB cbb, child;
int ret;
if (!CBB_init(&cbb, 256))
return 0;
if (!CBB_add_u16(&cbb, out->len))
goto err;
if (!CBB_add_u8_length_prefixed(&cbb, &child))
goto err;
if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel)))
goto err;
if (!CBB_add_bytes(&child, label, strlen(label)))
goto err;
if (!CBB_add_u8_length_prefixed(&cbb, &child))
goto err;
if (!CBB_add_bytes(&child, context->data, context->len))
goto err;
if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len))
goto err;
ret = HKDF_expand(out->data, out->len, digest, secret->data,
secret->len, hkdf_label, hkdf_label_len);
free(hkdf_label);
return(ret);
err:
CBB_cleanup(&cbb);
return(0);
}
static int
tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest,
const struct tls13_secret *secret, const char *label,
const struct tls13_secret *context)
{
return tls13_hkdf_expand_label(out, digest, secret, label, context);
}
int
tls13_derive_early_secrets(struct tls13_secrets *secrets,
uint8_t *psk, size_t psk_len, const struct tls13_secret *context)
{
if (!secrets->init_done || secrets->early_done)
return 0;
if (!HKDF_extract(secrets->extracted_early.data,
&secrets->extracted_early.len, secrets->digest, psk, psk_len,
secrets->zeros.data, secrets->zeros.len))
return 0;
if (secrets->extracted_early.len != secrets->zeros.len)
return 0;
if (!tls13_derive_secret(&secrets->binder_key, secrets->digest,
&secrets->extracted_early,
secrets->resumption ? "res binder" : "ext binder",
&secrets->empty_hash))
return 0;
if (!tls13_derive_secret(&secrets->client_early_traffic,
secrets->digest, &secrets->extracted_early, "c e traffic",
context))
return 0;
if (!tls13_derive_secret(&secrets->early_exporter_master,
secrets->digest, &secrets->extracted_early, "e exp master",
context))
return 0;
if (!tls13_derive_secret(&secrets->derived_early,
secrets->digest, &secrets->extracted_early, "derived",
&secrets->empty_hash))
return 0;
/* RFC 8446 recommends */
if (!secrets->insecure)
explicit_bzero(secrets->extracted_early.data,
secrets->extracted_early.len);
secrets->early_done = 1;
return 1;
}
int
tls13_derive_handshake_secrets(struct tls13_secrets *secrets,
const uint8_t *ecdhe, size_t ecdhe_len,
const struct tls13_secret *context)
{
if (!secrets->init_done || !secrets->early_done ||
secrets->handshake_done)
return 0;
if (!HKDF_extract(secrets->extracted_handshake.data,
&secrets->extracted_handshake.len, secrets->digest,
ecdhe, ecdhe_len, secrets->derived_early.data,
secrets->derived_early.len))
return 0;
if (secrets->extracted_handshake.len != secrets->zeros.len)
return 0;
/* XXX */
if (!secrets->insecure)
explicit_bzero(secrets->derived_early.data,
secrets->derived_early.len);
if (!tls13_derive_secret(&secrets->client_handshake_traffic,
secrets->digest, &secrets->extracted_handshake, "c hs traffic",
context))
return 0;
if (!tls13_derive_secret(&secrets->server_handshake_traffic,
secrets->digest, &secrets->extracted_handshake, "s hs traffic",
context))
return 0;
if (!tls13_derive_secret(&secrets->derived_handshake,
secrets->digest, &secrets->extracted_handshake, "derived",
&secrets->empty_hash))
return 0;
/* RFC 8446 recommends */
if (!secrets->insecure)
explicit_bzero(secrets->extracted_handshake.data,
secrets->extracted_handshake.len);
secrets->handshake_done = 1;
return 1;
}
int
tls13_derive_application_secrets(struct tls13_secrets *secrets,
const struct tls13_secret *context)
{
if (!secrets->init_done || !secrets->early_done ||
!secrets->handshake_done || secrets->schedule_done)
return 0;
if (!HKDF_extract(secrets->extracted_master.data,
&secrets->extracted_master.len, secrets->digest,
secrets->zeros.data, secrets->zeros.len,
secrets->derived_handshake.data, secrets->derived_handshake.len))
return 0;
if (secrets->extracted_master.len != secrets->zeros.len)
return 0;
/* XXX */
if (!secrets->insecure)
explicit_bzero(secrets->derived_handshake.data,
secrets->derived_handshake.len);
if (!tls13_derive_secret(&secrets->client_application_traffic,
secrets->digest, &secrets->extracted_master, "c ap traffic",
context))
return 0;
if (!tls13_derive_secret(&secrets->server_application_traffic,
secrets->digest, &secrets->extracted_master, "s ap traffic",
context))
return 0;
if (!tls13_derive_secret(&secrets->exporter_master,
secrets->digest, &secrets->extracted_master, "exp master",
context))
return 0;
if (!tls13_derive_secret(&secrets->resumption_master,
secrets->digest, &secrets->extracted_master, "res master",
context))
return 0;
/* RFC 8446 recommends */
if (!secrets->insecure)
explicit_bzero(secrets->extracted_master.data,
secrets->extracted_master.len);
secrets->schedule_done = 1;
return 1;
}
int
tls13_update_client_traffic_secret(struct tls13_secrets *secrets)
{
struct tls13_secret context = { .data = "", .len = 0 };
if (!secrets->init_done || !secrets->early_done ||
!secrets->handshake_done || !secrets->schedule_done)
return 0;
return tls13_hkdf_expand_label(&secrets->client_application_traffic,
secrets->digest, &secrets->client_application_traffic,
"traffic upd", &context);
}
int
tls13_update_server_traffic_secret(struct tls13_secrets *secrets)
{
struct tls13_secret context = { .data = "", .len = 0 };
if (!secrets->init_done || !secrets->early_done ||
!secrets->handshake_done || !secrets->schedule_done)
return 0;
return tls13_hkdf_expand_label(&secrets->server_application_traffic,
secrets->digest, &secrets->server_application_traffic,
"traffic upd", &context);
}

324
externals/libressl/ssl/tls13_key_share.c vendored Executable file
View File

@@ -0,0 +1,324 @@
/* $OpenBSD: tls13_key_share.c,v 1.6 2020/04/18 14:07:56 jsing Exp $ */
/*
* Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <openssl/curve25519.h>
#include "bytestring.h"
#include "ssl_locl.h"
#include "tls13_internal.h"
struct tls13_key_share {
int nid;
uint16_t group_id;
EC_KEY *ecdhe;
EC_KEY *ecdhe_peer;
uint8_t *x25519_public;
uint8_t *x25519_private;
uint8_t *x25519_peer_public;
};
struct tls13_key_share *
tls13_key_share_new(uint16_t group_id)
{
struct tls13_key_share *ks;
int nid;
if ((nid = tls1_ec_curve_id2nid(group_id)) == 0)
return NULL;
if ((ks = calloc(1, sizeof(struct tls13_key_share))) == NULL)
return NULL;
ks->group_id = group_id;
ks->nid = nid;
return ks;
}
struct tls13_key_share *
tls13_key_share_new_nid(int nid)
{
uint16_t group_id;
if ((group_id = tls1_ec_nid2curve_id(nid)) == 0)
return NULL;
return tls13_key_share_new(group_id);
}
void
tls13_key_share_free(struct tls13_key_share *ks)
{
if (ks == NULL)
return;
EC_KEY_free(ks->ecdhe);
EC_KEY_free(ks->ecdhe_peer);
freezero(ks->x25519_public, X25519_KEY_LENGTH);
freezero(ks->x25519_private, X25519_KEY_LENGTH);
freezero(ks->x25519_peer_public, X25519_KEY_LENGTH);
freezero(ks, sizeof(*ks));
}
uint16_t
tls13_key_share_group(struct tls13_key_share *ks)
{
return ks->group_id;
}
int
tls13_key_share_peer_pkey(struct tls13_key_share *ks, EVP_PKEY *pkey)
{
if (ks->nid == NID_X25519 && ks->x25519_peer_public != NULL) {
if (!ssl_kex_dummy_ecdhe_x25519(pkey))
return 0;
} else if (ks->ecdhe_peer != NULL) {
if (!EVP_PKEY_set1_EC_KEY(pkey, ks->ecdhe_peer))
return 0;
} else {
return 0;
}
return 1;
}
static int
tls13_key_share_generate_ecdhe_ecp(struct tls13_key_share *ks)
{
EC_KEY *ecdhe = NULL;
int ret = 0;
if (ks->ecdhe != NULL)
goto err;
if ((ecdhe = EC_KEY_new()) == NULL)
goto err;
if (!ssl_kex_generate_ecdhe_ecp(ecdhe, ks->nid))
goto err;
ks->ecdhe = ecdhe;
ecdhe = NULL;
ret = 1;
err:
EC_KEY_free(ecdhe);
return ret;
}
static int
tls13_key_share_generate_x25519(struct tls13_key_share *ks)
{
uint8_t *public = NULL, *private = NULL;
int ret = 0;
if (ks->x25519_public != NULL || ks->x25519_private != NULL)
goto err;
if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL)
goto err;
if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL)
goto err;
X25519_keypair(public, private);
ks->x25519_public = public;
ks->x25519_private = private;
public = NULL;
private = NULL;
ret = 1;
err:
freezero(public, X25519_KEY_LENGTH);
freezero(private, X25519_KEY_LENGTH);
return ret;
}
int
tls13_key_share_generate(struct tls13_key_share *ks)
{
if (ks->nid == NID_X25519)
return tls13_key_share_generate_x25519(ks);
return tls13_key_share_generate_ecdhe_ecp(ks);
}
static int
tls13_key_share_public_ecdhe_ecp(struct tls13_key_share *ks, CBB *cbb)
{
if (ks->ecdhe == NULL)
return 0;
return ssl_kex_public_ecdhe_ecp(ks->ecdhe, cbb);
}
static int
tls13_key_share_public_x25519(struct tls13_key_share *ks, CBB *cbb)
{
if (ks->x25519_public == NULL)
return 0;
return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH);
}
int
tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb)
{
CBB key_exchange;
if (!CBB_add_u16(cbb, ks->group_id))
goto err;
if (!CBB_add_u16_length_prefixed(cbb, &key_exchange))
goto err;
if (ks->nid == NID_X25519) {
if (!tls13_key_share_public_x25519(ks, &key_exchange))
goto err;
} else {
if (!tls13_key_share_public_ecdhe_ecp(ks, &key_exchange))
goto err;
}
if (!CBB_flush(cbb))
goto err;
return 1;
err:
return 0;
}
static int
tls13_key_share_peer_public_ecdhe_ecp(struct tls13_key_share *ks, CBS *cbs)
{
EC_KEY *ecdhe = NULL;
int ret = 0;
if (ks->ecdhe_peer != NULL)
goto err;
if ((ecdhe = EC_KEY_new()) == NULL)
goto err;
if (!ssl_kex_peer_public_ecdhe_ecp(ecdhe, ks->nid, cbs))
goto err;
ks->ecdhe_peer = ecdhe;
ecdhe = NULL;
ret = 1;
err:
EC_KEY_free(ecdhe);
return ret;
}
static int
tls13_key_share_peer_public_x25519(struct tls13_key_share *ks, CBS *cbs)
{
size_t out_len;
if (ks->x25519_peer_public != NULL)
return 0;
if (CBS_len(cbs) != X25519_KEY_LENGTH)
return 0;
return CBS_stow(cbs, &ks->x25519_peer_public, &out_len);
}
int
tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
CBS *cbs)
{
if (ks->group_id != group)
return 0;
if (ks->nid == NID_X25519) {
if (!tls13_key_share_peer_public_x25519(ks, cbs))
return 0;
} else {
if (!tls13_key_share_peer_public_ecdhe_ecp(ks, cbs))
return 0;
}
return 1;
}
static int
tls13_key_share_derive_ecdhe_ecp(struct tls13_key_share *ks,
uint8_t **shared_key, size_t *shared_key_len)
{
if (ks->ecdhe == NULL || ks->ecdhe_peer == NULL)
return 0;
return ssl_kex_derive_ecdhe_ecp(ks->ecdhe, ks->ecdhe_peer,
shared_key, shared_key_len);
}
static int
tls13_key_share_derive_x25519(struct tls13_key_share *ks,
uint8_t **shared_key, size_t *shared_key_len)
{
uint8_t *sk = NULL;
int ret = 0;
if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL)
goto err;
if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL)
goto err;
if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public))
goto err;
*shared_key = sk;
*shared_key_len = X25519_KEY_LENGTH;
sk = NULL;
ret = 1;
err:
freezero(sk, X25519_KEY_LENGTH);
return ret;
}
int
tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
size_t *shared_key_len)
{
if (*shared_key != NULL)
return 0;
*shared_key_len = 0;
if (ks->nid == NID_X25519)
return tls13_key_share_derive_x25519(ks, shared_key,
shared_key_len);
return tls13_key_share_derive_ecdhe_ecp(ks, shared_key,
shared_key_len);
}

525
externals/libressl/ssl/tls13_legacy.c vendored Executable file
View File

@@ -0,0 +1,525 @@
/* $OpenBSD: tls13_legacy.c,v 1.13 2020/09/13 15:04:35 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <limits.h>
#include "ssl_locl.h"
#include "tls13_internal.h"
SSL3_ENC_METHOD TLSv1_3_enc_data = {
.enc_flags = SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_TLS1_3_CIPHERS,
};
static ssize_t
tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
{
int n;
if (ssl->rbio == NULL) {
SSLerror(ssl, SSL_R_BIO_NOT_SET);
return TLS13_IO_FAILURE;
}
ssl->internal->rwstate = SSL_READING;
errno = 0;
if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) {
if (BIO_should_read(ssl->rbio))
return TLS13_IO_WANT_POLLIN;
if (BIO_should_write(ssl->rbio))
return TLS13_IO_WANT_POLLOUT;
if (n == 0)
return TLS13_IO_EOF;
if (ERR_peek_error() == 0 && errno != 0)
SYSerror(errno);
return TLS13_IO_FAILURE;
}
if (n == len)
ssl->internal->rwstate = SSL_NOTHING;
return n;
}
ssize_t
tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg)
{
struct tls13_ctx *ctx = arg;
return tls13_legacy_wire_read(ctx->ssl, buf, n);
}
static ssize_t
tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len)
{
int n;
if (ssl->wbio == NULL) {
SSLerror(ssl, SSL_R_BIO_NOT_SET);
return TLS13_IO_FAILURE;
}
ssl->internal->rwstate = SSL_WRITING;
errno = 0;
if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
if (BIO_should_read(ssl->wbio))
return TLS13_IO_WANT_POLLIN;
if (BIO_should_write(ssl->wbio))
return TLS13_IO_WANT_POLLOUT;
if (ERR_peek_error() == 0 && errno != 0)
SYSerror(errno);
return TLS13_IO_FAILURE;
}
if (n == len)
ssl->internal->rwstate = SSL_NOTHING;
return n;
}
ssize_t
tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
{
struct tls13_ctx *ctx = arg;
return tls13_legacy_wire_write(ctx->ssl, buf, n);
}
static void
tls13_legacy_error(SSL *ssl)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
int reason = SSL_R_UNKNOWN;
/* If we received a fatal alert we already put an error on the stack. */
if (S3I(ssl)->fatal_alert != 0)
return;
switch (ctx->error.code) {
case TLS13_ERR_VERIFY_FAILED:
reason = SSL_R_CERTIFICATE_VERIFY_FAILED;
break;
case TLS13_ERR_HRR_FAILED:
reason = SSL_R_NO_CIPHERS_AVAILABLE;
break;
case TLS13_ERR_TRAILING_DATA:
reason = SSL_R_EXTRA_DATA_IN_MESSAGE;
break;
case TLS13_ERR_NO_SHARED_CIPHER:
reason = SSL_R_NO_SHARED_CIPHER;
break;
case TLS13_ERR_NO_CERTIFICATE:
reason = SSL_R_MISSING_RSA_CERTIFICATE; /* XXX */
break;
case TLS13_ERR_NO_PEER_CERTIFICATE:
reason = SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE;
break;
}
/* Something (probably libcrypto) already pushed an error on the stack. */
if (reason == SSL_R_UNKNOWN && ERR_peek_error() != 0)
return;
ERR_put_error(ERR_LIB_SSL, (0xfff), reason, ctx->error.file,
ctx->error.line);
}
int
tls13_legacy_return_code(SSL *ssl, ssize_t ret)
{
if (ret > INT_MAX) {
SSLerror(ssl, ERR_R_INTERNAL_ERROR);
return -1;
}
/* A successful read, write or other operation. */
if (ret > 0)
return ret;
ssl->internal->rwstate = SSL_NOTHING;
switch (ret) {
case TLS13_IO_EOF:
return 0;
case TLS13_IO_FAILURE:
tls13_legacy_error(ssl);
return -1;
case TLS13_IO_ALERT:
tls13_legacy_error(ssl);
return -1;
case TLS13_IO_WANT_POLLIN:
BIO_set_retry_read(ssl->rbio);
ssl->internal->rwstate = SSL_READING;
return -1;
case TLS13_IO_WANT_POLLOUT:
BIO_set_retry_write(ssl->wbio);
ssl->internal->rwstate = SSL_WRITING;
return -1;
case TLS13_IO_WANT_RETRY:
SSLerror(ssl, ERR_R_INTERNAL_ERROR);
return -1;
}
SSLerror(ssl, ERR_R_INTERNAL_ERROR);
return -1;
}
int
tls13_legacy_pending(const SSL *ssl)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
ssize_t ret;
if (ctx == NULL)
return 0;
ret = tls13_pending_application_data(ctx->rl);
if (ret < 0 || ret > INT_MAX)
return 0;
return ret;
}
int
tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
ssize_t ret;
if (ctx == NULL || !ctx->handshake_completed) {
if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
return ret;
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN);
}
tls13_record_layer_set_retry_after_phh(ctx->rl,
(ctx->ssl->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
if (type != SSL3_RT_APPLICATION_DATA) {
SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
if (len < 0) {
SSLerror(ssl, SSL_R_BAD_LENGTH);
return -1;
}
if (peek)
ret = tls13_peek_application_data(ctx->rl, buf, len);
else
ret = tls13_read_application_data(ctx->rl, buf, len);
return tls13_legacy_return_code(ssl, ret);
}
int
tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
const uint8_t *buf = vbuf;
size_t n, sent;
ssize_t ret;
if (ctx == NULL || !ctx->handshake_completed) {
if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
return ret;
return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLOUT);
}
if (type != SSL3_RT_APPLICATION_DATA) {
SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
if (len < 0) {
SSLerror(ssl, SSL_R_BAD_LENGTH);
return -1;
}
/*
* The TLSv1.3 record layer write behaviour is the same as
* SSL_MODE_ENABLE_PARTIAL_WRITE.
*/
if (ssl->internal->mode & SSL_MODE_ENABLE_PARTIAL_WRITE) {
ret = tls13_write_application_data(ctx->rl, buf, len);
return tls13_legacy_return_code(ssl, ret);
}
/*
* In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until
* we have written out all of the requested data.
*/
sent = S3I(ssl)->wnum;
if (len < sent) {
SSLerror(ssl, SSL_R_BAD_LENGTH);
return -1;
}
n = len - sent;
for (;;) {
if (n == 0) {
S3I(ssl)->wnum = 0;
return sent;
}
if ((ret = tls13_write_application_data(ctx->rl,
&buf[sent], n)) <= 0) {
S3I(ssl)->wnum = sent;
return tls13_legacy_return_code(ssl, ret);
}
sent += ret;
n -= ret;
}
}
static int
tls13_use_legacy_stack(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
CBS cbs;
if (!ssl3_setup_init_buffer(s))
return 0;
if (!ssl3_setup_buffers(s))
return 0;
if (!ssl_init_wbio_buffer(s, 1))
return 0;
/* Stash any unprocessed data from the last record. */
tls13_record_layer_rbuf(ctx->rl, &cbs);
if (CBS_len(&cbs) > 0) {
if (!CBS_write_bytes(&cbs,
S3I(s)->rbuf.buf + SSL3_RT_HEADER_LENGTH,
S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH, NULL))
return 0;
S3I(s)->rbuf.offset = SSL3_RT_HEADER_LENGTH;
S3I(s)->rbuf.left = CBS_len(&cbs);
S3I(s)->rrec.type = SSL3_RT_HANDSHAKE;
S3I(s)->rrec.length = CBS_len(&cbs);
s->internal->rstate = SSL_ST_READ_BODY;
s->internal->packet = S3I(s)->rbuf.buf;
s->internal->packet_length = SSL3_RT_HEADER_LENGTH;
s->internal->mac_packet = 1;
}
/* Stash the current handshake message. */
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
if (!CBS_write_bytes(&cbs, s->internal->init_buf->data,
s->internal->init_buf->length, NULL))
return 0;
S3I(s)->tmp.reuse_message = 1;
S3I(s)->tmp.message_type = tls13_handshake_msg_type(ctx->hs_msg);
S3I(s)->tmp.message_size = CBS_len(&cbs);
return 1;
}
int
tls13_use_legacy_client(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
s->method = tls_legacy_client_method();
s->internal->handshake_func = s->method->internal->ssl_connect;
s->client_version = s->version = s->method->internal->max_version;
if (!tls13_use_legacy_stack(ctx))
return 0;
S3I(s)->hs.state = SSL3_ST_CR_SRVR_HELLO_A;
return 1;
}
int
tls13_use_legacy_server(struct tls13_ctx *ctx)
{
SSL *s = ctx->ssl;
s->method = tls_legacy_server_method();
s->internal->handshake_func = s->method->internal->ssl_accept;
s->client_version = s->version = s->method->internal->max_version;
s->server = 1;
if (!tls13_use_legacy_stack(ctx))
return 0;
S3I(s)->hs.state = SSL3_ST_SR_CLNT_HELLO_A;
return 1;
}
int
tls13_legacy_accept(SSL *ssl)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
int ret;
if (ctx == NULL) {
if ((ctx = tls13_ctx_new(TLS13_HS_SERVER)) == NULL) {
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
return -1;
}
ssl->internal->tls13 = ctx;
ctx->ssl = ssl;
ctx->hs = &S3I(ssl)->hs_tls13;
if (!tls13_server_init(ctx)) {
if (ERR_peek_error() == 0)
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
return -1;
}
}
ERR_clear_error();
S3I(ssl)->hs.state = SSL_ST_ACCEPT;
ret = tls13_server_accept(ctx);
if (ret == TLS13_IO_USE_LEGACY)
return ssl->method->internal->ssl_accept(ssl);
if (ret == TLS13_IO_SUCCESS)
S3I(ssl)->hs.state = SSL_ST_OK;
return tls13_legacy_return_code(ssl, ret);
}
int
tls13_legacy_connect(SSL *ssl)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
int ret;
#ifdef TLS13_USE_LEGACY_CLIENT_AUTH
/* XXX drop back to legacy for client auth for now */
if (ssl->cert->key->privatekey != NULL) {
ssl->method = tls_legacy_client_method();
return ssl->method->internal->ssl_connect(ssl);
}
#endif
if (ctx == NULL) {
if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) {
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
return -1;
}
ssl->internal->tls13 = ctx;
ctx->ssl = ssl;
ctx->hs = &S3I(ssl)->hs_tls13;
if (!tls13_client_init(ctx)) {
if (ERR_peek_error() == 0)
SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
return -1;
}
}
ERR_clear_error();
S3I(ssl)->hs.state = SSL_ST_CONNECT;
ret = tls13_client_connect(ctx);
if (ret == TLS13_IO_USE_LEGACY)
return ssl->method->internal->ssl_connect(ssl);
if (ret == TLS13_IO_SUCCESS)
S3I(ssl)->hs.state = SSL_ST_OK;
return tls13_legacy_return_code(ssl, ret);
}
int
tls13_legacy_shutdown(SSL *ssl)
{
struct tls13_ctx *ctx = ssl->internal->tls13;
uint8_t buf[512]; /* XXX */
ssize_t ret;
/*
* We need to return 0 when we have sent a close-notify but have not
* yet received one. We return 1 only once we have sent and received
* close-notify alerts. All other cases return -1 and set internal
* state appropriately.
*/
if (ctx == NULL || ssl->internal->quiet_shutdown) {
ssl->internal->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
return 1;
}
if (!ctx->close_notify_sent) {
/* Enqueue and send close notify. */
if (!(ssl->internal->shutdown & SSL_SENT_SHUTDOWN)) {
ssl->internal->shutdown |= SSL_SENT_SHUTDOWN;
if ((ret = tls13_send_alert(ctx->rl,
TLS13_ALERT_CLOSE_NOTIFY)) < 0)
return tls13_legacy_return_code(ssl, ret);
}
if ((ret = tls13_record_layer_send_pending(ctx->rl)) !=
TLS13_IO_SUCCESS)
return tls13_legacy_return_code(ssl, ret);
} else if (!ctx->close_notify_recv) {
/*
* If there is no application data pending, attempt to read more
* data in order to receive a close notify. This should trigger
* a record to be read from the wire, which may be application
* handshake or alert data. Only one attempt is made to match
* previous semantics.
*/
if (tls13_pending_application_data(ctx->rl) == 0) {
if ((ret = tls13_read_application_data(ctx->rl, buf,
sizeof(buf))) < 0)
return tls13_legacy_return_code(ssl, ret);
}
}
if (ctx->close_notify_recv)
return 1;
return 0;
}
int
tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert)
{
int legacy_alert = SSL_AD_UNRECOGNIZED_NAME;
int ret = SSL_TLSEXT_ERR_NOACK;
SSL_CTX *ssl_ctx = ctx->ssl->ctx;
SSL *ssl = ctx->ssl;
if (ssl_ctx->internal->tlsext_servername_callback == NULL)
ssl_ctx = ssl->initial_ctx;
if (ssl_ctx->internal->tlsext_servername_callback == NULL)
return 1;
ret = ssl_ctx->internal->tlsext_servername_callback(ssl, &legacy_alert,
ssl_ctx->internal->tlsext_servername_arg);
if (ret == SSL_TLSEXT_ERR_ALERT_FATAL ||
ret == SSL_TLSEXT_ERR_ALERT_WARNING) {
if (legacy_alert >= 0 && legacy_alert <= 255)
*alert = legacy_alert;
return 0;
}
return 1;
}

581
externals/libressl/ssl/tls13_lib.c vendored Executable file
View File

@@ -0,0 +1,581 @@
/* $OpenBSD: tls13_lib.c,v 1.54 2020/09/11 15:03:36 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2019 Bob Beck <beck@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stddef.h>
#include <openssl/evp.h>
#include "ssl_locl.h"
#include "ssl_tlsext.h"
#include "tls13_internal.h"
/*
* Downgrade sentinels - RFC 8446 section 4.1.3, magic values which must be set
* by the server in server random if it is willing to downgrade but supports
* TLSv1.3
*/
const uint8_t tls13_downgrade_12[8] = {
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01,
};
const uint8_t tls13_downgrade_11[8] = {
0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00,
};
/*
* HelloRetryRequest hash - RFC 8446 section 4.1.3.
*/
const uint8_t tls13_hello_retry_request_hash[32] = {
0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11,
0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91,
0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e,
0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
};
/*
* Certificate Verify padding - RFC 8446 section 4.4.3.
*/
const uint8_t tls13_cert_verify_pad[64] = {
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
};
const uint8_t tls13_cert_client_verify_context[] =
"TLS 1.3, client CertificateVerify";
const uint8_t tls13_cert_server_verify_context[] =
"TLS 1.3, server CertificateVerify";
const EVP_AEAD *
tls13_cipher_aead(const SSL_CIPHER *cipher)
{
if (cipher == NULL)
return NULL;
if (cipher->algorithm_ssl != SSL_TLSV1_3)
return NULL;
switch (cipher->algorithm_enc) {
case SSL_AES128GCM:
return EVP_aead_aes_128_gcm();
case SSL_AES256GCM:
return EVP_aead_aes_256_gcm();
case SSL_CHACHA20POLY1305:
return EVP_aead_chacha20_poly1305();
}
return NULL;
}
const EVP_MD *
tls13_cipher_hash(const SSL_CIPHER *cipher)
{
if (cipher == NULL)
return NULL;
if (cipher->algorithm_ssl != SSL_TLSV1_3)
return NULL;
switch (cipher->algorithm2) {
case SSL_HANDSHAKE_MAC_SHA256:
return EVP_sha256();
case SSL_HANDSHAKE_MAC_SHA384:
return EVP_sha384();
}
return NULL;
}
static void
tls13_alert_received_cb(uint8_t alert_desc, void *arg)
{
struct tls13_ctx *ctx = arg;
if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
ctx->close_notify_recv = 1;
ctx->ssl->internal->shutdown |= SSL_RECEIVED_SHUTDOWN;
S3I(ctx->ssl)->warn_alert = alert_desc;
return;
}
if (alert_desc == TLS13_ALERT_USER_CANCELED) {
/*
* We treat this as advisory, since a close_notify alert
* SHOULD follow this alert (RFC 8446 section 6.1).
*/
return;
}
/* All other alerts are treated as fatal in TLSv1.3. */
S3I(ctx->ssl)->fatal_alert = alert_desc;
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
ERR_asprintf_error_data("SSL alert number %d", alert_desc);
SSL_CTX_remove_session(ctx->ssl->ctx, ctx->ssl->session);
}
static void
tls13_alert_sent_cb(uint8_t alert_desc, void *arg)
{
struct tls13_ctx *ctx = arg;
if (alert_desc == TLS13_ALERT_CLOSE_NOTIFY) {
ctx->close_notify_sent = 1;
return;
}
if (alert_desc == TLS13_ALERT_USER_CANCELED) {
return;
}
/* All other alerts are treated as fatal in TLSv1.3. */
SSLerror(ctx->ssl, SSL_AD_REASON_OFFSET + alert_desc);
}
static void
tls13_legacy_handshake_message_recv_cb(void *arg)
{
struct tls13_ctx *ctx = arg;
SSL *s = ctx->ssl;
CBS cbs;
if (s->internal->msg_callback == NULL)
return;
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
s->internal->msg_callback(0, TLS1_3_VERSION, SSL3_RT_HANDSHAKE,
CBS_data(&cbs), CBS_len(&cbs), s, s->internal->msg_callback_arg);
}
static void
tls13_legacy_handshake_message_sent_cb(void *arg)
{
struct tls13_ctx *ctx = arg;
SSL *s = ctx->ssl;
CBS cbs;
if (s->internal->msg_callback == NULL)
return;
tls13_handshake_msg_data(ctx->hs_msg, &cbs);
s->internal->msg_callback(1, TLS1_3_VERSION, SSL3_RT_HANDSHAKE,
CBS_data(&cbs), CBS_len(&cbs), s, s->internal->msg_callback_arg);
}
static void
tls13_legacy_info_cb(void *arg, int state, int ret)
{
struct tls13_ctx *ctx = arg;
SSL *s = ctx->ssl;
void (*cb)(const SSL *, int, int);
if ((cb = s->internal->info_callback) == NULL)
cb = s->ctx->internal->info_callback;
if (cb != NULL)
cb(s, state, ret);
}
static int
tls13_legacy_ocsp_status_recv_cb(void *arg)
{
struct tls13_ctx *ctx = arg;
SSL *s = ctx->ssl;
int ret;
if (s->ctx->internal->tlsext_status_cb == NULL ||
s->internal->tlsext_ocsp_resp == NULL)
return 1;
ret = s->ctx->internal->tlsext_status_cb(s,
s->ctx->internal->tlsext_status_arg);
if (ret < 0) {
ctx->alert = TLS13_ALERT_INTERNAL_ERROR;
SSLerror(s, ERR_R_MALLOC_FAILURE);
return 0;
}
if (ret == 0) {
ctx->alert = TLS13_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE;
SSLerror(s, SSL_R_INVALID_STATUS_RESPONSE);
return 0;
}
return 1;
}
static int
tls13_phh_update_local_traffic_secret(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
if (ctx->mode == TLS13_HS_CLIENT)
return (tls13_update_client_traffic_secret(secrets) &&
tls13_record_layer_set_write_traffic_key(ctx->rl,
&secrets->client_application_traffic));
return (tls13_update_server_traffic_secret(secrets) &&
tls13_record_layer_set_read_traffic_key(ctx->rl,
&secrets->server_application_traffic));
}
static int
tls13_phh_update_peer_traffic_secret(struct tls13_ctx *ctx)
{
struct tls13_secrets *secrets = ctx->hs->secrets;
if (ctx->mode == TLS13_HS_CLIENT)
return (tls13_update_server_traffic_secret(secrets) &&
tls13_record_layer_set_read_traffic_key(ctx->rl,
&secrets->server_application_traffic));
return (tls13_update_client_traffic_secret(secrets) &&
tls13_record_layer_set_write_traffic_key(ctx->rl,
&secrets->client_application_traffic));
}
/*
* XXX arbitrarily chosen limit of 100 post handshake handshake
* messages in an hour - to avoid a hostile peer from constantly
* requesting certificates or key renegotiaitons, etc.
*/
static int
tls13_phh_limit_check(struct tls13_ctx *ctx)
{
time_t now = time(NULL);
if (ctx->phh_last_seen > now - TLS13_PHH_LIMIT_TIME) {
if (ctx->phh_count > TLS13_PHH_LIMIT)
return 0;
} else
ctx->phh_count = 0;
ctx->phh_count++;
ctx->phh_last_seen = now;
return 1;
}
static ssize_t
tls13_key_update_recv(struct tls13_ctx *ctx, CBS *cbs)
{
struct tls13_handshake_msg *hs_msg = NULL;
CBB cbb_hs;
CBS cbs_hs;
uint8_t alert = TLS13_ALERT_INTERNAL_ERROR;
uint8_t key_update_request;
ssize_t ret;
if (!CBS_get_u8(cbs, &key_update_request)) {
alert = TLS13_ALERT_DECODE_ERROR;
goto err;
}
if (CBS_len(cbs) != 0) {
alert = TLS13_ALERT_DECODE_ERROR;
goto err;
}
if (key_update_request > 1) {
alert = TLS13_ALERT_ILLEGAL_PARAMETER;
goto err;
}
if (!tls13_phh_update_peer_traffic_secret(ctx))
goto err;
if (key_update_request == 0)
return TLS13_IO_SUCCESS;
/* key_update_request == 1 */
if ((hs_msg = tls13_handshake_msg_new()) == NULL)
goto err;
if (!tls13_handshake_msg_start(hs_msg, &cbb_hs, TLS13_MT_KEY_UPDATE))
goto err;
if (!CBB_add_u8(&cbb_hs, 0))
goto err;
if (!tls13_handshake_msg_finish(hs_msg))
goto err;
ctx->key_update_request = 1;
tls13_handshake_msg_data(hs_msg, &cbs_hs);
ret = tls13_record_layer_phh(ctx->rl, &cbs_hs);
tls13_handshake_msg_free(hs_msg);
hs_msg = NULL;
return ret;
err:
tls13_handshake_msg_free(hs_msg);
return tls13_send_alert(ctx->rl, alert);
}
static void
tls13_phh_done_cb(void *cb_arg)
{
struct tls13_ctx *ctx = cb_arg;
if (ctx->key_update_request) {
tls13_phh_update_local_traffic_secret(ctx);
ctx->key_update_request = 0;
}
}
static ssize_t
tls13_phh_received_cb(void *cb_arg, CBS *cbs)
{
ssize_t ret = TLS13_IO_FAILURE;
struct tls13_ctx *ctx = cb_arg;
CBS phh_cbs;
if (!tls13_phh_limit_check(ctx))
return tls13_send_alert(ctx->rl, TLS13_ALERT_UNEXPECTED_MESSAGE);
if ((ctx->hs_msg == NULL) &&
((ctx->hs_msg = tls13_handshake_msg_new()) == NULL))
return TLS13_IO_FAILURE;
if (!tls13_handshake_msg_set_buffer(ctx->hs_msg, cbs))
return TLS13_IO_FAILURE;
if ((ret = tls13_handshake_msg_recv(ctx->hs_msg, ctx->rl))
!= TLS13_IO_SUCCESS)
return ret;
if (!tls13_handshake_msg_content(ctx->hs_msg, &phh_cbs))
return TLS13_IO_FAILURE;
switch(tls13_handshake_msg_type(ctx->hs_msg)) {
case TLS13_MT_KEY_UPDATE:
ret = tls13_key_update_recv(ctx, &phh_cbs);
break;
case TLS13_MT_NEW_SESSION_TICKET:
/* XXX do nothing for now and ignore this */
break;
case TLS13_MT_CERTIFICATE_REQUEST:
/* XXX add support if we choose to advertise this */
/* FALLTHROUGH */
default:
ret = TLS13_IO_FAILURE; /* XXX send alert */
break;
}
tls13_handshake_msg_free(ctx->hs_msg);
ctx->hs_msg = NULL;
return ret;
}
static const struct tls13_record_layer_callbacks rl_callbacks = {
.wire_read = tls13_legacy_wire_read_cb,
.wire_write = tls13_legacy_wire_write_cb,
.alert_recv = tls13_alert_received_cb,
.alert_sent = tls13_alert_sent_cb,
.phh_recv = tls13_phh_received_cb,
.phh_sent = tls13_phh_done_cb,
};
struct tls13_ctx *
tls13_ctx_new(int mode)
{
struct tls13_ctx *ctx = NULL;
if ((ctx = calloc(sizeof(struct tls13_ctx), 1)) == NULL)
goto err;
ctx->mode = mode;
if ((ctx->rl = tls13_record_layer_new(&rl_callbacks, ctx)) == NULL)
goto err;
ctx->handshake_message_sent_cb = tls13_legacy_handshake_message_sent_cb;
ctx->handshake_message_recv_cb = tls13_legacy_handshake_message_recv_cb;
ctx->info_cb = tls13_legacy_info_cb;
ctx->ocsp_status_recv_cb = tls13_legacy_ocsp_status_recv_cb;
ctx->middlebox_compat = 1;
return ctx;
err:
tls13_ctx_free(ctx);
return NULL;
}
void
tls13_ctx_free(struct tls13_ctx *ctx)
{
if (ctx == NULL)
return;
tls13_error_clear(&ctx->error);
tls13_record_layer_free(ctx->rl);
tls13_handshake_msg_free(ctx->hs_msg);
freezero(ctx, sizeof(struct tls13_ctx));
}
int
tls13_cert_add(struct tls13_ctx *ctx, CBB *cbb, X509 *cert,
int(*build_extensions)(SSL *s, uint16_t msg_type, CBB *cbb))
{
CBB cert_data;
uint8_t *data;
int cert_len;
if ((cert_len = i2d_X509(cert, NULL)) < 0)
return 0;
if (!CBB_add_u24_length_prefixed(cbb, &cert_data))
return 0;
if (!CBB_add_space(&cert_data, &data, cert_len))
return 0;
if (i2d_X509(cert, &data) != cert_len)
return 0;
if (build_extensions != NULL) {
if (!build_extensions(ctx->ssl, SSL_TLSEXT_MSG_CT, cbb))
return 0;
} else {
CBB cert_exts;
if (!CBB_add_u16_length_prefixed(cbb, &cert_exts))
return 0;
}
if (!CBB_flush(cbb))
return 0;
return 1;
}
int
tls13_synthetic_handshake_message(struct tls13_ctx *ctx)
{
struct tls13_handshake_msg *hm = NULL;
unsigned char buf[EVP_MAX_MD_SIZE];
size_t hash_len;
CBB cbb;
CBS cbs;
SSL *s = ctx->ssl;
int ret = 0;
/*
* Replace ClientHello with synthetic handshake message - see
* RFC 8446 section 4.4.1.
*/
if (!tls1_transcript_hash_init(s))
goto err;
if (!tls1_transcript_hash_value(s, buf, sizeof(buf), &hash_len))
goto err;
if ((hm = tls13_handshake_msg_new()) == NULL)
goto err;
if (!tls13_handshake_msg_start(hm, &cbb, TLS13_MT_MESSAGE_HASH))
goto err;
if (!CBB_add_bytes(&cbb, buf, hash_len))
goto err;
if (!tls13_handshake_msg_finish(hm))
goto err;
tls13_handshake_msg_data(hm, &cbs);
tls1_transcript_reset(ctx->ssl);
if (!tls1_transcript_record(ctx->ssl, CBS_data(&cbs), CBS_len(&cbs)))
goto err;
ret = 1;
err:
tls13_handshake_msg_free(hm);
return ret;
}
int
tls13_clienthello_hash_init(struct tls13_ctx *ctx)
{
if (ctx->hs->clienthello_md_ctx != NULL)
return 0;
if ((ctx->hs->clienthello_md_ctx = EVP_MD_CTX_new()) == NULL)
return 0;
if (!EVP_DigestInit_ex(ctx->hs->clienthello_md_ctx,
EVP_sha256(), NULL))
return 0;
if ((ctx->hs->clienthello_hash == NULL) &&
(ctx->hs->clienthello_hash = calloc(1, EVP_MAX_MD_SIZE)) ==
NULL)
return 0;
return 1;
}
void
tls13_clienthello_hash_clear(struct ssl_handshake_tls13_st *hs)
{
EVP_MD_CTX_free(hs->clienthello_md_ctx);
hs->clienthello_md_ctx = NULL;
freezero(hs->clienthello_hash, EVP_MAX_MD_SIZE);
hs->clienthello_hash = NULL;
}
int
tls13_clienthello_hash_update_bytes(struct tls13_ctx *ctx, void *data,
size_t len)
{
return EVP_DigestUpdate(ctx->hs->clienthello_md_ctx, data, len);
}
int
tls13_clienthello_hash_update(struct tls13_ctx *ctx, CBS *cbs)
{
return tls13_clienthello_hash_update_bytes(ctx, (void *)CBS_data(cbs),
CBS_len(cbs));
}
int
tls13_clienthello_hash_finalize(struct tls13_ctx *ctx)
{
if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx,
ctx->hs->clienthello_hash,
&ctx->hs->clienthello_hash_len))
return 0;
EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx);
ctx->hs->clienthello_md_ctx = NULL;
return 1;
}
int
tls13_clienthello_hash_validate(struct tls13_ctx *ctx)
{
unsigned char new_ch_hash[EVP_MAX_MD_SIZE];
unsigned int new_ch_hash_len;
if (ctx->hs->clienthello_hash == NULL)
return 0;
if (!EVP_DigestFinal_ex(ctx->hs->clienthello_md_ctx,
new_ch_hash, &new_ch_hash_len))
return 0;
EVP_MD_CTX_free(ctx->hs->clienthello_md_ctx);
ctx->hs->clienthello_md_ctx = NULL;
if (ctx->hs->clienthello_hash_len != new_ch_hash_len)
return 0;
if (memcmp(ctx->hs->clienthello_hash, new_ch_hash,
new_ch_hash_len) != 0)
return 0;
return 1;
}

187
externals/libressl/ssl/tls13_record.c vendored Executable file
View File

@@ -0,0 +1,187 @@
/* $OpenBSD: tls13_record.c,v 1.6 2020/05/11 18:08:11 jsing Exp $ */
/*
* Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssl_locl.h"
#include "tls13_internal.h"
#include "tls13_record.h"
struct tls13_record {
uint16_t version;
uint8_t content_type;
size_t rec_len;
uint8_t *data;
size_t data_len;
CBS cbs;
struct tls13_buffer *buf;
};
struct tls13_record *
tls13_record_new(void)
{
struct tls13_record *rec = NULL;
if ((rec = calloc(1, sizeof(struct tls13_record))) == NULL)
goto err;
if ((rec->buf = tls13_buffer_new(TLS13_RECORD_MAX_LEN)) == NULL)
goto err;
return rec;
err:
tls13_record_free(rec);
return NULL;
}
void
tls13_record_free(struct tls13_record *rec)
{
if (rec == NULL)
return;
tls13_buffer_free(rec->buf);
freezero(rec->data, rec->data_len);
freezero(rec, sizeof(struct tls13_record));
}
uint16_t
tls13_record_version(struct tls13_record *rec)
{
return rec->version;
}
uint8_t
tls13_record_content_type(struct tls13_record *rec)
{
return rec->content_type;
}
int
tls13_record_header(struct tls13_record *rec, CBS *cbs)
{
if (rec->data_len < TLS13_RECORD_HEADER_LEN)
return 0;
CBS_init(cbs, rec->data, TLS13_RECORD_HEADER_LEN);
return 1;
}
int
tls13_record_content(struct tls13_record *rec, CBS *cbs)
{
CBS content;
tls13_record_data(rec, &content);
if (!CBS_skip(&content, TLS13_RECORD_HEADER_LEN))
return 0;
CBS_dup(&content, cbs);
return 1;
}
void
tls13_record_data(struct tls13_record *rec, CBS *cbs)
{
CBS_init(cbs, rec->data, rec->data_len);
}
int
tls13_record_set_data(struct tls13_record *rec, uint8_t *data, size_t data_len)
{
if (data_len > TLS13_RECORD_MAX_LEN)
return 0;
freezero(rec->data, rec->data_len);
rec->data = data;
rec->data_len = data_len;
CBS_init(&rec->cbs, rec->data, rec->data_len);
return 1;
}
ssize_t
tls13_record_recv(struct tls13_record *rec, tls13_read_cb wire_read,
void *wire_arg)
{
uint16_t rec_len, rec_version;
uint8_t content_type;
ssize_t ret;
CBS cbs;
if (rec->data != NULL)
return TLS13_IO_FAILURE;
if (rec->content_type == 0) {
if ((ret = tls13_buffer_extend(rec->buf,
TLS13_RECORD_HEADER_LEN, wire_read, wire_arg)) <= 0)
return ret;
tls13_buffer_cbs(rec->buf, &cbs);
if (!CBS_get_u8(&cbs, &content_type))
return TLS13_IO_FAILURE;
if (!CBS_get_u16(&cbs, &rec_version))
return TLS13_IO_FAILURE;
if (!CBS_get_u16(&cbs, &rec_len))
return TLS13_IO_FAILURE;
if ((rec_version >> 8) != SSL3_VERSION_MAJOR)
return TLS13_IO_RECORD_VERSION;
if (rec_len > TLS13_RECORD_MAX_CIPHERTEXT_LEN)
return TLS13_IO_RECORD_OVERFLOW;
rec->content_type = content_type;
rec->version = rec_version;
rec->rec_len = rec_len;
}
if ((ret = tls13_buffer_extend(rec->buf,
TLS13_RECORD_HEADER_LEN + rec->rec_len, wire_read, wire_arg)) <= 0)
return ret;
if (!tls13_buffer_finish(rec->buf, &rec->data, &rec->data_len))
return TLS13_IO_FAILURE;
return rec->data_len;
}
ssize_t
tls13_record_send(struct tls13_record *rec, tls13_write_cb wire_write,
void *wire_arg)
{
ssize_t ret;
if (rec->data == NULL)
return TLS13_IO_FAILURE;
while (CBS_len(&rec->cbs) > 0) {
if ((ret = wire_write(CBS_data(&rec->cbs),
CBS_len(&rec->cbs), wire_arg)) <= 0)
return ret;
if (!CBS_skip(&rec->cbs, ret))
return TLS13_IO_FAILURE;
}
return rec->data_len;
}

67
externals/libressl/ssl/tls13_record.h vendored Executable file
View File

@@ -0,0 +1,67 @@
/* $OpenBSD: tls13_record.h,v 1.3 2019/01/21 00:24:19 jsing Exp $ */
/*
* Copyright (c) 2019 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HEADER_TLS13_RECORD_H
#define HEADER_TLS13_RECORD_H
#include "bytestring.h"
#include "tls13_internal.h"
__BEGIN_HIDDEN_DECLS
/*
* TLSv1.3 Record Protocol - RFC 8446 section 5.
*
* The maximum plaintext is 2^14, however for inner plaintext an additional
* byte is allowed for the content type. A maximum AEAD overhead of 255-bytes
* is permitted, along with a 5-byte header, giving a maximum size of
* 5 + 2^14 + 1 + 255 = 16,645-bytes.
*/
#define TLS13_RECORD_HEADER_LEN 5
#define TLS13_RECORD_MAX_AEAD_OVERHEAD 255
#define TLS13_RECORD_MAX_PLAINTEXT_LEN 16384
#define TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN \
(TLS13_RECORD_MAX_PLAINTEXT_LEN + 1)
#define TLS13_RECORD_MAX_CIPHERTEXT_LEN \
(TLS13_RECORD_MAX_INNER_PLAINTEXT_LEN + TLS13_RECORD_MAX_AEAD_OVERHEAD)
#define TLS13_RECORD_MAX_LEN \
(TLS13_RECORD_HEADER_LEN + TLS13_RECORD_MAX_CIPHERTEXT_LEN)
/*
* TLSv1.3 Per-Record Nonces and Sequence Numbers - RFC 8446 section 5.3.
*/
#define TLS13_RECORD_SEQ_NUM_LEN 8
struct tls13_record;
struct tls13_record *tls13_record_new(void);
void tls13_record_free(struct tls13_record *_rec);
uint16_t tls13_record_version(struct tls13_record *_rec);
uint8_t tls13_record_content_type(struct tls13_record *_rec);
int tls13_record_header(struct tls13_record *_rec, CBS *_cbs);
int tls13_record_content(struct tls13_record *_rec, CBS *_cbs);
void tls13_record_data(struct tls13_record *_rec, CBS *_cbs);
int tls13_record_set_data(struct tls13_record *_rec, uint8_t *_data,
size_t _data_len);
ssize_t tls13_record_recv(struct tls13_record *_rec, tls13_read_cb _wire_read,
void *_wire_arg);
ssize_t tls13_record_send(struct tls13_record *_rec, tls13_write_cb _wire_write,
void *_wire_arg);
__END_HIDDEN_DECLS
#endif

1200
externals/libressl/ssl/tls13_record_layer.c vendored Executable file

File diff suppressed because it is too large Load Diff

1071
externals/libressl/ssl/tls13_server.c vendored Executable file

File diff suppressed because it is too large Load Diff