Exemplo n.º 1
0
    def parse_args(self,
                   server="127.0.0.1",
                   dport=4433,
                   server_name=None,
                   mycert=None,
                   mykey=None,
                   client_hello=None,
                   version=None,
                   data=None,
                   **kargs):

        super(TLSClientAutomaton, self).parse_args(mycert=mycert,
                                                   mykey=mykey,
                                                   **kargs)
        tmp = socket.getaddrinfo(server, dport)
        self.remote_name = None
        try:
            if ':' in server:
                inet_pton(socket.AF_INET6, server)
            else:
                inet_pton(socket.AF_INET, server)
        except Exception:
            self.remote_name = socket.getfqdn(server)
            if self.remote_name != server:
                tmp = socket.getaddrinfo(self.remote_name, dport)

        if server_name:
            self.remote_name = server_name
        self.remote_family = tmp[0][0]
        self.remote_ip = tmp[0][4][0]
        self.remote_port = dport
        self.local_ip = None
        self.local_port = None
        self.socket = None

        self.client_hello = client_hello
        self.advertised_tls_version = None
        if version:
            v = _tls_version_options.get(version, None)
            if not v:
                self.vprint("Unrecognized TLS version option.")
            else:
                self.advertised_tls_version = v

        self.linebreak = False
        if isinstance(data, bytes):
            self.data_to_send = [data]
        elif isinstance(data, six.string_types):
            self.data_to_send = [bytes_encode(data)]
        elif isinstance(data, list):
            self.data_to_send = list(bytes_encode(d) for d in reversed(data))
        else:
            self.data_to_send = []
Exemplo n.º 2
0
def _tls_P_hash(secret, seed, req_len, hm):
    """
    Provides the implementation of P_hash function defined in
    section 5 of RFC 4346 (and section 5 of RFC 5246). Two
    parameters have been added (hm and req_len):

    - secret : the key to be used. If RFC 4868 is to be believed,
               the length must match hm.key_len. Actually,
               python hmac takes care of formatting every key.
    - seed : the seed to be used.
    - req_len : the length of data to be generated by iterating
               the specific HMAC function (hm). This prevents
               multiple calls to the function.
    - hm : the hmac function class to use for iteration (either
           Hmac_MD5 or Hmac_SHA1 in TLS <= 1.1 or
           Hmac_SHA256 or Hmac_SHA384 in TLS 1.2)
    """
    hash_len = hm.hash_alg.hash_len
    n = (req_len + hash_len - 1) // hash_len
    seed = bytes_encode(seed)

    res = b""
    a = hm(secret).digest(seed)  # A(1)

    while n > 0:
        res += hm(secret).digest(a + seed)
        a = hm(secret).digest(a)
        n -= 1

    return res[:req_len]
Exemplo n.º 3
0
 def pcom_binary_checksum(command):
     n = 0
     command = bytes_encode(command)
     for _, c in enumerate(command):
         c = c if isinstance(c, int) else ord(c)  # python 2 fallback
         n += c
     if n == 0:
         return [0x00, 0x00]
     else:
         two_complement = hex(0x10000 - (n % 0x10000))[2:].zfill(4)
         return [int(two_complement[:2], 16), int(two_complement[2:], 16)]
Exemplo n.º 4
0
 def enc(cls, oid):
     oid = bytes_encode(oid)
     if oid:
         lst = [int(x) for x in oid.strip(b".").split(b".")]
     else:
         lst = list()
     if len(lst) >= 2:
         lst[1] += 40 * lst[0]
         del(lst[0])
     s = b"".join(BER_num_enc(k) for k in lst)
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemplo n.º 5
0
 def i2m(self, pkt, val):
     if not isinstance(val, bytes):
         val = bytes_encode(val)
     ret_string = b""
     for i in range(0, len(val), 2):
         tmp = val[i:i + 2]
         if len(tmp) == 2:
             ret_string += chb(int(tmp[::-1], 16))
         else:
             ret_string += chb(int(b"F" + tmp[:1], 16))
     return ret_string
