1# This file is part of Scapy
2# Copyright (C) 2007, 2008, 2009 Arnaud Ebalard
3#               2015, 2016 Maxence Tury
4# This program is published under a GPLv2 license
5
6"""
7TLS compression.
8"""
9
10from __future__ import absolute_import
11import zlib
12
13from scapy.error import warning
14import scapy.modules.six as six
15
16
17_tls_compression_algs = {}
18_tls_compression_algs_cls = {}
19
20
21class _GenericCompMetaclass(type):
22    """
23    Compression classes are automatically registered through this metaclass.
24    """
25    def __new__(cls, name, bases, dct):
26        the_class = super(_GenericCompMetaclass, cls).__new__(cls, name,
27                                                              bases, dct)
28        comp_name = dct.get("name")
29        val = dct.get("val")
30        if comp_name:
31            _tls_compression_algs[val] = comp_name
32            _tls_compression_algs_cls[val] = the_class
33        return the_class
34
35
36class _GenericComp(six.with_metaclass(_GenericCompMetaclass, object)):
37    pass
38
39
40class Comp_NULL(_GenericComp):
41    """
42    The default and advised compression method for TLS: doing nothing.
43    """
44    name = "null"
45    val = 0
46
47    def compress(self, s):
48        return s
49
50    def decompress(self, s):
51        return s
52
53
54class Comp_Deflate(_GenericComp):
55    """
56    DEFLATE algorithm, specified for TLS by RFC 3749.
57    """
58    name = "deflate"
59    val = 1
60
61    def compress(self, s):
62        tmp = self.compress_state.compress(s)
63        tmp += self.compress_state.flush(zlib.Z_FULL_FLUSH)
64        return tmp
65
66    def decompress(self, s):
67        return self.decompress_state.decompress(s)
68
69    def __init__(self):
70        self.compress_state = zlib.compressobj()
71        self.decompress_state = zlib.decompressobj()
72
73
74class Comp_LZS(_GenericComp):
75    """
76    Lempel-Zic-Stac (LZS) algorithm, specified for TLS by RFC 3943.
77    XXX No support for now.
78    """
79    name = "LZS"
80    val = 64
81
82    def compress(self, s):
83        warning("LZS Compression algorithm is not implemented yet")
84        return s
85
86    def decompress(self, s):
87        warning("LZS Compression algorithm is not implemented yet")
88        return s
89