Example #1
0
    def generate(self, status):
        """Create a CertificateVerify message"""
        if self.msg_version is None:
            self.msg_version = status.version
        if self.sig_version is None:
            self.sig_version = self.msg_version
        if self.msg_alg is None and self.msg_version >= (3, 3):
            cert_req = next((msg for msg in status.handshake_messages[::-1]
                             if isinstance(msg, CertificateRequest)), None)
            if cert_req is not None:
                self.msg_alg = next(
                    (sig for sig in cert_req.supported_signature_algs
                     if sig[1] == SignatureAlgorithm.rsa), None)
            if self.msg_alg is None:
                self.msg_alg = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
        if self.sig_alg is None:
            self.sig_alg = self.msg_alg
        # TODO: generate a random key if none provided
        if self.private_key is None:
            raise ValueError("Can't create a signature without private key!")

        verify_bytes = KeyExchange.calcVerifyBytes(self.sig_version,
                                                   status.handshake_hashes,
                                                   self.sig_alg,
                                                   status.premaster_secret,
                                                   status.client_random,
                                                   status.server_random)
        signature = self.private_key.sign(verify_bytes)

        cert_verify = CertificateVerify(self.msg_version)
        cert_verify.create(signature, self.msg_alg)

        self.msg = cert_verify
        return cert_verify
Example #2
0
    def generate(self, status):
        """Create a CertificateVerify message"""
        if self.version is None:
            self.version = status.version
        if self.sig_type is None and self.version >= (3, 3):
            cert_req = next((msg for msg in status.handshake_messages[::-1]
                             if isinstance(msg, CertificateRequest)), None)
            if cert_req is not None:
                self.sig_type = next((sig for sig in
                                      cert_req.supported_signature_algs
                                      if sig[1] == SignatureAlgorithm.rsa),
                                     None)
            if self.sig_type is None:
                self.sig_type = (HashAlgorithm.sha1,
                                 SignatureAlgorithm.rsa)
        # TODO: generate a random key if none provided
        if self.private_key is None:
            raise ValueError("Can't create a signature without private key!")

        verify_bytes = KeyExchange.calcVerifyBytes(status.version,
                                                   status.handshake_hashes,
                                                   self.sig_type,
                                                   status.premaster_secret,
                                                   status.client_random,
                                                   status.server_random)
        signature = self.private_key.sign(verify_bytes)

        cert_verify = CertificateVerify(status.version)
        cert_verify.create(signature, self.sig_type)

        self.msg = cert_verify
        return cert_verify
    def test_with_TLS1_1(self):
        vrfy = KeyExchange.calcVerifyBytes((3, 2),
                                           self.handshake_hashes,
                                           None, None, None, None)

        self.assertEqual(vrfy, bytearray(
            # MD5 hash
            b'\xe9\x9f\xb4\xd24\xe9\xf41S\xe6?\xa5\xfe\xad\x16\x14'
            # SHA1 hash
            b'L3\x81\xad\x1b\xc2\x14\xc0\x8e\xba\xe4\xb8\xa2\x9d(6V1\xfb\xb0'
            ))
    def test_with_TLS1_1(self):
        vrfy = KeyExchange.calcVerifyBytes((3, 2),
                                           self.handshake_hashes,
                                           None, None, None, None)

        self.assertEqual(vrfy, bytearray(
            # MD5 hash
            b'\xe9\x9f\xb4\xd24\xe9\xf41S\xe6?\xa5\xfe\xad\x16\x14'
            # SHA1 hash
            b'L3\x81\xad\x1b\xc2\x14\xc0\x8e\xba\xe4\xb8\xa2\x9d(6V1\xfb\xb0'
            ))
    def test_with_SSL3(self):
        vrfy = KeyExchange.calcVerifyBytes((3, 0),
                                           self.handshake_hashes,
                                           None,
                                           bytearray(b'\x04'*48),
                                           bytearray(b'\xaa'*32),
                                           bytearray(b'\xbb'*32))

        self.assertEqual(vrfy, bytearray(
            b'r_\x06\xd2(\\}v\x87\xfc\xf5\xa2h\xd6S\xd8'
            b'\xed=\x9b\xe3\xd9_%qe\xa3k\xf5\x85\x0e?\x9fr\xfaML'
            ))
    def test_with_SSL3(self):
        vrfy = KeyExchange.calcVerifyBytes((3, 0),
                                           self.handshake_hashes,
                                           None,
                                           bytearray(b'\x04'*48),
                                           bytearray(b'\xaa'*32),
                                           bytearray(b'\xbb'*32))

        self.assertEqual(vrfy, bytearray(
            b'r_\x06\xd2(\\}v\x87\xfc\xf5\xa2h\xd6S\xd8'
            b'\xed=\x9b\xe3\xd9_%qe\xa3k\xf5\x85\x0e?\x9fr\xfaML'
            ))
 def test_with_TLS1_2(self):
     vrfy = KeyExchange.calcVerifyBytes((3, 3),
                                        self.handshake_hashes,
                                        (HashAlgorithm.sha1,
                                         SignatureAlgorithm.rsa),
                                        None,
                                        None,
                                        None)
     self.assertEqual(vrfy, bytearray(
         # PKCS#1 prefix
         b'0!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14'
         # SHA1 hash
         b'L3\x81\xad\x1b\xc2\x14\xc0\x8e\xba\xe4\xb8\xa2\x9d(6V1\xfb\xb0'))
 def test_with_TLS1_2(self):
     vrfy = KeyExchange.calcVerifyBytes((3, 3),
                                        self.handshake_hashes,
                                        (HashAlgorithm.sha1,
                                         SignatureAlgorithm.rsa),
                                        None,
                                        None,
                                        None)
     self.assertEqual(vrfy, bytearray(
         # PKCS#1 prefix
         b'0!0\t\x06\x05+\x0e\x03\x02\x1a\x05\x00\x04\x14'
         # SHA1 hash
         b'L3\x81\xad\x1b\xc2\x14\xc0\x8e\xba\xe4\xb8\xa2\x9d(6V1\xfb\xb0'))