Exemplo n.º 6
0
def inet_ntop(af, addr):
    """Convert an IP address from binary form into text representation."""
    # Use inet_ntop if available
    addr = bytes_encode(addr)
    try:
        return socket.inet_ntop(af, addr)
    except AttributeError:
        try:
            return _INET_NTOP[af](addr)
        except KeyError:
            raise ValueError("unknown address family %d" % af)
Exemplo n.º 7
0
 def sign(self, M, t="pkcs", h="sha256", mgf=None, L=None):
     M = bytes_encode(M)
     mgf = mgf or padding.MGF1
     h = _get_hash(h)
     pad = _get_padding(t, mgf, h, L)
     try:
         return self.key.sign(M, pad, h)
     except UnsupportedAlgorithm:
         if t != "pkcs" and h != "md5-sha1":
             raise UnsupportedAlgorithm("RSA signature with %s" % h)
         return self._legacy_sign_md5_sha1(M)
Exemplo n.º 8
0
 def enc(cls, s):
     # /!\ this is DER encoding (bit strings are only zero-bit padded)
     s = bytes_encode(s)
     if len(s) % 8 == 0:
         unused_bits = 0
     else:
         unused_bits = 8 - len(s) % 8
         s += b"0" * unused_bits
     s = b"".join(chb(int(b"".join(chb(y) for y in x), 2))
                  for x in zip(*[iter(s)] * 8))
     s = chb(unused_bits) + s
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemplo n.º 9
0
 def i2m(self, pkt, s):
     ret_s = b""
     for text in s:
         text = bytes_encode(text)
         # The initial string must be split into a list of strings
         # prepended with theirs sizes.
         while len(text) >= 255:
             ret_s += b"\xff" + text[:255]
             text = text[255:]
         # The remaining string is less than 255 bytes long
         if len(text):
             ret_s += struct.pack("!B", len(text)) + text
     return ret_s
Exemplo n.º 10
0
    def i2m(self, pkt, x):
        if isinstance(x, str):
            return x
        s = b""
        for o in x:
            if isinstance(o, tuple) and len(o) >= 2:
                name = o[0]
                lval = o[1:]

                if isinstance(name, int):
                    onum, oval = name, b"".join(lval)
                elif name in DHCPRevOptions:
                    onum, f = DHCPRevOptions[name]
                    if f is not None:
                        lval = (f.addfield(pkt, b"", f.any2i(pkt, val))
                                for val in lval)  # noqa: E501
                    else:
                        lval = (bytes_encode(x) for x in lval)
                    oval = b"".join(lval)
                else:
                    warning("Unknown field option %s", name)
                    continue

                s += chb(onum)
                s += chb(len(oval))
                s += oval

            elif (isinstance(o, str) and o in DHCPRevOptions
                  and DHCPRevOptions[o][1] is None):
                s += chb(DHCPRevOptions[o][0])
            elif isinstance(o, int):
                s += chb(o) + b"\0"
            elif isinstance(o, (str, bytes)):
                s += bytes_encode(o)
            else:
                warning("Malformed option %s", o)
        return s
Exemplo n.º 11
0
 def verify(self, M, S, t="pkcs", h="sha256", mgf=None, L=None):
     M = bytes_encode(M)
     mgf = mgf or padding.MGF1
     h = _get_hash(h)
     pad = _get_padding(t, mgf, h, L)
     try:
         try:
             self.pubkey.verify(S, M, pad, h)
         except UnsupportedAlgorithm:
             if t != "pkcs" and h != "md5-sha1":
                 raise UnsupportedAlgorithm("RSA verification with %s" % h)
             self._legacy_verify_md5_sha1(M, S)
         return True
     except InvalidSignature:
         return False
