def test__can_encrypt_and_decrypt_with_raw_bytes(self): self.write_secret() testdata = factory.make_bytes() token = fernet_encrypt_psk(testdata, raw=True) self.assertThat(token, IsInstance(bytes)) decrypted = fernet_decrypt_psk(token, raw=True) self.assertThat(decrypted, Equals(testdata))
def test__messages_from_up_to_a_minute_in_the_future_accepted(self): self.write_secret() testdata = factory.make_bytes() now = time.time() self.patch(time, "time").side_effect = [now + 60, now] token = fernet_encrypt_psk(testdata) fernet_decrypt_psk(token, ttl=1)
def create_beacon_payload(beacon_type, payload=None, version=PROTOCOL_VERSION): """Creates a beacon payload of the specified type, with the given data. :param beacon_type: The beacon packet type. Indicates the purpose of the beacon to the receiver. :param payload: Optional JSON-encodable dictionary. Will be converted to an inner encrypted payload and presented in the "data" field in the resulting dictionary. :param version: Optional protocol version to use (defaults to most recent). :return: BeaconPayload namedtuple representing the packet bytes, the outer payload, and the inner encrypted data (if any). """ beacon_type_code = BEACON_TYPES[beacon_type] if payload is not None: payload = payload.copy() payload["uuid"] = str(uuid.uuid1()) payload["type"] = beacon_type_code data_bytes = BSON.encode(payload) compressed_bytes = compress(data_bytes, compresslevel=9) payload_bytes = fernet_encrypt_psk(compressed_bytes, raw=True) else: payload_bytes = b'' beacon_bytes = struct.pack( BEACON_HEADER_FORMAT_V1 + "%ds" % len(payload_bytes), version, beacon_type_code, len(payload_bytes), payload_bytes) return BeaconPayload(beacon_bytes, version, BEACON_TYPE_VALUES[beacon_type_code], payload)
def test__raises_when_inner_encapsulation_is_not_bson(self): self.write_secret() payload = fernet_encrypt_psk(compress(b"\n\n"), raw=True) packet = _make_beacon_payload(payload=payload) with ExpectedException(InvalidBeaconingPacket, ".*beacon payload is not BSON.*"): read_beacon_payload(packet)
def test__raises_when_inner_encapsulation_does_not_decompress(self): self.write_secret() packet = _make_beacon_payload( payload=fernet_encrypt_psk('\n\n', raw=True)) with ExpectedException(InvalidBeaconingPacket, ".*Failed to decompress.*"): read_beacon_payload(packet)
def test__messages_from_future_exceeding_clock_skew_limit_rejected(self): self.write_secret() testdata = factory.make_bytes() now = time.time() self.patch(time, "time").side_effect = [now + 61, now] token = fernet_encrypt_psk(testdata) with ExpectedException(InvalidToken): fernet_decrypt_psk(token, ttl=1)
def test__can_encrypt_and_decrypt_string(self): self.write_secret() testdata = factory.make_string() token = fernet_encrypt_psk(testdata) # Round-trip this to a string, since Fernet tokens are used inside # strings (such as JSON objects) typically. token = token.decode("ascii") decrypted = fernet_decrypt_psk(token) decrypted = decrypted.decode("ascii") self.assertThat(decrypted, Equals(testdata))
def test__derives_identical_key_on_decrypt(self): self.write_secret() self.assertIsNone(security._fernet_psk) testdata = factory.make_bytes() token = fernet_encrypt_psk(testdata) first_key = security._fernet_psk # Make it seem like we're decrypting something without ever encrypting # anything first. security._fernet_psk = None decrypted = fernet_decrypt_psk(token) second_key = security._fernet_psk self.assertEqual(first_key, second_key) self.assertEqual(testdata, decrypted)
def test__assures_data_integrity(self): self.write_secret() testdata = factory.make_bytes(size=10) token = fernet_encrypt_psk(testdata) bad_token = bytearray(token) # Flip a bit in the token, so we can ensure it won't decrypt if it # has been corrupted. Subtract 4 to avoid the end of the token; that # portion is just padding, and isn't covered by the HMAC. byte_to_flip = randint(0, len(bad_token) - 4) bit_to_flip = 1 << randint(0, 7) bad_token[byte_to_flip] ^= bit_to_flip bad_token = bytes(bad_token) test_description = ("token=%s; token[%d] ^= 0x%02x" % ( token.decode("utf-8"), byte_to_flip, bit_to_flip)) with ExpectedException(InvalidToken, msg=test_description): fernet_decrypt_psk(bad_token)
def test__raises_when_no_secret_exists(self): testdata = factory.make_bytes() with ExpectedException(MissingSharedSecret): fernet_encrypt_psk(testdata) with ExpectedException(MissingSharedSecret): fernet_decrypt_psk(b"")
def test__can_encrypt_and_decrypt_bytes(self): self.write_secret() testdata = factory.make_bytes() token = fernet_encrypt_psk(testdata) decrypted = fernet_decrypt_psk(token) self.assertThat(decrypted, Equals(testdata))
def test__first_encrypt_caches_psk(self): self.write_secret() self.assertIsNone(security._fernet_psk) testdata = factory.make_string() fernet_encrypt_psk(testdata) self.assertIsNotNone(security._fernet_psk)