Skip to content

Commit acf10a4

Browse files
committed
feat :Added new clearAll API to clear all credentaisl and key pairs
1 parent 9f10837 commit acf10a4

7 files changed

Lines changed: 98 additions & 4 deletions

File tree

auth0/src/main/java/com/auth0/android/authentication/storage/BaseCredentialsManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ public abstract class BaseCredentialsManager internal constructor(
159159

160160
public abstract fun clearCredentials()
161161
public abstract fun clearApiCredentials(audience: String, scope: String? = null)
162+
public abstract fun clearAll()
162163
public abstract fun hasValidCredentials(): Boolean
163164
public abstract fun hasValidCredentials(minTtl: Long): Boolean
164165

auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import androidx.annotation.VisibleForTesting
66
import com.auth0.android.authentication.AuthenticationAPIClient
77
import com.auth0.android.authentication.AuthenticationException
88
import com.auth0.android.callback.Callback
9+
import com.auth0.android.dpop.DPoP
10+
import com.auth0.android.dpop.DPoPException
911
import com.auth0.android.request.internal.GsonProvider
1012
import com.auth0.android.request.internal.Jwt
1113
import com.auth0.android.result.APICredentials
@@ -528,7 +530,8 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
528530
callback.onFailure(
529531
CredentialsManagerException(
530532
CredentialsManagerException.Code.MFA_REQUIRED,
531-
error.message ?: "Multi-factor authentication is required to complete the credential renewal.",
533+
error.message
534+
?: "Multi-factor authentication is required to complete the credential renewal.",
532535
error,
533536
error.mfaRequiredErrorPayload
534537
)
@@ -654,7 +657,8 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
654657
callback.onFailure(
655658
CredentialsManagerException(
656659
CredentialsManagerException.Code.MFA_REQUIRED,
657-
error.message ?: "Multi-factor authentication is required to complete the credential renewal.",
660+
error.message
661+
?: "Multi-factor authentication is required to complete the credential renewal.",
658662
error,
659663
error.mfaRequiredErrorPayload
660664
)
@@ -710,6 +714,19 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
710714
storage.removeAll()
711715
}
712716

717+
/**
718+
* Removes all credentials, API credentials, and cryptographic key pairs.
719+
* This calls [Storage.removeAll] to clear all stored data
720+
*/
721+
override fun clearAll() {
722+
storage.removeAll()
723+
try {
724+
DPoP.clearKeyPair()
725+
} catch (e: DPoPException) {
726+
Log.e(TAG, "Failed to clear DPoP key pair ${e.stackTraceToString()}")
727+
}
728+
}
729+
713730
/**
714731
* Removes the credentials for the given audience from the storage if present.
715732
* @param audience Audience for which the [APICredentials] are stored

auth0/src/main/java/com/auth0/android/authentication/storage/CryptoUtil.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,14 @@ private void deleteAESKeys() {
327327
storage.remove(OLD_KEY_IV_ALIAS);
328328
}
329329

330+
/**
331+
* Removes all cryptographic keys (both RSA and AES) used by this instance.
332+
*/
333+
public void deleteAllKeys() {
334+
deleteRSAKeys();
335+
deleteAESKeys();
336+
}
337+
330338
/**
331339
* Decrypts the given input using a generated RSA Private Key.
332340
* Used to decrypt the AES key for later usage.

auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import com.auth0.android.Auth0
1010
import com.auth0.android.authentication.AuthenticationAPIClient
1111
import com.auth0.android.authentication.AuthenticationException
1212
import com.auth0.android.callback.Callback
13+
import com.auth0.android.dpop.DPoP
14+
import com.auth0.android.dpop.DPoPException
1315
import com.auth0.android.request.internal.GsonProvider
1416
import com.auth0.android.result.APICredentials
1517
import com.auth0.android.result.Credentials
@@ -736,6 +738,22 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
736738
Log.d(TAG, "Credentials were just removed from the storage")
737739
}
738740

741+
/**
742+
* Removes all credentials, API credentials, and cryptographic key pairs.
743+
* This calls [Storage.removeAll] to clear all stored data
744+
*/
745+
override fun clearAll() {
746+
storage.removeAll()
747+
crypto.deleteAllKeys()
748+
clearBiometricSession()
749+
try {
750+
DPoP.clearKeyPair()
751+
} catch (e: DPoPException) {
752+
Log.e(TAG, "Failed to clear DPoP key pair ${e.stackTraceToString()}")
753+
}
754+
Log.d(TAG, "All credentials and key pairs were removed")
755+
}
756+
739757
/**
740758
* Removes the credentials for the given audience from the storage if present.
741759
* @param audience Audience for which the [APICredentials] are stored
@@ -890,7 +908,8 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
890908
callback.onFailure(
891909
CredentialsManagerException(
892910
CredentialsManagerException.Code.MFA_REQUIRED,
893-
error.message ?: "Multi-factor authentication is required to complete the credential renewal.",
911+
error.message
912+
?: "Multi-factor authentication is required to complete the credential renewal.",
894913
error,
895914
error.mfaRequiredErrorPayload
896915
)
@@ -1048,7 +1067,8 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
10481067
callback.onFailure(
10491068
CredentialsManagerException(
10501069
CredentialsManagerException.Code.MFA_REQUIRED,
1051-
error.message ?: "Multi-factor authentication is required to complete the credential renewal.",
1070+
error.message
1071+
?: "Multi-factor authentication is required to complete the credential renewal.",
10521072
error,
10531073
error.mfaRequiredErrorPayload
10541074
)

auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,12 @@ public class CredentialsManagerTest {
14951495
verifyNoMoreInteractions(storage)
14961496
}
14971497

1498+
@Test
1499+
public fun shouldClearAllCredentialsAndDPoPKeyPair() {
1500+
manager.clearAll()
1501+
verify(storage).removeAll()
1502+
}
1503+
14981504
@Test
14991505
public fun shouldSaveApiCredentialsWithScopeAsKey() {
15001506
val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS

auth0/src/test/java/com/auth0/android/authentication/storage/CryptoUtilTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,6 +2086,41 @@ public void shouldNotPropagateProviderExceptionAsIncompatibleDeviceException() t
20862086
assertThat(result, is(newAESKey));
20872087
}
20882088

2089+
/*
2090+
* deleteAllKeys() tests
2091+
*/
2092+
2093+
@Test
2094+
public void shouldDeleteBothRSAAndAESKeysWhenDeleteAllKeysIsCalled() throws Exception {
2095+
cryptoUtil.deleteAllKeys();
2096+
2097+
// Verify RSA keys deleted from KeyStore
2098+
Mockito.verify(keyStore).deleteEntry(KEY_ALIAS);
2099+
Mockito.verify(keyStore).deleteEntry(OLD_KEY_ALIAS);
2100+
2101+
// Verify AES keys deleted from Storage
2102+
Mockito.verify(storage).remove(KEY_ALIAS);
2103+
Mockito.verify(storage).remove(KEY_ALIAS + "_iv");
2104+
Mockito.verify(storage).remove(OLD_KEY_ALIAS);
2105+
Mockito.verify(storage).remove(OLD_KEY_ALIAS + "_iv");
2106+
}
2107+
2108+
@Test
2109+
public void shouldDeleteAESKeysEvenIfRSAKeyDeletionFails() throws Exception {
2110+
doThrow(new KeyStoreException("KeyStore error")).when(keyStore).deleteEntry(anyString());
2111+
2112+
cryptoUtil.deleteAllKeys();
2113+
2114+
// RSA deletion was attempted (first deleteEntry throws, second is never reached)
2115+
Mockito.verify(keyStore).deleteEntry(KEY_ALIAS);
2116+
2117+
// AES keys should still be deleted from Storage
2118+
Mockito.verify(storage).remove(KEY_ALIAS);
2119+
Mockito.verify(storage).remove(KEY_ALIAS + "_iv");
2120+
Mockito.verify(storage).remove(OLD_KEY_ALIAS);
2121+
Mockito.verify(storage).remove(OLD_KEY_ALIAS + "_iv");
2122+
}
2123+
20892124
/*
20902125
* Helper methods
20912126
*/

auth0/src/test/java/com/auth0/android/authentication/storage/SecureCredentialsManagerTest.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,13 @@ public class SecureCredentialsManagerTest {
21642164
verifyNoMoreInteractions(storage)
21652165
}
21662166

2167+
@Test
2168+
public fun shouldClearAllCredentialsKeyPairsAndDPoPKeyPair() {
2169+
manager.clearAll()
2170+
verify(storage).removeAll()
2171+
verify(crypto).deleteAllKeys()
2172+
}
2173+
21672174
@Test
21682175
public fun shouldSaveEncryptedApiCredentialsWithScopeAsKey() {
21692176
val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS

0 commit comments

Comments
 (0)