blob: 254b6be77ea8e5e3d6352832c94bffde65972c71 [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)
80 .build();
81 }
82
Eran Messeria1730642017-12-11 17:48:47 +000083 public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) {
Eran Messeri852c8f12017-11-15 05:55:52 +000084 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}