/*
 * Copyright (C) 2011 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.tests;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.security.Credentials;
import android.security.IKeyChainService;
import android.security.KeyStore;
import android.util.Log;
import com.android.keychain.tests.support.IKeyChainServiceTestSupport;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.cert.Certificate;
import java.util.Arrays;
import junit.framework.Assert;
import libcore.java.security.TestKeyStore;

public class KeyChainServiceTest extends Service {

    private static final String TAG = "KeyChainServiceTest";

    private final Object mSupportLock = new Object();
    private IKeyChainServiceTestSupport mSupport;
    private boolean mIsBoundSupport;

    private final Object mServiceLock = new Object();
    private IKeyChainService mService;
    private boolean mIsBoundService;

    private ServiceConnection mSupportConnection = new ServiceConnection() {
        @Override public void onServiceConnected(ComponentName name, IBinder service) {
            synchronized (mSupportLock) {
                mSupport = IKeyChainServiceTestSupport.Stub.asInterface(service);
                mSupportLock.notifyAll();
            }
        }

        @Override public void onServiceDisconnected(ComponentName name) {
            synchronized (mSupportLock) {
                mSupport = null;
            }
        }
    };

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override public void onServiceConnected(ComponentName name, IBinder service) {
            synchronized (mServiceLock) {
                mService = IKeyChainService.Stub.asInterface(service);
                mServiceLock.notifyAll();
            }
        }

        @Override public void onServiceDisconnected(ComponentName name) {
            synchronized (mServiceLock) {
                mService = null;
            }
        }
    };

    private static void addComponentToIntent(PackageManager pm, Intent intent) {
        ResolveInfo service = pm.resolveService(intent, 0);
        if (service == null) {
            Log.w(TAG, String.format("No service found for intent: %s", intent.getAction()));
        } else {
            Log.d(TAG, String.format("Found service: %s %s for action %s",
                        service.serviceInfo.packageName, service.serviceInfo.name,
                        intent.getAction()));
            ComponentName comp = new ComponentName(
                    service.serviceInfo.packageName, service.serviceInfo.name);
            intent.setComponent(comp);
        }
    }

    private void bindSupport() {
        Intent serviceIntent = new Intent(IKeyChainServiceTestSupport.class.getName());
        addComponentToIntent(getPackageManager(), serviceIntent);
        mIsBoundSupport = bindService(serviceIntent,
                                      mSupportConnection,
                                      Context.BIND_AUTO_CREATE);
        Log.d(TAG, String.format("Finished bindSupport with result: %b", mIsBoundSupport));
    }

    private void bindService() {
        Intent serviceIntent = new Intent(IKeyChainService.class.getName());
        addComponentToIntent(getPackageManager(), serviceIntent);
        mIsBoundService = bindService(serviceIntent,
                                      mServiceConnection,
                                      Context.BIND_AUTO_CREATE);
        Log.d(TAG, String.format("Finished bindService with result: %b", mIsBoundService));
    }

    private void unbindServices() {
        if (mIsBoundSupport) {
            unbindService(mSupportConnection);
            mIsBoundSupport = false;
        }
        if (mIsBoundService) {
            unbindService(mServiceConnection);
            mIsBoundService = false;
        }
    }

    @Override public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind");
        return null;
    }

    @Override public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand");
        new Thread(new Test(), TAG).start();
        return START_STICKY;
    }

    @Override public void onDestroy () {
        Log.d(TAG, "onDestroy");
        unbindServices();
    }

    private final class Test extends Assert implements Runnable {

        @Override public void run() {
            try {
                test_KeyChainService();
            } catch (RuntimeException e) {
                // rethrow RuntimeException without wrapping
                throw e;
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                stopSelf();
            }
        }

        public void test_KeyChainService() throws Exception {
            Log.d(TAG, "test_KeyChainService uid=" + getApplicationInfo().uid);

            Log.d(TAG, "test_KeyChainService bind support");
            bindSupport();
            assertTrue(mIsBoundSupport);
            synchronized (mSupportLock) {
                if (mSupport == null) {
                    mSupportLock.wait(10 * 1000);
                }
            }
            assertNotNull(mSupport);

            Log.d(TAG, "test_KeyChainService setup keystore");
            KeyStore keyStore = KeyStore.getInstance();
            assertTrue(mSupport.keystoreReset());
            assertTrue(mSupport.keystoreSetPassword("newpasswd"));

            String intermediate = "-intermediate";
            String root = "-root";

            String alias1 = "client";
            String alias1Intermediate = alias1 + intermediate;
            String alias1Root = alias1 + root;
            String alias1Pkey = (Credentials.USER_PRIVATE_KEY + alias1);
            String alias1Cert = (Credentials.USER_CERTIFICATE + alias1);
            String alias1ICert = (Credentials.CA_CERTIFICATE + alias1Intermediate);
            String alias1RCert = (Credentials.CA_CERTIFICATE + alias1Root);
            PrivateKeyEntry pke1 = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
            Certificate intermediate1 = pke1.getCertificateChain()[1];
            Certificate root1 = TestKeyStore.getClientCertificate().getRootCertificate("RSA");

            final String alias2 = "server";
            String alias2Intermediate = alias2 + intermediate;
            String alias2Root = alias2 + root;
            String alias2Pkey = (Credentials.USER_PRIVATE_KEY + alias2);
            String alias2Cert = (Credentials.USER_CERTIFICATE + alias2);
            String alias2ICert = (Credentials.CA_CERTIFICATE + alias2Intermediate);
            String alias2RCert = (Credentials.CA_CERTIFICATE + alias2Root);
            PrivateKeyEntry pke2 = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
            Certificate intermediate2 = pke2.getCertificateChain()[1];
            Certificate root2 = TestKeyStore.getServer().getRootCertificate("RSA");

            assertTrue(mSupport.keystoreImportKey(alias1Pkey,
                                           pke1.getPrivateKey().getEncoded()));
            assertTrue(mSupport.keystorePut(alias1Cert,
                                            Credentials.convertToPem(pke1.getCertificate())));
            assertTrue(mSupport.keystorePut(alias1ICert,
                                            Credentials.convertToPem(intermediate1)));
            assertTrue(mSupport.keystorePut(alias1RCert,
                                            Credentials.convertToPem(root1)));
            assertTrue(mSupport.keystoreImportKey(alias2Pkey,
                                            pke2.getPrivateKey().getEncoded()));
            assertTrue(mSupport.keystorePut(alias2Cert,
                                            Credentials.convertToPem(pke2.getCertificate())));
            assertTrue(mSupport.keystorePut(alias2ICert,
                                            Credentials.convertToPem(intermediate2)));
            assertTrue(mSupport.keystorePut(alias2RCert,
                                            Credentials.convertToPem(root2)));

            assertEquals(KeyStore.State.UNLOCKED, keyStore.state());

            Log.d(TAG, "test_KeyChainService bind service");
            bindService();
            assertTrue(mIsBoundService);
            synchronized (mServiceLock) {
                if (mService == null) {
                    mServiceLock.wait(10 * 1000);
                }
            }
            assertNotNull(mService);

            mSupport.grantAppPermission(getApplicationInfo().uid, alias1);
            // don't grant alias2, so it can be done manually with KeyChainTestActivity
            Log.d(TAG, "test_KeyChainService positive testing");
            assertNotNull("Requesting private key should succeed",
                    mService.requestPrivateKey(alias1));

            byte[] certificate = mService.getCertificate(alias1);
            assertNotNull(certificate);
            assertEquals(Arrays.toString(Credentials.convertToPem(pke1.getCertificate())),
                         Arrays.toString(certificate));

            Log.d(TAG, "test_KeyChainService negative testing");
            mSupport.revokeAppPermission(getApplicationInfo().uid, alias2);
            try {
                mService.requestPrivateKey(alias2);
                fail();
            } catch (IllegalStateException expected) {
            }

            try {
                mService.getCertificate(alias2);
                fail();
            } catch (IllegalStateException expected) {
            }

            Log.d(TAG, "test_KeyChainService unbind");
            unbindServices();
            assertFalse(mIsBoundSupport);
            assertFalse(mIsBoundService);

            Log.d(TAG, "test_KeyChainService end");
        }
    }
}
