Skip to content

Non-blocking API #423

@chanced

Description

@chanced

A non-blocking API would be great. The crate is not that ergonomic to use in a project that relies on the tokio runtime. This is due to the fact that you can not spawn a tokio::Runtime from within a runtime.

    #[tokio::test]
    async fn test_construction() -> Result<(), Box<dyn std::error::Error>> {
        tink_aead::init();
        dotenv::dotenv().unwrap();
        let key_uri = std::env::var("GOOGLE_KMS_KEY_URI")?;
        let credential_path_var = std::env::var("GOOGLE_APPLICATION_CREDENTIALS").unwrap();
        let credential_path = std::path::Path::new(&credential_path_var);
        let client =
            tink_gcpkms::GcpClient::new_with_credentials(&key_uri, credential_path).unwrap();
        let backend = client.get_aead(&key_uri).unwrap();
        // ...
        Ok(())
    }
thread 'key_manager::tests::test_construction' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.'

Also, dyn <Primitive> are cumbersome without Send + Sync.

/// Returns a [`tink_core::Aead`] primitive from the given keyset handle.
pub fn new(h: &tink_core::keyset::Handle) -> Result<Box<dyn tink_core::Aead>, TinkError> {
    new_with_key_manager(h, None)
}

I can get around the first issue with an actor and spawning a thread, but lack of Send + Sync on the primitives is a tough one.

I believe there are a few changes that would need to be made:

  1. Create a feature flag, something like "non-blocking" to avoid breaking changes.
  2. Add async-trait as a dependency
  3. Add an AeadEnvelope trait:
#[async_trait::async_trait]
pub trait AeadEnvelope {
    async fn encrypt(
        &self,
        plaintext: &[u8],
        additional_data: &[u8],
    ) -> Result<Vec<u8>, TinkError>;

    async fn decrypt(
        &self,
        ciphertext: &[u8],
        additional_data: &[u8],
    ) -> Result<Vec<u8>, TinkError>;
}
  1. A good bit of the dyn <Primitive> will likely need to be dyn 'static + <Primitive> + Send + Sync
  2. Possibly provide implementations for the integrations but that's not as important as the above.

Thank you for your work and effort porting this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions