def test_decrypt_argument_validation(): mock_client = mock.Mock() key = mock.Mock( spec=KeyVaultKey, id="https://localhost/fake/key/version", properties=mock.Mock(not_before=datetime(2000, 1, 1, tzinfo=_UTC), expires_on=datetime(3000, 1, 1, tzinfo=_UTC)), ) client = CryptographyClient(key, mock.Mock()) client._client = mock_client with pytest.raises(ValueError) as ex: client.decrypt(EncryptionAlgorithm.rsa_oaep, b"...", iv=b"...") assert "iv" in str(ex.value) with pytest.raises(ValueError) as ex: client.decrypt(EncryptionAlgorithm.rsa_oaep, b"...", additional_authenticated_data=b"...") assert "additional_authenticated_data" in str(ex.value) with pytest.raises(ValueError) as ex: client.decrypt(EncryptionAlgorithm.rsa_oaep, b"...", authentication_tag=b"...") assert "authentication_tag" in str(ex.value) with pytest.raises(ValueError) as ex: client.decrypt(EncryptionAlgorithm.a128_gcm, b"...", iv=b"...") assert "authentication_tag" in str(ex.value) and "required" in str( ex.value) with pytest.raises(ValueError) as ex: client.decrypt(EncryptionAlgorithm.a192_cbcpad, b"...") assert "iv" in str(ex.value) and "required" in str(ex.value)
def test_calls_service_for_operations_unsupported_locally(): """When an operation can't be performed locally, the client should request Key Vault perform it""" mock_client = mock.Mock() key = mock.Mock(spec=KeyVaultKey, id="https://localhost/fake/key/version") client = CryptographyClient(key, mock.Mock()) client._client = mock_client supports_nothing = mock.Mock(supports=mock.Mock(return_value=False)) with mock.patch( CryptographyClient.__module__ + ".get_local_cryptography_provider", lambda *_: supports_nothing): client.decrypt(EncryptionAlgorithm.rsa_oaep, b"...") assert mock_client.decrypt.call_count == 1 assert supports_nothing.decrypt.call_count == 0 client.encrypt(EncryptionAlgorithm.rsa_oaep, b"...") assert mock_client.encrypt.call_count == 1 assert supports_nothing.encrypt.call_count == 0 client.sign(SignatureAlgorithm.rs256, b"...") assert mock_client.sign.call_count == 1 assert supports_nothing.sign.call_count == 0 client.verify(SignatureAlgorithm.rs256, b"...", b"...") assert mock_client.verify.call_count == 1 assert supports_nothing.verify.call_count == 0 client.unwrap_key(KeyWrapAlgorithm.rsa_oaep, b"...") assert mock_client.unwrap_key.call_count == 1 assert supports_nothing.unwrap_key.call_count == 0 client.wrap_key(KeyWrapAlgorithm.rsa_oaep, b"...") assert mock_client.wrap_key.call_count == 1 assert supports_nothing.wrap_key.call_count == 0
def test_initialization_get_key_successful(): """If the client is able to get key material, it shouldn't do so again""" key_id = "https://localhost/fake/key/version" mock_key = mock.Mock() mock_key.key.kid = key_id mock_client = mock.Mock() mock_client.get_key.return_value = mock_key client = CryptographyClient(key_id, mock.Mock()) client._client = mock_client assert mock_client.get_key.call_count == 0 with mock.patch(CryptographyClient.__module__ + ".get_local_cryptography_provider") as get_provider: client.verify(SignatureAlgorithm.rs256, b"...", b"...") args, _ = get_provider.call_args assert len(args) == 1 and isinstance(args[0], JsonWebKey) and args[0].kid == key_id for _ in range(3): assert mock_client.get_key.call_count == 1 assert get_provider.call_count == 1 client.verify(SignatureAlgorithm.rs256, b"...", b"...")
def test_initialization_transient_failure_getting_key(): """If the client is not forbidden to get key material, it should retry after failing to do so""" mock_client = mock.Mock() mock_client.get_key.side_effect = HttpResponseError(response=mock.Mock(status_code=500)) client = CryptographyClient("https://localhost/fake/key/version", mock.Mock()) client._client = mock_client for i in range(3): assert mock_client.get_key.call_count == i client.verify(SignatureAlgorithm.rs256, b"...", b"...")
def test_initialization_forbidden_to_get_key(): """If the client is forbidden to get key material, it should try to do so exactly once""" mock_client = mock.Mock() mock_client.get_key.side_effect = HttpResponseError(response=mock.Mock(status_code=403)) client = CryptographyClient("https://localhost/fake/key/version", mock.Mock()) client._client = mock_client assert mock_client.get_key.call_count == 0 for _ in range(3): client.verify(SignatureAlgorithm.rs256, b"...", b"...") assert mock_client.get_key.call_count == 1
def test_initialization_given_key(): """If the client is given key material, it should not attempt to get this from the vault""" mock_client = mock.Mock() key = mock.Mock(spec=KeyVaultKey, id="https://localhost/fake/key/version") client = CryptographyClient(key, mock.Mock()) client._client = mock_client with mock.patch(CryptographyClient.__module__ + ".get_local_cryptography_provider") as get_provider: client.verify(SignatureAlgorithm.rs256, b"...", b"...") get_provider.assert_called_once_with(key.key) assert mock_client.get_key.call_count == 0
def test_ec_key_id(self, key_client, credential, **kwargs): """When initialized with a key ID, the client should retrieve the key and perform public operations locally""" key = key_client.create_ec_key(self.create_random_name("eckey")) crypto_client = CryptographyClient(key.id, credential) crypto_client._initialize() assert crypto_client.key_id == key.id # ensure all remote crypto operations will fail crypto_client._client = None crypto_client.verify(SignatureAlgorithm.es256_k, hashlib.sha256(self.plaintext).digest(), self.plaintext)
def test_encrypt_argument_validation(): """The client should raise an error when arguments don't work with the specified algorithm""" mock_client = mock.Mock() key = mock.Mock( spec=KeyVaultKey, id="https://localhost/fake/key/version", properties=mock.Mock( not_before=datetime(2000, 1, 1, tzinfo=_UTC), expires_on=datetime(3000, 1, 1, tzinfo=_UTC) ), ) client = CryptographyClient(key, mock.Mock()) client._client = mock_client with pytest.raises(ValueError) as ex: client.encrypt(EncryptionAlgorithm.rsa_oaep, b"...", iv=b"...") assert "iv" in str(ex.value) with pytest.raises(ValueError) as ex: client.encrypt(EncryptionAlgorithm.rsa_oaep, b"...", additional_authenticated_data=b"...") assert "additional_authenticated_data" in str(ex.value)
def test_initialization_get_key_successful(): """If the client is able to get key material, it shouldn't do so again""" mock_client = mock.Mock() mock_client.get_key.return_value = mock.Mock(spec=KeyVaultKey) client = CryptographyClient("https://localhost/fake/key/version", mock.Mock()) client._client = mock_client mock_key = mock.Mock() mock_client.get_key.return_value = mock_key assert mock_client.get_key.call_count == 0 with mock.patch(CryptographyClient.__module__ + ".get_local_cryptography_provider") as get_provider: client.verify(SignatureAlgorithm.rs256, b"...", b"...") get_provider.assert_called_once_with(mock_key) for _ in range(3): assert mock_client.get_key.call_count == 1 assert get_provider.call_count == 1 client.verify(SignatureAlgorithm.rs256, b"...", b"...")
def test_prefers_local_provider(): """The client should complete operations locally whenever possible""" mock_client = mock.Mock() key = mock.Mock( spec=KeyVaultKey, id="https://localhost/fake/key/version", properties=mock.Mock(not_before=datetime(2000, 1, 1, tzinfo=_UTC), expires_on=datetime(3000, 1, 1, tzinfo=_UTC)), ) client = CryptographyClient(key, mock.Mock()) client._client = mock_client supports_everything = mock.Mock(supports=mock.Mock(return_value=True)) with mock.patch( CryptographyClient.__module__ + ".get_local_cryptography_provider", lambda *_: supports_everything): client.decrypt(EncryptionAlgorithm.rsa_oaep, b"...") assert mock_client.decrypt.call_count == 0 assert supports_everything.decrypt.call_count == 1 client.encrypt(EncryptionAlgorithm.rsa_oaep, b"...") assert mock_client.encrypt.call_count == 0 assert supports_everything.encrypt.call_count == 1 client.sign(SignatureAlgorithm.rs256, b"...") assert mock_client.sign.call_count == 0 assert supports_everything.sign.call_count == 1 client.verify(SignatureAlgorithm.rs256, b"...", b"...") assert mock_client.verify.call_count == 0 assert supports_everything.verify.call_count == 1 client.unwrap_key(KeyWrapAlgorithm.rsa_oaep, b"...") assert mock_client.unwrap_key.call_count == 0 assert supports_everything.unwrap_key.call_count == 1 client.wrap_key(KeyWrapAlgorithm.rsa_oaep, b"...") assert mock_client.wrap_key.call_count == 0 assert supports_everything.wrap_key.call_count == 1