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.

common.py 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. # some python3 compatibilty
  18. from __future__ import unicode_literals
  19. import logging
  20. import struct
  21. from potr.utils import human_hash, bytes_to_long, unpack, pack_mpi
  22. DEFAULT_KEYTYPE = 0x0000
  23. pkTypes = {}
  24. def registerkeytype(cls):
  25. if cls.keyType is None:
  26. raise TypeError('registered key class needs a type value')
  27. pkTypes[cls.keyType] = cls
  28. return cls
  29. def generateDefaultKey():
  30. return pkTypes[DEFAULT_KEYTYPE].generate()
  31. class PK(object):
  32. keyType = None
  33. @classmethod
  34. def generate(cls):
  35. raise NotImplementedError
  36. @classmethod
  37. def parsePayload(cls, data, private=False):
  38. raise NotImplementedError
  39. def sign(self, data):
  40. raise NotImplementedError
  41. def verify(self, data):
  42. raise NotImplementedError
  43. def fingerprint(self):
  44. raise NotImplementedError
  45. def serializePublicKey(self):
  46. return struct.pack(b'!H', self.keyType) \
  47. + self.getSerializedPublicPayload()
  48. def getSerializedPublicPayload(self):
  49. buf = b''
  50. for x in self.getPublicPayload():
  51. buf += pack_mpi(x)
  52. return buf
  53. def getPublicPayload(self):
  54. raise NotImplementedError
  55. def serializePrivateKey(self):
  56. return struct.pack(b'!H', self.keyType) \
  57. + self.getSerializedPrivatePayload()
  58. def getSerializedPrivatePayload(self):
  59. buf = b''
  60. for x in self.getPrivatePayload():
  61. buf += pack_mpi(x)
  62. return buf
  63. def getPrivatePayload(self):
  64. raise NotImplementedError
  65. def cfingerprint(self):
  66. return '{0:040x}'.format(bytes_to_long(self.fingerprint()))
  67. @classmethod
  68. def parsePrivateKey(cls, data):
  69. implCls, data = cls.getImplementation(data)
  70. logging.debug('Got privkey of type %r', implCls)
  71. return implCls.parsePayload(data, private=True)
  72. @classmethod
  73. def parsePublicKey(cls, data):
  74. implCls, data = cls.getImplementation(data)
  75. logging.debug('Got pubkey of type %r', implCls)
  76. return implCls.parsePayload(data)
  77. def __str__(self):
  78. return human_hash(self.cfingerprint())
  79. def __repr__(self):
  80. return '<{cls}(fpr=\'{fpr}\')>'.format(
  81. cls=self.__class__.__name__, fpr=str(self))
  82. @staticmethod
  83. def getImplementation(data):
  84. typeid, data = unpack(b'!H', data)
  85. cls = pkTypes.get(typeid, None)
  86. if cls is None:
  87. raise NotImplementedError('unknown typeid %r' % typeid)
  88. return cls, data