def from_parameters(cls, tls_version: TlsVersionEnum, heartbeat_data: bytes) -> "TlsHeartbeatRequestRecord": message = TlsHeartbeatMessage(TlsHeartbeatTypeByte.REQUEST, heartbeat_data) record_header = TlsRecordHeader(TlsRecordTypeByte.HEARTBEAT, tls_version, message.size) return TlsHeartbeatRequestRecord(record_header, message)
def from_parameters(cls, tls_version, public_exponent, public_modulus, pre_master_secret_with_padding): # type: (TlsVersionEnum, int, int, int) -> TlsHandshakeRecord cke_bytes = b'' # Encrypt the pre_master_secret encrypted_pms = pow(pre_master_secret_with_padding, public_exponent, public_modulus) # Add it to the message but pad it so that its length is the same as the length of the modulus modulus_length = len(int_to_bytes(public_modulus)) encrypted_pms_bytes = int_to_bytes(encrypted_pms, expected_length=modulus_length) # Per RFC 5246: the RSA-encrypted PreMasterSecret in a ClientKeyExchange is preceded by two length bytes # These bytes are redundant in the case of RSA because the EncryptedPreMasterSecret is the only data in the # ClientKeyExchange msg_size = struct.pack( '!I', len(encrypted_pms_bytes))[2:4] # Length is two bytes cke_bytes += msg_size cke_bytes += encrypted_pms_bytes msg = TlsHandshakeMessage(TlsHandshakeTypeByte.CLIENT_KEY_EXCHANGE, cke_bytes) # Build the header header = TlsRecordHeader(TlsRecordTypeByte.HANDSHAKE, tls_version, len(msg.to_bytes())) return TlsRsaClientKeyExchangeRecord(header, [msg])
def from_parameters(cls, tls_version: TlsVersionEnum, alert_severity: TlsAlertSeverityByte, alert_description: int) -> "TlsAlertRecord": alert_message = TlsAlertMessage(alert_severity, alert_description) record_header = TlsRecordHeader(TlsRecordTypeByte.ALERT, tls_version, alert_message.size) return TlsAlertRecord(record_header, alert_message)
def from_bytes(cls, raw_bytes): # type: (bytes) -> Tuple[TlsAlertRecord, int] header, len_consumed = TlsRecordHeader.from_bytes(raw_bytes) remaining_bytes = raw_bytes[len_consumed::] if header.type != TlsRecordTypeByte.ALERT: raise UnknownTypeByte() message, len_consumed_for_message = TlsAlertMessage.from_bytes(remaining_bytes) return TlsAlertRecord(header, message), len_consumed + len_consumed_for_message
def parse_bytes(raw_bytes: bytes) -> Tuple[TlsRecord, int]: record_header, len_consumed = TlsRecordHeader.from_bytes(raw_bytes) # Try to parse the record if record_header.type == TlsRecordTypeByte.HANDSHAKE: return TlsHandshakeRecord.from_bytes(raw_bytes) if record_header.type == TlsRecordTypeByte.ALERT: return TlsAlertRecord.from_bytes(raw_bytes) if record_header.type in TlsRecordTypeByte: # Valid record type but we don't have the code to parse it right now return TlsRecord.from_bytes(raw_bytes) # Unknown type raise UnknownTypeByte()
def from_bytes(cls, raw_bytes: bytes) -> Tuple["TlsHandshakeRecord", int]: header, len_consumed_for_header = TlsRecordHeader.from_bytes(raw_bytes) remaining_bytes = raw_bytes[len_consumed_for_header::] if header.type != TlsRecordTypeByte.HANDSHAKE: raise UnknownTypeByte() # Try to parse the handshake record - there may be multiple messages packed in the record messages = [] total_len_consumed_for_messages = 0 while total_len_consumed_for_messages != header.length: message, len_consumed_for_message = TlsHandshakeMessage.from_bytes(remaining_bytes) messages.append(message) total_len_consumed_for_messages += len_consumed_for_message remaining_bytes = remaining_bytes[len_consumed_for_message::] parsed_record = TlsHandshakeRecord(header, messages) return parsed_record, len_consumed_for_header + total_len_consumed_for_messages
def from_parameters(cls, tls_version): # type: (TlsVersionEnum) -> TlsChangeCipherSpecRecord ccs_message = TlsSubprotocolMessage(b'\x01') record_header = TlsRecordHeader(TlsRecordTypeByte.CHANGE_CIPHER_SPEC, tls_version, ccs_message.size) return TlsChangeCipherSpecRecord(record_header, [ccs_message])
def from_parameters(cls, tls_version: TlsVersionEnum, application_data: bytes) -> "TlsApplicationDataRecord": message = TlsApplicationDataMessage(application_data) record_header = TlsRecordHeader(TlsRecordTypeByte.APPLICATION_DATA, tls_version, message.size) return TlsApplicationDataRecord(record_header, message)
def to_record(submessage, kind=TlsRecordTypeByte.HANDSHAKE): length = len(submessage.to_bytes()) header = TlsRecordHeader(kind, TlsVersionEnum.TLSV1_2, length) return TlsRecord(header, [submessage])