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.KeyProperties; 26 import android.security.keystore.ParcelableKeyGenParameterSpec; 27 28 import androidx.test.runner.AndroidJUnit4; 29 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 33 import java.math.BigInteger; 34 import java.security.spec.ECGenParameterSpec; 35 import java.security.spec.RSAKeyGenParameterSpec; 36 import java.util.Date; 37 38 import javax.security.auth.x500.X500Principal; 39 40 /** Unit tests for {@link ParcelableKeyGenParameterSpec}. */ 41 @RunWith(AndroidJUnit4.class) 42 public final class ParcelableKeyGenParameterSpecTest { 43 static final String ALIAS = "keystore-alias"; 44 static final String ANOTHER_ALIAS = "another-keystore-alias"; 45 static final int KEY_PURPOSES = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY; 46 static final int UID = 1230; 47 static final int KEYSIZE = 2048; 48 static final X500Principal SUBJECT = new X500Principal("CN=subject"); 49 static final BigInteger SERIAL = new BigInteger("1234567890"); 50 static final Date NOT_BEFORE = new Date(1511799590); 51 static final Date NOT_AFTER = new Date(1511899590); 52 static final Date KEY_VALIDITY_START = new Date(1511799591); 53 static final Date KEY_VALIDITY_FOR_ORIG_END = new Date(1511799593); 54 static final Date KEY_VALIDITY_FOR_CONSUMPTION_END = new Date(1511799594); 55 static final String DIGEST = KeyProperties.DIGEST_SHA256; 56 static final String ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1; 57 static final String SIGNATURE_PADDING = KeyProperties.SIGNATURE_PADDING_RSA_PSS; 58 static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC; 59 static final int USER_AUTHENTICATION_DURATION = 300; 60 static final byte[] ATTESTATION_CHALLENGE = new byte[] {'c', 'h'}; 61 configureDefaultSpec()62 public static KeyGenParameterSpec configureDefaultSpec() { 63 return new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 64 .setUid(UID) 65 .setKeySize(KEYSIZE) 66 .setCertificateSubject(SUBJECT) 67 .setCertificateSerialNumber(SERIAL) 68 .setCertificateNotBefore(NOT_BEFORE) 69 .setCertificateNotAfter(NOT_AFTER) 70 .setKeyValidityStart(KEY_VALIDITY_START) 71 .setKeyValidityForOriginationEnd(KEY_VALIDITY_FOR_ORIG_END) 72 .setKeyValidityForConsumptionEnd(KEY_VALIDITY_FOR_CONSUMPTION_END) 73 .setDigests(DIGEST) 74 .setEncryptionPaddings(ENCRYPTION_PADDING) 75 .setSignaturePaddings(SIGNATURE_PADDING) 76 .setBlockModes(BLOCK_MODE) 77 .setRandomizedEncryptionRequired(true) 78 .setUserAuthenticationRequired(true) 79 .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_DURATION) 80 .setAttestationChallenge(ATTESTATION_CHALLENGE) 81 .setUniqueIdIncluded(true) 82 .setUserAuthenticationValidWhileOnBody(true) 83 .setInvalidatedByBiometricEnrollment(true) 84 .setIsStrongBoxBacked(true) 85 .setUserConfirmationRequired(true) 86 .setUnlockedDeviceRequired(true) 87 .setCriticalToDeviceEncryption(true) 88 .build(); 89 } 90 validateSpecValues(KeyGenParameterSpec spec, int uid, String alias)91 public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) { 92 assertThat(spec.getKeystoreAlias(), is(alias)); 93 assertThat(spec.getPurposes(), is(KEY_PURPOSES)); 94 assertThat(spec.getUid(), is(uid)); 95 assertThat(spec.getKeySize(), is(KEYSIZE)); 96 assertThat(spec.getCertificateSubject(), is(SUBJECT)); 97 assertThat(spec.getCertificateSerialNumber(), is(SERIAL)); 98 assertThat(spec.getCertificateNotBefore(), is(NOT_BEFORE)); 99 assertThat(spec.getCertificateNotAfter(), is(NOT_AFTER)); 100 assertThat(spec.getKeyValidityStart(), is(KEY_VALIDITY_START)); 101 assertThat(spec.getKeyValidityForOriginationEnd(), is(KEY_VALIDITY_FOR_ORIG_END)); 102 assertThat(spec.getKeyValidityForConsumptionEnd(), is(KEY_VALIDITY_FOR_CONSUMPTION_END)); 103 assertThat(spec.getDigests(), is(new String[] {DIGEST})); 104 assertThat(spec.getEncryptionPaddings(), is(new String[] {ENCRYPTION_PADDING})); 105 assertThat(spec.getSignaturePaddings(), is(new String[] {SIGNATURE_PADDING})); 106 assertThat(spec.getBlockModes(), is(new String[] {BLOCK_MODE})); 107 assertThat(spec.isRandomizedEncryptionRequired(), is(true)); 108 assertThat(spec.isUserAuthenticationRequired(), is(true)); 109 assertThat( 110 spec.getUserAuthenticationValidityDurationSeconds(), 111 is(USER_AUTHENTICATION_DURATION)); 112 assertThat(spec.getAttestationChallenge(), is(ATTESTATION_CHALLENGE)); 113 assertThat(spec.isUniqueIdIncluded(), is(true)); 114 assertThat(spec.isUserAuthenticationValidWhileOnBody(), is(true)); 115 assertThat(spec.isInvalidatedByBiometricEnrollment(), is(true)); 116 assertThat(spec.isStrongBoxBacked(), is(true)); 117 assertThat(spec.isUserConfirmationRequired(), is(true)); 118 assertThat(spec.isUnlockedDeviceRequired(), is(true)); 119 assertThat(spec.isCriticalToDeviceEncryption(), is(true)); 120 } 121 parcelForReading(ParcelableKeyGenParameterSpec spec)122 private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) { 123 Parcel parcel = Parcel.obtain(); 124 spec.writeToParcel(parcel, spec.describeContents()); 125 126 parcel.setDataPosition(0); 127 return parcel; 128 } 129 130 @Test testParcelingWithAllValues()131 public void testParcelingWithAllValues() { 132 ParcelableKeyGenParameterSpec spec = 133 new ParcelableKeyGenParameterSpec(configureDefaultSpec()); 134 Parcel parcel = parcelForReading(spec); 135 ParcelableKeyGenParameterSpec fromParcel = 136 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel); 137 validateSpecValues(fromParcel.getSpec(), UID, ALIAS); 138 assertThat(parcel.dataAvail(), is(0)); 139 } 140 141 @Test testParcelingWithNullValues()142 public void testParcelingWithNullValues() { 143 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 144 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES).build()); 145 146 Parcel parcel = parcelForReading(spec); 147 KeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR 148 .createFromParcel(parcel) 149 .getSpec(); 150 assertThat(fromParcel.getKeystoreAlias(), is(ALIAS)); 151 assertThat(fromParcel.getPurposes(), is(KEY_PURPOSES)); 152 assertThat(fromParcel.getCertificateNotBefore(), is(new Date(0L))); 153 assertThat(fromParcel.getCertificateNotAfter(), is(new Date(2461449600000L))); 154 assertThat(parcel.dataAvail(), is(0)); 155 } 156 157 @Test testParcelingRSAAlgoParameter()158 public void testParcelingRSAAlgoParameter() { 159 RSAKeyGenParameterSpec rsaSpec = 160 new RSAKeyGenParameterSpec(2048, new BigInteger("5231123")); 161 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 162 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 163 .setAlgorithmParameterSpec(rsaSpec) 164 .build()); 165 166 Parcel parcel = parcelForReading(spec); 167 KeyGenParameterSpec fromParcel = 168 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec(); 169 RSAKeyGenParameterSpec parcelSpec = 170 (RSAKeyGenParameterSpec) fromParcel.getAlgorithmParameterSpec(); 171 // Compare individual fields as RSAKeyGenParameterSpec, on android, does not 172 // implement equals() 173 assertEquals(parcelSpec.getKeysize(), rsaSpec.getKeysize()); 174 assertEquals(parcelSpec.getPublicExponent(), rsaSpec.getPublicExponent()); 175 } 176 177 @Test testParcelingECAlgoParameter()178 public void testParcelingECAlgoParameter() { 179 ECGenParameterSpec ecSpec = new ECGenParameterSpec("P-256"); 180 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 181 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 182 .setAlgorithmParameterSpec(ecSpec) 183 .build()); 184 Parcel parcel = parcelForReading(spec); 185 KeyGenParameterSpec fromParcel = 186 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec(); 187 // Compare individual fields as ECGenParameterSpec, on android, does not 188 // implement equals() 189 ECGenParameterSpec parcelSpec = (ECGenParameterSpec) fromParcel.getAlgorithmParameterSpec(); 190 assertEquals(parcelSpec.getName(), ecSpec.getName()); 191 } 192 } 193