Fix issue with TLSv1.3 negotiation
TLSv1.3 behaves differently in how PSK identity/PSK identity hints are exchanged, at least in regards to OpenSSL. This caused the TLS client to not send their TLS identity to the server, which rejected the connection (it expected "luksrku v1"). Couldn't solve it with TLSv1.3, so we're now simply forcing TLSv1.2.
This commit is contained in:
parent
aece35134e
commit
2cde43d357
15
client.c
15
client.c
@ -42,24 +42,25 @@
|
|||||||
static const struct keydb_t *client_keydb;
|
static const struct keydb_t *client_keydb;
|
||||||
|
|
||||||
static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) {
|
static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) {
|
||||||
|
log_msg(LLVL_DEBUG, "psk_client_callback: SSL %p, hint '%s'.", ssl, hint);
|
||||||
if (max_psk_len < PSK_SIZE_BYTES) {
|
if (max_psk_len < PSK_SIZE_BYTES) {
|
||||||
log_msg(LLVL_ERROR, "Client error: max_psk_len too small.\n");
|
log_msg(LLVL_ERROR, "Client error: max_psk_len too small.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (max_identity_len < strlen(CLIENT_PSK_IDENTITY) + 1) {
|
if (max_identity_len < strlen(CLIENT_PSK_IDENTITY) + 1) {
|
||||||
log_msg(LLVL_ERROR, "Client error: max_identity_len too small.\n");
|
log_msg(LLVL_ERROR, "Client error: max_identity_len too small.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t parsed_uuid[16];
|
uint8_t parsed_uuid[16];
|
||||||
if (!parse_uuid(parsed_uuid, hint)) {
|
if (!parse_uuid(parsed_uuid, hint)) {
|
||||||
log_msg(LLVL_ERROR, "Client error: given hint is not a valid UUID.\n");
|
log_msg(LLVL_ERROR, "Client error: given hint '%s' is not a valid UUID.", hint);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct keyentry_t *entry = keydb_find_entry_by_host_uuid(client_keydb, parsed_uuid);
|
const struct keyentry_t *entry = keydb_find_entry_by_host_uuid(client_keydb, parsed_uuid);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
log_msg(LLVL_ERROR, "Client error: server hint '%s' not present in database.\n", hint);
|
log_msg(LLVL_ERROR, "Client error: server hint '%s' not present in database.", hint);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ static int dtls_client_connect(const struct keyentry_t *keyentry, const char *ho
|
|||||||
log_openssl(LLVL_ERROR, "Cannot perform SSL client connect.");
|
log_openssl(LLVL_ERROR, "Cannot perform SSL client connect.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BIO_do_handshake(conn) != 1) {
|
if (BIO_do_handshake(conn) != 1) {
|
||||||
log_openssl(LLVL_ERROR, "Cannot perform SSL client handshake.");
|
log_openssl(LLVL_ERROR, "Cannot perform SSL client handshake.");
|
||||||
return false;
|
return false;
|
||||||
@ -127,7 +128,7 @@ static int dtls_client_connect(const struct keyentry_t *keyentry, const char *ho
|
|||||||
|
|
||||||
static bool parse_announcement(const struct options_t *options, const struct sockaddr_in *peer_addr, const struct announcement_t *announcement) {
|
static bool parse_announcement(const struct options_t *options, const struct sockaddr_in *peer_addr, const struct announcement_t *announcement) {
|
||||||
log_msg(LLVL_DEBUG, "Parsing possible announcement from %d.%d.%d.%d:%d", PRINTF_FORMAT_IP(peer_addr), ntohs(peer_addr->sin_port));
|
log_msg(LLVL_DEBUG, "Parsing possible announcement from %d.%d.%d.%d:%d", PRINTF_FORMAT_IP(peer_addr), ntohs(peer_addr->sin_port));
|
||||||
const uint8_t expect_magic[16] = CLIENT_ANNOUNCE_MAGIC;
|
const uint8_t expect_magic[16] = CLIENT_ANNOUNCE_MAGIC;
|
||||||
if (memcmp(announcement->magic, expect_magic, 16)) {
|
if (memcmp(announcement->magic, expect_magic, 16)) {
|
||||||
/* Magic number does not match, discard. */
|
/* Magic number does not match, discard. */
|
||||||
return false;
|
return false;
|
||||||
@ -175,7 +176,7 @@ bool dtls_client(const struct keydb_t *keydb, const struct options_t *options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int value = 1;
|
int value = 1;
|
||||||
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
|
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,11 @@ bool create_generic_tls_context(struct generic_tls_ctx_t *gctx, bool server) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SSL_CTX_set_max_proto_version(gctx->ctx, TLS1_2_VERSION)) {
|
||||||
|
log_openssl(LLVL_FATAL, "Cannot set TLS generic context maximal version.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SSL_CTX_set_cipher_list(gctx->ctx, "ECDHE-PSK-CHACHA20-POLY1305")) {
|
if (!SSL_CTX_set_cipher_list(gctx->ctx, "ECDHE-PSK-CHACHA20-POLY1305")) {
|
||||||
log_openssl(LLVL_FATAL, "Cannot set TLS generic context cipher suites.");
|
log_openssl(LLVL_FATAL, "Cannot set TLS generic context cipher suites.");
|
||||||
return false;
|
return false;
|
||||||
@ -97,7 +102,7 @@ bool create_generic_tls_context(struct generic_tls_ctx_t *gctx, bool server) {
|
|||||||
log_openssl(LLVL_FATAL, "Cannot set TLS generic context ECDHE curves.");
|
log_openssl(LLVL_FATAL, "Cannot set TLS generic context ECDHE curves.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
util.c
9
util.c
@ -36,7 +36,7 @@ char* query_passphrase(const char *prompt) {
|
|||||||
log_libc(LLVL_ERROR, "malloc(3) of passphrase memory");
|
log_libc(LLVL_ERROR, "malloc(3) of passphrase memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EVP_read_pw_string(passphrase, MAX_PASSPHRASE_LENGTH - 1, prompt, 0) != 0) {
|
if (EVP_read_pw_string(passphrase, MAX_PASSPHRASE_LENGTH - 1, prompt, 0) != 0) {
|
||||||
log_openssl(LLVL_ERROR, "EVP_read_pw_string failed");
|
log_openssl(LLVL_ERROR, "EVP_read_pw_string failed");
|
||||||
free(passphrase);
|
free(passphrase);
|
||||||
@ -66,8 +66,8 @@ void dump_hex(FILE *f, const void *vdata, unsigned int length) {
|
|||||||
|
|
||||||
bool is_hex(const char *str, int length) {
|
bool is_hex(const char *str, int length) {
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
if (((str[i] >= '0') && (str[i] <= '9')) ||
|
if (((str[i] >= '0') && (str[i] <= '9')) ||
|
||||||
((str[i] >= 'a') && (str[i] <= 'f')) ||
|
((str[i] >= 'a') && (str[i] <= 'f')) ||
|
||||||
((str[i] >= 'A') && (str[i] <= 'F'))) {
|
((str[i] >= 'A') && (str[i] <= 'F'))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -116,6 +116,9 @@ int parse_hexstr(const char *hexstr, uint8_t *data, int maxlen) {
|
|||||||
bool is_valid_uuid(const char *ascii_uuid) {
|
bool is_valid_uuid(const char *ascii_uuid) {
|
||||||
// e43fff25-5a01-40e8-b437-80b9d56c19ff
|
// e43fff25-5a01-40e8-b437-80b9d56c19ff
|
||||||
// '-' at offsets 8 13 18 23
|
// '-' at offsets 8 13 18 23
|
||||||
|
if (!ascii_uuid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (strlen(ascii_uuid) != 36) {
|
if (strlen(ascii_uuid) != 36) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user