示例#1
0
 def test_HMAC_expand_2(self):
     # RFC 5869 Appendix A.2 Test Vector 2
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int(
                     '0x06a6b88c5853361a06104c9ceb35b45cef7600149'
                     '04671014a193f40c15fc244', 16), 32),
             numberToByteArray(
                 int(
                     '0xb0b1b2b3b4b5b6b7'
                     'b8b9babbbcbdbebfc0'
                     'c1c2c3c4c5c6c7c8c9'
                     'cacbcccdcecfd0d1d2'
                     'd3d4d5d6d7d8d9dadb'
                     'dcdddedfe0e1e2e3e4'
                     'e5e6e7e8e9eaebeced'
                     'eeeff0f1f2f3f4f5f6'
                     'f7f8f9fafbfcfdf'
                     'eff', 16), 80), 82, 'sha256'),
         numberToByteArray(
             int(
                 '0xb11e398dc80327a1c8e7f78c596a'
                 '49344f012eda2d4efad8a050cc4c19'
                 'afa97c59045a99cac7827271cb41c6'
                 '5e590e09da3275600c2f09b8367793'
                 'a9aca3db71cc30c58179ec3e87c14c'
                 '01d5c1f3434f1d87', 16), 82))
示例#2
0
 def test_HMAC_expand_5(self):
     # RFC 5869 Appendix A.5 Test Vector 5
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int('0x8adae09a2a307059'
                     '478d309b26c4115a22'
                     '4cfaf6', 16), 20),
             numberToByteArray(
                 int(
                     '0xb0b1b2b3b4b5b6b7'
                     'b8b9babbbcbdbebfc0'
                     'c1c2c3c4c5c6c7c8c9'
                     'cacbcccdcecfd0d1d2'
                     'd3d4d5d6d7d8d9dadb'
                     'dcdddedfe0e1e2e3e4'
                     'e5e6e7e8e9eaebeced'
                     'eeeff0f1f2f3f4f5f6'
                     'f7f8f9fafbfcfdfe'
                     'ff', 16), 80), 82, 'sha1'),
         numberToByteArray(
             int(
                 '0x0bd770a74d1160f7c9f12cd5912a'
                 '06ebff6adcae899d92191fe4305673'
                 'ba2ffe8fa3f1a4e5ad79f3f334b3b2'
                 '02b2173c486ea37ce3d397ed034c7f'
                 '9dfeb15c5e927336d0441f4c4300e2'
                 'cff0d0900b52d3b4', 16), 82))
 def test_HMAC_expand_6(self):
     # RFC 5869 Appendix A.6 Test Vector 6
     self.assertEqual(HKDF_expand(numberToByteArray(int('0xda8c8a73c7fa7728'
                                                        '8ec6f5e7c297786aa0'
                                                        'd32d01', 16), 20),
                                  bytearray(), 42, 'sha1'),
                      numberToByteArray(int('0x0ac1af7002b3d761d1e55298da9d'
                                            '0506b9ae52057220a306e07b6b87e8'
                                            'df21d0ea00033de03984d34918',
                                            16), 42))
 def test_HMAC_expand_7(self):
     # RFC 5869 Appendix A.7 Test Vector 7
     self.assertEqual(HKDF_expand(numberToByteArray(int('0x2adccada18779e7c'
                                                        '2077ad2eb19d3f3e73'
                                                        '1385dd', 16), 20),
                                  bytearray(), 42, 'sha1'),
                      numberToByteArray(int('0x2c91117204d745f3500d636a62f6'
                                            '4f0ab3bae548aa53d423b0d1f27ebb'
                                            'a6f5e5673a081d70cce7acfc48',
                                            16), 42))
 def test_HMAC_expand_4(self):
     # RFC 5869 Appendix A.4 Test Vector 4
     self.assertEqual(HKDF_expand(numberToByteArray(int('0x9b6c18c432a7bf8f'
                                                        '0e71c8eb88f4b30baa'
                                                        '2ba243', 16), 20),
                                  numberToByteArray(int('0xf0f1f2f3f4f5f6f7'
                                                        'f8f9', 16),
                                                    10), 42, 'sha1'),
                      numberToByteArray(int('0x085a01ea1b10f36933068b56efa5'
                                            'ad81a4f14b822f5b091568a9cdd4f1'
                                            '55fda2c22e422478d305f3f896',
                                            16), 42))
 def test_HMAC_expand_3(self):
     # RFC 5869 Appendix A.3 Test Vector 3
     self.assertEqual(HKDF_expand(numberToByteArray(int('0x19ef24a32c717b16'
                                                        '7f33a91d6f648bdf96'
                                                        '596776afdb6377ac43'
                                                        '4c1c293ccb04', 16),
                                                    32), bytearray(),
                                  42, 'sha256'),
                      numberToByteArray(int('0x8da4e775a563c18f715f802a063c'
                                            '5a31b8a11f5c5ee1879ec3454e5f3c'
                                            '738d2d9d201395faa4b61a96c8',
                                            16), 42))
 def test_HMAC_expand_1(self):
     # RFC 5869 Appendix A.1 Test Vector 1
     self.assertEqual(HKDF_expand(numberToByteArray(int('0x077709362c2e32df'
                                                        '0ddc3f0dc47bba6390'
                                                        'b6c73bb50f9c3122ec'
                                                        '844ad7c2b3e5',
                                                        16), 32),
                                  numberToByteArray(0xf0f1f2f3f4f5f6f7f8f9,
                                                    10), 42, 'sha256'),
                      numberToByteArray(int('0x3cb25f25faacd57a90434f64d036'
                                            '2f2a2d2d0a90cf1a5a4c5db02d56ec'
                                            'c4c5bf34007208d5b887185865',
                                            16), 42))
示例#8
0
 def test_HMAC_expand_6(self):
     # RFC 5869 Appendix A.6 Test Vector 6
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int('0xda8c8a73c7fa7728'
                     '8ec6f5e7c297786aa0'
                     'd32d01', 16), 20), bytearray(), 42, 'sha1'),
         numberToByteArray(
             int(
                 '0x0ac1af7002b3d761d1e55298da9d'
                 '0506b9ae52057220a306e07b6b87e8'
                 'df21d0ea00033de03984d34918', 16), 42))
示例#9
0
 def test_HMAC_expand_7(self):
     # RFC 5869 Appendix A.7 Test Vector 7
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int('0x2adccada18779e7c'
                     '2077ad2eb19d3f3e73'
                     '1385dd', 16), 20), bytearray(), 42, 'sha1'),
         numberToByteArray(
             int(
                 '0x2c91117204d745f3500d636a62f6'
                 '4f0ab3bae548aa53d423b0d1f27ebb'
                 'a6f5e5673a081d70cce7acfc48', 16), 42))
