/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.security;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

import android.os.Parcel;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.ParcelableKeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.support.test.runner.AndroidJUnit4;
import java.math.BigInteger;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Date;
import javax.security.auth.x500.X500Principal;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Unit tests for {@link ParcelableKeyGenParameterSpec}. */
@RunWith(AndroidJUnit4.class)
public final class ParcelableKeyGenParameterSpecTest {
    static final String ALIAS = "keystore-alias";
    static final String ANOTHER_ALIAS = "another-keystore-alias";
    static final int KEY_PURPOSES = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY;
    static final int UID = 1230;
    static final int KEYSIZE = 2048;
    static final X500Principal SUBJECT = new X500Principal("CN=subject");
    static final BigInteger SERIAL = new BigInteger("1234567890");
    static final Date NOT_BEFORE = new Date(1511799590);
    static final Date NOT_AFTER = new Date(1511899590);
    static final Date KEY_VALIDITY_START = new Date(1511799591);
    static final Date KEY_VALIDITY_FOR_ORIG_END = new Date(1511799593);
    static final Date KEY_VALIDITY_FOR_CONSUMPTION_END = new Date(1511799594);
    static final String DIGEST = KeyProperties.DIGEST_SHA256;
    static final String ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1;
    static final String SIGNATURE_PADDING = KeyProperties.SIGNATURE_PADDING_RSA_PSS;
    static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC;
    static final int USER_AUTHENTICATION_DURATION = 300;
    static final byte[] ATTESTATION_CHALLENGE = new byte[] {'c', 'h'};