Example #9
0
    def generate(self, status):
        """Create a CertificateVerify message."""
        if self.msg_version is None:
            self.msg_version = status.version
        if self.sig_version is None:
            self.sig_version = self.msg_version
        if self.msg_alg is None and self.msg_version >= (3, 3):
            cert_req = next((msg for msg in status.handshake_messages[::-1]
                             if isinstance(msg, CertificateRequest)), None)
            if cert_req is not None:
                self.msg_alg = next((sig for sig in
                                     cert_req.supported_signature_algs
                                     if sig[1] == SignatureAlgorithm.rsa or
                                     sig[0] == 8 and sig[1] in (4, 5, 6)),
                                    None)
            if self.msg_alg is None:
                self.msg_alg = (HashAlgorithm.sha1,
                                SignatureAlgorithm.rsa)
        if self.sig_alg is None:
            self.sig_alg = self.msg_alg

        # TODO: generate a random key if none provided
        if self.signature is not None:
            signature = self.signature
        else:
            if self.private_key is None:
                raise ValueError("Can't create a signature without "
                                 "private key!")

            verify_bytes = KeyExchange.calcVerifyBytes(self.sig_version,
                                                       status.handshake_hashes,
                                                       self.sig_alg,
                                                       status.premaster_secret,
                                                       status.client_random,
                                                       status.server_random)

            # we don't have to handle non pkcs1 padding because the
            # calcVerifyBytes does everything
            scheme = SignatureScheme.toRepr(self.sig_alg)
            hashName = None
            saltLen = 0
            if scheme is None:
                padding = "pkcs1"
            else:
                padding = SignatureScheme.getPadding(scheme)
                if padding == 'pss':
                    hashName = SignatureScheme.getHash(scheme)
                    if self.rsa_pss_salt_len is None:
                        self.rsa_pss_salt_len = \
                                getattr(hashlib, hashName)().digest_size

            def _newRawPrivateKeyOp(self, m, original_rawPrivateKeyOp,
                                    subs=None, xors=None):
                signBytes = numberToByteArray(m, numBytes(self.n))
                signBytes = substitute_and_xor(signBytes, subs, xors)
                m = bytesToNumber(signBytes)
                # RSA operations are defined only on numbers that are smaller
                # than the modulus, so ensure the XORing or substitutions
                # didn't break it (especially necessary for pycrypto as
                # it raises exception in such case)
                if m > self.n:
                    m %= self.n
                return original_rawPrivateKeyOp(m)

            oldPrivateKeyOp = self.private_key._rawPrivateKeyOp
            self.private_key._rawPrivateKeyOp = \
                partial(_newRawPrivateKeyOp,
                        self.private_key,
                        original_rawPrivateKeyOp=oldPrivateKeyOp,
                        subs=self.padding_subs,
                        xors=self.padding_xors)
            try:
                signature = self.private_key.sign(verify_bytes,
                                                  padding,
                                                  hashName,
                                                  self.rsa_pss_salt_len)
            finally:
                # make sure the changes are undone even if the signing fails
                self.private_key._rawPrivateKeyOp = oldPrivateKeyOp

        cert_verify = CertificateVerify(self.msg_version)
        cert_verify.create(signature, self.msg_alg)

        self.msg = cert_verify
        return cert_verify
