1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security; 18 19 import static org.hamcrest.Matchers.is; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertThat; 22 23 import android.os.Parcel; 24 import android.security.keystore.KeyGenParameterSpec; 25 import android.security.keystore.ParcelableKeyGenParameterSpec; 26 import android.security.keystore.KeyProperties; 27 import android.support.test.runner.AndroidJUnit4; 28 import java.math.BigInteger; 29 import java.security.spec.ECGenParameterSpec; 30 import java.security.spec.RSAKeyGenParameterSpec; 31 import java.util.Date; 32 import javax.security.auth.x500.X500Principal; 33 import org.junit.Test; 34 import org.junit.runner.RunWith; 35 36 /** Unit tests for {@link ParcelableKeyGenParameterSpec}. */ 37 @RunWith(AndroidJUnit4.class) 38 public final class ParcelableKeyGenParameterSpecTest { 39 static final String ALIAS = "keystore-alias"; 40 static final String ANOTHER_ALIAS = "another-keystore-alias"; 41 static final int KEY_PURPOSES = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY; 42 static final int UID = 1230; 43 static final int KEYSIZE = 2048; 44 static final X500Principal SUBJECT = new X500Principal("CN=subject"); 45 static final BigInteger SERIAL = new BigInteger("1234567890"); 46 static final Date NOT_BEFORE = new Date(1511799590); 47 static final Date NOT_AFTER = new Date(1511899590); 48 static final Date KEY_VALIDITY_START = new Date(1511799591); 49 static final Date KEY_VALIDITY_FOR_ORIG_END = new Date(1511799593); 50 static final Date KEY_VALIDITY_FOR_CONSUMPTION_END = new Date(1511799594); 51 static final String DIGEST = KeyProperties.DIGEST_SHA256; 52 static final String ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1; 53 static final String SIGNATURE_PADDING = KeyProperties.SIGNATURE_PADDING_RSA_PSS; 54 static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC; 55 static final int USER_AUTHENTICATION_DURATION = 300; 56 static final byte[] ATTESTATION_CHALLENGE = new byte[] {'c', 'h'}; 57 58 public static KeyGenParameterSpec configureDefaultSpec() { 59 return new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 60 .setUid(UID) 61 .setKeySize(KEYSIZE) 62 .setCertificateSubject(SUBJECT) 63 .setCertificateSerialNumber(SERIAL) 64 .setCertificateNotBefore(NOT_BEFORE) 65 .setCertificateNotAfter(NOT_AFTER) 66 .setKeyValidityStart(KEY_VALIDITY_START) 67 .setKeyValidityForOriginationEnd(KEY_VALIDITY_FOR_ORIG_END) 68 .setKeyValidityForConsumptionEnd(KEY_VALIDITY_FOR_CONSUMPTION_END) 69 .setDigests(DIGEST) 70 .setEncryptionPaddings(ENCRYPTION_PADDING) 71 .setSignaturePaddings(SIGNATURE_PADDING) 72 .setBlockModes(BLOCK_MODE) 73 .setRandomizedEncryptionRequired(true) 74 .setUserAuthenticationRequired(true) 75 .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_DURATION) 76 .setAttestationChallenge(ATTESTATION_CHALLENGE) 77 .setUniqueIdIncluded(true) 78 .setUserAuthenticationValidWhileOnBody(true) 79 .setInvalidatedByBiometricEnrollment(true) 80 .build(); 81 } 82 83 public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) { 84 assertThat(spec.getKeystoreAlias(), is(alias)); 85 assertThat(spec.getPurposes(), is(KEY_PURPOSES)); 86 assertThat(spec.getUid(), is(uid)); 87 assertThat(spec.getKeySize(), is(KEYSIZE)); 88 assertThat(spec.getCertificateSubject(), is(SUBJECT)); 89 assertThat(spec.getCertificateSerialNumber(), is(SERIAL)); 90 assertThat(spec.getCertificateNotBefore(), is(NOT_BEFORE)); 91 assertThat(spec.getCertificateNotAfter(), is(NOT_AFTER)); 92 assertThat(spec.getKeyValidityStart(), is(KEY_VALIDITY_START)); 93 assertThat(spec.getKeyValidityForOriginationEnd(), is(KEY_VALIDITY_FOR_ORIG_END)); 94 assertThat(spec.getKeyValidityForConsumptionEnd(), is(KEY_VALIDITY_FOR_CONSUMPTION_END)); 95 assertThat(spec.getDigests(), is(new String[] {DIGEST})); 96 assertThat(spec.getEncryptionPaddings(), is(new String[] {ENCRYPTION_PADDING})); 97 assertThat(spec.getSignaturePaddings(), is(new String[] {SIGNATURE_PADDING})); 98 assertThat(spec.getBlockModes(), is(new String[] {BLOCK_MODE})); 99 assertThat(spec.isRandomizedEncryptionRequired(), is(true)); 100 assertThat(spec.isUserAuthenticationRequired(), is(true)); 101 assertThat( 102 spec.getUserAuthenticationValidityDurationSeconds(), 103 is(USER_AUTHENTICATION_DURATION)); 104 assertThat(spec.getAttestationChallenge(), is(ATTESTATION_CHALLENGE)); 105 assertThat(spec.isUniqueIdIncluded(), is(true)); 106 assertThat(spec.isUserAuthenticationValidWhileOnBody(), is(true)); 107 assertThat(spec.isInvalidatedByBiometricEnrollment(), is(true)); 108 } 109 110 private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) { 111 Parcel parcel = Parcel.obtain(); 112 spec.writeToParcel(parcel, spec.describeContents()); 113 114 parcel.setDataPosition(0); 115 return parcel; 116 } 117 118 @Test 119 public void testParcelingWithAllValues() { 120 ParcelableKeyGenParameterSpec spec = 121 new ParcelableKeyGenParameterSpec(configureDefaultSpec()); 122 Parcel parcel = parcelForReading(spec); 123 ParcelableKeyGenParameterSpec fromParcel = 124 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel); 125 validateSpecValues(fromParcel.getSpec(), UID, ALIAS); 126 assertThat(parcel.dataAvail(), is(0)); 127 } 128 129 @Test 130 public void testParcelingWithNullValues() { 131 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 132 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES).build()); 133 134 Parcel parcel = parcelForReading(spec); 135 KeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR 136 .createFromParcel(parcel) 137 .getSpec(); 138 assertThat(fromParcel.getKeystoreAlias(), is(ALIAS)); 139 assertThat(fromParcel.getPurposes(), is(KEY_PURPOSES)); 140 assertThat(fromParcel.getCertificateNotBefore(), is(new Date(0L))); 141 assertThat(fromParcel.getCertificateNotAfter(), is(new Date(2461449600000L))); 142 assertThat(parcel.dataAvail(), is(0)); 143 } 144 145 @Test 146 public void testParcelingRSAAlgoParameter() { 147 RSAKeyGenParameterSpec rsaSpec = 148 new RSAKeyGenParameterSpec(2048, new BigInteger("5231123")); 149 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 150 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 151 .setAlgorithmParameterSpec(rsaSpec) 152 .build()); 153 154 Parcel parcel = parcelForReading(spec); 155 KeyGenParameterSpec fromParcel = 156 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec(); 157 RSAKeyGenParameterSpec parcelSpec = 158 (RSAKeyGenParameterSpec) fromParcel.getAlgorithmParameterSpec(); 159 // Compare individual fields as RSAKeyGenParameterSpec, on android, does not 160 // implement equals() 161 assertEquals(parcelSpec.getKeysize(), rsaSpec.getKeysize()); 162 assertEquals(parcelSpec.getPublicExponent(), rsaSpec.getPublicExponent()); 163 } 164 165 @Test 166 public void testParcelingECAlgoParameter() { 167 ECGenParameterSpec ecSpec = new ECGenParameterSpec("P-256"); 168 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 169 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 170 .setAlgorithmParameterSpec(ecSpec) 171 .build()); 172 Parcel parcel = parcelForReading(spec); 173 KeyGenParameterSpec fromParcel = 174 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec(); 175 // Compare individual fields as ECGenParameterSpec, on android, does not 176 // implement equals() 177 ECGenParameterSpec parcelSpec = (ECGenParameterSpec) fromParcel.getAlgorithmParameterSpec(); 178 assertEquals(parcelSpec.getName(), ecSpec.getName()); 179 } 180 } 181