Commit 383031f1 authored by Szilárd Pfeiffer's avatar Szilárd Pfeiffer
Browse files

tls: Implement classes for TLS ChangeCipherSpec message

parent c77241ff
Loading
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -117,3 +117,36 @@ class TlsAlertMessage(TlsSubprotocolMessageBase):

    def __eq__(self, other):
        return self.level == other.level and self.description == other.description


class TlsChangeCipherSpecType(enum.IntEnum):
    CHANGE_CIPHER_SPEC = 0x01


class TlsChangeCipherSpecMessage(TlsSubprotocolMessageBase):
    def __init__(self, change_cipher_spec_type=TlsChangeCipherSpecType.CHANGE_CIPHER_SPEC):
        super(TlsChangeCipherSpecMessage, self).__init__()

        self._change_cipher_spec_type = change_cipher_spec_type

    @classmethod
    def get_content_type(cls):
        return TlsContentType.CHANGE_CIPHER_SPEC

    @classmethod
    def _parse(cls, parsable):
        parser = ParserBinary(parsable)

        parser.parse_numeric('change_cipher_spec_type', 1, TlsChangeCipherSpecType)

        return TlsChangeCipherSpecMessage(parser['change_cipher_spec_type']), parser.parsed_length

    def compose(self):
        composer = ComposerBinary()

        composer.compose_numeric(self._change_cipher_spec_type, 1)

        return composer.composed_bytes

    def __eq__(self, other):
        return self._change_cipher_spec_type == other._change_cipher_spec_type  # pylint: disable=protected-access
+41 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import unittest

import six

from cryptoparser.common.exception import NotEnoughData, InvalidValue

from cryptoparser.tls.record import TlsRecord
from cryptoparser.tls.subprotocol import TlsChangeCipherSpecMessage, TlsChangeCipherSpecType


class TestRecord(unittest.TestCase):
    def test_error(self):
        with six.assertRaisesRegex(self, InvalidValue, '0xff is not a valid TlsChangeCipherSpecType'):
            # pylint: disable=expression-not-assigned
            TlsChangeCipherSpecMessage.parse_exact_size(b'\xff'),

        with self.assertRaises(NotEnoughData) as context_manager:
            # pylint: disable=expression-not-assigned
            TlsChangeCipherSpecMessage.parse_exact_size(b''),
        self.assertEqual(context_manager.exception.bytes_needed, 1)

    def test_parse(self):
        self.assertEqual(
            TlsChangeCipherSpecMessage.parse_exact_size(b'\x01'),
            TlsChangeCipherSpecMessage(TlsChangeCipherSpecType.CHANGE_CIPHER_SPEC)
        )

    def test_compose(self):
        self.assertEqual(
            b'\x01',
            TlsChangeCipherSpecMessage(TlsChangeCipherSpecType.CHANGE_CIPHER_SPEC).compose()
        )

    def test_record(self):
        self.assertEqual(
            b'\x14\x03\x03\x00\x01\x01',
            TlsRecord([TlsChangeCipherSpecMessage()]).compose()
        )