Skip to content

Commit

Permalink
Add test to verify TLS depadding works correctly
Browse files Browse the repository at this point in the history
Signed-off-by: Simo Sorce <[email protected]>
  • Loading branch information
simo5 committed Jun 4, 2024
1 parent 7e7fb27 commit 554730b
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 112 deletions.
24 changes: 12 additions & 12 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,20 @@ if get_option('b_sanitize') == 'address'
endif
endif

test_programs = [
'tsession',
'tgenkey',
'tlsctx',
'tdigests',
'treadkeys',
'tcmpkeys',
'tfork',
'pincache',
]
test_programs = {
'tsession': ['tsession.c'],
'tgenkey': ['tgenkey.c'],
'tlsctx': ['tlsctx.c', 'util.c'],
'tdigests': ['tdigests.c'],
'treadkeys': ['treadkeys.c'],
'tcmpkeys': ['tcmpkeys.c', 'util.c'],
'tfork': ['tfork.c'],
'pincache': ['pincache.c'],
}

test_executables = []
foreach t : test_programs
t = executable(t, '@[email protected]'.format(t),
foreach t, sources : test_programs
t = executable(t, sources,
build_by_default: false,
include_directories: [configinc],
dependencies: [libcrypto, libssl])
Expand Down
81 changes: 1 addition & 80 deletions tests/tcmpkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,86 +7,7 @@
#include <openssl/err.h>
#include <openssl/store.h>
#include <openssl/core_names.h>

static void ossl_err_print(void)
{
bool first = true;
unsigned long err = 0;
while (true) {
const char *file, *func, *data;
int line;
err = ERR_get_error_all(&file, &line, &func, &data, NULL);
if (err == 0) {
break;
}

char buf[1024];
ERR_error_string_n(err, buf, sizeof(buf));

const char *fmt =
first ? ": %s (in function %s in %s:%d): %s\n"
: " caused by: %s (in function %s in %s:%d): %s\n";
fprintf(stderr, fmt, buf, func, file, line, data);

first = false;
}
if (first) {
fprintf(stderr, "\n");
}
}

static EVP_PKEY *load_key(const char *uri)
{
OSSL_STORE_CTX *store;
OSSL_STORE_INFO *info;
EVP_PKEY *key = NULL;

store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
if (store == NULL) {
fprintf(stderr, "Failed to open store: %s\n", uri);
ossl_err_print();
exit(EXIT_FAILURE);
}

if (strncmp(uri, "pkcs11:", 7) && strstr(uri, "type=private") == NULL) {
/* This is a workaround for OpenSSL < 3.2.0 where the code fails
* to correctly source public keys unless explicitly requested
* via an expect hint */
if (OSSL_STORE_expect(store, OSSL_STORE_INFO_PUBKEY) != 1) {
fprintf(stderr, "Failed to expect Public Key File\n");
exit(EXIT_FAILURE);
}
}

for (info = OSSL_STORE_load(store); info != NULL;
info = OSSL_STORE_load(store)) {
int type = OSSL_STORE_INFO_get_type(info);

if (key != NULL) {
fprintf(stderr, "Multiple keys matching URI: %s\n", uri);
exit(EXIT_FAILURE);
}

switch (type) {
case OSSL_STORE_INFO_PUBKEY:
key = OSSL_STORE_INFO_get1_PUBKEY(info);
break;
case OSSL_STORE_INFO_PKEY:
key = OSSL_STORE_INFO_get1_PKEY(info);
break;
}
OSSL_STORE_INFO_free(info);
}

if (key == NULL) {
fprintf(stderr, "Failed to load key from URI: %s\n", uri);
ossl_err_print();
exit(EXIT_FAILURE);
}
OSSL_STORE_close(store);

return key;
}
#include "util.h"

int main(int argc, char *argv[])
{
Expand Down
114 changes: 94 additions & 20 deletions tests/tlsctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,104 @@
#include <stdio.h>
#include <stdbool.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/core_names.h>
#include "util.h"

static void ossl_err_print(void)
static void test_pkcs1_with_tls_padding(void)
{
bool first = true;
unsigned long err = 0;
while (true) {
const char *file, *func, *data;
int line;
err = ERR_get_error_all(&file, &line, &func, &data, NULL);
if (err == 0) {
break;
}
EVP_PKEY_CTX *ctx;
EVP_PKEY *prikey;
EVP_PKEY *pubkey;
unsigned char plain[SSL_MAX_MASTER_KEY_LENGTH + 2] = { 0x03, 0x03, 0x01 };
unsigned char enc[1024];
unsigned char dec[1024];
size_t enclen;
size_t declen;
unsigned int ver = 0x0303;
const OSSL_PARAM ver_params[] = {
OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, &ver),
OSSL_PARAM_END
};
int err;

char buf[1024];
ERR_error_string_n(err, buf, sizeof(buf));
pubkey = load_key(getenv("PUBURI"));

const char *fmt =
first ? ": %s (in function %s in %s:%d): %s\n"
: " caused by: %s (in function %s in %s:%d): %s\n";
fprintf(stderr, fmt, buf, func, file, line, data);
ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pubkey, NULL);
if (!ctx) {
fprintf(stderr, "Failed to init pkey ctx for puburi\n");
ossl_err_print();
exit(EXIT_FAILURE);
}
err = EVP_PKEY_encrypt_init(ctx);
if (err != 1) {
fprintf(stderr, "Failed to init encrypt ctx\n");
ossl_err_print();
exit(EXIT_FAILURE);
}
err = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
if (err != 1) {
fprintf(stderr, "Failed to set padding on encrypt ctx\n");
ossl_err_print();
exit(EXIT_FAILURE);
}

enclen = sizeof(enc);
err = EVP_PKEY_encrypt(ctx, enc, &enclen, plain, sizeof(plain));
if (err != 1) {
fprintf(stderr, "Failed to encrypt TLS master key\n");
ossl_err_print();
exit(EXIT_FAILURE);
}

EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pubkey);

prikey = load_key(getenv("PRIURI"));

ctx = EVP_PKEY_CTX_new_from_pkey(NULL, prikey, NULL);
if (!ctx) {
fprintf(stderr, "Failed to init pkey ctx for priuri\n");
ossl_err_print();
exit(EXIT_FAILURE);
}
err = EVP_PKEY_decrypt_init(ctx);
if (err != 1) {
fprintf(stderr, "Failed to init decrypt ctx\n");
ossl_err_print();
exit(EXIT_FAILURE);
}
err = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_WITH_TLS_PADDING);
if (err != 1) {
fprintf(stderr, "Failed to set padding on decrypt ctx\n");
ossl_err_print();
exit(EXIT_FAILURE);
}

