/*******************************************************************************
 * Copyright (c) 2005, 2019 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.tests.security;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.osgi.internal.service.security.KeyStoreTrustEngine;
import org.eclipse.osgi.service.security.TrustEngine;
import org.eclipse.osgi.tests.OSGiTestsActivator;

public class KeyStoreTrustEngineTest extends TestCase {

	private static char[] PASSWORD_DEFAULT = { 'c', 'h', 'a', 'n', 'g', 'e', 'i', 't' };
	private static String TYPE_DEFAULT = "JKS"; //$NON-NLS-1$

	private static TestCase[] s_tests = {
			/* findTrustAnchor tests */
			new KeyStoreTrustEngineTest("findTrustAnchor positive test: self signed trusted", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor0();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor positive test: chain with root trusted", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor1();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor positive test: chain with intermediate trusted", "ca1_ou") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor2();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor positive test: chain with leaf trusted", "ca1_leafb") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor3();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: untrusted self signed") { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor4();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: untrusted chain") { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor5();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: invalid chain") { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor6();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: incomplete-able chain") { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor7();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: null chain") { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor8();
				}
			},
			/* addTrustAnchor tests */
			new KeyStoreTrustEngineTest("addTrustAnchor positive test: add with alias") { //$NON-NLS-1$
				public void runTest() {
					testAddTrustAnchor0();
				}
			}, /*
				 * , new
				 * KeyStoreTrustEngineTest("addTrustAnchor positive test: add with autogenerated alias"
				 * , null) { public void runTest() { testAddTrustAnchor1(); } }
				 */
			new KeyStoreTrustEngineTest("addTrustAnchor negative test: null cert specified") { //$NON-NLS-1$
				public void runTest() {
					testAddTrustAnchor2();
				}
			}, new KeyStoreTrustEngineTest("addTrustAnchor negative test: existing cert specified", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testAddTrustAnchor3();
				}
			}, new KeyStoreTrustEngineTest("addTrustAnchor negative test: existing alias specified", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testAddTrustAnchor4();
				}
			}
			/* removeTrustAnchor tests */
			, new KeyStoreTrustEngineTest("removeTrustAnchor positive test: remove by alias", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testRemoveTrustAnchor0();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor positive test: remove by cert", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testRemoveTrustAnchor1();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: cert not found") { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor2();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: by alias not found") { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor3();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: remove by null alias") { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor4();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: remove by null certificate") { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor5();
				}
			},
			/* getTrustAnchor tests */
			new KeyStoreTrustEngineTest("getTrustAnchor positive test: get by alias", "ca1_root") { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testGetTrustAnchor0();
				}
			}, new KeyStoreTrustEngineTest("getTrustAnchor negative test: get by null alias") { //$NON-NLS-1$
				public void runTest() {
					testGetTrustAnchor1();
				}
			}, new KeyStoreTrustEngineTest("getTrustAnchor negative test: does not exist") { //$NON-NLS-1$
				public void runTest() {
					testGetTrustAnchor2();
				}
			},
			/* getAliases tests */
			new KeyStoreTrustEngineTest("getAliases positive test: get the alias list", "ca1_root", "ca2_root") { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				public void runTest() {
					testGetAliases0();
				}
			} };

	public static Test suite() {
		TestSuite suite = new TestSuite("Unit tests for TrustEngine"); //$NON-NLS-1$
		for (TestCase s_test : s_tests) {
			suite.addTest(s_test);
		}
		return suite;
	}

	private static KeyStore supportStore;
	static {
		try {
			URL supportUrl = OSGiTestsActivator.getContext().getBundle().getEntry("test_files/security/keystore.jks"); //$NON-NLS-1$
			supportStore = KeyStore.getInstance(TYPE_DEFAULT);
			supportStore.load(supportUrl.openStream(), PASSWORD_DEFAULT);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String[] aliases;
	private KeyStore testStore;
	private File testStoreFile;
	TrustEngine engine;

	public KeyStoreTrustEngineTest() {
		// placeholder
	}

	public KeyStoreTrustEngineTest(String name, String... aliases) {
		super(name);
		this.aliases = aliases;
	}

	protected void setUp() throws Exception {
		if (supportStore == null) {
			fail("Could not open keystore with test certificates!"); //$NON-NLS-1$
		}

		testStore = KeyStore.getInstance(TYPE_DEFAULT);
		testStore.load(null, PASSWORD_DEFAULT);
		if (aliases != null) {
			for (String alias : aliases) {
				testStore.setCertificateEntry(alias, getTestCertificate(alias));
			}
		}
		testStoreFile = File.createTempFile("teststore", "jks"); //$NON-NLS-1$ //$NON-NLS-2$
		final FileOutputStream out = new FileOutputStream(testStoreFile);
		try {
			testStore.store(out, PASSWORD_DEFAULT);
		} finally {
			safeClose(out);
		}
		engine = new KeyStoreTrustEngine(testStoreFile.getPath(), TYPE_DEFAULT, PASSWORD_DEFAULT, "teststore", null); //$NON-NLS-1$
	}

	/**
	 * Closes a stream and ignores any resulting exception. This is useful when
	 * doing stream cleanup in a finally block where secondary exceptions are not
	 * worth logging.
	 */
	protected static void safeClose(OutputStream out) {
		try {
			if (out != null)
				out.close();
		} catch (IOException e) {
			// ignore
		}
	}

	protected void tearDown() {
		engine = null;
		testStore = null;
		testStoreFile.delete();
	}

	private static Certificate getTestCertificate(String alias) throws KeyStoreException {
		return supportStore.getCertificate(alias);
	}

	private static Certificate[] getTestCertificateChain(String... aliases) throws KeyStoreException {
		ArrayList<Certificate> certs = new ArrayList<>(aliases.length);
		for (String alias : aliases) {
			certs.add(getTestCertificate(alias));
		}
		return certs.toArray(new Certificate[] {});
	}

	// findTrustAnchor positive test: self signed trusted
	public void testFindTrustAnchor0() {
		try {
			Certificate cert = engine.findTrustAnchor(new Certificate[] { getTestCertificate("ca1_root") }); //$NON-NLS-1$
			assertNotNull("Did not return a cert for self-signed case", cert); //$NON-NLS-1$
			assertEquals("Input and output certs not equal for self-signed case", cert, getTestCertificate("ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (Throwable t) {
			fail("Unexpected exception testing trusted self-signed cert: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// findTrustAnchor positive test: chain with root trusted
	public void testFindTrustAnchor1() {
		try {
			Certificate cert = engine.findTrustAnchor(getTestCertificateChain("ca1_leafb", "ca1_ou", "ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			assertNotNull("Certificate did not come back in trusted root case", cert); //$NON-NLS-1$
			assertEquals("Output cert is not root trusted cert", cert, getTestCertificate("ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (Throwable t) {
			fail("Unexpected exception testing trusted root from complete chain: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// findTrustAnchor positive test: chain with intermediate trusted
	public void testFindTrustAnchor2() {
		try {
			Certificate cert = engine.findTrustAnchor(getTestCertificateChain("ca1_leafb", "ca1_ou", "ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			assertNotNull("Certificate did not come back in trusted intermediate case", cert); //$NON-NLS-1$
			assertEquals("Output cert is not intermediate trusted cert", cert, getTestCertificate("ca1_ou")); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (Throwable t) {
			fail("Unexpected exception testing trusted root from complete chain: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// findTrustAnchor positive test: chain with leaf trusted
	public void testFindTrustAnchor3() {
		try {
			Certificate cert = engine.findTrustAnchor(getTestCertificateChain("ca1_leafb", "ca1_ou", "ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			assertNotNull("Certificate did not come back in trusted leaf case", cert); //$NON-NLS-1$
			assertEquals("Output cert is not leaf trusted cert", cert, getTestCertificate("ca1_leafb")); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (Throwable t) {
			fail("Unexpected exception testing trusted root from complete chain: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// findTrustAnchor negative test: untrusted self signed
	public void testFindTrustAnchor4() {
		try {
			Certificate cert = engine.findTrustAnchor(new Certificate[] { getTestCertificate("ca2_root") }); //$NON-NLS-1$
			assertNull("Incorrectly returned a certificate for untrusted self-signed case", cert); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Unexpected exception testing untrusted self-signed cert: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// findTrustAnchor negative test: untrusted chain
	public void testFindTrustAnchor5() {
		try {
			Certificate cert = engine.findTrustAnchor(getTestCertificateChain("ca2_leafb", "ca2_ou", "ca2_root")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			assertNull("Incorrectly returned a certificate for untrusted chain case", cert); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Unexpected exception testing untrusted chain: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// findTrustAnchor negative test: invalid chain
	public void testFindTrustAnchor6() {
		try {
			Certificate cert = engine.findTrustAnchor(getTestCertificateChain("ca2_leafa", "ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$
			assertNull("Incorrectly returned a certificate on invalid certificate chain", cert); //$NON-NLS-1$
		} catch (Throwable t) {
			assertNull("Incorrectly thrown exception thrown on invalid certificate chain", t); //$NON-NLS-1$
		}
	}

	// findTrustAnchor negative test: incomplete-able chain
	public void testFindTrustAnchor7() {
		try {
			Certificate cert = engine.findTrustAnchor(getTestCertificateChain("ca1_leafb", "ca1_root")); //$NON-NLS-1$ //$NON-NLS-2$
			assertNull("Incorrectly returned a certificate on incomplete-able certificate chain", cert); //$NON-NLS-1$
		} catch (Throwable t) {
			assertNull("Incorrectly thrown exception thrown on incomplete-able certificate chain", t); //$NON-NLS-1$
		}
	}

	// findTrustAnchor negative test: null chain
	public void testFindTrustAnchor8() {
		try {
			engine.findTrustAnchor(null);
			fail("Did not throw IllegalArgumentException on NULL certificate"); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on NULL certificate", t instanceof IllegalArgumentException); //$NON-NLS-1$
		}
	}

	// testAddTrustAnchor positive test: add with alias
	public void testAddTrustAnchor0() {
		try {
			String alias = engine.addTrustAnchor(getTestCertificate("ca1_root"), "ca1_root"); //$NON-NLS-1$ //$NON-NLS-2$
			assertEquals("Alias returned does not equal alias input", alias, "ca1_root"); //$NON-NLS-1$ //$NON-NLS-2$

		} catch (Throwable t) {
			fail("Unexpected exception adding trusted root: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// testAddTrustAnchor positive test: add with autogenerated alias
	public void testAddTrustAnchor1() {
		try {
			String alias = engine.addTrustAnchor(getTestCertificate("ca1_root"), null); //$NON-NLS-1$
			assertNotNull("Generated alias was not correctly returned", alias); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Unexpected exception adding trusted root (autogen alias): " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// testAddTrustAnchor negative test: null cert specified
	public void testAddTrustAnchor2() {
		try {
			engine.addTrustAnchor(null, "ca1_root"); //$NON-NLS-1$
			fail("Did not throw IllegalArgumentException on NULL certificate"); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on NULL certificate", t instanceof IllegalArgumentException); //$NON-NLS-1$
		}
	}

	// testAddTrustAnchor negative test: existing cert specified
	public void testAddTrustAnchor3() {
		try {
			engine.addTrustAnchor(getTestCertificate("ca1_root"), "new_root"); //$NON-NLS-1$ //$NON-NLS-2$
			assertTrue("Did not throw CertificateException on duplicate cert", false); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on duplicate cert", t instanceof CertificateException); //$NON-NLS-1$
			return;
		}
		fail("Expected exception when adding trust anchor"); //$NON-NLS-1$
	}

	// testAddTrustAnchor negative test: existing alias specified
	public void testAddTrustAnchor4() {
		try {
			engine.addTrustAnchor(getTestCertificate("ca2_root"), "ca1_root"); //$NON-NLS-1$ //$NON-NLS-2$
			assertTrue("Did not throw CertificateException on duplicate alias", false); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on duplicate alias", t instanceof CertificateException); //$NON-NLS-1$
			return;
		}
		fail("Expected exception when adding trust anchor"); //$NON-NLS-1$
	}

	// removeTrustAnchor positive test: remove by alias
	public void testRemoveTrustAnchor0() {
		try {
			engine.removeTrustAnchor("ca1_root"); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Unexpected exception thrown when removing by alias: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// removeTrustAnchor positive test: remove by cert
	public void testRemoveTrustAnchor1() {
		try {
			engine.removeTrustAnchor(getTestCertificate("ca1_root")); //$NON-NLS-1$
		} catch (Throwable t) {
			fail("Unexpected exception thrown when removing by cert: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// removeTrustAnchor negative test: cert not found
	public void testRemoveTrustAnchor2() {
		try {
			engine.removeTrustAnchor(getTestCertificate("ca1_root")); //$NON-NLS-1$
			fail("Did not throw CertificateException on cert not found"); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on remove by cert", t instanceof CertificateException); //$NON-NLS-1$
		}
	}

	// removeTrustAnchor negative test: by alias not found
	public void testRemoveTrustAnchor3() {
		try {
			engine.removeTrustAnchor("ca2_root"); //$NON-NLS-1$
			assertTrue("Did not throw CertificateException on alias not found", false); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on remove by alias", t instanceof CertificateException); //$NON-NLS-1$
			return;
		}
		fail("Expected exception when removing trust anchor"); //$NON-NLS-1$
	}

	// removeTrustAnchor negative test: remove by null alias
	public void testRemoveTrustAnchor4() {
		try {
			engine.removeTrustAnchor((String) null);
			fail("Did not throw CertificateException on alias null"); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on remove by null alias", t instanceof IllegalArgumentException); //$NON-NLS-1$
		}
	}

	// removeTrustAnchor negative test: remove by null certificate
	public void testRemoveTrustAnchor5() {
		try {
			engine.removeTrustAnchor((Certificate) null);
			fail("Did not throw IllegalArgumentException on remove by cert null"); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on remove by null cert", t instanceof IllegalArgumentException); //$NON-NLS-1$
		}
	}

	// getTrustAnchor positive test: get by alias
	public void testGetTrustAnchor0() {
		try {
			Certificate cert = engine.getTrustAnchor("ca1_root"); //$NON-NLS-1$
			assertEquals("Did not get expected certificate", getTestCertificate("ca1_root"), cert); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (Throwable t) {
			fail("Unexpected exception when retrieving trust anchor: " + t.getMessage()); //$NON-NLS-1$
		}
	}

	// getTrustAnchor negative test: get by null alias
	public void testGetTrustAnchor1() {
		try {
			engine.getTrustAnchor(null);
			fail("Did not throw IllegalArgumentException on get by alias null"); //$NON-NLS-1$
		} catch (Throwable t) {
			assertTrue("Incorrect exception thrown on remove by null alias", t instanceof IllegalArgumentException); //$NON-NLS-1$
		}
	}

	// getTrustAnchor negative test: does not exist
	public void testGetTrustAnchor2() {
		try {
			Certificate cert = engine.getTrustAnchor("ca2_root"); //$NON-NLS-1$
			assertNull("Incorrectly returned a certificate on certificate does not exist", cert); //$NON-NLS-1$
		} catch (Throwable t) {
			assertNull("Incorrectly thrown exception on alias does not exist", t); //$NON-NLS-1$
			return;
		}
	}

	// getAliases positive test: get the alias list
	public void testGetAliases0() {
		try {
			engine.getAliases();
		} catch (Throwable t) {
			fail("Unexpected exception when retrieving alias list: " + t.getMessage()); //$NON-NLS-1$
		}

	}
	// TODO: thread safety tests
	// TODO: performance tests
}
