Esempio n. 1
0
File: RSA.py Progetto: 4ZM/pycrypto
    def exportKey(self, format='PEM'):
        """Export the RSA key. A string is returned
        with the encoded public or the private half
        under the selected format.

        format:		'DER' (PKCS#1) or 'PEM' (RFC1421)
        """
        der = DerSequence()
        if self.has_private():
            keyType = "RSA PRIVATE"
            der[:] = [ 0, self.n, self.e, self.d, self.p, self.q,
                   self.d % (self.p-1), self.d % (self.q-1),
                   self.u ]
        else:
            keyType = "PUBLIC"
            der.append(b('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00'))
            bitmap = DerObject('BIT STRING')
            derPK = DerSequence()
            derPK[:] = [ self.n, self.e ]
            bitmap.payload = b('\x00') + derPK.encode()
            der.append(bitmap.encode())
        if format=='DER':
            return der.encode()
        if format=='PEM':
            pem = b("-----BEGIN %s KEY-----\n" % keyType)
            binaryKey = der.encode()
            # Each BASE64 line can take up to 64 characters (=48 bytes of data)
            chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ]
            pem += b('').join(chunks)
            pem += b("-----END %s KEY-----" % keyType)
            return pem
        return ValueError("")
Esempio n. 2
0
 def _importKeyDER(self, externKey):
     der = DerSequence()
     der.decode(externKey, True)
     if len(der)==9 and der.hasOnlyInts() and der[0]==0:
         # ASN.1 RSAPrivateKey element
         del der[6:]	# Remove d mod (p-1), d mod (q-1), and q^{-1} mod p
         der.append(inverse(der[4],der[5])) # Add p^{-1} mod q
         del der[0]	# Remove version
         return self.construct(der[:])
     if len(der)==2:
         # The DER object is a SEQUENCE with two elements:
         # a SubjectPublicKeyInfo SEQUENCE and an opaque BIT STRING.
         #
         # The first element is always the same:
         # 0x30 0x0D     SEQUENCE, 12 bytes of payload
         #   0x06 0x09   OBJECT IDENTIFIER, 9 bytes of payload
         #     0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x01 0x01
         #               rsaEncryption (1 2 840 113549 1 1 1) (PKCS #1)
         #   0x05 0x00   NULL
         #
         # The second encapsulates the actual ASN.1 RSAPublicKey element.
         if der[0]==b('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00'):
             bitmap = DerObject()
             bitmap.decode(der[1], True)
             if bitmap.typeTag==b('\x03')[0] and bitmap.payload[0]==b('\x00')[0]:
                 der.decode(bitmap.payload[1:], True)
                 if len(der)==2 and der.hasOnlyInts():
                     return self.construct(der[:])
     raise ValueError("RSA key format is not supported")
Esempio n. 3
0
	def exportKey(self, format='PEM', public=False, type=None):
		"""Export the RSA key. A string is returned
		with the encoded public or the private half
		under the selected format.
		format: 'DER' (PKCS#1) or 'PEM' (RFC1421)
		"""
		if type == 'ssh-rsa' and public:
			return ''.join(binascii.b2a_base64('\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x03' + '\x00\x00\x01\x01\x00'.join([long_to_bytes(self.e), long_to_bytes(self.n)])).split("\n"))
		
		der = DerSequence()
		if not public and self.has_private():
			keyType = "RSA PRIVATE"
			der[:] = [ 0, self.n, self.e, self.d, self.p, self.q,
				   self.d % (self.p-1), self.d % (self.q-1),
				   self.u ]
		else:
			keyType = "PUBLIC"
			der.append('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00')
			bitmap = DerObject('BIT STRING')
			derPK = DerSequence()
			derPK[:] = [ self.n, self.e ]
			bitmap.payload = '\x00' + derPK.encode()
			der.append(bitmap.encode())
		if format=='DER':
			return der.encode()
		if format=='PEM':
			pem = "-----BEGIN %s KEY-----\n" % keyType
			binaryKey = der.encode()
			# Each BASE64 line can take up to 64 characters (=48 bytes of data)
			chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ]
			pem += ''.join(chunks)
			pem += "-----END %s KEY-----" % keyType
			return pem
		return ValueError("")
Esempio n. 4
0
	def testObjEncode1(self):
		# No payload
		der = DerObject('\x33')
		self.assertEquals(der.encode(), '\x33\x00')
		# Small payload
		der.payload = '\x45'
		self.assertEquals(der.encode(), '\x33\x01\x45')
		# Invariant
		self.assertEquals(der.encode(), '\x33\x01\x45')
Esempio n. 5
0
    def exportKey(self, format="PEM"):
        """Export the RSA key. A string is returned
        with the encoded public or the private half
        under the selected format.

        format:		'DER' (PKCS#1) or 'PEM' (RFC1421)
        """
        der = DerSequence()
        if self.has_private():
            keyType = "RSA PRIVATE"
            der[:] = [0, self.n, self.e, self.d, self.p, self.q, self.d % (self.p - 1), self.d % (self.q - 1), self.u]
        else:
            keyType = "PUBLIC"
            der.append("\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00")
            bitmap = DerObject("BIT STRING")
            derPK = DerSequence()
            derPK[:] = [self.n, self.e]
            bitmap.payload = "\x00" + derPK.encode()
            der.append(bitmap.encode())
        if format == "DER":
            return der.encode()
        if format == "PEM":
            pem = "-----BEGIN %s KEY-----\n" % keyType
            binaryKey = der.encode()
            # Each BASE64 line can take up to 64 characters (=48 bytes of data)
            chunks = []
            for i in range(0, len(binaryKey), 48):
                chunks.append(binascii.b2a_base64(binaryKey[i : i + 48]))
            pem += "".join(chunks)
            pem += "-----END %s KEY-----" % keyType
            return pem
        if format == "SSH":
            # Create public key.
            ssh_rsa = "00000007" + base64.b16encode("ssh-rsa")

            # Exponent.
            exponent = "%x" % (self.key.e,)
            if len(exponent) % 2:
                exponent = "0" + exponent

            ssh_rsa += "%08x" % (len(exponent) / 2,)
            ssh_rsa += exponent

            modulus = "%x" % (self.key.n,)
            if len(modulus) % 2:
                modulus = "0" + modulus

            if modulus[0] in "89abcdef":
                modulus = "00" + modulus

            ssh_rsa += "%08x" % (len(modulus) / 2,)
            ssh_rsa += modulus

            return "ssh-rsa %s" % (base64.b64encode(base64.b16decode(ssh_rsa.upper())),)

        return ValueError("")
Esempio n. 6
0
def get_pubkey_ssh2_fingerprint(pubkey):
    # This is the format that EC2 shows for public key fingerprints in its
    # KeyPair mgmt API
    if not pycrypto_available:
        raise RuntimeError('pycrypto is not available')
    k = importKey(pubkey)
    derPK = DerSequence([k.n, k.e])
    bitmap = DerObject('BIT STRING')
    bitmap.payload = bchr(0x00) + derPK.encode()
    der = DerSequence([algorithmIdentifier, bitmap.encode()])
    return _to_md5_fingerprint(der.encode())
Esempio n. 7
0
 def testObjEncode1(self):
     # No payload
     der = DerObject(b('\x02'))
     self.assertEqual(der.encode(), b('\x02\x00'))
     # Small payload (primitive)
     der.payload = b('\x45')
     self.assertEqual(der.encode(), b('\x02\x01\x45'))
     # Invariant
     self.assertEqual(der.encode(), b('\x02\x01\x45'))
     # Initialize with numerical tag
     der = DerObject(0x04)
     der.payload = b('\x45')
     self.assertEqual(der.encode(), b('\x04\x01\x45'))
     # Initialize with constructed type
     der = DerObject(b('\x10'), constructed=True)
     self.assertEqual(der.encode(), b('\x30\x00'))
