示例#1
0
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;
}
示例#2
0
static int
test_encrypt_decrypt (void)
{
  tr_crypto a, b;
  uint8_t hash[SHA_DIGEST_LENGTH];
  const char test1[] = { "test1" };
  char buf11[sizeof (test1)], buf12[sizeof (test1)];
  const char test2[] = { "@#)C$@)#(*%bvkdjfhwbc039bc4603756VB3)" };
  char buf21[sizeof (test2)], buf22[sizeof (test2)];
  int i;

  for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
    hash[i] = i;

  tr_cryptoConstruct (&a, hash, false);
  tr_cryptoConstruct (&b, hash, true);
  tr_cryptoComputeSecret (&a, tr_cryptoGetMyPublicKey (&b, &i));
  tr_cryptoComputeSecret (&b, tr_cryptoGetMyPublicKey (&a, &i));

  tr_cryptoEncryptInit (&a);
  tr_cryptoEncrypt (&a, sizeof (test1), test1, buf11);
  tr_cryptoDecryptInit (&b);
  tr_cryptoDecrypt (&b, sizeof (test1), buf11, buf12);
  check_streq (test1, buf12);

  tr_cryptoEncryptInit (&b);
  tr_cryptoEncrypt (&b, sizeof (test2), test2, buf21);
  tr_cryptoDecryptInit (&a);
  tr_cryptoDecrypt (&a, sizeof (test2), buf21, buf22);
  check_streq (test2, buf22);

  tr_cryptoDestruct (&b);
  tr_cryptoDestruct (&a);

  return 0;
}
示例#3
0
/* 2 $A \leftarrow B$: Diffie Hellman $Y_B$, PadB */
static int readYb(tr_handshake * handshake, struct evbuffer * inbuf) {
    int isEncrypted;
    const uint8_t * secret;
    uint8_t yb[KEY_LEN];
    struct evbuffer * outbuf;
    size_t needlen = HANDSHAKE_NAME_LEN;

    (...)
    isEncrypted = memcmp(evbuffer_pullup(inbuf, HANDSHAKE_NAME_LEN),
                    HANDSHAKE_NAME, HANDSHAKE_NAME_LEN);
    (...)
    tr_peerIoSetEncryption(handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
                                                      : PEER_ENCRYPTION_NONE);

    if (!isEncrypted) {
        setState(handshake, AWAITING_HANDSHAKE); // Handshake não encriptado acaba aqui.
        return READ_NOW;
    }

    (...)
    /* compute the secret $S$*/
    evbuffer_remove(inbuf, yb, KEY_LEN);
    secret = tr_cryptoComputeSecret(handshake->crypto, yb);
    memcpy(handshake->mySecret, secret, KEY_LEN);
示例#4
0
static int
readYb( tr_handshake * handshake, struct evbuffer * inbuf )
{
    int               isEncrypted;
    const uint8_t *   secret;
    uint8_t           yb[KEY_LEN];
    struct evbuffer * outbuf;
    size_t            needlen = HANDSHAKE_NAME_LEN;

    if( evbuffer_get_length( inbuf ) < needlen )
        return READ_LATER;

    isEncrypted = memcmp( evbuffer_pullup( inbuf, HANDSHAKE_NAME_LEN ), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
    if( isEncrypted )
    {
        needlen = KEY_LEN;
        if( evbuffer_get_length( inbuf ) < needlen )
            return READ_LATER;
    }

    dbgmsg( handshake, "got a %s handshake",
           ( isEncrypted ? "encrypted" : "plaintext" ) );

    tr_peerIoSetEncryption( handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
                                                       : PEER_ENCRYPTION_NONE );
    if( !isEncrypted )
    {
        setState( handshake, AWAITING_HANDSHAKE );
        return READ_NOW;
    }

    handshake->haveReadAnythingFromPeer = TRUE;

    /* compute the secret */
    evbuffer_remove( inbuf, yb, KEY_LEN );
    secret = tr_cryptoComputeSecret( handshake->crypto, yb );
    memcpy( handshake->mySecret, secret, KEY_LEN );

    /* now send these: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S),
     * ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) */
    outbuf = evbuffer_new( );

    /* HASH('req1', S) */
    {
        uint8_t req1[SHA_DIGEST_LENGTH];
        tr_sha1( req1, "req1", 4, secret, KEY_LEN, NULL );
        evbuffer_add( outbuf, req1, SHA_DIGEST_LENGTH );
    }

    /* HASH('req2', SKEY) xor HASH('req3', S) */
    {
        int     i;
        uint8_t req2[SHA_DIGEST_LENGTH];
        uint8_t req3[SHA_DIGEST_LENGTH];
        uint8_t buf[SHA_DIGEST_LENGTH];
        tr_sha1( req2, "req2", 4,
                 tr_cryptoGetTorrentHash( handshake->crypto ),
                 SHA_DIGEST_LENGTH, NULL );
        tr_sha1( req3, "req3", 4, secret, KEY_LEN, NULL );
        for( i = 0; i < SHA_DIGEST_LENGTH; ++i )
            buf[i] = req2[i] ^ req3[i];
        evbuffer_add( outbuf, buf, SHA_DIGEST_LENGTH );
    }

    /* ENCRYPT(VC, crypto_provide, len(PadC), PadC
     * PadC is reserved for future extensions to the handshake...
     * standard practice at this time is for it to be zero-length */
    {
        uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };

        tr_peerIoWriteBuf( handshake->io, outbuf, FALSE );
        tr_cryptoEncryptInit( handshake->crypto );
        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 );

        evbuffer_add        ( outbuf, vc, VC_LENGTH );
        evbuffer_add_uint32 ( outbuf, getCryptoProvide( handshake ) );
        evbuffer_add_uint16 ( outbuf, 0 );
    }

    /* ENCRYPT len(IA)), ENCRYPT(IA) */
    {
        uint8_t msg[HANDSHAKE_SIZE];
        buildHandshakeMessage( handshake, msg );

        evbuffer_add_uint16 ( outbuf, sizeof( msg ) );
        evbuffer_add        ( outbuf, msg, sizeof( msg ) );

        handshake->haveSentBitTorrentHandshake = 1;
    }

    /* send it */
    tr_cryptoDecryptInit( handshake->crypto );
    setReadState( handshake, AWAITING_VC );
    tr_peerIoWriteBuf( handshake->io, outbuf, FALSE );

    /* cleanup */
    evbuffer_free( outbuf );
    return READ_LATER;
}