    public static KeyGenParameterSpec configureDefaultSpec() {
        return new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
                .setUid(UID)
                .setKeySize(KEYSIZE)
                .setCertificateSubject(SUBJECT)
                .setCertificateSerialNumber(SERIAL)
                .setCertificateNotBefore(NOT_BEFORE)
                .setCertificateNotAfter(NOT_AFTER)
                .setKeyValidityStart(KEY_VALIDITY_START)
                .setKeyValidityForOriginationEnd(KEY_VALIDITY_FOR_ORIG_END)
                .setKeyValidityForConsumptionEnd(KEY_VALIDITY_FOR_CONSUMPTION_END)
                .setDigests(DIGEST)
                .setEncryptionPaddings(ENCRYPTION_PADDING)
                .setSignaturePaddings(SIGNATURE_PADDING)
                .setBlockModes(BLOCK_MODE)
                .setRandomizedEncryptionRequired(true)
                .setUserAuthenticationRequired(true)
                .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_DURATION)
                .setAttestationChallenge(ATTESTATION_CHALLENGE)
                .setUniqueIdIncluded(true)
                .setUserAuthenticationValidWhileOnBody(true)
                .setInvalidatedByBiometricEnrollment(true)
                .setIsStrongBoxBacked(true)
                .setUserConfirmationRequired(true)
                .setUnlockedDeviceRequired(true)
                .build();
    }

    public static void validateSpecValues(KeyGenParameterSpec spec, int uid, String alias) {
        assertThat(spec.getKeystoreAlias(), is(alias));
        assertThat(spec.getPurposes(), is(KEY_PURPOSES));
        assertThat(spec.getUid(), is(uid));
        assertThat(spec.getKeySize(), is(KEYSIZE));
        assertThat(spec.getCertificateSubject(), is(SUBJECT));
        assertThat(spec.getCertificateSerialNumber(), is(SERIAL));
        assertThat(spec.getCertificateNotBefore(), is(NOT_BEFORE));
        assertThat(spec.getCertificateNotAfter(), is(NOT_AFTER));
        assertThat(spec.getKeyValidityStart(), is(KEY_VALIDITY_START));
        assertThat(spec.getKeyValidityForOriginationEnd(), is(KEY_VALIDITY_FOR_ORIG_END));
        assertThat(spec.getKeyValidityForConsumptionEnd(), is(KEY_VALIDITY_FOR_CONSUMPTION_END));
        assertThat(spec.getDigests(), is(new String[] {DIGEST}));
        assertThat(spec.getEncryptionPaddings(), is(new String[] {ENCRYPTION_PADDING}));
        assertThat(spec.getSignaturePaddings(), is(new String[] {SIGNATURE_PADDING}));
        assertThat(spec.getBlockModes(), is(new String[] {BLOCK_MODE}));
        assertThat(spec.isRandomizedEncryptionRequired(), is(true));
        assertThat(spec.isUserAuthenticationRequired(), is(true));
        assertThat(
                spec.getUserAuthenticationValidityDurationSeconds(),
                is(USER_AUTHENTICATION_DURATION));
        assertThat(spec.getAttestationChallenge(), is(ATTESTATION_CHALLENGE));
        assertThat(spec.isUniqueIdIncluded(), is(true));
        assertThat(spec.isUserAuthenticationValidWhileOnBody(), is(true));
        assertThat(spec.isInvalidatedByBiometricEnrollment(), is(true));
        assertThat(spec.isStrongBoxBacked(), is(true));
        assertThat(spec.isUserConfirmationRequired(), is(true));
        assertThat(spec.isUnlockedDeviceRequired(), is(true));
    }

    private Parcel parcelForReading(ParcelableKeyGenParameterSpec spec) {
        Parcel parcel = Parcel.obtain();
        spec.writeToParcel(parcel, spec.describeContents());

        parcel.setDataPosition(0);
        return parcel;
    }

    @Test
    public void testParcelingWithAllValues() {
        ParcelableKeyGenParameterSpec spec =
            new ParcelableKeyGenParameterSpec(configureDefaultSpec());
        Parcel parcel = parcelForReading(spec);
        ParcelableKeyGenParameterSpec fromParcel =
            ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel);
        validateSpecValues(fromParcel.getSpec(), UID, ALIAS);
        assertThat(parcel.dataAvail(), is(0));
    }

    @Test
    public void testParcelingWithNullValues() {
        ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
            new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES).build());

        Parcel parcel = parcelForReading(spec);
        KeyGenParameterSpec fromParcel = ParcelableKeyGenParameterSpec.CREATOR
            .createFromParcel(parcel)
            .getSpec();
        assertThat(fromParcel.getKeystoreAlias(), is(ALIAS));
        assertThat(fromParcel.getPurposes(), is(KEY_PURPOSES));
        assertThat(fromParcel.getCertificateNotBefore(), is(new Date(0L)));
        assertThat(fromParcel.getCertificateNotAfter(), is(new Date(2461449600000L)));
        assertThat(parcel.dataAvail(), is(0));
    }

    @Test
    public void testParcelingRSAAlgoParameter() {
        RSAKeyGenParameterSpec rsaSpec =
                new RSAKeyGenParameterSpec(2048, new BigInteger("5231123"));
        ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
            new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
            .setAlgorithmParameterSpec(rsaSpec)
            .build());

        Parcel parcel = parcelForReading(spec);
        KeyGenParameterSpec fromParcel =
            ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
        RSAKeyGenParameterSpec parcelSpec =
                (RSAKeyGenParameterSpec) fromParcel.getAlgorithmParameterSpec();
        // Compare individual fields as RSAKeyGenParameterSpec, on android, does not
        // implement equals()
        assertEquals(parcelSpec.getKeysize(), rsaSpec.getKeysize());
        assertEquals(parcelSpec.getPublicExponent(), rsaSpec.getPublicExponent());
    }

    @Test
    public void testParcelingECAlgoParameter() {
        ECGenParameterSpec ecSpec = new ECGenParameterSpec("P-256");
        ParcelableKeyGenParameterSpec spec = new ParcelableKeyGenParameterSpec(
                new KeyGenParameterSpec.Builder(ALIAS, KEY_PURPOSES)
                        .setAlgorithmParameterSpec(ecSpec)
                        .build());
        Parcel parcel = parcelForReading(spec);
        KeyGenParameterSpec fromParcel =
            ParcelableKeyGenParameterSpec.CREATOR.createFromParcel(parcel).getSpec();
        // Compare individual fields as ECGenParameterSpec, on android, does not
        // implement equals()
        ECGenParameterSpec parcelSpec = (ECGenParameterSpec) fromParcel.getAlgorithmParameterSpec();
        assertEquals(parcelSpec.getName(), ecSpec.getName());
    }
}
