Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-blocking API #423

Open
chanced opened this issue Jan 19, 2023 · 0 comments
Open

Non-blocking API #423

chanced opened this issue Jan 19, 2023 · 0 comments

Comments

@chanced
Copy link

chanced commented Jan 19, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant