Esempio n. 1
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. 2
0
 def testObjEncode2(self):
     # Initialize with payload
     der = DerObject(0x03, b('\x12\x12'))
     self.assertEquals(der.encode(), b('\x03\x02\x12\x12'))
Esempio n. 3
0
 def testObjEncode3(self):
     # Long payload
     der = DerObject(b('\x10'))
     der.payload = b("0") * 128
     self.assertEquals(der.encode(), b('\x10\x81\x80' + "0" * 128))
Esempio n. 4
0
 def testObjDecode6(self):
     # Arbitrary DER object
     der = DerObject()
     der.decode(b('\x65\x01\x88'))
     self.assertEquals(der._tag_octet, 0x65)
     self.assertEquals(der.payload, b('\x88'))
Esempio n. 5
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. 6
0
 def testObjDecode2(self):
     # Decode long payload
     der = DerObject(0x02)
     der.decode(b('\x02\x81\x80' + "1" * 128))
     self.assertEquals(der.payload, b("1") * 128)
     self.assertEquals(der._tag_octet, 0x02)
Esempio n. 7
0
 def testObjDecode5(self):
     # Decode payload with unexpected tag gives error
     der = DerObject(0x02)
     self.assertRaises(ValueError, der.decode, b('\x03\x02\x01\x02'))
Esempio n. 8
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._idOctet, 0x02)
Esempio n. 9
0
	def testObjDecode2(self):
		# Decode short payload
		der = DerObject()
		der.decode(b('\x22\x81\x80' + "1"*128))
		self.assertEquals(der.payload, b("1")*128)
		self.assertEquals(der.typeTag, 0x22)
Esempio n. 10
0
	def testObjDecode1(self):
		# Decode short payload
		der = DerObject()
		der.decode(b('\x20\x02\x01\x02'))
		self.assertEquals(der.payload, b("\x01\x02"))
		self.assertEquals(der.typeTag, 0x20)
Esempio n. 11
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. 12
0
    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 = [ 'ssh-rsa', eb, nb ]
               keystring = ''.join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) 
               return '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)