blob: 32f8ec44d11f92d8488070de6a8cb584fb0138d5 [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;
25import android.security.keystore.ParcelableKeyGenParameterSpec;
26import android.security.keystore.KeyProperties;
27import android.support.test.runner.AndroidJUnit4;
28import java.math.BigInteger;
29import java.security.spec.ECGenParameterSpec;
30import java.security.spec.RSAKeyGenParameterSpec;
31import java.util.Date;
32import javax.security.auth.x500.X500Principal;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35
36/** Unit tests for {@link ParcelableKeyGenParameterSpec}. */
37@RunWith(AndroidJUnit4.class)
38public 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
Eran Messeria1730642017-12-11 17:48:47 +000058 public static KeyGenParameterSpec configureDefaultSpec() {
Eran Messeri852c8f12017-11-15 05:55:52 +000059 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)
Eran Messeri5a5c6e02018-06-28 11:20:44 +010080 .setIsStrongBoxBacked(true)
81 .setUserConfirmationRequired(true)
82 .setUnlockedDeviceRequired(true)
Eran Messeri852c8f12017-11-15 05:55:52 +000083 .build();
84 }
85
Eran Messeria1730642017-12-11 17:48:47 +000086 public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) {
Eran Messeri852c8f12017-11-15 05:55:52 +000087 assertThat(spec.getKeystoreAlias(), is(alias));
88 assertThat(spec.getPurposes(), is(KEY_PURPOSES));
89 assertThat(spec.getUid(), is(uid));
90 assertThat(spec.getKeySize(), is(KEYSIZE));
91 assertThat(spec.getCertificateSubject(), is(SUBJECT));
92 assertThat(spec.getCertificateSerialNumber(), is(SERIAL));
93 assertThat(spec.getCertificateNotBefore(), is(NOT_BEFORE));
94 assertThat(spec.getCertificateNotAfter(), is(NOT_AFTER));
95 assertThat(spec.getKeyValidityStart(), is(KEY_VALIDITY_START));
96 assertThat(spec.getKeyValidityForOriginationEnd(), is(KEY_VALIDITY_FOR_ORIG_END));
97 assertThat(spec.getKeyValidityForConsumptionEnd(), is(KEY_VALIDITY_FOR_CONSUMPTION_END));
98 assertThat(spec.getDigests(), is(new String[] {DIGEST}));
99 assertThat(spec.getEncryptionPaddings(), is(new String[] {ENCRYPTION_PADDING}));
100 assertThat(spec.getSignaturePaddings(), is(new String[] {SIGNATURE_PADDING}));
101 assertThat(spec.getBlockModes(), is(new String[] {BLOCK_MODE}));
102 assertThat(spec.isRandomizedEncryptionRequired(), is(true));
103 assertThat(spec.isUserAuthenticationRequired(), is(true));
104 assertThat(
105 spec.getUserAuthenticationValidityDurationSeconds(),
106 is(USER_AUTHENTICATION_DURATION));
107 assertThat(spec.getAttestationChallenge(), is(ATTESTATION_CHALLENGE));
108 assertThat(spec.isUniqueIdIncluded(), is(true));
109 assertThat(spec.isUserAuthenticationValidWhileOnBody(), is(true));
110 assertThat(spec.isInvalidatedByBiometricEnrollment(), is(true));
Eran Messeri5a5c6e02018-06-28 11:20:44 +0100111 assertThat(spec.isStrongBoxBacked(), is(true));
112 assertThat(spec.isUserConfirmationRequired(), is(true));
113 assertThat(spec.isUnlockedDeviceRequired(), is(true));
Eran Messeri852c8f12017-11-15 05:55:52 +0000114 }
115
116 private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) {
117 Parcel parcel = Parcel.obtain();
118 spec.writeToParcel(parcel, spec.describeContents());
119
120 parcel.setDataPosition(0);
121 return parcel;
122 }
123
124 @Test
125 public void testParcelingWithAllValues() {
126 ParcelableKeyGenParameterSpec spec =
127 new ParcelableKeyGenParameterSpec(configureDefaultSpec());
128 Parcel parcel = parcelForReading(spec);
129 ParcelableKeyGenParameterSpec fromParcel =
130 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel);
131 validateSpecValues(fromParcel.getSpec(), UID, ALIAS);
132 assertThat(parcel.dataAvail(), is(0));
133 }
134
135 @Test
136 public void testParcelingWithNullValues() {
137 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
138 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES).build());
139
140 Parcel parcel = parcelForReading(spec);
141 KeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR
142 .createFromParcel(parcel)
143 .getSpec();
144 assertThat(fromParcel.getKeystoreAlias(), is(ALIAS));
145 assertThat(fromParcel.getPurposes(), is(KEY_PURPOSES));
146 assertThat(fromParcel.getCertificateNotBefore(), is(new Date(0L)));
147 assertThat(fromParcel.getCertificateNotAfter(), is(new Date(2461449600000L)));
148 assertThat(parcel.dataAvail(), is(0));
149 }
150
151 @Test
152 public void testParcelingRSAAlgoParameter() {
153 RSAKeyGenParameterSpec rsaSpec =
154 new RSAKeyGenParameterSpec(2048, new BigInteger("5231123"));
155 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
156 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
157 .setAlgorithmParameterSpec(rsaSpec)
158 .build());
159
160 Parcel parcel = parcelForReading(spec);
161 KeyGenParameterSpec fromParcel =
162 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
163 RSAKeyGenParameterSpec parcelSpec =
164 (RSAKeyGenParameterSpec) fromParcel.getAlgorithmParameterSpec();
165 // Compare individual fields as RSAKeyGenParameterSpec, on android, does not
166 // implement equals()
167 assertEquals(parcelSpec.getKeysize(), rsaSpec.getKeysize());
168 assertEquals(parcelSpec.getPublicExponent(), rsaSpec.getPublicExponent());
169 }
170
171 @Test
172 public void testParcelingECAlgoParameter() {
173 ECGenParameterSpec ecSpec = new ECGenParameterSpec("P-256");
174 ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
175 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
176 .setAlgorithmParameterSpec(ecSpec)
177 .build());
178 Parcel parcel = parcelForReading(spec);
179 KeyGenParameterSpec fromParcel =
180 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
181 // Compare individual fields as ECGenParameterSpec, on android, does not
182 // implement equals()
183 ECGenParameterSpec parcelSpec = (ECGenParameterSpec) fromParcel.getAlgorithmParameterSpec();
184 assertEquals(parcelSpec.getName(), ecSpec.getName());
185 }
186}