示例#10
0
    def _cbcmac_calc(self, nonce, aad, msg):
        L = 15 - len(nonce)
        mac_data = bytearray()

        # Flags constructed as in section 2.2 in the rfc
        flags = 64 * (len(aad) > 0)
        flags += 8 * ((self.tagLength - 2) // 2)
        flags += 1 * (L - 1)

        # Construct B_0
        b_0 = bytearray([flags]) + nonce + numberToByteArray(len(msg), L)

        aad_len_encoded = bytearray()
        if len(aad) > 0:
            if len(aad) < (2**16 - 2**8):
                oct_size = 2
            elif len(aad) < (2**32):
                oct_size = 4
                aad_len_encoded = b'\xFF\xFE'
            else:
                oct_size = 8
                aad_len_encoded = b'\xFF\xFF'

            aad_len_encoded += numberToByteArray(len(aad), oct_size)

        # Construct the bytearray that goes into the MAC
        mac_data += b_0
        mac_data += aad_len_encoded
        mac_data += aad

        # We need to pad with zeroes before and after msg blocks are added
        self._pad_with_zeroes(mac_data, 16)
        if msg != b'':
            mac_data += msg
            self._pad_with_zeroes(mac_data, 16)

        # The mac data is now constructed and
        # we need to run in through AES-CBC with 0 IV

        self._cbc.IV = bytearray(b'\x00' * 16)
        cbcmac = self._cbc.encrypt(mac_data)

        # If the tagLength has default value 16, we return
        # the whole last block. Otherwise we return only
        # the first tagLength bytes from the last block
        if self.tagLength == 16:
            t = cbcmac[-16:]
        else:
            t = cbcmac[-16:-(16 - self.tagLength)]
        return t
示例#11
0
 def test_HMAC_expand_4(self):
     # RFC 5869 Appendix A.4 Test Vector 4
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int('0x9b6c18c432a7bf8f'
                     '0e71c8eb88f4b30baa'
                     '2ba243', 16), 20),
             numberToByteArray(int('0xf0f1f2f3f4f5f6f7'
                                   'f8f9', 16), 10), 42, 'sha1'),
         numberToByteArray(
             int(
                 '0x085a01ea1b10f36933068b56efa5'
                 'ad81a4f14b822f5b091568a9cdd4f1'
                 '55fda2c22e422478d305f3f896', 16), 42))
示例#12
0
 def test_HMAC_expand_3(self):
     # RFC 5869 Appendix A.3 Test Vector 3
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int(
                     '0x19ef24a32c717b16'
                     '7f33a91d6f648bdf96'
                     '596776afdb6377ac43'
                     '4c1c293ccb04', 16), 32), bytearray(), 42, 'sha256'),
         numberToByteArray(
             int(
                 '0x8da4e775a563c18f715f802a063c'
                 '5a31b8a11f5c5ee1879ec3454e5f3c'
                 '738d2d9d201395faa4b61a96c8', 16), 42))
示例#13
0
    def test_ECDHE_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha1,
                                              SignatureAlgorithm.rsa)])

        curveName = GroupName.toStr(srv_key_ex.named_curve)
        curve = getCurveByName(curveName)
        generator = curve.generator
        cln_Xc = ecdsa.util.randrange(generator.order())
        cln_Ys = decodeX962Point(srv_key_ex.ecdh_Ys, curve)
        cln_Yc = encodeX962Point(generator * cln_Xc)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createECDH(cln_Yc)

        cln_S = cln_Ys * cln_Xc
        cln_premaster = numberToByteArray(cln_S.x(),
                                          getPointByteSize(cln_S))

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
示例#14
0
    def seal(self, nonce, msg, aad):

        if len(nonce) != 12:
            raise ValueError("Bad nonce length")

        L = 15 - len(nonce)

        # We construct the key stream blocks.
        # S_0 is not used for encrypting the message, it is only used
        # to compute the authentication value.
        # S_1..S_n are used to encrypt the message.

        flags = L - 1
        s_0 = bytearray([flags]) + nonce + numberToByteArray(0, L)

        mac = self._cbcmac_calc(nonce, aad, msg)
        self._ctr.counter = s_0
        if self.tagLength == 16:
            auth_value = self._ctr.encrypt(mac)
        else:
            assert self.tagLength == 8
            self._pad_with_zeroes(mac, 16)
            auth_value = self._ctr.encrypt(mac)[:8]
        enc_msg = self._ctr.encrypt(msg)

        ciphertext = enc_msg + auth_value
        return ciphertext
示例#15
0
    def open(self, nonce, ciphertext, aad):

        if len(nonce) != 12:
            raise ValueError("Bad nonce length")
        if self.tagLength == 16 and len(ciphertext) < 16:
            return None
        if self.tagLength == 8 and len(ciphertext) < 8:
            return None

        L = 15 - len(nonce)
        flags = L - 1

        # Same construction as in seal function

        s_0 = bytearray([flags]) + nonce + numberToByteArray(0, L)

        auth_value = ciphertext[-self.tagLength:]

        # We decrypt the auth value
        self._ctr.counter = s_0
        received_mac = self._ctr.decrypt(auth_value)
        msg = self._ctr.decrypt(ciphertext)
        msg = msg[:-self.tagLength]
        computed_mac = self._cbcmac_calc(nonce, aad, msg)

        # Compare the mac vlaue is the same as the one we computed
        if received_mac != computed_mac:
            return None
        return msg
示例#16
0
    def test_SRP_key_exchange_without_signature(self):
        self.cipher_suite = CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA
        self.keyExchange.cipherSuite = self.cipher_suite
        self.server_hello.cipher_suite = self.cipher_suite

        srv_key_ex = self.keyExchange.makeServerKeyExchange()

        a = bytesToNumber(getRandomBytes(32))
        A = powMod(srv_key_ex.srp_g,
                   a,
                   srv_key_ex.srp_N)
        x = makeX(srv_key_ex.srp_s, bytearray(b'user'), bytearray(b'password'))
        v = powMod(srv_key_ex.srp_g,
                   x,
                   srv_key_ex.srp_N)
        u = makeU(srv_key_ex.srp_N,
                  A,
                  srv_key_ex.srp_B)

        k = makeK(srv_key_ex.srp_N,
                  srv_key_ex.srp_g)
        S = powMod((srv_key_ex.srp_B - (k*v)) % srv_key_ex.srp_N,
                   a+(u*x),
                   srv_key_ex.srp_N)

        cln_premaster = numberToByteArray(S)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
