Merge "Add support for DSA and ECDSA key types"
This commit is contained in:
@@ -244,7 +244,8 @@ public interface IKeystoreService extends IInterface {
|
||||
return _result;
|
||||
}
|
||||
|
||||
public int generate(String name, int uid, int flags) throws RemoteException {
|
||||
public int generate(String name, int uid, int keyType, int keySize, int flags,
|
||||
byte[][] args) throws RemoteException {
|
||||
Parcel _data = Parcel.obtain();
|
||||
Parcel _reply = Parcel.obtain();
|
||||
int _result;
|
||||
@@ -252,7 +253,17 @@ public interface IKeystoreService extends IInterface {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeString(name);
|
||||
_data.writeInt(uid);
|
||||
_data.writeInt(keyType);
|
||||
_data.writeInt(keySize);
|
||||
_data.writeInt(flags);
|
||||
if (args == null) {
|
||||
_data.writeInt(0);
|
||||
} else {
|
||||
_data.writeInt(args.length);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
_data.writeByteArray(args[i]);
|
||||
}
|
||||
}
|
||||
mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
_result = _reply.readInt();
|
||||
@@ -560,7 +571,8 @@ public interface IKeystoreService extends IInterface {
|
||||
|
||||
public int zero() throws RemoteException;
|
||||
|
||||
public int generate(String name, int uid, int flags) throws RemoteException;
|
||||
public int generate(String name, int uid, int keyType, int keySize, int flags, byte[][] args)
|
||||
throws RemoteException;
|
||||
|
||||
public int import_key(String name, byte[] data, int uid, int flags) throws RemoteException;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.security;
|
||||
|
||||
import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
|
||||
|
||||
import com.android.org.conscrypt.NativeCrypto;
|
||||
import com.android.org.conscrypt.OpenSSLEngine;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
@@ -33,7 +34,10 @@ import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
@@ -87,8 +91,12 @@ public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
|
||||
Credentials.deleteAllTypesForAlias(mKeyStore, alias);
|
||||
|
||||
final int keyType = KeyStore.getKeyTypeForAlgorithm(mSpec.getKeyType());
|
||||
byte[][] args = getArgsForKeyType(keyType, mSpec.getAlgorithmParameterSpec());
|
||||
|
||||
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
|
||||
if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mSpec.getFlags())) {
|
||||
if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, keyType,
|
||||
mSpec.getKeySize(), mSpec.getFlags(), args)) {
|
||||
throw new IllegalStateException("could not generate key in keystore");
|
||||
}
|
||||
|
||||
@@ -104,10 +112,10 @@ public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
|
||||
final PublicKey pubKey;
|
||||
try {
|
||||
final KeyFactory keyFact = KeyFactory.getInstance("RSA");
|
||||
final KeyFactory keyFact = KeyFactory.getInstance(mSpec.getKeyType());
|
||||
pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("Can't instantiate RSA key generator", e);
|
||||
throw new IllegalStateException("Can't instantiate key generator", e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new IllegalStateException("keystore returned invalid key encoding", e);
|
||||
}
|
||||
@@ -119,7 +127,7 @@ public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
certGen.setIssuerDN(mSpec.getSubjectDN());
|
||||
certGen.setNotBefore(mSpec.getStartDate());
|
||||
certGen.setNotAfter(mSpec.getEndDate());
|
||||
certGen.setSignatureAlgorithm("sha1WithRSA");
|
||||
certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyType(mSpec.getKeyType()));
|
||||
|
||||
final X509Certificate cert;
|
||||
try {
|
||||
@@ -146,6 +154,37 @@ public class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
|
||||
return new KeyPair(pubKey, privKey);
|
||||
}
|
||||
|
||||
private static String getDefaultSignatureAlgorithmForKeyType(String keyType) {
|
||||
if ("RSA".equalsIgnoreCase(keyType)) {
|
||||
return "sha256WithRSA";
|
||||
} else if ("DSA".equalsIgnoreCase(keyType)) {
|
||||
return "sha1WithDSA";
|
||||
} else if ("EC".equalsIgnoreCase(keyType)) {
|
||||
return "sha256WithECDSA";
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported key type " + keyType);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[][] getArgsForKeyType(int keyType, AlgorithmParameterSpec spec) {
|
||||
switch (keyType) {
|
||||
case NativeCrypto.EVP_PKEY_RSA:
|
||||
if (spec instanceof RSAKeyGenParameterSpec) {
|
||||
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
|
||||
return new byte[][] { rsaSpec.getPublicExponent().toByteArray() };
|
||||
}
|
||||
break;
|
||||
case NativeCrypto.EVP_PKEY_DSA:
|
||||
if (spec instanceof DSAParameterSpec) {
|
||||
DSAParameterSpec dsaSpec = (DSAParameterSpec) spec;
|
||||
return new byte[][] { dsaSpec.getG().toByteArray(),
|
||||
dsaSpec.getP().toByteArray(), dsaSpec.getQ().toByteArray() };
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(int keysize, SecureRandom random) {
|
||||
throw new IllegalArgumentException("cannot specify keysize with AndroidKeyPairGenerator");
|
||||
|
||||
@@ -16,13 +16,18 @@
|
||||
|
||||
package android.security;
|
||||
|
||||
import com.android.org.conscrypt.NativeCrypto;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
@@ -50,10 +55,35 @@ import javax.security.auth.x500.X500Principal;
|
||||
* certificate signed by a real Certificate Authority.
|
||||
*/
|
||||
public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
private final String mKeystoreAlias;
|
||||
/*
|
||||
* These must be kept in sync with system/security/keystore/defaults.h
|
||||
*/
|
||||
|
||||
/* DSA */
|
||||
private static final int DSA_DEFAULT_KEY_SIZE = 1024;
|
||||
private static final int DSA_MIN_KEY_SIZE = 512;
|
||||
private static final int DSA_MAX_KEY_SIZE = 8192;
|
||||
|
||||
/* EC */
|
||||
private static final int EC_DEFAULT_KEY_SIZE = 256;
|
||||
private static final int EC_MIN_KEY_SIZE = 192;
|
||||
private static final int EC_MAX_KEY_SIZE = 521;
|
||||
|
||||
/* RSA */
|
||||
private static final int RSA_DEFAULT_KEY_SIZE = 2048;
|
||||
private static final int RSA_MIN_KEY_SIZE = 512;
|
||||
private static final int RSA_MAX_KEY_SIZE = 8192;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private final String mKeystoreAlias;
|
||||
|
||||
private final String mKeyType;
|
||||
|
||||
private final int mKeySize;
|
||||
|
||||
private final AlgorithmParameterSpec mSpec;
|
||||
|
||||
private final X500Principal mSubjectDN;
|
||||
|
||||
private final BigInteger mSerialNumber;
|
||||
@@ -84,6 +114,9 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
* @param context Android context for the activity
|
||||
* @param keyStoreAlias name to use for the generated key in the Android
|
||||
* keystore
|
||||
* @param keyType key algorithm to use (RSA, DSA, EC)
|
||||
* @param keySize size of key to generate
|
||||
* @param spec the underlying key type parameters
|
||||
* @param subjectDN X.509 v3 Subject Distinguished Name
|
||||
* @param serialNumber X509 v3 certificate serial number
|
||||
* @param startDate the start of the self-signed certificate validity period
|
||||
@@ -93,9 +126,9 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
* {@code endDate} is before {@code startDate}.
|
||||
* @hide should be built with KeyPairGeneratorSpecBuilder
|
||||
*/
|
||||
public KeyPairGeneratorSpec(Context context, String keyStoreAlias,
|
||||
X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate,
|
||||
int flags) {
|
||||
public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
|
||||
AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
|
||||
Date startDate, Date endDate, int flags) {
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("context == null");
|
||||
} else if (TextUtils.isEmpty(keyStoreAlias)) {
|
||||
@@ -112,8 +145,18 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
throw new IllegalArgumentException("endDate < startDate");
|
||||
}
|
||||
|
||||
final int keyTypeInt = KeyStore.getKeyTypeForAlgorithm(keyType);
|
||||
if (keySize == -1) {
|
||||
keySize = getDefaultKeySizeForType(keyTypeInt);
|
||||
}
|
||||
checkCorrectParametersSpec(keyTypeInt, keySize, spec);
|
||||
checkValidKeySize(keyTypeInt, keySize);
|
||||
|
||||
mContext = context;
|
||||
mKeystoreAlias = keyStoreAlias;
|
||||
mKeyType = keyType;
|
||||
mKeySize = keySize;
|
||||
mSpec = spec;
|
||||
mSubjectDN = subjectDN;
|
||||
mSerialNumber = serialNumber;
|
||||
mStartDate = startDate;
|
||||
@@ -121,6 +164,64 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
private static int getDefaultKeySizeForType(int keyType) {
|
||||
if (keyType == NativeCrypto.EVP_PKEY_DSA) {
|
||||
return DSA_DEFAULT_KEY_SIZE;
|
||||
} else if (keyType == NativeCrypto.EVP_PKEY_EC) {
|
||||
return EC_DEFAULT_KEY_SIZE;
|
||||
} else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
|
||||
return RSA_DEFAULT_KEY_SIZE;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid key type " + keyType);
|
||||
}
|
||||
|
||||
private static void checkValidKeySize(int keyType, int keySize) {
|
||||
if (keyType == NativeCrypto.EVP_PKEY_DSA) {
|
||||
if (keySize < DSA_MIN_KEY_SIZE || keySize > DSA_MAX_KEY_SIZE) {
|
||||
throw new IllegalArgumentException("DSA keys must be >= " + DSA_MIN_KEY_SIZE
|
||||
+ " and <= " + DSA_MAX_KEY_SIZE);
|
||||
}
|
||||
} else if (keyType == NativeCrypto.EVP_PKEY_EC) {
|
||||
if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
|
||||
throw new IllegalArgumentException("EC keys must be >= " + EC_MIN_KEY_SIZE
|
||||
+ " and <= " + EC_MAX_KEY_SIZE);
|
||||
}
|
||||
} else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
|
||||
if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
|
||||
throw new IllegalArgumentException("RSA keys must be >= " + RSA_MIN_KEY_SIZE
|
||||
+ " and <= " + RSA_MAX_KEY_SIZE);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid key type " + keyType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCorrectParametersSpec(int keyType, int keySize,
|
||||
AlgorithmParameterSpec spec) {
|
||||
if (keyType == NativeCrypto.EVP_PKEY_DSA && spec != null) {
|
||||
if (!(spec instanceof DSAParameterSpec)) {
|
||||
throw new IllegalArgumentException("DSA keys must have DSAParameterSpec specified");
|
||||
}
|
||||
} else if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
|
||||
if (spec instanceof RSAKeyGenParameterSpec) {
|
||||
RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
|
||||
if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
|
||||
throw new IllegalArgumentException("RSA key size must match: " + keySize
|
||||
+ " vs " + rsaSpec.getKeysize());
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("RSA may only use RSAKeyGenParameterSpec");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Android context used for operations with this instance.
|
||||
*/
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alias that will be used in the {@code java.security.KeyStore}
|
||||
* in conjunction with the {@code AndroidKeyStore}.
|
||||
@@ -130,10 +231,31 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Android context used for operations with this instance.
|
||||
* Returns the key type (e.g., "RSA", "DSA", "EC") specified by this
|
||||
* parameter.
|
||||
* @hide
|
||||
*/
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
public String getKeyType() {
|
||||
return mKeyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key size specified by this parameter. For instance, for RSA
|
||||
* this will return the modulus size and for EC it will return the field
|
||||
* size.
|
||||
* @hide
|
||||
*/
|
||||
public int getKeySize() {
|
||||
return mKeySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AlgorithmParameterSpec} that will be used for creation
|
||||
* of the key pair.
|
||||
* @hide
|
||||
*/
|
||||
public AlgorithmParameterSpec getAlgorithmParameterSpec() {
|
||||
return mSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,6 +331,12 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
|
||||
private String mKeystoreAlias;
|
||||
|
||||
private String mKeyType = "RSA";
|
||||
|
||||
private int mKeySize = -1;
|
||||
|
||||
private AlgorithmParameterSpec mSpec;
|
||||
|
||||
private X500Principal mSubjectDN;
|
||||
|
||||
private BigInteger mSerialNumber;
|
||||
@@ -245,6 +373,52 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key type (e.g., RSA, DSA, EC) of the keypair to be created.
|
||||
* @hide
|
||||
*/
|
||||
public Builder setKeyType(String keyType) throws NoSuchAlgorithmException {
|
||||
if (keyType == null) {
|
||||
throw new NullPointerException("keyType == null");
|
||||
} else {
|
||||
try {
|
||||
KeyStore.getKeyTypeForAlgorithm(keyType);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
|
||||
}
|
||||
}
|
||||
mKeyType = keyType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key size for the keypair to be created. For instance, for a
|
||||
* key type of RSA this will set the modulus size and for a key type of
|
||||
* EC it will select a curve with a matching field size.
|
||||
* @hide
|
||||
*/
|
||||
public Builder setKeySize(int keySize) {
|
||||
if (keySize < 0) {
|
||||
throw new IllegalArgumentException("keySize < 0");
|
||||
}
|
||||
mKeySize = keySize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the underlying key type's parameters. This is required for DSA
|
||||
* where you must set this to an instance of
|
||||
* {@link java.security.spec.DSAParameterSpec}.
|
||||
* @hide
|
||||
*/
|
||||
public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) {
|
||||
if (spec == null) {
|
||||
throw new NullPointerException("spec == null");
|
||||
}
|
||||
mSpec = spec;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subject used for the self-signed certificate of the
|
||||
* generated key pair.
|
||||
@@ -311,8 +485,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||
* @return built instance of {@code KeyPairGeneratorSpec}
|
||||
*/
|
||||
public KeyPairGeneratorSpec build() {
|
||||
return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
|
||||
mSerialNumber, mStartDate, mEndDate, mFlags);
|
||||
return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mKeyType, mKeySize, mSpec,
|
||||
mSubjectDN, mSerialNumber, mStartDate, mEndDate, mFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.security;
|
||||
|
||||
import com.android.org.conscrypt.NativeCrypto;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
@@ -64,6 +66,18 @@ public class KeyStore {
|
||||
return new KeyStore(keystore);
|
||||
}
|
||||
|
||||
static int getKeyTypeForAlgorithm(String keyType) throws IllegalArgumentException {
|
||||
if ("RSA".equalsIgnoreCase(keyType)) {
|
||||
return NativeCrypto.EVP_PKEY_RSA;
|
||||
} else if ("DSA".equalsIgnoreCase(keyType)) {
|
||||
return NativeCrypto.EVP_PKEY_DSA;
|
||||
} else if ("EC".equalsIgnoreCase(keyType)) {
|
||||
return NativeCrypto.EVP_PKEY_EC;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported key type: " + keyType);
|
||||
}
|
||||
}
|
||||
|
||||
public State state() {
|
||||
final int ret;
|
||||
try {
|
||||
@@ -188,9 +202,10 @@ public class KeyStore {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean generate(String key, int uid, int flags) {
|
||||
public boolean generate(String key, int uid, int keyType, int keySize, int flags,
|
||||
byte[][] args) {
|
||||
try {
|
||||
return mBinder.generate(key, uid, flags) == NO_ERROR;
|
||||
return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR;
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Cannot connect to keystore", e);
|
||||
return false;
|
||||
|
||||
@@ -27,6 +27,13 @@ import java.security.SecureRandom;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@@ -118,6 +125,8 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
mGenerator.initialize(
|
||||
new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("RSA")
|
||||
.setKeySize(1024)
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
@@ -142,10 +151,207 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS);
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_Unencrypted_Success() throws Exception {
|
||||
public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception {
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("DSA")
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
.setEndDate(NOW_PLUS_10_YEARS)
|
||||
.build());
|
||||
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()
|
||||
throws Exception {
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("DSA")
|
||||
.setKeySize(2048)
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
.setEndDate(NOW_PLUS_10_YEARS)
|
||||
.build());
|
||||
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()
|
||||
throws Exception {
|
||||
/*
|
||||
* generated using: openssl dsaparam -C 2048
|
||||
*/
|
||||
BigInteger p = new BigInteger(1, new byte[] {
|
||||
(byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C,
|
||||
(byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD,
|
||||
(byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32,
|
||||
(byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A,
|
||||
(byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1,
|
||||
(byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C,
|
||||
(byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94,
|
||||
(byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E,
|
||||
(byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC,
|
||||
(byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96,
|
||||
(byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26,
|
||||
(byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F,
|
||||
(byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB,
|
||||
(byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88,
|
||||
(byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2,
|
||||
(byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C,
|
||||
(byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11,
|
||||
(byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44,
|
||||
(byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB,
|
||||
(byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38,
|
||||
(byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1,
|
||||
(byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5,
|
||||
(byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0,
|
||||
(byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76,
|
||||
(byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98,
|
||||
(byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED,
|
||||
(byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C,
|
||||
(byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99,
|
||||
(byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5,
|
||||
(byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23,
|
||||
(byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13,
|
||||
(byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3,
|
||||
(byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4,
|
||||
(byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B,
|
||||
(byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5,
|
||||
(byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40,
|
||||
(byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71,
|
||||
(byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D,
|
||||
(byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A,
|
||||
(byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED,
|
||||
(byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D,
|
||||
(byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44,
|
||||
(byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43,
|
||||
});
|
||||
|
||||
BigInteger q = new BigInteger(1, new byte[] {
|
||||
(byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6,
|
||||
(byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2,
|
||||
(byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1,
|
||||
(byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35,
|
||||
(byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC,
|
||||
(byte) 0xA8, (byte) 0xE5,
|
||||
});
|
||||
|
||||
BigInteger g = new BigInteger(1, new byte[] {
|
||||
(byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9,
|
||||
(byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B,
|
||||
(byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA,
|
||||
(byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8,
|
||||
(byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64,
|
||||
(byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67,
|
||||
(byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10,
|
||||
(byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04,
|
||||
(byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B,
|
||||
(byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11,
|
||||
(byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3,
|
||||
(byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69,
|
||||
(byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97,
|
||||
(byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27,
|
||||
(byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9,
|
||||
(byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4,
|
||||
(byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36,
|
||||
(byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93,
|
||||
(byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99,
|
||||
(byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC,
|
||||
(byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01,
|
||||
(byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D,
|
||||
(byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF,
|
||||
(byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB,
|
||||
(byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59,
|
||||
(byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16,
|
||||
(byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41,
|
||||
(byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5,
|
||||
(byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19,
|
||||
(byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84,
|
||||
(byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40,
|
||||
(byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E,
|
||||
(byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC,
|
||||
(byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0,
|
||||
(byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76,
|
||||
(byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3,
|
||||
(byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68,
|
||||
(byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF,
|
||||
(byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81,
|
||||
(byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7,
|
||||
(byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00,
|
||||
(byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11,
|
||||
(byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA,
|
||||
});
|
||||
|
||||
AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g);
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("DSA")
|
||||
.setKeySize(2048)
|
||||
.setAlgorithmParameterSpec(spec)
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
.setEndDate(NOW_PLUS_10_YEARS)
|
||||
.build());
|
||||
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("EC")
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
.setEndDate(NOW_PLUS_10_YEARS)
|
||||
.build());
|
||||
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception {
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("EC")
|
||||
.setKeySize(521)
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
.setEndDate(NOW_PLUS_10_YEARS)
|
||||
.build());
|
||||
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception {
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setSubject(TEST_DN_1)
|
||||
@@ -157,7 +363,28 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS);
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_RSA_WithParams_Unencrypted_Success()
|
||||
throws Exception {
|
||||
AlgorithmParameterSpec spec = new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3L));
|
||||
mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeySize(1024)
|
||||
.setAlgorithmParameterSpec(spec)
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(TEST_SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
.setEndDate(NOW_PLUS_10_YEARS)
|
||||
.build());
|
||||
|
||||
final KeyPair pair = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair);
|
||||
|
||||
assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 1024, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
|
||||
@@ -172,8 +399,8 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
.build());
|
||||
final KeyPair pair1 = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair1);
|
||||
assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
|
||||
NOW, NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
// Replace the original key
|
||||
@@ -187,8 +414,8 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
.build());
|
||||
final KeyPair pair2 = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair2);
|
||||
assertKeyPairCorrect(pair2, TEST_ALIAS_2, TEST_DN_2, TEST_SERIAL_2, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
|
||||
NOW, NOW_PLUS_10_YEARS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +432,8 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
.build());
|
||||
final KeyPair pair1 = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair1);
|
||||
assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
|
||||
NOW, NOW_PLUS_10_YEARS);
|
||||
}
|
||||
|
||||
// Attempt to replace previous key
|
||||
@@ -230,18 +457,45 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
|
||||
|
||||
final KeyPair pair2 = mGenerator.generateKeyPair();
|
||||
assertNotNull("The KeyPair returned should not be null", pair2);
|
||||
assertKeyPairCorrect(pair2, TEST_ALIAS_1, TEST_DN_2, TEST_SERIAL_2, NOW,
|
||||
NOW_PLUS_10_YEARS);
|
||||
assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
|
||||
NOW, NOW_PLUS_10_YEARS);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertKeyPairCorrect(KeyPair pair, String alias, X500Principal dn,
|
||||
BigInteger serial, Date start, Date end) throws Exception {
|
||||
private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize,
|
||||
AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)
|
||||
throws Exception {
|
||||
final PublicKey pubKey = pair.getPublic();
|
||||
assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
|
||||
assertEquals(keyType, pubKey.getAlgorithm());
|
||||
|
||||
if ("DSA".equalsIgnoreCase(keyType)) {
|
||||
DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
|
||||
DSAParams actualParams = dsaPubKey.getParams();
|
||||
assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
|
||||
if (spec != null) {
|
||||
DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
|
||||
assertEquals(expectedParams.getP(), actualParams.getP());
|
||||
assertEquals(expectedParams.getQ(), actualParams.getQ());
|
||||
assertEquals(expectedParams.getG(), actualParams.getG());
|
||||
}
|
||||
} else if ("EC".equalsIgnoreCase(keyType)) {
|
||||
assertEquals("Curve should be what was specified during initialization", keySize,
|
||||
((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
|
||||
} else if ("RSA".equalsIgnoreCase(keyType)) {
|
||||
RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
|
||||
assertEquals("Modulus size should be what is specified during initialization",
|
||||
(keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
|
||||
if (spec != null) {
|
||||
RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
|
||||
assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
|
||||
assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
|
||||
}
|
||||
}
|
||||
|
||||
final PrivateKey privKey = pair.getPrivate();
|
||||
assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
|
||||
assertEquals(keyType, privKey.getAlgorithm());
|
||||
|
||||
final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias);
|
||||
assertNotNull("The user certificate should exist for the generated entry", userCertBytes);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,13 +40,17 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_Success() throws Exception {
|
||||
KeyPairGeneratorSpec spec =
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
|
||||
NOW, NOW_PLUS_10_YEARS, 0);
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1,
|
||||
SERIAL_1, NOW, NOW_PLUS_10_YEARS, 0);
|
||||
|
||||
assertEquals("Context should be the one specified", getContext(), spec.getContext());
|
||||
|
||||
assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
|
||||
|
||||
assertEquals("Key algorithm should be the one specified", "RSA", spec.getKeyType());
|
||||
|
||||
assertEquals("Key size should be the one specified", 1024, spec.getKeySize());
|
||||
|
||||
assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
|
||||
|
||||
assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
|
||||
@@ -57,6 +61,8 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
public void testBuilder_Success() throws Exception {
|
||||
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
|
||||
.setAlias(TEST_ALIAS_1)
|
||||
.setKeyType("RSA")
|
||||
.setKeySize(1024)
|
||||
.setSubject(TEST_DN_1)
|
||||
.setSerialNumber(SERIAL_1)
|
||||
.setStartDate(NOW)
|
||||
@@ -68,6 +74,10 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
|
||||
|
||||
assertEquals("Key algorithm should be the one specified", "RSA", spec.getKeyType());
|
||||
|
||||
assertEquals("Key size should be the one specified", 1024, spec.getKeySize());
|
||||
|
||||
assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
|
||||
|
||||
assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
|
||||
@@ -79,7 +89,7 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_NullContext_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
|
||||
new KeyPairGeneratorSpec(null, TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS, 0);
|
||||
fail("Should throw IllegalArgumentException when context is null");
|
||||
} catch (IllegalArgumentException success) {
|
||||
@@ -88,7 +98,7 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_NullKeystoreAlias_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(getContext(), null, TEST_DN_1, SERIAL_1, NOW,
|
||||
new KeyPairGeneratorSpec(getContext(), null, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS, 0);
|
||||
fail("Should throw IllegalArgumentException when keystoreAlias is null");
|
||||
} catch (IllegalArgumentException success) {
|
||||
@@ -97,7 +107,7 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_NullSubjectDN_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, null, SERIAL_1, NOW,
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
|
||||
NOW_PLUS_10_YEARS, 0);
|
||||
fail("Should throw IllegalArgumentException when subjectDN is null");
|
||||
} catch (IllegalArgumentException success) {
|
||||
@@ -106,7 +116,7 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_NullSerial_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, null, NOW,
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
|
||||
NOW_PLUS_10_YEARS, 0);
|
||||
fail("Should throw IllegalArgumentException when startDate is null");
|
||||
} catch (IllegalArgumentException success) {
|
||||
@@ -115,8 +125,8 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_NullStartDate_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, null,
|
||||
NOW_PLUS_10_YEARS, 0);
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
|
||||
null, NOW_PLUS_10_YEARS, 0);
|
||||
fail("Should throw IllegalArgumentException when startDate is null");
|
||||
} catch (IllegalArgumentException success) {
|
||||
}
|
||||
@@ -124,8 +134,8 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_NullEndDate_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
|
||||
null, 0);
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
|
||||
NOW, null, 0);
|
||||
fail("Should throw IllegalArgumentException when keystoreAlias is null");
|
||||
} catch (IllegalArgumentException success) {
|
||||
}
|
||||
@@ -133,7 +143,7 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
|
||||
|
||||
public void testConstructor_EndBeforeStart_Failure() throws Exception {
|
||||
try {
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
|
||||
new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
|
||||
NOW_PLUS_10_YEARS, NOW, 0);
|
||||
fail("Should throw IllegalArgumentException when end is before start");
|
||||
} catch (IllegalArgumentException success) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.security.KeyStore;
|
||||
import android.test.ActivityUnitTestCase;
|
||||
import android.test.AssertionFailedError;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import com.android.org.conscrypt.NativeCrypto;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
@@ -347,21 +348,24 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
|
||||
public void testGenerate_NotInitialized_Fail() throws Exception {
|
||||
assertFalse("Should fail when keystore is not initialized",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
}
|
||||
|
||||
public void testGenerate_Locked_Fail() throws Exception {
|
||||
mKeyStore.password(TEST_PASSWD);
|
||||
mKeyStore.lock();
|
||||
assertFalse("Should fail when keystore is locked",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
}
|
||||
|
||||
public void testGenerate_Success() throws Exception {
|
||||
assertTrue(mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key when unlocked",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
assertTrue(mKeyStore.contains(TEST_KEYNAME));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
|
||||
}
|
||||
@@ -370,7 +374,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
assertTrue(mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key when unlocked",
|
||||
mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME));
|
||||
}
|
||||
@@ -378,7 +383,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
|
||||
assertTrue(mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID, KeyStore.FLAG_ENCRYPTED));
|
||||
assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
|
||||
NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME));
|
||||
@@ -424,7 +430,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
public void testSign_Success() throws Exception {
|
||||
mKeyStore.password(TEST_PASSWD);
|
||||
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
assertTrue(mKeyStore.contains(TEST_KEYNAME));
|
||||
final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
|
||||
|
||||
@@ -434,7 +441,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
public void testVerify_Success() throws Exception {
|
||||
mKeyStore.password(TEST_PASSWD);
|
||||
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
assertTrue(mKeyStore.contains(TEST_KEYNAME));
|
||||
final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
|
||||
|
||||
@@ -461,7 +469,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key for testcase",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertTrue("Should be able to grant key to other user",
|
||||
mKeyStore.grant(TEST_KEYNAME, 0));
|
||||
@@ -494,7 +503,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key for testcase",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertTrue("Should be able to grant key to other user",
|
||||
mKeyStore.grant(TEST_KEYNAME, 0));
|
||||
@@ -527,7 +537,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key for testcase",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertFalse("Should not be able to revoke not existent grant",
|
||||
mKeyStore.ungrant(TEST_KEYNAME, 0));
|
||||
@@ -538,7 +549,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key for testcase",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertTrue("Should be able to grant key to other user",
|
||||
mKeyStore.grant(TEST_KEYNAME, 0));
|
||||
@@ -555,7 +567,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
mKeyStore.password(TEST_PASSWD));
|
||||
|
||||
assertTrue("Should be able to generate key for testcase",
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertTrue("Should be able to grant key to other user",
|
||||
mKeyStore.grant(TEST_KEYNAME, 0));
|
||||
@@ -575,7 +588,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME));
|
||||
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertTrue(mKeyStore.contains(TEST_KEYNAME));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
|
||||
@@ -613,7 +627,8 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
|
||||
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME));
|
||||
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
|
||||
assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
|
||||
1024, KeyStore.FLAG_ENCRYPTED, null));
|
||||
|
||||
assertTrue(mKeyStore.contains(TEST_KEYNAME));
|
||||
assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
|
||||
|
||||
Reference in New Issue
Block a user