Merge "AndroidKeyStore: add Builder for param spec"
This commit is contained in:
@@ -28,10 +28,28 @@ import java.util.Date;
|
|||||||
import javax.security.auth.x500.X500Principal;
|
import javax.security.auth.x500.X500Principal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This provides the required parameters needed for initializing the KeyPair
|
* This provides the required parameters needed for initializing the
|
||||||
* generator that works with
|
* {@code KeyPairGenerator} that works with <a href="{@docRoot}
|
||||||
* <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore
|
* guide/topics/security/keystore.html">Android KeyStore facility</a>. The
|
||||||
* facility</a>.
|
* Android KeyStore facility is accessed through a
|
||||||
|
* {@link java.security.KeyPairGenerator} API using the
|
||||||
|
* {@code AndroidKeyPairGenerator} provider. The {@code context} passed in may
|
||||||
|
* be used to pop up some UI to ask the user to unlock or initialize the Android
|
||||||
|
* keystore facility.
|
||||||
|
* <p>
|
||||||
|
* After generation, the {@code keyStoreAlias} is used with the
|
||||||
|
* {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
|
||||||
|
* interface to retrieve the {@link PrivateKey} and its associated
|
||||||
|
* {@link Certificate} chain.
|
||||||
|
* <p>
|
||||||
|
* The KeyPair generator will create a self-signed certificate with the subject
|
||||||
|
* as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
|
||||||
|
* Distinguished Name along with the other parameters specified with the
|
||||||
|
* {@link Builder}.
|
||||||
|
* <p>
|
||||||
|
* The self-signed certificate may be replaced at a later time by a certificate
|
||||||
|
* signed by a real Certificate Authority.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
||||||
@@ -74,6 +92,7 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
* period
|
* period
|
||||||
* @throws IllegalArgumentException when any argument is {@code null} or
|
* @throws IllegalArgumentException when any argument is {@code null} or
|
||||||
* {@code endDate} is before {@code startDate}.
|
* {@code endDate} is before {@code startDate}.
|
||||||
|
* @hide should be built with AndroidKeyPairGeneratorSpecBuilder
|
||||||
*/
|
*/
|
||||||
public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias,
|
public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias,
|
||||||
X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) {
|
X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) {
|
||||||
@@ -142,4 +161,121 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
|
|||||||
Date getEndDate() {
|
Date getEndDate() {
|
||||||
return mEndDate;
|
return mEndDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder class for {@link AndroidKeyPairGeneratorSpec} objects.
|
||||||
|
* <p>
|
||||||
|
* This will build a parameter spec for use with the <a href="{@docRoot}
|
||||||
|
* guide/topics/security/keystore.html">Android KeyStore facility</a>.
|
||||||
|
* <p>
|
||||||
|
* The required fields must be filled in with the builder.
|
||||||
|
* <p>
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <pre class="prettyprint">
|
||||||
|
* Calendar start = new Calendar();
|
||||||
|
* Calendar end = new Calendar();
|
||||||
|
* end.add(1, Calendar.YEAR);
|
||||||
|
*
|
||||||
|
* AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(mContext)
|
||||||
|
* .setAlias("myKey")
|
||||||
|
* .setSubject(new X500Principal("CN=myKey"))
|
||||||
|
* .setSerial(BigInteger.valueOf(1337))
|
||||||
|
* .setStartDate(start.getTime())
|
||||||
|
* .setEndDate(end.getTime())
|
||||||
|
* .build();
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
private String mKeystoreAlias;
|
||||||
|
|
||||||
|
private X500Principal mSubjectDN;
|
||||||
|
|
||||||
|
private BigInteger mSerialNumber;
|
||||||
|
|
||||||
|
private Date mStartDate;
|
||||||
|
|
||||||
|
private Date mEndDate;
|
||||||
|
|
||||||
|
public Builder(Context context) {
|
||||||
|
if (context == null) {
|
||||||
|
throw new NullPointerException("context == null");
|
||||||
|
}
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the alias to be used to retrieve the key later from a
|
||||||
|
* {@link java.security.KeyStore} instance using the
|
||||||
|
* {@code AndroidKeyStore} provider.
|
||||||
|
*/
|
||||||
|
public Builder setAlias(String alias) {
|
||||||
|
if (alias == null) {
|
||||||
|
throw new NullPointerException("alias == null");
|
||||||
|
}
|
||||||
|
mKeystoreAlias = alias;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the subject used for the self-signed certificate of the
|
||||||
|
* generated key pair.
|
||||||
|
*/
|
||||||
|
public Builder setSubject(X500Principal subject) {
|
||||||
|
if (subject == null) {
|
||||||
|
throw new NullPointerException("subject == null");
|
||||||
|
}
|
||||||
|
mSubjectDN = subject;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the serial number used for the self-signed certificate of the
|
||||||
|
* generated key pair.
|
||||||
|
*/
|
||||||
|
public Builder setSerialNumber(BigInteger serialNumber) {
|
||||||
|
if (serialNumber == null) {
|
||||||
|
throw new NullPointerException("serialNumber == null");
|
||||||
|
}
|
||||||
|
mSerialNumber = serialNumber;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the start of the validity period for the self-signed certificate
|
||||||
|
* of the generated key pair.
|
||||||
|
*/
|
||||||
|
public Builder setStartDate(Date startDate) {
|
||||||
|
if (startDate == null) {
|
||||||
|
throw new NullPointerException("startDate == null");
|
||||||
|
}
|
||||||
|
mStartDate = startDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the end of the validity period for the self-signed certificate
|
||||||
|
* of the generated key pair.
|
||||||
|
*/
|
||||||
|
public Builder setEndDate(Date endDate) {
|
||||||
|
if (endDate == null) {
|
||||||
|
throw new NullPointerException("endDate == null");
|
||||||
|
}
|
||||||
|
mEndDate = endDate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the instance of the {@code AndroidKeyPairGeneratorSpec}.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if a required field is missing
|
||||||
|
* @return built instance of {@code AndroidKeyPairGeneratorSpec}
|
||||||
|
*/
|
||||||
|
public AndroidKeyPairGeneratorSpec build() {
|
||||||
|
return new AndroidKeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
|
||||||
|
mSerialNumber, mStartDate, mEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,26 @@ public class AndroidKeyPairGeneratorSpecTest extends AndroidTestCase {
|
|||||||
assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate());
|
assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBuilder_Success() throws Exception {
|
||||||
|
AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(getContext())
|
||||||
|
.setAlias(TEST_ALIAS_1)
|
||||||
|
.setSubject(TEST_DN_1)
|
||||||
|
.setSerialNumber(SERIAL_1)
|
||||||
|
.setStartDate(NOW)
|
||||||
|
.setEndDate(NOW_PLUS_10_YEARS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertEquals("Context should be the one specified", getContext(), spec.getContext());
|
||||||
|
|
||||||
|
assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
|
||||||
|
|
||||||
|
assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
|
||||||
|
|
||||||
|
assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
|
||||||
|
|
||||||
|
assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate());
|
||||||
|
}
|
||||||
|
|
||||||
public void testConstructor_NullContext_Failure() throws Exception {
|
public void testConstructor_NullContext_Failure() throws Exception {
|
||||||
try {
|
try {
|
||||||
new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
|
new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
|
||||||
|
|||||||
Reference in New Issue
Block a user