Beispiel #1
0
    def test_getmarker_nested(self):
        buf = MsgBuffer(b"\x00\x0b\x03foo\x06barfoo")
        with buf.new_marker("Outer"):
            sub_buf = buf.get_opaque(2)
            self.assertEqual(sub_buf.data, b"\x03foo\x06barfoo")
            with sub_buf.new_marker("Inner1"):
                subsub_buf = sub_buf.get_opaque(1)
                self.assertEqual(subsub_buf.data, b"foo")
            with sub_buf.new_marker("Inner2"):
                subsub_buf = sub_buf.get_opaque(1)
                self.assertEqual(subsub_buf.data, b"barfoo")

        expect = {
            "Outer": (0, 13),
            "Inner1": (2, 6),
            "Inner2": (6, 13),
        }
        fulfilled = set()

        for marker in buf.markers:
            if expect.get(marker.text) is not None:
                (expected_start, expected_end) = expect[marker.text]
                self.assertEqual(expected_start, marker.startoffset)
                self.assertEqual(expected_end, marker.endoffset)
                fulfilled.add(marker.text)
        self.assertEqual(len(fulfilled), len(expect))
Beispiel #2
0
    def rx_packet(self, layered_pkt):
        self._msgs["server"][layered_pkt.application.packet_type()].append(
            layered_pkt.application)
        pkt = layered_pkt.application
        ptype = pkt.packet_type()
        self._log.debug("<- %s" % (str(layered_pkt.application)))

        if ptype is HandshakeType.ServerHello:
            self._srandom = pkt.random
        elif ptype is HandshakeType.ServerKeyExchange:
            server_cert_der = self._msgs["server"][
                HandshakeType.Certificate][0].get_cert(0)
            server_cert = X509Certificate.fromderobj(server_cert_der)

            signed_kex_params = MsgBuffer()
            signed_kex_params += self._msgs["client"][
                HandshakeType.ClientHello][0].random
            signed_kex_params += self._msgs["server"][
                HandshakeType.ServerHello][0].random
            signed_kex_params += pkt.get_signedpayload()

            explanation = ExplainedSteps(
                "Verification of ServerKeyExchange parameters")
            explanation.append(
                ExplainedValueStep("Signed KEX parameters", signed_kex_params))
            sig_valid = server_cert.publickey.verify_md5sha1(
                signed_kex_params.data,
                pkt.signature.data,
                explain=explanation)
            self._conn.explain(explanation)

            if not sig_valid:
                raise Exception("Signature check failed for KEX parameters.")
        elif ptype is HandshakeType.ServerHelloDone:
            print("TODO")
Beispiel #3
0
 def _readpkt(self, filename):
     f = open(filename, "r")
     data = bytearray()
     for line in f:
         line = line.rstrip("\r\n")
         line = line.replace("-", "")
         data += bytes.fromhex(line)
     return MsgBuffer(data)
Beispiel #4
0
    def test_decode_nested(self):
        buf = MsgBuffer(b"\x00\x04\x03\xaa\xbb\xcc")
        uints = []

        with buf.new_marker("Sub1"):
            sub1 = buf.get_opaque(2)

            with sub1.new_marker("Sub2"):
                sub2 = sub1.get_opaque(1)

                for i in range(3):
                    with sub2.new_marker("Value%d" % (i)):
                        uints.append(sub2.get_uint8())
        self.assertEqual(uints, [0xaa, 0xbb, 0xcc])

        expect_depths = [0, 1, 2, 2, 3, 4, 4, 5, 5, 5]
        depths = [marker.depth for marker in buf.markers]
        self.assertEqual(depths, expect_depths)
Beispiel #5
0
    def test_getint(self):
        buf = MsgBuffer()
        buf.add_uint24(1234567)
        buf.add_uint24(7654321)

        buf.seek(0)
        self.assertEqual(buf.get_uint24(), 1234567)
        self.assertEqual(buf.get_uint24(), 7654321)
Beispiel #6
0
	def rx_from_peer(self, data):
		self._connlog.rx_rawdata(data)
		self._rxbuffer.put(data)
		while True:
			next_pkt = self._rxbuffer.getrecordlayerpkt()
			if next_pkt is None:
				return
			next_pkt = MsgBuffer(next_pkt)
			layered_pkt = self._protocol.parse(next_pkt)
			self._connlog.rx_packet(layered_pkt)
			self._handler.rx_packet(layered_pkt)
