def get_client_key_exchange_record(cls, robot_payload_enum, tls_version, modulus, exponent): """A client key exchange record with a hardcoded pre_master_secret, and a valid or invalid padding. """ # type: (RobotPmsPaddingPayloadEnum, TlsVersionEnum, int, int) -> TlsRsaClientKeyExchangeRecord pms_padding = cls._compute_pms_padding(modulus) tls_version_hex = binascii.b2a_hex(TlsRecordTlsVersionBytes[tls_version.name].value).decode('ascii') pms_with_padding_payload = cls._CKE_PAYLOADS_HEX[robot_payload_enum] final_pms = pms_with_padding_payload.format(pms_padding=pms_padding, tls_version=tls_version_hex, pms=cls._PMS_HEX) cke_robot_record = TlsRsaClientKeyExchangeRecord.from_parameters( tls_version, exponent, modulus, int(final_pms, 16) ) return cke_robot_record
def test_rsa_client_key_exchange_to_bytes(self): # Inspired by https://github.com/robotattackorg/robot-detect modulus = int(self.MODULUS_HEX, 16) exponent = int(self.EXPONENT_HEX, 16) modulus_bit_size = int(math.ceil(math.log(modulus, 2))) modulus_byte_size = (modulus_bit_size + 7) // 8 pre_master_secret = "aa112233445566778899112233445566778899112233445566778899112233445566778899112233445566778899" # Generate padding - it should be of the form "00 02 <random> 00 <TLS version> <premaster secret> tls_version_hex = binascii.b2a_hex(TlsRecordTlsVersionBytes[ TlsVersionEnum.TLSV1_2.name].value).decode('ascii') pad_len = (modulus_byte_size - 48 - 3) * 2 rnd_pad = ("abcd" * (pad_len // 2 + 1))[:pad_len] pms_with_padding = int( "0002" + rnd_pad + "00" + tls_version_hex + pre_master_secret, 16) record = TlsRsaClientKeyExchangeRecord.from_parameters( TlsVersionEnum.TLSV1_2, exponent, modulus, pms_with_padding) self.assertEqual(record.to_bytes(), self.EXPECTED_CLIENT_KEY_EXCHANGE_BYTES)