diff --git a/include/libssh/pki.h b/include/libssh/pki.h index 533d3e09..9b104349 100644 --- a/include/libssh/pki.h +++ b/include/libssh/pki.h @@ -111,6 +111,7 @@ enum ssh_keytypes_e ssh_key_type_from_signature_name(const char *name); enum ssh_keytypes_e ssh_key_type_plain(enum ssh_keytypes_e type); enum ssh_digest_e ssh_key_type_to_hash(ssh_session session, enum ssh_keytypes_e type); +enum ssh_digest_e ssh_key_hash_from_name(const char *name); #define is_ecdsa_key_type(t) \ ((t) >= SSH_KEYTYPE_ECDSA_P256 && (t) <= SSH_KEYTYPE_ECDSA_P521) @@ -153,7 +154,8 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session, struct ssh_buffer_struct *buf, const ssh_key pubkey); ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, - const ssh_key privkey); + const ssh_key privkey, + const enum ssh_digest_e digest); /* Temporary functions, to be removed after migration to ssh_key */ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key); diff --git a/include/libssh/priv.h b/include/libssh/priv.h index ce74465a..90ef0dcf 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -221,7 +221,17 @@ int gettimeofday(struct timeval *__p, void *__t); struct ssh_common_struct; struct ssh_kex_struct; -int ssh_get_key_params(ssh_session session, ssh_key *privkey); +enum ssh_digest_e { + SSH_DIGEST_AUTO=0, + SSH_DIGEST_SHA1=1, + SSH_DIGEST_SHA256, + SSH_DIGEST_SHA384, + SSH_DIGEST_SHA512, +}; + +int ssh_get_key_params(ssh_session session, + ssh_key *privkey, + enum ssh_digest_e *digest); /* LOGGING */ void ssh_log_function(int verbosity, diff --git a/include/libssh/session.h b/include/libssh/session.h index dfcb0cd6..6558da46 100644 --- a/include/libssh/session.h +++ b/include/libssh/session.h @@ -188,6 +188,7 @@ struct ssh_session_struct { ssh_key ed25519_key; /* The type of host key wanted by client */ enum ssh_keytypes_e hostkey; + enum ssh_digest_e hostkey_digest; } srv; /* auths accepted by server */ diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h index 1c18f288..ba64939b 100644 --- a/include/libssh/wrapper.h +++ b/include/libssh/wrapper.h @@ -29,14 +29,6 @@ #include "libssh/libgcrypt.h" #include "libssh/libmbedcrypto.h" -enum ssh_digest_e { - SSH_DIGEST_AUTO=0, - SSH_DIGEST_SHA1=1, - SSH_DIGEST_SHA256, - SSH_DIGEST_SHA384, - SSH_DIGEST_SHA512, -}; - enum ssh_kdf_digest { SSH_KDF_SHA1=1, SSH_KDF_SHA256, diff --git a/src/curve25519.c b/src/curve25519.c index cfbe6bd8..206cb130 100644 --- a/src/curve25519.c +++ b/src/curve25519.c @@ -388,6 +388,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){ /* SSH host keys (rsa,dsa,ecdsa) */ ssh_key privkey; + enum ssh_digest_e digest = SSH_DIGEST_AUTO; ssh_string sig_blob = NULL; int rc; (void)type; @@ -435,7 +436,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){ } /* privkey is not allocated */ - rc = ssh_get_key_params(session, &privkey); + rc = ssh_get_key_params(session, &privkey, &digest); if (rc == SSH_ERROR) { goto error; } @@ -478,7 +479,7 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){ goto error; } /* add signature blob */ - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); + sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest); if (sig_blob == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); goto error; diff --git a/src/dh.c b/src/dh.c index 2f63bafa..4869b37e 100644 --- a/src/dh.c +++ b/src/dh.c @@ -431,6 +431,7 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet) { struct ssh_crypto_struct *crypto = session->next_crypto; ssh_key privkey = NULL; + enum ssh_digest_e digest = SSH_DIGEST_AUTO; ssh_string sig_blob = NULL; ssh_string pubkey_blob = NULL; bignum client_pubkey; @@ -456,7 +457,7 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet) goto error; } - rc = ssh_get_key_params(session, &privkey); + rc = ssh_get_key_params(session, &privkey, &digest); if (rc != SSH_OK) { goto error; } @@ -473,7 +474,7 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet) ssh_set_error(session, SSH_FATAL, "Could not create a session id"); goto error; } - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); + sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest); if (sig_blob == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); goto error; diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c index 9bdfe310..10c0bcd7 100644 --- a/src/ecdh_crypto.c +++ b/src/ecdh_crypto.c @@ -206,6 +206,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ bignum_CTX ctx; /* SSH host keys (rsa,dsa,ecdsa) */ ssh_key privkey; + enum ssh_digest_e digest = SSH_DIGEST_AUTO; ssh_string sig_blob = NULL; ssh_string pubkey_blob = NULL; int curve; @@ -277,7 +278,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ } /* privkey is not allocated */ - rc = ssh_get_key_params(session, &privkey); + rc = ssh_get_key_params(session, &privkey, &digest); if (rc == SSH_ERROR) { goto error; } @@ -288,7 +289,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ goto error; } - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); + sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest); if (sig_blob == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); goto error; diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c index 3c3fe8f0..7bbad14e 100644 --- a/src/ecdh_gcrypt.c +++ b/src/ecdh_gcrypt.c @@ -273,6 +273,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ gcry_sexp_t key = NULL; /* SSH host keys (rsa,dsa,ecdsa) */ ssh_key privkey; + enum ssh_digest_e digest = SSH_DIGEST_AUTO; ssh_string sig_blob = NULL; ssh_string pubkey_blob = NULL; int rc = SSH_ERROR; @@ -325,7 +326,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ } /* privkey is not allocated */ - rc = ssh_get_key_params(session, &privkey); + rc = ssh_get_key_params(session, &privkey, &digest); if (rc != SSH_OK) { goto out; } @@ -336,7 +337,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ goto out; } - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); + sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest); if (sig_blob == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); rc = SSH_ERROR; diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c index 2c165aaa..3b10117b 100644 --- a/src/ecdh_mbedcrypto.c +++ b/src/ecdh_mbedcrypto.c @@ -188,6 +188,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ ssh_string q_s_string = NULL; mbedtls_ecp_group grp; ssh_key privkey = NULL; + enum ssh_digest_e digest = SSH_DIGEST_AUTO; ssh_string sig_blob = NULL; ssh_string pubkey_blob = NULL; int rc; @@ -250,7 +251,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ } /* privkey is not allocated */ - rc = ssh_get_key_params(session, &privkey); + rc = ssh_get_key_params(session, &privkey, &digest); if (rc == SSH_ERROR) { rc = SSH_ERROR; goto out; @@ -263,7 +264,7 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ goto out; } - sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey); + sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest); if (sig_blob == NULL) { ssh_set_error(session, SSH_FATAL, "Could not sign the session id"); rc = SSH_ERROR; diff --git a/src/pki.c b/src/pki.c index 488500cc..3bd7f272 100644 --- a/src/pki.c +++ b/src/pki.c @@ -305,7 +305,7 @@ const char *ssh_key_type_to_char(enum ssh_keytypes_e type) { return NULL; } -static enum ssh_digest_e ssh_key_hash_from_name(const char *name) +enum ssh_digest_e ssh_key_hash_from_name(const char *name) { if (name == NULL) { /* TODO we should rather fail */ @@ -2423,7 +2423,8 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session, #ifdef WITH_SERVER ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, - const ssh_key privkey) + const ssh_key privkey, + const enum ssh_digest_e digest) { struct ssh_crypto_struct *crypto = NULL; @@ -2432,8 +2433,6 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, ssh_buffer sign_input = NULL; - enum ssh_digest_e hash_type; - int rc; if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) { @@ -2448,9 +2447,6 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, return NULL; } - /* Get the hash type from the key type */ - hash_type = ssh_key_type_to_hash(session, privkey->type); - /* Fill the input */ sign_input = ssh_buffer_new(); if (sign_input == NULL) { @@ -2470,7 +2466,7 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, sig = pki_do_sign(privkey, ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input), - hash_type); + digest); if (sig == NULL) { goto end; } diff --git a/src/server.c b/src/server.c index 9256c30a..14295fca 100644 --- a/src/server.c +++ b/src/server.c @@ -264,7 +264,11 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){ return SSH_PACKET_NOT_USED; } -int ssh_get_key_params(ssh_session session, ssh_key *privkey){ +int +ssh_get_key_params(ssh_session session, + ssh_key *privkey, + enum ssh_digest_e *digest) +{ ssh_key pubkey; ssh_string pubkey_blob; int rc; @@ -290,6 +294,7 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){ *privkey = NULL; } + *digest = session->srv.hostkey_digest; rc = ssh_pki_export_privkey_to_pubkey(*privkey, &pubkey); if (rc < 0) { ssh_set_error(session, SSH_FATAL, diff --git a/src/wrapper.c b/src/wrapper.c index 299d4f3f..fd3417f3 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -539,6 +539,7 @@ int crypt_set_algorithms_server(ssh_session session){ method = session->next_crypto->kex_methods[SSH_HOSTKEYS]; session->srv.hostkey = ssh_key_type_from_signature_name(method); + session->srv.hostkey_digest = ssh_key_hash_from_name(method); /* setup DH key exchange type */ switch (session->next_crypto->kex_type) {