Home | History | Annotate | Download | only in security
      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.ParcelableKeyGenParameterSpec;
     26 import android.security.keystore.KeyProperties;
     27 import android.support.test.runner.AndroidJUnit4;
     28 import java.math.BigInteger;
     29 import java.security.spec.ECGenParameterSpec;
     30 import java.security.spec.RSAKeyGenParameterSpec;
     31 import java.util.Date;
     32 import javax.security.auth.x500.X500Principal;
     33 import org.junit.Test;
     34 import org.junit.runner.RunWith;
     35 
     36 /** Unit tests for {@link ParcelableKeyGenParameterSpec}. */
     37 @RunWith(AndroidJUnit4.class)
     38 public 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 
     58     public static KeyGenParameterSpec configureDefaultSpec() {
     59         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 
     83     public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) {
     84         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 }
    181