From 82da0c3361b18f804f1e2b0d99fae862bb5dcb6e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 6 Aug 2018 13:40:32 +0200 Subject: [PATCH] auth: Support SHA2 extension for pubkey authentication (RFC 8332) Signed-off-by: Jakub Jelen Reviewed-by: Andreas Schneider --- include/libssh/pki.h | 4 ++++ src/auth.c | 14 +++++++++----- src/pki.c | 24 ++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/include/libssh/pki.h b/include/libssh/pki.h index 558680d7..0a3823f3 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -96,6 +96,10 @@ typedef struct ssh_signature_struct *ssh_signature; ssh_key ssh_key_dup(const ssh_key key); void ssh_key_clean (ssh_key key); +const char * +ssh_key_get_signature_algorithm(ssh_session session, + enum ssh_keytypes_e type); + /* SSH Signature Functions */ ssh_signature ssh_signature_new(void); void ssh_signature_free(ssh_signature sign); diff --git a/src/auth.c b/src/auth.c index 9cd80c43..a491cf69 100644 --- a/src/auth.c +++ b/src/auth.c @@ -470,6 +470,7 @@ int ssh_userauth_try_publickey(ssh_session session, const ssh_key pubkey) { ssh_string pubkey_s = NULL; + const char *sig_type_c = NULL; int rc; if (session == NULL) { @@ -506,6 +507,7 @@ int ssh_userauth_try_publickey(ssh_session session, if (rc < 0) { goto fail; } + sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type); /* request */ rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", @@ -514,7 +516,7 @@ int ssh_userauth_try_publickey(ssh_session session, "ssh-connection", "publickey", 0, /* private key ? */ - pubkey->type_c, /* algo */ + sig_type_c, /* algo */ pubkey_s /* public key */ ); if (rc < 0) { @@ -575,7 +577,7 @@ int ssh_userauth_publickey(ssh_session session, { ssh_string str = NULL; int rc; - const char *type_c; + const char *sig_type_c; enum ssh_keytypes_e key_type; if (session == NULL) { @@ -608,7 +610,7 @@ int ssh_userauth_publickey(ssh_session session, /* Cert auth requires presenting the cert type name (*-cert@openssh.com) */ key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type; - type_c = ssh_key_type_to_char(key_type); + sig_type_c = ssh_key_get_signature_algorithm(session, key_type); /* get public key or cert */ rc = ssh_pki_export_pubkey_blob(privkey, &str); @@ -623,7 +625,7 @@ int ssh_userauth_publickey(ssh_session session, "ssh-connection", "publickey", 1, /* private key */ - type_c, /* algo */ + sig_type_c, /* algo */ str /* public key or cert */ ); if (rc < 0) { @@ -673,6 +675,7 @@ static int ssh_userauth_agent_publickey(ssh_session session, ssh_key pubkey) { ssh_string str = NULL; + const char *sig_type_c = NULL; int rc; switch(session->pending_call_state) { @@ -700,6 +703,7 @@ static int ssh_userauth_agent_publickey(ssh_session session, if (rc < 0) { goto fail; } + sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type); /* request */ rc = ssh_buffer_pack(session->out_buffer, "bsssbsS", @@ -708,7 +712,7 @@ static int ssh_userauth_agent_publickey(ssh_session session, "ssh-connection", "publickey", 1, /* private key */ - pubkey->type_c, /* algo */ + sig_type_c, /* algo */ str /* public key */ ); if (rc < 0) { diff --git a/src/pki.c b/src/pki.c index 5106aec5..d894762c 100644 --- a/src/pki.c +++ b/src/pki.c @@ -282,8 +282,8 @@ static enum ssh_digest_e ssh_key_hash_from_name(const char *name) * * @return A hash type to be used. */ -static enum ssh_keytypes_e ssh_key_type_to_hash(ssh_session session, - enum ssh_keytypes_e type) +static enum ssh_digest_e ssh_key_type_to_hash(ssh_session session, + enum ssh_keytypes_e type) { /* TODO this should also reflect supported key types specified in * configuration (ssh_config PubkeyAcceptedKeyTypes) */ @@ -309,6 +309,26 @@ static enum ssh_keytypes_e ssh_key_type_to_hash(ssh_session session, return SSH_DIGEST_AUTO; } +/** + * @brief Gets signature algorithm name to be used with the given + * key type. + * + * @param[in] session SSH session. + * @param[in] type The algorithm type to convert. + * + * @return A string for the keytype or NULL if unknown. + */ +const char * +ssh_key_get_signature_algorithm(ssh_session session, + enum ssh_keytypes_e type) +{ + enum ssh_digest_e hash_type; + + hash_type = ssh_key_type_to_hash(session, type); + + return ssh_key_signature_to_char(type, hash_type); +} + /** * @brief Convert a ssh key algorithm name to a ssh key algorithm type. *