-
Notifications
You must be signed in to change notification settings - Fork 38
Replace AbstractSecretKeyLoader with ISecretKeyLoader, Fixes AB#3297746 #2666
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
base: dev
Are you sure you want to change the base?
Conversation
❌ Work item link check failed. Description does not contain AB#{ID}. Click here to Learn more. |
✅ Work item link check complete. Description contains link AB#3297746 to an Azure Boards work item. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR replaces the deprecated AbstractSecretKeyLoader with the new ISecretKeyLoader interface, introduces the AndroidWrappedKeyLoaderFactory for future runtime switching of loader implementations, and delegates secret key generation to a dedicated generator class. Key changes include:
- Refactoring all key loader references from AbstractSecretKeyLoader to ISecretKeyLoader.
- Adding the getCipherTransformation method and updating encryption/decryption flows.
- Introducing a feature flag (ENABLE_NEW_ANDROID_WRAPPED_KEY_LOADER) and a new factory to support future loader changes.
Reviewed Changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
common4j/src/test/com/microsoft/identity/common/java/crypto/key/AES256SecretKeyGeneratorTest.kt | Added tests for AES256SecretKeyGenerator functionality. |
common4j/src/test/com/microsoft/identity/common/java/crypto/StorageEncryptionManagerTest.java | Updated tests to reference ISecretKeyLoader instead of AbstractSecretKeyLoader. |
common4j/src/test/com/microsoft/identity/common/java/crypto/MockStorageEncryptionManager.java | Refactored key loader types to use ISecretKeyLoader. |
common4j/src/test/com/microsoft/identity/common/java/crypto/MockAES256KeyLoaderWithGetKeyError.java | Added getCipherTransformation implementation. |
common4j/src/test/com/microsoft/identity/common/java/crypto/MockAES256KeyLoader.java | Updated secret key generation calls to use the new method. |
common4j/src/main/com/microsoft/identity/common/java/flighting/CommonFlight.java | Added the new feature flag for the Android wrapped key loader. |
common4j/src/main/com/microsoft/identity/common/java/crypto/key/PredefinedKeyLoader.java | Updated key loading and method signatures to work with ISecretKeyLoader. |
common4j/src/main/com/microsoft/identity/common/java/crypto/key/AES256KeyLoader.java | Modified to implement ISecretKeyLoader and updated key generator retrieval. |
common/src/main/java/com/microsoft/identity/common/crypto/AndroidWrappedKeyLoaderFactory.kt | Introduced a new factory to choose between loader implementations based on feature flags. |
common/src/main/java/com/microsoft/identity/common/crypto/AndroidWrappedKeyLoader.java | Refactored to use getCipherTransformation and updated key unwrapping logic. |
common/src/main/java/com/microsoft/identity/common/crypto/AndroidAuthSdkStorageEncryptionManager.java | Updated to integrate ISecretKeyLoader and the new wrapped key loader factory. |
common/src/androidTest/java/com/microsoft/identity/common/crypto/AndroidWrappedKeyLoaderTest.java | Updated tests to reflect changes in key algorithm referencing. |
Comments suppressed due to low confidence (1)
common4j/src/main/com/microsoft/identity/common/java/crypto/key/PredefinedKeyLoader.java:53
- [nitpick] If rawBytes is expected to be non-null, consider adding a @nonnull annotation for clarity and to prevent potential null-related issues.
public PredefinedKeyLoader(@NonNull final String alias, final byte[] rawBytes) {
common4j/src/main/com/microsoft/identity/common/java/crypto/key/AES256KeyLoader.java
Outdated
Show resolved
Hide resolved
...n/src/androidTest/java/com/microsoft/identity/common/crypto/AndroidWrappedKeyLoaderTest.java
Outdated
Show resolved
Hide resolved
* specific loader implementation should be used, allowing for runtime switching between | ||
* different implementations without affecting client code. | ||
*/ | ||
object AndroidWrappedKeyLoaderFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than a keyloader factory, it looks like you need a factory for storage layer instead?
two ways to tackle this
-
the new storage layer can decrypt (read) with both old and new keyloader. it would only write with the new keyloader
-
the storage re-encrypts its data with the new keyloader, and use the new keyloader to read/write.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we simply use the flight to switch here - it would lead to user's data loss (since they can't decrypt existing data)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I’m planning to address this in the next PR, where I’ll be using strategy 1, see ->
Line 111 in db8781a
override fun unwrapKey(wrappedSecretKey: ByteArray, secretKeyAlgorithm: String): SecretKey { |
Instead of handling it at the storage layer as you mentioned, I’m just plugging in a new keyloader. This new keyloader will be easier to update if we need to introduce a new algorithm, whether for the key itself or the key-encryption-key.
fun createWrappedKeyLoader( | ||
keyIdentifier: String, | ||
fileName: String, | ||
context: android.content.Context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* This should be compatible with cryptographic providers, such as | ||
* those used with KeyGenerator.getInstance(algorithm). | ||
*/ | ||
val keyAlgorithm: String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need these?
@@ -177,12 +185,11 @@ public synchronized SecretKey getKey() throws ClientException { | |||
return key; | |||
} | |||
|
|||
@Override | |||
@NonNull | |||
protected SecretKey generateRandomKey() throws ClientException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* different implementations without affecting client code. | ||
*/ | ||
object AndroidWrappedKeyLoaderFactory { | ||
const val WRAPPED_KEY_KEY_IDENTIFIER: String = "A001" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** | ||
* Flight to enable the new Android wrapped key loader. | ||
*/ | ||
ENABLE_NEW_ANDROID_WRAPPED_KEY_LOADER("EnableNewAndroidWrappedKeyLoader", true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this in this PR?
You could add this in next PR and factory class
* | ||
* [ISecretKeyLoader] provides a consistent abstraction layer for cryptographic key operations | ||
*/ | ||
interface ISecretKeyLoader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some suggestions
In the next PR:
All these changes lay the groundwork for the next PR, where the new implementation will be introduced and the feature flag will be used to switch between the two implementations.
AB#3297746