Beispiel #7
0
 def test_nesting(self):
     buf = MsgBuffer(bytes.fromhex("05 aabbccddee 03 112233 02 0815"))
     with buf.new_marker("integers"):
         with buf.new_marker("a") as marker:
             value = int(buf.get_opaque(1))
             marker.add_comment("0x%x" % (value))
             self.assertEqual(value, 0xaabbccddee)
         with buf.new_marker("b") as marker:
             value = int(buf.get_opaque(1))
             marker.add_comment("0x%x" % (value))
             self.assertEqual(value, 0x112233)
         with buf.new_marker("c") as marker:
             value = int(buf.get_opaque(1))
             marker.add_comment("0x%x" % (value))
             self.assertEqual(value, 0x0815)
     self.assertEqual([marker.depth for marker in buf.markers],
                      [0, 1, 2, 3, 3, 2, 3, 3, 2, 3, 3])
Beispiel #8
0
    def test_decode_very_simple(self):
        buf = MsgBuffer(bytes.fromhex("03 aa bb cc"))

        with buf.new_marker("SubStructure"):
            sub = buf.get_opaque(1)
            with sub.new_marker("ValA"):
                sub.get_uint8()
            with sub.new_marker("ValB"):
                sub.get_uint8()
            with sub.new_marker("ValC"):
                sub.get_uint8()

        expect_depths = [0, 1, 2, 2, 3, 3, 3]
        depths = [marker.depth for marker in buf.markers]
        self.assertEqual(depths, expect_depths)

        expect_offsets = [(0, 4), (0, 4), (0, 1), (1, 4), (1, 2), (2, 3),
                          (3, 4)]
        offsets = [(marker.startoffset, marker.endoffset)
                   for marker in buf.markers]
        self.assertEqual(offsets, expect_offsets)
Beispiel #9
0
    def test_addint(self):
        buf = MsgBuffer()
        buf.add_uint24_be(123456)
        self.assertEqual(buf.data, b"\x01\xe2\x40")

        buf.add_uint32_be(123456789)
        self.assertEqual(buf.data, b"\x01\xe2\x40\x07\x5b\xcd\x15")
Beispiel #10
0
 def test_setmarker(self):
     buf = MsgBuffer(b"\x03foo\x00\x04bar!\x00\x00\x06mookoo")
     with buf.new_marker("0:4:<"):
         self.assertEqual(buf.get_opaque(1).data, b"foo")
     with buf.new_marker("4:10:<"):
         self.assertEqual(buf.get_opaque(2).data, b"bar!")
     with buf.new_marker("10:19:<"):
         self.assertEqual(buf.get_opaque(3).data, b"mookoo")
     for marker in buf.markers:
         if (marker.text is not None) and marker.text.endswith(":<"):
             hints = marker.text.split(":")
             expected_start = int(hints[0])
             expected_end = int(hints[1])
             self.assertEqual(expected_start, marker.startoffset)
             self.assertEqual(expected_end, marker.endoffset)
Beispiel #11
0
    def test_decode_complex(self):
        buf = MsgBuffer(
            bytes.fromhex("33 0c 44 0a 55 66 77 06 88   03 aa bb cc   99"))
        #                               0  1  2  3  4  5  6  7  8    9 10 11 12   13    14
        #                                  ^     ^           ^       ^
        with buf.new_marker("Value_0"):
            buf.get_uint8()

        with buf.new_marker("Sub_1"):
            sub1 = buf.get_opaque(1)

            with sub1.new_marker("Value_1"):
                sub1.get_uint8()
            with sub1.new_marker("Sub_2"):
                sub2 = sub1.get_opaque(1)

                with sub2.new_marker("Value_A"):
                    sub2.get_uint16()
                with sub2.new_marker("Value_B"):
                    sub2.get_uint8()
                with sub2.new_marker("Sub_3"):
                    sub3 = sub2.get_opaque(1)

                    with sub3.new_marker("Value_X"):
                        sub3.get_uint8()

                    with sub3.new_marker("Sub_4"):
                        sub4 = sub3.get_opaque(1)

                        with sub4.new_marker("Sub_R"):
                            sub4.get_uint8()
                        with sub4.new_marker("Sub_S"):
                            sub4.get_uint8()
                        with sub4.new_marker("Sub_T"):
                            sub4.get_uint8()

                    with sub3.new_marker("Value_Y"):
                        sub3.get_uint8()

        expect_depths = [
            0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 7
        ]
        depths = [marker.depth for marker in buf.markers]
        self.assertEqual(depths, expect_depths)

        expect_offsets = [(0, 14), (0, 1), (1, 14), (1, 2), (2, 14)]
        expect_offsets += [(2, 3), (3, 14), (3, 4), (4, 14)]
        expect_offsets += [(4, 6), (6, 7), (7, 14), (7, 8), (8, 14)]
        expect_offsets += [(8, 9), (9, 13), (9, 10), (10, 13), (10, 11),
                           (11, 12), (12, 13), (13, 14)]
        offsets = [(marker.startoffset, marker.endoffset)
                   for marker in buf.markers]
        self.assertEqual(offsets, expect_offsets)
