• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.assertArrayEquals;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertThat;
23 
24 import android.os.Parcel;
25 import android.security.keystore.KeyGenParameterSpec;
26 import android.security.keystore.KeyProperties;
27 import android.security.keystore.ParcelableKeyGenParameterSpec;
28 
29 import androidx.test.runner.AndroidJUnit4;
30 
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 
34 import java.math.BigInteger;
35 import java.security.spec.ECGenParameterSpec;
36 import java.security.spec.RSAKeyGenParameterSpec;
37 import java.util.Date;
38 
39 import javax.security.auth.x500.X500Principal;
40 
41 /** Unit tests for {@link ParcelableKeyGenParameterSpec}. */
42 @RunWith(AndroidJUnit4.class)
43 public final class ParcelableKeyGenParameterSpecTest {
44     static final String ALIAS = "keystore-alias";
45     static final String ANOTHER_ALIAS = "another-keystore-alias";
46     static final int KEY_PURPOSES = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY;
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                 .setNamespace(KeyProperties.NAMESPACE_WIFI)
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, @KeyProperties.Namespace int namespace, String alias)91     public static void validateSpecValues(KeyGenParameterSpec spec,
92             @KeyProperties.Namespace int namespace, String alias) {
93         assertThat(spec.getKeystoreAlias(), is(alias));
94         assertThat(spec.getPurposes(), is(KEY_PURPOSES));
95         assertThat(spec.getNamespace(), is(namespace));
96         assertThat(spec.getKeySize(), is(KEYSIZE));
97         assertThat(spec.getCertificateSubject(), is(SUBJECT));
98         assertThat(spec.getCertificateSerialNumber(), is(SERIAL));
99         assertThat(spec.getCertificateNotBefore(), is(NOT_BEFORE));
100         assertThat(spec.getCertificateNotAfter(), is(NOT_AFTER));
101         assertThat(spec.getKeyValidityStart(), is(KEY_VALIDITY_START));
102         assertThat(spec.getKeyValidityForOriginationEnd(), is(KEY_VALIDITY_FOR_ORIG_END));
103         assertThat(spec.getKeyValidityForConsumptionEnd(), is(KEY_VALIDITY_FOR_CONSUMPTION_END));
104         assertThat(spec.getDigests(), is(new String[] {DIGEST}));
105         assertThat(spec.isMgf1DigestsSpecified(), is(false));
106         assertThat(spec.getEncryptionPaddings(), is(new String[] {ENCRYPTION_PADDING}));
107         assertThat(spec.getSignaturePaddings(), is(new String[] {SIGNATURE_PADDING}));
108         assertThat(spec.getBlockModes(), is(new String[] {BLOCK_MODE}));
109         assertThat(spec.isRandomizedEncryptionRequired(), is(true));
110         assertThat(spec.isUserAuthenticationRequired(), is(true));
111         assertThat(
112                 spec.getUserAuthenticationValidityDurationSeconds(),
113                 is(USER_AUTHENTICATION_DURATION));
114         assertThat(spec.getAttestationChallenge(), is(ATTESTATION_CHALLENGE));
115         assertThat(spec.isUniqueIdIncluded(), is(true));
116         assertThat(spec.isUserAuthenticationValidWhileOnBody(), is(true));
117         assertThat(spec.isInvalidatedByBiometricEnrollment(), is(true));
118         assertThat(spec.isStrongBoxBacked(), is(true));
119         assertThat(spec.isUserConfirmationRequired(), is(true));
120         assertThat(spec.isUnlockedDeviceRequired(), is(true));
121         assertThat(spec.isCriticalToDeviceEncryption(), is(true));
122     }
123 
parcelForReading(ParcelableKeyGenParameterSpec spec)124     private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) {
125         Parcel parcel = Parcel.obtain();
126         spec.writeToParcel(parcel, spec.describeContents());
127 
128         parcel.setDataPosition(0);
129         return parcel;
130     }
131 
132     @Test
testParcelingWithAllValues()133     public void testParcelingWithAllValues() {
134         ParcelableKeyGenParameterSpec spec =
135             new ParcelableKeyGenParameterSpec(configureDefaultSpec());
136         Parcel parcel = parcelForReading(spec);
137         ParcelableKeyGenParameterSpec fromParcel =
138             ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel);
139         validateSpecValues(fromParcel.getSpec(), KeyProperties.NAMESPACE_WIFI, ALIAS);
140         assertThat(parcel.dataAvail(), is(0));
141     }
142 
143     @Test
testParcelingWithNullValues()144     public void testParcelingWithNullValues() {
145         ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
146             new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES).build());
147 
148         Parcel parcel = parcelForReading(spec);
149         KeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR
150             .createFromParcel(parcel)
151             .getSpec();
152         assertThat(fromParcel.getKeystoreAlias(), is(ALIAS));
153         assertThat(fromParcel.getPurposes(), is(KEY_PURPOSES));
154         assertThat(fromParcel.getCertificateNotBefore(), is(new Date(0L)));
155         assertThat(fromParcel.getCertificateNotAfter(), is(new Date(2461449600000L)));
156         assertThat(parcel.dataAvail(), is(0));
157     }
158 
159     @Test
testParcelingRSAAlgoParameter()160     public void testParcelingRSAAlgoParameter() {
161         RSAKeyGenParameterSpec rsaSpec =
162                 new RSAKeyGenParameterSpec(2048, new BigInteger("5231123"));
163         ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
164             new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
165             .setAlgorithmParameterSpec(rsaSpec)
166             .build());
167 
168         Parcel parcel = parcelForReading(spec);
169         KeyGenParameterSpec fromParcel =
170             ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
171         RSAKeyGenParameterSpec parcelSpec =
172                 (RSAKeyGenParameterSpec) fromParcel.getAlgorithmParameterSpec();
173         // Compare individual fields as RSAKeyGenParameterSpec, on android, does not
174         // implement equals()
175         assertEquals(parcelSpec.getKeysize(), rsaSpec.getKeysize());
176         assertEquals(parcelSpec.getPublicExponent(), rsaSpec.getPublicExponent());
177     }
178 
179     @Test
testParcelingECAlgoParameter()180     public void testParcelingECAlgoParameter() {
181         ECGenParameterSpec ecSpec = new ECGenParameterSpec("P-256");
182         ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
183                 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
184                         .setAlgorithmParameterSpec(ecSpec)
185                         .build());
186         Parcel parcel = parcelForReading(spec);
187         KeyGenParameterSpec fromParcel =
188             ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
189         // Compare individual fields as ECGenParameterSpec, on android, does not
190         // implement equals()
191         ECGenParameterSpec parcelSpec = (ECGenParameterSpec) fromParcel.getAlgorithmParameterSpec();
192         assertEquals(parcelSpec.getName(), ecSpec.getName());
193     }
194 
195     @Test
testParcelingMgf1Digests()196     public void testParcelingMgf1Digests() {
197         String[] mgf1Digests =
198                 new String[] {KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA256};
199 
200         ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
201                 new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
202                         .setMgf1Digests(mgf1Digests)
203                         .build());
204         Parcel parcel = parcelForReading(spec);
205         KeyGenParameterSpec fromParcel =
206                 ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
207         assertArrayEquals(fromParcel.getMgf1Digests().toArray(), mgf1Digests);
208     }
209 }
210