/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric characters, where x is the major version number, y is the minor version number, z is the maintenance number, and b designates beta (Azureus-style) */ uint8_t* tr_peerIdNew( void ) { int i; int val; int total = 0; uint8_t * buf = tr_new( uint8_t, 21 ); const char * pool = "0123456789abcdefghijklmnopqrstuvwxyz"; const int base = 36; memcpy( buf, PEERID_PREFIX, 8 ); for( i = 8; i < 19; ++i ) { val = tr_cryptoRandInt( base ); total += val; buf[i] = pool[val]; } val = total % base ? base - ( total % base ) : 0; buf[19] = pool[val]; buf[20] = '\0'; return buf; }
static int readYa( tr_handshake * handshake, struct evbuffer * inbuf ) { uint8_t ya[KEY_LEN]; uint8_t * walk, outbuf[KEY_LEN + PadB_MAXLEN]; const uint8_t *myKey, *secret; int len; dbgmsg( handshake, "in readYa... need %d, have %zu", KEY_LEN, evbuffer_get_length( inbuf ) ); if( evbuffer_get_length( inbuf ) < KEY_LEN ) return READ_LATER; /* read the incoming peer's public key */ evbuffer_remove( inbuf, ya, KEY_LEN ); secret = tr_cryptoComputeSecret( handshake->crypto, ya ); memcpy( handshake->mySecret, secret, KEY_LEN ); tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL ); dbgmsg( handshake, "sending B->A: Diffie Hellman Yb, PadB" ); /* send our public key to the peer */ walk = outbuf; myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len ); memcpy( walk, myKey, len ); walk += len; len = tr_cryptoRandInt( PadB_MAXLEN ); tr_cryptoRandBuf( walk, len ); walk += len; setReadState( handshake, AWAITING_PAD_A ); tr_peerIoWriteBytes( handshake->io, outbuf, walk - outbuf, FALSE ); return READ_NOW; }
static int test_cryptoRand( void ) { int i; /* test that tr_cryptoRandInt() stays in-bounds */ for( i = 0; i < 100000; ++i ) { const int val = tr_cryptoRandInt( 100 ); check( val >= 0 ); check( val < 100 ); } return 0; }
/* 1 A->B: Diffie Hellman Ya, PadA */ static void sendYa( tr_handshake * handshake ) { int len; const uint8_t * public_key; char outbuf[ KEY_LEN + PadA_MAXLEN ], *walk=outbuf; /* add our public key (Ya) */ public_key = tr_cryptoGetMyPublicKey( handshake->crypto, &len ); assert( len == KEY_LEN ); assert( public_key ); memcpy( walk, public_key, len ); walk += len; /* add some bullshit padding */ len = tr_cryptoRandInt( PadA_MAXLEN ); tr_cryptoRandBuf( walk, len ); walk += len; /* send it */ setReadState( handshake, AWAITING_YB ); tr_peerIoWriteBytes( handshake->io, outbuf, walk - outbuf, FALSE ); }