660 lines
20 KiB
C
660 lines
20 KiB
C
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipssh_keyex_rsa.c,v $ $Revision: 1.4.12.3 $
|
|
* $Source: /home/interpeak/CVSRoot/ipssh/src/ipssh_keyex_rsa.c,v $
|
|
* $Author: jli7 $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Roger Boden <roger.boden@windriver.com>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include "ipssh_config.h"
|
|
|
|
#ifdef IPSSH_USE_KEYEX_RSA
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include <ipcom_type.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_err.h>
|
|
|
|
#include <ipcrypto.h>
|
|
#include <openssl/rand.h>
|
|
#include <openssl/sha.h>
|
|
|
|
#include "ipssh.h"
|
|
#include "ipssh_h.h"
|
|
#include "ipssh_buffer.h"
|
|
#include "ipssh_transport.h"
|
|
#include "ipssh_keyex_dh.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
IP_GLOBAL Ip_err ipssh_send_msg_kexrsa_pubkey(Ipssh_conn* ssh_conn);
|
|
IP_GLOBAL Ip_err ipssh_send_msg_kexrsa_done(Ipssh_conn* ssh_conn);
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_STATIC int
|
|
ipssh_kexrsa_get_hash_size(Ipssh_conn* ssh_conn)
|
|
{
|
|
switch(ssh_conn->conn_prop_pending.kex_alg[0])
|
|
{
|
|
case IPSSH_KEYEX_RSA1024_SHA1_ID:
|
|
return SHA_DIGEST_LENGTH;
|
|
case IPSSH_KEYEX_RSA2048_SHA256_ID:
|
|
return SHA256_DIGEST_LENGTH;
|
|
default:
|
|
IP_PANIC();
|
|
return 0;
|
|
}
|
|
}
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_send_msg_kexrsa_secret
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC Ip_err
|
|
ipssh_send_msg_kexrsa_secret(Ipssh_conn* ssh_conn, RSA* transient_key)
|
|
{
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
int encr_k_len;
|
|
int len;
|
|
Ip_u8* encr_k = IP_NULL;
|
|
Ip_u8* oaep_padded_shared_secret = IP_NULL;
|
|
Ip_u8* mpint_shared_secret = IP_NULL;
|
|
Ipcom_buffer* pkt = IP_NULL;
|
|
|
|
/* Generate random integer, K in rfc 4432, also known as shared secret */
|
|
ssh_conn->secr_len = RSA_size(transient_key) - 2*ipssh_kexrsa_get_hash_size(ssh_conn) - 7;
|
|
ssh_conn->shared_secret = ipcom_malloc(RSA_size(transient_key));
|
|
if (!ssh_conn->shared_secret)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: out of memory");
|
|
return IPCOM_ERR_NO_MEMORY;
|
|
}
|
|
if (!RAND_bytes(ssh_conn->shared_secret, ssh_conn->secr_len))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to get random bytes");
|
|
goto cleanup;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_MPINT,
|
|
ssh_conn->shared_secret,
|
|
ssh_conn->secr_len,
|
|
7))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to add K to hash list");
|
|
goto cleanup;
|
|
}
|
|
|
|
encr_k_len = RSA_size(transient_key);
|
|
encr_k = ipcom_malloc(encr_k_len);
|
|
oaep_padded_shared_secret = ipcom_malloc(encr_k_len);
|
|
mpint_shared_secret = ipcom_malloc(ssh_conn->secr_len+4);
|
|
if (!encr_k || !oaep_padded_shared_secret || !mpint_shared_secret)
|
|
goto cleanup;
|
|
IP_SET_HTONL(mpint_shared_secret, ssh_conn->secr_len);
|
|
ipcom_memcpy(mpint_shared_secret+4, ssh_conn->shared_secret, ssh_conn->secr_len);
|
|
ipcrypto_rsa_oaep_encode(ssh_conn->hash_func(), mpint_shared_secret, ssh_conn->secr_len+4, oaep_padded_shared_secret, encr_k_len);
|
|
len = RSA_public_encrypt(encr_k_len, oaep_padded_shared_secret, encr_k, transient_key, RSA_NO_PADDING);
|
|
if (len < 0)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to encrypt K");
|
|
goto cleanup;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_STR,
|
|
encr_k,
|
|
len,
|
|
6))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to add encrypted K to hash list");
|
|
goto cleanup;
|
|
}
|
|
|
|
pkt = ipssh_buffer_new_v2_pkt(encr_k_len+64, IPSSH_MSG_KEX_RSA_SECRET);
|
|
if (!pkt)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_secret :: failed to allocate pkt");
|
|
goto cleanup;
|
|
}
|
|
(void)ipssh_buffer_put_sshbuf(pkt, encr_k, encr_k_len);
|
|
|
|
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
|
|
|
cleanup:
|
|
if (encr_k)
|
|
ipcom_free(encr_k);
|
|
if (oaep_padded_shared_secret)
|
|
ipcom_free(oaep_padded_shared_secret);
|
|
if (mpint_shared_secret)
|
|
ipcom_free(mpint_shared_secret);
|
|
if(pkt)
|
|
ipcom_buffer_free(pkt);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_GLOBAL Ip_err
|
|
ipssh_msg_kexrsa_done(Ipssh_conn* ssh_conn)
|
|
{
|
|
char* sig_type = IP_NULL;
|
|
Ip_u8* signature = IP_NULL;
|
|
Ip_u32 sign_len;
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
|
|
if(ipssh_calc_hash((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
ssh_conn->hash_func,
|
|
8,
|
|
&(ssh_conn->hash),
|
|
&(ssh_conn->hash_len)))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: ipssh_calc_hash() failed");
|
|
goto cleanup;
|
|
}
|
|
|
|
if(ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6)) /* Skip headers */
|
|
goto cleanup;
|
|
|
|
/* Process signature */
|
|
if(ipcom_buffer_consume(ssh_conn->recv_plain_buf, 4)) /* Skip blob len field */
|
|
goto cleanup;
|
|
sig_type=ipssh_buffer_get_sshstr(ssh_conn->recv_plain_buf);
|
|
signature=ipssh_buffer_get_sshbuf(ssh_conn->recv_plain_buf, &sign_len);
|
|
if(!sig_type || !signature)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: failed to unpack signature");
|
|
goto cleanup;
|
|
}
|
|
|
|
/* Verify signature */
|
|
if(ipssh_verify_signature(ssh_conn->data.clt.srv_pub_key, ssh_conn->hash, ssh_conn->hash_len, sig_type, signature, sign_len) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: ipssh_verify_signature() failed");
|
|
goto cleanup;
|
|
}
|
|
|
|
if(ssh_conn->sess_id_len == 0)
|
|
{
|
|
ssh_conn->sess_id = ipcom_malloc(ssh_conn->hash_len);
|
|
if(!ssh_conn->sess_id)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_done :: out of memory");
|
|
goto cleanup;
|
|
}
|
|
ssh_conn->sess_id_len = ssh_conn->hash_len;
|
|
ipcom_memcpy(ssh_conn->sess_id, ssh_conn->hash, ssh_conn->sess_id_len);
|
|
}
|
|
|
|
rc = IPCOM_SUCCESS;
|
|
|
|
cleanup:
|
|
if (sig_type)
|
|
ipcom_free(sig_type);
|
|
if (signature)
|
|
ipcom_free(signature);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_msg_kexrsa_pubkey
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipssh_msg_kexrsa_pubkey(Ipssh_conn* ssh_conn)
|
|
{
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
EVP_PKEY* transient_key = IP_NULL;
|
|
Ip_u8* srv_key_ptr;
|
|
Ip_u8* transient_key_ptr;
|
|
|
|
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
|
srv_key_ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
|
ssh_conn->data.clt.srv_pub_key = ipssh_buffer_get_pub_key(ssh_conn->recv_plain_buf);
|
|
if (!ssh_conn->data.clt.srv_pub_key)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to unpack srv key");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_RAW,
|
|
srv_key_ptr,
|
|
ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - srv_key_ptr,
|
|
4))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to add host key to hash list");
|
|
goto cleanup;
|
|
}
|
|
|
|
transient_key_ptr = ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf);
|
|
transient_key = ipssh_buffer_get_pub_key(ssh_conn->recv_plain_buf);
|
|
if (!transient_key)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to unpack transient key");
|
|
goto cleanup;
|
|
}
|
|
if (transient_key->type != NID_rsaEncryption)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_msg_kexrsa_pubkey :: transient key not an RSA key: key type=%d",
|
|
transient_key->type);
|
|
goto cleanup;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_RAW,
|
|
transient_key_ptr,
|
|
ipcom_buffer_start_ptr(ssh_conn->recv_plain_buf) - transient_key_ptr,
|
|
5))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kexrsa_pubkey :: failed to add transient key to hash list");
|
|
goto cleanup;
|
|
}
|
|
|
|
rc = ipssh_send_msg_kexrsa_secret(ssh_conn, transient_key->pkey.rsa);
|
|
|
|
cleanup:
|
|
if (transient_key)
|
|
EVP_PKEY_free(transient_key);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_send_msg_kexrsa_pubkey
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipssh_send_msg_kexrsa_pubkey(Ipssh_conn* ssh_conn)
|
|
{
|
|
Ipcom_buffer* pkt;
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
Ip_size_t srv_key_pos;
|
|
Ip_size_t transient_key_pos;
|
|
|
|
pkt = ipssh_buffer_new_v2_pkt(1024, IPSSH_MSG_KEX_RSA_PUBKEY);
|
|
if (!pkt)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: out of memory");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
srv_key_pos = ipcom_buffer_end_pos(pkt);
|
|
switch(ssh_conn->conn_prop_pending.srv_host_key_alg[0])
|
|
{
|
|
case IPSSH_DSA_ID:
|
|
if (ipssh_buffer_put_dsa_key(pkt, ssh_conn->srv_dsa_key))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add srv dsa key to pkt");
|
|
goto cleanup;
|
|
}
|
|
break;
|
|
|
|
case IPSSH_RSA_ID:
|
|
if (ipssh_buffer_put_rsa_key(pkt, ssh_conn->srv_rsa_key))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add srv rsa key to pkt");
|
|
goto cleanup;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: unknown srv host key");
|
|
IP_PANIC();
|
|
goto cleanup;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_RAW,
|
|
(Ip_u8*)ipcom_buffer_ptr2pos(pkt, srv_key_pos),
|
|
ipcom_buffer_end_pos(pkt) - srv_key_pos,
|
|
4))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add host key to hash list");
|
|
goto cleanup;
|
|
}
|
|
|
|
transient_key_pos = ipcom_buffer_end_pos(pkt);
|
|
if (ipssh_buffer_put_rsa_key(pkt, ssh_conn->srv_rsa_keyex_key))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: out of memory");
|
|
goto cleanup;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_RAW,
|
|
(Ip_u8*)ipcom_buffer_ptr2pos(pkt, transient_key_pos),
|
|
ipcom_buffer_end_pos(pkt) - transient_key_pos,
|
|
5))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_pubkey :: failed to add transient key to hash list");
|
|
goto cleanup;
|
|
}
|
|
|
|
rc = ipssh_send_pkt(ssh_conn, pkt, IP_FALSE);
|
|
|
|
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_KEX_RSA;
|
|
|
|
cleanup:
|
|
ipcom_buffer_free(pkt);
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_send_msg_kexrsa_done
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipssh_send_msg_kexrsa_done(Ipssh_conn* ssh_conn)
|
|
{
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
Ipcom_buffer* pkt = IP_NULL;
|
|
|
|
if(ipssh_calc_hash((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
ssh_conn->hash_func,
|
|
8,
|
|
&(ssh_conn->hash),
|
|
&(ssh_conn->hash_len)))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: ipssh_calc_hash() failed");
|
|
goto failed;
|
|
}
|
|
if(ssh_conn->sess_id_len == 0)
|
|
{
|
|
ssh_conn->sess_id = ipcom_malloc(ssh_conn->hash_len);
|
|
if(!ssh_conn->sess_id)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: out of memory");
|
|
goto failed;
|
|
}
|
|
ssh_conn->sess_id_len = ssh_conn->hash_len;
|
|
ipcom_memcpy(ssh_conn->sess_id, ssh_conn->hash, ssh_conn->sess_id_len);
|
|
}
|
|
|
|
pkt = ipssh_buffer_new_v2_pkt(2048, IPSSH_MSG_KEX_RSA_DONE);
|
|
if (!pkt)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: failed to allocate pkt");
|
|
goto failed;
|
|
}
|
|
if (ipssh_sign_hash(ssh_conn, pkt) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: ipssh_sign_hash() failed");
|
|
goto failed;
|
|
}
|
|
|
|
if (ipssh_send_pkt(ssh_conn, pkt, IP_FALSE) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: failed to send SSH_MSG_NEW_KEY");
|
|
goto failed;
|
|
}
|
|
|
|
if(ipssh_compute_keys(ssh_conn))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: ipssh_compute_keys() failed");
|
|
goto failed;
|
|
}
|
|
|
|
if (ipssh_send_new_key_msg(ssh_conn) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_send_msg_kexrsa_done :: failed to send SSH_MSG_NEW_KEY");
|
|
goto failed;
|
|
}
|
|
|
|
rc = IPCOM_SUCCESS;
|
|
|
|
failed:
|
|
if (pkt)
|
|
ipcom_buffer_free(pkt);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
*
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipssh_msg_kex_rsa_secret(Ipssh_conn* ssh_conn)
|
|
{
|
|
Ip_u8* encr_shared_secret; /* K in rfc 4432 */
|
|
int len;
|
|
Ip_u8* shared_secret = IP_NULL;
|
|
Ip_u8* oaep_padded_shared_secret = IP_NULL;
|
|
Ip_err rc = IPCOM_ERR_FAILED;
|
|
|
|
(void)ipcom_buffer_consume(ssh_conn->recv_plain_buf, 6);
|
|
encr_shared_secret = ipssh_buffer_get_sshbuf(ssh_conn->recv_plain_buf, (Ip_u32*)&len);
|
|
if (!encr_shared_secret)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to unpack secret");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_STR,
|
|
encr_shared_secret,
|
|
len,
|
|
6))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to add encrypted K to hash list");
|
|
goto cleanup;
|
|
}
|
|
shared_secret = ipcom_malloc(RSA_size(ssh_conn->srv_rsa_keyex_key)+64);
|
|
oaep_padded_shared_secret = ipcom_malloc(RSA_size(ssh_conn->srv_rsa_keyex_key)+64);
|
|
if (!shared_secret || !oaep_padded_shared_secret)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: out of memory");
|
|
goto cleanup;
|
|
}
|
|
len = RSA_private_decrypt(len, encr_shared_secret, oaep_padded_shared_secret, ssh_conn->srv_rsa_keyex_key, RSA_NO_PADDING);
|
|
if (len < 0)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: RSA_private_decrypt failed");
|
|
goto cleanup;
|
|
}
|
|
if (ipcrypto_rsa_oaep_decode(ssh_conn->hash_func(), oaep_padded_shared_secret, len, shared_secret, (int*)&len) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to oaep decode shared secret");
|
|
goto cleanup;
|
|
}
|
|
if (len < 4)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipssh_msg_kex_rsa_secret :: invalid K lenght: %d", len);
|
|
goto cleanup;
|
|
}
|
|
ipcom_memmove(shared_secret, &shared_secret[4], len -4); /* Remove the length field */
|
|
len -= 4;
|
|
if (ipssh_msg2list((Ipssh_msg_list*)&(ssh_conn->handshake_msgs),
|
|
IPSSH_MPINT,
|
|
shared_secret,
|
|
len,
|
|
7))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_msg_kex_rsa_secret :: failed to add shared secret K to hash list");
|
|
goto cleanup;
|
|
}
|
|
ssh_conn->shared_secret = shared_secret;
|
|
shared_secret = IP_NULL;
|
|
ssh_conn->secr_len = len;
|
|
|
|
rc = ipssh_send_msg_kexrsa_done(ssh_conn);
|
|
|
|
ssh_conn->conn_state = IPSSH_CONN_STATE_SRV_NEW_KEY;
|
|
|
|
cleanup:
|
|
ipcom_free(encr_shared_secret);
|
|
if (shared_secret)
|
|
ipcom_free(shared_secret);
|
|
if (oaep_padded_shared_secret)
|
|
ipcom_free(oaep_padded_shared_secret);
|
|
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipssh_do_keyex_rsa_clt
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipssh_do_keyex_rsa_clt(Ipssh_conn* ssh_conn)
|
|
{
|
|
if (ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_KEX_RSA_PUBKEY) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to read SSH_MSG_KEY_RSA_PUBKEY");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if (ipssh_msg_kexrsa_pubkey(ssh_conn) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to process SSH_MSG_KEY_RSA_PUBKEY");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if (ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_KEX_RSA_DONE) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to read SSH_MSG_KEY_RSA_DONE");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if (ipssh_msg_kexrsa_done(ssh_conn) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to process SSH_MSG_KEY_RSA_DONE");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
if(ipssh_compute_keys(ssh_conn))
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: ipssh_compute_keys() failed");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
if (ipssh_send_new_key_msg(ssh_conn) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to send SSH_MSG_NEW_KEY");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if(ipssh_read_v2_pkt2(ssh_conn, IPSSH_MSG_NEWKEYS) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to read SSH_MSG_NEW_KEY");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
if(ipssh_msg_new_key(ssh_conn) != IPCOM_SUCCESS)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipssh_do_keyex_rsa_clt :: failed to process SSH_MSG_NEW_KEY");
|
|
return IPCOM_ERR_FAILED;
|
|
}
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
#else
|
|
int ipssh_keyex_rsa_empty_file;
|
|
#endif /* IPSSH_USE_RSA_KEYEX */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|