示例#17
0
    def test_SRP_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha256')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha256,
                                              SignatureAlgorithm.rsa)])

        a = bytesToNumber(getRandomBytes(32))
        A = powMod(srv_key_ex.srp_g,
                   a,
                   srv_key_ex.srp_N)
        x = makeX(srv_key_ex.srp_s, bytearray(b'user'), bytearray(b'password'))
        v = powMod(srv_key_ex.srp_g,
                   x,
                   srv_key_ex.srp_N)
        u = makeU(srv_key_ex.srp_N,
                  A,
                  srv_key_ex.srp_B)

        k = makeK(srv_key_ex.srp_N,
                  srv_key_ex.srp_g)
        S = powMod((srv_key_ex.srp_B - (k*v)) % srv_key_ex.srp_N,
                   a+(u*x),
                   srv_key_ex.srp_N)

        cln_premaster = numberToByteArray(S)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
示例#18
0
    def __call__(self, hostname):
        """Generate a client hello object, use hostname in SNI extension."""
        # SNI is special in that we don't want to send it if it is empty
        if self.extensions:
            sni = next((x for x in self.extensions
                        if isinstance(x, SNIExtension)),
                       None)
            if sni:
                if hostname is not None:
                    if sni.serverNames is None:
                        sni.serverNames = []
                    sni.hostNames = [hostname]
                else:
                    # but if we were not provided with a host name, we want
                    # to remove empty extension
                    if sni.serverNames is None:
                        self.extensions = [x for x in self.extensions
                                           if not isinstance(x, SNIExtension)]

        if self.random:
            rand = self.random
        else:
            # we're not doing any crypto with it, just need "something"
            # TODO: place unix time at the beginning
            rand = numberToByteArray(random.getrandbits(256), 32)

        ch = ClientHello(self.ssl2).create(self.version, rand, self.session_id,
                                           self.ciphers,
                                           extensions=self.extensions)
        ch.compression_methods = self.compression_methods
        for cb in self.callbacks:
            ch = cb(ch)
        return ch
    def test_SRP_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha256')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha256,
                                              SignatureAlgorithm.rsa)])

        a = bytesToNumber(getRandomBytes(32))
        A = powMod(srv_key_ex.srp_g,
                   a,
                   srv_key_ex.srp_N)
        x = makeX(srv_key_ex.srp_s, bytearray(b'user'), bytearray(b'password'))
        v = powMod(srv_key_ex.srp_g,
                   x,
                   srv_key_ex.srp_N)
        u = makeU(srv_key_ex.srp_N,
                  A,
                  srv_key_ex.srp_B)

        k = makeK(srv_key_ex.srp_N,
                  srv_key_ex.srp_g)
        S = powMod((srv_key_ex.srp_B - (k*v)) % srv_key_ex.srp_N,
                   a+(u*x),
                   srv_key_ex.srp_N)

        cln_premaster = numberToByteArray(S)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
    def test_SRP_key_exchange_without_signature(self):
        self.cipher_suite = CipherSuite.TLS_SRP_SHA_WITH_AES_128_CBC_SHA
        self.keyExchange.cipherSuite = self.cipher_suite
        self.server_hello.cipher_suite = self.cipher_suite

        srv_key_ex = self.keyExchange.makeServerKeyExchange()

        a = bytesToNumber(getRandomBytes(32))
        A = powMod(srv_key_ex.srp_g,
                   a,
                   srv_key_ex.srp_N)
        x = makeX(srv_key_ex.srp_s, bytearray(b'user'), bytearray(b'password'))
        v = powMod(srv_key_ex.srp_g,
                   x,
                   srv_key_ex.srp_N)
        u = makeU(srv_key_ex.srp_N,
                  A,
                  srv_key_ex.srp_B)

        k = makeK(srv_key_ex.srp_N,
                  srv_key_ex.srp_g)
        S = powMod((srv_key_ex.srp_B - (k*v)) % srv_key_ex.srp_N,
                   a+(u*x),
                   srv_key_ex.srp_N)

        cln_premaster = numberToByteArray(S)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3)).createSRP(A)

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
    def test_ECDHE_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        KeyExchange.verifyServerKeyExchange(srv_key_ex,
                                            self.srv_pub_key,
                                            self.client_hello.random,
                                            self.server_hello.random,
                                            [(HashAlgorithm.sha1,
                                              SignatureAlgorithm.rsa)])

        curveName = GroupName.toStr(srv_key_ex.named_curve)
        curve = getCurveByName(curveName)
        generator = curve.generator
        cln_Xc = ecdsa.util.randrange(generator.order())
        cln_Ys = decodeX962Point(srv_key_ex.ecdh_Ys, curve)
        cln_Yc = encodeX962Point(generator * cln_Xc)

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createECDH(cln_Yc)

        cln_S = cln_Ys * cln_Xc
        cln_premaster = numberToByteArray(cln_S.x(),
                                          getPointByteSize(cln_S))

        srv_premaster = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_premaster, srv_premaster)
示例#22
0
 def test_HMAC_expand_1(self):
     # RFC 5869 Appendix A.1 Test Vector 1
     self.assertEqual(
         HKDF_expand(
             numberToByteArray(
                 int(
                     '0x077709362c2e32df'
                     '0ddc3f0dc47bba6390'
                     'b6c73bb50f9c3122ec'
                     '844ad7c2b3e5', 16), 32),
             numberToByteArray(0xf0f1f2f3f4f5f6f7f8f9, 10), 42, 'sha256'),
         numberToByteArray(
             int(
                 '0x3cb25f25faacd57a90434f64d036'
                 '2f2a2d2d0a90cf1a5a4c5db02d56ec'
                 'c4c5bf34007208d5b887185865', 16), 42))
示例#23
0
 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)