Esempio n. 8
0
File: RSA.py Progetto: 4ZM/pycrypto
 def _importKeyDER(self, externKey):
     der = DerSequence()
     der.decode(externKey, True)
     if len(der)==9 and der.hasOnlyInts() and der[0]==0:
         # ASN.1 RSAPrivateKey element
         del der[6:8]	# Remove d mod (p-1) and d mod (q-1)
         del der[0]	# Remove version
         return self.construct(der[:])
     if len(der)==2:
         # ASN.1 SubjectPublicKeyInfo element
         if der[0]==b('\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00'):
             bitmap = DerObject()
             bitmap.decode(der[1], True)
             if bitmap.typeTag==b('\x03')[0] and bitmap.payload[0]==b('\x00')[0]:
                 der.decode(bitmap.payload[1:], True)
                 if len(der)==2 and der.hasOnlyInts():
                     return self.construct(der[:])
     raise ValueError("RSA key format is not supported")
Esempio n. 9
0
 def testObjEncode1(self):
     # No payload
     der = DerObject(b('\x33'))
     self.assertEquals(der.encode(), b('\x33\x00'))
     # Small payload
     der.payload = b('\x45')
     self.assertEquals(der.encode(), b('\x33\x01\x45'))
     # Invariant
     self.assertEquals(der.encode(), b('\x33\x01\x45'))
     # Initialize with numerical tag
     der = DerObject(b(0x33))
     der.payload = b('\x45')
     self.assertEquals(der.encode(), b('\x33\x01\x45'))
Esempio n. 10
0
 def testObjEncode4(self):
     # Implicit tags (constructed)
     der = DerObject(0x10, implicit=1, constructed=True)
     der.payload = b('ppll')
     self.assertEqual(der.encode(), b('\xa1\x04ppll'))
     # Implicit tags (primitive)
     der = DerObject(0x02, implicit=0x1E, constructed=False)
     der.payload = b('ppll')
     self.assertEqual(der.encode(), b('\x9E\x04ppll'))
Esempio n. 11
0
File: RSA.py Progetto: 5ant/lantern
    def _importKeyDER(self, externKey):
        """Import an RSA key (public or private half), encoded in DER form."""

        try:

            der = DerSequence()
            der.decode(externKey, True)

            # Try PKCS#1 first, for a private key
            if len(der)==9 and der.hasOnlyInts() and der[0]==0:
                # ASN.1 RSAPrivateKey element
                del der[6:]     # Remove d mod (p-1), d mod (q-1), and q^{-1} mod p
                der.append(inverse(der[4],der[5])) # Add p^{-1} mod q
                del der[0]      # Remove version
                return self.construct(der[:])

            # Keep on trying PKCS#1, but now for a public key
            if len(der)==2:
                # The DER object is an RSAPublicKey SEQUENCE with two elements
                if der.hasOnlyInts():
                    return self.construct(der[:])
                # The DER object is a SubjectPublicKeyInfo SEQUENCE with two elements:
                # an 'algorithm' (or 'algorithmIdentifier') SEQUENCE and a 'subjectPublicKey' BIT STRING.
                # 'algorithm' takes the value given a few lines above.
                # 'subjectPublicKey' encapsulates the actual ASN.1 RSAPublicKey element.
                if der[0]==algorithmIdentifier:
                        bitmap = DerObject()
                        bitmap.decode(der[1], True)
                        if bitmap.isType('BIT STRING') and bord(bitmap.payload[0])==0x00:
                                der.decode(bitmap.payload[1:], True)
                                if len(der)==2 and der.hasOnlyInts():
                                        return self.construct(der[:])

            # Try unencrypted PKCS#8
            if der[0]==0:
                # The second element in the SEQUENCE is algorithmIdentifier.
                # It must say RSA (see above for description).
                if der[1]==algorithmIdentifier:
                    privateKey = DerObject()
                    privateKey.decode(der[2], True)
                    if privateKey.isType('OCTET STRING'):
                        return self._importKeyDER(privateKey.payload)

        except (ValueError, IndexError):
            pass

        raise ValueError("RSA key format is not supported")
Esempio n. 12
0
 def testObjDecode4(self):
     # Decode implicit tag (primitive)
     der = DerObject(0x02, constructed=False, implicit=0xF)
     self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02'))
     der.decode(b('\x8F\x01\x00'))
     self.assertEqual(der.payload, b('\x00'))
     # Decode implicit tag (constructed)
     der = DerObject(0x02, constructed=True, implicit=0xF)
     self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02'))
     der.decode(b('\xAF\x01\x00'))
     self.assertEqual(der.payload, b('\x00'))
