/*******************************************************************************
 * 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
}