Exemplo n.º 12
0
def _legacy_pkcs1_v1_5_encode_md5_sha1(M, emLen):
    """
    Legacy method for PKCS1 v1.5 encoding with MD5-SHA1 hash.
    """
    M = bytes_encode(M)
    md5_hash = hashes.Hash(_get_hash("md5"), backend=default_backend())
    md5_hash.update(M)
    sha1_hash = hashes.Hash(_get_hash("sha1"), backend=default_backend())
    sha1_hash.update(M)
    H = md5_hash.finalize() + sha1_hash.finalize()
    if emLen < 36 + 11:
        warning("pkcs_emsa_pkcs1_v1_5_encode: "
                "intended encoded message length too short")
        return None
    PS = b'\xff' * (emLen - 36 - 3)
    return b'\x00' + b'\x01' + PS + b'\x00' + H
Exemplo n.º 13
0
 def _legacy_sign_md5_sha1(self, M):
     M = bytes_encode(M)
     k = self._modulusLen // 8
     EM = _legacy_pkcs1_v1_5_encode_md5_sha1(M, k)
     if EM is None:
         warning("Key._rsassa_pkcs1_v1_5_sign(): unable to encode")
         return None
     m = pkcs_os2ip(EM)
     n = self._modulus
     if isinstance(m, int) and six.PY2:
         m = long(m)  # noqa: F821
     if (six.PY2 and not isinstance(m, long)) or m > n - 1:  # noqa: F821
         warning("Key._rsaep() expects a long between 0 and n-1")
         return None
     privExp = self.key.private_numbers().d
     s = pow(m, privExp, n)
     return pkcs_i2osp(s, k)
Exemplo n.º 14
0
    def __call__(cls, obj_path, obj_max_size, pem_marker=None):
        # This enables transparent DER and PEM-encoded data imports.
        # Note that when importing a PEM file with multiple objects (like ECDSA
        # private keys output by openssl), it will concatenate every object in
        # order to create a 'der' attribute. When converting a 'multi' DER file
        # into a PEM file, though, the PEM attribute will not be valid,
        # because we do not try to identify the class of each object.
        error_msg = "Unable to import data"

        if obj_path is None:
            raise Exception(error_msg)
        obj_path = bytes_encode(obj_path)

        if (b'\x00' not in obj_path) and os.path.isfile(obj_path):
            _size = os.path.getsize(obj_path)
            if _size > obj_max_size:
                raise Exception(error_msg)
            try:
                f = open(obj_path, "rb")
                _raw = f.read()
                f.close()
            except Exception:
                raise Exception(error_msg)
        else:
            _raw = obj_path

        try:
            if b"-----BEGIN" in _raw:
                frmt = "PEM"
                pem = _raw
                der_list = split_pem(_raw)
                der = b''.join(map(pem2der, der_list))
            else:
                frmt = "DER"
                der = _raw
                pem = ""
                if pem_marker is not None:
                    pem = der2pem(_raw, pem_marker)
                # type identification may be needed for pem_marker
                # in such case, the pem attribute has to be updated
        except Exception:
            raise Exception(error_msg)

        p = _PKIObj(frmt, der, pem)
        return p
Exemplo n.º 15
0
 def open(self):
     """Open the TUN or TAP device."""
     if not self.closed:
         return
     self.outs = self.ins = open(
         "/dev/net/tun" if LINUX else ("/dev/%s" % self.iface), "r+b",
         buffering=0
     )
     if LINUX:
         from fcntl import ioctl
         # TUNSETIFF = 0x400454ca
         # IFF_TUN = 0x0001
         # IFF_TAP = 0x0002
         # IFF_NO_PI = 0x1000
         ioctl(self.ins, 0x400454ca, struct.pack(
             "16sH", bytes_encode(self.iface),
             0x0001 if self.mode_tun else 0x1002,
         ))
     self.closed = False
