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 3, 2024
1 parent bb68750 commit db001b2
Showing 1 changed file with 161 additions and 0 deletions.
161 changes: 161 additions & 0 deletions tests/tlsctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <stdbool.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/store.h>
#include <openssl/core_names.h>

static void ossl_err_print(void)
{
Expand Down Expand Up @@ -33,6 +37,161 @@ static void ossl_err_print(void)
}
}

static 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;
}

static void test_pkcs1_with_tls_padding(void)
{
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;

pubkey = load_key(getenv("PUBURI"));

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);
}

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);
}

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);
}
}

int main(int argc, char *argv[])
{
SSL_CTX *ctx;
Expand All @@ -48,5 +207,7 @@ int main(int argc, char *argv[])

SSL_CTX_free(ctx);

test_pkcs1_with_tls_padding();

exit(EXIT_SUCCESS);
}

0 comments on commit db001b2

Please sign in to comment.