summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEran Messeri <eranm@google.com>2022-02-08 17:33:52 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-02-08 17:33:52 +0000
commitaf771eb908192409118a36a02d604d68649948ae (patch)
treefd48b2232b42fe628ce775bbd3b39e2becf94395
parent9b73fc72a1ce7b63079684875222dc3877ca74f0 (diff)
parent5eedf5a3734308ee5ebe8a5ea2f73b6e6a0cb1fe (diff)
downloadbase-af771eb908192409118a36a02d604d68649948ae.tar.gz
Merge "Keystore: Surface service error message"
-rw-r--r--keystore/java/android/security/KeyStore2.java34
-rw-r--r--keystore/java/android/security/KeyStoreException.java10
-rw-r--r--keystore/java/android/security/KeyStoreOperation.java5
-rw-r--r--keystore/java/android/security/KeyStoreSecurityLevel.java6
-rw-r--r--keystore/tests/src/android/security/keystore/KeyStoreExceptionTest.java44
5 files changed, 81 insertions, 18 deletions
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index 1034847b761b..3d53cfb388e1 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -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);
}
}
}
diff --git a/keystore/java/android/security/KeyStoreException.java b/keystore/java/android/security/KeyStoreException.java
index 6db2745840f4..54184dbf6e08 100644
--- a/keystore/java/android/security/KeyStoreException.java
+++ b/keystore/java/android/security/KeyStoreException.java
@@ -158,6 +158,16 @@ public class KeyStoreException extends Exception {
}
/**
+ * @hide
+ */
+ public KeyStoreException(int errorCode, @Nullable String message,
+ @Nullable String keystoreErrorMessage) {
+ super(message + " (internal Keystore code: " + errorCode + " message: "
+ + keystoreErrorMessage + ")");
+ mErrorCode = errorCode;
+ }
+
+ /**
* Returns the internal error code. Only for use by the platform.
*
* @hide
diff --git a/keystore/java/android/security/KeyStoreOperation.java b/keystore/java/android/security/KeyStoreOperation.java
index e6c1ea827118..737ff2b4822f 100644
--- a/keystore/java/android/security/KeyStoreOperation.java
+++ b/keystore/java/android/security/KeyStoreOperation.java
@@ -75,7 +75,7 @@ public class KeyStoreOperation {
);
}
default:
- throw KeyStore2.getKeyStoreException(e.errorCode);
+ throw KeyStore2.getKeyStoreException(e.errorCode, e.getMessage());
}
} catch (RemoteException e) {
// Log exception and report invalid operation handle.
@@ -85,7 +85,8 @@ public class KeyStoreOperation {
"Remote exception while advancing a KeyStoreOperation.",
e
);
- throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE, "");
+ throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_OPERATION_HANDLE, "",
+ e.getMessage());
}
}
diff --git a/keystore/java/android/security/KeyStoreSecurityLevel.java b/keystore/java/android/security/KeyStoreSecurityLevel.java
index b85dd742cc49..9c0b46c8e87b 100644
--- a/keystore/java/android/security/KeyStoreSecurityLevel.java
+++ b/keystore/java/android/security/KeyStoreSecurityLevel.java
@@ -54,12 +54,12 @@ public class KeyStoreSecurityLevel {
try {
return request.execute();
} catch (ServiceSpecificException e) {
- throw KeyStore2.getKeyStoreException(e.errorCode);
+ throw KeyStore2.getKeyStoreException(e.errorCode, e.getMessage());
} catch (RemoteException e) {
// Log exception and report invalid operation handle.
// This should prompt the caller drop the reference to this operation and retry.
Log.e(TAG, "Could not connect to Keystore.", e);
- throw new KeyStoreException(ResponseCode.SYSTEM_ERROR, "");
+ throw new KeyStoreException(ResponseCode.SYSTEM_ERROR, "", e.getMessage());
}
}
@@ -117,7 +117,7 @@ public class KeyStoreSecurityLevel {
break;
}
default:
- throw KeyStore2.getKeyStoreException(e.errorCode);
+ throw KeyStore2.getKeyStoreException(e.errorCode, e.getMessage());
}
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
diff --git a/keystore/tests/src/android/security/keystore/KeyStoreExceptionTest.java b/keystore/tests/src/android/security/keystore/KeyStoreExceptionTest.java
new file mode 100644
index 000000000000..31c742289a61
--- /dev/null
+++ b/keystore/tests/src/android/security/keystore/KeyStoreExceptionTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import static org.junit.Assert.assertTrue;
+
+import android.security.KeyStoreException;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class KeyStoreExceptionTest {
+ @Test
+ public void testKeystoreMessageIsIncluded() {
+ final String primaryMessage = "some_message";
+ final String keystoreMessage = "ks_message";
+ KeyStoreException exception = new KeyStoreException(-1, primaryMessage, keystoreMessage);
+
+ String exceptionMessage = exception.getMessage();
+ assertTrue(exceptionMessage.contains(primaryMessage));
+ assertTrue(exceptionMessage.contains(keystoreMessage));
+
+ String exceptionString = exception.toString();
+ assertTrue(exceptionString.contains(primaryMessage));
+ assertTrue(exceptionString.contains(keystoreMessage));
+ }
+}