2525import android .annotation .SuppressLint ;
2626import android .annotation .TargetApi ;
2727import android .content .Context ;
28+ import android .content .SharedPreferences ;
2829import android .os .Build ;
30+ import android .preference .PreferenceManager ;
2931import android .security .KeyPairGeneratorSpec ;
3032import android .support .annotation .NonNull ;
3133import android .support .annotation .Nullable ;
@@ -119,6 +121,8 @@ public class StorageHelper implements IStorageHelper {
119121
120122 private static final String HMAC_ALGORITHM = "HmacSHA256" ;
121123
124+ private static final String CURRENT_ACTIVE_BROKER = "current_active_broker" ;
125+
122126 private static final int KEY_SIZE = 256 ;
123127
124128 /**
@@ -295,13 +299,10 @@ public String decrypt(final String encryptedBlob) throws GeneralSecurityExceptio
295299 }
296300
297301 String result = decryptWithSecretKey (bytes , secretKey );
298- Logger .verbose (TAG + methodName , "Finished decryption." );
302+ Logger .verbose (TAG + methodName , "Finished decryption with keyType:" + keyType . name () );
299303 return result ;
300304 } catch (GeneralSecurityException | IOException e ) {
301- logEvent (methodName ,
302- AuthenticationConstants .TelemetryEvents .DECRYPTION_ERROR ,
303- true ,
304- "failed to decrypt with keyType:" + keyType .name () + " exception: " + e .toString ());
305+ emitDecryptionFailureTelemetryIfNeeded (keyType , e );
305306 }
306307 }
307308
@@ -312,6 +313,36 @@ public String decrypt(final String encryptedBlob) throws GeneralSecurityExceptio
312313 throw new GeneralSecurityException (ErrorStrings .DECRYPTION_FAILED );
313314 }
314315
316+ // This is to make sure that Decryption error failure is only emitted once - to avoid bombarding ARIA.
317+ private void emitDecryptionFailureTelemetryIfNeeded (@ NonNull final KeyType keyType ,
318+ @ NonNull final Exception exception ) {
319+ final String methodName = ":emitDecryptionFailureTelemetryIfNeeded" ;
320+ final SharedPreferences sharedPreferences = PreferenceManager .
321+ getDefaultSharedPreferences (mContext );
322+ final String previousActiveBroker = sharedPreferences .getString (
323+ CURRENT_ACTIVE_BROKER ,
324+ ""
325+ );
326+ final String activeBroker = mContext .getPackageName ();
327+
328+ if (!previousActiveBroker .equalsIgnoreCase (activeBroker )) {
329+ final String message = "Decryption failed with key: " + keyType .name ()
330+ + " Active broker: " + activeBroker
331+ + " Exception: " + exception .toString ();
332+
333+ Logger .info (TAG + methodName , message );
334+
335+ if (mTelemetryCallback != null ) {
336+ mTelemetryCallback .logEvent (mContext ,
337+ AuthenticationConstants .TelemetryEvents .DECRYPTION_ERROR ,
338+ true ,
339+ message );
340+ }
341+
342+ sharedPreferences .edit ().putString (CURRENT_ACTIVE_BROKER , activeBroker ).apply ();
343+ }
344+ }
345+
315346 /**
316347 * Determine type of encryption performed on the given data blob.
317348 * NOTE: If it cannot verify the keyVersion, it will assume that this data is not encrypted.
@@ -524,8 +555,6 @@ protected void setBlobVersion(@NonNull String blobVersion) {
524555 public SecretKey loadSecretKey (@ NonNull final KeyType keyType ) throws IOException , GeneralSecurityException {
525556 final String methodName = ":loadSecretKey" ;
526557
527- Logger .verbose (TAG + methodName , "Loading key with Type:" + keyType .name ());
528-
529558 switch (keyType ) {
530559 case LEGACY_AUTHENTICATOR_APP_KEY :
531560 return getSecretKey (AuthenticationSettings .INSTANCE .getBrokerSecretKeys ().get (AZURE_AUTHENTICATOR_APP_PACKAGE_NAME ));
0 commit comments