diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2012-02-15 09:23:07 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2012-02-19 18:49:07 +0100 |
commit | 1973e833f2f8987c7be494e5dff86008a8557758 (patch) | |
tree | 5575fbdd4919c3a7acc60127987820482a015126 /src | |
parent | 387d9e485546a4f7e02e89fdcd097e700cf9ca81 (diff) | |
download | libssh-1973e833f2f8987c7be494e5dff86008a8557758.tar.gz libssh-1973e833f2f8987c7be494e5dff86008a8557758.tar.xz libssh-1973e833f2f8987c7be494e5dff86008a8557758.zip |
server: Add ecdsa hostkey support.
Diffstat (limited to 'src')
-rw-r--r-- | src/bind.c | 35 | ||||
-rw-r--r-- | src/server.c | 55 |
2 files changed, 77 insertions, 13 deletions
@@ -165,12 +165,36 @@ int ssh_bind_listen(ssh_bind sshbind) { return -1; } - if (sshbind->dsakey == NULL && sshbind->rsakey == NULL) { + if (sshbind->ecdsakey == NULL && + sshbind->dsakey == NULL && + sshbind->rsakey == NULL) { ssh_set_error(sshbind, SSH_FATAL, "DSA or RSA host key file must be set before listen()"); return SSH_ERROR; } +#ifdef HAVE_ECC + if (sshbind->ecdsakey) { + rc = ssh_pki_import_privkey_file(sshbind->ecdsakey, + NULL, + NULL, + NULL, + &sshbind->ecdsa); + if (rc == SSH_ERROR) { + ssh_set_error(sshbind, SSH_FATAL, + "Failed to import private ECDSA host key"); + return SSH_ERROR; + } + + if (ssh_key_type(sshbind->ecdsa) != SSH_KEYTYPE_ECDSA) { + ssh_set_error(sshbind, SSH_FATAL, + "The ECDSA host key has the wrong type"); + ssh_key_free(sshbind->ecdsa); + return SSH_ERROR; + } + } +#endif + if (sshbind->dsakey) { rc = ssh_pki_import_privkey_file(sshbind->dsakey, NULL, @@ -385,6 +409,15 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){ ssh_socket_set_fd(session->socket, fd); ssh_socket_get_poll_handle_out(session->socket); +#ifdef HAVE_ECC + if (sshbind->ecdsa) { + session->srv.ecdsa_key = ssh_key_dup(sshbind->ecdsa); + if (session->srv.ecdsa_key == NULL) { + ssh_set_error_oom(sshbind); + return SSH_ERROR; + } + } +#endif if (sshbind->dsa) { session->srv.dsa_key = ssh_key_dup(sshbind->dsa); if (session->srv.dsa_key == NULL) { diff --git a/src/server.c b/src/server.c index 5f1d8230..ac3fec30 100644 --- a/src/server.c +++ b/src/server.c @@ -84,24 +84,47 @@ static int dh_handshake_server(ssh_session session); static int server_set_kex(ssh_session session) { struct ssh_kex_struct *server = &session->next_crypto->server_kex; - int i, j; + int i, j, rc; const char *wanted; + char hostkeys[64] = {0}; + enum ssh_keytypes_e keytype; + size_t len; ZERO_STRUCTP(server); ssh_get_random(server->cookie, 16, 0); - if (session->srv.dsa_key != NULL && session->srv.rsa_key != NULL) { - if (ssh_options_set_algo(session, SSH_HOSTKEYS, - "ssh-dss,ssh-rsa") < 0) { - return -1; - } - } else if (session->srv.dsa_key != NULL) { - if (ssh_options_set_algo(session, SSH_HOSTKEYS, "ssh-dss") < 0) { + +#ifdef HAVE_ECC + if (session->srv.ecdsa_key != NULL) { + keytype = ssh_key_type(session->srv.ecdsa_key); + + snprintf(hostkeys, sizeof(hostkeys), + "%s", session->srv.ecdsa_key->type_c); + } +#endif + if (session->srv.dsa_key != NULL) { + len = strlen(hostkeys); + keytype = ssh_key_type(session->srv.dsa_key); + + snprintf(hostkeys + len, sizeof(hostkeys) - len, + ",%s", ssh_key_type_to_char(keytype)); + } + if (session->srv.rsa_key != NULL) { + len = strlen(hostkeys); + keytype = ssh_key_type(session->srv.rsa_key); + + snprintf(hostkeys + len, sizeof(hostkeys) - len, + ",%s", ssh_key_type_to_char(keytype)); + } + + if (strlen(hostkeys) == 0) { return -1; - } - } else { - if (ssh_options_set_algo(session, SSH_HOSTKEYS, "ssh-rsa") < 0) { + } + + rc = ssh_options_set_algo(session, + SSH_HOSTKEYS, + hostkeys[0] == ',' ? hostkeys + 1 : hostkeys); + if (rc < 0) { return -1; - } } for (i = 0; i < 10; i++) { @@ -186,6 +209,8 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){ *privkey = session->srv.rsa_key; break; case SSH_KEYTYPE_ECDSA: + *privkey = session->srv.ecdsa_key; + break; case SSH_KEYTYPE_UNKNOWN: *privkey = NULL; } @@ -263,6 +288,12 @@ static int dh_handshake_server(ssh_session session) { ssh_key_free(session->srv.dsa_key); session->srv.dsa_key = NULL; } +#ifdef HAVE_ECC + if (session->srv.ecdsa_key) { + ssh_key_free(session->srv.ecdsa_key); + session->srv.ecdsa_key = NULL; + } +#endif if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 || buffer_add_ssh_string(session->out_buffer, |