diff --git a/include/libssh/keys.h b/include/libssh/keys.h index e6354a93..e025b240 100644 --- a/include/libssh/keys.h +++ b/include/libssh/keys.h @@ -62,7 +62,6 @@ typedef struct signature_struct { const char *ssh_type_to_char(int type); int ssh_type_from_name(const char *name); -ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, char *service); ssh_private_key privatekey_make_dss(ssh_session session, ssh_buffer buffer); ssh_private_key privatekey_make_rsa(ssh_session session, ssh_buffer buffer, diff --git a/src/keys.c b/src/keys.c index 86c4a573..f4e8e2ca 100644 --- a/src/keys.c +++ b/src/keys.c @@ -379,70 +379,6 @@ ssh_string ssh_do_sign_with_agent(ssh_session session, } #endif /* _WIN32 */ -/* - * This function concats in a buffer the values needed to do a signature - * verification. */ -ssh_buffer ssh_userauth_build_digest(ssh_session session, ssh_message msg, char *service) { -/* - The value of 'signature' is a signature by the corresponding private - key over the following data, in the following order: - - string session identifier - byte SSH_MSG_USERAUTH_REQUEST - string user name - string service name - string "publickey" - boolean TRUE - string public key algorithm name - string public key to be used for authentication -*/ - struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : - session->next_crypto; - ssh_buffer buffer = NULL; - ssh_string session_id = NULL; - uint8_t type = SSH2_MSG_USERAUTH_REQUEST; - ssh_string username = ssh_string_from_char(msg->auth_request.username); - ssh_string servicename = ssh_string_from_char(service); - ssh_string method = ssh_string_from_char("publickey"); - uint8_t has_sign = 1; - ssh_string algo = ssh_string_from_char(msg->auth_request.public_key->type_c); - ssh_string publickey = publickey_to_string(msg->auth_request.public_key); - - buffer = ssh_buffer_new(); - if (buffer == NULL) { - goto error; - } - session_id = ssh_string_new(SHA_DIGEST_LEN); - if (session_id == NULL) { - ssh_buffer_free(buffer); - buffer = NULL; - goto error; - } - ssh_string_fill(session_id, crypto->session_id, SHA_DIGEST_LEN); - - if(buffer_add_ssh_string(buffer, session_id) < 0 || - buffer_add_u8(buffer, type) < 0 || - buffer_add_ssh_string(buffer, username) < 0 || - buffer_add_ssh_string(buffer, servicename) < 0 || - buffer_add_ssh_string(buffer, method) < 0 || - buffer_add_u8(buffer, has_sign) < 0 || - buffer_add_ssh_string(buffer, algo) < 0 || - buffer_add_ssh_string(buffer, publickey) < 0) { - ssh_buffer_free(buffer); - buffer = NULL; - goto error; - } - -error: - if(session_id) ssh_string_free(session_id); - if(username) ssh_string_free(username); - if(servicename) ssh_string_free(servicename); - if(method) ssh_string_free(method); - if(algo) ssh_string_free(algo); - if(publickey) ssh_string_free(publickey); - return buffer; -} - /* * This function signs the session id (known as H) as a string then * the content of sigbuf */ diff --git a/src/messages.c b/src/messages.c index 30a0fd77..663d8b28 100644 --- a/src/messages.c +++ b/src/messages.c @@ -312,6 +312,124 @@ error: return SSH_PACKET_USED; } + +/* + * This function concats in a buffer the values needed to do a signature + * verification. + */ +static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session, + ssh_message msg, + const char *service) +{ + struct ssh_crypto_struct *crypto = + session->current_crypto ? session->current_crypto : + session->next_crypto; + ssh_buffer buffer; + ssh_string str; + int rc; + + buffer = ssh_buffer_new(); + if (buffer == NULL) { + return NULL; + } + + /* Add session id */ + str = ssh_string_new(SHA_DIGEST_LEN); + if (str == NULL) { + ssh_buffer_free(buffer); + return NULL; + } + ssh_string_fill(str, crypto->session_id, SHA_DIGEST_LEN); + + rc = buffer_add_ssh_string(buffer, str); + string_free(str); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Add the type */ + rc = buffer_add_u8(buffer, SSH2_MSG_USERAUTH_REQUEST); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Add the username */ + str = ssh_string_from_char(msg->auth_request.username); + if (str == NULL) { + ssh_buffer_free(buffer); + return NULL; + } + rc = buffer_add_ssh_string(buffer, str); + string_free(str); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Add the service name */ + str = ssh_string_from_char(service); + if (str == NULL) { + ssh_buffer_free(buffer); + return NULL; + } + rc = buffer_add_ssh_string(buffer, str); + string_free(str); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Add the method (publickey) */ + str = ssh_string_from_char("publickey"); + if (str == NULL) { + ssh_buffer_free(buffer); + return NULL; + } + rc = buffer_add_ssh_string(buffer, str); + string_free(str); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Has been signed (TRUE) */ + rc = buffer_add_u8(buffer, 1); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Add the public key algorithm */ + str = ssh_string_from_char(msg->auth_request.public_key->type_c); + if (str == NULL) { + ssh_buffer_free(buffer); + return NULL; + } + rc = buffer_add_ssh_string(buffer, str); + string_free(str); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + /* Add the publickey as blob */ + str = publickey_to_string(msg->auth_request.public_key); + if (str == NULL) { + ssh_buffer_free(buffer); + return NULL; + } + rc = buffer_add_ssh_string(buffer, str); + string_free(str); + if (rc < 0) { + ssh_buffer_free(buffer); + return NULL; + } + + return buffer; +} + /** * @internal * @@ -482,7 +600,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ } signature = signature_from_string(session, sign, public_key, public_key->type); - digest = ssh_userauth_build_digest(session, msg, service_c); + digest = ssh_msg_userauth_build_digest(session, msg, service_c); if ((digest == NULL || signature == NULL) || (digest != NULL && signature != NULL && sig_verify(session, public_key, signature,