1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-08 19:02:06 +03:00

pki_crypto: Support Ed25519 keys in PEM files

This adds support for Ed25519 keys from files in PEM format when using
OpenSSL with Ed25519 support.  The default encoding for the PEM file is
expected to be PKCS#8.  Encrypted files are supported.

For the lack of an API, it is not possible to export keys in PEM format,
only in OpenSSH format.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Anderson Toshiyuki Sasaki
2019-08-30 18:41:16 +02:00
parent 61e6b6cc59
commit a3a0529b41
3 changed files with 229 additions and 22 deletions

View File

@@ -602,7 +602,12 @@ static const char torture_ecdsa521_testkey_cert[] =
* ED25519 KEYS
****************************************************************************/
static const char torture_ed25519_private_testkey[] =
static const char torture_ed25519_private_pkcs8_testkey[] =
"-----BEGIN PRIVATE KEY-----\n"
"MC4CAQAwBQYDK2VwBCIEIGBhcqLe61tkqVjIHKEzwB3oINasSHWGbIWXQWcLPmGN\n"
"-----END PRIVATE KEY-----\n";
static const char torture_ed25519_private_openssh_testkey[] =
"-----BEGIN OPENSSH PRIVATE KEY-----\n"
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW\n"
"QyNTUxOQAAACAVlp8bgmIjsrzGC7ZIKBMhCpS1fpJTPgVOjYdz5gIqlwAAAJBzsDN1c7Az\n"
@@ -611,16 +616,24 @@ static const char torture_ed25519_private_testkey[] =
"lLV+klM+BU6Nh3PmAiqXAAAADGFyaXNAa2FsaXg4NgE=\n"
"-----END OPENSSH PRIVATE KEY-----\n";
static const char torture_ed25519_private_testkey_passphrase[] =
static const char torture_ed25519_private_openssh_testkey_passphrase[] =
"-----BEGIN OPENSSH PRIVATE KEY-----\n"
"b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABB3FWpQcE\n"
"KHKq6PcjkxjmKzAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIOGFVuOyZBL0T+NR\n"
"C7qEV9qr6QiGhz2XSXrxuQoU84FgAAAAkBlOVfS5U7FxtBEtxfxQhZjrZAj2z9d4OfGRPl\n"
"ZfCnAJNEM3BZ3XCabsujhMkqEs9eptRfj41X6NA8aSFs5JYT+JFVfg470FKtpyUmAibMIo\n"
"JzI41zAncFd1x7bAgO5HBDe3xNsV159D+sXRkWB9Tzk0l4F8SZvInheIS7VSbqH7t1+yDB\n"
"Y3GsmYTDstmicanQ==\n"
"b3BlbnNzaC1rZXktdjEAAAAACmFlczEyOC1jYmMAAAAGYmNyeXB0AAAAGAAAABDYuz+a8i\n"
"nb/BgGjQjQtvkUAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIBWWnxuCYiOyvMYL\n"
"tkgoEyEKlLV+klM+BU6Nh3PmAiqXAAAAkOBxqvzvPSns3TbhjkCayvANI66100OELnpDOm\n"
"JBGgXr5q846NkAovH3pmJ4O7qzPLTQ/cm0+959VUODRhM1i96qBg5MTNtV33lf5Y57Klzu\n"
"JegbiexcqkHIzriH42K0XSOEpfW8f/rTH7ffjbE/7l8HRNwf7AmcnxLx/d8J8FTBr+8aU7\n"
"qMU3xAJ4ixnwhYFg==\n"
"-----END OPENSSH PRIVATE KEY-----\n";
static const char torture_ed25519_private_pkcs8_testkey_passphrase[] =
"-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
"MIGbMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAie1RBk/ub+EwICCAAw\n"
"DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEECRLkPChQx/sZPYLdNJhxMUEQFLj\n"
"7nelAdOx3WXIBbCOfOqg3aAn8C5cXPtIQ+fiui1V8wlXXV8RBiuDCC97ScLs91D5\n"
"qQhQtw0vgfnq1um/izg=\n"
"-----END ENCRYPTED PRIVATE KEY-----\n";
static const char torture_ed25519_public_testkey[] =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBWWnxuCYiOyvMYLtkgoEyEKlLV+klM+"
"BU6Nh3PmAiqX aris@kalix86";
@@ -733,16 +746,19 @@ static const char *torture_get_testkey_internal(enum ssh_keytypes_e type,
return torture_ed25519_public_testkey;
} else if (with_passphrase) {
if (format == 1) {
return torture_ed25519_private_testkey_passphrase;
return torture_ed25519_private_openssh_testkey_passphrase;
}
if (format == 2) {
return torture_ed25519_private_pkcs8_testkey_passphrase;
}
/* ed25519 keys are not available in legacy PEM format */
return NULL;
}
if (format == 1) {
return torture_ed25519_private_testkey;
return torture_ed25519_private_openssh_testkey;
}
/* ed25519 keys are not available in legacy PEM format */
return NULL;
return torture_ed25519_private_pkcs8_testkey;
case SSH_KEYTYPE_DSS_CERT01:
return torture_dsa_testkey_cert;
case SSH_KEYTYPE_RSA_CERT01:

