diff options
-rw-r--r-- | include/libssh/libssh.h | 4 | ||||
-rw-r--r-- | include/libssh/pki.h | 6 | ||||
-rw-r--r-- | src/pki.c | 159 | ||||
-rw-r--r-- | src/pki_crypto.c | 24 | ||||
-rw-r--r-- | src/pki_gcrypt.c | 36 | ||||
-rw-r--r-- | src/pki_mbedcrypto.c | 25 | ||||
-rw-r--r-- | tests/torture_key.c | 4 |
7 files changed, 245 insertions, 13 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index a0c9600c..d1ddffdc 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -304,6 +304,10 @@ enum ssh_keytypes_e{ SSH_KEYTYPE_ECDSA_P384_CERT01, SSH_KEYTYPE_ECDSA_P521_CERT01, SSH_KEYTYPE_ED25519_CERT01, + SSH_KEYTYPE_SK_ECDSA, + SSH_KEYTYPE_SK_ECDSA_CERT01, + SSH_KEYTYPE_SK_ED25519, + SSH_KEYTYPE_SK_ED25519_CERT01, }; enum ssh_keycmp_e { diff --git a/include/libssh/pki.h b/include/libssh/pki.h index ec0ce9af..0f8cae47 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -21,6 +21,7 @@ #ifndef PKI_H_ #define PKI_H_ +#include <stdint.h> #include "libssh/priv.h" #ifdef HAVE_OPENSSL_EC_H #include <openssl/ec.h> @@ -80,6 +81,7 @@ struct ssh_key_struct { ed25519_pubkey *ed25519_pubkey; ed25519_privkey *ed25519_privkey; #endif + ssh_string sk_application; void *cert; enum ssh_keytypes_e cert_type; }; @@ -100,6 +102,10 @@ struct ssh_signature_struct { ed25519_signature *ed25519_sig; #endif ssh_string raw_sig; + + /* Security Key specific additions */ + uint8_t sk_flags; + uint32_t sk_counter; }; typedef struct ssh_signature_struct *ssh_signature; @@ -33,9 +33,11 @@ */ #include "config.h" +#include "libssh/wrapper.h" #include <errno.h> #include <ctype.h> +#include <stdint.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> @@ -179,6 +181,13 @@ void ssh_key_clean (ssh_key key){ if (key->cert != NULL) { SSH_BUFFER_FREE(key->cert); } + if (key->type == SSH_KEYTYPE_SK_ECDSA || + key->type == SSH_KEYTYPE_SK_ED25519 || + key->type == SSH_KEYTYPE_SK_ECDSA_CERT01 || + key->type == SSH_KEYTYPE_SK_ED25519_CERT01) { + ssh_string_burn(key->sk_application); + ssh_string_free(key->sk_application); + } key->cert_type = SSH_KEYTYPE_UNKNOWN; key->flags=SSH_KEY_FLAG_EMPTY; key->type=SSH_KEYTYPE_UNKNOWN; @@ -299,6 +308,14 @@ const char *ssh_key_type_to_char(enum ssh_keytypes_e type) { return "ecdsa-sha2-nistp521-cert-v01@openssh.com"; case SSH_KEYTYPE_ED25519_CERT01: return "ssh-ed25519-cert-v01@openssh.com"; + case SSH_KEYTYPE_SK_ECDSA: + return "sk-ecdsa-sha2-nistp256@openssh.com"; + case SSH_KEYTYPE_SK_ED25519: + return "sk-ssh-ed25519@openssh.com"; + case SSH_KEYTYPE_SK_ECDSA_CERT01: + return "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"; + case SSH_KEYTYPE_SK_ED25519_CERT01: + return "sk-ssh-ed25519-cert-v01@openssh.com"; case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_UNKNOWN: return NULL; @@ -331,6 +348,10 @@ enum ssh_digest_e ssh_key_hash_from_name(const char *name) return SSH_DIGEST_SHA512; } else if (strcmp(name, "ssh-ed25519") == 0) { return SSH_DIGEST_AUTO; + } else if (strcmp(name, "sk-ecdsa-sha2-nistp256@openssh.com") == 0) { + return SSH_DIGEST_SHA256; + } else if (strcmp(name, "sk-ssh-ed25519@openssh.com") == 0) { + return SSH_DIGEST_AUTO; } SSH_LOG(SSH_LOG_WARN, "Unknown signature name %s", name); @@ -547,6 +568,14 @@ enum ssh_keytypes_e ssh_key_type_from_name(const char *name) { return SSH_KEYTYPE_ECDSA_P521_CERT01; } else if (strcmp(name, "ssh-ed25519-cert-v01@openssh.com") == 0) { return SSH_KEYTYPE_ED25519_CERT01; + } else if(strcmp(name, "sk-ecdsa-sha2-nistp256@openssh.com") == 0) { + return SSH_KEYTYPE_SK_ECDSA; + } else if(strcmp(name, "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0) { + return SSH_KEYTYPE_SK_ECDSA_CERT01; + } else if(strcmp(name, "sk-ssh-ed25519@openssh.com") == 0) { + return SSH_KEYTYPE_SK_ED25519; + } else if(strcmp(name, "sk-ssh-ed25519-cert-v01@openssh.com") == 0) { + return SSH_KEYTYPE_SK_ED25519_CERT01; } return SSH_KEYTYPE_UNKNOWN; @@ -573,6 +602,10 @@ enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type) { return SSH_KEYTYPE_ECDSA_P521; case SSH_KEYTYPE_ED25519_CERT01: return SSH_KEYTYPE_ED25519; + case SSH_KEYTYPE_SK_ECDSA_CERT01: + return SSH_KEYTYPE_SK_ECDSA; + case SSH_KEYTYPE_SK_ED25519_CERT01: + return SSH_KEYTYPE_SK_ED25519; default: return type; } @@ -639,7 +672,17 @@ int ssh_key_cmp(const ssh_key k1, } } - if (k1->type == SSH_KEYTYPE_ED25519) { + if (k1->type == SSH_KEYTYPE_SK_ECDSA || + k1->type == SSH_KEYTYPE_SK_ED25519) { + if (strncmp(ssh_string_get_char(k1->sk_application), + ssh_string_get_char(k2->sk_application), + ssh_string_len(k2->sk_application)) != 0) { + return 1; + } + } + + if (k1->type == SSH_KEYTYPE_ED25519 || + k1->type == SSH_KEYTYPE_SK_ED25519) { return pki_ed25519_key_cmp(k1, k2, what); } @@ -681,6 +724,7 @@ void ssh_signature_free(ssh_signature sig) case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: #ifdef HAVE_GCRYPT_ECC gcry_sexp_release(sig->ecdsa_sig); #elif defined HAVE_LIBMBEDCRYPTO @@ -689,6 +733,7 @@ void ssh_signature_free(ssh_signature sig) #endif break; case SSH_KEYTYPE_ED25519: + case SSH_KEYTYPE_SK_ED25519: #ifndef HAVE_OPENSSL_ED25519 /* When using OpenSSL, the signature is stored in sig->raw_sig */ SAFE_FREE(sig->ed25519_sig); @@ -700,6 +745,8 @@ void ssh_signature_free(ssh_signature sig) case SSH_KEYTYPE_ECDSA_P384_CERT01: case SSH_KEYTYPE_ECDSA_P521_CERT01: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ECDSA_CERT01: + case SSH_KEYTYPE_SK_ED25519_CERT01: case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_ECDSA: case SSH_KEYTYPE_UNKNOWN: @@ -1211,6 +1258,10 @@ int pki_import_privkey_buffer(enum ssh_keytypes_e type, case SSH_KEYTYPE_ECDSA_P384_CERT01: case SSH_KEYTYPE_ECDSA_P521_CERT01: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ECDSA: + case SSH_KEYTYPE_SK_ECDSA_CERT01: + case SSH_KEYTYPE_SK_ED25519: + case SSH_KEYTYPE_SK_ED25519_CERT01: case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_UNKNOWN: default: @@ -1306,6 +1357,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: { ssh_string e = NULL; ssh_string i = NULL; @@ -1335,12 +1387,25 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, if (type == SSH_KEYTYPE_ECDSA) { key->type_c = ssh_pki_key_ecdsa_name(key); } + + /* Unpack SK specific parameters */ + if (type == SSH_KEYTYPE_SK_ECDSA) { + ssh_string application = ssh_buffer_get_ssh_string(buffer); + if (application == NULL) { + SSH_LOG(SSH_LOG_WARN, "SK Unpack error"); + goto fail; + } + key->sk_application = application; + key->type_c = ssh_key_type_to_char(key->type); + } } break; #endif case SSH_KEYTYPE_ED25519: + case SSH_KEYTYPE_SK_ED25519: { ssh_string pubkey = ssh_buffer_get_ssh_string(buffer); + if (ssh_string_len(pubkey) != ED25519_KEY_LEN) { SSH_LOG(SSH_LOG_WARN, "Invalid public key length"); ssh_string_burn(pubkey); @@ -1358,6 +1423,15 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_KEY_LEN); ssh_string_burn(pubkey); SSH_STRING_FREE(pubkey); + + if (type == SSH_KEYTYPE_SK_ED25519) { + ssh_string application = ssh_buffer_get_ssh_string(buffer); + if (application == NULL) { + SSH_LOG(SSH_LOG_WARN, "SK Unpack error"); + goto fail; + } + key->sk_application = application; + } } break; case SSH_KEYTYPE_DSS_CERT01: @@ -1365,7 +1439,9 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer, case SSH_KEYTYPE_ECDSA_P256_CERT01: case SSH_KEYTYPE_ECDSA_P384_CERT01: case SSH_KEYTYPE_ECDSA_P521_CERT01: + case SSH_KEYTYPE_SK_ECDSA_CERT01: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ED25519_CERT01: case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_UNKNOWN: default: @@ -1443,6 +1519,12 @@ static int pki_import_cert_buffer(ssh_buffer buffer, case SSH_KEYTYPE_ED25519_CERT01: rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_ED25519, &key); break; + case SSH_KEYTYPE_SK_ECDSA_CERT01: + rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_SK_ECDSA, &key); + break; + case SSH_KEYTYPE_SK_ED25519_CERT01: + rc = pki_import_pubkey_buffer(buffer, SSH_KEYTYPE_SK_ED25519, &key); + break; default: key = ssh_key_new(); } @@ -1878,6 +1960,10 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter, case SSH_KEYTYPE_ECDSA_P384_CERT01: case SSH_KEYTYPE_ECDSA_P521_CERT01: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ECDSA: + case SSH_KEYTYPE_SK_ECDSA_CERT01: + case SSH_KEYTYPE_SK_ED25519: + case SSH_KEYTYPE_SK_ED25519_CERT01: case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_UNKNOWN: default: @@ -2162,6 +2248,8 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob, ssh_string algorithm = NULL, blob = NULL; ssh_buffer buf; const char *alg = NULL; + uint8_t flags = 0; + uint32_t counter = 0; int rc; if (sig_blob == NULL || psig == NULL) { @@ -2193,17 +2281,31 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob, SSH_STRING_FREE(algorithm); blob = ssh_buffer_get_ssh_string(buf); - SSH_BUFFER_FREE(buf); if (blob == NULL) { + SSH_BUFFER_FREE(buf); return SSH_ERROR; } + if (type == SSH_KEYTYPE_SK_ECDSA || + type == SSH_KEYTYPE_SK_ED25519) { + rc = ssh_buffer_unpack(buf, "bd", &flags, &counter); + if (rc < 0) { + SSH_BUFFER_FREE(buf); + return SSH_ERROR; + } + } + SSH_BUFFER_FREE(buf); + sig = pki_signature_from_blob(pubkey, blob, type, hash_type); SSH_STRING_FREE(blob); if (sig == NULL) { return SSH_ERROR; } + /* Set SK specific values */ + sig->sk_flags = flags; + sig->sk_counter = counter; + *psig = sig; return SSH_OK; } @@ -2259,6 +2361,8 @@ int pki_key_check_hash_compatible(ssh_key key, break; case SSH_KEYTYPE_ECDSA_P256_CERT01: case SSH_KEYTYPE_ECDSA_P256: + case SSH_KEYTYPE_SK_ECDSA_CERT01: + case SSH_KEYTYPE_SK_ECDSA: if (hash_type == SSH_DIGEST_SHA256) { return SSH_OK; } @@ -2277,6 +2381,8 @@ int pki_key_check_hash_compatible(ssh_key key, break; case SSH_KEYTYPE_ED25519_CERT01: case SSH_KEYTYPE_ED25519: + case SSH_KEYTYPE_SK_ED25519_CERT01: + case SSH_KEYTYPE_SK_ED25519: if (hash_type == SSH_DIGEST_AUTO) { return SSH_OK; } @@ -2327,9 +2433,54 @@ int ssh_pki_signature_verify(ssh_session session, return SSH_ERROR; } - rc = pki_verify_data_signature(sig, key, input, input_len); + if (key->type == SSH_KEYTYPE_SK_ECDSA || + key->type == SSH_KEYTYPE_SK_ECDSA_CERT01 || + key->type == SSH_KEYTYPE_SK_ED25519 || + key->type == SSH_KEYTYPE_SK_ED25519_CERT01) { - return rc; + ssh_buffer sk_buffer = NULL; + SHA256CTX ctx = NULL; + unsigned char application_hash[SHA256_DIGEST_LEN] = {0}; + unsigned char input_hash[SHA256_DIGEST_LEN] = {0}; + + if ((ctx = sha256_init())== NULL) { + SSH_LOG(SSH_LOG_WARN, + "Can not create SHA256CTX for application hash"); + return SSH_ERROR; + } + sha256_update(ctx, ssh_string_data(key->sk_application), + ssh_string_len(key->sk_application)); + sha256_final(application_hash, ctx); + + if ((ctx = sha256_init())== NULL) { + SSH_LOG(SSH_LOG_WARN, + "Can not create SHA256CTX for input hash"); + return SSH_ERROR; + } + sha256_update(ctx, input, input_len); + sha256_final(input_hash, ctx); + + sk_buffer = ssh_buffer_new(); + if (sk_buffer == NULL) { + return SSH_ERROR; + } + + ssh_buffer_pack(sk_buffer, "PbdP", + SHA256_DIGEST_LEN, application_hash, + sig->sk_flags, sig->sk_counter, + SHA256_DIGEST_LEN, input_hash); + + rc = pki_verify_data_signature(sig, key, ssh_buffer_get(sk_buffer), + ssh_buffer_get_len(sk_buffer)); + + ssh_buffer_free(sk_buffer); + explicit_bzero(input_hash, SHA256_DIGEST_LEN); + explicit_bzero(application_hash, SHA256_DIGEST_LEN); + + return rc; + } + + return pki_verify_data_signature(sig, key, input, input_len); } ssh_signature pki_do_sign(const ssh_key privkey, diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 3fd4f2a6..9ac4d99f 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -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); } diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c index ac17e105..62ec8ea7 100644 --- a/src/pki_gcrypt.c +++ b/src/pki_gcrypt.c @@ -1506,11 +1506,13 @@ int pki_key_compare(const ssh_key k1, } break; case SSH_KEYTYPE_ED25519: + case SSH_KEYTYPE_SK_ED25519: /* ed25519 keys handled globaly */ return 0; case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: #ifdef HAVE_GCRYPT_ECC if (k1->ecdsa_nid != k2->ecdsa_nid) { return 1; @@ -1533,7 +1535,9 @@ int pki_key_compare(const ssh_key k1, case SSH_KEYTYPE_ECDSA_P256_CERT01: case SSH_KEYTYPE_ECDSA_P384_CERT01: case SSH_KEYTYPE_ECDSA_P521_CERT01: + case SSH_KEYTYPE_SK_ECDSA_CERT01: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ED25519_CERT01: case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_UNKNOWN: return 1; @@ -1675,14 +1679,20 @@ ssh_string pki_publickey_to_blob(const ssh_key key) break; case SSH_KEYTYPE_ED25519: - rc = pki_ed25519_public_key_to_blob(buffer, key); - if (rc != SSH_OK){ - goto fail; - } - break; + case SSH_KEYTYPE_SK_ED25519: + rc = pki_ed25519_public_key_to_blob(buffer, key); + if (rc != SSH_OK){ + 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_GCRYPT_ECC type_s = ssh_string_from_char( pki_key_ecdsa_nid_to_char(key->ecdsa_nid)); @@ -1713,6 +1723,12 @@ ssh_string pki_publickey_to_blob(const ssh_key key) ssh_string_burn(e); 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_RSA1: @@ -1996,6 +2012,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){ ssh_signature_free(sig); @@ -2005,6 +2022,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: #ifdef HAVE_GCRYPT_ECC { /* build ecdsa siganature */ ssh_buffer b; @@ -2347,7 +2365,9 @@ int pki_verify_data_signature(ssh_signature signature, break; case SSH_DIGEST_AUTO: 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) { verify_input = input; hlen = input_len; @@ -2416,6 +2436,8 @@ int pki_verify_data_signature(ssh_signature signature, 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_GCRYPT_ECC err = gcry_sexp_build(&sexp, NULL, @@ -2443,6 +2465,8 @@ int pki_verify_data_signature(ssh_signature signature, #endif case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ED25519: + case SSH_KEYTYPE_SK_ED25519_CERT01: rc = pki_ed25519_verify(pubkey, signature, verify_input, hlen); if (rc != SSH_OK) { SSH_LOG(SSH_LOG_TRACE, "ED25519 error: Signature invalid"); diff --git a/src/pki_mbedcrypto.c b/src/pki_mbedcrypto.c index e82d2ff9..cac357f8 100644 --- a/src/pki_mbedcrypto.c +++ b/src/pki_mbedcrypto.c @@ -543,7 +543,8 @@ int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what) } case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: - case SSH_KEYTYPE_ECDSA_P521: { + case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: { mbedtls_ecp_keypair *ecdsa1 = k1->ecdsa; mbedtls_ecp_keypair *ecdsa2 = k2->ecdsa; @@ -572,6 +573,7 @@ int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what) break; } case SSH_KEYTYPE_ED25519: + case SSH_KEYTYPE_SK_ED25519: /* ed25519 keys handled globally */ return 0; default: @@ -713,6 +715,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: type_s = ssh_string_from_char(pki_key_ecdsa_nid_to_char(key->ecdsa_nid)); if (type_s == NULL) { @@ -743,12 +746,22 @@ 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; case SSH_KEYTYPE_ED25519: + case SSH_KEYTYPE_SK_ED25519: rc = pki_ed25519_public_key_to_blob(buffer, key); if (rc != SSH_OK) { goto fail; } + if (key->type == SSH_KEYTYPE_SK_ED25519 && + ssh_buffer_add_ssh_string(buffer, key->sk_application) < 0) { + goto fail; + } break; default: goto fail; @@ -939,7 +952,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, break; case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: - case SSH_KEYTYPE_ECDSA_P521: { + case SSH_KEYTYPE_ECDSA_P521: + case SSH_KEYTYPE_SK_ECDSA: { ssh_buffer b; ssh_string r; ssh_string s; @@ -1008,6 +1022,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_ERROR) { ssh_signature_free(sig); @@ -1291,6 +1306,8 @@ int pki_verify_data_signature(ssh_signature signature, break; case SSH_DIGEST_AUTO: if (pubkey->type == SSH_KEYTYPE_ED25519 || + pubkey->type == SSH_KEYTYPE_ED25519_CERT01 || + pubkey->type == SSH_KEYTYPE_SK_ED25519 || pubkey->type == SSH_KEYTYPE_ED25519_CERT01) { verify_input = input; @@ -1323,6 +1340,8 @@ int pki_verify_data_signature(ssh_signature signature, 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: rc = mbedtls_ecdsa_verify(&pubkey->ecdsa->grp, hash, hlen, &pubkey->ecdsa->Q, signature->ecdsa_sig.r, signature->ecdsa_sig.s); @@ -1336,6 +1355,8 @@ int pki_verify_data_signature(ssh_signature signature, break; case SSH_KEYTYPE_ED25519: case SSH_KEYTYPE_ED25519_CERT01: + case SSH_KEYTYPE_SK_ED25519: + case SSH_KEYTYPE_SK_ED25519_CERT01: rc = pki_ed25519_verify(pubkey, signature, verify_input, hlen); if (rc != SSH_OK) { SSH_LOG(SSH_LOG_TRACE, "ED25519 error: Signature invalid"); diff --git a/tests/torture_key.c b/tests/torture_key.c index e8b7d561..c4fb08ea 100644 --- a/tests/torture_key.c +++ b/tests/torture_key.c @@ -822,6 +822,10 @@ static const char *torture_get_testkey_internal(enum ssh_keytypes_e type, return torture_ed25519_testkey_cert; case SSH_KEYTYPE_RSA1: case SSH_KEYTYPE_ECDSA: + case SSH_KEYTYPE_SK_ECDSA: + case SSH_KEYTYPE_SK_ECDSA_CERT01: + case SSH_KEYTYPE_SK_ED25519: + case SSH_KEYTYPE_SK_ED25519_CERT01: case SSH_KEYTYPE_UNKNOWN: return NULL; } |