mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-27 13:21:11 +03:00
dh-gex: Add client implementation
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
154eb91914
commit
574bfb5459
@@ -58,6 +58,9 @@ enum ssh_key_exchange_e {
|
|||||||
SSH_KEX_DH_GROUP1_SHA1=1,
|
SSH_KEX_DH_GROUP1_SHA1=1,
|
||||||
/* diffie-hellman-group14-sha1 */
|
/* diffie-hellman-group14-sha1 */
|
||||||
SSH_KEX_DH_GROUP14_SHA1,
|
SSH_KEX_DH_GROUP14_SHA1,
|
||||||
|
/* diffie-hellman-group-exchange-sha1 */
|
||||||
|
SSH_KEX_DH_GEX_SHA1,
|
||||||
|
SSH_KEX_DH_GEX_SHA256,
|
||||||
/* ecdh-sha2-nistp256 */
|
/* ecdh-sha2-nistp256 */
|
||||||
SSH_KEX_ECDH_SHA2_NISTP256,
|
SSH_KEX_ECDH_SHA2_NISTP256,
|
||||||
/* ecdh-sha2-nistp384 */
|
/* ecdh-sha2-nistp384 */
|
||||||
|
|||||||
37
include/libssh/dh-gex.h
Normal file
37
include/libssh/dh-gex.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.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; either version 2.1 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SRC_DH_GEX_H_
|
||||||
|
#define SRC_DH_GEX_H_
|
||||||
|
|
||||||
|
/* Minimum, recommanded and maximum size of DH group */
|
||||||
|
#define DH_PMIN 2048
|
||||||
|
#define DH_PREQ 2048
|
||||||
|
#define DH_PMAX 8192
|
||||||
|
|
||||||
|
int ssh_client_dhgex_init(ssh_session session);
|
||||||
|
|
||||||
|
#ifdef WITH_SERVER
|
||||||
|
void ssh_server_dhgex_init(ssh_session session);
|
||||||
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
|
#endif /* SRC_DH_GEX_H_ */
|
||||||
@@ -49,6 +49,7 @@ enum ssh_session_state_e {
|
|||||||
|
|
||||||
enum ssh_dh_state_e {
|
enum ssh_dh_state_e {
|
||||||
DH_STATE_INIT=0,
|
DH_STATE_INIT=0,
|
||||||
|
DH_STATE_REQUEST_SENT,
|
||||||
DH_STATE_INIT_SENT,
|
DH_STATE_INIT_SENT,
|
||||||
DH_STATE_NEWKEYS_SENT,
|
DH_STATE_NEWKEYS_SENT,
|
||||||
DH_STATE_FINISHED
|
DH_STATE_FINISHED
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ set(libssh_SRCS
|
|||||||
connector.c
|
connector.c
|
||||||
curve25519.c
|
curve25519.c
|
||||||
dh.c
|
dh.c
|
||||||
|
dh-gex.c
|
||||||
ecdh.c
|
ecdh.c
|
||||||
error.c
|
error.c
|
||||||
getpass.c
|
getpass.c
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "libssh/socket.h"
|
#include "libssh/socket.h"
|
||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/dh.h"
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/dh-gex.h"
|
||||||
#include "libssh/ecdh.h"
|
#include "libssh/ecdh.h"
|
||||||
#include "libssh/threads.h"
|
#include "libssh/threads.h"
|
||||||
#include "libssh/misc.h"
|
#include "libssh/misc.h"
|
||||||
@@ -253,6 +254,10 @@ static int dh_handshake(ssh_session session) {
|
|||||||
case SSH_KEX_DH_GROUP18_SHA512:
|
case SSH_KEX_DH_GROUP18_SHA512:
|
||||||
rc = ssh_client_dh_init(session);
|
rc = ssh_client_dh_init(session);
|
||||||
break;
|
break;
|
||||||
|
case SSH_KEX_DH_GEX_SHA1:
|
||||||
|
case SSH_KEX_DH_GEX_SHA256:
|
||||||
|
rc = ssh_client_dhgex_init(session);
|
||||||
|
break;
|
||||||
#ifdef HAVE_ECDH
|
#ifdef HAVE_ECDH
|
||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
case SSH_KEX_ECDH_SHA2_NISTP384:
|
case SSH_KEX_ECDH_SHA2_NISTP384:
|
||||||
|
|||||||
254
src/dh-gex.c
Normal file
254
src/dh-gex.c
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/*
|
||||||
|
* dh-gex.c - diffie-hellman group exchange
|
||||||
|
*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 by Aris Adamantiadis <aris@0xbadc0de.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; either version 2.1 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* 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/priv.h"
|
||||||
|
#include "libssh/dh-gex.h"
|
||||||
|
#include "libssh/libssh.h"
|
||||||
|
#include "libssh/ssh2.h"
|
||||||
|
#include "libssh/callbacks.h"
|
||||||
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/buffer.h"
|
||||||
|
#include "libssh/session.h"
|
||||||
|
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group);
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply);
|
||||||
|
|
||||||
|
static ssh_packet_callback dhgex_client_callbacks[] = {
|
||||||
|
ssh_packet_client_dhgex_group, /* SSH_MSG_KEX_DH_GEX_GROUP */
|
||||||
|
NULL, /* SSH_MSG_KEX_DH_GEX_INIT */
|
||||||
|
ssh_packet_client_dhgex_reply /* SSH_MSG_KEX_DH_GEX_REPLY */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ssh_packet_callbacks_struct ssh_dhgex_client_callbacks = {
|
||||||
|
.start = SSH2_MSG_KEX_DH_GEX_GROUP,
|
||||||
|
.n_callbacks = 3,
|
||||||
|
.callbacks = dhgex_client_callbacks,
|
||||||
|
.user = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief initiates a diffie-hellman-group-exchange kex
|
||||||
|
*/
|
||||||
|
int ssh_client_dhgex_init(ssh_session session)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_dh_init_common(session);
|
||||||
|
if (rc != SSH_OK){
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Minimum group size, preferred group size, maximum group size */
|
||||||
|
rc = ssh_buffer_pack(session->out_buffer,
|
||||||
|
"bddd",
|
||||||
|
SSH2_MSG_KEX_DH_GEX_REQUEST,
|
||||||
|
DH_PMIN,
|
||||||
|
DH_PREQ,
|
||||||
|
DH_PMAX);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register the packet callbacks */
|
||||||
|
ssh_packet_set_callbacks(session, &ssh_dhgex_client_callbacks);
|
||||||
|
session->dh_handshake_state = DH_STATE_REQUEST_SENT;
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
error:
|
||||||
|
ssh_dh_cleanup(session);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal
|
||||||
|
* @brief handle a DH_GEX_GROUP packet, client side. This packet contains
|
||||||
|
* the group parameters.
|
||||||
|
*/
|
||||||
|
SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_group)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int blen;
|
||||||
|
bignum pmin1 = NULL, one = NULL;
|
||||||
|
bignum_CTX ctx = bignum_ctx_new();
|
||||||
|
|
||||||
|
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_GROUP received");
|
||||||
|
|
||||||
|
if (bignum_ctx_invalid(ctx)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->dh_handshake_state != DH_STATE_REQUEST_SENT) {
|
||||||
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
|
"Received DH_GEX_GROUP in invalid state");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
one = bignum_new();
|
||||||
|
pmin1 = bignum_new();
|
||||||
|
if (one == NULL || pmin1 == NULL) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
session->next_crypto->dh_group_is_mutable = 1;
|
||||||
|
rc = ssh_buffer_unpack(packet,
|
||||||
|
"BB",
|
||||||
|
&session->next_crypto->p,
|
||||||
|
&session->next_crypto->g);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_GROUP packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* basic checks */
|
||||||
|
rc = bignum_set_word(one, 1);
|
||||||
|
if (rc != 1) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
blen = bignum_num_bits(session->next_crypto->p);
|
||||||
|
if (blen < DH_PMIN || blen > DH_PMAX) {
|
||||||
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
|
"Invalid dh group parameter p: %d not in [%d:%d]",
|
||||||
|
blen,
|
||||||
|
DH_PMIN,
|
||||||
|
DH_PMAX);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (bignum_cmp(session->next_crypto->p, one) <= 0) {
|
||||||
|
/* p must be positive and preferably bigger than one */
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
|
||||||
|
}
|
||||||
|
if (!bignum_is_bit_set(session->next_crypto->p, 0)) {
|
||||||
|
/* p must be a prime and therefore not divisible by 2 */
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter p");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
bignum_sub(pmin1, session->next_crypto->p, one);
|
||||||
|
if (bignum_cmp(session->next_crypto->g, one) <= 0 ||
|
||||||
|
bignum_cmp(session->next_crypto->g, pmin1) > 0) {
|
||||||
|
/* generator must be at least 2 and smaller than p-1*/
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid dh group parameter g");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* compute and send DH public parameter */
|
||||||
|
rc = ssh_dh_generate_secret(session, session->next_crypto->x);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
session->next_crypto->e = bignum_new();
|
||||||
|
if (session->next_crypto->e == NULL) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
rc = bignum_mod_exp(session->next_crypto->e,
|
||||||
|
session->next_crypto->g,
|
||||||
|
session->next_crypto->x,
|
||||||
|
session->next_crypto->p,
|
||||||
|
ctx);
|
||||||
|
if (rc != 1) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bignum_ctx_free(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
|
||||||
|
rc = ssh_buffer_pack(session->out_buffer,
|
||||||
|
"bB",
|
||||||
|
SSH2_MSG_KEX_DH_GEX_INIT,
|
||||||
|
session->next_crypto->e);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->dh_handshake_state = DH_STATE_INIT_SENT;
|
||||||
|
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
|
||||||
|
bignum_safe_free(one);
|
||||||
|
bignum_safe_free(pmin1);
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
error:
|
||||||
|
bignum_safe_free(one);
|
||||||
|
bignum_safe_free(pmin1);
|
||||||
|
if(!bignum_ctx_invalid(ctx)) {
|
||||||
|
bignum_ctx_free(ctx);
|
||||||
|
}
|
||||||
|
ssh_dh_cleanup(session);
|
||||||
|
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||||
|
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply)
|
||||||
|
{
|
||||||
|
struct ssh_crypto_struct *crypto=session->next_crypto;
|
||||||
|
int rc;
|
||||||
|
ssh_string pubkey_blob = NULL;
|
||||||
|
(void)type;
|
||||||
|
(void)user;
|
||||||
|
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_DH_GEX_REPLY received");
|
||||||
|
|
||||||
|
ssh_packet_remove_callbacks(session, &ssh_dhgex_client_callbacks);
|
||||||
|
rc = ssh_buffer_unpack(packet,
|
||||||
|
"SBS",
|
||||||
|
&pubkey_blob, &crypto->f,
|
||||||
|
&crypto->dh_server_signature);
|
||||||
|
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid DH_GEX_REPLY packet");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
|
||||||
|
ssh_string_free(pubkey_blob);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_dh_build_k(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the MSG_NEWKEYS */
|
||||||
|
if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_packet_send(session);
|
||||||
|
if (rc == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||||
|
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||||
|
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
error:
|
||||||
|
ssh_dh_cleanup(session);
|
||||||
|
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||||
|
|
||||||
|
return SSH_PACKET_USED;
|
||||||
|
}
|
||||||
28
src/kex.c
28
src/kex.c
@@ -31,6 +31,7 @@
|
|||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/buffer.h"
|
#include "libssh/buffer.h"
|
||||||
#include "libssh/dh.h"
|
#include "libssh/dh.h"
|
||||||
|
#include "libssh/dh-gex.h"
|
||||||
#include "libssh/kex.h"
|
#include "libssh/kex.h"
|
||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
@@ -115,7 +116,13 @@
|
|||||||
|
|
||||||
#define CHACHA20 "chacha20-poly1305@openssh.com,"
|
#define CHACHA20 "chacha20-poly1305@openssh.com,"
|
||||||
|
|
||||||
#define KEY_EXCHANGE CURVE25519 ECDH "diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
|
#define KEY_EXCHANGE \
|
||||||
|
CURVE25519 \
|
||||||
|
ECDH \
|
||||||
|
"diffie-hellman-group18-sha512,diffie-hellman-group16-sha512," \
|
||||||
|
"diffie-hellman-group-exchange-sha256," \
|
||||||
|
"diffie-hellman-group14-sha1,diffie-hellman-group1-sha1," \
|
||||||
|
"diffie-hellman-group-exchange-sha1"
|
||||||
#define KEX_METHODS_SIZE 10
|
#define KEX_METHODS_SIZE 10
|
||||||
|
|
||||||
/* RFC 8308 */
|
/* RFC 8308 */
|
||||||
@@ -826,6 +833,10 @@ int ssh_kex_select_methods (ssh_session session){
|
|||||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP16_SHA512;
|
session->next_crypto->kex_type=SSH_KEX_DH_GROUP16_SHA512;
|
||||||
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
|
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
|
||||||
session->next_crypto->kex_type=SSH_KEX_DH_GROUP18_SHA512;
|
session->next_crypto->kex_type=SSH_KEX_DH_GROUP18_SHA512;
|
||||||
|
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
|
||||||
|
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA1;
|
||||||
|
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
|
||||||
|
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA256;
|
||||||
} 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], "ecdh-sha2-nistp384") == 0){
|
} else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
|
||||||
@@ -1080,6 +1091,19 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SSH_KEX_DH_GEX_SHA1:
|
||||||
|
case SSH_KEX_DH_GEX_SHA256:
|
||||||
|
rc = ssh_buffer_pack(buf,
|
||||||
|
"dddBBBB",
|
||||||
|
DH_PMIN, DH_PREQ, DH_PMAX,
|
||||||
|
session->next_crypto->p,
|
||||||
|
session->next_crypto->g,
|
||||||
|
session->next_crypto->e,
|
||||||
|
session->next_crypto->f);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
#ifdef HAVE_ECDH
|
#ifdef HAVE_ECDH
|
||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
case SSH_KEX_ECDH_SHA2_NISTP384:
|
case SSH_KEX_ECDH_SHA2_NISTP384:
|
||||||
@@ -1126,6 +1150,7 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
switch (session->next_crypto->kex_type) {
|
switch (session->next_crypto->kex_type) {
|
||||||
case SSH_KEX_DH_GROUP1_SHA1:
|
case SSH_KEX_DH_GROUP1_SHA1:
|
||||||
case SSH_KEX_DH_GROUP14_SHA1:
|
case SSH_KEX_DH_GROUP14_SHA1:
|
||||||
|
case SSH_KEX_DH_GEX_SHA1:
|
||||||
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
|
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
|
||||||
session->next_crypto->mac_type = SSH_MAC_SHA1;
|
session->next_crypto->mac_type = SSH_MAC_SHA1;
|
||||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||||
@@ -1139,6 +1164,7 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||||
case SSH_KEX_CURVE25519_SHA256:
|
case SSH_KEX_CURVE25519_SHA256:
|
||||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||||
|
case SSH_KEX_DH_GEX_SHA256:
|
||||||
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);
|
||||||
|
|||||||
@@ -388,6 +388,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
|||||||
* States required:
|
* States required:
|
||||||
* - session_state == SSH_SESSION_STATE_DH
|
* - session_state == SSH_SESSION_STATE_DH
|
||||||
* - dh_handshake_state == DH_STATE_INIT_SENT
|
* - dh_handshake_state == DH_STATE_INIT_SENT
|
||||||
|
* or dh_handshake_state == DH_STATE_REQUEST_SENT (dh-gex)
|
||||||
*
|
*
|
||||||
* Transitions:
|
* Transitions:
|
||||||
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
|
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
|
||||||
@@ -398,7 +399,8 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
|
if (session->dh_handshake_state != DH_STATE_INIT_SENT &&
|
||||||
|
session->dh_handshake_state != DH_STATE_REQUEST_SENT) {
|
||||||
rc = SSH_PACKET_DENIED;
|
rc = SSH_PACKET_DENIED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1273,6 +1275,10 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
|||||||
ssh_packet_process(session, session->in_packet.type);
|
ssh_packet_process(session, session->in_packet.type);
|
||||||
break;
|
break;
|
||||||
case SSH_PACKET_DENIED:
|
case SSH_PACKET_DENIED:
|
||||||
|
ssh_set_error(session,
|
||||||
|
SSH_FATAL,
|
||||||
|
"Packet filter: rejected packet (type %d)",
|
||||||
|
session->in_packet.type);
|
||||||
goto error;
|
goto error;
|
||||||
case SSH_PACKET_UNKNOWN:
|
case SSH_PACKET_UNKNOWN:
|
||||||
ssh_packet_send_unimplemented(session, session->recv_seq - 1);
|
ssh_packet_send_unimplemented(session, session->recv_seq - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user