From 8c8a91a9b750e9730327c991fd44d7a4a90c16b6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 22 Aug 2011 17:05:48 +0200 Subject: [PATCH] server: Migrate more functions to new pki. --- include/libssh/messages.h | 2 +- include/libssh/server.h | 13 ++++++ src/messages.c | 98 ++++++++++++++++++++------------------- src/server.c | 40 ++++++++++++---- 4 files changed, 95 insertions(+), 58 deletions(-) diff --git a/include/libssh/messages.h b/include/libssh/messages.h index 667f7cca..17e25320 100644 --- a/include/libssh/messages.h +++ b/include/libssh/messages.h @@ -28,7 +28,7 @@ struct ssh_auth_request { char *username; int method; char *password; - struct ssh_public_key_struct *public_key; + struct ssh_key_struct *pubkey; char signature_state; char kbdint_response; }; diff --git a/include/libssh/server.h b/include/libssh/server.h index cb12c133..48f0eabd 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -281,6 +281,19 @@ LIBSSH_API const char *ssh_message_auth_user(ssh_message msg); * @see ssh_message_type() */ LIBSSH_API const char *ssh_message_auth_password(ssh_message msg); + +/** + * @brief Get the publickey of the authenticated user. + * + * @param[in] msg The message to get the public key from. + * + * @return The public key or NULL. + * + * @see ssh_message_get() + * @see ssh_message_type() + */ +LIBSSH_API ssh_key ssh_message_auth_pubkey(ssh_message msg); + LIBSSH_API ssh_public_key ssh_message_auth_publickey(ssh_message msg); LIBSSH_API int ssh_message_auth_kbdint_is_response(ssh_message msg); LIBSSH_API enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg); diff --git a/src/messages.c b/src/messages.c index 663d8b28..d8aad758 100644 --- a/src/messages.c +++ b/src/messages.c @@ -38,7 +38,7 @@ #include "libssh/channels.h" #include "libssh/session.h" #include "libssh/misc.h" -#include "libssh/keys.h" +#include "libssh/pki.h" #include "libssh/dh.h" #include "libssh/messages.h" #ifdef WITH_SERVER @@ -252,7 +252,7 @@ void ssh_message_free(ssh_message msg){ strlen(msg->auth_request.password)); SAFE_FREE(msg->auth_request.password); } - publickey_free(msg->auth_request.public_key); + ssh_key_free(msg->auth_request.pubkey); break; case SSH_REQUEST_CHANNEL_OPEN: SAFE_FREE(msg->channel_request_open.originator); @@ -402,7 +402,7 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session, } /* Add the public key algorithm */ - str = ssh_string_from_char(msg->auth_request.public_key->type_c); + str = ssh_string_from_char(msg->auth_request.pubkey->type_c); if (str == NULL) { ssh_buffer_free(buffer); return NULL; @@ -415,7 +415,7 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session, } /* Add the publickey as blob */ - str = publickey_to_string(msg->auth_request.public_key); + str = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey); if (str == NULL) { ssh_buffer_free(buffer); return NULL; @@ -560,8 +560,9 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ if (strncmp(method_c, "publickey", method_size) == 0) { ssh_string algo = NULL; - ssh_string publickey = NULL; + ssh_string pubkey_blob = NULL; uint8_t has_sign; + int rc; msg->auth_request.method = SSH_AUTH_METHOD_PUBLICKEY; SAFE_FREE(method_c); @@ -570,64 +571,67 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){ if (algo == NULL) { goto error; } - publickey = buffer_get_ssh_string(packet); - if (publickey == NULL) { + pubkey_blob = buffer_get_ssh_string(packet); + if (pubkey_blob == NULL) { ssh_string_free(algo); algo = NULL; goto error; } - msg->auth_request.public_key = publickey_from_string(session, publickey); ssh_string_free(algo); algo = NULL; - ssh_string_free(publickey); - publickey = NULL; - if (msg->auth_request.public_key == NULL) { - goto error; + + rc = ssh_pki_import_pubkey_blob(pubkey_blob, &msg->auth_request.pubkey); + ssh_string_free(pubkey_blob); + pubkey_blob = NULL; + if (rc < 0) { + goto error; } msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_NONE; // has a valid signature ? if(has_sign) { - SIGNATURE *signature = NULL; - ssh_public_key public_key = msg->auth_request.public_key; - ssh_string sign = NULL; - ssh_buffer digest = NULL; + ssh_signature sig; + ssh_string sig_blob = NULL; + ssh_buffer digest = NULL; - sign = buffer_get_ssh_string(packet); - if(sign == NULL) { - ssh_log(session, SSH_LOG_PACKET, "Invalid signature packet from peer"); - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR; - goto error; - } - signature = signature_from_string(session, sign, public_key, - public_key->type); - 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, - buffer_get_rest(digest), buffer_get_rest_len(digest)) < 0)) { - ssh_log(session, SSH_LOG_PACKET, "Wrong signature from peer"); + sig_blob = buffer_get_ssh_string(packet); + if(sig_blob == NULL) { + ssh_log(session, SSH_LOG_PACKET, "Invalid signature packet from peer"); + msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_ERROR; + goto error; + } + rc = ssh_pki_import_signature_blob(sig_blob, + msg->auth_request.pubkey, + &sig); + ssh_string_free(sig_blob); + if (rc < 0) { + ssh_log(session, SSH_LOG_PACKET, "Wrong signature from peer"); + msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; + goto error; + } - ssh_string_free(sign); - sign = NULL; + digest = ssh_msg_userauth_build_digest(session, msg, service_c); + if (digest == NULL) { + ssh_signature_free(sig); + ssh_log(session, SSH_LOG_PACKET, "Failed to get digest"); + msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; + goto error; + } + + rc = ssh_srv_pki_signature_verify_blob(session, + sig_blob, + msg->auth_request.pubkey, + buffer_get_rest(digest), + buffer_get_rest_len(digest)); + ssh_string_free(sig_blob); ssh_buffer_free(digest); - digest = NULL; - signature_free(signature); - signature = NULL; + if (rc < 0) { + msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; + goto error; + } - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_WRONG; - goto error; - } - else ssh_log(session, SSH_LOG_PACKET, "Valid signature received"); - ssh_buffer_free(digest); - digest = NULL; - ssh_string_free(sign); - sign = NULL; - signature_free(signature); - signature = NULL; - - msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_VALID; + msg->auth_request.signature_state = SSH_PUBLICKEY_STATE_VALID; } SAFE_FREE(service_c); goto end; diff --git a/src/server.c b/src/server.c index faa4c4c5..cde8a199 100644 --- a/src/server.c +++ b/src/server.c @@ -737,13 +737,21 @@ const char *ssh_message_auth_password(ssh_message msg){ return msg->auth_request.password; } +ssh_key ssh_message_auth_pubkey(ssh_message msg) { + if (msg == NULL) { + return NULL; + } + + return msg->auth_request.pubkey; +} + /* Get the publickey of an auth request */ ssh_public_key ssh_message_auth_publickey(ssh_message msg){ if (msg == NULL) { return NULL; } - return msg->auth_request.public_key; + return ssh_pki_convert_key_to_publickey(msg->auth_request.pubkey); } enum ssh_publickey_state_e ssh_message_auth_publickey_state(ssh_message msg){ @@ -944,15 +952,27 @@ int ssh_message_auth_reply_pk_ok(ssh_message msg, ssh_string algo, ssh_string pu } int ssh_message_auth_reply_pk_ok_simple(ssh_message msg) { - ssh_string algo; - ssh_string pubkey; - int ret; - algo=ssh_string_from_char(msg->auth_request.public_key->type_c); - pubkey=publickey_to_string(msg->auth_request.public_key); - ret=ssh_message_auth_reply_pk_ok(msg,algo,pubkey); - ssh_string_free(algo); - ssh_string_free(pubkey); - return ret; + ssh_string algo; + ssh_string pubkey_blob; + int ret; + + algo = ssh_string_from_char(msg->auth_request.pubkey->type_c); + if (algo == NULL) { + return SSH_ERROR; + } + + pubkey_blob = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey); + if (pubkey_blob == NULL) { + ssh_string_free(algo); + return SSH_ERROR; + } + + ret = ssh_message_auth_reply_pk_ok(msg, algo, pubkey_blob); + + ssh_string_free(algo); + ssh_string_free(pubkey_blob); + + return ret; }