Esempio n. 13
0
    def testObjDecode7(self):
        # Decode explicit tag
        der = DerObject(0x10, explicit=5)
        der.decode(b("\xa5\x06\x10\x04xxll"))
        self.assertEqual(der._tag_octet, 0x10)
        self.assertEqual(der.payload, b('xxll'))

        # Explicit tag may be 0
        der = DerObject(0x10, explicit=0)
        der.decode(b("\xa0\x06\x10\x04xxll"))
        self.assertEqual(der._tag_octet, 0x10)
        self.assertEqual(der.payload, b('xxll'))
Esempio n. 14
0
	def testObjDecode2(self):
		# Decode short payload
		der = DerObject()
		der.decode('\x22\x81\x80' + ("1"*128))
		self.assertEquals(der.payload, "1"*128)
		self.assertEquals(der.typeTag, "\x22")
Esempio n. 15
0
	def testObjEncode3(self):
		# Long payload
		der = DerObject('\x34')
		der.payload = "0"*128
		self.assertEquals(der.encode(), '\x34\x81\x80' + ("0"*128))		
Esempio n. 16
0
	def testObjDecode1(self):
		# Decode short payload
		der = DerObject()
		der.decode('\x20\x02\x01\x02')
		self.assertEquals(der.payload, "\x01\x02")
		self.assertEquals(der.typeTag, "\x20")
Esempio n. 17
0
 def testObjEncode3(self):
     # Long payload
     der = DerObject(b("\x34"))
     der.payload = b("0") * 128
     self.assertEquals(der.encode(), b("\x34\x81\x80" + "0" * 128))
Esempio n. 18
0
	def testObjEncode2(self):
		# Known types
		der = DerObject('SEQUENCE')
		self.assertEquals(der.encode(), '\x30\x00')
		der = DerObject('BIT STRING')
		self.assertEquals(der.encode(), '\x03\x00')
Esempio n. 19
0
File: RSA.py Progetto: 5ant/lantern
    def exportKey(self, format='PEM', passphrase=None, pkcs=1):
        """Export this RSA key.

        :Parameter format: The format to use for wrapping the key.

            - *'DER'*. Binary encoding, always unencrypted.
            - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_.
              Unencrypted (default) or encrypted.
            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
              Only suitable for public keys (not private keys).
        :Type format: string

        :Parameter passphrase: In case of PEM, the pass phrase to derive the encryption key from.
        :Type passphrase: string 

        :Parameter pkcs: The PKCS standard to follow for assembling the key.
         You have two choices:

          - with **1**, the public key is embedded into an X.509 `SubjectPublicKeyInfo` DER SEQUENCE.
            The private key is embedded into a `PKCS#1`_ `RSAPrivateKey` DER SEQUENCE.
            This mode is the default.
          - with **8**, the private key is embedded into a `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE.
            This mode is not available for public keys.

         PKCS standards are not relevant for the *OpenSSH* format.
        :Type pkcs: integer

        :Return: A byte string with the encoded public or private half.
        :Raise ValueError:
            When the format is unknown.

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """
        if passphrase is not None:
            passphrase = tobytes(passphrase)
        if format=='OpenSSH':
               eb = long_to_bytes(self.e)
               nb = long_to_bytes(self.n)
               if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb
               if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb
               keyparts = [ b('ssh-rsa'), eb, nb ]
               keystring = b('').join([ struct.pack(">I",len(kp))+kp for kp in keyparts])
               return b('ssh-rsa ')+binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        der = DerSequence()
        if self.has_private():
                keyType= { 1: 'RSA PRIVATE', 8: 'PRIVATE' }[pkcs]
                der[:] = [ 0, self.n, self.e, self.d, self.p, self.q,
                           self.d % (self.p-1), self.d % (self.q-1),
                           inverse(self.q, self.p) ]
                if pkcs==8:
                    derkey = der.encode()
                    der = DerSequence([0])
                    der.append(algorithmIdentifier)
                    der.append(DerObject('OCTET STRING', derkey).encode())
        else:
                keyType = "PUBLIC"
                der.append(algorithmIdentifier)
                bitmap = DerObject('BIT STRING')
                derPK = DerSequence( [ self.n, self.e ] )
                bitmap.payload = bchr(0x00) + derPK.encode()
                der.append(bitmap.encode())
        if format=='DER':
                return der.encode()
        if format=='PEM':
                pem = b("-----BEGIN " + keyType + " KEY-----\n")
                objenc = None
                if passphrase and keyType.endswith('PRIVATE'):
                    # We only support 3DES for encryption
                    import Crypto.Hash.MD5
                    from Crypto.Cipher import DES3
                    from Crypto.Protocol.KDF import PBKDF1
                    salt = self._randfunc(8)
                    key =  PBKDF1(passphrase, salt, 16, 1, Crypto.Hash.MD5)
                    key += PBKDF1(key+passphrase, salt, 8, 1, Crypto.Hash.MD5)
                    objenc = DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, salt)
                    pem += b('Proc-Type: 4,ENCRYPTED\n')
                    pem += b('DEK-Info: DES-EDE3-CBC,') + binascii.b2a_hex(salt).upper() + b('\n\n')
                
                binaryKey = der.encode()
                if objenc:
                    # Add PKCS#7-like padding
                    padding = objenc.block_size-len(binaryKey)%objenc.block_size
                    binaryKey = objenc.encrypt(binaryKey+bchr(padding)*padding)

                # Each BASE64 line can take up to 64 characters (=48 bytes of data)
                chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ]
                pem += b('').join(chunks)
                pem += b("-----END " + keyType + " KEY-----")
                return pem
        return ValueError("Unknown key format '%s'. Cannot export the RSA key." % format)