Example #10
0
    def generate(self, status):
        """Create a CertificateVerify message."""
        if self.msg_version is None:
            self.msg_version = status.version
        if self.sig_version is None:
            self.sig_version = self.msg_version
        if self.msg_alg is None and self.msg_version >= (3, 3):
            cert_req = next((msg for msg in status.handshake_messages[::-1]
                             if isinstance(msg, CertificateRequest)), None)
            if cert_req is not None:
                self.msg_alg = next(
                    (sig for sig in cert_req.supported_signature_algs
                     if sig[1] == SignatureAlgorithm.rsa
                     or sig[0] == 8 and sig[1] in (4, 5, 6)), None)
            if self.msg_alg is None:
                self.msg_alg = (HashAlgorithm.sha1, SignatureAlgorithm.rsa)
        if self.sig_alg is None:
            self.sig_alg = self.msg_alg

        # we need a copy of the handshake hashes for use in Extended Master
        # Secret calculation
        status.certificate_verify_handshake_hashes = \
            status.handshake_hashes.copy()
        # TODO: generate a random key if none provided
        if self.signature is not None:
            signature = self.signature
        else:
            if self.private_key is None:
                raise ValueError("Can't create a signature without "
                                 "private key!")

            verify_bytes = KeyExchange.calcVerifyBytes(self.sig_version,
                                                       status.handshake_hashes,
                                                       self.sig_alg,
                                                       status.premaster_secret,
                                                       status.client_random,
                                                       status.server_random)

            # we don't have to handle non pkcs1 padding because the
            # calcVerifyBytes does everything
            scheme = SignatureScheme.toRepr(self.sig_alg)
            hashName = None
            saltLen = 0
            if scheme is None:
                padding = "pkcs1"
            else:
                padding = SignatureScheme.getPadding(scheme)
                if padding == 'pss':
                    hashName = SignatureScheme.getHash(scheme)
                    if self.rsa_pss_salt_len is None:
                        self.rsa_pss_salt_len = \
                                getattr(hashlib, hashName)().digest_size

            def _newRawPrivateKeyOp(self,
                                    m,
                                    original_rawPrivateKeyOp,
                                    subs=None,
                                    xors=None):
                signBytes = numberToByteArray(m, numBytes(self.n))
                signBytes = substitute_and_xor(signBytes, subs, xors)
                m = bytesToNumber(signBytes)
                return original_rawPrivateKeyOp(m)

            oldPrivateKeyOp = self.private_key._rawPrivateKeyOp
            self.private_key._rawPrivateKeyOp = \
                partial(_newRawPrivateKeyOp,
                        self.private_key,
                        original_rawPrivateKeyOp=oldPrivateKeyOp,
                        subs=self.padding_subs,
                        xors=self.padding_xors)
            signature = self.private_key.sign(verify_bytes, padding, hashName,
                                              self.rsa_pss_salt_len)
            self.private_key._rawPrivateKeyOp = oldPrivateKeyOp

        cert_verify = CertificateVerify(self.msg_version)
        cert_verify.create(signature, self.msg_alg)

        self.msg = cert_verify
        return cert_verify