/gdata/tlslite/utils/OpenSSL_RSAKey.py

http://radioappz.googlecode.com/ · Python · 148 lines · 128 code · 17 blank · 3 comment · 41 complexity · 8367f5881944cd039a46fec017aaf8f8 MD5 · raw file

  1. """OpenSSL/M2Crypto RSA implementation."""
  2. from cryptomath import *
  3. from RSAKey import *
  4. from Python_RSAKey import Python_RSAKey
  5. #copied from M2Crypto.util.py, so when we load the local copy of m2
  6. #we can still use it
  7. def password_callback(v, prompt1='Enter private key passphrase:',
  8. prompt2='Verify passphrase:'):
  9. from getpass import getpass
  10. while 1:
  11. try:
  12. p1=getpass(prompt1)
  13. if v:
  14. p2=getpass(prompt2)
  15. if p1==p2:
  16. break
  17. else:
  18. break
  19. except KeyboardInterrupt:
  20. return None
  21. return p1
  22. if m2cryptoLoaded:
  23. class OpenSSL_RSAKey(RSAKey):
  24. def __init__(self, n=0, e=0):
  25. self.rsa = None
  26. self._hasPrivateKey = False
  27. if (n and not e) or (e and not n):
  28. raise AssertionError()
  29. if n and e:
  30. self.rsa = m2.rsa_new()
  31. m2.rsa_set_n(self.rsa, numberToMPI(n))
  32. m2.rsa_set_e(self.rsa, numberToMPI(e))
  33. def __del__(self):
  34. if self.rsa:
  35. m2.rsa_free(self.rsa)
  36. def __getattr__(self, name):
  37. if name == 'e':
  38. if not self.rsa:
  39. return 0
  40. return mpiToNumber(m2.rsa_get_e(self.rsa))
  41. elif name == 'n':
  42. if not self.rsa:
  43. return 0
  44. return mpiToNumber(m2.rsa_get_n(self.rsa))
  45. else:
  46. raise AttributeError
  47. def hasPrivateKey(self):
  48. return self._hasPrivateKey
  49. def hash(self):
  50. return Python_RSAKey(self.n, self.e).hash()
  51. def _rawPrivateKeyOp(self, m):
  52. s = numberToString(m)
  53. byteLength = numBytes(self.n)
  54. if len(s)== byteLength:
  55. pass
  56. elif len(s) == byteLength-1:
  57. s = '\0' + s
  58. else:
  59. raise AssertionError()
  60. c = stringToNumber(m2.rsa_private_encrypt(self.rsa, s,
  61. m2.no_padding))
  62. return c
  63. def _rawPublicKeyOp(self, c):
  64. s = numberToString(c)
  65. byteLength = numBytes(self.n)
  66. if len(s)== byteLength:
  67. pass
  68. elif len(s) == byteLength-1:
  69. s = '\0' + s
  70. else:
  71. raise AssertionError()
  72. m = stringToNumber(m2.rsa_public_decrypt(self.rsa, s,
  73. m2.no_padding))
  74. return m
  75. def acceptsPassword(self): return True
  76. def write(self, password=None):
  77. bio = m2.bio_new(m2.bio_s_mem())
  78. if self._hasPrivateKey:
  79. if password:
  80. def f(v): return password
  81. m2.rsa_write_key(self.rsa, bio, m2.des_ede_cbc(), f)
  82. else:
  83. def f(): pass
  84. m2.rsa_write_key_no_cipher(self.rsa, bio, f)
  85. else:
  86. if password:
  87. raise AssertionError()
  88. m2.rsa_write_pub_key(self.rsa, bio)
  89. s = m2.bio_read(bio, m2.bio_ctrl_pending(bio))
  90. m2.bio_free(bio)
  91. return s
  92. def writeXMLPublicKey(self, indent=''):
  93. return Python_RSAKey(self.n, self.e).write(indent)
  94. def generate(bits):
  95. key = OpenSSL_RSAKey()
  96. def f():pass
  97. key.rsa = m2.rsa_generate_key(bits, 3, f)
  98. key._hasPrivateKey = True
  99. return key
  100. generate = staticmethod(generate)
  101. def parse(s, passwordCallback=None):
  102. if s.startswith("-----BEGIN "):
  103. if passwordCallback==None:
  104. callback = password_callback
  105. else:
  106. def f(v, prompt1=None, prompt2=None):
  107. return passwordCallback()
  108. callback = f
  109. bio = m2.bio_new(m2.bio_s_mem())
  110. try:
  111. m2.bio_write(bio, s)
  112. key = OpenSSL_RSAKey()
  113. if s.startswith("-----BEGIN RSA PRIVATE KEY-----"):
  114. def f():pass
  115. key.rsa = m2.rsa_read_key(bio, callback)
  116. if key.rsa == None:
  117. raise SyntaxError()
  118. key._hasPrivateKey = True
  119. elif s.startswith("-----BEGIN PUBLIC KEY-----"):
  120. key.rsa = m2.rsa_read_pub_key(bio)
  121. if key.rsa == None:
  122. raise SyntaxError()
  123. key._hasPrivateKey = False
  124. else:
  125. raise SyntaxError()
  126. return key
  127. finally:
  128. m2.bio_free(bio)
  129. else:
  130. raise SyntaxError()
  131. parse = staticmethod(parse)