mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-29 01:03:57 +03:00
server: Add ecdsa hostkey support.
This commit is contained in:
@@ -34,8 +34,10 @@ struct ssh_bind_struct {
|
|||||||
/* options */
|
/* options */
|
||||||
char *wanted_methods[10];
|
char *wanted_methods[10];
|
||||||
char *banner;
|
char *banner;
|
||||||
|
char *ecdsakey;
|
||||||
char *dsakey;
|
char *dsakey;
|
||||||
char *rsakey;
|
char *rsakey;
|
||||||
|
ssh_key ecdsa;
|
||||||
ssh_key dsa;
|
ssh_key dsa;
|
||||||
ssh_key rsa;
|
ssh_key rsa;
|
||||||
char *bindaddr;
|
char *bindaddr;
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ struct ssh_session_struct {
|
|||||||
struct {
|
struct {
|
||||||
ssh_key rsa_key;
|
ssh_key rsa_key;
|
||||||
ssh_key dsa_key;
|
ssh_key dsa_key;
|
||||||
|
ssh_key ecdsa_key;
|
||||||
|
|
||||||
/* The type of host key wanted by client */
|
/* The type of host key wanted by client */
|
||||||
enum ssh_keytypes_e hostkey;
|
enum ssh_keytypes_e hostkey;
|
||||||
|
|||||||
35
src/bind.c
35
src/bind.c
@@ -165,12 +165,36 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
|||||||
return -1;
|
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,
|
ssh_set_error(sshbind, SSH_FATAL,
|
||||||
"DSA or RSA host key file must be set before listen()");
|
"DSA or RSA host key file must be set before listen()");
|
||||||
return SSH_ERROR;
|
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) {
|
if (sshbind->dsakey) {
|
||||||
rc = ssh_pki_import_privkey_file(sshbind->dsakey,
|
rc = ssh_pki_import_privkey_file(sshbind->dsakey,
|
||||||
NULL,
|
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_set_fd(session->socket, fd);
|
||||||
ssh_socket_get_poll_handle_out(session->socket);
|
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) {
|
if (sshbind->dsa) {
|
||||||
session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
|
session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
|
||||||
if (session->srv.dsa_key == NULL) {
|
if (session->srv.dsa_key == NULL) {
|
||||||
|
|||||||
55
src/server.c
55
src/server.c
@@ -84,24 +84,47 @@ static int dh_handshake_server(ssh_session session);
|
|||||||
|
|
||||||
static int server_set_kex(ssh_session session) {
|
static int server_set_kex(ssh_session session) {
|
||||||
struct ssh_kex_struct *server = &session->next_crypto->server_kex;
|
struct ssh_kex_struct *server = &session->next_crypto->server_kex;
|
||||||
int i, j;
|
int i, j, rc;
|
||||||
const char *wanted;
|
const char *wanted;
|
||||||
|
char hostkeys[64] = {0};
|
||||||
|
enum ssh_keytypes_e keytype;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
ZERO_STRUCTP(server);
|
ZERO_STRUCTP(server);
|
||||||
ssh_get_random(server->cookie, 16, 0);
|
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,
|
#ifdef HAVE_ECC
|
||||||
"ssh-dss,ssh-rsa") < 0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (session->srv.dsa_key != NULL) {
|
|
||||||
if (ssh_options_set_algo(session, SSH_HOSTKEYS, "ssh-dss") < 0) {
|
rc = ssh_options_set_algo(session,
|
||||||
|
SSH_HOSTKEYS,
|
||||||
|
hostkeys[0] == ',' ? hostkeys + 1 : hostkeys);
|
||||||
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ssh_options_set_algo(session, SSH_HOSTKEYS, "ssh-rsa") < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
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;
|
*privkey = session->srv.rsa_key;
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_ECDSA:
|
case SSH_KEYTYPE_ECDSA:
|
||||||
|
*privkey = session->srv.ecdsa_key;
|
||||||
|
break;
|
||||||
case SSH_KEYTYPE_UNKNOWN:
|
case SSH_KEYTYPE_UNKNOWN:
|
||||||
*privkey = NULL;
|
*privkey = NULL;
|
||||||
}
|
}
|
||||||
@@ -263,6 +288,12 @@ static int dh_handshake_server(ssh_session session) {
|
|||||||
ssh_key_free(session->srv.dsa_key);
|
ssh_key_free(session->srv.dsa_key);
|
||||||
session->srv.dsa_key = NULL;
|
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 ||
|
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY) < 0 ||
|
||||||
buffer_add_ssh_string(session->out_buffer,
|
buffer_add_ssh_string(session->out_buffer,
|
||||||
|
|||||||
Reference in New Issue
Block a user