pki: add support for sk-ecdsa and sk-ed25519

This adds server-side support for the newly introduced OpenSSH
keytypes sk-ecdsa-sha2-nistp256@openssh.com and sk-ed25519@openssh.com
(including their corresponding certificates), which are backed
by U2F/FIDO2 tokens.

Change-Id: Ib73425c572601c3002be45974e6ea051f1d7efdc
Signed-off-by: Sebastian Kinne <skinne@google.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Sebastian Kinne
2019-12-16 17:57:18 -08:00
committed by Jakub Jelen
parent 3664ba2800
commit 17b518a677
7 changed files with 245 additions and 13 deletions

View File

@@ -682,6 +682,7 @@ int pki_key_compare(const ssh_key k1,
case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521:
case SSH_KEYTYPE_SK_ECDSA:
#ifdef HAVE_OPENSSL_ECC
{
const EC_POINT *p1 = EC_KEY_get0_public_key(k1->ecdsa);
@@ -712,6 +713,7 @@ int pki_key_compare(const ssh_key k1,
}
#endif
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_SK_ED25519:
/* ed25519 keys handled globaly */
case SSH_KEYTYPE_UNKNOWN:
default:
@@ -1300,14 +1302,20 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
break;
}
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_SK_ED25519:
rc = pki_ed25519_public_key_to_blob(buffer, key);
if (rc == SSH_ERROR){
goto fail;
}
if (key->type == SSH_KEYTYPE_SK_ED25519 &&
ssh_buffer_add_ssh_string(buffer, key->sk_application) < 0) {
goto fail;
}
break;
case SSH_KEYTYPE_ECDSA_P256:
case SSH_KEYTYPE_ECDSA_P384:
case SSH_KEYTYPE_ECDSA_P521:
case SSH_KEYTYPE_SK_ECDSA:
#ifdef HAVE_OPENSSL_ECC
type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid));
if (type_s == NULL) {
@@ -1338,6 +1346,11 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
SSH_STRING_FREE(e);
e = NULL;
if (key->type == SSH_KEYTYPE_SK_ECDSA &&
ssh_buffer_add_ssh_string(buffer, key->sk_application) < 0) {
goto fail;
}
break;
#endif
case SSH_KEYTYPE_UNKNOWN:
@@ -1937,6 +1950,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
}
break;
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_SK_ED25519:
rc = pki_signature_from_ed25519_blob(sig, sig_blob);
if (rc != SSH_OK){
goto error;
@@ -1948,6 +1962,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
case SSH_KEYTYPE_ECDSA_P256_CERT01:
case SSH_KEYTYPE_ECDSA_P384_CERT01:
case SSH_KEYTYPE_ECDSA_P521_CERT01:
case SSH_KEYTYPE_SK_ECDSA:
case SSH_KEYTYPE_SK_ECDSA_CERT01:
#ifdef HAVE_OPENSSL_ECC
rc = pki_signature_from_ecdsa_blob(pubkey, sig_blob, sig);
if (rc != SSH_OK) {
@@ -2044,6 +2060,8 @@ static EVP_PKEY *pki_key_to_pkey(ssh_key key)
case SSH_KEYTYPE_ECDSA_P256_CERT01:
case SSH_KEYTYPE_ECDSA_P384_CERT01:
case SSH_KEYTYPE_ECDSA_P521_CERT01:
case SSH_KEYTYPE_SK_ECDSA:
case SSH_KEYTYPE_SK_ECDSA_CERT01:
# if defined(HAVE_OPENSSL_ECC)
if (key->ecdsa == NULL) {
SSH_LOG(SSH_LOG_TRACE, "NULL key->ecdsa");
@@ -2060,6 +2078,8 @@ static EVP_PKEY *pki_key_to_pkey(ssh_key key)
# endif
case SSH_KEYTYPE_ED25519:
case SSH_KEYTYPE_ED25519_CERT01:
case SSH_KEYTYPE_SK_ED25519:
case SSH_KEYTYPE_SK_ED25519_CERT01:
# if defined(HAVE_OPENSSL_ED25519)
if (ssh_key_is_private(key)) {
if (key->ed25519_privkey == NULL) {
@@ -2306,7 +2326,9 @@ int pki_verify_data_signature(ssh_signature signature,
#ifndef HAVE_OPENSSL_ED25519
if (pubkey->type == SSH_KEYTYPE_ED25519 ||
pubkey->type == SSH_KEYTYPE_ED25519_CERT01)
pubkey->type == SSH_KEYTYPE_ED25519_CERT01 ||
pubkey->type == SSH_KEYTYPE_SK_ED25519 ||
pubkey->type == SSH_KEYTYPE_SK_ED25519_CERT01)
{
return pki_ed25519_verify(pubkey, signature, input, input_len);
}