Merge changes I316fdb8b,I99c1bd49
* changes: Keystore 2.0 SPI: Public key operation workaround. Keystore 2.0 SPI: Bug fixes
This commit is contained in:
@@ -41,7 +41,7 @@ import javax.crypto.spec.IvParameterSpec;
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class AndroidKeyStore3DESCipherSpi extends AndroidKeyStoreCipherSpiBase {
|
public abstract class AndroidKeyStore3DESCipherSpi extends AndroidKeyStoreCipherSpiBase {
|
||||||
|
|
||||||
private static final int BLOCK_SIZE_BYTES = 8;
|
private static final int BLOCK_SIZE_BYTES = 8;
|
||||||
|
|
||||||
@@ -73,12 +73,22 @@ public class AndroidKeyStore3DESCipherSpi extends AndroidKeyStoreCipherSpiBase {
|
|||||||
public NoPadding() {
|
public NoPadding() {
|
||||||
super(KeymasterDefs.KM_PAD_NONE);
|
super(KeymasterDefs.KM_PAD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "DESede/ECB/NoPadding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PKCS7Padding extends ECB {
|
public static class PKCS7Padding extends ECB {
|
||||||
public PKCS7Padding() {
|
public PKCS7Padding() {
|
||||||
super(KeymasterDefs.KM_PAD_PKCS7);
|
super(KeymasterDefs.KM_PAD_PKCS7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "DESede/ECB/PKCS7Padding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,12 +101,23 @@ public class AndroidKeyStore3DESCipherSpi extends AndroidKeyStoreCipherSpiBase {
|
|||||||
public NoPadding() {
|
public NoPadding() {
|
||||||
super(KeymasterDefs.KM_PAD_NONE);
|
super(KeymasterDefs.KM_PAD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "DESede/CBC/NoPadding";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PKCS7Padding extends CBC {
|
public static class PKCS7Padding extends CBC {
|
||||||
public PKCS7Padding() {
|
public PKCS7Padding() {
|
||||||
super(KeymasterDefs.KM_PAD_PKCS7);
|
super(KeymasterDefs.KM_PAD_PKCS7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "DESede/CBC/PKCS7Padding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC
|
|||||||
super(KeymasterDefs.KM_MODE_GCM, keymasterPadding);
|
super(KeymasterDefs.KM_MODE_GCM, keymasterPadding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "AES/GCM/NoPadding";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void resetAll() {
|
protected final void resetAll() {
|
||||||
mTagLengthBits = DEFAULT_TAG_LENGTH_BITS;
|
mTagLengthBits = DEFAULT_TAG_LENGTH_BITS;
|
||||||
|
|||||||
@@ -254,13 +254,13 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider {
|
|||||||
private void putAsymmetricCipherImpl(String transformation, String implClass) {
|
private void putAsymmetricCipherImpl(String transformation, String implClass) {
|
||||||
put("Cipher." + transformation, implClass);
|
put("Cipher." + transformation, implClass);
|
||||||
put("Cipher." + transformation + " SupportedKeyClasses",
|
put("Cipher." + transformation + " SupportedKeyClasses",
|
||||||
KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME);
|
KEYSTORE_PRIVATE_KEY_CLASS_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putSignatureImpl(String algorithm, String implClass) {
|
private void putSignatureImpl(String algorithm, String implClass) {
|
||||||
put("Signature." + algorithm, implClass);
|
put("Signature." + algorithm, implClass);
|
||||||
put("Signature." + algorithm + " SupportedKeyClasses",
|
put("Signature." + algorithm + " SupportedKeyClasses",
|
||||||
KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME);
|
KEYSTORE_PRIVATE_KEY_CLASS_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getSupportedEcdsaSignatureDigests() {
|
public static String[] getSupportedEcdsaSignatureDigests() {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import java.security.PublicKey;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.spec.AlgorithmParameterSpec;
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.security.spec.MGF1ParameterSpec;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -57,6 +58,8 @@ import javax.crypto.NoSuchPaddingException;
|
|||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.SecretKeyFactory;
|
import javax.crypto.SecretKeyFactory;
|
||||||
import javax.crypto.ShortBufferException;
|
import javax.crypto.ShortBufferException;
|
||||||
|
import javax.crypto.spec.OAEPParameterSpec;
|
||||||
|
import javax.crypto.spec.PSource;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,6 +102,8 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
*/
|
*/
|
||||||
private Exception mCachedException;
|
private Exception mCachedException;
|
||||||
|
|
||||||
|
private Cipher mCipher;
|
||||||
|
|
||||||
AndroidKeyStoreCipherSpiBase() {
|
AndroidKeyStoreCipherSpiBase() {
|
||||||
mOperation = null;
|
mOperation = null;
|
||||||
mEncrypting = false;
|
mEncrypting = false;
|
||||||
@@ -110,6 +115,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
mAdditionalAuthenticationDataStreamer = null;
|
mAdditionalAuthenticationDataStreamer = null;
|
||||||
mAdditionalAuthenticationDataStreamerClosed = false;
|
mAdditionalAuthenticationDataStreamerClosed = false;
|
||||||
mCachedException = null;
|
mCachedException = null;
|
||||||
|
mCipher = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -117,6 +123,45 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
throws InvalidKeyException {
|
throws InvalidKeyException {
|
||||||
resetAll();
|
resetAll();
|
||||||
|
|
||||||
|
if (!(key instanceof AndroidKeyStorePrivateKey
|
||||||
|
|| key instanceof AndroidKeyStoreSecretKey)) {
|
||||||
|
try {
|
||||||
|
mCipher = Cipher.getInstance(getTransform());
|
||||||
|
String transform = getTransform();
|
||||||
|
|
||||||
|
if ("RSA/ECB/OAEPWithSHA-224AndMGF1Padding".equals(transform)) {
|
||||||
|
OAEPParameterSpec spec =
|
||||||
|
new OAEPParameterSpec("SHA-224", "MGF1",
|
||||||
|
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
|
||||||
|
mCipher.init(opmode, key, spec, random);
|
||||||
|
} else if ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding".equals(transform)) {
|
||||||
|
OAEPParameterSpec spec =
|
||||||
|
new OAEPParameterSpec("SHA-256", "MGF1",
|
||||||
|
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
|
||||||
|
mCipher.init(opmode, key, spec, random);
|
||||||
|
|
||||||
|
} else if ("RSA/ECB/OAEPWithSHA-384AndMGF1Padding".equals(transform)) {
|
||||||
|
OAEPParameterSpec spec =
|
||||||
|
new OAEPParameterSpec("SHA-384", "MGF1",
|
||||||
|
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
|
||||||
|
mCipher.init(opmode, key, spec, random);
|
||||||
|
|
||||||
|
} else if ("RSA/ECB/OAEPWithSHA-512AndMGF1Padding".equals(transform)) {
|
||||||
|
OAEPParameterSpec spec =
|
||||||
|
new OAEPParameterSpec("SHA-512", "MGF1",
|
||||||
|
new MGF1ParameterSpec("SHA1"), PSource.PSpecified.DEFAULT);
|
||||||
|
mCipher.init(opmode, key, spec, random);
|
||||||
|
} else {
|
||||||
|
mCipher.init(opmode, key, random);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} catch (NoSuchAlgorithmException
|
||||||
|
| NoSuchPaddingException
|
||||||
|
| InvalidAlgorithmParameterException e) {
|
||||||
|
throw new InvalidKeyException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
init(opmode, key, random);
|
init(opmode, key, random);
|
||||||
@@ -139,6 +184,17 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||||
resetAll();
|
resetAll();
|
||||||
|
|
||||||
|
if (!(key instanceof AndroidKeyStorePrivateKey
|
||||||
|
|| key instanceof AndroidKeyStoreSecretKey)) {
|
||||||
|
try {
|
||||||
|
mCipher = Cipher.getInstance(getTransform());
|
||||||
|
mCipher.init(opmode, key, params, random);
|
||||||
|
return;
|
||||||
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||||
|
throw new InvalidKeyException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
init(opmode, key, random);
|
init(opmode, key, random);
|
||||||
@@ -157,6 +213,17 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||||
resetAll();
|
resetAll();
|
||||||
|
|
||||||
|
if (!(key instanceof AndroidKeyStorePrivateKey
|
||||||
|
|| key instanceof AndroidKeyStoreSecretKey)) {
|
||||||
|
try {
|
||||||
|
mCipher = Cipher.getInstance(getTransform());
|
||||||
|
mCipher.init(opmode, key, params, random);
|
||||||
|
return;
|
||||||
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||||
|
throw new InvalidKeyException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
init(opmode, key, random);
|
init(opmode, key, random);
|
||||||
@@ -214,6 +281,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
mAdditionalAuthenticationDataStreamer = null;
|
mAdditionalAuthenticationDataStreamer = null;
|
||||||
mAdditionalAuthenticationDataStreamerClosed = false;
|
mAdditionalAuthenticationDataStreamerClosed = false;
|
||||||
mCachedException = null;
|
mCachedException = null;
|
||||||
|
mCipher = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -320,6 +388,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
|
protected final byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.update(input, inputOffset, inputLen);
|
||||||
|
}
|
||||||
|
|
||||||
if (mCachedException != null) {
|
if (mCachedException != null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -371,6 +443,9 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
@Override
|
@Override
|
||||||
protected final int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
|
protected final int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
|
||||||
int outputOffset) throws ShortBufferException {
|
int outputOffset) throws ShortBufferException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.update(input, inputOffset, inputLen, output);
|
||||||
|
}
|
||||||
byte[] outputCopy = engineUpdate(input, inputOffset, inputLen);
|
byte[] outputCopy = engineUpdate(input, inputOffset, inputLen);
|
||||||
if (outputCopy == null) {
|
if (outputCopy == null) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -387,6 +462,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
@Override
|
@Override
|
||||||
protected final int engineUpdate(ByteBuffer input, ByteBuffer output)
|
protected final int engineUpdate(ByteBuffer input, ByteBuffer output)
|
||||||
throws ShortBufferException {
|
throws ShortBufferException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.update(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
throw new NullPointerException("input == null");
|
throw new NullPointerException("input == null");
|
||||||
}
|
}
|
||||||
@@ -423,6 +502,11 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void engineUpdateAAD(byte[] input, int inputOffset, int inputLen) {
|
protected final void engineUpdateAAD(byte[] input, int inputOffset, int inputLen) {
|
||||||
|
if (mCipher != null) {
|
||||||
|
mCipher.updateAAD(input, inputOffset, inputLen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mCachedException != null) {
|
if (mCachedException != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -459,6 +543,11 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void engineUpdateAAD(ByteBuffer src) {
|
protected final void engineUpdateAAD(ByteBuffer src) {
|
||||||
|
if (mCipher != null) {
|
||||||
|
mCipher.updateAAD(src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (src == null) {
|
if (src == null) {
|
||||||
throw new IllegalArgumentException("src == null");
|
throw new IllegalArgumentException("src == null");
|
||||||
}
|
}
|
||||||
@@ -486,6 +575,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
@Override
|
@Override
|
||||||
protected final byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
|
protected final byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
|
||||||
throws IllegalBlockSizeException, BadPaddingException {
|
throws IllegalBlockSizeException, BadPaddingException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.doFinal(input, inputOffset, inputLen);
|
||||||
|
}
|
||||||
|
|
||||||
if (mCachedException != null) {
|
if (mCachedException != null) {
|
||||||
throw (IllegalBlockSizeException)
|
throw (IllegalBlockSizeException)
|
||||||
new IllegalBlockSizeException().initCause(mCachedException);
|
new IllegalBlockSizeException().initCause(mCachedException);
|
||||||
@@ -522,6 +615,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
protected final int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
|
protected final int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
|
||||||
int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
|
int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
|
||||||
BadPaddingException {
|
BadPaddingException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.doFinal(input, inputOffset, inputLen, output);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] outputCopy = engineDoFinal(input, inputOffset, inputLen);
|
byte[] outputCopy = engineDoFinal(input, inputOffset, inputLen);
|
||||||
if (outputCopy == null) {
|
if (outputCopy == null) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -538,6 +635,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
@Override
|
@Override
|
||||||
protected final int engineDoFinal(ByteBuffer input, ByteBuffer output)
|
protected final int engineDoFinal(ByteBuffer input, ByteBuffer output)
|
||||||
throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
|
throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.doFinal(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
throw new NullPointerException("input == null");
|
throw new NullPointerException("input == null");
|
||||||
}
|
}
|
||||||
@@ -575,6 +676,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
@Override
|
@Override
|
||||||
protected final byte[] engineWrap(Key key)
|
protected final byte[] engineWrap(Key key)
|
||||||
throws IllegalBlockSizeException, InvalidKeyException {
|
throws IllegalBlockSizeException, InvalidKeyException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.wrap(key);
|
||||||
|
}
|
||||||
|
|
||||||
if (mKey == null) {
|
if (mKey == null) {
|
||||||
throw new IllegalStateException("Not initilized");
|
throw new IllegalStateException("Not initilized");
|
||||||
}
|
}
|
||||||
@@ -656,6 +761,10 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
@Override
|
@Override
|
||||||
protected final Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
|
protected final Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
|
||||||
int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
|
int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
|
||||||
|
if (mCipher != null) {
|
||||||
|
return mCipher.unwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType);
|
||||||
|
}
|
||||||
|
|
||||||
if (mKey == null) {
|
if (mKey == null) {
|
||||||
throw new IllegalStateException("Not initilized");
|
throw new IllegalStateException("Not initilized");
|
||||||
}
|
}
|
||||||
@@ -902,4 +1011,6 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor
|
|||||||
*/
|
*/
|
||||||
protected abstract void loadAlgorithmSpecificParametersFromBeginResult(
|
protected abstract void loadAlgorithmSpecificParametersFromBeginResult(
|
||||||
KeyParameter[] parameters);
|
KeyParameter[] parameters);
|
||||||
|
|
||||||
|
protected abstract String getTransform();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
|
|||||||
super(KeymasterDefs.KM_DIGEST_NONE);
|
super(KeymasterDefs.KM_DIGEST_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "NONEwithECDSA";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
|
protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
|
||||||
KeyStoreOperation operation) {
|
KeyStoreOperation operation) {
|
||||||
@@ -113,30 +118,50 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature
|
|||||||
public SHA1() {
|
public SHA1() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA1);
|
super(KeymasterDefs.KM_DIGEST_SHA1);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA1withECDSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static class SHA224 extends AndroidKeyStoreECDSASignatureSpi {
|
public final static class SHA224 extends AndroidKeyStoreECDSASignatureSpi {
|
||||||
public SHA224() {
|
public SHA224() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA224withECDSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static class SHA256 extends AndroidKeyStoreECDSASignatureSpi {
|
public final static class SHA256 extends AndroidKeyStoreECDSASignatureSpi {
|
||||||
public SHA256() {
|
public SHA256() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA256withECDSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static class SHA384 extends AndroidKeyStoreECDSASignatureSpi {
|
public final static class SHA384 extends AndroidKeyStoreECDSASignatureSpi {
|
||||||
public SHA384() {
|
public SHA384() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA384withECDSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static class SHA512 extends AndroidKeyStoreECDSASignatureSpi {
|
public final static class SHA512 extends AndroidKeyStoreECDSASignatureSpi {
|
||||||
public SHA512() {
|
public SHA512() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA512withECDSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int mKeymasterDigest;
|
private final int mKeymasterDigest;
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ import android.system.keystore2.KeyEntryResponse;
|
|||||||
import android.system.keystore2.KeyMetadata;
|
import android.system.keystore2.KeyMetadata;
|
||||||
import android.system.keystore2.ResponseCode;
|
import android.system.keystore2.ResponseCode;
|
||||||
|
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
import java.security.ProviderException;
|
import java.security.ProviderException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
@@ -42,8 +40,6 @@ import java.security.Signature;
|
|||||||
import java.security.UnrecoverableKeyException;
|
import java.security.UnrecoverableKeyException;
|
||||||
import java.security.interfaces.ECPublicKey;
|
import java.security.interfaces.ECPublicKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
@@ -237,28 +233,11 @@ public class AndroidKeyStoreProvider extends Provider {
|
|||||||
throw new UnrecoverableKeyException("Failed to obtain X.509 form of public key."
|
throw new UnrecoverableKeyException("Failed to obtain X.509 form of public key."
|
||||||
+ " Keystore has no public certificate stored.");
|
+ " Keystore has no public certificate stored.");
|
||||||
}
|
}
|
||||||
final byte[] x509EncodedPublicKey = metadata.certificate;
|
final byte[] x509PublicCert = metadata.certificate;
|
||||||
|
|
||||||
String jcaKeyAlgorithm;
|
PublicKey publicKey = AndroidKeyStoreSpi.toCertificate(x509PublicCert).getPublicKey();
|
||||||
try {
|
|
||||||
jcaKeyAlgorithm = KeyProperties.KeyAlgorithm.fromKeymasterAsymmetricKeyAlgorithm(
|
|
||||||
algorithm);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw (UnrecoverableKeyException)
|
|
||||||
new UnrecoverableKeyException("Failed to load private key")
|
|
||||||
.initCause(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
PublicKey publicKey;
|
String jcaKeyAlgorithm = publicKey.getAlgorithm();
|
||||||
try {
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance(jcaKeyAlgorithm);
|
|
||||||
publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedPublicKey));
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new ProviderException(
|
|
||||||
"Failed to obtain " + jcaKeyAlgorithm + " KeyFactory", e);
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
throw new ProviderException("Invalid X.509 encoding of public key", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyStoreSecurityLevel securityLevel = iSecurityLevel;
|
KeyStoreSecurityLevel securityLevel = iSecurityLevel;
|
||||||
if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
|
if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
|
||||||
@@ -358,7 +337,7 @@ public class AndroidKeyStoreProvider extends Provider {
|
|||||||
|
|
||||||
KeyDescriptor descriptor = new KeyDescriptor();
|
KeyDescriptor descriptor = new KeyDescriptor();
|
||||||
if (namespace == KeyProperties.NAMESPACE_APPLICATION) {
|
if (namespace == KeyProperties.NAMESPACE_APPLICATION) {
|
||||||
descriptor.nspace = 0; // ignored;
|
descriptor.nspace = KeyProperties.NAMESPACE_APPLICATION; // ignored;
|
||||||
descriptor.domain = Domain.APP;
|
descriptor.domain = Domain.APP;
|
||||||
} else {
|
} else {
|
||||||
descriptor.nspace = namespace;
|
descriptor.nspace = namespace;
|
||||||
@@ -407,7 +386,7 @@ public class AndroidKeyStoreProvider extends Provider {
|
|||||||
keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
|
keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
|
||||||
return makeAndroidKeyStorePublicKeyFromKeyEntryResponse(descriptor, response.metadata,
|
return makeAndroidKeyStorePublicKeyFromKeyEntryResponse(descriptor, response.metadata,
|
||||||
new KeyStoreSecurityLevel(response.iSecurityLevel),
|
new KeyStoreSecurityLevel(response.iSecurityLevel),
|
||||||
keymasterAlgorithm);
|
keymasterAlgorithm).getPrivateKey();
|
||||||
} else {
|
} else {
|
||||||
throw new UnrecoverableKeyException("Key algorithm unknown");
|
throw new UnrecoverableKeyException("Key algorithm unknown");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSA cipher with OAEP encryption padding. Only SHA-1 based MGF1 is supported as MGF.
|
* RSA cipher with OAEP encryption padding.
|
||||||
*/
|
*/
|
||||||
abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi {
|
abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi {
|
||||||
|
|
||||||
@@ -316,6 +316,25 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
|||||||
protected final int getAdditionalEntropyAmountForFinish() {
|
protected final int getAdditionalEntropyAmountForFinish() {
|
||||||
return (isEncrypting()) ? mDigestOutputSizeBytes : 0;
|
return (isEncrypting()) ? mDigestOutputSizeBytes : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
switch (mKeymasterDigest) {
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA1:
|
||||||
|
return "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_224:
|
||||||
|
return "RSA/ECB/OAEPWithSHA-224AndMGF1Padding";
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_256:
|
||||||
|
return "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_384:
|
||||||
|
return "RSA/ECB/OAEPWithSHA-384AndMGF1Padding";
|
||||||
|
case KeymasterDefs.KM_DIGEST_SHA_2_512:
|
||||||
|
return "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
|
||||||
|
default:
|
||||||
|
return "RSA/ECB/OAEPPadding";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class OAEPWithSHA1AndMGF1Padding extends OAEPWithMGF1Padding {
|
public static class OAEPWithSHA1AndMGF1Padding extends OAEPWithMGF1Padding {
|
||||||
@@ -357,6 +376,11 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase
|
|||||||
mKeymasterPadding = keymasterPadding;
|
mKeymasterPadding = keymasterPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTransform() {
|
||||||
|
return "RSA/ECB/" + KeyProperties.EncryptionPadding.fromKeymaster(mKeymasterPadding);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void initKey(int opmode, Key key) throws InvalidKeyException {
|
protected final void initKey(int opmode, Key key) throws InvalidKeyException {
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
|
|||||||
@@ -48,42 +48,70 @@ abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSp
|
|||||||
public NONEWithPKCS1Padding() {
|
public NONEWithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_NONE);
|
super(KeymasterDefs.KM_DIGEST_NONE);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "NONEwithRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class MD5WithPKCS1Padding extends PKCS1Padding {
|
public static final class MD5WithPKCS1Padding extends PKCS1Padding {
|
||||||
public MD5WithPKCS1Padding() {
|
public MD5WithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_MD5);
|
super(KeymasterDefs.KM_DIGEST_MD5);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "MD5withRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA1WithPKCS1Padding extends PKCS1Padding {
|
public static final class SHA1WithPKCS1Padding extends PKCS1Padding {
|
||||||
public SHA1WithPKCS1Padding() {
|
public SHA1WithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA1);
|
super(KeymasterDefs.KM_DIGEST_SHA1);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA1withRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA224WithPKCS1Padding extends PKCS1Padding {
|
public static final class SHA224WithPKCS1Padding extends PKCS1Padding {
|
||||||
public SHA224WithPKCS1Padding() {
|
public SHA224WithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA224withRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA256WithPKCS1Padding extends PKCS1Padding {
|
public static final class SHA256WithPKCS1Padding extends PKCS1Padding {
|
||||||
public SHA256WithPKCS1Padding() {
|
public SHA256WithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA256withRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA384WithPKCS1Padding extends PKCS1Padding {
|
public static final class SHA384WithPKCS1Padding extends PKCS1Padding {
|
||||||
public SHA384WithPKCS1Padding() {
|
public SHA384WithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA384withRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA512WithPKCS1Padding extends PKCS1Padding {
|
public static final class SHA512WithPKCS1Padding extends PKCS1Padding {
|
||||||
public SHA512WithPKCS1Padding() {
|
public SHA512WithPKCS1Padding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA512withRSA";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract static class PSSPadding extends AndroidKeyStoreRSASignatureSpi {
|
abstract static class PSSPadding extends AndroidKeyStoreRSASignatureSpi {
|
||||||
@@ -103,30 +131,50 @@ abstract class AndroidKeyStoreRSASignatureSpi extends AndroidKeyStoreSignatureSp
|
|||||||
public SHA1WithPSSPadding() {
|
public SHA1WithPSSPadding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA1);
|
super(KeymasterDefs.KM_DIGEST_SHA1);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA1withRSA/PSS";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA224WithPSSPadding extends PSSPadding {
|
public static final class SHA224WithPSSPadding extends PSSPadding {
|
||||||
public SHA224WithPSSPadding() {
|
public SHA224WithPSSPadding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA224withRSA/PSS";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA256WithPSSPadding extends PSSPadding {
|
public static final class SHA256WithPSSPadding extends PSSPadding {
|
||||||
public SHA256WithPSSPadding() {
|
public SHA256WithPSSPadding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA256withRSA/PSS";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA384WithPSSPadding extends PSSPadding {
|
public static final class SHA384WithPSSPadding extends PSSPadding {
|
||||||
public SHA384WithPSSPadding() {
|
public SHA384WithPSSPadding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA384withRSA/PSS";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class SHA512WithPSSPadding extends PSSPadding {
|
public static final class SHA512WithPSSPadding extends PSSPadding {
|
||||||
public SHA512WithPSSPadding() {
|
public SHA512WithPSSPadding() {
|
||||||
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
|
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected String getAlgorithm() {
|
||||||
|
return "SHA512withRSA/PSS";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int mKeymasterDigest;
|
private final int mKeymasterDigest;
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ import libcore.util.EmptyArray;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.ProviderException;
|
import java.security.ProviderException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.security.Signature;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.security.SignatureSpi;
|
import java.security.SignatureSpi;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -76,6 +78,13 @@ abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
|
|||||||
*/
|
*/
|
||||||
private Exception mCachedException;
|
private Exception mCachedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This signature object is used for public key operations, i.e, signatrue verification.
|
||||||
|
* The Android Keystore backend does not perform public key operations and defers to the
|
||||||
|
* Highest priority provider.
|
||||||
|
*/
|
||||||
|
private Signature mSignature;
|
||||||
|
|
||||||
AndroidKeyStoreSignatureSpiBase() {
|
AndroidKeyStoreSignatureSpiBase() {
|
||||||
mOperation = null;
|
mOperation = null;
|
||||||
mOperationChallenge = 0;
|
mOperationChallenge = 0;
|
||||||
@@ -84,6 +93,7 @@ abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
|
|||||||
appRandom = null;
|
appRandom = null;
|
||||||
mMessageStreamer = null;
|
mMessageStreamer = null;
|
||||||
mCachedException = null;
|
mCachedException = null;
|
||||||
|
mSignature = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -123,27 +133,13 @@ abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
|
|||||||
protected final void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
|
protected final void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
|
||||||
resetAll();
|
resetAll();
|
||||||
|
|
||||||
boolean success = false;
|
|
||||||
try {
|
try {
|
||||||
if (publicKey == null) {
|
mSignature = Signature.getInstance(getAlgorithm());
|
||||||
throw new InvalidKeyException("Unsupported key: null");
|
} catch (NoSuchAlgorithmException e) {
|
||||||
}
|
throw new InvalidKeyException(e);
|
||||||
AndroidKeyStoreKey keystoreKey;
|
|
||||||
if (publicKey instanceof AndroidKeyStorePublicKey) {
|
|
||||||
keystoreKey = (AndroidKeyStorePublicKey) publicKey;
|
|
||||||
} else {
|
|
||||||
throw new InvalidKeyException("Unsupported public key type: " + publicKey);
|
|
||||||
}
|
|
||||||
mSigning = false;
|
|
||||||
initKey(keystoreKey);
|
|
||||||
appRandom = null;
|
|
||||||
ensureKeystoreOperationInitialized();
|
|
||||||
success = true;
|
|
||||||
} finally {
|
|
||||||
if (!success) {
|
|
||||||
resetAll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSignature.initVerify(publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -251,6 +247,11 @@ abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void engineUpdate(byte[] b, int off, int len) throws SignatureException {
|
protected final void engineUpdate(byte[] b, int off, int len) throws SignatureException {
|
||||||
|
if (mSignature != null) {
|
||||||
|
mSignature.update(b, off, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mCachedException != null) {
|
if (mCachedException != null) {
|
||||||
throw new SignatureException(mCachedException);
|
throw new SignatureException(mCachedException);
|
||||||
}
|
}
|
||||||
@@ -337,39 +338,10 @@ abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final boolean engineVerify(byte[] signature) throws SignatureException {
|
protected final boolean engineVerify(byte[] signature) throws SignatureException {
|
||||||
if (mCachedException != null) {
|
if (mSignature != null) {
|
||||||
throw new SignatureException(mCachedException);
|
return mSignature.verify(signature);
|
||||||
}
|
}
|
||||||
|
throw new IllegalStateException("Not initialised.");
|
||||||
try {
|
|
||||||
ensureKeystoreOperationInitialized();
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
throw new SignatureException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean verified;
|
|
||||||
try {
|
|
||||||
byte[] output = mMessageStreamer.doFinal(
|
|
||||||
EmptyArray.BYTE, 0, 0,
|
|
||||||
signature);
|
|
||||||
if (output.length != 0) {
|
|
||||||
throw new ProviderException(
|
|
||||||
"Signature verification unexpected produced output: " + output.length
|
|
||||||
+ " bytes");
|
|
||||||
}
|
|
||||||
verified = true;
|
|
||||||
} catch (KeyStoreException e) {
|
|
||||||
switch (e.getErrorCode()) {
|
|
||||||
case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
|
|
||||||
verified = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new SignatureException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resetWhilePreservingInitState();
|
|
||||||
return verified;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -391,6 +363,13 @@ abstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
|
|||||||
throw new InvalidParameterException();
|
throw new InvalidParameterException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementations need to report the algorithm they implement so that we can delegate to the
|
||||||
|
* highest priority provider.
|
||||||
|
* @return Algorithm string.
|
||||||
|
*/
|
||||||
|
protected abstract String getAlgorithm();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if this signature is initialized for signing, {@code false} if this
|
* Returns {@code true} if this signature is initialized for signing, {@code false} if this
|
||||||
* signature is initialized for verification.
|
* signature is initialized for verification.
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static X509Certificate toCertificate(byte[] bytes) {
|
static X509Certificate toCertificate(byte[] bytes) {
|
||||||
try {
|
try {
|
||||||
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||||
return (X509Certificate) certFactory.generateCertificate(
|
return (X509Certificate) certFactory.generateCertificate(
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import javax.crypto.spec.IvParameterSpec;
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase {
|
abstract class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase {
|
||||||
|
|
||||||
abstract static class ECB extends AndroidKeyStoreUnauthenticatedAESCipherSpi {
|
abstract static class ECB extends AndroidKeyStoreUnauthenticatedAESCipherSpi {
|
||||||
protected ECB(int keymasterPadding) {
|
protected ECB(int keymasterPadding) {
|
||||||
@@ -53,12 +53,22 @@ class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSp
|
|||||||
public NoPadding() {
|
public NoPadding() {
|
||||||
super(KeymasterDefs.KM_PAD_NONE);
|
super(KeymasterDefs.KM_PAD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "AES/ECB/NoPadding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PKCS7Padding extends ECB {
|
public static class PKCS7Padding extends ECB {
|
||||||
public PKCS7Padding() {
|
public PKCS7Padding() {
|
||||||
super(KeymasterDefs.KM_PAD_PKCS7);
|
super(KeymasterDefs.KM_PAD_PKCS7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "AES/ECB/PKCS7Padding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,12 +81,22 @@ class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSp
|
|||||||
public NoPadding() {
|
public NoPadding() {
|
||||||
super(KeymasterDefs.KM_PAD_NONE);
|
super(KeymasterDefs.KM_PAD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "AES/CBC/NoPadding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PKCS7Padding extends CBC {
|
public static class PKCS7Padding extends CBC {
|
||||||
public PKCS7Padding() {
|
public PKCS7Padding() {
|
||||||
super(KeymasterDefs.KM_PAD_PKCS7);
|
super(KeymasterDefs.KM_PAD_PKCS7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "AES/CBC/PKCS7Padding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +109,11 @@ class AndroidKeyStoreUnauthenticatedAESCipherSpi extends AndroidKeyStoreCipherSp
|
|||||||
public NoPadding() {
|
public NoPadding() {
|
||||||
super(KeymasterDefs.KM_PAD_NONE);
|
super(KeymasterDefs.KM_PAD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final String getTransform() {
|
||||||
|
return "AES/CTR/NoPadding";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public abstract class KeyStore2ParameterUtils {
|
|||||||
static void forEachSetFlag(int flags, Consumer<Integer> consumer) {
|
static void forEachSetFlag(int flags, Consumer<Integer> consumer) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
while (flags != 0) {
|
while (flags != 0) {
|
||||||
if ((flags & 1) == 0) {
|
if ((flags & 1) == 1) {
|
||||||
consumer.accept(1 << offset);
|
consumer.accept(1 << offset);
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user