Exemplo n.º 16
0
 def __setattr__(self, name, value):
     # type: (str, Any) -> None
     if name == "val_readable":
         if isinstance(value, (str, bytes)):
             val = "".join(binrepr(orb(x)).zfill(8) for x in value)
         else:
             warning("Invalid val: should be bytes")
             val = "<invalid val_readable>"
         object.__setattr__(self, "val", val)
         object.__setattr__(self, name, bytes_encode(value))
         object.__setattr__(self, "unused_bits", 0)
     elif name == "val":
         value = plain_str(value)
         if isinstance(value, str):
             if any(c for c in value if c not in ["0", "1"]):
                 warning(
                     "Invalid operation: 'val' is not a valid bit string."
                 )  # noqa: E501
                 return
             else:
                 if len(value) % 8 == 0:
                     unused_bits = 0
                 else:
                     unused_bits = 8 - (len(value) % 8)
                 padded_value = value + ("0" * unused_bits)
                 bytes_arr = zip(*[iter(padded_value)] * 8)
                 val_readable = b"".join(
                     chb(int("".join(x), 2))
                     for x in bytes_arr)  # noqa: E501
         else:
             warning("Invalid val: should be str")
             val_readable = b"<invalid val>"
             unused_bits = 0
         object.__setattr__(self, "val_readable", val_readable)
         object.__setattr__(self, name, value)
         object.__setattr__(self, "unused_bits", unused_bits)
     elif name == "unused_bits":
         warning("Invalid operation: unused_bits rewriting "
                 "is not supported.")
     else:
         object.__setattr__(self, name, value)
Exemplo n.º 17
0
 def __setattr__(self, name, value):
     if isinstance(value, str):
         value = bytes_encode(value)
     if name == "val_readable":
         if isinstance(value, bytes):
             val = b"".join(
                 binrepr(orb(x)).zfill(8).encode("utf8")
                 for x in value)  # noqa: E501
         else:
             val = "<invalid val_readable>"
         super(ASN1_Object, self).__setattr__("val", val)
         super(ASN1_Object, self).__setattr__(name, value)
         super(ASN1_Object, self).__setattr__("unused_bits", 0)
     elif name == "val":
         if isinstance(value, bytes):
             if any(True for x in range(len(value))
                    if value[x:x + 1] not in [b"0", b"1"]):
                 print("Invalid operation: 'val' is not a valid bit string."
                       )  # noqa: E501
                 return
             else:
                 if len(value) % 8 == 0:
                     unused_bits = 0
                 else:
                     unused_bits = 8 - (len(value) % 8)
                 padded_value = value + (b"0" * unused_bits)
                 bytes_arr = zip(*[(padded_value[i:i + 1]
                                    for i in range(len(padded_value)))] * 8)
                 val_readable = b"".join(
                     chb(int(b"".join(x), 2)) for x in bytes_arr)
         else:
             val_readable = "<invalid val>"
             unused_bits = 0
         super(ASN1_Object, self).__setattr__("val_readable", val_readable)
         super(ASN1_Object, self).__setattr__(name, value)
         super(ASN1_Object, self).__setattr__("unused_bits", unused_bits)
     elif name == "unused_bits":
         print("Invalid operation: unused_bits rewriting is not supported.")
     else:
         super(ASN1_Object, self).__setattr__(name, value)
Exemplo n.º 18
0
 def i2m(self, pkt, s):
     if pkt.type == 1:  # A
         if s:
             s = inet_pton(socket.AF_INET, s)
     elif pkt.type in [2, 3, 4, 5, 12]:  # NS, MD, MF, CNAME, PTR
         s = DNSStrField("", "").i2m(None, s)
     elif pkt.type == 16:  # TXT
         ret_s = b""
         for text in s:
             text = bytes_encode(text)
             # The initial string must be split into a list of strings
             # prepended with theirs sizes.
             while len(text) >= 255:
                 ret_s += b"\xff" + text[:255]
                 text = text[255:]
             # The remaining string is less than 255 bytes long
             if len(text):
                 ret_s += struct.pack("!B", len(text)) + text
         s = ret_s
     elif pkt.type == 28:  # AAAA
         if s:
             s = inet_pton(socket.AF_INET6, s)
     return s
