(trunk libT) #1776: crash in tr_cryptoComputeSecret()

This commit is contained in:
Charles Kerr 2009-02-10 15:54:47 +00:00
parent e3e2314418
commit 9727985836
1 changed files with 47 additions and 17 deletions

View File

@ -1,5 +1,4 @@
/* /* * This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com>
* This file Copyright (C) 2007-2009 Charles Kerr <charles@transmissionbt.com>
* *
* This file is licensed by the GPL version 2. Works owned by the * This file is licensed by the GPL version 2. Works owned by the
* Transmission project are granted a special exemption to clause 2(b) * Transmission project are granted a special exemption to clause 2(b)
@ -21,6 +20,7 @@
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/dh.h> #include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/rc4.h> #include <openssl/rc4.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/rand.h> #include <openssl/rand.h>
@ -30,6 +30,8 @@
#include "crypto.h" #include "crypto.h"
#include "utils.h" #include "utils.h"
#define MY_NAME "tr_crypto"
/** /**
*** ***
**/ **/
@ -97,6 +99,15 @@ struct tr_crypto
*** ***
**/ **/
#define logErrorFromSSL( ... ) \
do { \
if( tr_msgLoggingIsActive( TR_MSG_ERR ) ) { \
char buf[512]; \
ERR_error_string_n( ERR_get_error( ), buf, sizeof( buf ) ); \
tr_msg( __FILE__, __LINE__, TR_MSG_ERR, MY_NAME, "%s", buf ); \
} \
} while( 0 )
static DH* static DH*
getSharedDH( void ) getSharedDH( void )
{ {
@ -105,9 +116,17 @@ getSharedDH( void )
if( dh == NULL ) if( dh == NULL )
{ {
dh = DH_new( ); dh = DH_new( );
dh->p = BN_bin2bn( dh_P, sizeof( dh_P ), NULL ); dh->p = BN_bin2bn( dh_P, sizeof( dh_P ), NULL );
if( dh->p == NULL )
logErrorFromSSL( );
dh->g = BN_bin2bn( dh_G, sizeof( dh_G ), NULL ); dh->g = BN_bin2bn( dh_G, sizeof( dh_G ), NULL );
DH_generate_key( dh ); if( dh->g == NULL )
logErrorFromSSL( );
if( !DH_generate_key( dh ) )
logErrorFromSSL( );
} }
return dh; return dh;
@ -151,7 +170,7 @@ const uint8_t*
tr_cryptoComputeSecret( tr_crypto * crypto, tr_cryptoComputeSecret( tr_crypto * crypto,
const uint8_t * peerPublicKey ) const uint8_t * peerPublicKey )
{ {
int len, offset; int len;
uint8_t secret[KEY_LEN]; uint8_t secret[KEY_LEN];
BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL ); BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL );
DH * dh = getSharedDH( ); DH * dh = getSharedDH( );
@ -159,14 +178,18 @@ tr_cryptoComputeSecret( tr_crypto * crypto,
assert( DH_size( dh ) == KEY_LEN ); assert( DH_size( dh ) == KEY_LEN );
len = DH_compute_key( secret, bn, dh ); len = DH_compute_key( secret, bn, dh );
assert( len <= KEY_LEN ); if( len == -1 )
offset = KEY_LEN - len; logErrorFromSSL( );
memset( crypto->mySecret, 0, offset ); else {
memcpy( crypto->mySecret + offset, secret, len ); int offset;
crypto->mySecretIsSet = 1; assert( len <= KEY_LEN );
offset = KEY_LEN - len;
memset( crypto->mySecret, 0, offset );
memcpy( crypto->mySecret + offset, secret, len );
crypto->mySecretIsSet = 1;
}
BN_free( bn ); BN_free( bn );
return crypto->mySecret; return crypto->mySecret;
} }
@ -193,12 +216,18 @@ initRC4( tr_crypto * crypto,
assert( crypto->torrentHashIsSet ); assert( crypto->torrentHashIsSet );
assert( crypto->mySecretIsSet ); assert( crypto->mySecretIsSet );
SHA1_Init( &sha ); if( SHA1_Init( &sha )
SHA1_Update( &sha, key, 4 ); && SHA1_Update( &sha, key, 4 )
SHA1_Update( &sha, crypto->mySecret, KEY_LEN ); && SHA1_Update( &sha, crypto->mySecret, KEY_LEN )
SHA1_Update( &sha, crypto->torrentHash, SHA_DIGEST_LENGTH ); && SHA1_Update( &sha, crypto->torrentHash, SHA_DIGEST_LENGTH )
SHA1_Final( buf, &sha ); && SHA1_Final( buf, &sha ) )
RC4_set_key( setme, SHA_DIGEST_LENGTH, buf ); {
RC4_set_key( setme, SHA_DIGEST_LENGTH, buf );
}
else
{
logErrorFromSSL( );
}
} }
void void
@ -306,6 +335,7 @@ void
tr_cryptoRandBuf( unsigned char *buf, tr_cryptoRandBuf( unsigned char *buf,
size_t len ) size_t len )
{ {
RAND_pseudo_bytes ( buf, len ); if( RAND_pseudo_bytes ( buf, len ) != 1 )
logErrorFromSSL( );
} }