Beispiel #12
0
    def initiate_handshake(self):
        #chello = ClientHelloPkt(SSLVersion.ProtocolTLSv1_2)
        chello = ClientHelloPkt(SSLVersion.ProtocolSSLv3_0)
        #csdir = CipherSuiteDirectory().kwfilter(sig_alg = "RSA", kex_alg = "DHE", kex_pfs = True, cipher_name = "AES", cipher_keylen = 128)
        csdir = CipherSuiteDirectory().kwfilter(sig_alg="RSA",
                                                kex_alg="DH",
                                                kex_pfs=True,
                                                cipher_name="AES",
                                                cipher_keylen=128,
                                                cipher_opmode="CBC")
        for cs in csdir:
            self._log.debug("Adding cipher suite: 0x%x = %s" %
                            (int(cs.csid), cs.csid.name))
            chello.add_cipher_suite(cs.csid)
        #chello.add_cipher_suite(CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA)
        #chello.add_cipher_suite(CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)
        chello.add_compression_method(CompressionMethod.null)
        chello.add_extension(HelloExtensionSignatureAlgs().add_algorithm(
            SignatureAlgorithm.ECDSA, HashAlgorithm.sha256))
        chello.add_extension(
            BaseHelloExtension(ExtensionType.heartbeat, MsgBuffer(b"\x01")))
        self._conn.send_pkt(chello)

        self._crandom = chello.random
Beispiel #13
0
 def test_emptybuf(self):
     buf = MsgBuffer()
     self.assertEqual(buf.data, b"")
Beispiel #14
0
    def test_concat(self):
        sub_buf = MsgBuffer()
        with sub_buf.new_marker("IntA"):
            sub_buf.add_opaque(1, b"ABC")
        with sub_buf.new_marker("IntB"):
            sub_buf.add_opaque(1, b"DEF")

        buf = MsgBuffer()
        with buf.new_marker("X"):
            buf.add_opaque(1, sub_buf)
        with buf.new_marker("Y"):
            buf.add_opaque(1, sub_buf)

        buf.markers.dump()
