From c573adced41dc195b6ec5369b2ec0cdc67581e08 Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Tue, 30 Nov 2021 16:35:15 +0000 Subject: [PATCH] server: reply with PK_OK with correct algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC 4252 §7 states that the public key algorithm in a SSH_MSG_USERAUTH_PK_OK response is the public key algorithm name from the request. When using RSA with SHA-2, this will be either "rsa-sha2-256" or "rsa-sha2-512" as specified by RFC 8332 §3.2. However, currently libssh emits the public key type instead, which is "ssh-rsa". This is not in conformance with the RFCs, so let's fix this by storing the signature type and emitting it in our response instead of the public key when sending SSH_MSG_USERAUTH_PK_OK in the server. Signed-off-by: brian m. carlson Reviewed-by: Jakub Jelen --- include/libssh/messages.h | 1 + src/messages.c | 9 +++++++++ src/server.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/libssh/messages.h b/include/libssh/messages.h index 04d041d4..1341d708 100644 --- a/include/libssh/messages.h +++ b/include/libssh/messages.h @@ -28,6 +28,7 @@ struct ssh_auth_request { int method; char *password; struct ssh_key_struct *pubkey; + char *sigtype; enum ssh_publickey_state_e signature_state; char kbdint_response; }; diff --git a/src/messages.c b/src/messages.c index a772d488..c09a841c 100644 --- a/src/messages.c +++ b/src/messages.c @@ -593,6 +593,7 @@ void ssh_message_free(ssh_message msg){ switch(msg->type) { case SSH_REQUEST_AUTH: SAFE_FREE(msg->auth_request.username); + SAFE_FREE(msg->auth_request.sigtype); if (msg->auth_request.password) { explicit_bzero(msg->auth_request.password, strlen(msg->auth_request.password)); @@ -852,6 +853,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ goto error; } msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_NONE; + msg->auth_request.sigtype = strdup(ssh_string_get_char(algo)); + if (msg->auth_request.sigtype == NULL) { + msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR; + SSH_STRING_FREE(algo); + algo = NULL; + goto error; + } + // has a valid signature ? if(has_sign) { ssh_string sig_blob = NULL; diff --git a/src/server.c b/src/server.c index 841a1c42..c9c17ec5 100644 --- a/src/server.c +++ b/src/server.c @@ -1025,7 +1025,7 @@ int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) { ssh_string pubkey_blob = NULL; int ret; - algo = ssh_string_from_char(msg->auth_request.pubkey->type_c); + algo = ssh_string_from_char(msg->auth_request.sigtype); if (algo == NULL) { return SSH_ERROR; }