Source code for proxy.core.tls.tls

# -*- coding: utf-8 -*-
"""
    proxy.py
    ~~~~~~~~
    ⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
    Network monitoring, controls & Application development, testing, debugging.

    :copyright: (c) 2013-present by Abhinav Singh and contributors.
    :license: BSD, see LICENSE for more details.
"""
import struct
import logging
from typing import Tuple, Optional

from .types import tlsContentType
from .handshake import TlsHandshake
from .certificate import TlsCertificate


logger = logging.getLogger(__name__)


[docs]class TlsParser: """TLS packet parser""" def __init__(self) -> None: self.content_type: int = tlsContentType.OTHER self.protocol_version: Optional[bytes] = None self.length: Optional[bytes] = None # only parse hand shake payload temporary self.handshake: Optional[TlsHandshake] = None self.certificate: Optional[TlsCertificate]
[docs] def parse(self, raw: bytes) -> Tuple[bool, bytes]: """Parse TLS fragmentation. References https://datatracker.ietf.org/doc/html/rfc5246#page-15 https://datatracker.ietf.org/doc/html/rfc5077#page-3 https://datatracker.ietf.org/doc/html/rfc8446#page-10 """ length = len(raw) if length < 5: logger.debug('invalid data, len(raw) = %s', length) return False, raw payload_length, = struct.unpack('!H', raw[3:5]) if length < 5 + payload_length: logger.debug( 'incomplete data, len(raw) = %s, len(payload) = %s', length, payload_length, ) return False, raw # parse self.content_type = raw[0] self.protocol_version = raw[1:3] self.length = raw[3:5] payload = raw[5:5 + payload_length] if self.content_type == tlsContentType.HANDSHAKE: # parse handshake self.handshake = TlsHandshake() self.handshake.parse(payload) return True, raw[5 + payload_length:]
[docs] def build(self) -> bytes: data = b'' data += bytes([self.content_type]) assert self.protocol_version data += self.protocol_version payload = b'' if self.content_type == tlsContentType.HANDSHAKE: assert self.handshake payload += self.handshake.build() length = struct.pack('!H', len(payload)) data += length data += payload return data