OTR plugin for Gajim 1.0+
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pycrypto.py 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. # Copyright 2012 Kjell Braden <afflux@pentabarf.de>
  2. #
  3. # This file is part of the python-potr library.
  4. #
  5. # python-potr is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU Lesser General Public License as published by
  7. # the Free Software Foundation; either version 3 of the License, or
  8. # any later version.
  9. #
  10. # python-potr is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this library. If not, see <http://www.gnu.org/licenses/>.
  17. try:
  18. import Crypto
  19. except ImportError:
  20. import crypto as Crypto
  21. from Crypto import Cipher
  22. from Crypto.Hash import SHA256 as _SHA256
  23. from Crypto.Hash import SHA as _SHA1
  24. from Crypto.Hash import HMAC as _HMAC
  25. from Crypto.PublicKey import DSA
  26. import Crypto.Random.random
  27. from numbers import Number
  28. from potr.compatcrypto import common
  29. from potr.utils import read_mpi, bytes_to_long, long_to_bytes
  30. def SHA256(data):
  31. return _SHA256.new(data).digest()
  32. def SHA1(data):
  33. return _SHA1.new(data).digest()
  34. def SHA1HMAC(key, data):
  35. return _HMAC.new(key, msg=data, digestmod=_SHA1).digest()
  36. def SHA256HMAC(key, data):
  37. return _HMAC.new(key, msg=data, digestmod=_SHA256).digest()
  38. def AESCTR(key, counter=0):
  39. if isinstance(counter, Number):
  40. counter = Counter(counter)
  41. if not isinstance(counter, Counter):
  42. raise TypeError
  43. return Cipher.AES.new(key, Cipher.AES.MODE_CTR, counter=counter)
  44. class Counter(object):
  45. def __init__(self, prefix):
  46. self.prefix = prefix
  47. self.val = 0
  48. def inc(self):
  49. self.prefix += 1
  50. self.val = 0
  51. def __setattr__(self, attr, val):
  52. if attr == 'prefix':
  53. self.val = 0
  54. super(Counter, self).__setattr__(attr, val)
  55. def __repr__(self):
  56. return '<Counter(p={p!r},v={v!r})>'.format(p=self.prefix, v=self.val)
  57. def byteprefix(self):
  58. return long_to_bytes(self.prefix, 8)
  59. def __call__(self):
  60. bytesuffix = long_to_bytes(self.val, 8)
  61. self.val += 1
  62. return self.byteprefix() + bytesuffix
  63. @common.registerkeytype
  64. class DSAKey(common.PK):
  65. keyType = 0x0000
  66. def __init__(self, key=None, private=False):
  67. self.priv = self.pub = None
  68. if not isinstance(key, tuple):
  69. raise TypeError('4/5-tuple required for key')
  70. if len(key) == 5 and private:
  71. self.priv = DSA.construct(key)
  72. self.pub = self.priv.publickey()
  73. elif len(key) == 4 and not private:
  74. self.pub = DSA.construct(key)
  75. else:
  76. raise TypeError('wrong number of arguments for ' \
  77. 'private={0!r}: got {1} '
  78. .format(private, len(key)))
  79. def getPublicPayload(self):
  80. return (self.pub.p, self.pub.q, self.pub.g, self.pub.y)
  81. def getPrivatePayload(self):
  82. return (self.priv.p, self.priv.q, self.priv.g, self.priv.y, self.priv.x)
  83. def fingerprint(self):
  84. return SHA1(self.getSerializedPublicPayload())
  85. def sign(self, data):
  86. # 2 <= K <= q
  87. K = randrange(2, self.priv.q)
  88. r, s = self.priv.sign(data, K)
  89. return long_to_bytes(r, 20) + long_to_bytes(s, 20)
  90. def verify(self, data, sig):
  91. r, s = bytes_to_long(sig[:20]), bytes_to_long(sig[20:])
  92. return self.pub.verify(data, (r, s))
  93. def __hash__(self):
  94. return bytes_to_long(self.fingerprint())
  95. def __eq__(self, other):
  96. if not isinstance(other, type(self)):
  97. return False
  98. return self.fingerprint() == other.fingerprint()
  99. def __ne__(self, other):
  100. return not (self == other)
  101. @classmethod
  102. def generate(cls):
  103. privkey = DSA.generate(1024)
  104. return cls((privkey.key.y, privkey.key.g, privkey.key.p, privkey.key.q,
  105. privkey.key.x), private=True)
  106. @classmethod
  107. def parsePayload(cls, data, private=False):
  108. p, data = read_mpi(data)
  109. q, data = read_mpi(data)
  110. g, data = read_mpi(data)
  111. y, data = read_mpi(data)
  112. if private:
  113. x, data = read_mpi(data)
  114. return cls((y, g, p, q, x), private=True), data
  115. return cls((y, g, p, q), private=False), data
  116. def getrandbits(k):
  117. return Crypto.Random.random.getrandbits(k)
  118. def randrange(start, stop):
  119. return Crypto.Random.random.randrange(start, stop)