Exemplo n.º 19
0
def _header_line(name, val):
    """Creates a HTTP header line"""
    # Python 3.4 doesn't support % on bytes
    return bytes_encode(name) + b": " + bytes_encode(val)
Exemplo n.º 20
0
    def __init__(self,
                 iface=None,
                 mode_tun=None,
                 default_read_size=MTU,
                 strip_packet_info=True,
                 *args,
                 **kwargs):
        self.iface = bytes_encode(conf.iface if iface is None else iface)

        self.mode_tun = mode_tun
        if self.mode_tun is None:
            if self.iface.startswith(b"tun"):
                self.mode_tun = True
            elif self.iface.startswith(b"tap"):
                self.mode_tun = False
            else:
                raise ValueError(
                    "Could not determine interface type for %r; set "
                    "`mode_tun` explicitly." % (self.iface, ))

        self.strip_packet_info = bool(strip_packet_info)

        # This is non-zero when there is some kernel-specific packet info.
        # We add this to any MTU value passed to recv(), and use it to
        # remove leading bytes when strip_packet_info=True.
        self.mtu_overhead = 0

        # The TUN packet specification sends raw IP at us, and doesn't specify
        # which version.
        self.kernel_packet_class = IPv46 if self.mode_tun else Ether

        if LINUX:
            devname = b"/dev/net/tun"

            # Having an EtherType always helps on Linux, then we don't need
            # to use auto-detection of IP version.
            if self.mode_tun:
                self.kernel_packet_class = LinuxTunPacketInfo
                self.mtu_overhead = 4  # len(LinuxTunPacketInfo)
            else:
                warning("tap devices on Linux do not include packet info!")
                self.strip_packet_info = True

            if len(self.iface) > LINUX_IFNAMSIZ:
                warning("Linux interface names are limited to %d bytes, "
                        "truncating!" % (LINUX_IFNAMSIZ, ))
                self.iface = self.iface[:LINUX_IFNAMSIZ]

        elif BSD:  # also DARWIN
            if not (self.iface.startswith(b"tap")
                    or self.iface.startswith(b"tun")):
                raise ValueError("Interface names must start with `tun` or "
                                 "`tap` on BSD and Darwin")
            devname = b"/dev/" + self.iface
            if not self.strip_packet_info:
                warning("tun/tap devices on BSD and Darwin never include "
                        "packet info!")
                self.strip_packet_info = True
        else:
            raise NotImplementedError("TunTapInterface is not supported on "
                                      "this platform!")

        sock = open(devname, "r+b", buffering=0)

        if LINUX:
            if self.mode_tun:
                flags = LINUX_IFF_TUN
            else:
                # Linux can send us LinuxTunPacketInfo for TAP interfaces, but
                # the kernel sends the wrong information!
                #
                # Instead of type=1 (Ether), it sends that of the payload
                # (eg: 0x800 for IPv4 or 0x86dd for IPv6).
                #
                # tap interfaces always send Ether frames, which include a
                # type parameter for the IPv4/v6/etc. payload, so we set
                # IFF_NO_PI.
                flags = LINUX_IFF_TAP | LINUX_IFF_NO_PI

            tsetiff = raw(
                LinuxTunIfReq(ifrn_name=bytes_encode(self.iface),
                              ifru_flags=flags))

            ioctl(sock, LINUX_TUNSETIFF, tsetiff)

        self.closed = False
        self.default_read_size = default_read_size
        super(TunTapInterface, self).__init__(sock)