示例#24
0
    def generate(self, status):
        """Create a Client Key Exchange message."""
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        if self.client_version is None:
            self.client_version = status.client_version

        cke = ClientKeyExchange(self.cipher, self.version)
        if self.cipher in CipherSuite.certSuites:
            if self.modulus_as_encrypted_premaster:
                public_key = status.get_server_public_key()
                self.encrypted_premaster = numberToByteArray(public_key.n)
            if self.encrypted_premaster:
                cke.createRSA(self.encrypted_premaster)
            else:
                assert len(self.premaster_secret) > 1
                self.premaster_secret[0] = self.client_version[0]
                self.premaster_secret[1] = self.client_version[1]

                status.premaster_secret = self.premaster_secret

                public_key = status.get_server_public_key()

                cke.createRSA(self._encrypt_with_fuzzing(public_key))
        elif self.cipher in CipherSuite.dheCertSuites:
            if self.dh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createDH(self.dh_Yc)
            elif self.p_as_share or self.p_1_as_share:
                ske = next((i for i in reversed(status.handshake_messages)
                            if isinstance(i, ServerKeyExchange)), None)
                assert ske, "No server key exchange in messages"
                if self.p_as_share:
                    cke = ClientKeyExchange(self.cipher,
                                            self.version).createDH(ske.dh_p)
                else:
                    cke = ClientKeyExchange(self.cipher,
                                            self.version).createDH(ske.dh_p-1)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        elif self.cipher in CipherSuite.ecdhAllSuites:
            if self.ecdh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createECDH(self.ecdh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        else:
            raise AssertionError("Unknown cipher/key exchange type")

        self.msg = cke

        return cke
示例#25
0
 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)
 def test_HMAC_expand_2(self):
     # RFC 5869 Appendix A.2 Test Vector 2
     self.assertEqual(HKDF_expand(
         numberToByteArray(int('0x06a6b88c5853361a06104c9ceb35b45cef7600149'
                               '04671014a193f40c15fc244', 16), 32),
                                  numberToByteArray(int('0xb0b1b2b3b4b5b6b7'
                                                        'b8b9babbbcbdbebfc0'
                                                        'c1c2c3c4c5c6c7c8c9'
                                                        'cacbcccdcecfd0d1d2'
                                                        'd3d4d5d6d7d8d9dadb'
                                                        'dcdddedfe0e1e2e3e4'
                                                        'e5e6e7e8e9eaebeced'
                                                        'eeeff0f1f2f3f4f5f6'
                                                        'f7f8f9fafbfcfdf'
                                                        'eff', 16),
                                                    80), 82, 'sha256'),
                      numberToByteArray(int('0xb11e398dc80327a1c8e7f78c596a'
                                            '49344f012eda2d4efad8a050cc4c19'
                                            'afa97c59045a99cac7827271cb41c6'
                                            '5e590e09da3275600c2f09b8367793'
                                            'a9aca3db71cc30c58179ec3e87c14c'
                                            '01d5c1f3434f1d87', 16), 82))
 def test_HMAC_expand_5(self):
     # RFC 5869 Appendix A.5 Test Vector 5
     self.assertEqual(HKDF_expand(numberToByteArray(int('0x8adae09a2a307059'
                                                        '478d309b26c4115a22'
                                                        '4cfaf6', 16), 20),
                                  numberToByteArray(int('0xb0b1b2b3b4b5b6b7'
                                                        'b8b9babbbcbdbebfc0'
                                                        'c1c2c3c4c5c6c7c8c9'
                                                        'cacbcccdcecfd0d1d2'
                                                        'd3d4d5d6d7d8d9dadb'
                                                        'dcdddedfe0e1e2e3e4'
                                                        'e5e6e7e8e9eaebeced'
                                                        'eeeff0f1f2f3f4f5f6'
                                                        'f7f8f9fafbfcfdfe'
                                                        'ff', 16), 80),
                                  82, 'sha1'),
                      numberToByteArray(int('0x0bd770a74d1160f7c9f12cd5912a'
                                            '06ebff6adcae899d92191fe4305673'
                                            'ba2ffe8fa3f1a4e5ad79f3f334b3b2'
                                            '02b2173c486ea37ce3d397ed034c7f'
                                            '9dfeb15c5e927336d0441f4c4300e2'
                                            'cff0d0900b52d3b4', 16), 82))
示例#28
0
    def test_DHE_RSA_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        cln_X = bytesToNumber(getRandomBytes(32))
        cln_Yc = powMod(srv_key_ex.dh_g,
                        cln_X,
                        srv_key_ex.dh_p)
        cln_secret = numberToByteArray(powMod(srv_key_ex.dh_Ys,
                                              cln_X,
                                              srv_key_ex.dh_p))

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createDH(cln_Yc)

        srv_secret = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_secret, srv_secret)
    def test_DHE_RSA_key_exchange(self):
        srv_key_ex = self.keyExchange.makeServerKeyExchange('sha1')

        cln_X = bytesToNumber(getRandomBytes(32))
        cln_Yc = powMod(srv_key_ex.dh_g,
                        cln_X,
                        srv_key_ex.dh_p)
        cln_secret = numberToByteArray(powMod(srv_key_ex.dh_Ys,
                                              cln_X,
                                              srv_key_ex.dh_p))

        cln_key_ex = ClientKeyExchange(self.cipher_suite, (3, 3))
        cln_key_ex.createDH(cln_Yc)

        srv_secret = self.keyExchange.processClientKeyExchange(cln_key_ex)

        self.assertEqual(cln_secret, srv_secret)
