~ubuntu-branches/ubuntu/precise/bittornado/precise

« back to all changes in this revision

Viewing changes to .pc/29_fix_urandom_error.dpatch/BitTornado/BTcrypto.py

  • Committer: Barry Warsaw
  • Date: 2011-08-10 23:17:46 UTC
  • mfrom: (7.1.1 bittornado)
  • Revision ID: barry@python.org-20110810231746-5buiob6p54m266s8
Tags: 0.3.18-10ubuntu2
* switch to dh_python2 (LP: #788514)
  - install btmakemetafile.py and btcompletedir.py via pyinstall
  - add build depend on python-all
  - bump debhelper depend to 7 for dh_auto_install

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Written by John Hoffman
 
2
# based on code by Uoti Urpala
 
3
# see LICENSE.txt for license information
 
4
 
 
5
from __future__ import generators   # for python 2.2
 
6
from random import randrange,randint,seed
 
7
try:
 
8
    from os import urandom
 
9
except:
 
10
    seed()
 
11
    urandom = lambda x: ''.join([chr(randint(0,255)) for i in xrange(x)])
 
12
from sha import sha
 
13
 
 
14
try:
 
15
    True
 
16
except:
 
17
    True = 1
 
18
    False = 0
 
19
    
 
20
try:
 
21
    from Crypto.Cipher import ARC4
 
22
    CRYPTO_OK = True
 
23
except:
 
24
    CRYPTO_OK = False
 
25
 
 
26
KEY_LENGTH = 160
 
27
DH_PRIME = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A36210000000000090563
 
28
PAD_MAX = 200 # less than protocol maximum, and later assumed to be < 256
 
29
DH_BYTES = 96
 
30
 
 
31
def bytetonum(x):
 
32
    return long(x.encode('hex'), 16)
 
33
 
 
34
def numtobyte(x):
 
35
    x = hex(x).lstrip('0x').rstrip('Ll')
 
36
    x = '0'*(192 - len(x)) + x
 
37
    return x.decode('hex')
 
38
 
 
39
class Crypto:
 
40
    def __init__(self, initiator, disable_crypto = False):
 
41
        self.initiator = initiator
 
42
        self.disable_crypto = disable_crypto
 
43
        if not disable_crypto and not CRYPTO_OK:
 
44
            raise NotImplementedError, "attempt to run encryption w/ none installed"
 
45
        self.privkey = bytetonum(urandom(KEY_LENGTH/8))
 
46
        self.pubkey = numtobyte(pow(2, self.privkey, DH_PRIME))
 
47
        self.keylength = DH_BYTES
 
48
        self._VC_pattern = None
 
49
 
 
50
    def received_key(self, k):
 
51
        self.S = numtobyte(pow(bytetonum(k), self.privkey, DH_PRIME))
 
52
        self.block3a = sha('req1'+self.S).digest()
 
53
        self.block3bkey = sha('req3'+self.S).digest()
 
54
        self.block3b = None
 
55
 
 
56
    def _gen_block3b(self, SKEY):
 
57
        a = sha('req2'+SKEY).digest()
 
58
        return ''.join([ chr(ord(a[i])^ord(self.block3bkey[i]))
 
59
                         for i in xrange(20) ])
 
60
 
 
61
    def test_skey(self, s, SKEY):
 
62
        block3b = self._gen_block3b(SKEY)
 
63
        if block3b != s:
 
64
            return False
 
65
        self.block3b = block3b
 
66
        if not self.disable_crypto:
 
67
            self.set_skey(SKEY)
 
68
        return True
 
69
 
 
70
    def set_skey(self, SKEY):
 
71
        if not self.block3b:
 
72
            self.block3b = self._gen_block3b(SKEY)
 
73
        crypta = ARC4.new(sha('keyA'+self.S+SKEY).digest())
 
74
        cryptb = ARC4.new(sha('keyB'+self.S+SKEY).digest())
 
75
        if self.initiator:
 
76
            self.encrypt = crypta.encrypt
 
77
            self.decrypt = cryptb.decrypt
 
78
        else:
 
79
            self.encrypt = cryptb.encrypt
 
80
            self.decrypt = crypta.decrypt
 
81
        self.encrypt('x'*1024)  # discard first 1024 bytes
 
82
        self.decrypt('x'*1024)
 
83
 
 
84
    def VC_pattern(self):
 
85
        if not self._VC_pattern:
 
86
            self._VC_pattern = self.decrypt('\x00'*8)
 
87
        return self._VC_pattern
 
88
 
 
89
 
 
90
    def read(self, s):
 
91
        self._read(self.decrypt(s))
 
92
 
 
93
    def write(self, s):
 
94
        self._write(self.encrypt(s))
 
95
 
 
96
    def setrawaccess(self, _read, _write):
 
97
        self._read = _read
 
98
        self._write = _write
 
99
 
 
100
    def padding(self):
 
101
        return urandom(randrange(PAD_MAX-16)+16)
 
102
     
 
103