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 .build(); 88 } 89 validateSpecValues(KeyGenParameterSpec spec, int uid, String alias)90 public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) { 91 assertThat(spec.getKeystoreAlias(), is(alias)); 92 assertThat(spec.getPurposes(), is(KEY_PURPOSES)); 93 assertThat(spec.getUid(), is(uid)); 94 assertThat(spec.getKeySize(), is(KEYSIZE)); 95 assertThat(spec.getCertificateSubject(), is(SUBJECT)); 96 assertThat(spec.getCertificateSerialNumber(), is(SERIAL)); 97 assertThat(spec.getCertificateNotBefore(), is(NOT_BEFORE)); 98 assertThat(spec.getCertificateNotAfter(), is(NOT_AFTER)); 99 assertThat(spec.getKeyValidityStart(), is(KEY_VALIDITY_START)); 100 assertThat(spec.getKeyValidityForOriginationEnd(), is(KEY_VALIDITY_FOR_ORIG_END)); 101 assertThat(spec.getKeyValidityForConsumptionEnd(), is(KEY_VALIDITY_FOR_CONSUMPTION_END)); 102 assertThat(spec.getDigests(), is(new String[] {DIGEST})); 103 assertThat(spec.getEncryptionPaddings(), is(new String[] {ENCRYPTION_PADDING})); 104 assertThat(spec.getSignaturePaddings(), is(new String[] {SIGNATURE_PADDING})); 105 assertThat(spec.getBlockModes(), is(new String[] {BLOCK_MODE})); 106 assertThat(spec.isRandomizedEncryptionRequired(), is(true)); 107 assertThat(spec.isUserAuthenticationRequired(), is(true)); 108 assertThat( 109 spec.getUserAuthenticationValidityDurationSeconds(), 110 is(USER_AUTHENTICATION_DURATION)); 111 assertThat(spec.getAttestationChallenge(), is(ATTESTATION_CHALLENGE)); 112 assertThat(spec.isUniqueIdIncluded(), is(true)); 113 assertThat(spec.isUserAuthenticationValidWhileOnBody(), is(true)); 114 assertThat(spec.isInvalidatedByBiometricEnrollment(), is(true)); 115 assertThat(spec.isStrongBoxBacked(), is(true)); 116 assertThat(spec.isUserConfirmationRequired(), is(true)); 117 assertThat(spec.isUnlockedDeviceRequired(), is(true)); 118 } 119 parcelForReading(ParcelableKeyGenParameterSpec spec)120 private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) { 121 Parcel parcel = Parcel.obtain(); 122 spec.writeToParcel(parcel, spec.describeContents()); 123 124 parcel.setDataPosition(0); 125 return parcel; 126 } 127 128 @Test testParcelingWithAllValues()129 public void testParcelingWithAllValues() { 130 ParcelableKeyGenParameterSpec spec = 131 new ParcelableKeyGenParameterSpec(configureDefaultSpec()); 132 Parcel parcel = parcelForReading(spec); 133 ParcelableKeyGenParameterSpec fromParcel = 134 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel); 135 validateSpecValues(fromParcel.getSpec(), UID, ALIAS); 136 assertThat(parcel.dataAvail(), is(0)); 137 } 138 139 @Test testParcelingWithNullValues()140 public void testParcelingWithNullValues() { 141 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 142 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES).build()); 143 144 Parcel parcel = parcelForReading(spec); 145 KeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR 146 .createFromParcel(parcel) 147 .getSpec(); 148 assertThat(fromParcel.getKeystoreAlias(), is(ALIAS)); 149 assertThat(fromParcel.getPurposes(), is(KEY_PURPOSES)); 150 assertThat(fromParcel.getCertificateNotBefore(), is(new Date(0L))); 151 assertThat(fromParcel.getCertificateNotAfter(), is(new Date(2461449600000L))); 152 assertThat(parcel.dataAvail(), is(0)); 153 } 154 155 @Test testParcelingRSAAlgoParameter()156 public void testParcelingRSAAlgoParameter() { 157 RSAKeyGenParameterSpec rsaSpec = 158 new RSAKeyGenParameterSpec(2048, new BigInteger("5231123")); 159 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 160 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 161 .setAlgorithmParameterSpec(rsaSpec) 162 .build()); 163 164 Parcel parcel = parcelForReading(spec); 165 KeyGenParameterSpec fromParcel = 166 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec(); 167 RSAKeyGenParameterSpec parcelSpec = 168 (RSAKeyGenParameterSpec) fromParcel.getAlgorithmParameterSpec(); 169 // Compare individual fields as RSAKeyGenParameterSpec, on android, does not 170 // implement equals() 171 assertEquals(parcelSpec.getKeysize(), rsaSpec.getKeysize()); 172 assertEquals(parcelSpec.getPublicExponent(), rsaSpec.getPublicExponent()); 173 } 174 175 @Test testParcelingECAlgoParameter()176 public void testParcelingECAlgoParameter() { 177 ECGenParameterSpec ecSpec = new ECGenParameterSpec("P-256"); 178 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec( 179 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES) 180 .setAlgorithmParameterSpec(ecSpec) 181 .build()); 182 Parcel parcel = parcelForReading(spec); 183 KeyGenParameterSpec fromParcel = 184 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec(); 185 // Compare individual fields as ECGenParameterSpec, on android, does not 186 // implement equals() 187 ECGenParameterSpec parcelSpec = (ECGenParameterSpec) fromParcel.getAlgorithmParameterSpec(); 188 assertEquals(parcelSpec.getName(), ecSpec.getName()); 189 } 190 } 191