View File

@@ -643,14 +643,131 @@ static void torture_pki_ed25519_sign(void **state)
assert_non_null(blob);
assert_int_equal(ssh_string_len(blob), sizeof(ref_signature));
assert_memory_equal(ssh_string_data(blob), ref_signature, sizeof(ref_signature));
/* ssh_print_hexa("signature", ssh_string_data(blob), ssh_string_len(blob)); */
assert_memory_equal(ssh_string_data(blob), ref_signature,
sizeof(ref_signature));
ssh_signature_free(sig);
SSH_KEY_FREE(privkey);
SSH_STRING_FREE(blob);
}
static void torture_pki_ed25519_sign_openssh_privkey_passphrase(void **state)
{
ssh_key privkey = NULL;
ssh_signature sig = NULL;
ssh_string blob = NULL;
const char *keystring = NULL;
int rc;
/* Skip test if in FIPS mode */
if (ssh_fips_mode()) {
skip();
}
(void)state;
keystring = torture_get_openssh_testkey(SSH_KEYTYPE_ED25519, 1);
rc = ssh_pki_import_privkey_base64(keystring,
torture_get_testkey_passphrase(),
NULL,
NULL,
&privkey);
assert_true(rc == SSH_OK);
assert_non_null(privkey);
sig = pki_do_sign(privkey, HASH, sizeof(HASH), SSH_DIGEST_AUTO);
assert_non_null(sig);
blob = pki_signature_to_blob(sig);
assert_non_null(blob);
assert_int_equal(ssh_string_len(blob), sizeof(ref_signature));
assert_memory_equal(ssh_string_data(blob), ref_signature,
sizeof(ref_signature));
ssh_signature_free(sig);
SSH_KEY_FREE(privkey);
SSH_STRING_FREE(blob);
}
#ifdef HAVE_OPENSSL_ED25519
static void torture_pki_ed25519_sign_pkcs8_privkey(void **state)
{
ssh_key privkey = NULL;
ssh_signature sig = NULL;
ssh_string blob = NULL;
const char *keystring = NULL;
int rc;
/* Skip test if in FIPS mode */
if (ssh_fips_mode()) {
skip();
}
(void)state;
keystring = torture_get_testkey(SSH_KEYTYPE_ED25519, 0);
rc = ssh_pki_import_privkey_base64(keystring,
NULL,
NULL,
NULL,
&privkey);
assert_true(rc == SSH_OK);
assert_non_null(privkey);
sig = pki_do_sign(privkey, HASH, sizeof(HASH), SSH_DIGEST_AUTO);
assert_non_null(sig);
blob = pki_signature_to_blob(sig);
assert_non_null(blob);
assert_int_equal(ssh_string_len(blob), sizeof(ref_signature));
assert_memory_equal(ssh_string_data(blob), ref_signature,
sizeof(ref_signature));
ssh_signature_free(sig);
SSH_KEY_FREE(privkey);
SSH_STRING_FREE(blob);
}
static void torture_pki_ed25519_sign_pkcs8_privkey_passphrase(void **state)
{
ssh_key privkey = NULL;
ssh_signature sig = NULL;
ssh_string blob = NULL;
const char *keystring = NULL;
int rc;
/* Skip test if in FIPS mode */
if (ssh_fips_mode()) {
skip();
}
(void)state;
keystring = torture_get_testkey(SSH_KEYTYPE_ED25519, 1);
rc = ssh_pki_import_privkey_base64(keystring,
torture_get_testkey_passphrase(),
NULL,
NULL,
&privkey);
assert_true(rc == SSH_OK);
assert_non_null(privkey);
sig = pki_do_sign(privkey, HASH, sizeof(HASH), SSH_DIGEST_AUTO);
assert_non_null(sig);
blob = pki_signature_to_blob(sig);
assert_non_null(blob);
assert_int_equal(ssh_string_len(blob), sizeof(ref_signature));
assert_memory_equal(ssh_string_data(blob), ref_signature,
sizeof(ref_signature));
ssh_signature_free(sig);
SSH_KEY_FREE(privkey);
SSH_STRING_FREE(blob);
}
#endif /* HAVE_OPENSSL_ED25519 */
static void torture_pki_ed25519_verify(void **state){
ssh_key pubkey = NULL;
ssh_signature sig = NULL;
@@ -895,6 +1012,11 @@ int torture_run_tests(void) {
teardown),
cmocka_unit_test(torture_pki_ed25519_import_privkey_base64_passphrase),
cmocka_unit_test(torture_pki_ed25519_sign),
cmocka_unit_test(torture_pki_ed25519_sign_openssh_privkey_passphrase),
#ifdef HAVE_OPENSSL_ED25519
cmocka_unit_test(torture_pki_ed25519_sign_pkcs8_privkey),
cmocka_unit_test(torture_pki_ed25519_sign_pkcs8_privkey_passphrase),
#endif
cmocka_unit_test(torture_pki_ed25519_verify),
cmocka_unit_test(torture_pki_ed25519_verify_bad),
cmocka_unit_test(torture_pki_ed25519_privkey_dup),