faysou opened a new pull request, #455: URL: https://github.com/apache/arrow-rs-object-store/pull/455
# Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123. --> Closes #413 Note: I've used an AI agent for this PR and I'm not hiding this fact. It looks like the result is good though, I did this in about 1 hour, which would take much longer if done manually. # Rationale for this change # Add Support for aws-lc-rs as Alternative Cryptographic Provider ## Overview This PR implements support for using `aws-lc-rs` as an alternative to `ring` for cryptographic operations in arrow-rs-object-store, addressing issue #413. Users can now choose between `ring` (default) and `aws-lc-rs` as their cryptographic provider, with compile-time mutual exclusivity enforcement. ## ๐ฏ Problem Solved - **Issue**: The crate was hardcoded to use `ring` for cryptographic operations - **Need**: Support for `aws-lc-rs` as an alternative, particularly for FIPS compliance requirements - **Constraint**: Prevent both libraries from being compiled simultaneously to avoid bloat ## โ Solution Implemented ### 1. **Feature Flag System** - Added `crypto-ring` and `crypto-aws-lc-rs` mutually exclusive feature flags - `crypto-ring` is enabled by default for backward compatibility - Compile-time error prevents both providers from being enabled simultaneously ### 2. **Comprehensive Crypto Provider Support** #### **Core Functions (src/util.rs)** - โ `hmac_sha256()` - HMAC-SHA256 operations for both providers - โ `hex_digest()` - SHA256 digest computation for both providers - โ `hex_encode()` - Hex encoding utility - โ Compile-time mutual exclusivity checks #### **AWS Client Support (src/aws/client.rs)** - โ Updated digest imports to support both crypto providers - โ All AWS cryptographic operations work with both providers #### **GCP Support (src/gcp/credential.rs)** - โ RSA key pair signing with both providers - โ JWT token generation with both providers - โ Proper API compatibility handling for different method signatures ### 3. **Configuration Updates** #### **Cargo.toml** ```toml # New optional dependencies aws-lc-rs = { version = "1.0", default-features = false, features = ["aws-lc-sys"], optional = true } # New feature flags crypto-ring = ["ring"] crypto-aws-lc-rs = ["aws-lc-rs"] # Updated cloud feature (no longer hardcoded to ring) cloud = ["serde", "serde_json", "quick-xml", "hyper", "reqwest", ...] ``` #### **Default Behavior** - `default = ["fs", "crypto-ring"]` - maintains backward compatibility - Existing users see no changes unless they opt into aws-lc-rs ## ๐ Usage Examples ### Default (ring) ```toml [dependencies] object_store = { version = "0.12", features = ["cloud"] } ``` ### With aws-lc-rs ```toml [dependencies] object_store = { version = "0.12", default-features = false, features = ["cloud", "crypto-aws-lc-rs"] } ``` ### Specific Cloud Providers ```toml # AWS with aws-lc-rs object_store = { version = "0.12", default-features = false, features = ["aws", "crypto-aws-lc-rs"] } # GCP with aws-lc-rs object_store = { version = "0.12", default-features = false, features = ["gcp", "crypto-aws-lc-rs"] } ``` ## ๐งช Testing ### **Comprehensive Test Suite** - โ Unit tests for all crypto functions with both providers - โ Consistency tests ensuring identical outputs from both providers - โ Integration tests for AWS, GCP, and Azure with both providers - โ Compile-time mutual exclusivity verification - โ Example programs demonstrating usage ### **Test Results** ```bash # All tests pass with ring cargo test --features "crypto-ring,aws,gcp,fs" # All tests pass with aws-lc-rs cargo test --features "crypto-aws-lc-rs,aws,gcp,fs" --no-default-features # Compile error when both enabled (as expected) cargo check --features "crypto-ring,crypto-aws-lc-rs" ``` ### **Automated Test Script** - Created `test_crypto_providers.sh` for comprehensive validation - Tests all combinations and mutual exclusivity - Verifies examples work with both providers ## ๐ Security & Compatibility ### **API Compatibility** - Both providers expose identical APIs to the rest of the codebase - Function signatures remain unchanged - Cryptographic outputs are identical between providers ### **Backward Compatibility** - โ Existing code continues to work without changes - โ Default behavior unchanged (still uses ring) - โ No breaking changes to public APIs ### **FIPS Compliance** - Users requiring FIPS compliance can now use `aws-lc-rs` - Compile-time selection ensures no performance overhead ## ๐ Files Modified ### **Core Implementation** - `src/util.rs` - Core crypto functions with dual provider support - `src/aws/client.rs` - AWS client crypto provider imports - `src/gcp/credential.rs` - GCP RSA signing with both providers - `Cargo.toml` - Feature flags and dependencies ### **Documentation & Testing** - `README.md` - Usage documentation and examples - `examples/crypto_providers.rs` - Example demonstrating both providers - `test_crypto_providers.sh` - Comprehensive test script - `CRYPTO_PROVIDER_PR_SUMMARY.md` - This comprehensive PR summary ## ๐ Benefits 1. **Choice**: Users can select their preferred cryptographic provider 2. **FIPS Compliance**: aws-lc-rs provides FIPS-validated cryptography 3. **No Bloat**: Compile-time exclusivity prevents dual compilation 4. **Backward Compatible**: Existing code continues to work unchanged 5. **Well Tested**: Comprehensive test suite ensures reliability 6. **Future Proof**: Easy to add additional crypto providers if needed ## ๐ Implementation Details ### **Compile-Time Safety** ```rust #[cfg(all(feature = "crypto-ring", feature = "crypto-aws-lc-rs"))] compile_error!("Cannot enable both 'crypto-ring' and 'crypto-aws-lc-rs' features simultaneously."); ``` ### **Provider-Specific Implementations** ```rust #[cfg(feature = "crypto-ring")] pub(crate) fn hmac_sha256(secret: impl AsRef<[u8]>, bytes: impl AsRef<[u8]>) -> ring::hmac::Tag { let key = ring::hmac::Key::new(ring::hmac::HMAC_SHA256, secret.as_ref()); ring::hmac::sign(&key, bytes.as_ref()) } #[cfg(feature = "crypto-aws-lc-rs")] pub(crate) fn hmac_sha256(secret: impl AsRef<[u8]>, bytes: impl AsRef<[u8]>) -> aws_lc_rs::hmac::Tag { let key = aws_lc_rs::hmac::Key::new(aws_lc_rs::hmac::HMAC_SHA256, secret.as_ref()); aws_lc_rs::hmac::sign(&key, bytes.as_ref()) } ``` ## โ Verification Checklist - [x] Both crypto providers compile successfully - [x] Both providers produce identical cryptographic outputs - [x] All cloud providers (AWS, GCP, Azure) work with both crypto libraries - [x] Mutual exclusivity is enforced at compile time - [x] Comprehensive test coverage for all functionality - [x] Backward compatibility maintained - [x] Documentation updated with usage examples - [x] Implementation focused only on crypto provider functionality - [x] Example code demonstrates both providers - [x] Automated test script validates all scenarios ## ๐ Ready for Production This implementation provides a robust, well-tested solution for cryptographic provider selection in arrow-rs-object-store. Users can now choose between `ring` and `aws-lc-rs` based on their specific requirements, with full confidence that both providers work identically and are mutually exclusive at compile time. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: github-unsubscr...@arrow.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org