Loading keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java +42 −2 Original line number Diff line number Diff line Loading @@ -43,13 +43,17 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { private static final String PACKAGE_NAME = "android.security.keystore"; private static final String KEYSTORE_SECRET_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStoreSecretKey"; private static final String KEYSTORE_PRIVATE_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStorePrivateKey"; private static final String KEYSTORE_PUBLIC_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStorePublicKey"; AndroidKeyStoreBCWorkaroundProvider() { super("AndroidKeyStoreBCWorkaround", 1.0, "Android KeyStore security provider to work around Bouncy Castle"); // javax.crypto.Mac // --------------------- javax.crypto.Mac putMacImpl("HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA1"); put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1"); put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1"); Loading @@ -75,7 +79,7 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512"); put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512"); // javax.crypto.Cipher // --------------------- javax.crypto.Cipher putSymmetricCipherImpl("AES/ECB/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$ECB$NoPadding"); putSymmetricCipherImpl("AES/ECB/PKCS7Padding", Loading @@ -88,6 +92,36 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { putSymmetricCipherImpl("AES/CTR/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CTR$NoPadding"); putAsymmetricCipherImpl("RSA/ECB/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$NoPadding"); put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding"); putAsymmetricCipherImpl("RSA/ECB/PKCS1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$PKCS1Padding"); put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPPadding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPPadding", "RSA/ECB/OAEPPadding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-1AndMGF1Padding", "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA224AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-224AndMGF1Padding", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA256AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-256AndMGF1Padding", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA384AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-384AndMGF1Padding", "RSA/ECB/OAEPWithSHA-384AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA512AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-512AndMGF1Padding", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); } private void putMacImpl(String algorithm, String implClass) { Loading @@ -99,4 +133,10 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { put("Cipher." + transformation, implClass); put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME); } private void putAsymmetricCipherImpl(String transformation, String implClass) { put("Cipher." + transformation, implClass); put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME); } } keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java +15 −4 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor */ private IBinder mOperationToken; private long mOperationHandle; private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer; private KeyStoreCryptoOperationStreamer mMainDataStreamer; /** * Encountered exception which could not be immediately thrown because it was encountered inside Loading Loading @@ -210,7 +210,6 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor byte[] additionalEntropy = KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng( mRng, getAdditionalEntropyAmountForBegin()); KeymasterArguments keymasterOutputArgs = new KeymasterArguments(); OperationResult opResult = mKeyStore.begin( mKey.getAlias(), mEncrypting ? KeymasterDefs.KM_PURPOSE_ENCRYPT : KeymasterDefs.KM_PURPOSE_DECRYPT, Loading Loading @@ -247,9 +246,21 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } loadAlgorithmSpecificParametersFromBeginResult(opResult.outParams); mMainDataStreamer = new KeyStoreCryptoOperationChunkedStreamer( mMainDataStreamer = createMainDataStreamer(mKeyStore, opResult.token); } /** * Creates a streamer which sends plaintext/ciphertext into the provided KeyStore and receives * the corresponding ciphertext/plaintext from the KeyStore. * * <p>This implementation returns a working streamer. */ @NonNull protected KeyStoreCryptoOperationStreamer createMainDataStreamer( KeyStore keyStore, IBinder operationToken) { return new KeyStoreCryptoOperationChunkedStreamer( new KeyStoreCryptoOperationChunkedStreamer.MainDataStream( mKeyStore, opResult.token)); keyStore, operationToken)); } @Override Loading keystore/java/android/security/keystore/AndroidKeyStoreKey.java +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package android.security.keystore; import java.security.Key; /** * {@link Key} backed by AndroidKeyStore. * {@link Key} backed by Android Keystore. * * @hide */ Loading keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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 java.security.PrivateKey; /** * {@link PrivateKey} backed by Android Keystore. * * @hide */ public class AndroidKeyStorePrivateKey extends AndroidKeyStoreKey implements PrivateKey { public AndroidKeyStorePrivateKey(String alias, String algorithm) { super(alias, algorithm); } } keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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 java.security.PublicKey; /** * {@link PublicKey} backed by Android Keystore. * * @hide */ public class AndroidKeyStorePublicKey extends AndroidKeyStoreKey implements PublicKey { private final byte[] mEncoded; public AndroidKeyStorePublicKey(String alias, String algorithm, byte[] x509EncodedForm) { super(alias, algorithm); mEncoded = ArrayUtils.cloneIfNotEmpty(x509EncodedForm); } @Override public String getFormat() { return "X.509"; } @Override public byte[] getEncoded() { return ArrayUtils.cloneIfNotEmpty(mEncoded); } } Loading
keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java +42 −2 Original line number Diff line number Diff line Loading @@ -43,13 +43,17 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { private static final String PACKAGE_NAME = "android.security.keystore"; private static final String KEYSTORE_SECRET_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStoreSecretKey"; private static final String KEYSTORE_PRIVATE_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStorePrivateKey"; private static final String KEYSTORE_PUBLIC_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStorePublicKey"; AndroidKeyStoreBCWorkaroundProvider() { super("AndroidKeyStoreBCWorkaround", 1.0, "Android KeyStore security provider to work around Bouncy Castle"); // javax.crypto.Mac // --------------------- javax.crypto.Mac putMacImpl("HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA1"); put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1"); put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1"); Loading @@ -75,7 +79,7 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512"); put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512"); // javax.crypto.Cipher // --------------------- javax.crypto.Cipher putSymmetricCipherImpl("AES/ECB/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$ECB$NoPadding"); putSymmetricCipherImpl("AES/ECB/PKCS7Padding", Loading @@ -88,6 +92,36 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { putSymmetricCipherImpl("AES/CTR/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CTR$NoPadding"); putAsymmetricCipherImpl("RSA/ECB/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$NoPadding"); put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding"); putAsymmetricCipherImpl("RSA/ECB/PKCS1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$PKCS1Padding"); put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPPadding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPPadding", "RSA/ECB/OAEPPadding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-1AndMGF1Padding", "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA224AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-224AndMGF1Padding", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA256AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-256AndMGF1Padding", "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA384AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-384AndMGF1Padding", "RSA/ECB/OAEPWithSHA-384AndMGF1Padding"); putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA512AndMGF1Padding"); put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-512AndMGF1Padding", "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); } private void putMacImpl(String algorithm, String implClass) { Loading @@ -99,4 +133,10 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { put("Cipher." + transformation, implClass); put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME); } private void putAsymmetricCipherImpl(String transformation, String implClass) { put("Cipher." + transformation, implClass); put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME); } }
keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java +15 −4 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor */ private IBinder mOperationToken; private long mOperationHandle; private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer; private KeyStoreCryptoOperationStreamer mMainDataStreamer; /** * Encountered exception which could not be immediately thrown because it was encountered inside Loading Loading @@ -210,7 +210,6 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor byte[] additionalEntropy = KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng( mRng, getAdditionalEntropyAmountForBegin()); KeymasterArguments keymasterOutputArgs = new KeymasterArguments(); OperationResult opResult = mKeyStore.begin( mKey.getAlias(), mEncrypting ? KeymasterDefs.KM_PURPOSE_ENCRYPT : KeymasterDefs.KM_PURPOSE_DECRYPT, Loading Loading @@ -247,9 +246,21 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } loadAlgorithmSpecificParametersFromBeginResult(opResult.outParams); mMainDataStreamer = new KeyStoreCryptoOperationChunkedStreamer( mMainDataStreamer = createMainDataStreamer(mKeyStore, opResult.token); } /** * Creates a streamer which sends plaintext/ciphertext into the provided KeyStore and receives * the corresponding ciphertext/plaintext from the KeyStore. * * <p>This implementation returns a working streamer. */ @NonNull protected KeyStoreCryptoOperationStreamer createMainDataStreamer( KeyStore keyStore, IBinder operationToken) { return new KeyStoreCryptoOperationChunkedStreamer( new KeyStoreCryptoOperationChunkedStreamer.MainDataStream( mKeyStore, opResult.token)); keyStore, operationToken)); } @Override Loading
keystore/java/android/security/keystore/AndroidKeyStoreKey.java +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package android.security.keystore; import java.security.Key; /** * {@link Key} backed by AndroidKeyStore. * {@link Key} backed by Android Keystore. * * @hide */ Loading
keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java 0 → 100644 +31 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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 java.security.PrivateKey; /** * {@link PrivateKey} backed by Android Keystore. * * @hide */ public class AndroidKeyStorePrivateKey extends AndroidKeyStoreKey implements PrivateKey { public AndroidKeyStorePrivateKey(String alias, String algorithm) { super(alias, algorithm); } }
keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 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 java.security.PublicKey; /** * {@link PublicKey} backed by Android Keystore. * * @hide */ public class AndroidKeyStorePublicKey extends AndroidKeyStoreKey implements PublicKey { private final byte[] mEncoded; public AndroidKeyStorePublicKey(String alias, String algorithm, byte[] x509EncodedForm) { super(alias, algorithm); mEncoded = ArrayUtils.cloneIfNotEmpty(x509EncodedForm); } @Override public String getFormat() { return "X.509"; } @Override public byte[] getEncoded() { return ArrayUtils.cloneIfNotEmpty(mEncoded); } }