first = false;
err = EVP_PKEY_CTX_set_params(ctx, ver_params);
if (err != 1) {
fprintf(stderr, "Failed to set version params\n");
ossl_err_print();
exit(EXIT_FAILURE);
}
if (first) {
fprintf(stderr, "\n");

declen = sizeof(dec);
err = EVP_PKEY_decrypt(ctx, dec, &declen, enc, enclen);
if (err != 1) {
fprintf(stderr, "Failed to decrypt TLS master key\n");
ossl_err_print();
exit(EXIT_FAILURE);
}

EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(prikey);

if ((declen != sizeof(plain) - 2)
|| (memcmp(plain + 2, dec, declen) != 0)) {
fprintf(stderr, "Fail, decrypted master secret differs from input\n");
ossl_err_print();
exit(EXIT_FAILURE);
}
}

Expand All @@ -48,5 +120,7 @@ int main(int argc, char *argv[])

SSL_CTX_free(ctx);

test_pkcs1_with_tls_padding();

exit(EXIT_SUCCESS);
}
94 changes: 94 additions & 0 deletions tests/util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* Copyright (C) 2024 Simo Sorce <[email protected]>
SPDX-License-Identifier: Apache-2.0 */

#include <stdio.h>
#include <stdbool.h>
#include <openssl/err.h>
#include <openssl/store.h>
#include "util.h"

void ossl_err_print(void)
{
bool first = true;
unsigned long err = 0;
while (true) {
const char *file, *func, *data;
int line;
err = ERR_get_error_all(&file, &line, &func, &data, NULL);
if (err == 0) {
break;
}

char buf[1024];
ERR_error_string_n(err, buf, sizeof(buf));

const char *fmt =
first ? ": %s (in function %s in %s:%d): %s\n"
: " caused by: %s (in function %s in %s:%d): %s\n";
fprintf(stderr, fmt, buf, func, file, line, data);

first = false;
}
if (first) {
fprintf(stderr, "\n");
}
}

EVP_PKEY *load_key(const char *uri)
{
OSSL_STORE_CTX *store;
OSSL_STORE_INFO *info;
EVP_PKEY *key = NULL;

if (!uri) {
fprintf(stderr, "Invalid NULL uri");
ossl_err_print();
exit(EXIT_FAILURE);
}

store = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
if (store == NULL) {
fprintf(stderr, "Failed to open store: %s\n", uri);
ossl_err_print();
exit(EXIT_FAILURE);
}

if (strncmp(uri, "pkcs11:", 7) && strstr(uri, "type=private") == NULL) {
/* This is a workaround for OpenSSL < 3.2.0 where the code fails
* to correctly source public keys unless explicitly requested
* via an expect hint */
if (OSSL_STORE_expect(store, OSSL_STORE_INFO_PUBKEY) != 1) {
fprintf(stderr, "Failed to expect Public Key File\n");
exit(EXIT_FAILURE);
}
}

for (info = OSSL_STORE_load(store); info != NULL;
info = OSSL_STORE_load(store)) {
int type = OSSL_STORE_INFO_get_type(info);

if (key != NULL) {
fprintf(stderr, "Multiple keys matching URI: %s\n", uri);
exit(EXIT_FAILURE);
}

switch (type) {
case OSSL_STORE_INFO_PUBKEY:
key = OSSL_STORE_INFO_get1_PUBKEY(info);
break;
case OSSL_STORE_INFO_PKEY:
key = OSSL_STORE_INFO_get1_PKEY(info);
break;
}
OSSL_STORE_INFO_free(info);
}

if (key == NULL) {
fprintf(stderr, "Failed to load key from URI: %s\n", uri);
ossl_err_print();
exit(EXIT_FAILURE);
}
OSSL_STORE_close(store);

return key;
}
5 changes: 5 additions & 0 deletions tests/util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* Copyright (C) 2024 Simo Sorce <[email protected]>
SPDX-License-Identifier: Apache-2.0 */

void ossl_err_print(void);
EVP_PKEY *load_key(const char *uri);

0 comments on commit 554730b

Please sign in to comment.