AndroidKeyStoreKeyPairGeneratorSpi.java revision e21f0231765492718f1284442136c2ae45e6dd93
14f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber/* 24f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Copyright (C) 2012 The Android Open Source Project 34f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 44f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 54f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * you may not use this file except in compliance with the License. 64f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * You may obtain a copy of the License at 74f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 84f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 94f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Unless required by applicable law or agreed to in writing, software 114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * See the License for the specific language governing permissions and 144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * limitations under the License. 154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber */ 164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberpackage android.security.keystore; 184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport android.annotation.NonNull; 204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport android.security.Credentials; 214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport android.security.KeyPairGeneratorSpec; 224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport android.security.KeyStore; 234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport com.android.org.bouncycastle.x509.X509V3CertificateGenerator; 254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport com.android.org.conscrypt.NativeConstants; 264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport com.android.org.conscrypt.OpenSSLEngine; 274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.InvalidAlgorithmParameterException; 294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.InvalidKeyException; 304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.KeyFactory; 314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.KeyPair; 324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.KeyPairGenerator; 334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.KeyPairGeneratorSpi; 344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.NoSuchAlgorithmException; 354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.PrivateKey; 364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.PublicKey; 374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.SecureRandom; 384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.cert.CertificateEncodingException; 394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.cert.X509Certificate; 404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.spec.AlgorithmParameterSpec; 414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.spec.InvalidKeySpecException; 424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.spec.RSAKeyGenParameterSpec; 434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.security.spec.X509EncodedKeySpec; 444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberimport java.util.Locale; 454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber/** 474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Provides a way to create instances of a KeyPair which will be placed in the 484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Android keystore service usable only by the application that called it. This 494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * can be used in conjunction with 504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * {@link java.security.KeyStore#getInstance(String)} using the 514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * {@code "AndroidKeyStore"} type. 524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * <p> 534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * This class can not be directly instantiated and must instead be used via the 544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * {@link KeyPairGenerator#getInstance(String) 554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * KeyPairGenerator.getInstance("AndroidKeyStore")} API. 564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * @hide 584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber */ 594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberpublic abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGeneratorSpi { 604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public static class RSA extends AndroidKeyStoreKeyPairGeneratorSpi { 624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public RSA() { 634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber super(KeyProperties.KEY_ALGORITHM_RSA); 644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public static class EC extends AndroidKeyStoreKeyPairGeneratorSpi { 684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public EC() { 694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber super(KeyProperties.KEY_ALGORITHM_EC); 704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber /* 744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * These must be kept in sync with system/security/keystore/defaults.h 754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber */ 764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber /* EC */ 784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static final int EC_DEFAULT_KEY_SIZE = 256; 794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static final int EC_MIN_KEY_SIZE = 192; 804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static final int EC_MAX_KEY_SIZE = 521; 814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber /* RSA */ 834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static final int RSA_DEFAULT_KEY_SIZE = 2048; 844f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static final int RSA_MIN_KEY_SIZE = 512; 854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static final int RSA_MAX_KEY_SIZE = 8192; 864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private final String mAlgorithm; 884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private KeyStore mKeyStore; 904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private KeyGenParameterSpec mSpec; 924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private boolean mEncryptionAtRestRequired; 934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private @KeyProperties.KeyAlgorithmEnum String mKeyAlgorithm; 944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private int mKeyType; 954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private int mKeySize; 964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber protected AndroidKeyStoreKeyPairGeneratorSpi(@KeyProperties.KeyAlgorithmEnum String algorithm) { 984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mAlgorithm = algorithm; 994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber @KeyProperties.KeyAlgorithmEnum String getAlgorithm() { 1024f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return mAlgorithm; 1034f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1044f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1054f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber /** 1064f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * Generate a KeyPair which is backed by the Android keystore service. You 1074f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * must call {@link KeyPairGenerator#initialize(AlgorithmParameterSpec)} 1084f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * with an {@link KeyPairGeneratorSpec} as the {@code params} 1094f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * argument before calling this otherwise an {@code IllegalStateException} 1104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * will be thrown. 1114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * <p> 1124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * This will create an entry in the Android keystore service with a 1134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * self-signed certificate using the {@code params} specified in the 1144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * {@code initialize(params)} call. 1154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * 1164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * @throws IllegalStateException when called before calling 1174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * {@link KeyPairGenerator#initialize(AlgorithmParameterSpec)} 1184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber * @see java.security.KeyPairGeneratorSpi#generateKeyPair() 1194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber */ 1204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber @Override 1214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public KeyPair generateKeyPair() { 1224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (mKeyStore == null || mSpec == null) { 1234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("Not initialized"); 1244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final int flags = (mEncryptionAtRestRequired) ? KeyStore.FLAG_ENCRYPTED : 0; 1284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (((flags & KeyStore.FLAG_ENCRYPTED) != 0) 1294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber && (mKeyStore.state() != KeyStore.State.UNLOCKED)) { 1304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException( 1314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Encryption at rest using secure lock screen credential requested for key pair" 1324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + ", but the user has not yet entered the credential"); 1334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final String alias = mSpec.getKeystoreAlias(); 1364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber Credentials.deleteAllTypesForAlias(mKeyStore, alias); 1384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber byte[][] args = getArgsForKeyType(mKeyType, mSpec.getAlgorithmParameterSpec()); 1404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias; 1424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mKeyType, mKeySize, 1444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber flags, args)) { 1454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("could not generate key in keystore"); 1464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber Credentials.deleteSecretKeyTypeForAlias(mKeyStore, alias); 1494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final PrivateKey privKey; 1514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore"); 1524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber try { 1534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber privKey = engine.getPrivateKeyById(privateKeyAlias); 1544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } catch (InvalidKeyException e) { 1554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new RuntimeException("Can't get key", e); 1564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final byte[] pubKeyBytes = mKeyStore.getPubkey(privateKeyAlias); 1594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final PublicKey pubKey; 1614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber try { 1624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final KeyFactory keyFact = KeyFactory.getInstance(mKeyAlgorithm); 1634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes)); 1644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } catch (NoSuchAlgorithmException e) { 1654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("Can't instantiate key generator", e); 1664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } catch (InvalidKeySpecException e) { 1674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("keystore returned invalid key encoding", e); 1684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final X509Certificate cert; 1714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber try { 1724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber cert = generateCertificate(privKey, pubKey); 1734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } catch (Exception e) { 1744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber Credentials.deleteAllTypesForAlias(mKeyStore, alias); 1754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("Can't generate certificate", e); 1764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber byte[] certBytes; 1794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber try { 1804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certBytes = cert.getEncoded(); 1814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } catch (CertificateEncodingException e) { 1824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber Credentials.deleteAllTypesForAlias(mKeyStore, alias); 1834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("Can't get encoding of certificate", e); 1844f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, certBytes, KeyStore.UID_SELF, 1874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber flags)) { 1884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber Credentials.deleteAllTypesForAlias(mKeyStore, alias); 1894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalStateException("Can't store certificate in AndroidKeyStore"); 1904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return new KeyPair(pubKey, privKey); 1934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 1944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 1954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber @SuppressWarnings("deprecation") 1964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private X509Certificate generateCertificate(PrivateKey privateKey, PublicKey publicKey) 1974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throws Exception { 1984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); 1994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setPublicKey(publicKey); 2004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setSerialNumber(mSpec.getCertificateSerialNumber()); 2014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setSubjectDN(mSpec.getCertificateSubject()); 2024f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setIssuerDN(mSpec.getCertificateSubject()); 2034f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setNotBefore(mSpec.getCertificateNotBefore()); 2044f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setNotAfter(mSpec.getCertificateNotAfter()); 2054f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyAlgorithm(mKeyAlgorithm)); 2064f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return certGen.generate(privateKey); 2074f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2084f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2094f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber @NonNull 2104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private @KeyProperties.KeyAlgorithmEnum String getKeyAlgorithm(KeyPairGeneratorSpec spec) { 2114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber String result = spec.getKeyType(); 2124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (result != null) { 2134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return result; 2144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return getAlgorithm(); 2164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static int getDefaultKeySize(int keyType) { 2194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keyType == NativeConstants.EVP_PKEY_EC) { 2204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return EC_DEFAULT_KEY_SIZE; 2214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else if (keyType == NativeConstants.EVP_PKEY_RSA) { 2224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return RSA_DEFAULT_KEY_SIZE; 2234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return -1; 2254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static void checkValidKeySize(String keyAlgorithm, int keyType, int keySize) 2284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throws InvalidAlgorithmParameterException { 2294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keyType == NativeConstants.EVP_PKEY_EC) { 2304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 2314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException("EC keys must be >= " 2324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + EC_MIN_KEY_SIZE + " and <= " + EC_MAX_KEY_SIZE); 2334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else if (keyType == NativeConstants.EVP_PKEY_RSA) { 2354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 2364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException("RSA keys must be >= " 2374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + RSA_MIN_KEY_SIZE + " and <= " + RSA_MAX_KEY_SIZE); 2384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else { 2404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 2414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Unsupported key algorithm: " + keyAlgorithm); 2424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static void checkCorrectParametersSpec(int keyType, int keySize, 2464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException { 2474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keyType == NativeConstants.EVP_PKEY_RSA && spec != null) { 2484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (spec instanceof RSAKeyGenParameterSpec) { 2494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec; 2504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keySize != -1 && keySize != rsaSpec.getKeysize()) { 2514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException("RSA key size must match: " 2524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + keySize + " vs " + rsaSpec.getKeysize()); 2534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else { 2554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 2564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "RSA may only use RSAKeyGenParameterSpec"); 2574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static String getDefaultSignatureAlgorithmForKeyAlgorithm( 2624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber @KeyProperties.KeyAlgorithmEnum String algorithm) { 2634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) { 2644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return "sha256WithRSA"; 2654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) { 2664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return "sha256WithECDSA"; 2674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else { 2684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalArgumentException("Unsupported key type " + algorithm); 2694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber private static byte[][] getArgsForKeyType(int keyType, AlgorithmParameterSpec spec) { 2734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber switch (keyType) { 2744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber case NativeConstants.EVP_PKEY_RSA: 2754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (spec instanceof RSAKeyGenParameterSpec) { 2764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec; 2774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return new byte[][] { rsaSpec.getPublicExponent().toByteArray() }; 2784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber break; 2804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber return null; 2824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2842d0ac425564ff9882ebaac5267d1a04d4af67d00Bernhard Rosenkränzer @Override 2854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public void initialize(int keysize, SecureRandom random) { 2864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new IllegalArgumentException( 2874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "cannot specify keysize with AndroidKeyStore KeyPairGenerator"); 2884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber @Override 2914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber public void initialize(AlgorithmParameterSpec params, SecureRandom random) 2924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throws InvalidAlgorithmParameterException { 2934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (params == null) { 2944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 2954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Must supply params of type " + KeyGenParameterSpec.class.getName() 2964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + " or " + KeyPairGeneratorSpec.class.getName()); 2974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 2984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 2994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber String keyAlgorithm; 3004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyGenParameterSpec spec; 3014f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber boolean encryptionAtRestRequired = false; 3024f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (params instanceof KeyPairGeneratorSpec) { 3034f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyPairGeneratorSpec legacySpec = (KeyPairGeneratorSpec) params; 3044f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber try { 3054f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyGenParameterSpec.Builder specBuilder; 3064f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber keyAlgorithm = getKeyAlgorithm(legacySpec).toUpperCase(Locale.US); 3074f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { 3084f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder = new KeyGenParameterSpec.Builder( 3094f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber legacySpec.getKeystoreAlias(), 3104f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.PURPOSE_SIGN 3114f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber | KeyProperties.PURPOSE_VERIFY); 3124f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setDigests( 3134f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_NONE, 3144f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_MD5, 3154f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA1, 3164f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA224, 3174f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA256, 3184f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA384, 3194f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA512); 3204f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { 3214f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder = new KeyGenParameterSpec.Builder( 3224f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber legacySpec.getKeystoreAlias(), 3234f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.PURPOSE_ENCRYPT 3244f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber | KeyProperties.PURPOSE_DECRYPT 3254f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber | KeyProperties.PURPOSE_SIGN 3264f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber | KeyProperties.PURPOSE_VERIFY); 3274f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setDigests( 3284f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_NONE, 3294f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_MD5, 3304f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA1, 3314f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA224, 3324f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA256, 3334f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA384, 3344f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.DIGEST_SHA512); 3354f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setSignaturePaddings( 3364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); 3374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setBlockModes(KeyProperties.BLOCK_MODE_ECB); 3384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setEncryptionPaddings( 3394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.ENCRYPTION_PADDING_NONE, 3404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); 3414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // Disable randomized encryption requirement to support encryption padding NONE 3424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber // above. 3434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setRandomizedEncryptionRequired(false); 3444f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else { 3454f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 3464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Unsupported key algorithm: " + keyAlgorithm); 3474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 3494f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (legacySpec.getKeySize() != -1) { 3504f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setKeySize(legacySpec.getKeySize()); 3514f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3524f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (legacySpec.getAlgorithmParameterSpec() != null) { 3534f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setAlgorithmParameterSpec(legacySpec.getAlgorithmParameterSpec()); 3544f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3554f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setCertificateSubject(legacySpec.getSubjectDN()); 3564f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setCertificateSerialNumber(legacySpec.getSerialNumber()); 3574f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setCertificateNotBefore(legacySpec.getStartDate()); 3584f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setCertificateNotAfter(legacySpec.getEndDate()); 3594f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber encryptionAtRestRequired = legacySpec.isEncryptionRequired(); 3604f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber specBuilder.setUserAuthenticationRequired(false); 3614f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 3624f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber spec = specBuilder.build(); 3634f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } catch (NullPointerException | IllegalArgumentException e) { 3644f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException(e); 3654f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3664f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else if (params instanceof KeyGenParameterSpec) { 3674f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber spec = (KeyGenParameterSpec) params; 3684f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber keyAlgorithm = getAlgorithm(); 3694f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } else { 3704f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 3714f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Unsupported params class: " + params.getClass().getName() 3724f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + ". Supported: " + KeyGenParameterSpec.class.getName() 3734f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber + ", " + KeyPairGeneratorSpec.class); 3744f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3754f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 3764f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm); 3774f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keyType == -1) { 3784f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 3794f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Unsupported key algorithm: " + keyAlgorithm); 3804f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3814f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber int keySize = spec.getKeySize(); 3824f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keySize == -1) { 3834f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber keySize = getDefaultKeySize(keyType); 3844f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber if (keySize == -1) { 3854f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber throw new InvalidAlgorithmParameterException( 3864f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber "Unsupported key algorithm: " + keyAlgorithm); 3874f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3884f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3894f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber checkCorrectParametersSpec(keyType, keySize, spec.getAlgorithmParameterSpec()); 3904f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber checkValidKeySize(keyAlgorithm, keyType, keySize); 3914f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber 3924f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mKeyAlgorithm = keyAlgorithm; 3934f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mKeyType = keyType; 3944f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mKeySize = keySize; 3954f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mSpec = spec; 3964f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mEncryptionAtRestRequired = encryptionAtRestRequired; 3974f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber mKeyStore = KeyStore.getInstance(); 3984f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber } 3994f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber} 4004f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber