/*******************************************************************************
 * Copyright (c) 2006, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.framework.util.SecureAction;
import org.eclipse.osgi.internal.framework.EquinoxBundle;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.hookregistry.ActivatorHookFactory;
import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
import org.eclipse.osgi.internal.hookregistry.HookRegistry;
import org.eclipse.osgi.internal.service.security.KeyStoreTrustEngine;
import org.eclipse.osgi.internal.signedcontent.SignedContentFromBundleFile.BaseSignerInfo;
import org.eclipse.osgi.service.security.TrustEngine;
import org.eclipse.osgi.signedcontent.SignedContent;
import org.eclipse.osgi.signedcontent.SignedContentFactory;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

/**
 * Implements signed bundle hook support for the framework
 */
public class SignedBundleHook implements ActivatorHookFactory, HookConfigurator, SignedContentFactory {
	static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction());

	//TODO: comes from configuration!;
	private final static String CACERTS_PATH = System.getProperty("java.home") + File.separatorChar + "lib" + File.separatorChar + "security" + File.separatorChar + "cacerts"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
	private final static String CACERTS_TYPE = "JKS"; //$NON-NLS-1$
	private final static String OSGI_KEYSTORE = "osgi.framework.keystore"; //$NON-NLS-1$
	private int supportSignedBundles;
	TrustEngineListener trustEngineListener;
	private String trustEngineNameProp;
	private ServiceRegistration<?> signedContentFactoryReg;
	private ServiceRegistration<?> systemTrustEngineReg;
	private List<ServiceRegistration<?>> osgiTrustEngineReg;
	private ServiceTracker<TrustEngine, TrustEngine> trustEngineTracker;
	private BundleContext context;
	private EquinoxContainer container;

	@Override
	public BundleActivator createActivator() {
		return new BundleActivator() {

			@Override
			public void start(BundleContext bc) throws Exception {
				frameworkStart(bc);
			}

			@Override
			public void stop(BundleContext bc) throws Exception {
				frameworkStop(bc);
			}
		};
	}

	BundleContext getContext() {
		return context;
	}

	void frameworkStart(BundleContext bc) {
		this.context = bc;
		if ((supportSignedBundles & EquinoxConfiguration.SIGNED_CONTENT_VERIFY_TRUST) != 0)
			// initialize the trust engine listener only if trust is being established with a trust engine
			trustEngineListener = new TrustEngineListener(context, this);
		// always register the trust engine
		Dictionary<String, Object> trustEngineProps = new Hashtable<>(7);
		trustEngineProps.put(Constants.SERVICE_RANKING, Integer.valueOf(Integer.MIN_VALUE));
		trustEngineProps.put(SignedContentConstants.TRUST_ENGINE, SignedContentConstants.DEFAULT_TRUST_ENGINE);
		KeyStoreTrustEngine systemTrustEngine = new KeyStoreTrustEngine(CACERTS_PATH, CACERTS_TYPE, null, "System", this); //$NON-NLS-1$
		systemTrustEngineReg = context.registerService(TrustEngine.class.getName(), systemTrustEngine, trustEngineProps);
		String osgiTrustPath = context.getProperty(OSGI_KEYSTORE);
		if (osgiTrustPath != null) {
			try {
				URL url = new URL(osgiTrustPath);
				if ("file".equals(url.getProtocol())) { //$NON-NLS-1$
					trustEngineProps.put(SignedContentConstants.TRUST_ENGINE, OSGI_KEYSTORE);
					String path = url.getPath();
					osgiTrustEngineReg = new ArrayList<>(1);
					osgiTrustEngineReg.add(context.registerService(TrustEngine.class.getName(), new KeyStoreTrustEngine(path, CACERTS_TYPE, null, OSGI_KEYSTORE, this), trustEngineProps));
				}
			} catch (MalformedURLException e) {
				log("Invalid setting for " + OSGI_KEYSTORE, FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
			}
		} else {
			String osgiTrustRepoPaths = context.getProperty(Constants.FRAMEWORK_TRUST_REPOSITORIES);
			if (osgiTrustRepoPaths != null) {
				trustEngineProps.put(SignedContentConstants.TRUST_ENGINE, Constants.FRAMEWORK_TRUST_REPOSITORIES);
				StringTokenizer st = new StringTokenizer(osgiTrustRepoPaths, File.pathSeparator);
				osgiTrustEngineReg = new ArrayList<>(1);
				while (st.hasMoreTokens()) {
					String trustRepoPath = st.nextToken();
					osgiTrustEngineReg.add(context.registerService(TrustEngine.class.getName(), new KeyStoreTrustEngine(trustRepoPath, CACERTS_TYPE, null, OSGI_KEYSTORE, this), trustEngineProps));
				}
			}
		}
		// always register the signed content factory
		signedContentFactoryReg = context.registerService(SignedContentFactory.class.getName(), this, null);
	}

	void frameworkStop(BundleContext bc) {
		if (signedContentFactoryReg != null) {
			signedContentFactoryReg.unregister();
			signedContentFactoryReg = null;
		}
		if (systemTrustEngineReg != null) {
			systemTrustEngineReg.unregister();
			systemTrustEngineReg = null;
		}
		if (osgiTrustEngineReg != null) {
			for (Iterator<ServiceRegistration<?>> it = osgiTrustEngineReg.iterator(); it.hasNext();)
				it.next().unregister();
			osgiTrustEngineReg = null;
		}
		if (trustEngineTracker != null) {
			trustEngineTracker.close();
			trustEngineTracker = null;
		}
	}

	@Override
	public void addHooks(HookRegistry hookRegistry) {
		container = hookRegistry.getContainer();
		hookRegistry.addActivatorHookFactory(this);
		supportSignedBundles = hookRegistry.getConfiguration().supportSignedBundles;
		trustEngineNameProp = hookRegistry.getConfiguration().getConfiguration(SignedContentConstants.TRUST_ENGINE);
	}

	@Override
	public SignedContent getSignedContent(File content) throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
		SignedContentFromBundleFile signedContent = new SignedContentFromBundleFile(content,
				container.getConfiguration().getDebug());
		determineTrust(signedContent, EquinoxConfiguration.SIGNED_CONTENT_VERIFY_TRUST);
		return signedContent;
	}

	@Override
	public SignedContent getSignedContent(Bundle bundle) throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
		Generation generation = (Generation) ((EquinoxBundle) bundle).getModule().getCurrentRevision()
				.getRevisionInfo();
		SignedContentFromBundleFile signedContent = new SignedContentFromBundleFile(generation.getBundleFile());
		determineTrust(signedContent, EquinoxConfiguration.SIGNED_CONTENT_VERIFY_TRUST);
		return signedContent;
	}

	public void log(String msg, int severity, Throwable t) {
		container.getLogServices().log(EquinoxContainer.NAME, severity, msg, t);
	}

	private TrustEngine[] getTrustEngines() {
		// find all the trust engines available
		if (context == null)
			return new TrustEngine[0];
		if (trustEngineTracker == null) {
			// read the trust provider security property
			Filter filter = null;
			if (trustEngineNameProp != null)
				try {
					filter = context.createFilter("(&(" + Constants.OBJECTCLASS + "=" + TrustEngine.class.getName() + ")(" + SignedContentConstants.TRUST_ENGINE + "=" + trustEngineNameProp + "))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$
				} catch (InvalidSyntaxException e) {
					log("Invalid trust engine filter", FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
				}
			if (filter != null) {
				trustEngineTracker = new ServiceTracker<>(context, filter, new TrustEngineCustomizer());
			} else
				trustEngineTracker = new ServiceTracker<>(context, TrustEngine.class.getName(), new TrustEngineCustomizer());
			trustEngineTracker.open();
		}
		Object[] services = trustEngineTracker.getServices();
		if (services != null) {
			TrustEngine[] engines = new TrustEngine[services.length];
			System.arraycopy(services, 0, engines, 0, services.length);
			return engines;
		}
		return new TrustEngine[0];
	}

	class TrustEngineCustomizer implements ServiceTrackerCustomizer<TrustEngine, TrustEngine> {

		@Override
		public TrustEngine addingService(ServiceReference<TrustEngine> reference) {
			TrustEngine engine = getContext().getService(reference);
			if (engine != null) {
				try {
					Field trustEngineListenerField = TrustEngine.class.getDeclaredField("trustEngineListener"); //$NON-NLS-1$
					trustEngineListenerField.setAccessible(true);
					trustEngineListenerField.set(engine, SignedBundleHook.this.trustEngineListener);
				} catch (Exception e) {
					log("Unable to set the trust engine listener.", FrameworkLogEntry.ERROR, e); //$NON-NLS-1$
				}

			}
			return engine;
		}

		@Override
		public void modifiedService(ServiceReference<TrustEngine> reference, TrustEngine service) {
			// nothing
		}

		@Override
		public void removedService(ServiceReference<TrustEngine> reference, TrustEngine service) {
			// nothing
		}

	}

	void determineTrust(SignedContentFromBundleFile trustedContent, int supportFlags) {
		TrustEngine[] engines = null;
		SignerInfo[] signers = trustedContent.getSignerInfos();
		for (SignerInfo signer : signers) {
			// first check if we need to find an anchor
			if (signer.getTrustAnchor() == null) {
				// no anchor set ask the trust engines
				if (engines == null)
					engines = getTrustEngines();
				// check trust of singer certs
				Certificate[] signerCerts = signer.getCertificateChain();
				((BaseSignerInfo) signer).setTrustAnchor(findTrustAnchor(signerCerts, engines, supportFlags));
				// if signer has a tsa check trust of tsa certs
				SignerInfo tsaSignerInfo = trustedContent.getTSASignerInfo(signer);
				if (tsaSignerInfo != null) {
					Certificate[] tsaCerts = tsaSignerInfo.getCertificateChain();
					((BaseSignerInfo) tsaSignerInfo).setTrustAnchor(findTrustAnchor(tsaCerts, engines, supportFlags));
				}
			}
		}
	}

	private Certificate findTrustAnchor(Certificate[] certs, TrustEngine[] engines, int supportFlags) {
		if ((supportFlags & EquinoxConfiguration.SIGNED_CONTENT_VERIFY_TRUST) == 0)
			// we are not searching the engines; in this case we just assume the root cert is trusted
			return certs != null && certs.length > 0 ? certs[certs.length - 1] : null;
			for (TrustEngine engine : engines) {
				try {
					Certificate anchor = engine.findTrustAnchor(certs);
					if (anchor != null)
						// found an anchor
						return anchor;
				} catch (IOException e) {
					// log the exception and continue
					log("TrustEngine failure: " + engine.getName(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
				}
			}
			return null;
	}
}
