source: branches/encryption/libtransmission/handshake.c @ 3101

Last change on this file since 3101 was 3101, checked in by charles, 15 years ago
  • add a public API call for setting encryption preferences
  • fix upload bug that caused us to send the same block out more than once
  • fix handshake bug that caused us to shun uTorrent and vice versa
  • fix minor memory leaks (valgrind).
  • move extension handshakes into peer-msgs
  • Property svn:keywords set to Date Rev Author Id
File size: 26.7 KB
Line 
1/*
2 * This file Copyright (C) 2007 Charles Kerr <charles@rebelbase.com>
3 *
4 * This file is licensed by the GPL version 2.  Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: handshake.c 3101 2007-09-20 04:11:09Z charles $
11 */
12
13#include <assert.h>
14#include <errno.h>
15#include <inttypes.h>
16#include <limits.h> /* UCHAR_MAX */
17#include <string.h>
18#include <stdio.h>
19#include <arpa/inet.h>
20
21#include <sys/types.h> /* event.h needs this */
22#include <event.h>
23
24#include "transmission.h"
25#include "bencode.h"
26#include "crypto.h"
27#include "handshake.h"
28#include "peer-io.h"
29#include "utils.h"
30
31/* enable LibTransmission extension protocol */
32#define ENABLE_LTEP
33
34/* enable Azureus messaging protocol */
35//#define ENABLE_AZMP
36
37/***
38****
39***/
40
41#define HANDSHAKE_NAME          "\023BitTorrent protocol"
42#define HANDSHAKE_NAME_LEN      20
43#define HANDSHAKE_FLAGS_LEN     8
44#define HANDSHAKE_SIZE          68
45
46/***
47****
48***/
49
50enum
51{
52    HANDSHAKE_EXTPREF_LTEP_FORCE   = 0x0,
53    HANDSHAKE_EXTPREF_LTEP_PREFER  = 0x1,
54    HANDSHAKE_EXTPREF_AZMP_PREFER  = 0x2,
55    HANDSHAKE_EXTPREF_AZMP_FORCE   = 0x3
56};
57
58
59#ifdef ENABLE_LTEP
60#define HANDSHAKE_HAS_EXTMSGS( bits ) ( ( (bits)[5] & 0x10 ) ? 1 : 0 )
61#define HANDSHAKE_SET_EXTMSGS( bits ) ( ( (bits)[5] |= 0x10 ) ? 1 : 0 )
62#else
63#define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 )
64#define HANDSHAKE_SET_EXTMSGS( bits ) ( (void)0 )
65#endif
66
67#ifdef ENABLE_AZMP
68#define HANDSHAKE_HAS_AZPROTO( bits ) ( ( (bits)[0] & 0x80 ) ? 1 : 0 )
69#define HANDSHAKE_SET_AZPROTO( bits ) ( ( (bits)[0] |= 0x80 ) ? 1 : 0 )
70#else
71#define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 )
72#define HANDSHAKE_SET_AZPROTO( bits ) ( (void)0 )
73#endif
74
75/* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol
76   these macros are to be used if both extended messaging and the
77   azureus protocol is supported, they indicate which protocol is preferred */
78#define HANDSHAKE_GET_EXTPREF( reserved )      ( (reserved)[5] & 0x03 )
79#define HANDSHAKE_SET_EXTPREF( reserved, val ) ( (reserved)[5] |= 0x03 & (val) )
80#define HANDSHAKE_EXTPREF_LTEP_FORCE   ( 0x0 )
81#define HANDSHAKE_EXTPREF_LTEP_PREFER  ( 0x1 )
82#define HANDSHAKE_EXTPREF_AZMP_PREFER  ( 0x2 )
83#define HANDSHAKE_EXTPREF_AZMP_FORCE   ( 0x3 )
84
85enum
86{
87    PadA_MAXLEN = 512,
88    PadB_MAXLEN = 512,
89    PadC_MAXLEN = 512,
90    PadD_MAXLEN = 512
91};
92
93extern const char* getPeerId( void ) ;
94
95#define KEY_LEN 96
96#define VC_LENGTH 8
97
98struct tr_handshake
99{
100    unsigned int peerSupportsEncryption       : 1;
101    unsigned int havePeerID                   : 1;
102    unsigned int haveSentBitTorrentHandshake  : 1;
103    unsigned int shunUnencryptedPeers         : 1;
104    tr_peerIo * io;
105    tr_crypto * crypto;
106    struct tr_handle * handle;
107    uint8_t myPublicKey[96];
108    uint8_t mySecret[96];
109    uint8_t state;
110    uint16_t pad_c_len;
111    uint16_t pad_d_len;
112    uint16_t  ia_len;
113    uint32_t crypto_select;
114    uint8_t myReq1[SHA_DIGEST_LENGTH];
115    uint8_t peer_id[20];
116    handshakeDoneCB doneCB;
117    void * doneUserData;
118};
119
120/**
121***
122**/
123
124enum
125{
126    /* incoming */
127    AWAITING_HANDSHAKE,
128    AWAITING_YA,
129    AWAITING_PAD_A,
130    AWAITING_CRYPTO_PROVIDE,
131    AWAITING_PAD_C,
132    AWAITING_IA,
133
134    /* outgoing */
135    AWAITING_YB,
136    AWAITING_VC,
137    AWAITING_CRYPTO_SELECT,
138    AWAITING_PAD_D,
139};
140
141/**
142***
143**/
144
145static void
146myDebug( const char * file, int line, const tr_handshake * handshake, const char * fmt, ... )
147{
148    va_list args;
149    const char * addr = tr_peerIoGetAddrStr( handshake->io );
150    struct evbuffer * buf = evbuffer_new( );
151    evbuffer_add_printf( buf, "[%s:%d] %s (%p) ", file, line, addr, handshake );
152    va_start( args, fmt );
153    evbuffer_add_vprintf( buf, fmt, args );
154    va_end( args );
155
156    fprintf( stderr, "%s\n", EVBUFFER_DATA(buf) );
157
158    evbuffer_free( buf );
159}
160
161#define dbgmsg(handshake, fmt...) myDebug(__FILE__, __LINE__, handshake, ##fmt )
162
163static const char* getStateName( short state )
164{
165    const char * str = "f00!";
166    switch( state ) {
167        case AWAITING_HANDSHAKE:      str = "awaiting handshake"; break;
168        case AWAITING_YA:             str = "awaiting ya"; break;
169        //case SENDING_YB:              str = "sending yb"; break;
170        case AWAITING_PAD_A:          str = "awaiting pad a"; break;
171        case AWAITING_CRYPTO_PROVIDE: str = "awaiting crypto_provide"; break;
172        case AWAITING_PAD_C:          str = "awaiting pad c"; break;
173        case AWAITING_IA:             str = "awaiting ia"; break;
174        //case SENDING_YA:              str = "sending ya"; break;
175        case AWAITING_YB:             str = "awaiting yb"; break;
176        //case SENDING_CRYPTO_PROVIDE:  str = "sending crypto provide"; break;
177        case AWAITING_VC:             str = "awaiting vc"; break;
178        case AWAITING_CRYPTO_SELECT:  str = "awaiting crypto select"; break;
179        case AWAITING_PAD_D:          str = "awaiting pad d"; break;
180        //case SENDING_NONE: str = "sending plaintext handshake"; break;
181    }
182    return str;
183}
184
185static void
186setState( tr_handshake * handshake, short state )
187{
188    dbgmsg( handshake, "setting to state [%s]", getStateName(state) );
189    handshake->state = state;
190}
191
192static void
193setReadState( tr_handshake * handshake, int state )
194{
195    setState( handshake, state );
196    //tr_peerIoSetIOMode( handshake->io, EV_READ, EV_WRITE );
197}
198
199static uint8_t *
200buildHandshakeMessage( tr_handshake * handshake,
201                       int            extensionPreference,
202                       int          * setme_len )
203{
204    uint8_t * buf = tr_new0( uint8_t, HANDSHAKE_SIZE );
205    uint8_t * walk = buf;
206    const uint8_t * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto );
207
208    memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
209    walk += HANDSHAKE_NAME_LEN;
210    memset( walk, 0, HANDSHAKE_FLAGS_LEN );
211    switch( extensionPreference )
212    {
213        case HANDSHAKE_EXTPREF_LTEP_FORCE:
214            HANDSHAKE_SET_EXTMSGS( walk );
215            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
216            break;
217
218        case HANDSHAKE_EXTPREF_LTEP_PREFER:
219            HANDSHAKE_SET_EXTMSGS( walk );
220            HANDSHAKE_SET_AZPROTO( walk );
221            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
222            break;
223
224        case HANDSHAKE_EXTPREF_AZMP_PREFER:
225            HANDSHAKE_SET_EXTMSGS( walk );
226            HANDSHAKE_SET_AZPROTO( walk );
227            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
228            break;
229
230        case HANDSHAKE_EXTPREF_AZMP_FORCE:
231            HANDSHAKE_SET_AZPROTO( walk );
232            HANDSHAKE_SET_EXTPREF( walk, extensionPreference );
233            break;
234    }
235
236    walk += HANDSHAKE_FLAGS_LEN;
237    memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );
238    walk += SHA_DIGEST_LENGTH;
239    memcpy( walk, getPeerId(), TR_ID_LEN );
240    walk += TR_ID_LEN;
241
242    assert( walk-buf == HANDSHAKE_SIZE );
243    *setme_len = walk - buf;
244    return buf;
245}
246
247/***
248****
249****  OUTGOING CONNECTIONS
250****
251***/
252
253/* 1 A->B: Diffie Hellman Ya, PadA */
254static void
255sendYa( tr_handshake * handshake )
256{
257    int i;
258    int len;
259    const uint8_t * public_key;
260    struct evbuffer * outbuf = evbuffer_new( );
261    uint8_t pad_a[PadA_MAXLEN];
262
263    /* add our public key (Ya) */
264    public_key = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
265    assert( len == KEY_LEN );
266    assert( public_key != NULL );
267    evbuffer_add( outbuf, public_key, len );
268
269    /* add some bullshit padding */
270    len = tr_rand( PadA_MAXLEN );
271    for( i=0; i<len; ++i )
272        pad_a[i] = tr_rand( UCHAR_MAX );
273    evbuffer_add( outbuf, pad_a, len );
274
275    /* send it */
276    setReadState( handshake, AWAITING_YB );
277    tr_peerIoWriteBuf( handshake->io, outbuf );
278
279    /* cleanup */
280    evbuffer_free( outbuf );
281}
282
283static int
284readYb( tr_handshake * handshake, struct evbuffer * inbuf )
285{
286    int isEncrypted;
287    const uint8_t * secret;
288    uint8_t yb[KEY_LEN];
289    struct evbuffer * outbuf;
290    size_t needlen = HANDSHAKE_NAME_LEN;
291
292    if( EVBUFFER_LENGTH(inbuf) < needlen )
293        return READ_MORE;
294
295    isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
296    if( isEncrypted ) {
297        needlen = KEY_LEN;
298        if( EVBUFFER_LENGTH(inbuf) < needlen )
299            return READ_MORE;
300    }
301
302    dbgmsg( handshake, "got a %s handshake", (isEncrypted ? "encrypted" : "plaintext") );
303
304    handshake->peerSupportsEncryption = isEncrypted;
305    tr_peerIoSetEncryption( handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
306                                                       : PEER_ENCRYPTION_NONE );
307    if( !isEncrypted ) {
308        setState( handshake, AWAITING_HANDSHAKE );
309        return READ_AGAIN;
310    }
311
312    /* compute the secret */
313    evbuffer_remove( inbuf, yb, KEY_LEN );
314    secret = tr_cryptoComputeSecret( handshake->crypto, yb );
315    memcpy( handshake->mySecret, secret, KEY_LEN );
316
317    /* now send these: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S),
318     * ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) */
319    outbuf = evbuffer_new( );
320
321    /* HASH('req1', S) */
322    {
323        uint8_t req1[SHA_DIGEST_LENGTH];
324        tr_sha1( req1, "req1", 4, secret, KEY_LEN, NULL );
325        evbuffer_add( outbuf, req1, SHA_DIGEST_LENGTH );
326    }
327
328    /* HASH('req2', SKEY) xor HASH('req3', S) */
329    {
330        int i;
331        uint8_t req2[SHA_DIGEST_LENGTH];
332        uint8_t req3[SHA_DIGEST_LENGTH];
333        uint8_t buf[SHA_DIGEST_LENGTH];
334        tr_sha1( req2, "req2", 4, tr_cryptoGetTorrentHash(handshake->crypto), SHA_DIGEST_LENGTH, NULL );
335        tr_sha1( req3, "req3", 4, secret, KEY_LEN, NULL );
336        for( i=0; i<SHA_DIGEST_LENGTH; ++i )
337            buf[i] = req2[i] ^ req3[i];
338        evbuffer_add( outbuf, buf, SHA_DIGEST_LENGTH );
339    }
340     
341    /* ENCRYPT(VC, crypto_provide, len(PadC), PadC */
342    {
343        uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
344        uint8_t pad[512];
345        uint16_t i, len;
346        uint32_t crypto_provide;
347
348        tr_cryptoEncryptInit( handshake->crypto );
349       
350        /* vc */ 
351        tr_cryptoEncrypt( handshake->crypto, VC_LENGTH, vc, vc );
352        evbuffer_add( outbuf, vc, VC_LENGTH );
353
354        /* crypto_provide */
355        crypto_provide = 0;
356        crypto_provide |= (1<<0); /* encryption */
357        if( !handshake->shunUnencryptedPeers ) /* plaintext */
358            crypto_provide |= (1<<1);
359        assert( 1<=crypto_provide && crypto_provide<=3 );
360
361        crypto_provide = htonl( crypto_provide );
362        tr_cryptoEncrypt( handshake->crypto, sizeof(crypto_provide), &crypto_provide, &crypto_provide );
363        evbuffer_add( outbuf, &crypto_provide, sizeof(crypto_provide) );
364
365        /* len(padc) */
366        i = len = tr_rand( 512 );
367        i = htons( i );
368        tr_cryptoEncrypt( handshake->crypto, sizeof(i), &i, &i );
369        evbuffer_add( outbuf, &i, sizeof(i) );
370
371        /* padc */
372        for( i=0; i<len; ++i ) pad[i] = tr_rand( UCHAR_MAX );
373        tr_cryptoEncrypt( handshake->crypto, len, pad, pad );
374        evbuffer_add( outbuf, pad, len );
375    }
376
377    /* ENCRYPT len(IA)), ENCRYPT(IA) */
378    {
379        uint16_t i;
380        int msgSize;
381        uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize );
382
383        i = htons( msgSize );
384        tr_cryptoEncrypt( handshake->crypto, sizeof(uint16_t), &i, &i );
385        evbuffer_add( outbuf, &i, sizeof(uint16_t) );
386
387        tr_cryptoEncrypt( handshake->crypto, msgSize, msg, msg );
388        evbuffer_add( outbuf, msg, HANDSHAKE_SIZE );
389        handshake->haveSentBitTorrentHandshake = 1;
390
391        tr_free( msg );
392    }
393
394    /* send it */
395    tr_cryptoDecryptInit( handshake->crypto );
396    setReadState( handshake, AWAITING_VC );
397    tr_peerIoWriteBuf( handshake->io, outbuf );
398
399    /* cleanup */
400    evbuffer_free( outbuf );
401    return READ_DONE;
402}
403
404static int
405readVC( tr_handshake * handshake, struct evbuffer * inbuf )
406{
407    const uint8_t key[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
408    const int key_len = VC_LENGTH;
409    uint8_t tmp[VC_LENGTH];
410
411    /* note: this works w/o having to `unwind' the buffer if
412     * we read too much, but it is pretty brute-force.
413     * it would be nice to make this cleaner. */
414    for( ;; )
415    {
416        if( EVBUFFER_LENGTH(inbuf) < VC_LENGTH ) {
417            dbgmsg( handshake, "not enough bytes... returning read_more" );
418            return READ_MORE;
419        }
420
421        memcpy( tmp, EVBUFFER_DATA(inbuf), key_len );
422        tr_cryptoDecryptInit( handshake->crypto );
423        tr_cryptoDecrypt( handshake->crypto, key_len, tmp, tmp );
424        if( !memcmp( tmp, key, key_len ) )
425            break;
426
427        evbuffer_drain( inbuf, 1 );
428    }
429
430    dbgmsg( handshake, "got it!" );
431    evbuffer_drain( inbuf, key_len );
432    setState( handshake, AWAITING_CRYPTO_SELECT );
433    return READ_AGAIN;
434}
435
436static int
437readCryptoSelect( tr_handshake * handshake, struct evbuffer * inbuf )
438{
439    uint32_t crypto_select;
440    uint16_t pad_d_len;
441    const size_t needlen = sizeof(uint32_t) + sizeof(uint16_t);
442
443    if( EVBUFFER_LENGTH(inbuf) < needlen )
444        return READ_MORE;
445
446    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_select );
447    assert( crypto_select==1 || crypto_select==2 );
448    handshake->crypto_select = crypto_select;
449    dbgmsg( handshake, "crypto select is %d", (int)crypto_select );
450
451    tr_peerIoReadUint16( handshake->io, inbuf, &pad_d_len );
452    dbgmsg( handshake, "pad_d_len is %d", (int)pad_d_len );
453    assert( pad_d_len <= 512 );
454    handshake->pad_d_len = pad_d_len;
455
456    setState( handshake, AWAITING_PAD_D );
457    return READ_AGAIN;
458}
459
460static int
461readPadD( tr_handshake * handshake, struct evbuffer * inbuf )
462{
463    const size_t needlen = handshake->pad_d_len;
464    uint8_t * tmp;
465
466    dbgmsg( handshake, "pad d: need %d, got %d", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) );
467    if( EVBUFFER_LENGTH(inbuf) < needlen )
468        return READ_MORE;
469
470    tmp = tr_new( uint8_t, needlen );
471    tr_peerIoReadBytes( handshake->io, inbuf, tmp, needlen );
472    tr_free( tmp );
473
474    tr_peerIoSetEncryption( handshake->io,
475                                    handshake->crypto_select );
476
477    setState( handshake, AWAITING_HANDSHAKE );
478    return READ_AGAIN;
479}
480
481/***
482****
483****  INCOMING CONNECTIONS
484****
485***/
486
487static void
488tr_handshakeDone( tr_handshake * handshake, int isConnected );
489
490static int
491readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
492{
493    int i;
494    uint8_t ltep = 0;
495    uint8_t azmp = 0;
496    uint8_t pstrlen;
497    uint8_t * pstr;
498    uint8_t reserved[8];
499    uint8_t hash[SHA_DIGEST_LENGTH];
500
501    dbgmsg( handshake, "payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) );
502
503    if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE )
504        return READ_MORE;
505
506for( i=0; i<(int)EVBUFFER_LENGTH(inbuf); ++i )
507fprintf( stderr, "[%c]", EVBUFFER_DATA(inbuf)[i] );
508fprintf( stderr, "\n" );
509
510    pstrlen = EVBUFFER_DATA(inbuf)[0]; /* peek, don't read.  We may be
511                                          handing inbuf to AWAITING_YA */
512
513    if( pstrlen == 19 ) /* unencrypted */
514    {
515        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
516    }
517    else /* encrypted or corrupt */
518    {
519        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 );
520
521        if( tr_peerIoIsIncoming( handshake->io ) )
522        {
523            dbgmsg( handshake, "I think peer is sending us an encrypted handshake..." );
524            setState( handshake, AWAITING_YA );
525            return READ_AGAIN;
526        }
527        tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen );
528
529        if( pstrlen != 19 )
530        {
531            dbgmsg( handshake, "I think peer has sent us a corrupt handshake..." );
532            tr_handshakeDone( handshake, FALSE );
533            return READ_DONE;
534        }
535    }
536
537    evbuffer_drain( inbuf, 1 );
538
539    /* pstr (BitTorrent) */
540    pstr = tr_new( uint8_t, pstrlen+1 );
541    tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen );
542    pstr[pstrlen] = '\0';
543    if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) {
544        tr_free( pstr );
545        tr_handshakeDone( handshake, FALSE );
546        return READ_DONE;
547    }
548    tr_free( pstr );
549
550    /* reserved bytes */
551    tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof(reserved) );
552
553    /* torrent hash */
554    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) );
555    if( tr_peerIoIsIncoming( handshake->io ) )
556    {
557        if( !tr_torrentExists( handshake->handle, hash ) )
558        {
559            dbgmsg( handshake, "peer is trying to connect to us for a torrent we don't have." );
560            tr_handshakeDone( handshake, FALSE );
561            return READ_DONE;
562        }
563        else
564        {
565            assert( !tr_peerIoHasTorrentHash( handshake->io ) );
566            tr_peerIoSetTorrentHash( handshake->io, hash );
567        }
568    }
569    else /* outgoing */
570    {
571        assert( tr_torrentExists( handshake->handle, hash ) );
572        assert( tr_peerIoHasTorrentHash( handshake->io ) );
573        if( memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) )
574        {
575            dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
576            tr_handshakeDone( handshake, FALSE );
577            return READ_DONE;
578        }
579    }
580
581    /* peer id */
582    tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
583    tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
584    handshake->havePeerID = TRUE;
585
586    /**
587    *** Extension negotiation
588    **/
589
590    ltep = HANDSHAKE_HAS_EXTMSGS( reserved );
591    azmp = HANDSHAKE_HAS_AZPROTO( reserved );
592    if( ltep && azmp ) {
593        switch( HANDSHAKE_GET_EXTPREF( reserved ) ) {
594            case HANDSHAKE_EXTPREF_LTEP_FORCE:
595            case HANDSHAKE_EXTPREF_LTEP_PREFER:
596                azmp = 0;
597                break;
598            case HANDSHAKE_EXTPREF_AZMP_FORCE:
599            case HANDSHAKE_EXTPREF_AZMP_PREFER:
600                ltep = 0;
601                break;
602        }
603    }
604    assert( !ltep || !azmp );
605         if( ltep ) { i = LT_EXTENSIONS_LTEP; dbgmsg(handshake,"using ltep" ); }
606    else if( azmp ) { i = LT_EXTENSIONS_AZMP; dbgmsg(handshake,"using azmp" ); }
607    else            { i = LT_EXTENSIONS_NONE; dbgmsg(handshake,"using no extensions" ); }
608    tr_peerIoSetExtension( handshake->io, i );
609
610
611    /**
612    ***  If this is an incoming message, then we need to send a response handshake
613    **/
614
615    if( !handshake->haveSentBitTorrentHandshake )
616    {
617        const int ext = ltep ? HANDSHAKE_EXTPREF_LTEP_FORCE
618                             : HANDSHAKE_EXTPREF_AZMP_FORCE;
619        int msgSize;
620        uint8_t * msg = buildHandshakeMessage( handshake, ext, &msgSize );
621        tr_peerIoWrite( handshake->io, msg, msgSize );
622        tr_free( msg );
623        handshake->haveSentBitTorrentHandshake = 1;
624    }
625
626    /* we've completed the BT handshake... pass the work on to peer-msgs */
627    tr_handshakeDone( handshake, TRUE );
628    return READ_DONE;
629}
630
631static int
632readYa( tr_handshake * handshake, struct evbuffer  * inbuf )
633{
634    uint8_t ya[KEY_LEN];
635    uint8_t *walk, outbuf[KEY_LEN + PadB_MAXLEN];
636    const uint8_t *myKey, *secret;
637    int len;
638
639    if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN )
640        return READ_MORE;
641
642    /* read the incoming peer's public key */
643    evbuffer_remove( inbuf, ya, KEY_LEN );
644    secret = tr_cryptoComputeSecret( handshake->crypto, ya );
645    memcpy( handshake->mySecret, secret, KEY_LEN );
646    tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );
647
648    /* send our public key to the peer */
649    walk = outbuf;
650    myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
651    memcpy( walk, myKey, len );
652    len = tr_rand( PadB_MAXLEN );
653    while( len-- )
654        *walk++ = tr_rand( UCHAR_MAX );
655
656    setReadState( handshake, AWAITING_PAD_A );
657    tr_peerIoWrite( handshake->io, outbuf, walk-outbuf );
658
659    return READ_DONE;
660}
661
662static int
663readPadA( tr_handshake * handshake, struct evbuffer * inbuf )
664{
665    uint8_t * pch;
666
667    /**
668    *** Resynchronizing on HASH('req1',S)
669    **/
670
671    pch = memchr( EVBUFFER_DATA(inbuf),
672                  handshake->myReq1[0],
673                  EVBUFFER_LENGTH(inbuf) );
674    if( pch == NULL ) {
675        evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) );
676        return READ_MORE;
677    }
678    evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) );
679    if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH )
680        return READ_MORE;
681    if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) {
682        evbuffer_drain( inbuf, 1 );
683        return READ_AGAIN;
684    }
685
686    setState( handshake, AWAITING_CRYPTO_PROVIDE );
687    return READ_AGAIN;
688}
689
690static int
691readCryptoProvide( tr_handshake * handshake, struct evbuffer * inbuf )
692{
693    /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC)) */
694
695    int i;
696    uint8_t vc_in[VC_LENGTH];
697    uint8_t req2[SHA_DIGEST_LENGTH];
698    uint8_t req3[SHA_DIGEST_LENGTH];
699    uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
700    uint16_t padc_len = 0;
701    uint32_t crypto_provide = 0;
702    const size_t needlen = SHA_DIGEST_LENGTH + VC_LENGTH + sizeof(crypto_provide) + sizeof(padc_len);
703    tr_torrent * tor = NULL;
704
705    if( EVBUFFER_LENGTH(inbuf) < needlen )
706        return READ_MORE;
707
708    /* TODO: confirm they sent HASH('req1',S) here? */
709    evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );
710
711    /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
712     * we can get the first half of that (the obufscatedTorrentHash)
713     * by building the latter and xor'ing it with what the peer sent us */
714    dbgmsg( handshake, "reading obfuscated torrent hash...\n" );
715    evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );
716    tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );
717    for( i=0; i<SHA_DIGEST_LENGTH; ++i )
718        obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
719    tor = tr_torrentFindFromObfuscatedHash( handshake->handle, obfuscatedTorrentHash );
720    assert( tor != NULL );
721    dbgmsg( handshake, "found the torrent; it's [%s]\n", tor->info.name );
722    tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );
723
724    /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
725
726    tr_cryptoDecryptInit( handshake->crypto );
727
728    tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );
729
730    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
731    dbgmsg( handshake, "crypto_provide is %d\n", (int)crypto_provide );
732
733    tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );
734    dbgmsg( handshake, "padc is %d\n", (int)padc_len );
735    handshake->pad_c_len = padc_len;
736    setState( handshake, AWAITING_PAD_C );
737    return READ_AGAIN;
738}
739
740static int
741readPadC( tr_handshake * handshake, struct evbuffer * inbuf )
742{
743    uint16_t ia_len;
744    const size_t needlen = handshake->pad_c_len + sizeof(uint16_t);
745
746    if( EVBUFFER_LENGTH(inbuf) < needlen )
747        return READ_MORE;
748
749    evbuffer_drain( inbuf, needlen );
750
751    tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );
752    dbgmsg( handshake, "ia_len is %d", (int)ia_len );
753    handshake->ia_len = ia_len;
754    setState( handshake, AWAITING_IA );
755    return READ_AGAIN;
756}
757
758static int
759readIA( tr_handshake * handshake, struct evbuffer * inbuf )
760{
761    const size_t needlen = handshake->ia_len;
762
763    if( EVBUFFER_LENGTH(inbuf) < needlen )
764        return READ_MORE;
765
766    return readHandshake( handshake, inbuf );
767}
768
769/***
770****
771****
772****
773***/
774
775static ReadState
776canRead( struct bufferevent * evin, void * arg )
777{
778    tr_handshake * handshake = (tr_handshake *) arg;
779    struct evbuffer * inbuf = EVBUFFER_INPUT ( evin );
780    ReadState ret;
781    dbgmsg( handshake, "handling canRead; state is [%s]\n", getStateName(handshake->state) );
782
783    switch( handshake->state )
784    {
785        case AWAITING_HANDSHAKE:       ret = readHandshake    ( handshake, inbuf ); break;
786        case AWAITING_YA:              ret = readYa           ( handshake, inbuf ); break;
787        case AWAITING_PAD_A:           ret = readPadA         ( handshake, inbuf ); break;
788        case AWAITING_CRYPTO_PROVIDE:  ret = readCryptoProvide( handshake, inbuf ); break;
789        case AWAITING_PAD_C:           ret = readPadC         ( handshake, inbuf ); break;
790        case AWAITING_IA:              ret = readIA           ( handshake, inbuf ); break;
791
792        case AWAITING_YB:              ret = readYb           ( handshake, inbuf ); break;
793        case AWAITING_VC:              ret = readVC           ( handshake, inbuf ); break;
794        case AWAITING_CRYPTO_SELECT:   ret = readCryptoSelect ( handshake, inbuf ); break;
795        case AWAITING_PAD_D:           ret = readPadD         ( handshake, inbuf ); break;
796
797        default: assert( 0 );
798    }
799
800    return ret;
801}
802
803static void
804fireDoneFunc( tr_handshake * handshake, int isConnected )
805{
806    const uint8_t * peer_id = isConnected && handshake->havePeerID
807        ? handshake->peer_id
808        : NULL;
809    (*handshake->doneCB)( handshake,
810                          handshake->io,
811                          isConnected,
812                          peer_id,
813                          handshake->peerSupportsEncryption,
814                          handshake->doneUserData );
815}
816
817void
818tr_handshakeDone( tr_handshake * handshake, int isOK )
819{
820    dbgmsg( handshake, "handshakeDone: %s", isOK ? "connected" : "aborting" );
821    tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
822    fireDoneFunc( handshake, isOK );
823    tr_free( handshake );
824}
825
826void
827tr_handshakeAbort( tr_handshake * handshake )
828{
829    tr_handshakeDone( handshake, FALSE );
830}
831
832static void
833gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg )
834{
835    tr_handshake * handshake = (tr_handshake *) arg;
836
837    /* if the error happened while we were sending a public key, we might
838     * have encountered a peer that doesn't do encryption... reconnect and
839     * try a plaintext handshake */
840    if(    ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) )
841        && ( !handshake->shunUnencryptedPeers )
842        && ( !tr_peerIoReconnect( handshake->io ) ) )
843    {
844        int msgSize; 
845        uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize );
846        setReadState( handshake, AWAITING_HANDSHAKE );
847        tr_peerIoWrite( handshake->io, msg, msgSize );
848        tr_free( msg );
849    }
850    else
851    {
852        tr_handshakeDone( handshake, FALSE );
853    }
854}
855
856/**
857***
858**/
859
860tr_handshake*
861tr_handshakeNew( tr_peerIo           * io,
862                 tr_encryption_mode    encryption_mode,
863                 handshakeDoneCB       doneCB,
864                 void                * doneUserData )
865{
866    tr_handshake * handshake;
867
868// w00t
869//static int count = 0;
870//if( count++ ) return NULL;
871
872    handshake = tr_new0( tr_handshake, 1 );
873    handshake->io = io;
874    handshake->crypto = tr_peerIoGetCrypto( io );
875    handshake->shunUnencryptedPeers = encryption_mode==TR_ENCRYPTION_REQUIRED;
876    handshake->doneCB = doneCB;
877    handshake->doneUserData = doneUserData;
878    handshake->handle = tr_peerIoGetHandle( io );
879
880    tr_peerIoSetIOMode( io, EV_READ|EV_WRITE, 0 );
881    tr_peerIoSetIOFuncs( io, canRead, NULL, gotError, handshake );
882
883dbgmsg( handshake, "new handshake for io %p", io );
884
885    if( tr_peerIoIsIncoming( io ) )
886        setReadState( handshake, AWAITING_HANDSHAKE );
887    else
888        sendYa( handshake );
889
890    return handshake;
891}
Note: See TracBrowser for help on using the repository browser.