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'))
 def testDecode8(self):
     # Only 2 other types
     der = DerSequence()
     der.decode(b('0\x06\x24\x02\xb6\x63\x12\x00'))
     self.assertEqual(len(der), 2)
     self.assertEqual(der[0], b('\x24\x02\xb6\x63'))
     self.assertEqual(der[1], b('\x12\x00'))
     self.assertEqual(der.hasInts(), 0)
     self.assertEqual(der.hasInts(False), 0)
     self.assertFalse(der.hasOnlyInts())
     self.assertFalse(der.hasOnlyInts(False))
 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.assertEqual(der.hasInts(), 1)
     self.assertEqual(der.hasInts(False), 1)
     self.assertTrue(der.hasOnlyInts())
     self.assertTrue(der.hasOnlyInts(False))
     # Invariant
     self.assertEqual(der.encode(), b('0\x03\x02\x01\x00'))
 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())
 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())
Example #6
0
    def verify(self, msg_hash, signature):
        """Check if a certain (EC)DSA signature is authentic.

        :parameter msg_hash:
            The hash that was carried out over the message.
            This is an object belonging to the :mod:`crypto.Hash` module.

            Under mode *'fips-186-3'*, the hash must be a FIPS
            approved secure hash (SHA-1 or a member of the SHA-2 family),
            of cryptographic strength appropriate for the DSA key.
            For instance, a 3072/256 DSA key can only be used in
            combination with SHA-512.
        :type msg_hash: hash object

        :parameter signature:
            The signature that needs to be validated
        :type signature: byte string

        :raise ValueError: if the signature is not authentic
        """

        if not self._valid_hash(msg_hash):
            raise ValueError("Hash is not sufficiently strong")

        if self._encoding == 'binary':
            if len(signature) != (2 * self._order_bytes):
                raise ValueError("The signature is not authentic (length)")
            r_prime, s_prime = [
                Integer.from_bytes(x) for x in (signature[:self._order_bytes],
                                                signature[self._order_bytes:])
            ]
        else:
            try:
                der_seq = DerSequence().decode(signature, strict=True)
            except (ValueError, IndexError):
                raise ValueError("The signature is not authentic (DER)")
            if len(der_seq) != 2 or not der_seq.hasOnlyInts():
                raise ValueError(
                    "The signature is not authentic (DER content)")
            r_prime, s_prime = Integer(der_seq[0]), Integer(der_seq[1])

        if not (0 < r_prime < self._order) or not (0 < s_prime < self._order):
            raise ValueError("The signature is not authentic (d)")

        z = Integer.from_bytes(msg_hash.digest()[:self._order_bytes])
        result = self._key._verify(z, (r_prime, s_prime))
        if not result:
            raise ValueError("The signature is not authentic")
        # Make PyCrypto code to fail
        return False