/*
 * Copyright (C) 2018 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 com.android.keychain;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyVararg;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.app.admin.SecurityLog;
import android.content.Intent;
import android.security.IKeyChainService;

import com.android.org.conscrypt.TrustedCertificateStore;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ServiceController;
import org.robolectric.annotation.Config;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.security.auth.x500.X500Principal;

@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
        shadows = {ShadowTrustedCertificateStore.class})
public final class KeyChainServiceRoboTest {
    private IKeyChainService.Stub mKeyChain;

    @Mock
    private KeyChainService.Injector mockInjector;
    @Mock
    private TrustedCertificateStore mockCertStore;

    /*
     * The CA cert below is the content of cacert.pem as generated by:
     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
     */
    private static final String TEST_CA =
            "-----BEGIN CERTIFICATE-----\n" +
            "MIIDXTCCAkWgAwIBAgIJAK9Tl/F9V8kSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" +
            "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" +
            "aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzA2MTczMjExWhcNMjUwMzAzMTczMjExWjBF\n" +
            "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" +
            "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" +
            "CgKCAQEAvItOutsE75WBTgTyNAHt4JXQ3JoseaGqcC3WQij6vhrleWi5KJ0jh1/M\n" +
            "Rpry7Fajtwwb4t8VZa0NuM2h2YALv52w1xivql88zce/HU1y7XzbXhxis9o6SCI+\n" +
            "oVQSbPeXRgBPppFzBEh3ZqYTVhAqw451XhwdA4Aqs3wts7ddjwlUzyMdU44osCUg\n" +
            "kVg7lfPf9sTm5IoHVcfLSCWH5n6Nr9sH3o2ksyTwxuOAvsN11F/a0mmUoPciYPp+\n" +
            "q7DzQzdi7akRG601DZ4YVOwo6UITGvDyuAAdxl5isovUXqe6Jmz2/myTSpAKxGFs\n" +
            "jk9oRoG6WXWB1kni490GIPjJ1OceyQIDAQABo1AwTjAdBgNVHQ4EFgQUH1QIlPKL\n" +
            "p2OQ/AoLOjKvBW4zK3AwHwYDVR0jBBgwFoAUH1QIlPKLp2OQ/AoLOjKvBW4zK3Aw\n" +
            "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcMi4voMMJHeQLjtq8Oky\n" +
            "Azpyk8moDwgCd4llcGj7izOkIIFqq/lyqKdtykVKUWz2bSHO5cLrtaOCiBWVlaCV\n" +
            "DYAnnVLM8aqaA6hJDIfaGs4zmwz0dY8hVMFCuCBiLWuPfiYtbEmjHGSmpQTG6Qxn\n" +
            "ZJlaK5CZyt5pgh5EdNdvQmDEbKGmu0wpCq9qjZImwdyAul1t/B0DrsWApZMgZpeI\n" +
            "d2od0VBrCICB1K4p+C51D93xyQiva7xQcCne+TAnGNy9+gjQ/MyR8MRpwRLv5ikD\n" +
            "u0anJCN8pXo6IMglfMAsoton1J6o5/ae5uhC6caQU8bNUsCK570gpNfjkzo6rbP0\n" +
            "wQ==\n" +
            "-----END CERTIFICATE-----\n";

    private X509Certificate mCert;
    private String mSubject;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        ShadowTrustedCertificateStore.sDelegate = mockCertStore;

        mCert = parseCertificate(TEST_CA);
        mSubject = mCert.getSubjectX500Principal().getName(X500Principal.CANONICAL);

        final ServiceController<KeyChainService> serviceController =
                Robolectric.buildService(KeyChainService.class).create().bind();
        final KeyChainService service = serviceController.get();
        service.setInjector(mockInjector);
        final Intent intent = new Intent(IKeyChainService.class.getName());
        mKeyChain = (IKeyChainService.Stub) service.onBind(intent);
    }

    @Test
    public void testCaInstallSuccessLogging() throws Exception {
        setUpLoggingAndAccess(true);

        mKeyChain.installCaCertificate(TEST_CA.getBytes());

        verify(mockInjector, times(1)).writeSecurityEvent(
                SecurityLog.TAG_CERT_AUTHORITY_INSTALLED, 1 /* success */, mSubject);
    }

    @Test
    public void testCaInstallFailedLogging() throws Exception {
        setUpLoggingAndAccess(true);

        doThrow(new IOException()).when(mockCertStore).installCertificate(any());

        try {
            mKeyChain.installCaCertificate(TEST_CA.getBytes());
            fail("didn't propagate the exception");
        } catch (IllegalStateException ignored) {
            assertTrue(ignored.getCause() instanceof IOException);
        }

        verify(mockInjector, times(1)).writeSecurityEvent(
                SecurityLog.TAG_CERT_AUTHORITY_INSTALLED, 0 /* failure */, mSubject);
    }

    @Test
    public void testCaRemoveSuccessLogging() throws Exception {
        setUpLoggingAndAccess(true);

        doReturn(mCert).when(mockCertStore).getCertificate("alias");

        mKeyChain.deleteCaCertificate("alias");

        verify(mockInjector, times(1)).writeSecurityEvent(
                SecurityLog.TAG_CERT_AUTHORITY_REMOVED, 1 /* success */, mSubject);
    }

    @Test
    public void testCaRemoveFailedLogging() throws Exception {
        setUpLoggingAndAccess(true);

        doReturn(mCert).when(mockCertStore).getCertificate("alias");
        doThrow(new IOException()).when(mockCertStore).deleteCertificateEntry(any());

        mKeyChain.deleteCaCertificate("alias");

        verify(mockInjector, times(1)).writeSecurityEvent(
                SecurityLog.TAG_CERT_AUTHORITY_REMOVED, 0 /* failure */, mSubject);
    }

    @Test
    public void testNoLoggingWhenDisabled() throws Exception {
        setUpLoggingAndAccess(false);

        doReturn(mCert).when(mockCertStore).getCertificate("alias");

        mKeyChain.installCaCertificate(TEST_CA.getBytes());
        mKeyChain.deleteCaCertificate("alias");

        doThrow(new IOException()).when(mockCertStore).installCertificate(any());
        doThrow(new IOException()).when(mockCertStore).deleteCertificateEntry(any());

        try {
            mKeyChain.installCaCertificate(TEST_CA.getBytes());
            fail("didn't propagate the exception");
        } catch (IllegalStateException ignored) {
            assertTrue(ignored.getCause() instanceof IOException);
        }
        mKeyChain.deleteCaCertificate("alias");

        verify(mockInjector, never()).writeSecurityEvent(anyInt(), anyInt(), anyVararg());
    }

    private X509Certificate parseCertificate(String cert) throws CertificateException {
        final CertificateFactory cf = CertificateFactory.getInstance("X.509");
        return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getBytes()));
    }

    private void setUpLoggingAndAccess(boolean loggingEnabled) {
        doReturn(loggingEnabled).when(mockInjector).isSecurityLoggingEnabled();
        // Pretend the caller is system.
        doReturn(1000).when(mockInjector).getCallingUid();
    }
}
