def build_client_hello(tls_version, cipher_suites, session_ticket=None): """ Build a ClientHello with the given TLS version, cipher suite, and optional session ticket. """ client_hello_record = None # Build TLS ClientHello if tls_version > 0x0002: extensions = None if session_ticket: extensions = [TLS_Ext_SessionTicket(ticket=session_ticket)] tls_client_hello = TLSClientHello(version=tls_version, gmt_unix_time=int(time.time()), random_bytes=randstring(28), sidlen=0, ciphers=cipher_suites, complen=1, ext=extensions) client_hello_record = TLS(msg=[tls_client_hello]) else: # SSLv2 ClientHello sslv2_client_hello = SSLv2ClientHello(version=tls_version, sidlen=0, ciphers=cipher_suites) client_hello_record = SSLv2(msg=[sslv2_client_hello]) return client_hello_record
def post_build(self, pkt, pay): """ Apply the previous methods according to the writing cipher type. """ # Compute the length of TLSPlaintext fragment hdr, frag = pkt[:5], pkt[5:] l = len(frag) hdr = hdr[:3] + struct.pack("!H", l) # Compression cfrag = self._tls_compress(frag) l = len(cfrag) # Update the length as a result of compression hdr = hdr[:3] + struct.pack("!H", l) cipher_type = self.tls_session.wcs.cipher.type if cipher_type == 'block': # Integrity mfrag = self._tls_hmac_add(hdr, cfrag) # Excerpt below better corresponds to TLS 1.1 IV definition, # but the result is the same as with TLS 1.2 anyway. # if self.version >= 0x0302: # l = self.tls_session.wcs.cipher.block_size # iv = randstring(l) # mfrag = iv + mfrag # Add padding pfrag = self._tls_pad(mfrag) # Encryption if self.version >= 0x0302: # Explicit IV for TLS 1.1 and 1.2 l = self.tls_session.wcs.cipher.block_size iv = randstring(l) self.tls_session.wcs.cipher.iv = iv efrag = self._tls_encrypt(pfrag) efrag = iv + efrag else: # Implicit IV for SSLv3 and TLS 1.0 efrag = self._tls_encrypt(pfrag) elif cipher_type == "stream": # Integrity mfrag = self._tls_hmac_add(hdr, cfrag) # Encryption efrag = self._tls_encrypt(mfrag) elif cipher_type == "aead": # Authenticated encryption (with nonce_explicit as header) efrag = self._tls_auth_encrypt(cfrag) if self.len is not None: # The user gave us a 'len', let's respect this ultimately hdr = hdr[:3] + struct.pack("!H", self.len) else: # Update header with the length of TLSCiphertext.fragment hdr = hdr[:3] + struct.pack("!H", len(efrag)) # Now we commit the pending write state if it has been triggered (e.g. # by an underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We # update nothing if the pwcs was not set. This probably means that # we're working out-of-context (and we need to keep the default wcs). if self.tls_session.triggered_pwcs_commit: if self.tls_session.pwcs is not None: self.tls_session.wcs = self.tls_session.pwcs self.tls_session.pwcs = None self.tls_session.triggered_pwcs_commit = False return hdr + efrag + pay
def post_build(self, pkt, pay): """ Apply the previous methods according to the writing cipher type. """ # Compute the length of TLSPlaintext fragment hdr, frag = pkt[:5], pkt[5:] l = len(frag) hdr = hdr[:3] + struct.pack("!H", l) # Compression cfrag = self._tls_compress(frag) l = len(cfrag) # Update the length as a result of compression hdr = hdr[:3] + struct.pack("!H", l) cipher_type = self.tls_session.wcs.cipher.type if cipher_type == 'block': # Integrity mfrag = self._tls_hmac_add(hdr, cfrag) # Excerpt below better corresponds to TLS 1.1 IV definition, # but the result is the same as with TLS 1.2 anyway. #if self.version >= 0x0302: # l = self.tls_session.wcs.cipher.block_size # iv = randstring(l) # mfrag = iv + mfrag # Add padding pfrag = self._tls_pad(mfrag) # Encryption if self.version >= 0x0302: # Explicit IV for TLS 1.1 and 1.2 l = self.tls_session.wcs.cipher.block_size iv = randstring(l) self.tls_session.wcs.cipher.iv = iv efrag = self._tls_encrypt(pfrag) efrag = iv + efrag else: # Implicit IV for SSLv3 and TLS 1.0 efrag = self._tls_encrypt(pfrag) elif cipher_type == "stream": # Integrity mfrag = self._tls_hmac_add(hdr, cfrag) # Encryption efrag = self._tls_encrypt(mfrag) elif cipher_type == "aead": # Authenticated encryption (with nonce_explicit as header) efrag = self._tls_auth_encrypt(cfrag) if self.len is not None: # The user gave us a 'len', let's respect this ultimately hdr = hdr[:3] + struct.pack("!H", self.len) else: # Update header with the length of TLSCiphertext.fragment hdr = hdr[:3] + struct.pack("!H", len(efrag)) # Now we commit the pending write state if it has been triggered (e.g. # by an underlying TLSChangeCipherSpec or a SSLv2ClientMasterKey). We # update nothing if the pwcs was not set. This probably means that # we're working out-of-context (and we need to keep the default wcs). if self.tls_session.triggered_pwcs_commit: if self.tls_session.pwcs is not None: self.tls_session.wcs = self.tls_session.pwcs self.tls_session.pwcs = None self.tls_session.triggered_pwcs_commit = False return hdr + efrag + pay