Merge "Keystore: Surface service error message" am: af771eb908 am: b3612e019f am: e53fd593b5 am: a2b165989b
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1969819 Change-Id: I0f3d9721af9aa47bf7f7ae6a419d79ec3547210b
This commit is contained in:
commit
ee3c80f288
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +157,16 @@ public class KeyStoreException extends Exception {
|
||||
mErrorCode = errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user