Keystore: Surface service error message

Surface the service-specific error message. To avoid API changes, the
error message is surfaced in the toString / getMessage methods.

Test: atest android.security.keystore.KeyStoreExceptionTest
Bug: 217593122
Change-Id: Id4090564b46db9b3b10ea390390f6683f7314463
This commit is contained in:
Eran Messeri
2022-02-02 22:50:50 +00:00
parent 9b73fc72a1
commit 5eedf5a373
5 changed files with 81 additions and 18 deletions

View File

@@ -108,7 +108,7 @@ public class KeyStore2 {
try {
return request.execute(service);
} catch (ServiceSpecificException e) {
throw getKeyStoreException(e.errorCode);
throw getKeyStoreException(e.errorCode, e.getMessage());
} catch (RemoteException e) {
if (firstTry) {
Log.w(TAG, "Looks like we may have lost connection to the Keystore "
@@ -120,7 +120,7 @@ public class KeyStore2 {
firstTry = false;
} else {
Log.e(TAG, "Cannot connect to Keystore daemon.", e);
throw new KeyStoreException(ResponseCode.SYSTEM_ERROR, "");
throw new KeyStoreException(ResponseCode.SYSTEM_ERROR, "", e.getMessage());
}
}
}
@@ -322,26 +322,32 @@ public class KeyStore2 {
}
}
static KeyStoreException getKeyStoreException(int errorCode) {
static KeyStoreException getKeyStoreException(int errorCode, String serviceErrorMessage) {
if (errorCode > 0) {
// KeyStore layer error
switch (errorCode) {
case ResponseCode.LOCKED:
return new KeyStoreException(errorCode, "User authentication required");
return new KeyStoreException(errorCode, "User authentication required",
serviceErrorMessage);
case ResponseCode.UNINITIALIZED:
return new KeyStoreException(errorCode, "Keystore not initialized");
return new KeyStoreException(errorCode, "Keystore not initialized",
serviceErrorMessage);
case ResponseCode.SYSTEM_ERROR:
return new KeyStoreException(errorCode, "System error");
return new KeyStoreException(errorCode, "System error", serviceErrorMessage);
case ResponseCode.PERMISSION_DENIED:
return new KeyStoreException(errorCode, "Permission denied");
return new KeyStoreException(errorCode, "Permission denied",
serviceErrorMessage);
case ResponseCode.KEY_NOT_FOUND:
return new KeyStoreException(errorCode, "Key not found");
return new KeyStoreException(errorCode, "Key not found", serviceErrorMessage);
case ResponseCode.VALUE_CORRUPTED:
return new KeyStoreException(errorCode, "Key blob corrupted");
return new KeyStoreException(errorCode, "Key blob corrupted",
serviceErrorMessage);
case ResponseCode.KEY_PERMANENTLY_INVALIDATED:
return new KeyStoreException(errorCode, "Key permanently invalidated");
return new KeyStoreException(errorCode, "Key permanently invalidated",
serviceErrorMessage);
default:
return new KeyStoreException(errorCode, String.valueOf(errorCode));
return new KeyStoreException(errorCode, String.valueOf(errorCode),
serviceErrorMessage);
}
} else {
// Keymaster layer error
@@ -350,10 +356,12 @@ public class KeyStore2 {
// The name of this parameter significantly differs between Keymaster and
// framework APIs. Use the framework wording to make life easier for developers.
return new KeyStoreException(errorCode,
"Invalid user authentication validity duration");
"Invalid user authentication validity duration",
serviceErrorMessage);
default:
return new KeyStoreException(errorCode,
KeymasterDefs.getErrorMessage(errorCode));
KeymasterDefs.getErrorMessage(errorCode),
serviceErrorMessage);
}
}
}