From 9c6b3eb58a22817daa576063c3626d7a239e7093 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 26 Aug 2015 22:00:50 +0200 Subject: clean up clienthello parsing --- libmproxy/contrib/README | 4 + libmproxy/contrib/tls/_constructs.py | 6 +- libmproxy/contrib/tls/alert_message.py | 64 ------ libmproxy/contrib/tls/ciphersuites.py | 343 --------------------------------- libmproxy/contrib/tls/exceptions.py | 2 - libmproxy/contrib/tls/hello_message.py | 178 ----------------- libmproxy/contrib/tls/message.py | 313 ------------------------------ libmproxy/contrib/tls/record.py | 110 ----------- libmproxy/contrib/tls/utils.py | 26 --- libmproxy/protocol2/tls.py | 14 +- 10 files changed, 19 insertions(+), 1041 deletions(-) delete mode 100644 libmproxy/contrib/tls/alert_message.py delete mode 100644 libmproxy/contrib/tls/ciphersuites.py delete mode 100644 libmproxy/contrib/tls/exceptions.py delete mode 100644 libmproxy/contrib/tls/hello_message.py delete mode 100644 libmproxy/contrib/tls/message.py delete mode 100644 libmproxy/contrib/tls/record.py diff --git a/libmproxy/contrib/README b/libmproxy/contrib/README index 3b0f7512..e339310a 100644 --- a/libmproxy/contrib/README +++ b/libmproxy/contrib/README @@ -8,3 +8,7 @@ jsbeautifier, git checkout 25/03/12, MIT license wbxml - https://github.com/davidpshaw/PyWBXMLDecoder + +tls, BSD license + - https://github.com/mhils/tls/tree/extension-parsing + - limited to required files. \ No newline at end of file diff --git a/libmproxy/contrib/tls/_constructs.py b/libmproxy/contrib/tls/_constructs.py index a5f8b524..9c57a799 100644 --- a/libmproxy/contrib/tls/_constructs.py +++ b/libmproxy/contrib/tls/_constructs.py @@ -4,8 +4,8 @@ from __future__ import absolute_import, division, print_function -from construct import Array, Bytes, Struct, UBInt16, UBInt32, UBInt8, PascalString, Embed, \ - TunnelAdapter, GreedyRange, Switch +from construct import (Array, Bytes, Struct, UBInt16, UBInt32, UBInt8, PascalString, Embed, TunnelAdapter, GreedyRange, + Switch, OptionalGreedyRange) from .utils import UBInt24 @@ -113,7 +113,7 @@ Extension = Struct( extensions = TunnelAdapter( PascalString("extensions", length_field=UBInt16("extensions_length")), - GreedyRange(Extension) + OptionalGreedyRange(Extension) ) ClientHello = Struct( diff --git a/libmproxy/contrib/tls/alert_message.py b/libmproxy/contrib/tls/alert_message.py deleted file mode 100644 index ef02f56d..00000000 --- a/libmproxy/contrib/tls/alert_message.py +++ /dev/null @@ -1,64 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -from enum import Enum - -from characteristic import attributes - -from . import _constructs - - -class AlertLevel(Enum): - WARNING = 1 - FATAL = 2 - - -class AlertDescription(Enum): - CLOSE_NOTIFY = 0 - UNEXPECTED_MESSAGE = 10 - BAD_RECORD_MAC = 20 - DECRYPTION_FAILED_RESERVED = 21 - RECORD_OVERFLOW = 22 - DECOMPRESSION_FAILURE = 30 - HANDSHAKE_FAILURE = 40 - NO_CERTIFICATE_RESERVED = 41 - BAD_CERTIFICATE = 42 - UNSUPPORTED_CERTIFICATE = 43 - CERTIFICATE_REVOKED = 44 - CERTIFICATE_EXPIRED = 45 - CERTIFICATE_UNKNOWN = 46 - ILLEGAL_PARAMETER = 47 - UNKNOWN_CA = 48 - ACCESS_DENIED = 49 - DECODE_ERROR = 50 - DECRYPT_ERROR = 51 - EXPORT_RESTRICTION_RESERVED = 60 - PROTOCOL_VERSION = 70 - INSUFFICIENT_SECURITY = 71 - INTERNAL_ERROR = 80 - USER_CANCELED = 90 - NO_RENEGOTIATION = 100 - UNSUPPORTED_EXTENSION = 110 - - -@attributes(['level', 'description']) -class Alert(object): - """ - An object representing an Alert message. - """ - @classmethod - def from_bytes(cls, bytes): - """ - Parse an ``Alert`` struct. - - :param bytes: the bytes representing the input. - :return: Alert object. - """ - construct = _constructs.Alert.parse(bytes) - return cls( - level=AlertLevel(construct.level), - description=AlertDescription(construct.description) - ) diff --git a/libmproxy/contrib/tls/ciphersuites.py b/libmproxy/contrib/tls/ciphersuites.py deleted file mode 100644 index 86298f80..00000000 --- a/libmproxy/contrib/tls/ciphersuites.py +++ /dev/null @@ -1,343 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -from enum import Enum - -from .exceptions import UnsupportedCipherException - - -class CipherSuites(Enum): - TLS_NULL_WITH_NULL_NULL = 0x0000 - TLS_RSA_WITH_NULL_MD5 = 0x0001 - TLS_RSA_WITH_NULL_SHA = 0x0002 - TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003 - TLS_RSA_WITH_RC4_128_MD5 = 0x0004 - TLS_RSA_WITH_RC4_128_SHA = 0x0005 - TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006 - TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007 - TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008 - TLS_RSA_WITH_DES_CBC_SHA = 0x0009 - TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A - TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B - TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C - TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D - TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E - TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F - TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010 - TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011 - TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012 - TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013 - TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014 - TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015 - TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016 - TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017 - TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018 - TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0x0019 - TLS_DH_anon_WITH_DES_CBC_SHA = 0x001A - TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B - TLS_KRB5_WITH_DES_CBC_SHA = 0x001E - TLS_KRB5_WITH_3DES_EDE_CBC_SHA = 0x001F - TLS_KRB5_WITH_RC4_128_SHA = 0x0020 - TLS_KRB5_WITH_IDEA_CBC_SHA = 0x0021 - TLS_KRB5_WITH_DES_CBC_MD5 = 0x0022 - TLS_KRB5_WITH_3DES_EDE_CBC_MD5 = 0x0023 - TLS_KRB5_WITH_RC4_128_MD5 = 0x0024 - TLS_KRB5_WITH_IDEA_CBC_MD5 = 0x0025 - TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = 0x0026 - TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = 0x0027 - TLS_KRB5_EXPORT_WITH_RC4_40_SHA = 0x0028 - TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = 0x0029 - TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = 0x002A - TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = 0x002B - TLS_PSK_WITH_NULL_SHA = 0x002C - TLS_DHE_PSK_WITH_NULL_SHA = 0x002D - TLS_RSA_PSK_WITH_NULL_SHA = 0x002E - TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F - TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030 - TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031 - TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 - TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 - TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034 - TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 - TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036 - TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037 - TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 - TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 - TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A - TLS_RSA_WITH_NULL_SHA256 = 0x003B - TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C - TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D - TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E - TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F - TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 - TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041 - TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042 - TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043 - TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044 - TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045 - TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046 - TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 - TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068 - TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069 - TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A - TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B - TLS_DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C - TLS_DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D - TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084 - TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085 - TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086 - TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087 - TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088 - TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089 - TLS_PSK_WITH_RC4_128_SHA = 0x008A - TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B - TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C - TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D - TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E - TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F - TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090 - TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091 - TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092 - TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093 - TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094 - TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095 - TLS_RSA_WITH_SEED_CBC_SHA = 0x0096 - TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097 - TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098 - TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099 - TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A - TLS_DH_anon_WITH_SEED_CBC_SHA = 0x009B - TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C - TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D - TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E - TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F - TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0 - TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1 - TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 - TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 - TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4 - TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5 - TLS_DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6 - TLS_DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7 - TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8 - TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9 - TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA - TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB - TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC - TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD - TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE - TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF - TLS_PSK_WITH_NULL_SHA256 = 0x00B0 - TLS_PSK_WITH_NULL_SHA384 = 0x00B1 - TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2 - TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3 - TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4 - TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5 - TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6 - TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7 - TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8 - TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9 - TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA - TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB - TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC - TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD - TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE - TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF - TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0 - TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1 - TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2 - TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3 - TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4 - TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5 - TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF - TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001 - TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002 - TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003 - TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004 - TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005 - TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006 - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007 - TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A - TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B - TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C - TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D - TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E - TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F - TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010 - TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 - TLS_ECDH_anon_WITH_NULL_SHA = 0xC015 - TLS_ECDH_anon_WITH_RC4_128_SHA = 0xC016 - TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017 - TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018 - TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019 - TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A - TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B - TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C - TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D - TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E - TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F - TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020 - TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021 - TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 - TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025 - TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 - TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029 - TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C - TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D - TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 - TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031 - TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032 - TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033 - TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034 - TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035 - TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036 - TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037 - TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038 - TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039 - TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A - TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B - TLS_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC03C - TLS_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC03D - TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC03E - TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC03F - TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC040 - TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC041 - TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC042 - TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC043 - TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC044 - TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC045 - TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 = 0xC046 - TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 = 0xC047 - TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC048 - TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC049 - TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC04A - TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC04B - TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04C - TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04D - TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04E - TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04F - TLS_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC050 - TLS_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC051 - TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC052 - TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC053 - TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC054 - TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC055 - TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC056 - TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC057 - TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC058 - TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC059 - TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 = 0xC05A - TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 = 0xC05B - TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05C - TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05D - TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05E - TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05F - TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC060 - TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC061 - TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC062 - TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC063 - TLS_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC064 - TLS_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC065 - TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC066 - TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC067 - TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC068 - TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC069 - TLS_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06A - TLS_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06B - TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06C - TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06D - TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06E - TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06F - TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC070 - TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC071 - TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072 - TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073 - TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074 - TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075 - TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076 - TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077 - TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078 - TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079 - TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A - TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B - TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C - TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D - TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E - TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F - TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080 - TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081 - TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082 - TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083 - TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084 - TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085 - TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086 - TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087 - TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088 - TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089 - TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A - TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B - TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C - TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D - TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E - TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F - TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090 - TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091 - TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092 - TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093 - TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094 - TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095 - TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096 - TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097 - TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098 - TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099 - TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A - TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B - TLS_RSA_WITH_AES_128_CCM = 0xC09C - TLS_RSA_WITH_AES_256_CCM = 0xC09D - TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E - TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F - TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0 - TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1 - TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2 - TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3 - TLS_PSK_WITH_AES_128_CCM = 0xC0A4 - TLS_PSK_WITH_AES_256_CCM = 0xC0A5 - TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6 - TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7 - TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8 - TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9 - TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA - TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB - TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC - TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD - TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE - TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13 - - -def select_preferred_ciphersuite(client_supported, server_supported): - for i in server_supported: - assert isinstance(i, CipherSuites) - if i in client_supported: - return i - - raise UnsupportedCipherException( - "Client supported ciphersuites are not supported on the server." - ) diff --git a/libmproxy/contrib/tls/exceptions.py b/libmproxy/contrib/tls/exceptions.py deleted file mode 100644 index 75b34d11..00000000 --- a/libmproxy/contrib/tls/exceptions.py +++ /dev/null @@ -1,2 +0,0 @@ -class UnsupportedCipherException(Exception): - pass diff --git a/libmproxy/contrib/tls/hello_message.py b/libmproxy/contrib/tls/hello_message.py deleted file mode 100644 index 23cd872b..00000000 --- a/libmproxy/contrib/tls/hello_message.py +++ /dev/null @@ -1,178 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -from enum import Enum - -from characteristic import attributes - -from construct import Container - -from six import BytesIO - -from . import _constructs - - -@attributes(['major', 'minor']) -class ProtocolVersion(object): - """ - An object representing a ProtocolVersion struct. - """ - - -@attributes(['gmt_unix_time', 'random_bytes']) -class Random(object): - """ - An object representing a Random struct. - """ - - -@attributes(['type', 'data']) -class Extension(object): - """ - An object representing an Extension struct. - """ - def as_bytes(self): - return _constructs.Extension.build(Container( - type=self.type.value, length=len(self.data), data=self.data)) - - -@attributes(['client_version', 'random', 'session_id', 'cipher_suites', - 'compression_methods', 'extensions']) -class ClientHello(object): - """ - An object representing a ClientHello message. - """ - def as_bytes(self): - return _constructs.ClientHello.build( - Container( - version=Container(major=self.client_version.major, - minor=self.client_version.minor), - random=Container( - gmt_unix_time=self.random.gmt_unix_time, - random_bytes=self.random.random_bytes - ), - session_id=Container(length=len(self.session_id), - session_id=self.session_id), - cipher_suites=Container(length=len(self.cipher_suites) * 2, - cipher_suites=self.cipher_suites), - compression_methods=Container( - length=len(self.compression_methods), - compression_methods=self.compression_methods - ), - extensions_length=sum([2 + 2 + len(ext.data) - for ext in self.extensions]), - extensions_bytes=b''.join( - [ext.as_bytes() for ext in self.extensions] - ) - ) - ) - - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``ClientHello`` struct. - - :param bytes: the bytes representing the input. - :return: ClientHello object. - """ - construct = _constructs.ClientHello.parse(bytes) - # XXX Is there a better way in Construct to parse an array of - # variable-length structs? - extensions = [] - extensions_io = BytesIO(construct.extensions_bytes) - while extensions_io.tell() < construct.extensions_length: - extension_construct = _constructs.Extension.parse_stream( - extensions_io) - extensions.append( - Extension(type=ExtensionType(extension_construct.type), - data=extension_construct.data)) - return ClientHello( - client_version=ProtocolVersion( - major=construct.version.major, - minor=construct.version.minor, - ), - random=Random( - gmt_unix_time=construct.random.gmt_unix_time, - random_bytes=construct.random.random_bytes, - ), - session_id=construct.session_id.session_id, - # TODO: cipher suites should be enums - cipher_suites=construct.cipher_suites.cipher_suites, - compression_methods=( - construct.compression_methods.compression_methods - ), - extensions=extensions, - ) - - -class ExtensionType(Enum): - SIGNATURE_ALGORITHMS = 13 - # XXX: See http://tools.ietf.org/html/rfc5246#ref-TLSEXT - - -@attributes(['server_version', 'random', 'session_id', 'cipher_suite', - 'compression_method', 'extensions']) -class ServerHello(object): - """ - An object representing a ServerHello message. - """ - def as_bytes(self): - return _constructs.ServerHello.build( - Container( - version=Container(major=self.server_version.major, - minor=self.server_version.minor), - random=Container( - gmt_unix_time=self.random.gmt_unix_time, - random_bytes=self.random.random_bytes - ), - session_id=Container(length=len(self.session_id), - session_id=self.session_id), - cipher_suite=self.cipher_suite, - compression_method=self.compression_method.value, - extensions_length=sum([2 + 2 + len(ext.data) - for ext in self.extensions]), - extensions_bytes=b''.join( - [ext.as_bytes() for ext in self.extensions] - ) - ) - ) - - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``ServerHello`` struct. - - :param bytes: the bytes representing the input. - :return: ServerHello object. - """ - construct = _constructs.ServerHello.parse(bytes) - # XXX: Find a better way to parse extensions - extensions = [] - extensions_io = BytesIO(construct.extensions_bytes) - while extensions_io.tell() < construct.extensions_length: - extension_construct = _constructs.Extension.parse_stream( - extensions_io) - extensions.append( - Extension(type=ExtensionType(extension_construct.type), - data=extension_construct.data)) - return ServerHello( - server_version=ProtocolVersion( - major=construct.version.major, - minor=construct.version.minor, - ), - random=Random( - gmt_unix_time=construct.random.gmt_unix_time, - random_bytes=construct.random.random_bytes, - ), - session_id=construct.session_id.session_id, - cipher_suite=construct.cipher_suite, - compression_method=CompressionMethod(construct.compression_method), - extensions=extensions, - ) - - -class CompressionMethod(Enum): - NULL = 0 diff --git a/libmproxy/contrib/tls/message.py b/libmproxy/contrib/tls/message.py deleted file mode 100644 index b372859f..00000000 --- a/libmproxy/contrib/tls/message.py +++ /dev/null @@ -1,313 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -from enum import Enum - -from characteristic import attributes - -from construct import Container - -from six import BytesIO - -from . import _constructs - -from .hello_message import ( - ClientHello, ProtocolVersion, ServerHello -) - - -class ClientCertificateType(Enum): - RSA_SIGN = 1 - DSS_SIGN = 2 - RSA_FIXED_DH = 3 - DSS_FIXED_DH = 4 - RSA_EPHEMERAL_DH_RESERVED = 5 - DSS_EPHEMERAL_DH_RESERVED = 6 - FORTEZZA_DMS_RESERVED = 20 - - -class HashAlgorithm(Enum): - NONE = 0 - MD5 = 1 - SHA1 = 2 - SHA224 = 3 - SHA256 = 4 - SHA384 = 5 - SHA512 = 6 - - -class SignatureAlgorithm(Enum): - ANONYMOUS = 0 - RSA = 1 - DSA = 2 - ECDSA = 3 - - -class HandshakeType(Enum): - HELLO_REQUEST = 0 - CLIENT_HELLO = 1 - SERVER_HELLO = 2 - CERTIFICATE = 11 - SERVER_KEY_EXCHANGE = 12 - CERTIFICATE_REQUEST = 13 - SERVER_HELLO_DONE = 14 - CERTIFICATE_VERIFY = 15 - CLIENT_KEY_EXCHANGE = 16 - FINISHED = 20 - - -class HelloRequest(object): - """ - An object representing a HelloRequest struct. - """ - def as_bytes(self): - return b'' - - -class ServerHelloDone(object): - """ - An object representing a ServerHelloDone struct. - """ - def as_bytes(self): - return b'' - - -@attributes(['certificate_types', 'supported_signature_algorithms', - 'certificate_authorities']) -class CertificateRequest(object): - """ - An object representing a CertificateRequest struct. - """ - def as_bytes(self): - return _constructs.CertificateRequest.build(Container( - certificate_types=Container( - length=len(self.certificate_types), - certificate_types=[cert_type.value - for cert_type in self.certificate_types] - ), - supported_signature_algorithms=Container( - supported_signature_algorithms_length=2 * len( - self.supported_signature_algorithms - ), - algorithms=[Container( - hash=algorithm.hash.value, - signature=algorithm.signature.value, - ) - for algorithm in self.supported_signature_algorithms - ] - ), - certificate_authorities=Container( - length=len(self.certificate_authorities), - certificate_authorities=self.certificate_authorities - ) - )) - - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``CertificateRequest`` struct. - - :param bytes: the bytes representing the input. - :return: CertificateRequest object. - """ - construct = _constructs.CertificateRequest.parse(bytes) - return cls( - certificate_types=[ - ClientCertificateType(cert_type) - for cert_type in construct.certificate_types.certificate_types - ], - supported_signature_algorithms=[ - SignatureAndHashAlgorithm( - hash=HashAlgorithm(algorithm.hash), - signature=SignatureAlgorithm(algorithm.signature), - ) - for algorithm in ( - construct.supported_signature_algorithms.algorithms - ) - ], - certificate_authorities=( - construct.certificate_authorities.certificate_authorities - ) - ) - - -@attributes(['hash', 'signature']) -class SignatureAndHashAlgorithm(object): - """ - An object representing a SignatureAndHashAlgorithm struct. - """ - - -@attributes(['dh_p', 'dh_g', 'dh_Ys']) -class ServerDHParams(object): - """ - An object representing a ServerDHParams struct. - """ - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``ServerDHParams`` struct. - - :param bytes: the bytes representing the input. - :return: ServerDHParams object. - """ - construct = _constructs.ServerDHParams.parse(bytes) - return cls( - dh_p=construct.dh_p, - dh_g=construct.dh_g, - dh_Ys=construct.dh_Ys - ) - - -@attributes(['client_version', 'random']) -class PreMasterSecret(object): - """ - An object representing a PreMasterSecret struct. - """ - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``PreMasterSecret`` struct. - - :param bytes: the bytes representing the input. - :return: CertificateRequest object. - """ - construct = _constructs.PreMasterSecret.parse(bytes) - return cls( - client_version=ProtocolVersion( - major=construct.version.major, - minor=construct.version.minor, - ), - random=construct.random_bytes, - ) - - -@attributes(['asn1_cert']) -class ASN1Cert(object): - """ - An object representing ASN.1 Certificate - """ - def as_bytes(self): - return _constructs.ASN1Cert.build(Container( - length=len(self.asn1_cert), - asn1_cert=self.asn1_cert - )) - - -@attributes(['certificate_list']) -class Certificate(object): - """ - An object representing a Certificate struct. - """ - def as_bytes(self): - return _constructs.Certificate.build(Container( - certificates_length=sum([4 + len(asn1cert.asn1_cert) - for asn1cert in self.certificate_list]), - certificates_bytes=b''.join( - [asn1cert.as_bytes() for asn1cert in self.certificate_list] - ) - - )) - - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``Certificate`` struct. - - :param bytes: the bytes representing the input. - :return: Certificate object. - """ - construct = _constructs.Certificate.parse(bytes) - # XXX: Find a better way to parse an array of variable-length objects - certificates = [] - certificates_io = BytesIO(construct.certificates_bytes) - - while certificates_io.tell() < construct.certificates_length: - certificate_construct = _constructs.ASN1Cert.parse_stream( - certificates_io - ) - certificates.append( - ASN1Cert(asn1_cert=certificate_construct.asn1_cert) - ) - return cls( - certificate_list=certificates - ) - - -@attributes(['verify_data']) -class Finished(object): - def as_bytes(self): - return self.verify_data - - -@attributes(['msg_type', 'length', 'body']) -class Handshake(object): - """ - An object representing a Handshake struct. - """ - def as_bytes(self): - if self.msg_type in [ - HandshakeType.SERVER_HELLO, HandshakeType.CLIENT_HELLO, - HandshakeType.CERTIFICATE, HandshakeType.CERTIFICATE_REQUEST, - HandshakeType.HELLO_REQUEST, HandshakeType.SERVER_HELLO_DONE, - HandshakeType.FINISHED - ]: - _body_as_bytes = self.body.as_bytes() - else: - _body_as_bytes = b'' - return _constructs.Handshake.build( - Container( - msg_type=self.msg_type.value, - length=self.length, - body=_body_as_bytes - ) - ) - - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``Handshake`` struct. - - :param bytes: the bytes representing the input. - :return: Handshake object. - """ - construct = _constructs.Handshake.parse(bytes) - return cls( - msg_type=HandshakeType(construct.msg_type), - length=construct.length, - body=cls._get_handshake_message( - HandshakeType(construct.msg_type), construct.body - ), - ) - - @staticmethod - def _get_handshake_message(msg_type, body): - _handshake_message_parser = { - HandshakeType.CLIENT_HELLO: ClientHello.from_bytes, - HandshakeType.SERVER_HELLO: ServerHello.from_bytes, - HandshakeType.CERTIFICATE: Certificate.from_bytes, - # 12: parse_server_key_exchange, - HandshakeType.CERTIFICATE_REQUEST: CertificateRequest.from_bytes, - # 15: parse_certificate_verify, - # 16: parse_client_key_exchange, - } - - try: - if msg_type == HandshakeType.HELLO_REQUEST: - return HelloRequest() - elif msg_type == HandshakeType.SERVER_HELLO_DONE: - return ServerHelloDone() - elif msg_type == HandshakeType.FINISHED: - return Finished(verify_data=body) - elif msg_type in [HandshakeType.SERVER_KEY_EXCHANGE, - HandshakeType.CERTIFICATE_VERIFY, - HandshakeType.CLIENT_KEY_EXCHANGE, - ]: - raise NotImplementedError - else: - return _handshake_message_parser[msg_type](body) - except NotImplementedError: - return None # TODO diff --git a/libmproxy/contrib/tls/record.py b/libmproxy/contrib/tls/record.py deleted file mode 100644 index 481c93bc..00000000 --- a/libmproxy/contrib/tls/record.py +++ /dev/null @@ -1,110 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -from enum import Enum - -from characteristic import attributes - -from construct import Container - -from . import _constructs - - -@attributes(['major', 'minor']) -class ProtocolVersion(object): - """ - An object representing a ProtocolVersion struct. - """ - - -@attributes(['type', 'version', 'fragment']) -class TLSPlaintext(object): - """ - An object representing a TLSPlaintext struct. - """ - def as_bytes(self): - return _constructs.TLSPlaintext.build( - Container( - type=self.type.value, - version=Container(major=self.version.major, - minor=self.version.minor), - length=len(self.fragment), - fragment=self.fragment - ) - ) - - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``TLSPlaintext`` struct. - - :param bytes: the bytes representing the input. - :return: TLSPlaintext object. - """ - construct = _constructs.TLSPlaintext.parse(bytes) - return cls( - type=ContentType(construct.type), - version=ProtocolVersion( - major=construct.version.major, - minor=construct.version.minor - ), - fragment=construct.fragment - ) - - -@attributes(['type', 'version', 'fragment']) -class TLSCompressed(object): - """ - An object representing a TLSCompressed struct. - """ - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``TLSCompressed`` struct. - - :param bytes: the bytes representing the input. - :return: TLSCompressed object. - """ - construct = _constructs.TLSCompressed.parse(bytes) - return cls( - type=ContentType(construct.type), - version=ProtocolVersion( - major=construct.version.major, - minor=construct.version.minor - ), - fragment=construct.fragment - ) - - -@attributes(['type', 'version', 'fragment']) -class TLSCiphertext(object): - """ - An object representing a TLSCiphertext struct. - """ - @classmethod - def from_bytes(cls, bytes): - """ - Parse a ``TLSCiphertext`` struct. - - :param bytes: the bytes representing the input. - :return: TLSCiphertext object. - """ - construct = _constructs.TLSCiphertext.parse(bytes) - return cls( - type=ContentType(construct.type), - version=ProtocolVersion( - major=construct.version.major, - minor=construct.version.minor - ), - fragment=construct.fragment - ) - - -class ContentType(Enum): - CHANGE_CIPHER_SPEC = 20 - ALERT = 21 - HANDSHAKE = 22 - APPLICATION_DATA = 23 diff --git a/libmproxy/contrib/tls/utils.py b/libmproxy/contrib/tls/utils.py index a971af49..4c917303 100644 --- a/libmproxy/contrib/tls/utils.py +++ b/libmproxy/contrib/tls/utils.py @@ -24,29 +24,3 @@ class _UBInt24(construct.Adapter): def UBInt24(name): # noqa return _UBInt24(construct.Bytes(name, 3)) - - -def LengthPrefixedArray(subcon, length_field=construct.UBInt8("length")): - """ - An array prefixed by a byte length field. - - In contrast to construct.macros.PrefixedArray, - the length field signifies the number of bytes, not the number of elements. - """ - subcon_with_pos = construct.Struct( - subcon.name, - construct.Embed(subcon), - construct.Anchor("__current_pos") - ) - - return construct.Embed( - construct.Struct( - "", - length_field, - construct.Anchor("__start_pos"), - construct.RepeatUntil( - lambda obj, ctx: obj.__current_pos == ctx.__start_pos + getattr(ctx, length_field.name), - subcon_with_pos - ), - ) - ) \ No newline at end of file diff --git a/libmproxy/protocol2/tls.py b/libmproxy/protocol2/tls.py index 7ef0ad8c..9c8aeb24 100644 --- a/libmproxy/protocol2/tls.py +++ b/libmproxy/protocol2/tls.py @@ -61,7 +61,12 @@ class TlsLayer(Layer): layer() def _get_client_hello(self): - # Read all records that contain the initial Client Hello message. + """ + Peek into the socket and read all records that contain the initial client hello message. + + Returns: + The raw handshake packet bytes, without TLS record header(s). + """ client_hello = "" client_hello_size = 1 offset = 0 @@ -75,10 +80,15 @@ class TlsLayer(Layer): return client_hello def _parse_client_hello(self): + """ + Peek into the connection, read the initial client hello and parse it to obtain ALPN values. + """ + raw_client_hello = self._get_client_hello()[4:] # exclude handshake header. try: - client_hello = ClientHello.parse(self._get_client_hello()[4:]) + client_hello = ClientHello.parse(raw_client_hello) except ConstructError as e: self.log("Cannot parse Client Hello: %s" % repr(e), "error") + self.log("Raw Client Hello:\r\n:%s" % raw_client_hello.encode("hex"), "debug") return for extension in client_hello.extensions: -- cgit v1.2.3