/*
 * 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 com.android.server.devicepolicy;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.security.Credentials;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.util.Log;

import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.R;

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

public class CertificateMonitor {
    protected static final String LOG_TAG = DevicePolicyManagerService.LOG_TAG;
    protected static final int MONITORING_CERT_NOTIFICATION_ID = SystemMessage.NOTE_SSL_CERT_INFO;

    private final DevicePolicyManagerService mService;
    private final DevicePolicyManagerService.Injector mInjector;
    private final Handler mHandler;

    public CertificateMonitor(final DevicePolicyManagerService service,
            final DevicePolicyManagerService.Injector injector, final Handler handler) {
        mService = service;
        mInjector = injector;
        mHandler = handler;

        // Broadcast filter for changes to the trusted certificate store. Listens on the background
        // handler to avoid blocking time-critical tasks on the main handler thread.
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_USER_STARTED);
        filter.addAction(Intent.ACTION_USER_UNLOCKED);
        filter.addAction(KeyChain.ACTION_TRUST_STORE_CHANGED);
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        mInjector.mContext.registerReceiverAsUser(
                mRootCaReceiver, UserHandle.ALL, filter, null, mHandler);
    }

    public String installCaCert(final UserHandle userHandle, byte[] certBuffer) {
        // Convert certificate data from X509 format to PEM.
        byte[] pemCert;
        try {
            X509Certificate cert = parseCert(certBuffer);
            pemCert = Credentials.convertToPem(cert);
        } catch (CertificateException | IOException ce) {
            Log.e(LOG_TAG, "Problem converting cert", ce);
            return null;
        }

        try (KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser(userHandle)) {
            return keyChainConnection.getService().installCaCertificate(pemCert);
        } catch (RemoteException e) {
            Log.e(LOG_TAG, "installCaCertsToKeyChain(): ", e);
        } catch (InterruptedException e1) {
            Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1);
            Thread.currentThread().interrupt();
        }
        return null;
    }

    public void uninstallCaCerts(final UserHandle userHandle, final String[] aliases) {
        try (KeyChainConnection keyChainConnection = mInjector.keyChainBindAsUser(userHandle)) {
            for (int i = 0 ; i < aliases.length; i++) {
                keyChainConnection.getService().deleteCaCertificate(aliases[i]);
            }
        } catch (RemoteException e) {
            Log.e(LOG_TAG, "from CaCertUninstaller: ", e);
        } catch (InterruptedException ie) {
            Log.w(LOG_TAG, "CaCertUninstaller: ", ie);
            Thread.currentThread().interrupt();
        }
    }

    public List<String> getInstalledCaCertificates(UserHandle userHandle)
            throws RemoteException, RuntimeException {
        try (KeyChainConnection conn = mInjector.keyChainBindAsUser(userHandle)) {
            return conn.getService().getUserCaAliases().getList();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return null;
        } catch (AssertionError e) {
            throw new RuntimeException(e);
        }
    }

    public void onCertificateApprovalsChanged(int userId) {
        mHandler.post(() -> updateInstalledCertificates(UserHandle.of(userId)));
    }

    /**
     * Broadcast receiver for changes to the trusted certificate store.
     */
    private final BroadcastReceiver mRootCaReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (StorageManager.inCryptKeeperBounce()) {
                return;
            }
            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId());
            updateInstalledCertificates(UserHandle.of(userId));
        }
    };

    private void updateInstalledCertificates(final UserHandle userHandle) {
        if (!mInjector.getUserManager().isUserUnlocked(userHandle.getIdentifier())) {
            return;
        }

        final List<String> installedCerts;
        try {
            installedCerts = getInstalledCaCertificates(userHandle);
        } catch (RemoteException | RuntimeException e) {
            Log.e(LOG_TAG, "Could not retrieve certificates from KeyChain service", e);
            return;
        }
        mService.onInstalledCertificatesChanged(userHandle, installedCerts);

        final int pendingCertificateCount =
                installedCerts.size() - mService.getAcceptedCaCertificates(userHandle).size();
        if (pendingCertificateCount != 0) {
            final Notification noti = buildNotification(userHandle, pendingCertificateCount);
            mInjector.getNotificationManager().notifyAsUser(
                    LOG_TAG, MONITORING_CERT_NOTIFICATION_ID, noti, userHandle);
        } else {
            mInjector.getNotificationManager().cancelAsUser(
                    LOG_TAG, MONITORING_CERT_NOTIFICATION_ID, userHandle);
        }
    }

    private Notification buildNotification(UserHandle userHandle, int pendingCertificateCount) {
        final Context userContext;
        try {
            userContext = mInjector.createContextAsUser(userHandle);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(LOG_TAG, "Create context as " + userHandle + " failed", e);
            return null;
        }

        final Resources resources = mInjector.getResources();
        final int smallIconId;
        final String contentText;

        int parentUserId = userHandle.getIdentifier();

        if (mService.getProfileOwner(userHandle.getIdentifier()) != null) {
            contentText = resources.getString(R.string.ssl_ca_cert_noti_managed,
                    mService.getProfileOwnerName(userHandle.getIdentifier()));
            smallIconId = R.drawable.stat_sys_certificate_info;
            parentUserId = mService.getProfileParentId(userHandle.getIdentifier());
        } else if (mService.getDeviceOwnerUserId() == userHandle.getIdentifier()) {
            final String ownerName = mService.getDeviceOwnerName();
            contentText = resources.getString(R.string.ssl_ca_cert_noti_managed,
                    mService.getDeviceOwnerName());
            smallIconId = R.drawable.stat_sys_certificate_info;
        } else {
            contentText = resources.getString(R.string.ssl_ca_cert_noti_by_unknown);
            smallIconId = android.R.drawable.stat_sys_warning;
        }

        // Create an intent to launch an activity showing information about the certificate.
        Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
        dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        dialogIntent.putExtra(Settings.EXTRA_NUMBER_OF_CERTIFICATES, pendingCertificateCount);
        dialogIntent.putExtra(Intent.EXTRA_USER_ID, userHandle.getIdentifier());

        // The intent should only be allowed to resolve to a system app.
        ActivityInfo targetInfo = dialogIntent.resolveActivityInfo(
                mInjector.getPackageManager(), PackageManager.MATCH_SYSTEM_ONLY);
        if (targetInfo != null) {
            dialogIntent.setComponent(targetInfo.getComponentName());
        }

        PendingIntent notifyIntent = mInjector.pendingIntentGetActivityAsUser(userContext, 0,
                dialogIntent, PendingIntent.FLAG_UPDATE_CURRENT, null,
                UserHandle.of(parentUserId));

        return new Notification.Builder(userContext, SystemNotificationChannels.SECURITY)
                .setSmallIcon(smallIconId)
                .setContentTitle(resources.getQuantityText(R.plurals.ssl_ca_cert_warning,
                        pendingCertificateCount))
                .setContentText(contentText)
                .setContentIntent(notifyIntent)
                .setShowWhen(false)
                .setColor(R.color.system_notification_accent_color)
                .build();
    }

    private static X509Certificate parseCert(byte[] certBuffer) throws CertificateException {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(
                certBuffer));
    }
}
