in sdk/communication/azure-communication-chat/src/main/java/com/azure/android/communication/chat/implementation/notifications/fcm/RegistrationKeyManager.java [164:229]
private void rotateKeys(String directoryPath, Context context) {
int removed = 0;
HashSet<Integer> set = new HashSet<>();
HashSet<Integer> removedSet = new HashSet<>();
try {
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
set.add(extractIndex(aliases.nextElement()));
}
} catch (KeyStoreException e) {
throw clientLogger.logExceptionAsError(new RuntimeException("Failed iterate key-store", e));
}
Set<String> aliases = keyMetaDataStore.getAliases();
for (String alias : aliases) {
set.add(extractIndex(alias));
}
//Delete expired keys or inconsistent records
for (int curIndex : set) {
String cryptoKeyAlias = CRYPTO_KEY_PREFIX + curIndex;
String authKeyAlias = AUTH_KEY_PREFIX + curIndex;
Long insertionTime = getCreationTime(cryptoKeyAlias);
if (insertionTime == null) {
insertionTime = 0L;
}
long currentTime = System.currentTimeMillis();
long diffInMinutes = (currentTime - insertionTime) / (60 * 1000);
if (diffInMinutes > EXPIRATION_TIME_MINUTES || anyEntryMissed(cryptoKeyAlias, authKeyAlias)) {
try {
deleteKeyFromFiles(cryptoKeyAlias, directoryPath);
deleteKeyFromFiles(authKeyAlias, directoryPath);
removedSet.add(curIndex);
removed++;
} catch (Exception e) {
throw clientLogger.logExceptionAsError(new RuntimeException("Failed to delete entry from key-store with index: " + curIndex, e));
}
}
}
set.removeAll(removedSet);
//Rotate to fill the empty entries. Move remained entries to lowest index
int toIndex = 0;
if (removed == 0) {
return;
}
for (int fromIndex : set) {
String fromCryptoAlias = CRYPTO_KEY_PREFIX + fromIndex;
String fromAuthAlias = AUTH_KEY_PREFIX + fromIndex;
//No need to move
if (toIndex == fromIndex) {
toIndex++;
continue;
}
String toCryptoAlias = CRYPTO_KEY_PREFIX + toIndex;
String toAuthAlias = AUTH_KEY_PREFIX + toIndex;
moveAnEntry(fromCryptoAlias, toCryptoAlias, directoryPath, context);
moveAnEntry(fromAuthAlias, toAuthAlias, directoryPath, context);
deleteKeyFromFiles(fromCryptoAlias, directoryPath);
deleteKeyFromFiles(fromAuthAlias, directoryPath);
toIndex++;
}
}