示例#30
0
    def generate(self, status):
        if self.version is None:
            self.version = status.version

        if self.cipher is None:
            self.cipher = status.cipher

        if self.client_version is None:
            self.client_version = status.client_version

        cke = ClientKeyExchange(self.cipher, self.version)
        if self.cipher in CipherSuite.certSuites:
            if self.modulus_as_encrypted_premaster:
                public_key = status.get_server_public_key()
                self.encrypted_premaster = numberToByteArray(public_key.n)
            if self.encrypted_premaster:
                cke.createRSA(self.encrypted_premaster)
            else:
                assert len(self.premaster_secret) > 1
                self.premaster_secret[0] = self.client_version[0]
                self.premaster_secret[1] = self.client_version[1]

                status.premaster_secret = self.premaster_secret

                public_key = status.get_server_public_key()

                cke.createRSA(self._encrypt_with_fuzzing(public_key))
        elif self.cipher in CipherSuite.dheCertSuites:
            if self.dh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createDH(self.dh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        elif self.cipher in CipherSuite.ecdhAllSuites:
            if self.ecdh_Yc is not None:
                cke = ClientKeyExchange(self.cipher,
                                        self.version).createECDH(self.ecdh_Yc)
            else:
                cke = status.key_exchange.makeClientKeyExchange()
        else:
            raise AssertionError("Unknown cipher/key exchange type")

        self.msg = cke

        return cke
示例#31
0
    def __call__(self, hostname):
        """Generate a client hello object, use hostname in SNI extension."""
        # SNI is special in that we don't want to send it if it is empty
        if self.extensions:
            sni = next(
                (x for x in self.extensions if isinstance(x, SNIExtension)),
                None)
            if sni:
                if hostname is not None:
                    if sni.serverNames is None:
                        sni.serverNames = []
                    sni.hostNames = [hostname]
                else:
                    # but if we were not provided with a host name, we want
                    # to remove empty extension
                    if sni.serverNames is None:
                        self.extensions = [
                            x for x in self.extensions
                            if not isinstance(x, SNIExtension)
                        ]

        if self.random:
            rand = self.random
        else:
            # we're not doing any crypto with it, just need "something"
            # TODO: place unix time at the beginning
            rand = numberToByteArray(random.getrandbits(256), 32)

        ch = ClientHello(self.ssl2).create(self.version,
                                           rand,
                                           self.session_id,
                                           self.ciphers,
                                           extensions=self.extensions)
        ch.compression_methods = self.compression_methods
        for cb in self.callbacks:
            ch = cb(ch)
        return ch
 def test_very_large_number(self):
     self.assertEqual(numberToByteArray((1<<128)-1, endian="little"),
                      bytearray(b'\xff'*16))
示例#33
0
 def test_numberToByteArray_with_not_enough_length(self):
     self.assertEqual(numberToByteArray(0x0a0b0c, 2),
                      bytearray(b'\x0b\x0c'))
 def test_numberToByteArray_with_length(self):
     self.assertEqual(numberToByteArray(0xff, 2),
                      bytearray(b'\x00\xff'))
 def test_numberToByteArray(self):
     self.assertEqual(numberToByteArray(0x00000000000001),
                      bytearray(b'\x01'))
示例#36
0
 def test_small_number(self, number):
     self.assertEqual(numberToByteArray(number, 1),
                      bytearray(struct.pack(">B", number)))
示例#37
0
 def test_with_bad_endian_type(self):
     with self.assertRaises(ValueError):
         numberToByteArray(1, endian="middle")
 def test_big_number(self, number):
     self.assertEqual(numberToByteArray(number, 4),
                      bytearray(struct.pack(">L", number)))
 def test_small_number(self, number):
     self.assertEqual(numberToByteArray(number, 1),
                      bytearray(struct.pack(">B", number)))
 def test_with_bad_endian_type(self):
     with self.assertRaises(ValueError):
         numberToByteArray(1, endian="middle")
 def test_with_large_number_of_bytes_in_little_endian(self):
     self.assertEqual(numberToByteArray(1, 16, endian="little"),
                      bytearray(b'\x01' + b'\x00'*15))
 def test_numberToByteArray_with_not_enough_length_little_endian(self):
     self.assertEqual(numberToByteArray(0x0a0b0c, 2, endian="little"),
                      bytearray(b'\x0c\x0b'))
示例#43
0
 def test_small_number_little_endian(self, number):
     self.assertEqual(numberToByteArray(number, 1, endian="little"),
                      bytearray(struct.pack("<B", number)))
示例#44
0
 def test_with_large_number_of_bytes_in_little_endian(self):
     self.assertEqual(numberToByteArray(1, 16, endian="little"),
                      bytearray(b'\x01' + b'\x00' * 15))
示例#45
0
 def test_big_number(self, number):
     self.assertEqual(numberToByteArray(number, 4),
                      bytearray(struct.pack(">L", number)))
示例#46
0
 def test_numberToByteArray_with_not_enough_length_little_endian(self):
     self.assertEqual(numberToByteArray(0x0a0b0c, 2, endian="little"),
                      bytearray(b'\x0c\x0b'))
def main():
    host = "localhost"
    port = 4433
    num_limit = None
    run_exclude = set()
    expected_failures = {}
    last_exp_tmp = None

    argv = sys.argv[1:]
    opts, args = getopt.getopt(argv, "h:p:e:x:X:n:", ["help"])
    for opt, arg in opts:
        if opt == '-h':
            host = arg
        elif opt == '-p':
            port = int(arg)
        elif opt == '-e':
            run_exclude.add(arg)
        elif opt == '-x':
            expected_failures[arg] = None
            last_exp_tmp = str(arg)
        elif opt == '-X':
            if not last_exp_tmp:
                raise ValueError("-x has to be specified before -X")
            expected_failures[last_exp_tmp] = str(arg)
        elif opt == '-n':
            num_limit = int(arg)
        elif opt == '--help':
            help_msg()
            sys.exit(0)
        else:
            raise ValueError("Unknown option: {0}".format(opt))

    if args:
        run_only = set(args)
    else:
        run_only = None

    conversations = {}

    conversation = Connect(host, port)
    node = conversation
    ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
               CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
    ext = {}
    groups = GroupName.allFF
    ext[ExtensionType.key_share] = key_share_ext_gen(groups)
    ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
        .create([TLS_1_3_DRAFT, (3, 3)])
    ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
        .create(groups)
    sig_algs = [SignatureScheme.rsa_pss_rsae_sha256,
                SignatureScheme.rsa_pss_pss_sha256]
    sig_algs += ECDSA_SIG_TLS1_3_ALL
    ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
        .create(sig_algs)
    ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
        .create(SIG_ALL)
    node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
    node = node.add_child(ExpectServerHello())
    node = node.add_child(ExpectChangeCipherSpec())
    node = node.add_child(ExpectEncryptedExtensions())
    node = node.add_child(ExpectCertificate())
    node = node.add_child(ExpectCertificateVerify())
    node = node.add_child(ExpectFinished())
    node = node.add_child(FinishedGenerator())
    node = node.add_child(ApplicationDataGenerator(
        bytearray(b"GET / HTTP/1.0\r\n\r\n")))

    # This message is optional and may show up 0 to many times
    cycle = ExpectNewSessionTicket()
    node = node.add_child(cycle)
    node.add_child(cycle)

    node.next_sibling = ExpectApplicationData()
    node = node.next_sibling.add_child(AlertGenerator(AlertLevel.warning,
                                       AlertDescription.close_notify))

    node = node.add_child(ExpectAlert())
    node.next_sibling = ExpectClose()
    conversations["sanity"] = conversation

    for group in groups:
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        ext[ExtensionType.key_share] = key_share_ext_gen([group])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectServerHello())
        node = node.add_child(ExpectChangeCipherSpec())
        node = node.add_child(ExpectEncryptedExtensions())
        node = node.add_child(ExpectCertificate())
        node = node.add_child(ExpectCertificateVerify())
        node = node.add_child(ExpectFinished())
        node = node.add_child(FinishedGenerator())
        node = node.add_child(ApplicationDataGenerator(
            bytearray(b"GET / HTTP/1.0\r\n\r\n")))

        # This message is optional and may show up 0 to many times
        cycle = ExpectNewSessionTicket()
        node = node.add_child(cycle)
        node.add_child(cycle)

        node.next_sibling = ExpectApplicationData()
        node = node.next_sibling.add_child(AlertGenerator(AlertLevel.warning,
                                           AlertDescription.close_notify))

        node = node.add_child(ExpectAlert())
        node.next_sibling = ExpectClose()
        conversations["sanity - {0}".format(GroupName.toRepr(group))] = conversation

        # duplicated key share entry
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_shares = []
        key_shares.append(key_share_gen(group))
        key_shares.append(key_share_gen(group))
        ext[ExtensionType.key_share] = ClientKeyShareExtension()\
            .create(key_shares)
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - duplicated key share entry"
                      .format(GroupName.toRepr(group))] = conversation

        # padded representation
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = key_share_gen(group)
        key_share.key_exchange += bytearray(b'\x00')
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - right 0-padded key_share"
                      .format(GroupName.toRepr(group))] = conversation

        # truncated representation (given that all groups use safe primes,
        # any integer between 1 and p-1 is a valid key share, it's just that
        # after truncation we don't know the private key that generates it)
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = key_share_gen(group)
        key_share.key_exchange.pop()
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - right-truncated key_share"
                      .format(GroupName.toRepr(group))] = conversation

        # key share from wrong group
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = key_share_gen(group)
        if group == GroupName.ffdhe2048:
            key_share2 = key_share_gen(GroupName.ffdhe3072)
        else:
            key_share2 = key_share_gen(GroupName.ffdhe2048)
        key_share.key_exchange = key_share2.key_exchange
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - key share from other group"
                      .format(GroupName.toRepr(group))] = conversation

        # just 0
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = KeyShareEntry().create(group, bytearray(b'\x00'))
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - 0 as one byte"
                      .format(GroupName.toRepr(group))] = conversation

        # 0 key share
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = key_share_gen(group)
        key_share.key_exchange = bytearray(len(key_share.key_exchange))
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - 0 as key share"
                      .format(GroupName.toRepr(group))] = conversation

        # 1 key share
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = key_share_gen(group)
        key_share.key_exchange = bytearray(len(key_share.key_exchange))
        key_share.key_exchange[-1] = 0x01
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - 1 as key share"
                      .format(GroupName.toRepr(group))] = conversation

        # all bits set key share
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = key_share_gen(group)
        key_share.key_exchange = bytearray([0xff] * len(key_share.key_exchange))
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - all bits set key share"
                      .format(GroupName.toRepr(group))] = conversation

        if group == GroupName.ffdhe2048:
            params = FFDHE2048
        elif group == GroupName.ffdhe3072:
            params = FFDHE3072
        elif group == GroupName.ffdhe4096:
            params = FFDHE4096
        elif group == GroupName.ffdhe6144:
            params = FFDHE6144
        else:
            assert group == GroupName.ffdhe8192
            params = FFDHE8192

        # p-1 key share
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = KeyShareEntry().create(group,
                                           numberToByteArray(params[1]-1))
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - p-1 as key share"
                      .format(GroupName.toRepr(group))] = conversation

        # p key share
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = KeyShareEntry().create(group,
                                           numberToByteArray(params[1]))
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - p as key share"
                      .format(GroupName.toRepr(group))] = conversation

        # empty key share entry
        conversation = Connect(host, port)
        node = conversation
        ciphers = [CipherSuite.TLS_AES_128_GCM_SHA256,
                   CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        ext = {}
        key_share = KeyShareEntry().create(group,
                                           bytearray())
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create([key_share])
        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create([group])
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(ExpectAlert(AlertLevel.fatal,
                                          AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} - empty key share entry in key_share ext"
                      .format(GroupName.toRepr(group))] = conversation

    # run the conversation
    good = 0
    bad = 0
    xfail = 0
    xpass = 0
    failed = []
    xpassed = []
    if not num_limit:
        num_limit = len(conversations)

    # make sure that sanity test is run first and last
    # to verify that server was running and kept running throughout
    sanity_tests = [('sanity', conversations['sanity'])]
    if run_only:
        if num_limit > len(run_only):
            num_limit = len(run_only)
        regular_tests = [(k, v) for k, v in conversations.items() if
                          k in run_only]
    else:
        regular_tests = [(k, v) for k, v in conversations.items() if
                         (k != 'sanity') and k not in run_exclude]
    sampled_tests = sample(regular_tests, min(num_limit, len(regular_tests)))
    ordered_tests = chain(sanity_tests, sampled_tests, sanity_tests)

    for c_name, c_test in ordered_tests:
        if run_only and c_name not in run_only or c_name in run_exclude:
            continue
        print("{0} ...".format(c_name))

        runner = Runner(c_test)

        res = True
        exception = None
        try:
            runner.run()
        except Exception as exp:
            exception = exp
            print("Error while processing")
            print(traceback.format_exc())
            res = False

        if c_name in expected_failures:
            if res:
                xpass += 1
                xpassed.append(c_name)
                print("XPASS-expected failure but test passed\n")
            else:
                if expected_failures[c_name] is not None and  \
                    expected_failures[c_name] not in str(exception):
                        bad += 1
                        failed.append(c_name)
                        print("Expected error message: {0}\n"
                            .format(expected_failures[c_name]))
                else:
                    xfail += 1
                    print("OK-expected failure\n")
        else:
            if res:
                good += 1
                print("OK\n")
            else:
                bad += 1
                failed.append(c_name)

    print("Basic FFDHE group tests in TLS 1.3")
    print("Check if invalid, malformed and incompatible group key_shares are")
    print("rejected by server")

    print("Test end")
    print(20 * '=')
    print("version: {0}".format(version))
    print(20 * '=')
    print("TOTAL: {0}".format(len(sampled_tests) + 2*len(sanity_tests)))
    print("SKIP: {0}".format(len(run_exclude.intersection(conversations.keys()))))
    print("PASS: {0}".format(good))
    print("XFAIL: {0}".format(xfail))
    print("FAIL: {0}".format(bad))
    print("XPASS: {0}".format(xpass))
    print(20 * '=')
    sort = sorted(xpassed ,key=natural_sort_keys)
    if len(sort):
        print("XPASSED:\n\t{0}".format('\n\t'.join(repr(i) for i in sort)))
    sort = sorted(failed, key=natural_sort_keys)
    if len(sort):
        print("FAILED:\n\t{0}".format('\n\t'.join(repr(i) for i in sort)))

    if bad > 0:
        sys.exit(1)
示例#48
0
 def test_very_large_number(self):
     self.assertEqual(numberToByteArray((1 << 128) - 1, endian="little"),
                      bytearray(b'\xff' * 16))
 def test_numberToByteArray_with_MSB_number(self):
     self.assertEqual(numberToByteArray(0xff),
                      bytearray(b'\xff'))
示例#50
0
 def test_big_number(self, number):
     self.assertEqual(numberToByteArray(number, 4, endian="little"),
                      bytearray(struct.pack("<L", number)))
 def test_numberToByteArray_with_not_enough_length(self):
     self.assertEqual(numberToByteArray(0x0a0b0c, 2),
                      bytearray(b'\x0b\x0c'))
示例#52
0
def main():
    host = "localhost"
    port = 4433
    num_limit = None
    run_exclude = set()
    expected_failures = {}
    last_exp_tmp = None

    argv = sys.argv[1:]
    opts, args = getopt.getopt(argv, "h:p:e:x:X:n:", ["help"])
    for opt, arg in opts:
        if opt == '-h':
            host = arg
        elif opt == '-p':
            port = int(arg)
        elif opt == '-e':
            run_exclude.add(arg)
        elif opt == '-x':
            expected_failures[arg] = None
            last_exp_tmp = str(arg)
        elif opt == '-X':
            if not last_exp_tmp:
                raise ValueError("-x has to be specified before -X")
            expected_failures[last_exp_tmp] = str(arg)
        elif opt == '-n':
            num_limit = int(arg)
        elif opt == '--help':
            help_msg()
            sys.exit(0)
        else:
            raise ValueError("Unknown option: {0}".format(opt))

    if args:
        run_only = set(args)
    else:
        run_only = None

    conversations = {}

    conversation = Connect(host, port)
    node = conversation
    ciphers = [
        CipherSuite.TLS_AES_128_GCM_SHA256,
        CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
    ]
    ext = {}
    groups = [GroupName.secp256r1]
    key_shares = []
    for group in groups:
        key_shares.append(key_share_gen(group))
    ext[ExtensionType.key_share] = ClientKeyShareExtension().create(key_shares)
    ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
        .create([TLS_1_3_DRAFT, (3, 3)])
    ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
        .create(groups)
    sig_algs = [
        SignatureScheme.rsa_pss_rsae_sha256, SignatureScheme.rsa_pss_pss_sha256
    ]
    ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
        .create(sig_algs)
    ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
        .create(RSA_SIG_ALL)
    node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
    node = node.add_child(ExpectServerHello())
    node = node.add_child(ExpectChangeCipherSpec())
    node = node.add_child(ExpectEncryptedExtensions())
    node = node.add_child(ExpectCertificate())
    node = node.add_child(ExpectCertificateVerify())
    node = node.add_child(ExpectFinished())
    node = node.add_child(FinishedGenerator())
    node = node.add_child(
        ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n")))

    # This message is optional and may show up 0 to many times
    cycle = ExpectNewSessionTicket()
    node = node.add_child(cycle)
    node.add_child(cycle)

    node.next_sibling = ExpectApplicationData()
    node = node.next_sibling.add_child(
        AlertGenerator(AlertLevel.warning, AlertDescription.close_notify))

    node = node.add_child(ExpectAlert())
    node.next_sibling = ExpectClose()
    conversations["sanity"] = conversation

    test_groups = {
        GroupName.x25519: X25519_ORDER_SIZE,
        GroupName.x448: X448_ORDER_SIZE,
    }

    # check if server will negotiate x25519/x448 - sanity check
    for test_group, group_size in test_groups.items():
        for compression_format in [
                ECPointFormat.ansiX962_compressed_prime,
                ECPointFormat.ansiX962_compressed_char2,
                ECPointFormat.uncompressed
        ]:
            conversation = Connect(host, port)
            node = conversation
            ciphers = [
                CipherSuite.TLS_AES_128_GCM_SHA256,
                CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
            ]
            ext = {}
            ext[ExtensionType.ec_point_formats] = ECPointFormatsExtension(
            ).create([compression_format])
            groups = [test_group]
            key_shares = []
            for group in groups:
                key_shares.append(key_share_gen(group))
            ext[ExtensionType.key_share] = ClientKeyShareExtension().create(
                key_shares)
            ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
                .create([TLS_1_3_DRAFT, (3, 3)])
            ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
                .create(groups)
            sig_algs = [
                SignatureScheme.rsa_pss_rsae_sha256,
                SignatureScheme.rsa_pss_pss_sha256
            ]
            ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
                .create(sig_algs)
            ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
                .create(RSA_SIG_ALL)
            node = node.add_child(ClientHelloGenerator(ciphers,
                                                       extensions=ext))
            node = node.add_child(ExpectServerHello())
            node = node.add_child(ExpectChangeCipherSpec())
            node = node.add_child(ExpectEncryptedExtensions())
            node = node.add_child(ExpectCertificate())
            node = node.add_child(ExpectCertificateVerify())
            node = node.add_child(ExpectFinished())
            node = node.add_child(FinishedGenerator())
            node = node.add_child(
                ApplicationDataGenerator(bytearray(b"GET / HTTP/1.0\r\n\r\n")))

            # This message is optional and may show up 0 to many times
            cycle = ExpectNewSessionTicket()
            node = node.add_child(cycle)
            node.add_child(cycle)

            node.next_sibling = ExpectApplicationData()
            node = node.next_sibling.add_child(
                AlertGenerator(AlertLevel.warning,
                               AlertDescription.close_notify))

            node = node.add_child(ExpectAlert())
            node.next_sibling = ExpectClose()
            conversations["sanity {0} with compression {1}".format(
                GroupName.toRepr(test_group),
                ECPointFormat.toRepr(compression_format))] = conversation

        # check if server will reject an all-zero key share for x25519/x448
        # (it should result in all-zero shared secret)
        conversation = Connect(host, port)
        node = conversation
        ciphers = [
            CipherSuite.TLS_AES_128_GCM_SHA256,
            CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        ]
        ext = {}
        groups = [test_group]

        key_shares = [
            KeyShareEntry().create(test_group, bytearray(group_size))
        ]
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create(
            key_shares)

        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create(groups)
        sig_algs = [
            SignatureScheme.rsa_pss_rsae_sha256,
            SignatureScheme.rsa_pss_pss_sha256
        ]
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(RSA_SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(
            ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["all zero {0} key share".format(
            GroupName.toRepr(test_group))] = conversation

        # check if server will reject a key share or 1 for x25519/x448
        # (it should result in all-zero shared secret)
        conversation = Connect(host, port)
        node = conversation
        ciphers = [
            CipherSuite.TLS_AES_128_GCM_SHA256,
            CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        ]
        ext = {}
        groups = [test_group]

        key_shares = [
            KeyShareEntry().create(test_group,
                                   numberToByteArray(1, group_size, "little"))
        ]
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create(
            key_shares)

        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create(groups)
        sig_algs = [
            SignatureScheme.rsa_pss_rsae_sha256,
            SignatureScheme.rsa_pss_pss_sha256
        ]
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(RSA_SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(
            ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["{0} key share of \"1\"".format(
            GroupName.toRepr(test_group))] = conversation

        # check if server will reject too small x25519/x448 share
        # (one with too few bytes in the key share)
        conversation = Connect(host, port)
        node = conversation
        ciphers = [
            CipherSuite.TLS_AES_128_GCM_SHA256,
            CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        ]
        ext = {}
        groups = [test_group]

        key_shares = [
            KeyShareEntry().create(test_group,
                                   bytearray([55] * (group_size - 1)))
        ]
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create(
            key_shares)

        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create(groups)
        sig_algs = [
            SignatureScheme.rsa_pss_rsae_sha256,
            SignatureScheme.rsa_pss_pss_sha256
        ]
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(RSA_SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(
            ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["too small {0} key share".format(
            GroupName.toRepr(test_group))] = conversation

        # check if server will reject empty x25519/x448 share
        # no compression
        conversation = Connect(host, port)
        node = conversation
        ciphers = [
            CipherSuite.TLS_AES_128_GCM_SHA256,
            CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        ]
        ext = {}
        groups = [test_group]

        key_shares = [KeyShareEntry().create(test_group, bytearray())]
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create(
            key_shares)

        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create(groups)
        sig_algs = [
            SignatureScheme.rsa_pss_rsae_sha256,
            SignatureScheme.rsa_pss_pss_sha256
        ]
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(RSA_SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(
            ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["empty {0} key share".format(
            GroupName.toRepr(test_group))] = conversation

        # check if server will reject too big x25519/x448 share
        # (one with too many bytes in the key share)
        conversation = Connect(host, port)
        node = conversation
        ciphers = [
            CipherSuite.TLS_AES_128_GCM_SHA256,
            CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        ]
        ext = {}
        groups = [test_group]

        key_shares = [
            KeyShareEntry().create(test_group,
                                   bytearray([55] * (group_size + 1)))
        ]
        ext[ExtensionType.key_share] = ClientKeyShareExtension().create(
            key_shares)

        ext[ExtensionType.supported_versions] = SupportedVersionsExtension()\
            .create([TLS_1_3_DRAFT, (3, 3)])
        ext[ExtensionType.supported_groups] = SupportedGroupsExtension()\
            .create(groups)
        sig_algs = [
            SignatureScheme.rsa_pss_rsae_sha256,
            SignatureScheme.rsa_pss_pss_sha256
        ]
        ext[ExtensionType.signature_algorithms] = SignatureAlgorithmsExtension()\
            .create(sig_algs)
        ext[ExtensionType.signature_algorithms_cert] = SignatureAlgorithmsCertExtension()\
            .create(RSA_SIG_ALL)
        node = node.add_child(ClientHelloGenerator(ciphers, extensions=ext))
        node = node.add_child(
            ExpectAlert(AlertLevel.fatal, AlertDescription.illegal_parameter))
        node.add_child(ExpectClose())
        conversations["too big {0} key share".format(
            GroupName.toRepr(test_group))] = conversation

    # run the conversation
    good = 0
    bad = 0
    xfail = 0
    xpass = 0
    failed = []
    xpassed = []
    if not num_limit:
        num_limit = len(conversations)

    # make sure that sanity test is run first and last
    # to verify that server was running and kept running throughout
    sanity_tests = [('sanity', conversations['sanity'])]
    regular_tests = [(k, v) for k, v in conversations.items() if k != 'sanity']
    sampled_tests = sample(regular_tests, min(num_limit, len(regular_tests)))
    ordered_tests = chain(sanity_tests, sampled_tests, sanity_tests)

    for c_name, c_test in ordered_tests:
        if run_only and c_name not in run_only or c_name in run_exclude:
            continue
        print("{0} ...".format(c_name))

        runner = Runner(c_test)

        res = True
        exception = None
        try:
            runner.run()
        except Exception as exp:
            exception = exp
            print("Error while processing")
            print(traceback.format_exc())
            res = False

        if c_name in expected_failures:
            if res:
                xpass += 1
                xpassed.append(c_name)
                print("XPASS: expected failure but test passed\n")
            else:
                if expected_failures[c_name] is not None and  \
                    expected_failures[c_name] not in str(exception):
                    bad += 1
                    failed.append(c_name)
                    print("Expected error message: {0}\n".format(
                        expected_failures[c_name]))
                else:
                    xfail += 1
                    print("OK-expected failure\n")
        else:
            if res:
                good += 1
                print("OK\n")
            else:
                bad += 1
                failed.append(c_name)

    print("Basic test to verify that server selects same ECDHE parameters")
    print("and ciphersuites when x25519 or x448 curve is an option\n")
    print("version: {0}\n".format(version))

    print("Test end")
    print(20 * '=')
    print("TOTAL: {0}".format(len(sampled_tests) + 2 * len(sanity_tests)))
    print("SKIP: {0}".format(
        len(run_exclude.intersection(conversations.keys()))))
    print("PASS: {0}".format(good))
    print("XFAIL: {0}".format(xfail))
    print("FAIL: {0}".format(bad))
    print("XPASS: {0}".format(xpass))
    print(20 * '=')
    sort = sorted(xpassed, key=natural_sort_keys)
    if len(sort):
        print("XPASSED:\n\t{0}".format('\n\t'.join(repr(i) for i in sort)))
    sort = sorted(failed, key=natural_sort_keys)
    if len(sort):
        print("FAILED:\n\t{0}".format('\n\t'.join(repr(i) for i in sort)))

    if bad > 0:
        sys.exit(1)
 def test_small_number_little_endian(self, number):
     self.assertEqual(numberToByteArray(number, 1, endian="little"),
                      bytearray(struct.pack("<B", number)))
 def test_big_number(self, number):
     self.assertEqual(numberToByteArray(number, 4, endian="little"),
                      bytearray(struct.pack("<L", number)))