mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-30 13:01:23 +03:00
packet: Introduce a new function to access crypto
And remove most of the direct access to the structure throughout the code Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Daiki Ueno <dueno@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
8d90266661
commit
8e0c047031
@@ -136,6 +136,7 @@ struct ssh_crypto_struct {
|
|||||||
char *kex_methods[SSH_KEX_METHODS];
|
char *kex_methods[SSH_KEX_METHODS];
|
||||||
enum ssh_key_exchange_e kex_type;
|
enum ssh_key_exchange_e kex_type;
|
||||||
enum ssh_mac_e mac_type; /* Mac operations to use for key gen */
|
enum ssh_mac_e mac_type; /* Mac operations to use for key gen */
|
||||||
|
enum ssh_crypto_direction_e used; /* Is this crypto still used for either of directions? */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_cipher_struct {
|
struct ssh_cipher_struct {
|
||||||
|
|||||||
@@ -83,5 +83,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session,
|
|||||||
unsigned int len);
|
unsigned int len);
|
||||||
int ssh_packet_hmac_verify(ssh_session session,ssh_buffer buffer,
|
int ssh_packet_hmac_verify(ssh_session session,ssh_buffer buffer,
|
||||||
unsigned char *mac, enum ssh_hmac_e type);
|
unsigned char *mac, enum ssh_hmac_e type);
|
||||||
|
struct ssh_crypto_struct *ssh_packet_get_current_crypto(ssh_session session,
|
||||||
|
enum ssh_crypto_direction_e direction);
|
||||||
|
|
||||||
#endif /* PACKET_H_ */
|
#endif /* PACKET_H_ */
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ struct ssh_hmac_struct {
|
|||||||
enum ssh_hmac_e hmac_type;
|
enum ssh_hmac_e hmac_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ssh_crypto_direction_e {
|
||||||
|
SSH_DIRECTION_IN = 1,
|
||||||
|
SSH_DIRECTION_OUT = 2,
|
||||||
|
SSH_DIRECTION_BOTH = 3,
|
||||||
|
};
|
||||||
|
|
||||||
struct ssh_cipher_struct;
|
struct ssh_cipher_struct;
|
||||||
|
|
||||||
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
|
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
|
||||||
|
|||||||
16
src/auth.c
16
src/auth.c
@@ -282,7 +282,10 @@ end:
|
|||||||
*
|
*
|
||||||
* It is also used to communicate the new to the upper levels.
|
* It is also used to communicate the new to the upper levels.
|
||||||
*/
|
*/
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
|
SSH_PACKET_CALLBACK(ssh_packet_userauth_success)
|
||||||
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
|
||||||
(void)packet;
|
(void)packet;
|
||||||
(void)type;
|
(void)type;
|
||||||
(void)user;
|
(void)user;
|
||||||
@@ -294,13 +297,16 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
|
|||||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||||
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
|
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
|
||||||
|
|
||||||
if (session->current_crypto && session->current_crypto->delayed_compress_out) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
|
||||||
|
if (crypto != NULL && crypto->delayed_compress_out) {
|
||||||
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression OUT");
|
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression OUT");
|
||||||
session->current_crypto->do_compress_out = 1;
|
crypto->do_compress_out = 1;
|
||||||
}
|
}
|
||||||
if (session->current_crypto && session->current_crypto->delayed_compress_in) {
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
|
if (crypto != NULL && crypto->delayed_compress_in) {
|
||||||
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression IN");
|
SSH_LOG(SSH_LOG_DEBUG, "Enabling delayed compression IN");
|
||||||
session->current_crypto->do_compress_in = 1;
|
crypto->do_compress_in = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset errors by previous authentication methods. */
|
/* Reset errors by previous authentication methods. */
|
||||||
|
|||||||
11
src/gssapi.c
11
src/gssapi.c
@@ -435,8 +435,10 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
|||||||
|
|
||||||
#endif /* WITH_SERVER */
|
#endif /* WITH_SERVER */
|
||||||
|
|
||||||
static ssh_buffer ssh_gssapi_build_mic(ssh_session session){
|
static ssh_buffer ssh_gssapi_build_mic(ssh_session session)
|
||||||
ssh_buffer mic_buffer;
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
ssh_buffer mic_buffer = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mic_buffer = ssh_buffer_new();
|
mic_buffer = ssh_buffer_new();
|
||||||
@@ -445,10 +447,11 @@ static ssh_buffer ssh_gssapi_build_mic(ssh_session session){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
|
||||||
rc = ssh_buffer_pack(mic_buffer,
|
rc = ssh_buffer_pack(mic_buffer,
|
||||||
"dPbsss",
|
"dPbsss",
|
||||||
session->current_crypto->digest_len,
|
crypto->digest_len,
|
||||||
(size_t)session->current_crypto->digest_len, session->current_crypto->session_id,
|
(size_t)crypto->digest_len, crypto->session_id,
|
||||||
SSH2_MSG_USERAUTH_REQUEST,
|
SSH2_MSG_USERAUTH_REQUEST,
|
||||||
session->gssapi->user,
|
session->gssapi->user,
|
||||||
"ssh-connection",
|
"ssh-connection",
|
||||||
|
|||||||
20
src/gzip.c
20
src/gzip.c
@@ -55,8 +55,10 @@ static z_stream *initcompress(ssh_session session, int level) {
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int level){
|
static ssh_buffer gzip_compress(ssh_session session, ssh_buffer source, int level)
|
||||||
z_stream *zout = session->current_crypto->compress_out_ctx;
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
z_stream *zout = NULL;
|
||||||
void *in_ptr = ssh_buffer_get(source);
|
void *in_ptr = ssh_buffer_get(source);
|
||||||
unsigned long in_size = ssh_buffer_get_len(source);
|
unsigned long in_size = ssh_buffer_get_len(source);
|
||||||
ssh_buffer dest = NULL;
|
ssh_buffer dest = NULL;
|
||||||
@@ -64,8 +66,10 @@ static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int level)
|
|||||||
unsigned long len;
|
unsigned long len;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
|
||||||
|
zout = crypto->compress_out_ctx;
|
||||||
if (zout == NULL) {
|
if (zout == NULL) {
|
||||||
zout = session->current_crypto->compress_out_ctx = initcompress(session, level);
|
zout = crypto->compress_out_ctx = initcompress(session, level);
|
||||||
if (zout == NULL) {
|
if (zout == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -143,8 +147,10 @@ static z_stream *initdecompress(ssh_session session) {
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t maxlen) {
|
static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t maxlen)
|
||||||
z_stream *zin = session->current_crypto->compress_in_ctx;
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
z_stream *zin = NULL;
|
||||||
void *in_ptr = ssh_buffer_get(source);
|
void *in_ptr = ssh_buffer_get(source);
|
||||||
unsigned long in_size = ssh_buffer_get_len(source);
|
unsigned long in_size = ssh_buffer_get_len(source);
|
||||||
unsigned char out_buf[BLOCKSIZE] = {0};
|
unsigned char out_buf[BLOCKSIZE] = {0};
|
||||||
@@ -152,8 +158,10 @@ static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t
|
|||||||
unsigned long len;
|
unsigned long len;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
|
zin = crypto->compress_in_ctx;
|
||||||
if (zin == NULL) {
|
if (zin == NULL) {
|
||||||
zin = session->current_crypto->compress_in_ctx = initdecompress(session);
|
zin = crypto->compress_in_ctx = initdecompress(session);
|
||||||
if (zin == NULL) {
|
if (zin == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -683,13 +683,13 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
|
|||||||
const char *service,
|
const char *service,
|
||||||
ssh_string algo)
|
ssh_string algo)
|
||||||
{
|
{
|
||||||
struct ssh_crypto_struct *crypto =
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
session->current_crypto ? session->current_crypto :
|
|
||||||
session->next_crypto;
|
|
||||||
ssh_buffer buffer;
|
ssh_buffer buffer;
|
||||||
ssh_string str=NULL;
|
ssh_string str=NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
|
|
||||||
buffer = ssh_buffer_new();
|
buffer = ssh_buffer_new();
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
69
src/packet.c
69
src/packet.c
@@ -927,6 +927,18 @@ end:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns current_crypto structure from the session.
|
||||||
|
* During key exchange (or rekey), after one of the sides
|
||||||
|
* sending NEWKEYS packet, this might return next_crypto for one
|
||||||
|
* of the directions that is ahead to send already queued packets
|
||||||
|
*/
|
||||||
|
struct ssh_crypto_struct *
|
||||||
|
ssh_packet_get_current_crypto(ssh_session session,
|
||||||
|
enum ssh_crypto_direction_e direction)
|
||||||
|
{
|
||||||
|
return session->current_crypto;
|
||||||
|
}
|
||||||
|
|
||||||
/* in nonblocking mode, socket_read will read as much as it can, and return */
|
/* in nonblocking mode, socket_read will read as much as it can, and return */
|
||||||
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
|
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
|
||||||
/* in blocking mode, it will read at least len bytes and will block until it's ok. */
|
/* in blocking mode, it will read at least len bytes and will block until it's ok. */
|
||||||
@@ -942,10 +954,8 @@ end:
|
|||||||
int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
||||||
{
|
{
|
||||||
ssh_session session = (ssh_session)user;
|
ssh_session session = (ssh_session)user;
|
||||||
unsigned int blocksize = (session->current_crypto ?
|
unsigned int blocksize = 8;
|
||||||
session->current_crypto->in_cipher->blocksize : 8);
|
unsigned int lenfield_blocksize = 8;
|
||||||
unsigned int lenfield_blocksize = (session->current_crypto ?
|
|
||||||
session->current_crypto->in_cipher->lenfield_blocksize : 8);
|
|
||||||
size_t current_macsize = 0;
|
size_t current_macsize = 0;
|
||||||
uint8_t *ptr = NULL;
|
uint8_t *ptr = NULL;
|
||||||
int to_be_read;
|
int to_be_read;
|
||||||
@@ -958,10 +968,15 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
|||||||
uint8_t padding;
|
uint8_t padding;
|
||||||
size_t processed = 0; /* number of byte processed from the callback */
|
size_t processed = 0; /* number of byte processed from the callback */
|
||||||
enum ssh_packet_filter_result_e filter_result;
|
enum ssh_packet_filter_result_e filter_result;
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
|
||||||
if (session->current_crypto != NULL) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
|
if (crypto != NULL) {
|
||||||
|
current_macsize = hmac_digest_len(crypto->in_hmac);
|
||||||
|
blocksize = crypto->in_cipher->blocksize;
|
||||||
|
lenfield_blocksize = crypto->in_cipher->lenfield_blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lenfield_blocksize == 0) {
|
if (lenfield_blocksize == 0) {
|
||||||
lenfield_blocksize = blocksize;
|
lenfield_blocksize = blocksize;
|
||||||
}
|
}
|
||||||
@@ -1073,7 +1088,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet_second_block != NULL) {
|
if (packet_second_block != NULL) {
|
||||||
if (session->current_crypto != NULL) {
|
if (crypto != NULL) {
|
||||||
/*
|
/*
|
||||||
* Decrypt the rest of the packet (lenfield_blocksize bytes
|
* Decrypt the rest of the packet (lenfield_blocksize bytes
|
||||||
* already have been decrypted)
|
* already have been decrypted)
|
||||||
@@ -1096,7 +1111,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
|||||||
rc = ssh_packet_hmac_verify(session,
|
rc = ssh_packet_hmac_verify(session,
|
||||||
session->in_buffer,
|
session->in_buffer,
|
||||||
mac,
|
mac,
|
||||||
session->current_crypto->in_hmac);
|
crypto->in_hmac);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1142,8 +1157,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
|||||||
compsize = ssh_buffer_get_len(session->in_buffer);
|
compsize = ssh_buffer_get_len(session->in_buffer);
|
||||||
|
|
||||||
#ifdef WITH_ZLIB
|
#ifdef WITH_ZLIB
|
||||||
if (session->current_crypto
|
if (crypto && crypto->do_compress_in
|
||||||
&& session->current_crypto->do_compress_in
|
|
||||||
&& ssh_buffer_get_len(session->in_buffer) > 0) {
|
&& ssh_buffer_get_len(session->in_buffer) > 0) {
|
||||||
rc = decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN);
|
rc = decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -1153,10 +1167,10 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
|||||||
#endif /* WITH_ZLIB */
|
#endif /* WITH_ZLIB */
|
||||||
payloadsize = ssh_buffer_get_len(session->in_buffer);
|
payloadsize = ssh_buffer_get_len(session->in_buffer);
|
||||||
session->recv_seq++;
|
session->recv_seq++;
|
||||||
if (session->current_crypto != NULL) {
|
if (crypto != NULL) {
|
||||||
struct ssh_cipher_struct *cipher = NULL;
|
struct ssh_cipher_struct *cipher = NULL;
|
||||||
|
|
||||||
cipher = session->current_crypto->in_cipher;
|
cipher = crypto->in_cipher;
|
||||||
cipher->packets++;
|
cipher->packets++;
|
||||||
cipher->blocks += payloadsize / cipher->blocksize;
|
cipher->blocks += payloadsize / cipher->blocksize;
|
||||||
}
|
}
|
||||||
@@ -1407,16 +1421,11 @@ static int ssh_packet_write(ssh_session session) {
|
|||||||
|
|
||||||
static int packet_send2(ssh_session session)
|
static int packet_send2(ssh_session session)
|
||||||
{
|
{
|
||||||
unsigned int blocksize =
|
unsigned int blocksize = 8;
|
||||||
(session->current_crypto ?
|
unsigned int lenfield_blocksize = 0;
|
||||||
session->current_crypto->out_cipher->blocksize : 8);
|
enum ssh_hmac_e hmac_type;
|
||||||
unsigned int lenfield_blocksize =
|
|
||||||
(session->current_crypto ?
|
|
||||||
session->current_crypto->out_cipher->lenfield_blocksize : 0);
|
|
||||||
enum ssh_hmac_e hmac_type =
|
|
||||||
(session->current_crypto ?
|
|
||||||
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
|
|
||||||
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
|
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
unsigned char *hmac = NULL;
|
unsigned char *hmac = NULL;
|
||||||
uint8_t padding_data[32] = { 0 };
|
uint8_t padding_data[32] = { 0 };
|
||||||
uint8_t padding_size;
|
uint8_t padding_size;
|
||||||
@@ -1424,10 +1433,18 @@ static int packet_send2(ssh_session session)
|
|||||||
uint8_t header[5] = {0};
|
uint8_t header[5] = {0};
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
|
||||||
|
if (crypto) {
|
||||||
|
blocksize = crypto->out_cipher->blocksize;
|
||||||
|
lenfield_blocksize = crypto->out_cipher->lenfield_blocksize;
|
||||||
|
hmac_type = crypto->out_hmac;
|
||||||
|
} else {
|
||||||
|
hmac_type = session->next_crypto->out_hmac;
|
||||||
|
}
|
||||||
|
|
||||||
payloadsize = currentlen;
|
payloadsize = currentlen;
|
||||||
#ifdef WITH_ZLIB
|
#ifdef WITH_ZLIB
|
||||||
if (session->current_crypto != NULL &&
|
if (crypto != NULL && crypto->do_compress_out &&
|
||||||
session->current_crypto->do_compress_out &&
|
|
||||||
ssh_buffer_get_len(session->out_buffer) > 0) {
|
ssh_buffer_get_len(session->out_buffer) > 0) {
|
||||||
rc = compress_buffer(session,session->out_buffer);
|
rc = compress_buffer(session,session->out_buffer);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -1444,7 +1461,7 @@ static int packet_send2(ssh_session session)
|
|||||||
padding_size += blocksize;
|
padding_size += blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->current_crypto != NULL) {
|
if (crypto != NULL) {
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
ok = ssh_get_random(padding_data, padding_size, 0);
|
ok = ssh_get_random(padding_data, padding_size, 0);
|
||||||
@@ -1495,10 +1512,10 @@ static int packet_send2(ssh_session session)
|
|||||||
|
|
||||||
rc = ssh_packet_write(session);
|
rc = ssh_packet_write(session);
|
||||||
session->send_seq++;
|
session->send_seq++;
|
||||||
if (session->current_crypto != NULL) {
|
if (crypto != NULL) {
|
||||||
struct ssh_cipher_struct *cipher = NULL;
|
struct ssh_cipher_struct *cipher = NULL;
|
||||||
|
|
||||||
cipher = session->current_crypto->out_cipher;
|
cipher = crypto->out_cipher;
|
||||||
cipher->packets++;
|
cipher->packets++;
|
||||||
cipher->blocks += payloadsize / cipher->blocksize;
|
cipher->blocks += payloadsize / cipher->blocksize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,14 +52,16 @@ uint32_t ssh_packet_decrypt_len(ssh_session session,
|
|||||||
uint8_t *destination,
|
uint8_t *destination,
|
||||||
uint8_t *source)
|
uint8_t *source)
|
||||||
{
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
uint32_t decrypted;
|
uint32_t decrypted;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (session->current_crypto != NULL) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
if (session->current_crypto->in_cipher->aead_decrypt_length != NULL) {
|
if (crypto != NULL) {
|
||||||
session->current_crypto->in_cipher->aead_decrypt_length(
|
if (crypto->in_cipher->aead_decrypt_length != NULL) {
|
||||||
session->current_crypto->in_cipher, source, destination,
|
crypto->in_cipher->aead_decrypt_length(
|
||||||
session->current_crypto->in_cipher->lenfield_blocksize,
|
crypto->in_cipher, source, destination,
|
||||||
|
crypto->in_cipher->lenfield_blocksize,
|
||||||
session->recv_seq);
|
session->recv_seq);
|
||||||
} else {
|
} else {
|
||||||
rc = ssh_packet_decrypt(
|
rc = ssh_packet_decrypt(
|
||||||
@@ -67,7 +69,7 @@ uint32_t ssh_packet_decrypt_len(ssh_session session,
|
|||||||
destination,
|
destination,
|
||||||
source,
|
source,
|
||||||
0,
|
0,
|
||||||
session->current_crypto->in_cipher->blocksize);
|
crypto->in_cipher->blocksize);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -92,13 +94,17 @@ int ssh_packet_decrypt(ssh_session session,
|
|||||||
size_t start,
|
size_t start,
|
||||||
size_t encrypted_size)
|
size_t encrypted_size)
|
||||||
{
|
{
|
||||||
struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher;
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
struct ssh_cipher_struct *cipher = NULL;
|
||||||
|
|
||||||
if (encrypted_size <= 0) {
|
if (encrypted_size <= 0) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encrypted_size % session->current_crypto->in_cipher->blocksize != 0) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
|
cipher = crypto->in_cipher;
|
||||||
|
|
||||||
|
if (encrypted_size % cipher->blocksize != 0) {
|
||||||
ssh_set_error(session,
|
ssh_set_error(session,
|
||||||
SSH_FATAL,
|
SSH_FATAL,
|
||||||
"Cryptographic functions must be used on multiple of "
|
"Cryptographic functions must be used on multiple of "
|
||||||
@@ -107,34 +113,41 @@ int ssh_packet_decrypt(ssh_session session,
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crypto->aead_decrypt != NULL) {
|
if (cipher->aead_decrypt != NULL) {
|
||||||
return crypto->aead_decrypt(crypto,
|
return cipher->aead_decrypt(cipher,
|
||||||
source,
|
source,
|
||||||
destination,
|
destination,
|
||||||
encrypted_size,
|
encrypted_size,
|
||||||
session->recv_seq);
|
session->recv_seq);
|
||||||
} else {
|
} else {
|
||||||
crypto->decrypt(crypto, source + start, destination, encrypted_size);
|
cipher->decrypt(cipher, source + start, destination, encrypted_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len) {
|
unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
||||||
struct ssh_cipher_struct *crypto = NULL;
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
|
struct ssh_cipher_struct *cipher = NULL;
|
||||||
HMACCTX ctx = NULL;
|
HMACCTX ctx = NULL;
|
||||||
char *out = NULL;
|
char *out = NULL;
|
||||||
unsigned int finallen;
|
unsigned int finallen, blocksize;
|
||||||
uint32_t seq;
|
uint32_t seq, lenfield_blocksize;
|
||||||
enum ssh_hmac_e type;
|
enum ssh_hmac_e type;
|
||||||
|
|
||||||
assert(len);
|
assert(len);
|
||||||
|
|
||||||
if (!session->current_crypto) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
|
||||||
|
if (crypto == NULL) {
|
||||||
return NULL; /* nothing to do here */
|
return NULL; /* nothing to do here */
|
||||||
}
|
}
|
||||||
if((len - session->current_crypto->out_cipher->lenfield_blocksize) % session->current_crypto->out_cipher->blocksize != 0){
|
|
||||||
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
|
blocksize = crypto->out_cipher->blocksize;
|
||||||
|
lenfield_blocksize = crypto->out_cipher->lenfield_blocksize;
|
||||||
|
if ((len - lenfield_blocksize) % blocksize != 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set"
|
||||||
|
" on at least one blocksize (received %d)", len);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
out = malloc(len);
|
out = malloc(len);
|
||||||
@@ -142,37 +155,37 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = session->current_crypto->out_hmac;
|
type = crypto->out_hmac;
|
||||||
seq = ntohl(session->send_seq);
|
seq = ntohl(session->send_seq);
|
||||||
crypto = session->current_crypto->out_cipher;
|
cipher = crypto->out_cipher;
|
||||||
|
|
||||||
if (crypto->aead_encrypt != NULL) {
|
if (cipher->aead_encrypt != NULL) {
|
||||||
crypto->aead_encrypt(crypto, data, out, len,
|
cipher->aead_encrypt(cipher, data, out, len,
|
||||||
session->current_crypto->hmacbuf, session->send_seq);
|
crypto->hmacbuf, session->send_seq);
|
||||||
} else {
|
} else {
|
||||||
ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
|
ctx = hmac_init(crypto->encryptMAC, hmac_digest_len(type), type);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
SAFE_FREE(out);
|
SAFE_FREE(out);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t));
|
hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t));
|
||||||
hmac_update(ctx,data,len);
|
hmac_update(ctx,data,len);
|
||||||
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
|
hmac_final(ctx, crypto->hmacbuf, &finallen);
|
||||||
|
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_print_hexa("mac: ",data,hmac_digest_len(type));
|
ssh_print_hexa("mac: ",data,hmac_digest_len(type));
|
||||||
if (finallen != hmac_digest_len(type)) {
|
if (finallen != hmac_digest_len(type)) {
|
||||||
printf("Final len is %d\n",finallen);
|
printf("Final len is %d\n",finallen);
|
||||||
}
|
}
|
||||||
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
|
ssh_print_hexa("Packet hmac", crypto->hmacbuf, hmac_digest_len(type));
|
||||||
#endif
|
#endif
|
||||||
crypto->encrypt(crypto, data, out, len);
|
cipher->encrypt(cipher, data, out, len);
|
||||||
}
|
}
|
||||||
memcpy(data, out, len);
|
memcpy(data, out, len);
|
||||||
explicit_bzero(out, len);
|
explicit_bzero(out, len);
|
||||||
SAFE_FREE(out);
|
SAFE_FREE(out);
|
||||||
|
|
||||||
return session->current_crypto->hmacbuf;
|
return crypto->hmacbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -192,6 +205,7 @@ int ssh_packet_hmac_verify(ssh_session session,
|
|||||||
uint8_t *mac,
|
uint8_t *mac,
|
||||||
enum ssh_hmac_e type)
|
enum ssh_hmac_e type)
|
||||||
{
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
||||||
HMACCTX ctx;
|
HMACCTX ctx;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@@ -203,7 +217,8 @@ int ssh_packet_hmac_verify(ssh_session session,
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type);
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
|
ctx = hmac_init(crypto->decryptMAC, hmac_digest_len(type), type);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/pki.c
21
src/pki.c
@@ -2009,10 +2009,9 @@ int ssh_pki_signature_verify(ssh_session session,
|
|||||||
* the content of sigbuf */
|
* the content of sigbuf */
|
||||||
ssh_string ssh_pki_do_sign(ssh_session session,
|
ssh_string ssh_pki_do_sign(ssh_session session,
|
||||||
ssh_buffer sigbuf,
|
ssh_buffer sigbuf,
|
||||||
const ssh_key privkey) {
|
const ssh_key privkey)
|
||||||
struct ssh_crypto_struct *crypto =
|
{
|
||||||
session->current_crypto ? session->current_crypto :
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
session->next_crypto;
|
|
||||||
ssh_signature sig = NULL;
|
ssh_signature sig = NULL;
|
||||||
ssh_string sig_blob;
|
ssh_string sig_blob;
|
||||||
ssh_string session_id;
|
ssh_string session_id;
|
||||||
@@ -2022,6 +2021,7 @@ ssh_string ssh_pki_do_sign(ssh_session session,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
|
||||||
session_id = ssh_string_new(crypto->digest_len);
|
session_id = ssh_string_new(crypto->digest_len);
|
||||||
if (session_id == NULL) {
|
if (session_id == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -2144,18 +2144,15 @@ ssh_string ssh_pki_do_sign(ssh_session session,
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
||||||
struct ssh_buffer_struct *buf,
|
struct ssh_buffer_struct *buf,
|
||||||
const ssh_key pubkey) {
|
const ssh_key pubkey)
|
||||||
struct ssh_crypto_struct *crypto;
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
ssh_string session_id;
|
ssh_string session_id;
|
||||||
ssh_string sig_blob;
|
ssh_string sig_blob;
|
||||||
ssh_buffer sig_buf;
|
ssh_buffer sig_buf;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (session->current_crypto) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
|
||||||
crypto = session->current_crypto;
|
|
||||||
} else {
|
|
||||||
crypto = session->next_crypto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepend session identifier */
|
/* prepend session identifier */
|
||||||
session_id = ssh_string_new(crypto->digest_len);
|
session_id = ssh_string_new(crypto->digest_len);
|
||||||
@@ -2197,7 +2194,7 @@ ssh_string ssh_pki_do_sign_agent(ssh_session session,
|
|||||||
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||||
const ssh_key privkey)
|
const ssh_key privkey)
|
||||||
{
|
{
|
||||||
struct ssh_crypto_struct *crypto;
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
ssh_signature sig = NULL;
|
ssh_signature sig = NULL;
|
||||||
ssh_string sig_blob;
|
ssh_string sig_blob;
|
||||||
int rc;
|
int rc;
|
||||||
|
|||||||
11
src/server.c
11
src/server.c
@@ -1048,6 +1048,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
|
|||||||
|
|
||||||
int ssh_auth_reply_success(ssh_session session, int partial)
|
int ssh_auth_reply_success(ssh_session session, int partial)
|
||||||
{
|
{
|
||||||
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
@@ -1068,14 +1069,16 @@ int ssh_auth_reply_success(ssh_session session, int partial)
|
|||||||
|
|
||||||
r = ssh_packet_send(session);
|
r = ssh_packet_send(session);
|
||||||
|
|
||||||
if (session->current_crypto && session->current_crypto->delayed_compress_out) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
|
||||||
|
if (crypto != NULL && crypto->delayed_compress_out) {
|
||||||
SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression OUT");
|
SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression OUT");
|
||||||
session->current_crypto->do_compress_out = 1;
|
crypto->do_compress_out = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->current_crypto && session->current_crypto->delayed_compress_in) {
|
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||||
|
if (crypto != NULL && crypto->delayed_compress_in) {
|
||||||
SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression IN");
|
SSH_LOG(SSH_LOG_PROTOCOL, "Enabling delayed compression IN");
|
||||||
session->current_crypto->do_compress_in = 1;
|
crypto->do_compress_in = 1;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user