blob: a3e5d9690ef7132c65d29fd9ffe316acaf09d208 [file] [log] [blame]
/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.keystore.cts;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.test.MoreAsserts;
import junit.framework.TestCase;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.util.Arrays;
import java.util.Date;
import javax.security.auth.x500.X500Principal;
public class KeyGenParameterSpecTest extends TestCase {
private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
public void testDefaults() {
// Set only the mandatory parameters and assert values returned by getters.
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
"arbitrary", KeyProperties.PURPOSE_ENCRYPT)
.build();
assertEquals("arbitrary", spec.getKeystoreAlias());
assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
assertNull(null, spec.getAlgorithmParameterSpec());
MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getCertificateNotBefore());
assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getCertificateNotAfter());
assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getCertificateSerialNumber());
assertEquals(DEFAULT_CERT_SUBJECT, spec.getCertificateSubject());
assertFalse(spec.isDigestsSpecified());
try {
spec.getDigests();
fail();
} catch (IllegalStateException expected) {}
MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
assertEquals(-1, spec.getKeySize());
assertNull(spec.getKeyValidityStart());
assertNull(spec.getKeyValidityForOriginationEnd());
assertNull(spec.getKeyValidityForConsumptionEnd());
assertTrue(spec.isRandomizedEncryptionRequired());
MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
assertFalse(spec.isUserAuthenticationRequired());
assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
}
public void testSettersReflectedInGetters() {
// Set all parameters to non-default values and then assert that getters reflect that.
Date certNotBeforeDate = new Date(System.currentTimeMillis());
Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
AlgorithmParameterSpec algSpecificParams = new ECGenParameterSpec("secp256r1");
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
"arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
.setAlgorithmParameterSpec(algSpecificParams)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
.setCertificateNotBefore(certNotBeforeDate)
.setCertificateNotAfter(certNotAfterDate)
.setCertificateSerialNumber(new BigInteger("13946146"))
.setCertificateSubject(new X500Principal("CN=test"))
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setKeySize(1234)
.setKeyValidityStart(keyValidityStartDate)
.setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
.setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
.setRandomizedEncryptionRequired(false)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(12345)
.build();
assertEquals("arbitrary", spec.getKeystoreAlias());
assertEquals(
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
assertSame(algSpecificParams, spec.getAlgorithmParameterSpec());
MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC);
assertEquals(certNotBeforeDate, spec.getCertificateNotBefore());
assertEquals(certNotAfterDate, spec.getCertificateNotAfter());
assertEquals(new BigInteger("13946146"), spec.getCertificateSerialNumber());
assertEquals(new X500Principal("CN=test"), spec.getCertificateSubject());
assertTrue(spec.isDigestsSpecified());
MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384);
MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7);
assertEquals(1234, spec.getKeySize());
assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
assertFalse(spec.isRandomizedEncryptionRequired());
MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
assertTrue(spec.isUserAuthenticationRequired());
assertEquals(12345, spec.getUserAuthenticationValidityDurationSeconds());
}
public void testNullAliasNotPermitted() {
try {
new KeyGenParameterSpec.Builder(null, KeyProperties.PURPOSE_ENCRYPT);
fail();
} catch (NullPointerException expected) {}
}
public void testEmptyAliasNotPermitted() {
try {
new KeyGenParameterSpec.Builder("", KeyProperties.PURPOSE_ENCRYPT);
fail();
} catch (IllegalArgumentException expected) {}
}
public void testSetKeyValidityEndDateAppliesToBothEndDates() {
Date date = new Date(System.currentTimeMillis() + 555555);
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
"ignore", KeyProperties.PURPOSE_VERIFY)
.setKeyValidityEnd(date)
.build();
assertEquals(date, spec.getKeyValidityForOriginationEnd());
assertEquals(date, spec.getKeyValidityForConsumptionEnd());
}
public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("alias", 0);
try {
builder.setUserAuthenticationValidityDurationSeconds(-2);
fail();
} catch (IllegalArgumentException expected) {}
try {
builder.setUserAuthenticationValidityDurationSeconds(-100);
fail();
} catch (IllegalArgumentException expected) {}
try {
builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
fail();
} catch (IllegalArgumentException expected) {}
builder.setUserAuthenticationValidityDurationSeconds(-1);
builder.setUserAuthenticationValidityDurationSeconds(0);
builder.setUserAuthenticationValidityDurationSeconds(1);
builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
try {
builder.setUserAuthenticationValidityDurationSeconds(-2);
fail();
} catch (IllegalArgumentException expected) {}
}
public void testImmutabilityViaSetterParams() {
// Assert that all mutable parameters provided to setters are copied to ensure that values
// returned by getters never change.
String[] blockModes =
new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
String[] originalBlockModes = blockModes.clone();
Date certNotBeforeDate = new Date(System.currentTimeMillis());
Date originalCertNotBeforeDate = new Date(certNotBeforeDate.getTime());
Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
Date originalCertNotAfterDate = new Date(certNotAfterDate.getTime());
Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
Date originalKeyValidityEndDateForOrigination =
new Date(keyValidityEndDateForOrigination.getTime());
Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
Date originalKeyValidityEndDateForConsumption =
new Date(keyValidityEndDateForConsumption.getTime());
String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
String[] originalDigests = digests.clone();
String[] encryptionPaddings = new String[] {
KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
String[] originalEncryptionPaddings = encryptionPaddings.clone();
String[] signaturePaddings = new String[] {
KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
String[] originalSignaturePaddings = signaturePaddings.clone();
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
"arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
.setBlockModes(blockModes)
.setCertificateNotBefore(certNotBeforeDate)
.setCertificateNotAfter(certNotAfterDate)
.setDigests(digests)
.setEncryptionPaddings(encryptionPaddings)
.setKeyValidityStart(keyValidityStartDate)
.setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
.setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
.setSignaturePaddings(signaturePaddings)
.build();
assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
blockModes[0] = null;
assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
certNotBeforeDate.setTime(1234567890L);
assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
certNotAfterDate.setTime(1234567890L);
assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
digests[1] = null;
assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
assertEquals(Arrays.asList(originalEncryptionPaddings),
Arrays.asList(spec.getEncryptionPaddings()));
encryptionPaddings[0] = null;
assertEquals(Arrays.asList(originalEncryptionPaddings),
Arrays.asList(spec.getEncryptionPaddings()));
assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
keyValidityStartDate.setTime(1234567890L);
assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
assertEquals(originalKeyValidityEndDateForOrigination,
spec.getKeyValidityForOriginationEnd());
keyValidityEndDateForOrigination.setTime(1234567890L);
assertEquals(originalKeyValidityEndDateForOrigination,
spec.getKeyValidityForOriginationEnd());
assertEquals(originalKeyValidityEndDateForConsumption,
spec.getKeyValidityForConsumptionEnd());
keyValidityEndDateForConsumption.setTime(1234567890L);
assertEquals(originalKeyValidityEndDateForConsumption,
spec.getKeyValidityForConsumptionEnd());
assertEquals(Arrays.asList(originalSignaturePaddings),
Arrays.asList(spec.getSignaturePaddings()));
signaturePaddings[1] = null;
assertEquals(Arrays.asList(originalSignaturePaddings),
Arrays.asList(spec.getSignaturePaddings()));
}
public void testImmutabilityViaGetterReturnValues() {
// Assert that none of the mutable return values from getters modify the state of the spec.
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
"arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
.setCertificateNotBefore(new Date(System.currentTimeMillis()))
.setCertificateNotAfter(new Date(System.currentTimeMillis() + 12345678))
.setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
.setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
.setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PSS,
KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.build();
String[] originalBlockModes = spec.getBlockModes().clone();
spec.getBlockModes()[0] = null;
assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
Date originalCertNotBeforeDate = (Date) spec.getCertificateNotBefore().clone();
spec.getCertificateNotBefore().setTime(1234567890L);
assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
Date originalCertNotAfterDate = (Date) spec.getCertificateNotAfter().clone();
spec.getCertificateNotAfter().setTime(1234567890L);
assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
String[] originalDigests = spec.getDigests().clone();
spec.getDigests()[0] = null;
assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
spec.getEncryptionPaddings()[0] = null;
assertEquals(Arrays.asList(originalEncryptionPaddings),
Arrays.asList(spec.getEncryptionPaddings()));
Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
spec.getKeyValidityStart().setTime(1234567890L);
assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
Date originalKeyValidityEndDateForOrigination =
(Date) spec.getKeyValidityForOriginationEnd().clone();
spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
assertEquals(originalKeyValidityEndDateForOrigination,
spec.getKeyValidityForOriginationEnd());
Date originalKeyValidityEndDateForConsumption =
(Date) spec.getKeyValidityForConsumptionEnd().clone();
spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
assertEquals(originalKeyValidityEndDateForConsumption,
spec.getKeyValidityForConsumptionEnd());
String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
spec.getSignaturePaddings()[0] = null;
assertEquals(Arrays.asList(originalSignaturePaddings),
Arrays.asList(spec.getSignaturePaddings()));
}
}