mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-08 19:02:06 +03:00
kex: implement curve25519-sha256@libssh.org
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "libssh/ecdh.h"
|
#include "libssh/ecdh.h"
|
||||||
#include "libssh/kex.h"
|
#include "libssh/kex.h"
|
||||||
|
#include "libssh/curve25519.h"
|
||||||
|
|
||||||
enum ssh_key_exchange_e {
|
enum ssh_key_exchange_e {
|
||||||
/* diffie-hellman-group1-sha1 */
|
/* diffie-hellman-group1-sha1 */
|
||||||
@@ -51,7 +52,9 @@ enum ssh_key_exchange_e {
|
|||||||
/* diffie-hellman-group14-sha1 */
|
/* diffie-hellman-group14-sha1 */
|
||||||
SSH_KEX_DH_GROUP14_SHA1,
|
SSH_KEX_DH_GROUP14_SHA1,
|
||||||
/* ecdh-sha2-nistp256 */
|
/* ecdh-sha2-nistp256 */
|
||||||
SSH_KEX_ECDH_SHA2_NISTP256
|
SSH_KEX_ECDH_SHA2_NISTP256,
|
||||||
|
/* curve25519-sha256@libssh.org */
|
||||||
|
SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_crypto_struct {
|
struct ssh_crypto_struct {
|
||||||
@@ -60,6 +63,11 @@ struct ssh_crypto_struct {
|
|||||||
EC_KEY *ecdh_privkey;
|
EC_KEY *ecdh_privkey;
|
||||||
ssh_string ecdh_client_pubkey;
|
ssh_string ecdh_client_pubkey;
|
||||||
ssh_string ecdh_server_pubkey;
|
ssh_string ecdh_server_pubkey;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
ssh_curve25519_privkey curve25519_privkey;
|
||||||
|
ssh_curve25519_pubkey curve25519_client_pubkey;
|
||||||
|
ssh_curve25519_pubkey curve25519_server_pubkey;
|
||||||
#endif
|
#endif
|
||||||
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
ssh_string dh_server_signature; /* information used by dh_handshake. */
|
||||||
size_t digest_len; /* len of all the fields below */
|
size_t digest_len; /* len of all the fields below */
|
||||||
|
46
include/libssh/curve25519.h
Normal file
46
include/libssh/curve25519.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 by Aris Adamantiadis <aris@badcode.be>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation,
|
||||||
|
* version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CURVE25519_H_
|
||||||
|
#define CURVE25519_H_
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "libssh.h"
|
||||||
|
|
||||||
|
#ifdef WITH_NACL
|
||||||
|
|
||||||
|
#define HAVE_CURVE25519
|
||||||
|
#include <nacl/crypto_scalarmult_curve25519.h>
|
||||||
|
#define CURVE25519_PUBKEY_SIZE crypto_scalarmult_curve25519_BYTES
|
||||||
|
#define CURVE25519_PRIVKEY_SIZE crypto_scalarmult_curve25519_SCALARBYTES
|
||||||
|
|
||||||
|
typedef unsigned char ssh_curve25519_pubkey[CURVE25519_PUBKEY_SIZE];
|
||||||
|
typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
|
||||||
|
|
||||||
|
#endif /* WITH_NACL */
|
||||||
|
|
||||||
|
int ssh_client_curve25519_init(ssh_session session);
|
||||||
|
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet);
|
||||||
|
|
||||||
|
#ifdef WITH_SERVER
|
||||||
|
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet);
|
||||||
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
#endif /* CURVE25519_H_ */
|
@@ -76,6 +76,18 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
|||||||
)
|
)
|
||||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||||
|
|
||||||
|
if (WITH_NACL AND NACL_FOUND)
|
||||||
|
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||||
|
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||||
|
${NACL_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LIBSSH_LINK_LIBRARIES
|
||||||
|
${LIBSSH_LINK_LIBRARIES}
|
||||||
|
${NACL_LIBRARY}
|
||||||
|
)
|
||||||
|
endif (WITH_NACL AND NACL_FOUND)
|
||||||
|
|
||||||
set(LIBSSH_LINK_LIBRARIES
|
set(LIBSSH_LINK_LIBRARIES
|
||||||
${LIBSSH_LINK_LIBRARIES}
|
${LIBSSH_LINK_LIBRARIES}
|
||||||
CACHE INTERNAL "libssh link libraries"
|
CACHE INTERNAL "libssh link libraries"
|
||||||
@@ -192,6 +204,13 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
|||||||
)
|
)
|
||||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||||
|
|
||||||
|
if (WITH_NACL)
|
||||||
|
set(libssh_SRCS
|
||||||
|
${libssh_SRCS}
|
||||||
|
curve25519.c
|
||||||
|
)
|
||||||
|
endif (WITH_NACL)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||||
|
@@ -196,6 +196,11 @@ static int dh_handshake(ssh_session session) {
|
|||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
rc = ssh_client_ecdh_init(session);
|
rc = ssh_client_ecdh_init(session);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
|
rc = ssh_client_curve25519_init(session);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
rc = SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
|
285
src/curve25519.c
Normal file
285
src/curve25519.c
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* curve25519.c - Curve25519 ECDH functions for key exchange
|
||||||
|
* curve25519-sha256@libssh.org
|
||||||
|
*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013 by Aris Adamantiadis <aris@badcode.be>
|
||||||
|
*
|
||||||
|
* The SSH Library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, version 2.1 of the License.
|
||||||
|
*
|
||||||
|
* The SSH Library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
* License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with the SSH Library; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
* MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "libssh/curve25519.h"
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
|
||||||
|
#include "nacl/crypto_scalarmult_curve25519.h"
|
||||||
|
#include "libssh/ssh2.h"
|
||||||
|
#include "libssh/buffer.h"
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
#include "libssh/session.h"
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/pki.h"
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief Starts curve25519-sha256@libssh.org key exchange
|
||||||
|
*/
|
||||||
|
int ssh_client_curve25519_init(ssh_session session){
|
||||||
|
ssh_string client_pubkey;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
|
||||||
|
if (rc < 0) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
|
||||||
|
if (rc == 0){
|
||||||
|
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_scalarmult_curve25519_base(session->next_crypto->curve25519_client_pubkey,
|
||||||
|
session->next_crypto->curve25519_privkey);
|
||||||
|
client_pubkey = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||||
|
if (client_pubkey == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
ssh_string_fill(client_pubkey, session->next_crypto->curve25519_client_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
rc = buffer_add_ssh_string(session->out_buffer,client_pubkey);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_string_free(client_pubkey);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = packet_send(session);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ssh_curve25519_build_k(ssh_session session) {
|
||||||
|
ssh_curve25519_pubkey k;
|
||||||
|
session->next_crypto->k = bignum_new();
|
||||||
|
|
||||||
|
if (session->next_crypto->k == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->server)
|
||||||
|
crypto_scalarmult_curve25519(k, session->next_crypto->curve25519_privkey,
|
||||||
|
session->next_crypto->curve25519_client_pubkey);
|
||||||
|
else
|
||||||
|
crypto_scalarmult_curve25519(k, session->next_crypto->curve25519_privkey,
|
||||||
|
session->next_crypto->curve25519_server_pubkey);
|
||||||
|
|
||||||
|
BN_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
||||||
|
|
||||||
|
#ifdef DEBUG_CRYPTO
|
||||||
|
ssh_print_hexa("Session server cookie",
|
||||||
|
session->next_crypto->server_kex.cookie, 16);
|
||||||
|
ssh_print_hexa("Session client cookie",
|
||||||
|
session->next_crypto->client_kex.cookie, 16);
|
||||||
|
ssh_print_bignum("Shared secret key", session->next_crypto->k);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief parses a SSH_MSG_KEX_ECDH_REPLY packet and sends back
|
||||||
|
* a SSH_MSG_NEWKEYS
|
||||||
|
*/
|
||||||
|
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){
|
||||||
|
ssh_string q_s_string = NULL;
|
||||||
|
ssh_string pubkey = NULL;
|
||||||
|
ssh_string signature = NULL;
|
||||||
|
int rc;
|
||||||
|
pubkey = buffer_get_ssh_string(packet);
|
||||||
|
if (pubkey == NULL){
|
||||||
|
ssh_set_error(session,SSH_FATAL, "No public key in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* this is the server host key */
|
||||||
|
session->next_crypto->server_pubkey = pubkey;
|
||||||
|
pubkey = NULL;
|
||||||
|
|
||||||
|
q_s_string = buffer_get_ssh_string(packet);
|
||||||
|
if (q_s_string == NULL) {
|
||||||
|
ssh_set_error(session,SSH_FATAL, "No Q_S ECC point in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
||||||
|
ssh_string_len(q_s_string));
|
||||||
|
ssh_string_free(q_s_string);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE);
|
||||||
|
|
||||||
|
signature = buffer_get_ssh_string(packet);
|
||||||
|
if (signature == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "No signature in packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
session->next_crypto->dh_server_signature = signature;
|
||||||
|
signature=NULL; /* ownership changed */
|
||||||
|
/* TODO: verify signature now instead of waiting for NEWKEYS */
|
||||||
|
if (ssh_curve25519_build_k(session) < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the MSG_NEWKEYS */
|
||||||
|
if (buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc=packet_send(session);
|
||||||
|
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||||
|
return rc;
|
||||||
|
error:
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_SERVER
|
||||||
|
|
||||||
|
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
|
||||||
|
* SSH_MSG_KEXDH_REPLY
|
||||||
|
*/
|
||||||
|
int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
||||||
|
/* ECDH keys */
|
||||||
|
ssh_string q_c_string;
|
||||||
|
ssh_string q_s_string;
|
||||||
|
|
||||||
|
/* SSH host keys (rsa,dsa,ecdsa) */
|
||||||
|
ssh_key privkey;
|
||||||
|
ssh_string sig_blob = NULL;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Extract the client pubkey from the init packet */
|
||||||
|
q_c_string = buffer_get_ssh_string(packet);
|
||||||
|
if (q_c_string == NULL) {
|
||||||
|
ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
||||||
|
ssh_string_len(q_c_string));
|
||||||
|
ssh_string_free(q_c_string);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(session->next_crypto->curve25519_client_pubkey,
|
||||||
|
ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
|
||||||
|
ssh_string_free(q_c_string);
|
||||||
|
/* Build server's keypair */
|
||||||
|
|
||||||
|
rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
|
||||||
|
if (rc == 0){
|
||||||
|
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_scalarmult_curve25519_base(session->next_crypto->curve25519_server_pubkey,
|
||||||
|
session->next_crypto->curve25519_privkey);
|
||||||
|
|
||||||
|
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||||
|
if (q_s_string == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_string_fill(q_s_string, session->next_crypto->curve25519_server_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
|
||||||
|
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build k and session_id */
|
||||||
|
rc = ssh_curve25519_build_k(session);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* privkey is not allocated */
|
||||||
|
rc = ssh_get_key_params(session, &privkey);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = make_sessionid(session);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add host's public key */
|
||||||
|
rc = buffer_add_ssh_string(session->out_buffer,
|
||||||
|
session->next_crypto->server_pubkey);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add ecdh public key */
|
||||||
|
rc = buffer_add_ssh_string(session->out_buffer, q_s_string);
|
||||||
|
ssh_string_free(q_s_string);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
/* add signature blob */
|
||||||
|
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||||
|
if (sig_blob == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = buffer_add_ssh_string(session->out_buffer, sig_blob);
|
||||||
|
ssh_string_free(sig_blob);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_ECDH_REPLY sent");
|
||||||
|
rc = packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the MSG_NEWKEYS */
|
||||||
|
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
|
||||||
|
if (rc < 0) {
|
||||||
|
return SSH_ERROR;;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||||
|
rc = packet_send(session);
|
||||||
|
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
#endif /* HAVE_CURVE25519 */
|
13
src/dh.c
13
src/dh.c
@@ -770,6 +770,18 @@ int make_sessionid(ssh_session session) {
|
|||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
} else if(session->next_crypto->kex_type == SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG){
|
||||||
|
rc = buffer_add_u32(buf, htonl(CURVE25519_PUBKEY_SIZE));
|
||||||
|
rc += buffer_add_data(buf, session->next_crypto->curve25519_client_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
rc += buffer_add_u32(buf, htonl(CURVE25519_PUBKEY_SIZE));
|
||||||
|
rc += buffer_add_data(buf, session->next_crypto->curve25519_server_pubkey,
|
||||||
|
CURVE25519_PUBKEY_SIZE);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
num = make_bignum_string(session->next_crypto->k);
|
num = make_bignum_string(session->next_crypto->k);
|
||||||
@@ -800,6 +812,7 @@ int make_sessionid(ssh_session session) {
|
|||||||
session->next_crypto->secret_hash);
|
session->next_crypto->secret_hash);
|
||||||
break;
|
break;
|
||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
|
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
|
||||||
session->next_crypto->mac_type = SSH_MAC_SHA256;
|
session->next_crypto->mac_type = SSH_MAC_SHA256;
|
||||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||||
|
20
src/kex.c
20
src/kex.c
@@ -34,6 +34,7 @@
|
|||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
#include "libssh/string.h"
|
#include "libssh/string.h"
|
||||||
|
#include "libssh/curve25519.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
# define BLOWFISH "blowfish-cbc,"
|
# define BLOWFISH "blowfish-cbc,"
|
||||||
@@ -63,14 +64,21 @@
|
|||||||
#define ZLIB "none"
|
#define ZLIB "none"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ECDH
|
#ifdef HAVE_CURVE25519
|
||||||
#define KEY_EXCHANGE "ecdh-sha2-nistp256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
|
#define CURVE25519 "curve25519-sha256@libssh.org,"
|
||||||
#define HOSTKEYS "ecdsa-sha2-nistp256,ssh-rsa,ssh-dss"
|
|
||||||
#else
|
#else
|
||||||
#define KEY_EXCHANGE "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
|
#define CURVE25519 ""
|
||||||
#define HOSTKEYS "ssh-rsa,ssh-dss"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ECDH
|
||||||
|
#define ECDH "ecdh-sha2-nistp256,"
|
||||||
|
#define HOSTKEYS "ecdsa-sha2-nistp256,ssh-rsa,ssh-dss"
|
||||||
|
#else
|
||||||
|
#define HOSTKEYS "ssh-rsa,ssh-dss"
|
||||||
|
#define ECDH ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KEY_EXCHANGE CURVE25519 ECDH "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
|
||||||
#define KEX_METHODS_SIZE 10
|
#define KEX_METHODS_SIZE 10
|
||||||
|
|
||||||
/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */
|
/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */
|
||||||
@@ -412,6 +420,8 @@ int ssh_kex_select_methods (ssh_session session){
|
|||||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1;
|
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1;
|
||||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
|
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
|
||||||
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256;
|
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256;
|
||||||
|
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
|
||||||
|
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/socket.h"
|
#include "libssh/socket.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
|
#include "libssh/curve25519.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
@@ -102,6 +103,11 @@ SSH_PACKET_CALLBACK(ssh_packet_dh_reply){
|
|||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
rc = ssh_client_ecdh_reply(session, packet);
|
rc = ssh_client_ecdh_reply(session, packet);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
|
rc = ssh_client_curve25519_reply(session, packet);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_dh_reply");
|
ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_dh_reply");
|
||||||
|
@@ -58,6 +58,7 @@
|
|||||||
#include "libssh/dh.h"
|
#include "libssh/dh.h"
|
||||||
#include "libssh/messages.h"
|
#include "libssh/messages.h"
|
||||||
#include "libssh/options.h"
|
#include "libssh/options.h"
|
||||||
|
#include "libssh/curve25519.h"
|
||||||
|
|
||||||
#define set_status(session, status) do {\
|
#define set_status(session, status) do {\
|
||||||
if (session->common.callbacks && session->common.callbacks->connect_status_function) \
|
if (session->common.callbacks && session->common.callbacks->connect_status_function) \
|
||||||
@@ -182,6 +183,11 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
|
|||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
rc = ssh_server_ecdh_init(session, packet);
|
rc = ssh_server_ecdh_init(session, packet);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURVE25519
|
||||||
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
|
rc = ssh_server_curve25519_init(session, packet);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_kexdh_init");
|
ssh_set_error(session,SSH_FATAL,"Wrong kex type in ssh_packet_kexdh_init");
|
||||||
|
Reference in New Issue
Block a user