Пример #1
0
    def fill_missing(self):
        s = self.tls_session
        s.client_kx_privkey = _tls_named_groups_generate(
            s.client_kx_ecdh_params
        )
        # ecdh_Yc follows ECPoint.point format as defined in
        # https://tools.ietf.org/html/rfc8422#section-5.4
        pubkey = s.client_kx_privkey.public_key()
        if isinstance(pubkey, (x25519.X25519PublicKey,
                               x448.X448PublicKey)):
            self.ecdh_Yc = pubkey.public_bytes(
                serialization.Encoding.Raw,
                serialization.PublicFormat.Raw
            )
            if s.client_kx_privkey and s.server_kx_pubkey:
                pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
        else:
            # uncompressed format of an elliptic curve point
            x = pubkey.public_numbers().x
            y = pubkey.public_numbers().y
            self.ecdh_Yc = (b"\x04" +
                            pkcs_i2osp(x, pubkey.key_size // 8) +
                            pkcs_i2osp(y, pubkey.key_size // 8))
            if s.client_kx_privkey and s.server_kx_pubkey:
                pms = s.client_kx_privkey.exchange(ec.ECDH(),
                                                   s.server_kx_pubkey)

        if s.client_kx_privkey and s.server_kx_pubkey:
            s.pre_master_secret = pms
            if not s.extms or s.session_hash:
                s.compute_ms_and_derive_keys()
Пример #2
0
    def _tls_auth_encrypt(self, s):
        """
        Return the TLSCiphertext.encrypted_record for AEAD ciphers.
        """
        wcs = self.tls_session.wcs
        write_seq_num = struct.pack("!Q", wcs.seq_num)
        wcs.seq_num += 1
        add_data = (pkcs_i2osp(self.type, 1) + pkcs_i2osp(self.version, 2) +
                    pkcs_i2osp(len(s) + wcs.cipher.tag_len, 2))

        return wcs.cipher.auth_encrypt(s, add_data, write_seq_num)
Пример #3
0
 def _tls_auth_encrypt(self, s):
     """
     Return the TLSCiphertext.fragment for AEAD ciphers, i.e. the whole
     GenericAEADCipher. Also, the additional data is computed right here.
     """
     write_seq_num = struct.pack("!Q", self.tls_session.wcs.seq_num)
     self.tls_session.wcs.seq_num += 1
     add_data = (write_seq_num + pkcs_i2osp(self.type, 1) +
                 pkcs_i2osp(self.version, 2) + pkcs_i2osp(len(s), 2))
     return self.tls_session.wcs.cipher.auth_encrypt(
         s, add_data, write_seq_num)
Пример #4
0
 def _tls_auth_encrypt(self, s):
     """
     Return the TLSCiphertext.fragment for AEAD ciphers, i.e. the whole
     GenericAEADCipher. Also, the additional data is computed right here.
     """
     write_seq_num = struct.pack("!Q", self.tls_session.wcs.seq_num)
     self.tls_session.wcs.seq_num += 1
     add_data = (write_seq_num +
                 pkcs_i2osp(self.type, 1) +
                 pkcs_i2osp(self.version, 2) +
                 pkcs_i2osp(len(s), 2))
     return self.tls_session.wcs.cipher.auth_encrypt(s, add_data,
                                                     write_seq_num)
Пример #5
0
    def fill_missing(self):
        s = self.tls_session
        s.client_kx_privkey = _tls_named_groups_generate(
            s.client_kx_ecdh_params)
        pubkey = s.client_kx_privkey.public_key()
        x = pubkey.public_numbers().x
        y = pubkey.public_numbers().y
        self.ecdh_Yc = (b"\x04" + pkcs_i2osp(x, pubkey.key_size // 8) +
                        pkcs_i2osp(y, pubkey.key_size // 8))

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(ec.ECDH(), s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()
Пример #6
0
def encode_point(point, point_format=0):
    """
    Return a string representation of the Point p, according to point_format.
    """
    pLen = len(binrepr(point.curve().p()))
    x = pkcs_i2osp(point.x(), math.ceil(pLen / 8))
    y = pkcs_i2osp(point.y(), math.ceil(pLen / 8))
    if point_format == 0:
        frmt = '\x04'
    elif point_format == 1:
        frmt = chr(2 + y % 2)
        y = ''
    else:
        raise Exception("No support for point_format %d" % point_format)
    return frmt + x + y
Пример #7
0
def encode_point(point, point_format=0):
    """
    Return a string representation of the Point p, according to point_format.
    """
    pLen = len(binrepr(point.curve().p()))
    x = pkcs_i2osp(point.x(), math.ceil(pLen/8))
    y = pkcs_i2osp(point.y(), math.ceil(pLen/8))
    if point_format == 0:
        frmt = '\x04'
    elif point_format == 1:
        frmt = chr(2 + y%2)
        y = ''
    else:
        raise Exception("No support for point_format %d" % point_format)
    return frmt + x + y
Пример #8
0
    def fill_missing(self):
        s = self.tls_session
        params = s.client_kx_ecdh_params
        s.client_kx_privkey = ec.generate_private_key(params,
                                                      default_backend())
        pubkey = s.client_kx_privkey.public_key()
        x = pubkey.public_numbers().x
        y = pubkey.public_numbers().y
        self.ecdh_Yc = (b"\x04" + pkcs_i2osp(x, params.key_size / 8) +
                        pkcs_i2osp(y, params.key_size / 8))

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(ec.ECDH(), s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()
Пример #9
0
    def fill_missing(self):
        k = PrivKeyRSA()
        k.fill_and_store(modulusLen=512)
        self.tls_session.server_tmp_rsa_key = k
        pubNum = k.pubkey.public_numbers()

        if not self.rsamod:
            self.rsamod = pkcs_i2osp(pubNum.n, k.pubkey.key_size // 8)
        if self.rsamodlen is None:
            self.rsamodlen = len(self.rsamod)

        rsaexplen = math.ceil(math.log(pubNum.e) / math.log(2) / 8.)
        if not self.rsaexp:
            self.rsaexp = pkcs_i2osp(pubNum.e, rsaexplen)
        if self.rsaexplen is None:
            self.rsaexplen = len(self.rsaexp)
Пример #10
0
    def auth_encrypt(self, P, A, seq_num=None):
        """
        Encrypt the data then prepend the explicit part of the nonce. The
        authentication tag is directly appended with the most recent crypto
        API. Additional data may be authenticated without encryption (as A).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        """
        if False in six.itervalues(self.ready):
            raise CipherError(P, A)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce()
            self._cipher.mode._tag = None
            encryptor = self._cipher.encryptor()
            encryptor.authenticate_additional_data(A)
            res = encryptor.update(P) + encryptor.finalize()
            res += encryptor.tag
        else:
            if isinstance(self._cipher, AESCCM):
                res = self._cipher.encrypt(self._get_nonce(), P, A,
                                           tag_length=self.tag_len)
            else:
                res = self._cipher.encrypt(self._get_nonce(), P, A)

        nonce_explicit = pkcs_i2osp(self.nonce_explicit,
                                    self.nonce_explicit_len)
        self._update_nonce_explicit()
        return nonce_explicit + res
Пример #11
0
    def __init__(self, key=None, salt=None, nonce_explicit=None):
        """
        'key' and 'salt' are to be provided as strings, whereas the internal
        'nonce_explicit' is an integer (it is simpler for incrementation).
        """
        self.ready = {"key": True, "salt": True, "nonce_explicit": True}
        if key is None:
            self.ready["key"] = False
            key = b"\0" * self.key_len
        if salt is None:
            self.ready["salt"] = False
            salt = b"\0" * self.salt_len
        if nonce_explicit is None:
            self.ready["nonce_explicit"] = False
            nonce_explicit = 0

        if isinstance(nonce_explicit, str):
            nonce_explicit = pkcs_os2ip(nonce_explicit)

        # we use super() in order to avoid any deadlock with __setattr__
        super(_AEADCipher, self).__setattr__("key", key)
        super(_AEADCipher, self).__setattr__("salt", salt)
        super(_AEADCipher, self).__setattr__("nonce_explicit", nonce_explicit)

        iv = salt + pkcs_i2osp(nonce_explicit, self.nonce_explicit_len)
        self._cipher = Cipher(self.pc_cls(key),
                              self.pc_cls_mode(iv),
                              backend=default_backend())
Пример #12
0
    def fill_missing(self):
        k = PrivKeyRSA()
        k.fill_and_store(modulusLen=512)
        self.tls_session.server_tmp_rsa_key = k
        pubNum = k.pubkey.public_numbers()

        if not self.rsamod:
            self.rsamod = pkcs_i2osp(pubNum.n, k.pubkey.key_size // 8)
        if self.rsamodlen is None:
            self.rsamodlen = len(self.rsamod)

        rsaexplen = math.ceil(math.log(pubNum.e) / math.log(2) / 8.)
        if not self.rsaexp:
            self.rsaexp = pkcs_i2osp(pubNum.e, rsaexplen)
        if self.rsaexplen is None:
            self.rsaexplen = len(self.rsaexp)
Пример #13
0
    def auth_encrypt(self, P, A, seq_num=None):
        """
        Encrypt the data then prepend the explicit part of the nonce. The
        authentication tag is directly appended with the most recent crypto
        API. Additional data may be authenticated without encryption (as A).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        """
        if False in six.itervalues(self.ready):
            raise CipherError(P, A)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce()
            self._cipher.mode._tag = None
            encryptor = self._cipher.encryptor()
            encryptor.authenticate_additional_data(A)
            res = encryptor.update(P) + encryptor.finalize()
            res += encryptor.tag
        else:
            if isinstance(self._cipher, AESCCM):
                res = self._cipher.encrypt(self._get_nonce(),
                                           P,
                                           A,
                                           tag_length=self.tag_len)
            else:
                res = self._cipher.encrypt(self._get_nonce(), P, A)

        nonce_explicit = pkcs_i2osp(self.nonce_explicit,
                                    self.nonce_explicit_len)
        self._update_nonce_explicit()
        return nonce_explicit + res
Пример #14
0
    def fill_missing(self):
        s = self.tls_session
        params = s.client_kx_ecdh_params
        s.client_kx_privkey = ec.generate_private_key(params,
                                                      default_backend())
        pubkey = s.client_kx_privkey.public_key()
        x = pubkey.public_numbers().x
        y = pubkey.public_numbers().y
        self.ecdh_Yc = (b"\x04" +
                        pkcs_i2osp(x, params.key_size // 8) +
                        pkcs_i2osp(y, params.key_size // 8))

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(ec.ECDH(), s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()
Пример #15
0
 def post_build(self, pkt, pay):
     if not self.ecdh_Yc:
         try:
             self.fill_missing()
         except ImportError:
             pass
     if self.ecdh_Yclen is None:
         self.ecdh_Yclen = len(self.ecdh_Yc)
     return pkcs_i2osp(self.ecdh_Yclen, 1) + self.ecdh_Yc + pay
Пример #16
0
 def post_build(self, pkt, pay):
     if not self.ecdh_Yc:
         try:
             self.fill_missing()
         except ImportError:
             pass
     if self.ecdh_Yclen is None:
         self.ecdh_Yclen = len(self.ecdh_Yc)
     return pkcs_i2osp(self.ecdh_Yclen, 1) + self.ecdh_Yc + pay
Пример #17
0
 def __setattr__(self, name, val):
     if name == "key":
         if self._cipher is not None:
             self._cipher.algorithm.key = val
         self.ready["key"] = True
     elif name == "salt":
         iv = val + pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len)
         if self._cipher is not None:
             self._cipher.mode._initialization_vector = iv
         self.ready["salt"] = True
     elif name == "nonce_explicit":
         if isinstance(val, str):
             val = pkcs_os2ip(val)
         iv = self.salt + pkcs_i2osp(val, self.nonce_explicit_len)
         if self._cipher is not None:
             self._cipher.mode._initialization_vector = iv
         self.ready["nonce_explicit"] = True
     super(_AEADCipher, self).__setattr__(name, val)
Пример #18
0
    def post_build(self, pkt, pay):
        s = self.tls_session

        if self.dh_Yc == "":
            params = s.client_kx_ffdh_params
            s.client_kx_privkey = params.generate_private_key()
            pubkey = s.client_kx_privkey.public_key()
            y = pubkey.public_numbers().y
            self.dh_Yc = pkcs_i2osp(y, pubkey.key_size / 8)
        # else, we assume that the user wrote the client_kx_privkey by himself
        if self.dh_Yclen is None:
            self.dh_Yclen = len(self.dh_Yc)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()

        return pkcs_i2osp(self.dh_Yclen, 2) + self.dh_Yc + pay
Пример #19
0
    def post_build(self, pkt, pay):
        s = self.tls_session

        if self.dh_Yc == "":
            params = s.client_kx_ffdh_params
            s.client_kx_privkey = params.generate_private_key()
            pubkey = s.client_kx_privkey.public_key()
            y = pubkey.public_numbers().y
            self.dh_Yc = pkcs_i2osp(y, pubkey.key_size/8)
        # else, we assume that the user wrote the client_kx_privkey by himself
        if self.dh_Yclen is None:
            self.dh_Yclen = len(self.dh_Yc)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()

        return pkcs_i2osp(self.dh_Yclen, 2) + self.dh_Yc + pay
Пример #20
0
    def fill_missing(self):
        s = self.tls_session
        s.client_kx_privkey = s.client_kx_ffdh_params.generate_private_key()
        pubkey = s.client_kx_privkey.public_key()
        y = pubkey.public_numbers().y
        self.dh_Yc = pkcs_i2osp(y, pubkey.key_size // 8)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()
Пример #21
0
    def fill_missing(self):
        s = self.tls_session
        params = s.client_kx_ffdh_params
        s.client_kx_privkey = params.generate_private_key()
        pubkey = s.client_kx_privkey.public_key()
        y = pubkey.public_numbers().y
        self.dh_Yc = pkcs_i2osp(y, pubkey.key_size // 8)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()
Пример #22
0
    def fill_missing(self):
        ext_k = rsa.generate_private_key(public_exponent=0x10001,
                                         key_size=512,
                                         backend=default_backend())
        pem_k = ext_k.private_bytes(
                        encoding=serialization.Encoding.PEM,
                        format=serialization.PrivateFormat.TraditionalOpenSSL,
                        encryption_algorithm=serialization.NoEncryption())
        k = PrivKeyRSA(pem_k)
        self.tls_session.server_tmp_rsa_key = k
        pubNum = k.pubkey.public_numbers()

        if self.rsamod is "":
            self.rsamod = pkcs_i2osp(pubNum.n, k.pubkey.key_size/8)
        if self.rsamodlen is None:
            self.rsamodlen = len(self.rsamod)

        rsaexplen = math.ceil(math.log(pubNum.e)/math.log(2)/8.)
        if self.rsaexp is "":
            self.rsaexp = pkcs_i2osp(pubNum.e, rsaexplen)
        if self.rsaexplen is None:
            self.rsaexplen = len(self.rsaexp)
Пример #23
0
 def _tls_auth_decrypt(self, s):
     """
     Provided with the record header and AEAD-ciphered data, return the
     sliced and clear tuple (TLSInnerPlaintext, tag). Note that
     we still return the slicing of the original input in case of decryption
     failure. Also, if the integrity check fails, a warning will be issued,
     but we still return the sliced (unauthenticated) plaintext.
     """
     rcs = self.tls_session.rcs
     read_seq_num = struct.pack("!Q", rcs.seq_num)
     rcs.seq_num += 1
     add_data = (pkcs_i2osp(self.type, 1) + pkcs_i2osp(self.version, 2) +
                 pkcs_i2osp(len(s), 2))
     try:
         return rcs.cipher.auth_decrypt(add_data, s, read_seq_num)
     except CipherError as e:
         return e.args
     except AEADTagError as e:
         pkt_info = self.firstlayer().summary()
         log_runtime.info("TLS: record integrity check failed [%s]",
                          pkt_info)  # noqa: E501
         return e.args
Пример #24
0
    def fill_missing(self):
        ext_k = rsa.generate_private_key(public_exponent=0x10001,
                                         key_size=512,
                                         backend=default_backend())
        pem_k = ext_k.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption())
        k = PrivKeyRSA(pem_k)
        self.tls_session.server_tmp_rsa_key = k
        pubNum = k.pubkey.public_numbers()

        if self.rsamod is "":
            self.rsamod = pkcs_i2osp(pubNum.n, k.pubkey.key_size / 8)
        if self.rsamodlen is None:
            self.rsamodlen = len(self.rsamod)

        rsaexplen = math.ceil(math.log(pubNum.e) / math.log(2) / 8.)
        if self.rsaexp is "":
            self.rsaexp = pkcs_i2osp(pubNum.e, rsaexplen)
        if self.rsaexplen is None:
            self.rsaexplen = len(self.rsaexp)
Пример #25
0
    def post_build(self, pkt, pay):
        s = self.tls_session

        if self.ecdh_Yc == "":
            params = s.client_kx_ecdh_params
            s.client_kx_privkey = ec.generate_private_key(
                params, default_backend())
            pubkey = s.client_kx_privkey.public_key()
            x = pubkey.public_numbers().x
            y = pubkey.public_numbers().y
            self.ecdh_Yc = (b"\x04" + pkcs_i2osp(x, params.key_size / 8) +
                            pkcs_i2osp(y, params.key_size / 8))
        # else, we assume that the user wrote the client_kx_privkey by himself
        if self.ecdh_Yclen is None:
            self.ecdh_Yclen = len(self.ecdh_Yc)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(ec.ECDH(), s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()

        return pkcs_i2osp(self.ecdh_Yclen, 1) + self.ecdh_Yc + pay
Пример #26
0
    def fill_missing(self):
        """
        We do not want TLSServerKeyExchange.build() to overload and recompute
        things every time it is called. This method can be called specifically
        to have things filled in a smart fashion.

        Note that we do not expect default_params.g to be more than 0xff.
        """
        s = self.tls_session

        default_params = _ffdh_groups['modp2048'][0].parameter_numbers()
        default_mLen = _ffdh_groups['modp2048'][1]

        if not self.dh_p:
            self.dh_p = pkcs_i2osp(default_params.p, default_mLen // 8)
        if self.dh_plen is None:
            self.dh_plen = len(self.dh_p)

        if not self.dh_g:
            self.dh_g = pkcs_i2osp(default_params.g, 1)
        if self.dh_glen is None:
            self.dh_glen = 1

        p = pkcs_os2ip(self.dh_p)
        g = pkcs_os2ip(self.dh_g)
        real_params = dh.DHParameterNumbers(p, g).parameters(default_backend())

        if not self.dh_Ys:
            s.server_kx_privkey = real_params.generate_private_key()
            pubkey = s.server_kx_privkey.public_key()
            y = pubkey.public_numbers().y
            self.dh_Ys = pkcs_i2osp(y, pubkey.key_size // 8)
        # else, we assume that the user wrote the server_kx_privkey by himself
        if self.dh_Yslen is None:
            self.dh_Yslen = len(self.dh_Ys)

        if not s.client_kx_ffdh_params:
            s.client_kx_ffdh_params = real_params
Пример #27
0
    def fill_missing(self):
        """
        We do not want TLSServerKeyExchange.build() to overload and recompute
        things everytime it is called. This method can be called specifically
        to have things filled in a smart fashion.

        Note that we do not expect default_params.g to be more than 0xff.
        """
        s = self.tls_session

        default_params = _ffdh_groups['modp2048'][0].parameter_numbers()
        default_mLen = _ffdh_groups['modp2048'][1]

        if not self.dh_p:
            self.dh_p = pkcs_i2osp(default_params.p, default_mLen // 8)
        if self.dh_plen is None:
            self.dh_plen = len(self.dh_p)

        if not self.dh_g:
            self.dh_g = pkcs_i2osp(default_params.g, 1)
        if self.dh_glen is None:
            self.dh_glen = 1

        p = pkcs_os2ip(self.dh_p)
        g = pkcs_os2ip(self.dh_g)
        real_params = dh.DHParameterNumbers(p, g).parameters(default_backend())

        if not self.dh_Ys:
            s.server_kx_privkey = real_params.generate_private_key()
            pubkey = s.server_kx_privkey.public_key()
            y = pubkey.public_numbers().y
            self.dh_Ys = pkcs_i2osp(y, pubkey.key_size // 8)
        # else, we assume that the user wrote the server_kx_privkey by himself
        if self.dh_Yslen is None:
            self.dh_Yslen = len(self.dh_Ys)

        if not s.client_kx_ffdh_params:
            s.client_kx_ffdh_params = real_params
Пример #28
0
    def post_build(self, pkt, pay):
        s = self.tls_session

        if self.ecdh_Yc == "":
            params = s.client_kx_ecdh_params
            s.client_kx_privkey = ec.generate_private_key(params,
                                                          default_backend())
            pubkey = s.client_kx_privkey.public_key()
            x = pubkey.public_numbers().x
            y = pubkey.public_numbers().y
            self.ecdh_Yc = (b"\x04" +
                            pkcs_i2osp(x, params.key_size/8) +
                            pkcs_i2osp(y, params.key_size/8))
        # else, we assume that the user wrote the client_kx_privkey by himself
        if self.ecdh_Yclen is None:
            self.ecdh_Yclen = len(self.ecdh_Yc)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(ec.ECDH(), s.server_kx_pubkey)
            s.pre_master_secret = pms
            s.compute_ms_and_derive_keys()

        return pkcs_i2osp(self.ecdh_Yclen, 1) + self.ecdh_Yc + pay
Пример #29
0
    def fill_missing(self):
        s = self.tls_session
        s.client_kx_privkey = s.client_kx_ffdh_params.generate_private_key()
        pubkey = s.client_kx_privkey.public_key()
        y = pubkey.public_numbers().y
        self.dh_Yc = pkcs_i2osp(y, pubkey.key_size // 8)

        if s.client_kx_privkey and s.server_kx_pubkey:
            pms = s.client_kx_privkey.exchange(s.server_kx_pubkey)
            s.pre_master_secret = pms
            if not s.extms or s.session_hash:
                # If extms is set (extended master secret), the key will
                # need the session hash to be computed. This is provided
                # by the TLSClientKeyExchange. Same in all occurrences
                s.compute_ms_and_derive_keys()
Пример #30
0
    def auth_encrypt(self, P, A):
        """
        Encrypt the data, prepend the explicit part of the nonce,
        and append the computed authentication code.
        Additional data may be authenticated without encryption (as A).

        Note that the cipher's authentication tag must be None when encrypting.
        """
        if False in self.ready.itervalues():
            raise CipherError, (P, A)
        self._cipher.mode._tag = None
        encryptor = self._cipher.encryptor()
        encryptor.authenticate_additional_data(A)
        res = encryptor.update(P) + encryptor.finalize()
        res += encryptor.tag

        nonce_explicit = pkcs_i2osp(self.nonce_explicit,
                                    self.nonce_explicit_len)
        self._update_nonce()
        return nonce_explicit + res
Пример #31
0
 def _get_nonce(self):
     return (self.fixed_iv +
             pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len))
Пример #32
0
 def _get_nonce(self):
     return (self.fixed_iv +
             pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len))
Пример #33
0
    def decryptTLSStream(self):
        """
        Generator function that decrypts an RDP stream that uses TLS.
        """

        tpktParser = TPKTParser()
        tls = None
        clientRandom = None
        serverRandom = None
        currentTimeStamp = None
        reconstructingRecord = False
        savedRecord = None
        savedPayload = b""
        tlsKeyGenerated = False

        for packet in self.packets:
            ip = packet.getlayer(IP)
            tcp = packet.getlayer(TCP)

            if len(tcp.payload) == 0 or tcp.flags & TCPFlags.PSH == 0:
                continue

            currentTimeStamp = packet.time
            currentSrc = ip.src
            currentDst = ip.dst

            # The first couple messages don't use TLS. Check if it's one of those messages and output it as is.
            if hasattr(tcp, "load") and tpktParser.isTPKTPDU(tcp.load):
                yield PCAPStream.output(tcp.load, currentTimeStamp, ip.src,
                                        ip.dst)
                continue

            # Create the TLS session context.
            if not tls:
                tls = tlsSession(
                    ipsrc=ip.src,
                    ipdst=ip.dst,
                    sport=tcp.sport,
                    dport=tcp.dport,
                    connection_end="server",
                )

            if tls.ipsrc != ip.src:
                tls = tls.mirror()

            # Pass every TLS message through our own custom session so the state is kept properly
            record = packet[TLS]
            record = TLS(bytes(record), tls_session=tls)

            for msg in record.msg:
                if isinstance(msg, TLSClientHello):
                    clientRandom = pkcs_i2osp(msg.gmt_unix_time,
                                              4) + msg.random_bytes
                elif isinstance(msg, TLSServerHello):
                    serverRandom = pkcs_i2osp(msg.gmt_unix_time,
                                              4) + msg.random_bytes
                elif isinstance(msg, TLSNewSessionTicket):
                    # Session established, set master secret.
                    tls.rcs.derive_keys(
                        client_random=clientRandom,
                        server_random=serverRandom,
                        master_secret=self.masterSecret,
                    )

                    tls.wcs.derive_keys(
                        client_random=clientRandom,
                        server_random=serverRandom,
                        master_secret=self.masterSecret,
                    )

                    tlsKeyGenerated = True
                elif isinstance(msg, TLSApplicationData):
                    yield PCAPStream.output(msg.data, currentTimeStamp, ip.src,
                                            ip.dst)