1
1

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
Этот коммит содержится в:
Andreas Schneider 2009-04-16 15:14:15 +00:00
родитель ac38bbc138
Коммит 5b2586312a
4 изменённых файлов: 128 добавлений и 68 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -662,48 +662,84 @@ 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, k, string_len(k) + 4);
sha1_update(ctx, session_id, SHA_DIGEST_LEN); sha1_update(ctx, session_id, SHA_DIGEST_LEN);
sha1_update(ctx, &letter, 1); sha1_update(ctx, &letter, 1);
sha1_update(ctx, session_id, SHA_DIGEST_LEN); sha1_update(ctx, session_id, SHA_DIGEST_LEN);
sha1_final(output, ctx); 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 (session->client) {
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptkey,'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->decryptkey,'D'); session->next_crypto->encryptkey, 'C') < 0) {
} else { goto error;
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->decryptkey,'C');
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptkey,'D');
} }
if (generate_one_key(k_string, session->next_crypto->session_id,
session->next_crypto->decryptkey, 'D') < 0) {
goto error;
}
} else {
if (generate_one_key(k_string, session->next_crypto->session_id,
session->next_crypto->decryptkey, 'C') < 0) {
goto error;
}
if (generate_one_key(k_string, session->next_crypto->session_id,
session->next_crypto->encryptkey, 'D') < 0) {
goto error;
}
}
/* some ciphers need more than 20 bytes of input key */ /* some ciphers need more than 20 bytes of input key */
/* XXX verify it's ok for server implementation */ /* XXX verify it's ok for server implementation */
if (session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN * 8) { if (session->next_crypto->out_cipher->keysize > SHA_DIGEST_LEN * 8) {
ctx = sha1_init(); ctx = sha1_init();
if (ctx == NULL) { if (ctx == NULL) {
leave_function(); goto error;
return;
} }
sha1_update(ctx, k_string, string_len(k_string) + 4); 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->session_id, SHA_DIGEST_LEN);
@ -719,23 +755,42 @@ void generate_session_keys(SSH_SESSION *session){
sha1_final(session->next_crypto->decryptkey + SHA_DIGEST_LEN, ctx); sha1_final(session->next_crypto->decryptkey + SHA_DIGEST_LEN, ctx);
} }
if(session->client) { if(session->client) {
generate_one_key(k_string,session->next_crypto->session_id,session->next_crypto->encryptMAC,'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->decryptMAC,'F'); 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;
}
} 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("Decryption key", session->next_crypto->decryptkey,
session->next_crypto->in_cipher->keysize);
ssh_print_hexa("Encryption MAC", session->next_crypto->encryptMAC, SHA_DIGEST_LEN); ssh_print_hexa("Encryption MAC", session->next_crypto->encryptMAC, SHA_DIGEST_LEN);
ssh_print_hexa("Decryption MAC", session->next_crypto->decryptMAC, 20); 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);