Esempio n. 20
0
	def testObjDecode1(self):
		# Decode short payload
		der = DerObject()
		der.decode(b('\x20\x02\x01\x02'))
		self.assertEqual(der.payload, b("\x01\x02"))
		self.assertEqual(der.typeTag, 0x20)
Esempio n. 21
0
 def testObjEncode5(self):
     # Encode type with explicit tag
     der = DerObject(0x10, explicit=5)
     der.payload = b("xxll")
     self.assertEqual(der.encode(), b("\xa5\x06\x10\x04xxll"))
Esempio n. 22
0
 def testObjDecode1(self):
     # Decode short payload
     der = DerObject(0x02)
     der.decode(b('\x02\x02\x01\x02'))
     self.assertEqual(der.payload, b("\x01\x02"))
     self.assertEqual(der._tag_octet, 0x02)
Esempio n. 23
0
 def testObjEncode3(self):
     # Long payload
     der = DerObject(b('\x10'))
     der.payload = b("0")*128
     self.assertEqual(der.encode(), b('\x10\x81\x80' + "0"*128))
Esempio n. 24
0
	def testObjDecode2(self):
		# Decode short payload
		der = DerObject()
		der.decode(b('\x22\x81\x80' + "1"*128))
		self.assertEqual(der.payload, b("1")*128)
		self.assertEqual(der.typeTag, 0x22)
Esempio n. 25
0
 def testObjEncode2(self):
     # Initialize with payload
     der = DerObject(0x03, b('\x12\x12'))
     self.assertEqual(der.encode(), b('\x03\x02\x12\x12'))
Esempio n. 26
0
 def testObjDecode2(self):
     # Decode long payload
     der = DerObject(0x02)
     der.decode(b('\x02\x81\x80' + "1"*128))
     self.assertEqual(der.payload, b("1")*128)
     self.assertEqual(der._tag_octet, 0x02)
Esempio n. 27
0
 def testObjDecode8(self):
     # Verify that decode returns the object
     der = DerObject(0x02)
     self.assertEqual(der, der.decode(b('\x02\x02\x01\x02')))
Esempio n. 28
0
 def testObjEncode2(self):
     # Known types
     der = DerObject("SEQUENCE")
     self.assertEquals(der.encode(), b("\x30\x00"))
     der = DerObject("BIT STRING")
     self.assertEquals(der.encode(), b("\x03\x00"))
Esempio n. 29
0
 def testObjDecode6(self):
     # Arbitrary DER object
     der = DerObject()
     der.decode(b('\x65\x01\x88'))
     self.assertEqual(der._tag_octet, 0x65)
     self.assertEqual(der.payload, b('\x88'))