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