Beispiel #15
0
    def rx_packet(self, layered_pkt):
        self._msgs["client"][layered_pkt.application.packet_type()].append(
            layered_pkt.application)
        self._log.debug("<- %s" % (str(layered_pkt.application)))
        pkt = layered_pkt.application

        if layered_pkt.application.packet_type() is HandshakeType.ClientHello:
            # Issue a server hello as a response
            rsp = ServerHelloPkt(SSLVersion.ProtocolTLSv1_0)
            rsp.set_compression_method(CompressionMethod.null)
            rsp.set_cipher_suite(CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA)
            self._conn.send_pkt(rsp)

            # Then send the server certificate
            server_cert = pem_readfile("server.crt", "CERTIFICATE")
            rsp = CertificatePkt()
            rsp.add_cert(server_cert)
            self._conn.send_pkt(rsp)

            # Then prepare the server key exchange
            explanation = ExplainedSteps("Server key exchange")
            dh_params = pem_readfile("dhp.pem", "DH PARAMETERS")
            kex_params = DHModPKexParams.parse(dh_params)
            rsp = ServerKeyExchangePkt(KeyExchangeAlgorithm.DHE_RSA)
            rsp.set_kex_params(kex_params)
            rsp.set_kex_session(kex_params.new_session().randomize())

            # Sign the server key exchange message
            signed_kex_params = MsgBuffer()
            signed_kex_params += self._msgs["client"][
                HandshakeType.ClientHello][0].random
            signed_kex_params += self._msgs["server"][
                HandshakeType.ServerHello][0].random
            signed_kex_params += rsp.get_signedpayload()
            signed_kex_params.hexdump()
            priv_key = PrivateKey.from_der(
                pem_readfile("server.key", "PRIVATE KEY"))
            signature = priv_key.sign_md5sha1(signed_kex_params.data)
            rsp.set_signature(signature)

            # Explain it first
            self._conn.explain(explanation)

            # And send it to the client
            self._conn.send_pkt(rsp)

            # Then send the ServerHelloDone
            rsp = ServerHelloDonePkt()
            self._conn.send_pkt(rsp)

        elif layered_pkt.application.packet_type(
        ) is ChangeCipherSpecType.ChangeCipherSpec:
            explanation = ExplainedSteps("Key agreement")
            ske = self._msgs["server"][HandshakeType.ServerKeyExchange][0]
            cke = self._msgs["client"][HandshakeType.ClientKeyExchange][0]
            session = ske.kexsession
            shared_secret = session.establish(cke.kexparam)

            server_rnd = self._msgs["server"][
                HandshakeType.ServerHello][0].random.data
            client_rnd = self._msgs["client"][
                HandshakeType.ClientHello][0].random.data

            premaster_secret_part1 = shared_secret[:64]
            master_secret_part1 = PreMasterSecret.pms_to_ms(
                PMSPRF.MD5,
                PMSCalcLabel.MasterSecret,
                premaster_secret_part1,
                server_rnd,
                client_rnd,
                explain=explanation)

            premaster_secret_part2 = shared_secret[64:]
            master_secret_part2 = PreMasterSecret.pms_to_ms(
                PMSPRF.SHA1,
                PMSCalcLabel.MasterSecret,
                premaster_secret_part2,
                server_rnd,
                client_rnd,
                explain=explanation)

            master_secret = MsgBuffer(master_secret_part1) ^ MsgBuffer(
                master_secret_part2)
            master_secret.hexdump()

            self._conn.explain(explanation)
Beispiel #16
0
 def test_mkmarker_nested(self):
     buf = MsgBuffer()
     with buf.add_opaque_deferred(2):
         buf.add_uint16(0x1122)
         buf.add_uint32(0xaabbccdd)
         buf.add_uint8(0xff)
         with buf.add_opaque_deferred(3):
             buf.add_uint16(0xaaaa)
             buf.add_uint16(0xbbbb)
             buf.add_uint16(0xcccc)
             buf.add_uint8(0x55)
     self.assertEqual(
         buf.data,
         bytes.fromhex("0011 1122 aabbccdd ff 000007  aaaa bbbb cccc 55"))
Beispiel #17
0
 def test_setopaque(self):
     buf = MsgBuffer()
     buf.add_opaque(1, b"foo")
     buf.add_opaque(2, b"bar!")
     buf.add_opaque(3, b"mookoo")
     self.assertEqual(buf.data, b"\x03foo\x00\x04bar!\x00\x00\x06mookoo")
Beispiel #18
0
 def test_mkopaque_annotated(self):
     buf = MsgBuffer()
     with buf.new_marker("MainPayload"), buf.add_opaque_deferred(2):
         with buf.new_marker("AnimalCounts"), buf.add_opaque_deferred(2):
             with buf.new_marker("CowCount"):
                 buf.add_uint16(9000)
             with buf.new_marker("SheepCount"):
                 buf.add_uint16(4321)
             with buf.new_marker("ChickenCount"):
                 buf.add_uint32(12345678)
         with buf.new_marker("VehicleCounts"), buf.add_opaque_deferred(2):
             with buf.new_marker("CarCount"):
                 buf.add_uint24(133)
             with buf.new_marker("TrainCount"):
                 buf.add_uint24(92)
Beispiel #19
0
 def test_addbuf(self):
     buf = MsgBuffer()
     buf += b"foobar"
     buf += b"mookoo"
     self.assertEqual(buf.data, b"foobarmookoo")
Beispiel #20
0
 def test_decode_seq(self):
     buf = MsgBuffer(bytes.fromhex("03 aaaaaa 03 bbbbbb 03 cccccc"))
     with buf.new_marker("Chunk1"):
         buf.get_opaque(1)
     with buf.new_marker("Chunk2"):
         buf.get_opaque(1)
     with buf.new_marker("Chunk3"):
         buf.get_opaque(1)