Exemplo n.º 21
0
    def parse_args(self,
                   server="127.0.0.1",
                   dport=4433,
                   server_name=None,
                   mycert=None,
                   mykey=None,
                   client_hello=None,
                   version=None,
                   data=None,
                   ciphersuite=None,
                   curve=None,
                   **kargs):

        super(TLSClientAutomaton, self).parse_args(mycert=mycert,
                                                   mykey=mykey,
                                                   **kargs)
        tmp = socket.getaddrinfo(server, dport)
        self.remote_name = None
        try:
            if ':' in server:
                inet_pton(socket.AF_INET6, server)
            else:
                inet_pton(socket.AF_INET, server)
        except Exception:
            self.remote_name = socket.getfqdn(server)
            if self.remote_name != server:
                tmp = socket.getaddrinfo(self.remote_name, dport)

        if server_name:
            self.remote_name = server_name
        self.remote_family = tmp[0][0]
        self.remote_ip = tmp[0][4][0]
        self.remote_port = dport
        self.local_ip = None
        self.local_port = None
        self.socket = None

        if (isinstance(client_hello, TLSClientHello)
                or isinstance(client_hello, TLS13ClientHello)):
            self.client_hello = client_hello
        else:
            self.client_hello = None
        self.advertised_tls_version = None
        if version:
            v = _tls_version_options.get(version, None)
            if not v:
                self.vprint("Unrecognized TLS version option.")
            else:
                self.advertised_tls_version = v

        self.linebreak = False
        if isinstance(data, bytes):
            self.data_to_send = [data]
        elif isinstance(data, six.string_types):
            self.data_to_send = [bytes_encode(data)]
        elif isinstance(data, list):
            self.data_to_send = list(bytes_encode(d) for d in reversed(data))
        else:
            self.data_to_send = []
        self.curve = None

        if self.advertised_tls_version == 0x0304:
            self.ciphersuite = 0x1301
            if ciphersuite is not None:
                cs = int(ciphersuite, 16)
                if cs in _tls_cipher_suites.keys():
                    self.ciphersuite = cs
            if conf.crypto_valid_advanced:
                # Default to x25519 if supported
                self.curve = 29
            else:
                # Or secp256r1 otherwise
                self.curve = 23
            if curve is not None:
                for (group_id, ng) in _tls_named_groups.items():
                    if ng == curve:
                        if curve == "x25519":
                            if conf.crypto_valid_advanced:
                                self.curve = group_id
                        else:
                            self.curve = group_id
Exemplo n.º 22
0
 def i2m(self, pkt, s):
     if not isinstance(s, bytes):
         s = bytes_encode(s)
     s = b"".join(chb(len(x)) + x for x in s.split(b"."))
     return s
Exemplo n.º 23
0
 def __init__(self, key=None):
     if key is None:
         self.key = b""
     else:
         self.key = bytes_encode(key)
Exemplo n.º 24
0
 def enc(cls, s):
     s = bytes_encode(s)
     # Be sure we are encoding bytes
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s
Exemplo n.º 25
0
 def pcom_ascii_checksum(command):
     n = 0
     command = bytes_encode(command)
     for _, c in enumerate(command):
         n += orb(c)
     return list(map(ord, hex(n % 256)[2:].zfill(2).upper()))
Exemplo n.º 26
0
 def __bytes__(self):
     return bytes_encode(self._fix())
Exemplo n.º 27
0
 def i2m(self, pkt, x):
     if x is None:
         return b""
     return bytes_encode(x)
Exemplo n.º 28
0
 def digest(self, tbd):
     if self.key is None:
         raise HMACError
     tbd = bytes_encode(tbd)
     return hmac.new(self.key, tbd, self.hash_alg.hash_cls).digest()
Exemplo n.º 29
0
 def __init__(self, size, term):
     self.term = bytes_encode(term)
     super(RandTermString, self).__init__(size=size)
Exemplo n.º 30
0
 def enc(cls, _s):
     # type: (str) -> bytes
     s = bytes_encode(_s)
     # Be sure we are encoding bytes
     return chb(hash(cls.tag)) + BER_len_enc(len(s)) + s