Beispiel #1
0
 def testEncode4(self):
     # One very long integer
     der = DerSequence()
     der.append(2 ** 2048)
     self.assertEquals(
         der.encode(),
         b("0\x82\x01\x05")
         + b("\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
         + b("\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
     )
Beispiel #2
0
 def testEncode7(self):
     # One integer and another type (no matter what it is)
     der = DerSequence()
     der.append(0x180)
     der.append(b('\x00\x02\x00\x00'))
     self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00'))
     self.assertFalse(der.hasOnlyInts())
Beispiel #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("")
Beispiel #4
0
 def testEncode7(self):
     # One integer and another type (already encoded)
     der = DerSequence()
     der.append(0x180)
     der.append(b('0\x03\x02\x01\x05'))
     self.assertEqual(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05'))
     self.assertFalse(der.hasOnlyInts())
 def testEncode8(self):
     # One integer and another type (yet to encode)
     der = DerSequence()
     der.append(0x180)
     der.append(DerSequence([5]))
     self.assertEquals(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05'))
     self.failIf(der.hasOnlyInts())
Beispiel #6
0
 def testEncode8(self):
     # One integer and another type (yet to encode)
     der = DerSequence()
     der.append(0x180)
     der.append(DerSequence([5]))
     self.assertEqual(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05'))
     self.assertFalse(der.hasOnlyInts())
Beispiel #7
0
	def testEncode6(self):
		# One integer and another type (no matter what it is)
		der = DerSequence()
		der.append(0x180L)
		der.append('\x00\x02\x00\x00')
		self.assertEquals(der.encode(), '0\x08\x02\x02\x01\x80\x00\x02\x00\x00')
		self.failIf(der.hasOnlyInts())
Beispiel #8
0
 def testEncode6(self):
     # Two positive integers
     der = DerSequence()
     der.append(0x180)
     der.append(0xFF)
     self.assertEquals(der.encode(),
                       b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
     self.failUnless(der.hasOnlyInts())
     self.failUnless(der.hasOnlyInts(False))
     # Two mixed integers
     der = DerSequence()
     der.append(2)
     der.append(-2)
     self.assertEquals(der.encode(), b('0\x06\x02\x01\x02\x02\x01\xFE'))
     self.assertEquals(der.hasInts(), 1)
     self.assertEquals(der.hasInts(False), 2)
     self.failIf(der.hasOnlyInts())
     self.failUnless(der.hasOnlyInts(False))
     #
     der.append(0x01)
     der[1:] = [9, 8]
     self.assertEquals(len(der), 3)
     self.assertEqual(der[1:], [9, 8])
     self.assertEqual(der[1:-1], [9])
     self.assertEquals(der.encode(),
                       b('0\x09\x02\x01\x02\x02\x01\x09\x02\x01\x08'))
Beispiel #9
0
 def testEncode4(self):
     # One very long integer
     der = DerSequence()
     der.append(2**2048)
     self.assertEquals(
         der.encode(), '0\x82\x01\x05'
         '\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
         '\x00\x00\x00\x00\x00\x00\x00\x00\x00')
Beispiel #10
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(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("")
Beispiel #11
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")
Beispiel #12
0
 def testEncode7(self):
     # One integer and another type (already encoded)
     der = DerSequence()
     der.append(0x180)
     der.append(b('0\x03\x02\x01\x05'))
     self.assertEqual(der.encode(), b('0\x09\x02\x02\x01\x800\x03\x02\x01\x05'))
     self.assertFalse(der.hasOnlyInts())
Beispiel #13
0
def _importKeyDER(extern_key, passphrase, verify_x509_cert):
    """Import an RSA key (public or private half), encoded in DER form."""

    try:

        der = DerSequence().decode(extern_key)

        # 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(Integer(der[4]).inverse(der[5]))  # Add p^{-1} mod q
            del der[0]      # Remove version
            return construct(der[:])

        # Keep on trying PKCS#1, but now for a public key
        if len(der) == 2:
            try:
                # The DER object is an RSAPublicKey SEQUENCE with
                # two elements
                if der.hasOnlyInts():
                    return construct(der[:])
                # The DER object is a SubjectPublicKeyInfo SEQUENCE
                # with two elements: an 'algorithmIdentifier' and a
                # 'subjectPublicKey'BIT STRING.
                # 'algorithmIdentifier' takes the value given at the
                # module level.
                # 'subjectPublicKey' encapsulates the actual ASN.1
                # RSAPublicKey element.
                if der[0] == algorithmIdentifier:
                    bitmap = DerBitString().decode(der[1])
                    rsaPub = DerSequence().decode(bitmap.value)
                    if len(rsaPub) == 2 and rsaPub.hasOnlyInts():
                        return construct(rsaPub[:])
            except (ValueError, EOFError):
                pass

        # Try to see if this is an X.509 DER certificate
        # (Certificate ASN.1 type)
        if len(der) == 3:
            from Crypto.PublicKey import _extract_sp_info
            try:
                sp_info = _extract_sp_info(der)
                if verify_x509_cert:
                    raise NotImplementedError("X.509 certificate validation is not supported")
                return _importKeyDER(sp_info, passphrase, False)
            except ValueError:
                pass

        # Try PKCS#8 (possibly encrypted)
        k = PKCS8.unwrap(extern_key, passphrase)
        if k[0] == oid:
            return _importKeyDER(k[1], passphrase, False)

    except (ValueError, EOFError):
        pass

    raise ValueError("RSA key format is not supported")
Beispiel #14
0
 def testEncode7(self):
     # One integer and another type (no matter what it is)
     der = DerSequence()
     der.append(0x180)
     der.append(b('\x00\x02\x00\x00'))
     self.assertEqual(der.encode(),
                      b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00'))
     self.assertFalse(der.hasOnlyInts())
Beispiel #15
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("")
Beispiel #16
0
	def testEncode1(self):
		# Empty sequence
		der = DerSequence()
		self.assertEqual(der.encode(), b('0\x00'))
		self.assertFalse(der.hasOnlyInts())
		# One single-byte integer (zero)
		der.append(0)
		self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
		self.assertTrue(der.hasOnlyInts())
		# Invariant
		self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
Beispiel #17
0
 def testEncode1(self):
     # Empty sequence
     der = DerSequence()
     self.assertEqual(der.encode(), b('0\x00'))
     self.assertFalse(der.hasOnlyInts())
     # One single-byte integer (zero)
     der.append(0)
     self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
     self.assertTrue(der.hasOnlyInts())
     # Invariant
     self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
Beispiel #18
0
	def testEncode1(self):
		# Empty sequence
		der = DerSequence()
		self.assertEquals(der.encode(), '0\x00')
		self.failIf(der.hasOnlyInts())
		# One single-byte integer (zero)
		der.append(0)
		self.assertEquals(der.encode(), '0\x03\x02\x01\x00')
		self.failUnless(der.hasOnlyInts())
		# Invariant
		self.assertEquals(der.encode(), '0\x03\x02\x01\x00')
Beispiel #19
0
	def testEncode6(self):
		# Two integers
		der = DerSequence()
		der.append(0x180L)
		der.append(0xFFL)
		self.assertEquals(der.encode(), '0\x08\x02\x02\x01\x80\x02\x02\x00\xff')
		self.failUnless(der.hasOnlyInts())
		#
		der.append(0x01)
		der[1:] = [9,8]
		self.assertEquals(len(der),3)
		self.assertEqual(der[1:],[9,8])
		self.assertEqual(der[1:-1],[9])
		self.assertEquals(der.encode(), '0\x0A\x02\x02\x01\x80\x02\x01\x09\x02\x01\x08')
Beispiel #20
0
 def testEncode2(self):
     # Indexing
     der = DerSequence()
     der.append(0)
     der[0] = 1
     self.assertEqual(len(der),1)
     self.assertEqual(der[0],1)
     self.assertEqual(der[-1],1)
     self.assertEqual(der.encode(), b('0\x03\x02\x01\x01'))
     #
     der[:] = [1]
     self.assertEqual(len(der),1)
     self.assertEqual(der[0],1)
     self.assertEqual(der.encode(), b('0\x03\x02\x01\x01'))
Beispiel #21
0
 def testEncode2(self):
     # Indexing
     der = DerSequence()
     der.append(0)
     der[0] = 1
     self.assertEquals(len(der), 1)
     self.assertEquals(der[0], 1)
     self.assertEquals(der[-1], 1)
     self.assertEquals(der.encode(), b('0\x03\x02\x01\x01'))
     #
     der[:] = [1]
     self.assertEquals(len(der), 1)
     self.assertEquals(der[0], 1)
     self.assertEquals(der.encode(), b('0\x03\x02\x01\x01'))
Beispiel #22
0
    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")
Beispiel #23
0
	def testEncode2(self):
		# One single-byte integer (non-zero)
		der = DerSequence()
		der.append(127)
		self.assertEquals(der.encode(), '0\x03\x02\x01\x7f')
		# Indexing
		der[0] = 1
		self.assertEquals(len(der),1)
		self.assertEquals(der[0],1)
		self.assertEquals(der[-1],1)
		self.assertEquals(der.encode(), '0\x03\x02\x01\x01')
		#
		der[:] = [1]
		self.assertEquals(len(der),1)
		self.assertEquals(der[0],1)
		self.assertEquals(der.encode(), '0\x03\x02\x01\x01')
Beispiel #24
0
    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")
Beispiel #25
0
def pkcs1_v1_5_encode(msg_hash: SHA256.SHA256Hash, emLen: int) -> bytes:
    # this code is copied from  EMSA_PKCS1_V1_5_ENCODE
    # https://github.com/dlitz/pycrypto/blob/v2.7a1/lib/Crypto/Signature/PKCS1_v1_5.py#L173
    digestAlgo = DerSequence([ DerObjectId(msg_hash.oid).encode() ])

    #if with_hash_parameters:
    if True:
        digestAlgo.append(DerNull().encode())

    digest      = DerOctetString(msg_hash.digest())
    digestInfo  = DerSequence([
                    digestAlgo.encode(),
                      digest.encode()
                    ]).encode()

    # We need at least 11 bytes for the remaining data: 3 fixed bytes and
    # at least 8 bytes of padding).
    if emLen<len(digestInfo)+11:
          raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest))
    PS = b'\xFF' * (emLen - len(digestInfo) - 3)
    return b'\x00\x01' + PS + b'\x00' + digestInfo
def sign_bytes_dsa(byte_array, path_to_private_key_pem_file):
    # Use this method for DSA keys
    key = open(path_to_private_key_pem_file, 'r').read()
    # Import the key
    dsa_key = DSA.importKey(key)

    # Create a digest of nonce + cnonce
    # This only seems to work with SHA1 (SHA256 gives us a 401 error)
    buf = buffer(byte_array)
    digest = SHA1.new(buf).digest()

    # Digitally sign the digest with our private key
    # The corresponding public key is in our admin handle on the server
    k = random.StrongRandom().randint(1, dsa_key.q-1)
    sign = dsa_key.sign(digest, k)

    # Signature bytes from a DSA key need to be DER-encoded
    # This signature is in two parts (r and s)
    seq = DerSequence()
    seq.append(sign[0])
    seq.append(sign[1])

    return seq.encode()
def sign_bytes_dsa(byte_array, path_to_private_key_pem_file):
    # Use this method for DSA keys
    key = open(path_to_private_key_pem_file, 'r').read()
    # Import the key
    dsa_key = DSA.importKey(key)

    # Create a digest of nonce + cnonce
    # This only seems to work with SHA1 (SHA256 gives us a 401 error)
    buf = buffer(byte_array)
    digest = SHA1.new(buf).digest()

    # Digitally sign the digest with our private key
    # The corresponding public key is in our admin handle on the server
    k = random.StrongRandom().randint(1, dsa_key.q - 1)
    sign = dsa_key.sign(digest, k)

    # Signature bytes from a DSA key need to be DER-encoded
    # This signature is in two parts (r and s)
    seq = DerSequence()
    seq.append(sign[0])
    seq.append(sign[1])

    return seq.encode()
Beispiel #28
0
        def CRYPTO_EMSA_PKCS1_V1_5_ENCODE(M, emLen):
            msg_hash = SHA256.new(M)
            digestAlgo = DerSequence([DerObjectId(msg_hash.oid).encode()])
            print(digestAlgo)

            digestAlgo.append(DerNull().encode())

            digest = DerOctetString(msg_hash.digest())
            digestInfo = DerSequence([digestAlgo.encode(),
                                      digest.encode()]).encode()
            print("%x" % int.from_bytes(digestInfo, byteorder='big'))
            print("%x" % int.from_bytes(digestAlgo.encode(), byteorder='big'))
            print("%x" % int.from_bytes(digest.encode(), byteorder='big'))
            print("%x" % int.from_bytes(msg_hash.digest(), byteorder='big'))

            #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc132273 2004 00 0501020403650148866009060d30 3130
            #                                                                          501020403650148866009060d30
            #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc132273 2004
            #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc132273
            #b91d0b7a09f57c109926a449647283adb5dc213c0fdb0cf2b219e064cc1322732004000501020403650148866009060d30313000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0100

            #3031 300d06096086480165030402010500 0420 732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9
            #     300d06096086480165030402010500
            #                                    0420 732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9
            #                                         732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9
            #0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420732213cc64e019b2f20cdb0f3c21dcb5ad83726449a42699107cf5097a0b1db9

            # We need at least 11 bytes for the remaining data: 3 fixed bytes and
            # at least 8 bytes of padding).
            if emLen < len(digestInfo) + 11:
                raise TypeError(
                    "Selected hash algorith has a too long digest (%d bytes)."
                    % len(digest))
            PS = b'\xFF' * (emLen - len(digestInfo) - 3)
            out = b'\x00\x01' + PS + b'\x00' + digestInfo
            print("%x" % int.from_bytes(out, byteorder='big'))
            return out
Beispiel #29
0
 def testEncode4(self):
     # One very long integer
     der = DerSequence()
     der.append(2**2048)
     self.assertEqual(der.encode(), b('0\x82\x01\x05')+
     b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
Beispiel #30
0
 def testEncode6(self):
     # Two positive integers
     der = DerSequence()
     der.append(0x180)
     der.append(0xFF)
     self.assertEqual(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
     self.assertTrue(der.hasOnlyInts())
     self.assertTrue(der.hasOnlyInts(False))
     # Two mixed integers
     der = DerSequence()
     der.append(2)
     der.append(-2)
     self.assertEqual(der.encode(), b('0\x06\x02\x01\x02\x02\x01\xFE'))
     self.assertEqual(der.hasInts(), 1)
     self.assertEqual(der.hasInts(False), 2)
     self.assertFalse(der.hasOnlyInts())
     self.assertTrue(der.hasOnlyInts(False))
     #
     der.append(0x01)
     der[1:] = [9,8]
     self.assertEqual(len(der),3)
     self.assertEqual(der[1:],[9,8])
     self.assertEqual(der[1:-1],[9])
     self.assertEqual(der.encode(), b('0\x09\x02\x01\x02\x02\x01\x09\x02\x01\x08'))
Beispiel #31
0
				INTEGER modulus
				INTEGER exponent
'''

print sys.argv[1]
print sys.argv[2]

modulus = int(sys.argv[1])
exponent = int(sys.argv[2])

# Codificacion HEX-DER del SEQUENCE(OID, NULL)
oid_seq = '300d06092a864886f70d0101010500'

# Codificacion DER del SEQUENCE(INTEGER, INTEGER)
int_seq = DerSequence()
int_seq.append(modulus)
int_seq.append(exponent)
int_seq = int_seq.encode()

# Codificacion DER del BIT STRING(...)
bs_der = DerBitString(int_seq)
bs_der = bs_der.encode()

# Codificacion DER del SEQUENCE(SEQUENCE, BIT STRING)
rsa_seq = DerSequence()
rsa_seq.append(unhexlify(oid_seq))
rsa_seq.append(bs_der)
rsa_seq = rsa_seq.encode()

# Exportar la clave publica formateada en hexadecimal a un fichero
f = open(sys.argv[3] + "/pub_key.txt", "w+")
Beispiel #32
0
	def testEncode5(self):
		# One single-byte integer (looks negative)
		der = DerSequence()
		der.append(0xFFL)
		self.assertEquals(der.encode(), '0\x04\x02\x02\x00\xff')
Beispiel #33
0
	def testEncode3(self):
		# One multi-byte integer (non-zero)
		der = DerSequence()
		der.append(0x180L)
		self.assertEquals(der.encode(), '0\x04\x02\x02\x01\x80')
Beispiel #34
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 = [ 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)
Beispiel #35
0
 def testEncode5(self):
     # One single-byte integer (looks negative)
     der = DerSequence()
     der.append(0xFF)
     self.assertEqual(der.encode(), b('0\x04\x02\x02\x00\xff'))
 def testEncode3(self):
     # One multi-byte integer (non-zero)
     der = DerSequence()
     der.append(0x180)
     self.assertEquals(der.encode(), b('0\x04\x02\x02\x01\x80'))
Beispiel #37
0
def _EMSA_PKCS1_V1_5_ENCODE(msg_hash, emLen, with_hash_parameters=True):
    """
    Implement the ``EMSA-PKCS1-V1_5-ENCODE`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.2).

    ``_EMSA-PKCS1-V1_5-ENCODE`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
     msg_hash : hash object
            The hash object that holds the digest of the message being signed.
     emLen : int
            The length the final encoding must have, in bytes.
     with_hash_parameters : bool
            If True (default), include NULL parameters for the hash
            algorithm in the ``digestAlgorithm`` SEQUENCE.

    :attention: the early standard (RFC2313) stated that ``DigestInfo``
        had to be BER-encoded. This means that old signatures
        might have length tags in indefinite form, which
        is not supported in DER. Such encoding cannot be
        reproduced by this function.

    :Return: An ``emLen`` byte long string that encodes the hash.
    """

    # First, build the ASN.1 DER object DigestInfo:
    #
    #   DigestInfo ::= SEQUENCE {
    #       digestAlgorithm AlgorithmIdentifier,
    #       digest OCTET STRING
    #   }
    #
    # where digestAlgorithm identifies the hash function and shall be an
    # algorithm ID with an OID in the set PKCS1-v1-5DigestAlgorithms.
    #
    #   PKCS1-v1-5DigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
    #       { OID id-md2 PARAMETERS NULL    }|
    #       { OID id-md5 PARAMETERS NULL    }|
    #       { OID id-sha1 PARAMETERS NULL   }|
    #       { OID id-sha256 PARAMETERS NULL }|
    #       { OID id-sha384 PARAMETERS NULL }|
    #       { OID id-sha512 PARAMETERS NULL }
    #   }
    #
    # Appendix B.1 also says that for SHA-1/-2 algorithms, the parameters
    # should be omitted. They may be present, but when they are, they shall
    # have NULL value.

    digestAlgo = DerSequence([ DerObjectId(msg_hash.oid).encode() ])

    if with_hash_parameters:
        digestAlgo.append(DerNull().encode())

    digest      = DerOctetString(msg_hash.digest())
    digestInfo  = DerSequence([
                    digestAlgo.encode(),
                    digest.encode()
                    ]).encode()

    # We need at least 11 bytes for the remaining data: 3 fixed bytes and
    # at least 8 bytes of padding).
    if emLen<len(digestInfo)+11:
        raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest))
    PS = b'\xFF' * (emLen - len(digestInfo) - 3)
    return b'\x00\x01' + PS + b'\x00' + digestInfo