Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4834ae3 authored by Alex Klyubin's avatar Alex Klyubin
Browse files

Rename KeymasterException to KeyStoreException.

The code in question talks to KeyStore which returns error codes
which are a mix of keystore and keymaster error codes. To better
match the layering of KeyStore on top of keystore and keymaster,
this CL renames KeymasterException into KeyStoreException. It also
adds human-readable error messages to exceptions raised by keystore
rather than keymaster (e.g., key not found).

Bug: 18088752
Change-Id: I4cd1235e16518c9f2e8c5557a457774c6e687b88
parent 3cc9e5d6
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
import android.util.Log;

@@ -506,4 +507,57 @@ public class KeyStore {
            return SYSTEM_ERROR;
        }
    }

    public static KeyStoreException getKeyStoreException(int errorCode) {
        if (errorCode > 0) {
            // KeyStore layer error
            switch (errorCode) {
                case NO_ERROR:
                    return new KeyStoreException(errorCode, "OK");
                case LOCKED:
                    return new KeyStoreException(errorCode, "Keystore locked");
                case UNINITIALIZED:
                    return new KeyStoreException(errorCode, "Keystore not initialized");
                case SYSTEM_ERROR:
                    return new KeyStoreException(errorCode, "System error");
                case PERMISSION_DENIED:
                    return new KeyStoreException(errorCode, "Permission denied");
                case KEY_NOT_FOUND:
                    return new KeyStoreException(errorCode, "Key not found");
                case VALUE_CORRUPTED:
                    return new KeyStoreException(errorCode, "Key blob corrupted");
                default:
                    return new KeyStoreException(errorCode, String.valueOf(errorCode));
            }
        } else {
            // Keymaster layer error
            switch (errorCode) {
                case KeymasterDefs.KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT:
                    // 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");
                default:
                    return new KeyStoreException(errorCode,
                            KeymasterDefs.getErrorMessage(errorCode));
            }
        }
    }

    public static CryptoOperationException getCryptoOperationException(KeyStoreException e) {
        switch (e.getErrorCode()) {
            case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
                return new KeyExpiredException();
            case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
                return new KeyNotYetValidException();
            case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
                return new UserNotAuthenticatedException();
            default:
                return new CryptoOperationException("Crypto operation failed", e);
        }
    }

    public static CryptoOperationException getCryptoOperationException(int errorCode) {
        return getCryptoOperationException(getKeyStoreException(errorCode));
    }
}
+5 −5
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
        if (opResult == null) {
            throw new KeyStoreConnectException();
        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
            throw KeymasterUtils.getCryptoOperationException(opResult.resultCode);
            throw KeyStore.getCryptoOperationException(opResult.resultCode);
        }

        if (opResult.token == null) {
@@ -250,8 +250,8 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
        byte[] output;
        try {
            output = mMainDataStreamer.update(input, inputOffset, inputLen);
        } catch (KeymasterException e) {
            throw KeymasterUtils.getCryptoOperationException(e);
        } catch (KeyStoreException e) {
            throw KeyStore.getCryptoOperationException(e);
        }

        if (output.length == 0) {
@@ -285,7 +285,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
        byte[] output;
        try {
            output = mMainDataStreamer.doFinal(input, inputOffset, inputLen);
        } catch (KeymasterException e) {
        } catch (KeyStoreException e) {
            switch (e.getErrorCode()) {
                case KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH:
                    throw new IllegalBlockSizeException();
@@ -294,7 +294,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
                case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
                    throw new AEADBadTagException();
                default:
                    throw KeymasterUtils.getCryptoOperationException(e);
                    throw KeyStore.getCryptoOperationException(e);
            }
        }

+6 −6
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
        mMaxChunkSize = maxChunkSize;
    }

    public byte[] update(byte[] input, int inputOffset, int inputLength) throws KeymasterException {
    public byte[] update(byte[] input, int inputOffset, int inputLength) throws KeyStoreException {
        if (inputLength == 0) {
            // No input provided
            return EMPTY_BYTE_ARRAY;
@@ -120,7 +120,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
            if (opResult == null) {
                throw new KeyStoreConnectException();
            } else if (opResult.resultCode != KeyStore.NO_ERROR) {
                throw KeymasterUtils.getKeymasterException(opResult.resultCode);
                throw KeyStore.getKeyStoreException(opResult.resultCode);
            }

            if (opResult.inputConsumed == chunk.length) {
@@ -188,7 +188,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
    }

    public byte[] doFinal(byte[] input, int inputOffset, int inputLength)
            throws KeymasterException {
            throws KeyStoreException {
        if (inputLength == 0) {
            // No input provided -- simplify the rest of the code
            input = EMPTY_BYTE_ARRAY;
@@ -203,7 +203,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
        if (opResult == null) {
            throw new KeyStoreConnectException();
        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
            throw KeymasterUtils.getKeymasterException(opResult.resultCode);
            throw KeyStore.getKeyStoreException(opResult.resultCode);
        }

        return concat(output, opResult.output);
@@ -213,7 +213,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
     * Passes all of buffered input into the the KeyStore operation (via the {@code update}
     * operation) and returns output.
     */
    public byte[] flush() throws KeymasterException {
    public byte[] flush() throws KeyStoreException {
        if (mBufferedLength <= 0) {
            return EMPTY_BYTE_ARRAY;
        }
@@ -227,7 +227,7 @@ public class KeyStoreCryptoOperationChunkedStreamer {
        if (opResult == null) {
            throw new KeyStoreConnectException();
        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
            throw KeymasterUtils.getKeymasterException(opResult.resultCode);
            throw KeyStore.getKeyStoreException(opResult.resultCode);
        }

        if (opResult.inputConsumed < chunk.length) {
+4 −3
Original line number Diff line number Diff line
@@ -17,15 +17,16 @@
package android.security;

/**
 * Keymaster exception.
 * KeyStore/keymaster exception with positive error codes coming from the KeyStore and negative
 * ones from keymaster.
 *
 * @hide
 */
public class KeymasterException extends Exception {
public class KeyStoreException extends Exception {

    private final int mErrorCode;

    public KeymasterException(int errorCode, String message) {
    public KeyStoreException(int errorCode, String message) {
        super(message);
        mErrorCode = errorCode;
    }
+5 −5
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
        if (opResult == null) {
            throw new KeyStoreConnectException();
        } else if (opResult.resultCode != KeyStore.NO_ERROR) {
            throw KeymasterUtils.getCryptoOperationException(opResult.resultCode);
            throw KeyStore.getCryptoOperationException(opResult.resultCode);
        }
        if (opResult.token == null) {
            throw new CryptoOperationException("Keystore returned null operation token");
@@ -141,8 +141,8 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
        byte[] output;
        try {
            output = mChunkedStreamer.update(input, offset, len);
        } catch (KeymasterException e) {
            throw KeymasterUtils.getCryptoOperationException(e);
        } catch (KeyStoreException e) {
            throw KeyStore.getCryptoOperationException(e);
        }
        if ((output != null) && (output.length != 0)) {
            throw new CryptoOperationException("Update operation unexpectedly produced output");
@@ -156,8 +156,8 @@ public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOp
        byte[] result;
        try {
            result = mChunkedStreamer.doFinal(null, 0, 0);
        } catch (KeymasterException e) {
            throw KeymasterUtils.getCryptoOperationException(e);
        } catch (KeyStoreException e) {
            throw KeyStore.getCryptoOperationException(e);
        }

        engineReset();
Loading