diff --git a/src/api-impl/android/content/Context.java b/src/api-impl/android/content/Context.java index 6e61d20e..aa48a4d5 100644 --- a/src/api-impl/android/content/Context.java +++ b/src/api-impl/android/content/Context.java @@ -130,6 +130,7 @@ public class Context extends Object { Provider provider = new Provider("AndroidKeyStore", 1.0, "Android KeyStore provider") {}; provider.put("KeyStore.AndroidKeyStore", "android.security.keystore.AndroidKeyStore"); + provider.put("KeyGenerator.AES", "android.security.keystore.KeyGenerator"); Security.addProvider(provider); r.applyPackageQuirks(application_info.packageName); diff --git a/src/api-impl/android/security/keystore/AndroidKeyStore.java b/src/api-impl/android/security/keystore/AndroidKeyStore.java index 681d897f..53b619f8 100644 --- a/src/api-impl/android/security/keystore/AndroidKeyStore.java +++ b/src/api-impl/android/security/keystore/AndroidKeyStore.java @@ -10,6 +10,7 @@ import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Enumeration; @@ -19,12 +20,12 @@ import android.util.Slog; public class AndroidKeyStore extends KeyStoreSpi { - HashMap map = new HashMap<>(); + static HashMap map = new HashMap<>(); @Override public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'engineGetKey'"); + System.out.println("engineGetKey alias=" + alias + " password=" + Arrays.toString(password)); + return map.get(alias); } @Override diff --git a/src/api-impl/android/security/keystore/KeyGenParameterSpec.java b/src/api-impl/android/security/keystore/KeyGenParameterSpec.java new file mode 100644 index 00000000..fdc9647e --- /dev/null +++ b/src/api-impl/android/security/keystore/KeyGenParameterSpec.java @@ -0,0 +1,68 @@ +package android.security.keystore; + +public class KeyGenParameterSpec { + + private String keystoreAlias; + private int purposes; + private int keySize; + private String[] blockModes; + private String[] encryptionPaddings; + private boolean userAuthenticationRequired; + + public static class Builder { + private KeyGenParameterSpec spec = new KeyGenParameterSpec(); + + public Builder(String keystoreAlias, int purposes) { + spec.keystoreAlias = keystoreAlias; + spec.purposes = purposes; + } + + public Builder setKeySize(int keySize) { + spec.keySize = keySize; + return this; + } + + public Builder setBlockModes(String[] blockModes) { + spec.blockModes = blockModes; + return this; + } + + public Builder setEncryptionPaddings(String[] encryptionPaddings) { + spec.encryptionPaddings = encryptionPaddings; + return this; + } + + public Builder setUserAuthenticationRequired(boolean userAuthenticationRequired) { + spec.userAuthenticationRequired = userAuthenticationRequired; + return this; + } + + public KeyGenParameterSpec build() { + return spec; + } + } + + public int getKeySize() { + return keySize; + } + + public String[] getBlockModes() { + return blockModes; + } + + public int getPurposes() { + return purposes; + } + + public String[] getEncryptionPaddings() { + return encryptionPaddings; + } + + public boolean isUserAuthenticationRequired() { + return userAuthenticationRequired; + } + + public String getKeystoreAlias() { + return keystoreAlias; + } +} diff --git a/src/api-impl/android/security/keystore/KeyGenerator.java b/src/api-impl/android/security/keystore/KeyGenerator.java new file mode 100644 index 00000000..d512af7f --- /dev/null +++ b/src/api-impl/android/security/keystore/KeyGenerator.java @@ -0,0 +1,50 @@ +package android.security.keystore; + +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; + +public class KeyGenerator extends KeyGeneratorSpi { + + private javax.crypto.KeyGenerator keyGenerator; + private AlgorithmParameterSpec params; + + @Override + protected SecretKey engineGenerateKey() { + System.out.println("generating key with alias " + ((KeyGenParameterSpec)params).getKeystoreAlias()); + SecretKey key = keyGenerator.generateKey(); + AndroidKeyStore.map.put(((KeyGenParameterSpec)params).getKeystoreAlias(), key); + return key; + } + + @Override + protected void engineInit(SecureRandom random) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'engineInit'"); + } + + @Override + protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException { + try { + keyGenerator = javax.crypto.KeyGenerator.getInstance("AES", "BC"); + this.params = params; + keyGenerator.init(random); + } catch (NoSuchAlgorithmException | NoSuchProviderException e) { + e.printStackTrace(); + throw new UnsupportedOperationException("Unimplemented method 'engineInit'"); + } + } + + @Override + protected void engineInit(int keysize, SecureRandom random) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'engineInit'"); + } + +} diff --git a/src/api-impl/meson.build b/src/api-impl/meson.build index ed68cdfb..0dddf30e 100644 --- a/src/api-impl/meson.build +++ b/src/api-impl/meson.build @@ -373,6 +373,8 @@ srcs = [ 'android/provider/Settings.java', 'android/provider/UserDictionary.java', 'android/security/keystore/AndroidKeyStore.java', + 'android/security/keystore/KeyGenerator.java', + 'android/security/keystore/KeyGenParameterSpec.java', 'android/service/media/MediaBrowserService.java', 'android/speech/tts/TextToSpeech.java', 'android/telecom/ConnectionService.java',