tlslite.utils.python_rsakey

Package tlslite :: Package utils :: Module python_rsakey |
[hide private]
[frames] | no frames]

# Source Code for Module tlslite.utils.python_rsakey

      1  # Author: Trevor Perrin
      2  # See the LICENSE file for legal information regarding use of this file.
      3
      4  """Pure-Python RSA implementation."""
      5
      6  from .cryptomath import *
      7  from .asn1parser import ASN1Parser
      8  from .rsakey import *
      9  from .pem import *
     10
     11 -class Python_RSAKey(RSAKey):
     12 -    def __init__(self, n=0, e=0, d=0, p=0, q=0, dP=0, dQ=0, qInv=0):
     13          if (n and not e) or (e and not n):
     14              raise AssertionError()
     15          self.n = n
     16          self.e = e
     17          self.d = d
     18          self.p = p
     19          self.q = q
     20          self.dP = dP
     21          self.dQ = dQ
     22          self.qInv = qInv
     23          self.blinder = 0
     24          self.unblinder = 0
     25
     26 -    def hasPrivateKey(self):
     27          return self.d != 0
     28
     29 -    def _rawPrivateKeyOp(self, m):
     30          #Create blinding values, on the first pass:
     31          if not self.blinder:
     32              self.unblinder = getRandomNumber(2, self.n)
     33              self.blinder = powMod(invMod(self.unblinder, self.n), self.e,
     34                                    self.n)
     35
     36          #Blind the input
     37          m = (m * self.blinder) % self.n
     38
     39          #Perform the RSA operation
     40          c = self._rawPrivateKeyOpHelper(m)
     41
     42          #Unblind the output
     43          c = (c * self.unblinder) % self.n
     44
     45          #Update blinding values
     46          self.blinder = (self.blinder * self.blinder) % self.n
     47          self.unblinder = (self.unblinder * self.unblinder) % self.n
     48
     49          #Return the output
     50          return c
     51
     52
     53 -    def _rawPrivateKeyOpHelper(self, m):
     54          #Non-CRT version
     55          #c = powMod(m, self.d, self.n)
     56
     57          #CRT version  (~3x faster)
     58          s1 = powMod(m, self.dP, self.p)
     59          s2 = powMod(m, self.dQ, self.q)
     60          h = ((s1 - s2) * self.qInv) % self.p
     61          c = s2 + self.q * h
     62          return c
     63
     64 -    def _rawPublicKeyOp(self, c):
     65          m = powMod(c, self.e, self.n)
     66          return m
     67
     68 -    def acceptsPassword(self): return False
     69
     70 -    def generate(bits):
     71          key = Python_RSAKey()
     72          p = getRandomPrime(bits//2, False)
     73          q = getRandomPrime(bits//2, False)
     74          t = lcm(p-1, q-1)
     75          key.n = p * q
     76          key.e = 65537
     77          key.d = invMod(key.e, t)
     78          key.p = p
     79          key.q = q
     80          key.dP = key.d % (p-1)
     81          key.dQ = key.d % (q-1)
     82          key.qInv = invMod(q, p)
     83          return key
     84      generate = staticmethod(generate)
     85
     86 -    def parsePEM(s, passwordCallback=None):
     87          """Parse a string containing a PEM-encoded <privateKey>."""
     88
     89          if pemSniff(s, "PRIVATE KEY"):
     90              bytes = dePem(s, "PRIVATE KEY")
     91              return Python_RSAKey._parsePKCS8(bytes)
     92          elif pemSniff(s, "RSA PRIVATE KEY"):
     93              bytes = dePem(s, "RSA PRIVATE KEY")
     94              return Python_RSAKey._parseSSLeay(bytes)
     95          else:
     96              raise SyntaxError("Not a PEM private key file")
     97      parsePEM = staticmethod(parsePEM)
     98
     99 -    def _parsePKCS8(bytes):
    100          p = ASN1Parser(bytes)
    101
    102          version = p.getChild(0).value[0]
    103          if version != 0:
    104              raise SyntaxError("Unrecognized PKCS8 version")
    105
    106          rsaOID = p.getChild(1).value
    107          if list(rsaOID) != [6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0]:
    108              raise SyntaxError("Unrecognized AlgorithmIdentifier")
    109
    110          #Get the privateKey
    111          privateKeyP = p.getChild(2)
    112
    113          #Adjust for OCTET STRING encapsulation
    114          privateKeyP = ASN1Parser(privateKeyP.value)
    115
    116          return Python_RSAKey._parseASN1PrivateKey(privateKeyP)
    117      _parsePKCS8 = staticmethod(_parsePKCS8)
    118
    119 -    def _parseSSLeay(bytes):
    120          privateKeyP = ASN1Parser(bytes)
    121          return Python_RSAKey._parseASN1PrivateKey(privateKeyP)
    122      _parseSSLeay = staticmethod(_parseSSLeay)
    123
    124 -    def _parseASN1PrivateKey(privateKeyP):
    125          version = privateKeyP.getChild(0).value[0]
    126          if version != 0:
    127              raise SyntaxError("Unrecognized RSAPrivateKey version")
    128          n = bytesToNumber(privateKeyP.getChild(1).value)
    129          e = bytesToNumber(privateKeyP.getChild(2).value)
    130          d = bytesToNumber(privateKeyP.getChild(3).value)
    131          p = bytesToNumber(privateKeyP.getChild(4).value)
    132          q = bytesToNumber(privateKeyP.getChild(5).value)
    133          dP = bytesToNumber(privateKeyP.getChild(6).value)
    134          dQ = bytesToNumber(privateKeyP.getChild(7).value)
    135          qInv = bytesToNumber(privateKeyP.getChild(8).value)
    136          return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv)
    137      _parseASN1PrivateKey = staticmethod(_parseASN1PrivateKey)
    138