pubkey.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #
  2. # pubkey.py : Internal functions for public key operations
  3. #
  4. # Part of the Python Cryptography Toolkit
  5. #
  6. # Written by Andrew Kuchling, Paul Swartz, and others
  7. #
  8. # ===================================================================
  9. # The contents of this file are dedicated to the public domain. To
  10. # the extent that dedication to the public domain is not available,
  11. # everyone is granted a worldwide, perpetual, royalty-free,
  12. # non-exclusive license to exercise all rights associated with the
  13. # contents of this file for any purpose whatsoever.
  14. # No rights are reserved.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  20. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  21. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. # SOFTWARE.
  24. # ===================================================================
  25. #
  26. __revision__ = "$Id$"
  27. import types, warnings
  28. from Crypto.Util.number import *
  29. # Basic public key class
  30. class pubkey:
  31. """An abstract class for a public key object.
  32. :undocumented: __getstate__, __setstate__, __eq__, __ne__, validate
  33. """
  34. def __init__(self):
  35. pass
  36. def __getstate__(self):
  37. """To keep key objects platform-independent, the key data is
  38. converted to standard Python long integers before being
  39. written out. It will then be reconverted as necessary on
  40. restoration."""
  41. d=self.__dict__
  42. for key in self.keydata:
  43. if d.has_key(key): d[key]=long(d[key])
  44. return d
  45. def __setstate__(self, d):
  46. """On unpickling a key object, the key data is converted to the big
  47. number representation being used, whether that is Python long
  48. integers, MPZ objects, or whatever."""
  49. for key in self.keydata:
  50. if d.has_key(key): self.__dict__[key]=bignum(d[key])
  51. def encrypt(self, plaintext, K):
  52. """Encrypt a piece of data.
  53. :Parameter plaintext: The piece of data to encrypt.
  54. :Type plaintext: byte string or long
  55. :Parameter K: A random parameter required by some algorithms
  56. :Type K: byte string or long
  57. :Return: A tuple with two items. Each item is of the same type as the
  58. plaintext (string or long).
  59. """
  60. wasString=0
  61. if isinstance(plaintext, types.StringType):
  62. plaintext=bytes_to_long(plaintext) ; wasString=1
  63. if isinstance(K, types.StringType):
  64. K=bytes_to_long(K)
  65. ciphertext=self._encrypt(plaintext, K)
  66. if wasString: return tuple(map(long_to_bytes, ciphertext))
  67. else: return ciphertext
  68. def decrypt(self, ciphertext):
  69. """Decrypt a piece of data.
  70. :Parameter ciphertext: The piece of data to decrypt.
  71. :Type ciphertext: byte string, long or a 2-item tuple as returned by `encrypt`
  72. :Return: A byte string if ciphertext was a byte string or a tuple
  73. of byte strings. A long otherwise.
  74. """
  75. wasString=0
  76. if not isinstance(ciphertext, types.TupleType):
  77. ciphertext=(ciphertext,)
  78. if isinstance(ciphertext[0], types.StringType):
  79. ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1
  80. plaintext=self._decrypt(ciphertext)
  81. if wasString: return long_to_bytes(plaintext)
  82. else: return plaintext
  83. def sign(self, M, K):
  84. """Sign a piece of data.
  85. :Parameter M: The piece of data to encrypt.
  86. :Type M: byte string or long
  87. :Parameter K: A random parameter required by some algorithms
  88. :Type K: byte string or long
  89. :Return: A tuple with two items.
  90. """
  91. if (not self.has_private()):
  92. raise TypeError('Private key not available in this object')
  93. if isinstance(M, types.StringType): M=bytes_to_long(M)
  94. if isinstance(K, types.StringType): K=bytes_to_long(K)
  95. return self._sign(M, K)
  96. def verify (self, M, signature):
  97. """Verify the validity of a signature.
  98. :Parameter M: The expected message.
  99. :Type M: byte string or long
  100. :Parameter signature: The signature to verify.
  101. :Type signature: tuple with two items, as return by `sign`
  102. :Return: True if the signature is correct, False otherwise.
  103. """
  104. if isinstance(M, types.StringType): M=bytes_to_long(M)
  105. return self._verify(M, signature)
  106. # alias to compensate for the old validate() name
  107. def validate (self, M, signature):
  108. warnings.warn("validate() method name is obsolete; use verify()",
  109. DeprecationWarning)
  110. def blind(self, M, B):
  111. """Blind a message to prevent certain side-channel attacks.
  112. :Parameter M: The message to blind.
  113. :Type M: byte string or long
  114. :Parameter B: Blinding factor.
  115. :Type B: byte string or long
  116. :Return: A byte string if M was so. A long otherwise.
  117. """
  118. wasString=0
  119. if isinstance(M, types.StringType):
  120. M=bytes_to_long(M) ; wasString=1
  121. if isinstance(B, types.StringType): B=bytes_to_long(B)
  122. blindedmessage=self._blind(M, B)
  123. if wasString: return long_to_bytes(blindedmessage)
  124. else: return blindedmessage
  125. def unblind(self, M, B):
  126. """Unblind a message after cryptographic processing.
  127. :Parameter M: The encoded message to unblind.
  128. :Type M: byte string or long
  129. :Parameter B: Blinding factor.
  130. :Type B: byte string or long
  131. """
  132. wasString=0
  133. if isinstance(M, types.StringType):
  134. M=bytes_to_long(M) ; wasString=1
  135. if isinstance(B, types.StringType): B=bytes_to_long(B)
  136. unblindedmessage=self._unblind(M, B)
  137. if wasString: return long_to_bytes(unblindedmessage)
  138. else: return unblindedmessage
  139. # The following methods will usually be left alone, except for
  140. # signature-only algorithms. They both return Boolean values
  141. # recording whether this key's algorithm can sign and encrypt.
  142. def can_sign (self):
  143. """Tell if the algorithm can deal with cryptographic signatures.
  144. This property concerns the *algorithm*, not the key itself.
  145. It may happen that this particular key object hasn't got
  146. the private information required to generate a signature.
  147. :Return: boolean
  148. """
  149. return 1
  150. def can_encrypt (self):
  151. """Tell if the algorithm can deal with data encryption.
  152. This property concerns the *algorithm*, not the key itself.
  153. It may happen that this particular key object hasn't got
  154. the private information required to decrypt data.
  155. :Return: boolean
  156. """
  157. return 1
  158. def can_blind (self):
  159. """Tell if the algorithm can deal with data blinding.
  160. This property concerns the *algorithm*, not the key itself.
  161. It may happen that this particular key object hasn't got
  162. the private information required carry out blinding.
  163. :Return: boolean
  164. """
  165. return 0
  166. # The following methods will certainly be overridden by
  167. # subclasses.
  168. def size (self):
  169. """Tell the maximum number of bits that can be handled by this key.
  170. :Return: int
  171. """
  172. return 0
  173. def has_private (self):
  174. """Tell if the key object contains private components.
  175. :Return: bool
  176. """
  177. return 0
  178. def publickey (self):
  179. """Construct a new key carrying only the public information.
  180. :Return: A new `pubkey` object.
  181. """
  182. return self
  183. def __eq__ (self, other):
  184. """__eq__(other): 0, 1
  185. Compare us to other for equality.
  186. """
  187. return self.__getstate__() == other.__getstate__()
  188. def __ne__ (self, other):
  189. """__ne__(other): 0, 1
  190. Compare us to other for inequality.
  191. """
  192. return not self.__eq__(other)