blob: b7d72fce6eba397219c7bf2c5d18383adf1ea318 [file] [log] [blame]
Eran Messeri852c8f12017-11-15 05:55:52 +00001/*
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
17package android.security;
18
19import static org.hamcrest.Matchers.is;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertThat;
22
23import android.os.Parcel;
24import android.security.keystore.KeyGenParameterSpec;
Eran Messeri852c8f12017-11-15 05:55:52 +000025import android.security.keystore.KeyProperties;
Brett Chabot502ec7a2019-03-01 14:43:20 -080026import android.security.keystore.ParcelableKeyGenParameterSpec;
27
28import androidx.test.runner.AndroidJUnit4;
29
30import org.junit.Test;
31import org.junit.runner.RunWith;
32
Eran Messeri852c8f12017-11-15 05:55:52 +000033import java.math.BigInteger;
34import java.security.spec.ECGenParameterSpec;
35import java.security.spec.RSAKeyGenParameterSpec;
36import java.util.Date;
Brett Chabot502ec7a2019-03-01 14:43:20 -080037
Eran Messeri852c8f12017-11-15 05:55:52 +000038import javax.security.auth.x500.X500Principal;
Eran Messeri852c8f12017-11-15 05:55:52 +000039
40/** Unit tests for {@link ParcelableKeyGenParameterSpec}. */
41@RunWith(AndroidJUnit4.class)
42public 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
Eran Messeria1730642017-12-11 17:48:47 +000062 public static KeyGenParameterSpec configureDefaultSpec() {
Eran Messeri852c8f12017-11-15 05:55:52 +000063 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)
Eran Messeri5a5c6e02018-06-28 11:20:44 +010084 .setIsStrongBoxBacked(true)
85 .setUserConfirmationRequired(true)
86 .setUnlockedDeviceRequired(true)
Rubin Xub3a13e12019-12-24 13:35:02 +000087 .setCriticalToDeviceEncryption(true)
Eran Messeri852c8f12017-11-15 05:55:52 +000088 .build();
89 }
90
Eran Messeria1730642017-12-11 17:48:47 +000091 public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) {
Eran Messeri852c8f12017-11-15 05:55:52 +000092 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));
Eran Messeri5a5c6e02018-06-28 11:20:44 +0100116 assertThat(spec.isStrongBoxBacked(), is(true));
117 assertThat(spec.isUserConfirmationRequired(), is(true));
118 assertThat(spec.isUnlockedDeviceRequired(), is(true));
Rubin Xub3a13e12019-12-24 13:35:02 +0000119 assertThat(spec.isCriticalToDeviceEncryption(), is(true));
Eran Messeri852c8f12017-11-15 05:55:52 +0000120 }
121
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
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
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
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
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}