Add return values to generate_session_keys() and generate_one_key().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@508 7dcaeef0-15fb-0310-b436-a5af3365683c
Этот коммит содержится в:
родитель
ac38bbc138
Коммит
5b2586312a
@ -533,7 +533,7 @@ int make_sessionid(SSH_SESSION *session);
|
|||||||
/* add data for the final cookie */
|
/* add data for the final cookie */
|
||||||
int hashbufin_add_cookie(SSH_SESSION *session, unsigned char *cookie);
|
int hashbufin_add_cookie(SSH_SESSION *session, unsigned char *cookie);
|
||||||
int hashbufout_add_cookie(SSH_SESSION *session);
|
int hashbufout_add_cookie(SSH_SESSION *session);
|
||||||
void generate_session_keys(SSH_SESSION *session);
|
int generate_session_keys(SSH_SESSION *session);
|
||||||
/* returns 1 if server signature ok, 0 otherwise. The NEXT crypto is checked, not the current one */
|
/* returns 1 if server signature ok, 0 otherwise. The NEXT crypto is checked, not the current one */
|
||||||
int signature_verify(SSH_SESSION *session,STRING *signature);
|
int signature_verify(SSH_SESSION *session,STRING *signature);
|
||||||
bignum make_string_bn(STRING *string);
|
bignum make_string_bn(STRING *string);
|
||||||
|
@ -313,7 +313,10 @@ static int dh_handshake(SSH_SESSION *session) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_session_keys(session);
|
if (generate_session_keys(session) < 0) {
|
||||||
|
rc = SSH_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Verify the host's signature. FIXME do it sooner */
|
/* Verify the host's signature. FIXME do it sooner */
|
||||||
signature = session->dh_server_signature;
|
signature = session->dh_server_signature;
|
||||||
|
161
libssh/dh.c
161
libssh/dh.c
@ -662,80 +662,135 @@ int hashbufin_add_cookie(SSH_SESSION *session, unsigned char *cookie) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO FIXME add return value for memory checks */
|
static int generate_one_key(STRING *k,
|
||||||
static void generate_one_key(STRING *k,unsigned char session_id[SHA_DIGEST_LEN],unsigned char output[SHA_DIGEST_LEN],char letter){
|
unsigned char session_id[SHA_DIGEST_LEN],
|
||||||
SHACTX ctx=sha1_init();
|
unsigned char output[SHA_DIGEST_LEN],
|
||||||
|
char letter) {
|
||||||
|
SHACTX ctx = NULL;
|
||||||
|
|
||||||
|
ctx = sha1_init();
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
sha1_update(ctx,k,string_len(k)+4);
|
|
||||||
sha1_update(ctx,session_id,SHA_DIGEST_LEN);
|
sha1_update(ctx, k, string_len(k) + 4);
|
||||||
sha1_update(ctx,&letter,1);
|
sha1_update(ctx, session_id, SHA_DIGEST_LEN);
|
||||||
sha1_update(ctx,session_id,SHA_DIGEST_LEN);
|
sha1_update(ctx, &letter, 1);
|
||||||
sha1_final(output,ctx);
|
sha1_update(ctx, session_id, SHA_DIGEST_LEN);
|
||||||
|
sha1_final(output, ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO FIXME add return value for memory checks */
|
int generate_session_keys(SSH_SESSION *session) {
|
||||||
void generate_session_keys(SSH_SESSION *session){
|
STRING *k_string = NULL;
|
||||||
STRING *k_string;
|
SHACTX ctx = NULL;
|
||||||
SHACTX ctx;
|
int rc = -1;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
k_string=make_bignum_string(session->next_crypto->k);
|
|
||||||
|
k_string = make_bignum_string(session->next_crypto->k);
|
||||||
|
if (k_string == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* IV */
|
/* IV */
|
||||||
if(session->client){
|
if (session->client) {
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptIV,'A');
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptIV,'B');
|
session->next_crypto->encryptIV, 'A') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->decryptIV, 'B') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptIV,'A');
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptIV,'B');
|
session->next_crypto->decryptIV, 'A') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->encryptIV, 'B') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (session->client) {
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->encryptkey, 'C') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->decryptkey, 'D') < 0) {
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
if(session->client){
|
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptkey,'C');
|
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptkey,'D');
|
|
||||||
} else {
|
} else {
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptkey,'C');
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptkey,'D');
|
session->next_crypto->decryptkey, 'C') < 0) {
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
/* some ciphers need more than 20 bytes of input key */
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
/* XXX verify it's ok for server implementation */
|
session->next_crypto->encryptkey, 'D') < 0) {
|
||||||
if(session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN*8){
|
goto error;
|
||||||
ctx=sha1_init();
|
|
||||||
if (ctx == NULL) {
|
|
||||||
leave_function();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
sha1_update(ctx,k_string,string_len(k_string)+4);
|
|
||||||
sha1_update(ctx,session->next_crypto->session_id,SHA_DIGEST_LEN);
|
|
||||||
sha1_update(ctx,session->next_crypto->encryptkey,SHA_DIGEST_LEN);
|
|
||||||
sha1_final(session->next_crypto->encryptkey+SHA_DIGEST_LEN,ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(session->next_crypto->in_cipher->keysize > SHA_DIGEST_LEN*8){
|
/* some ciphers need more than 20 bytes of input key */
|
||||||
ctx=sha1_init();
|
/* XXX verify it's ok for server implementation */
|
||||||
sha1_update(ctx,k_string,string_len(k_string)+4);
|
if (session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN * 8) {
|
||||||
sha1_update(ctx,session->next_crypto->session_id,SHA_DIGEST_LEN);
|
ctx = sha1_init();
|
||||||
sha1_update(ctx,session->next_crypto->decryptkey,SHA_DIGEST_LEN);
|
if (ctx == NULL) {
|
||||||
sha1_final(session->next_crypto->decryptkey+SHA_DIGEST_LEN,ctx);
|
goto error;
|
||||||
|
}
|
||||||
|
sha1_update(ctx, k_string, string_len(k_string) + 4);
|
||||||
|
sha1_update(ctx, session->next_crypto->session_id, SHA_DIGEST_LEN);
|
||||||
|
sha1_update(ctx, session->next_crypto->encryptkey, SHA_DIGEST_LEN);
|
||||||
|
sha1_final(session->next_crypto->encryptkey + SHA_DIGEST_LEN, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->next_crypto->in_cipher->keysize > SHA_DIGEST_LEN * 8) {
|
||||||
|
ctx = sha1_init();
|
||||||
|
sha1_update(ctx, k_string, string_len(k_string) + 4);
|
||||||
|
sha1_update(ctx, session->next_crypto->session_id, SHA_DIGEST_LEN);
|
||||||
|
sha1_update(ctx, session->next_crypto->decryptkey, SHA_DIGEST_LEN);
|
||||||
|
sha1_final(session->next_crypto->decryptkey + SHA_DIGEST_LEN, ctx);
|
||||||
|
}
|
||||||
|
if(session->client) {
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->encryptMAC, 'E') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->decryptMAC, 'F') < 0) {
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
if(session->client){
|
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptMAC,'E');
|
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptMAC,'F');
|
|
||||||
} else {
|
} else {
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptMAC,'E');
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptMAC,'F');
|
session->next_crypto->decryptMAC, 'E') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (generate_one_key(k_string, session->next_crypto->session_id,
|
||||||
|
session->next_crypto->encryptMAC, 'F') < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_print_hexa("encrypt IV",session->next_crypto->encryptIV,SHA_DIGEST_LEN);
|
ssh_print_hexa("Encrypt IV", session->next_crypto->encryptIV, SHA_DIGEST_LEN);
|
||||||
ssh_print_hexa("decrypt IV",session->next_crypto->decryptIV,SHA_DIGEST_LEN);
|
ssh_print_hexa("Decrypt IV", session->next_crypto->decryptIV, SHA_DIGEST_LEN);
|
||||||
ssh_print_hexa("encryption key",session->next_crypto->encryptkey,session->next_crypto->out_cipher->keysize);
|
ssh_print_hexa("Encryption key", session->next_crypto->encryptkey,
|
||||||
ssh_print_hexa("decryption key",session->next_crypto->decryptkey,session->next_crypto->in_cipher->keysize);
|
session->next_crypto->out_cipher->keysize);
|
||||||
ssh_print_hexa("Encryption MAC",session->next_crypto->encryptMAC,SHA_DIGEST_LEN);
|
ssh_print_hexa("Decryption key", session->next_crypto->decryptkey,
|
||||||
ssh_print_hexa("Decryption MAC",session->next_crypto->decryptMAC,20);
|
session->next_crypto->in_cipher->keysize);
|
||||||
|
ssh_print_hexa("Encryption MAC", session->next_crypto->encryptMAC, SHA_DIGEST_LEN);
|
||||||
|
ssh_print_hexa("Decryption MAC", session->next_crypto->decryptMAC, 20);
|
||||||
#endif
|
#endif
|
||||||
free(k_string);
|
|
||||||
|
rc = 0;
|
||||||
|
error:
|
||||||
|
string_free(k_string);
|
||||||
leave_function();
|
leave_function();
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \addtogroup ssh_session
|
/** \addtogroup ssh_session
|
||||||
|
@ -330,7 +330,9 @@ static int dh_handshake_server(SSH_SESSION *session){
|
|||||||
|
|
||||||
packet_wait(session,SSH2_MSG_NEWKEYS,1);
|
packet_wait(session,SSH2_MSG_NEWKEYS,1);
|
||||||
ssh_log(session, SSH_LOG_PACKET, "Got SSH_MSG_NEWKEYS");
|
ssh_log(session, SSH_LOG_PACKET, "Got SSH_MSG_NEWKEYS");
|
||||||
generate_session_keys(session);
|
if (generate_session_keys(session) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* once we got SSH2_MSG_NEWKEYS we can switch next_crypto and current_crypto */
|
/* once we got SSH2_MSG_NEWKEYS we can switch next_crypto and current_crypto */
|
||||||
if(session->current_crypto)
|
if(session->current_crypto)
|
||||||
crypto_free(session->current_crypto);
|
crypto_free(session->current_crypto);
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user