Add a test for encoding and decoding of parameters files
Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13050)
This commit is contained in:
parent
3861ac3b55
commit
b565a17d9f
1 changed files with 167 additions and 32 deletions
|
@ -93,18 +93,21 @@ typedef int (encoder)(void **encoded, long *encoded_len, void *object,
|
|||
const char *output_type, int selection,
|
||||
const char *pass, const char *pcipher);
|
||||
typedef int (decoder)(void **object, void *encoded, long encoded_len,
|
||||
const char *pass);
|
||||
const char *keytype, const char *input_type,
|
||||
int selection, const char *pass);
|
||||
typedef int (tester)(const void *data1, size_t data1_len,
|
||||
const void *data2, size_t data2_len);
|
||||
typedef int (checker)(const char *type, const void *data, size_t data_len);
|
||||
typedef void (dumper)(const char *label, const void *data, size_t data_len);
|
||||
|
||||
#define FLAG_DECODE_WITH_TYPE 0x0001
|
||||
|
||||
static int test_encode_decode(const char *type, EVP_PKEY *pkey,
|
||||
const char *output_type, int selection,
|
||||
const char *pass, const char *pcipher,
|
||||
encoder *encode_cb, decoder *decode_cb,
|
||||
tester *test_cb, checker *check_cb,
|
||||
dumper *dump_cb)
|
||||
dumper *dump_cb, int flags)
|
||||
{
|
||||
void *encoded = NULL;
|
||||
long encoded_len = 0;
|
||||
|
@ -118,16 +121,23 @@ static int test_encode_decode(const char *type, EVP_PKEY *pkey,
|
|||
* encoding |pkey2| as well. That last encoding is for checking and
|
||||
* dumping purposes.
|
||||
*/
|
||||
if (!encode_cb(&encoded, &encoded_len, pkey, output_type, selection,
|
||||
pass, pcipher)
|
||||
|| !check_cb(type, encoded, encoded_len)
|
||||
|| !decode_cb((void **)&pkey2, encoded, encoded_len, pass)
|
||||
|| !encode_cb(&encoded2, &encoded2_len, pkey2, output_type, selection,
|
||||
pass, pcipher))
|
||||
if (!TEST_true(encode_cb(&encoded, &encoded_len, pkey, output_type,
|
||||
selection, pass, pcipher))
|
||||
|| !TEST_true(check_cb(type, encoded, encoded_len))
|
||||
|| !TEST_true(decode_cb((void **)&pkey2, encoded, encoded_len,
|
||||
(flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
|
||||
output_type, selection, pass))
|
||||
|| !TEST_true(encode_cb(&encoded2, &encoded2_len, pkey2, output_type,
|
||||
selection, pass, pcipher)))
|
||||
goto end;
|
||||
|
||||
if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
|
||||
goto end;
|
||||
if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
|
||||
if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey2), 1))
|
||||
goto end;
|
||||
} else {
|
||||
if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1))
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Double check the encoding, but only for unprotected keys,
|
||||
|
@ -193,25 +203,71 @@ static int encode_EVP_PKEY_prov(void **encoded, long *encoded_len,
|
|||
}
|
||||
|
||||
static int decode_EVP_PKEY_prov(void **object, void *encoded, long encoded_len,
|
||||
const char *pass)
|
||||
const char *keytype, const char *input_type,
|
||||
int selection, const char *pass)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY *pkey = NULL, *testpkey = NULL;
|
||||
OSSL_DECODER_CTX *dctx = NULL;
|
||||
BIO *mem_deser = NULL;
|
||||
BIO *encoded_bio = NULL;
|
||||
const unsigned char *upass = (const unsigned char *)pass;
|
||||
int ok = 0;
|
||||
int i;
|
||||
const char *badtype;
|
||||
|
||||
if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, NULL, NULL,
|
||||
NULL, NULL))
|
||||
|| (pass != NULL
|
||||
&& !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
|
||||
|| !TEST_ptr(mem_deser = BIO_new_mem_buf(encoded, encoded_len))
|
||||
|| !TEST_true(OSSL_DECODER_from_bio(dctx, mem_deser)))
|
||||
if (strcmp(input_type, "DER") == 0)
|
||||
badtype = "PEM";
|
||||
else
|
||||
badtype = "DER";
|
||||
|
||||
if (!TEST_ptr(encoded_bio = BIO_new_mem_buf(encoded, encoded_len)))
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* We attempt the decode 3 times. The first time we provide the expected
|
||||
* starting input type. The second time we provide NULL for the starting
|
||||
* type. The third time we provide a bad starting input type.
|
||||
* The bad starting input type should fail. The other two should succeed
|
||||
* and produce the same result.
|
||||
*/
|
||||
for (i = 0; i < 3; i++) {
|
||||
const char *testtype = (i == 0) ? input_type
|
||||
: ((i == 1) ? NULL : badtype);
|
||||
|
||||
if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&testpkey,
|
||||
testtype,
|
||||
keytype,
|
||||
NULL, NULL))
|
||||
|| (pass != NULL
|
||||
&& !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
|
||||
|| !TEST_int_gt(BIO_reset(encoded_bio), 0)
|
||||
/* We expect to fail when using a bad input type */
|
||||
|| !TEST_int_eq(OSSL_DECODER_from_bio(dctx, encoded_bio),
|
||||
(i == 2) ? 0 : 1))
|
||||
goto end;
|
||||
OSSL_DECODER_CTX_free(dctx);
|
||||
dctx = NULL;
|
||||
|
||||
if (i == 0) {
|
||||
pkey = testpkey;
|
||||
testpkey = NULL;
|
||||
} else if (i == 1) {
|
||||
if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
|
||||
if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, testpkey), 1))
|
||||
goto end;
|
||||
} else {
|
||||
if (!TEST_int_eq(EVP_PKEY_eq(pkey, testpkey), 1))
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
*object = pkey;
|
||||
pkey = NULL;
|
||||
|
||||
end:
|
||||
BIO_free(mem_deser);
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_free(testpkey);
|
||||
BIO_free(encoded_bio);
|
||||
OSSL_DECODER_CTX_free(dctx);
|
||||
return ok;
|
||||
}
|
||||
|
@ -433,7 +489,7 @@ static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
|
|||
NULL, NULL,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_mem, check_unprotected_PKCS8_DER,
|
||||
dump_der);
|
||||
dump_der, 0);
|
||||
}
|
||||
|
||||
static int check_unprotected_PKCS8_PEM(const char *type,
|
||||
|
@ -454,7 +510,64 @@ static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
|
|||
NULL, NULL,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_text, check_unprotected_PKCS8_PEM,
|
||||
dump_pem);
|
||||
dump_pem, 0);
|
||||
}
|
||||
|
||||
static int check_params_DER(const char *type, const void *data, size_t data_len)
|
||||
{
|
||||
const unsigned char *datap = data;
|
||||
int ok = 0;
|
||||
int itype = NID_undef;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
if (strcmp(type, "DH") == 0)
|
||||
itype = EVP_PKEY_DH;
|
||||
else if (strcmp(type, "X9.42 DH") == 0)
|
||||
itype = EVP_PKEY_DHX;
|
||||
else if (strcmp(type, "DSA") == 0)
|
||||
itype = EVP_PKEY_DSA;
|
||||
else if (strcmp(type, "EC") == 0)
|
||||
itype = EVP_PKEY_EC;
|
||||
|
||||
if (itype != NID_undef) {
|
||||
pkey = d2i_KeyParams(itype, NULL, &datap, data_len);
|
||||
ok = (pkey != NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int check_params_PEM(const char *type,
|
||||
const void *data, size_t data_len)
|
||||
{
|
||||
static char expected_pem_header[80];
|
||||
|
||||
return
|
||||
TEST_int_gt(BIO_snprintf(expected_pem_header,
|
||||
sizeof(expected_pem_header),
|
||||
"-----BEGIN %s PARAMETERS-----", type), 0)
|
||||
&& TEST_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
|
||||
}
|
||||
|
||||
static int test_params_via_DER(const char *type, EVP_PKEY *key)
|
||||
{
|
||||
return test_encode_decode(type, key,
|
||||
"DER", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
NULL, NULL,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_mem, check_params_DER,
|
||||
dump_der, FLAG_DECODE_WITH_TYPE);
|
||||
}
|
||||
|
||||
static int test_params_via_PEM(const char *type, EVP_PKEY *key)
|
||||
{
|
||||
return test_encode_decode(type, key,
|
||||
"PEM", OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
NULL, NULL,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_text, check_params_PEM,
|
||||
dump_pem, 0);
|
||||
}
|
||||
|
||||
static int check_unprotected_legacy_PEM(const char *type,
|
||||
|
@ -477,7 +590,7 @@ static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
|
|||
NULL, NULL,
|
||||
encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
|
||||
test_text, check_unprotected_legacy_PEM,
|
||||
dump_pem);
|
||||
dump_pem, 0);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
|
@ -499,7 +612,7 @@ static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
|
|||
NULL, NULL,
|
||||
encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
|
||||
test_mem, check_MSBLOB,
|
||||
dump_der);
|
||||
dump_der, 0);
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
|
@ -520,7 +633,7 @@ static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
|
|||
NULL, NULL,
|
||||
encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
|
||||
test_mem, check_PVK,
|
||||
dump_der);
|
||||
dump_der, 0);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
@ -547,7 +660,7 @@ static int test_protected_via_DER(const char *type, EVP_PKEY *key)
|
|||
pass, pass_cipher,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_mem, check_protected_PKCS8_DER,
|
||||
dump_der);
|
||||
dump_der, 0);
|
||||
}
|
||||
|
||||
static int check_protected_PKCS8_PEM(const char *type,
|
||||
|
@ -568,7 +681,7 @@ static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
|
|||
pass, pass_cipher,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_text, check_protected_PKCS8_PEM,
|
||||
dump_pem);
|
||||
dump_pem, 0);
|
||||
}
|
||||
|
||||
static int check_protected_legacy_PEM(const char *type,
|
||||
|
@ -592,7 +705,7 @@ static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
|
|||
pass, pass_cipher,
|
||||
encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
|
||||
test_text, check_protected_legacy_PEM,
|
||||
dump_pem);
|
||||
dump_pem, 0);
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
|
@ -603,7 +716,7 @@ static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
|
|||
| OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
pass, NULL,
|
||||
encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
|
||||
test_mem, check_PVK, dump_der);
|
||||
test_mem, check_PVK, dump_der, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -624,7 +737,7 @@ static int test_public_via_DER(const char *type, EVP_PKEY *key)
|
|||
| OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
NULL, NULL,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_mem, check_public_DER, dump_der);
|
||||
test_mem, check_public_DER, dump_der, 0);
|
||||
}
|
||||
|
||||
static int check_public_PEM(const char *type, const void *data, size_t data_len)
|
||||
|
@ -644,7 +757,7 @@ static int test_public_via_PEM(const char *type, EVP_PKEY *key)
|
|||
| OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
NULL, NULL,
|
||||
encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
|
||||
test_text, check_public_PEM, dump_pem);
|
||||
test_text, check_public_PEM, dump_pem, 0);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
|
@ -667,7 +780,7 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
|
|||
NULL, NULL,
|
||||
encode_public_EVP_PKEY_MSBLOB,
|
||||
decode_EVP_PKEY_prov,
|
||||
test_mem, check_public_MSBLOB, dump_der);
|
||||
test_mem, check_public_MSBLOB, dump_der, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -726,6 +839,20 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
|
|||
ADD_TEST(test_public_##KEYTYPE##_via_DER); \
|
||||
ADD_TEST(test_public_##KEYTYPE##_via_PEM)
|
||||
|
||||
#define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr) \
|
||||
static int test_params_##KEYTYPE##_via_DER(void) \
|
||||
{ \
|
||||
return test_params_via_DER(KEYTYPEstr, key_##KEYTYPE); \
|
||||
} \
|
||||
static int test_params_##KEYTYPE##_via_PEM(void) \
|
||||
{ \
|
||||
return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
|
||||
}
|
||||
|
||||
#define ADD_TEST_SUITE_PARAMS(KEYTYPE) \
|
||||
ADD_TEST(test_params_##KEYTYPE##_via_DER); \
|
||||
ADD_TEST(test_params_##KEYTYPE##_via_PEM)
|
||||
|
||||
#define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr) \
|
||||
static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void) \
|
||||
{ \
|
||||
|
@ -777,8 +904,10 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
|
|||
#ifndef OPENSSL_NO_DH
|
||||
DOMAIN_KEYS(DH);
|
||||
IMPLEMENT_TEST_SUITE(DH, "DH")
|
||||
IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
|
||||
DOMAIN_KEYS(DHX);
|
||||
IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
|
||||
IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
|
||||
/*
|
||||
* DH has no support for PEM_write_bio_PrivateKey_traditional(),
|
||||
* so no legacy tests.
|
||||
|
@ -787,6 +916,7 @@ IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
|
|||
#ifndef OPENSSL_NO_DSA
|
||||
DOMAIN_KEYS(DSA);
|
||||
IMPLEMENT_TEST_SUITE(DSA, "DSA")
|
||||
IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
|
||||
IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
|
||||
IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
|
@ -796,6 +926,7 @@ IMPLEMENT_TEST_SUITE_PVK(DSA, "DSA")
|
|||
#ifndef OPENSSL_NO_EC
|
||||
DOMAIN_KEYS(EC);
|
||||
IMPLEMENT_TEST_SUITE(EC, "EC")
|
||||
IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
|
||||
IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
|
||||
DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
|
||||
IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC")
|
||||
|
@ -1101,7 +1232,9 @@ int setup_tests(void)
|
|||
if (ok) {
|
||||
#ifndef OPENSSL_NO_DH
|
||||
ADD_TEST_SUITE(DH);
|
||||
ADD_TEST_SUITE_PARAMS(DH);
|
||||
ADD_TEST_SUITE(DHX);
|
||||
ADD_TEST_SUITE_PARAMS(DHX);
|
||||
/*
|
||||
* DH has no support for PEM_write_bio_PrivateKey_traditional(),
|
||||
* so no legacy tests.
|
||||
|
@ -1109,6 +1242,7 @@ int setup_tests(void)
|
|||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
ADD_TEST_SUITE(DSA);
|
||||
ADD_TEST_SUITE_PARAMS(DSA);
|
||||
ADD_TEST_SUITE_LEGACY(DSA);
|
||||
ADD_TEST_SUITE_MSBLOB(DSA);
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
|
@ -1117,6 +1251,7 @@ int setup_tests(void)
|
|||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
ADD_TEST_SUITE(EC);
|
||||
ADD_TEST_SUITE_PARAMS(EC);
|
||||
ADD_TEST_SUITE_LEGACY(EC);
|
||||
ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
|
||||
ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue