/*******************************************************************************
 * Copyright (c) 2005, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.tests.security;

import java.io.*;
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.*;
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", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor0();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor positive test: chain with root trusted", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor1();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor positive test: chain with intermediate trusted", new String[] {"ca1_ou"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor2();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor positive test: chain with leaf trusted", new String[] {"ca1_leafb"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testFindTrustAnchor3();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: untrusted self signed", null) { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor4();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: untrusted chain", null) { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor5();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: invalid chain", null) { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor6();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: incomplete-able chain", null) { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor7();
				}
			}, new KeyStoreTrustEngineTest("findTrustAnchor negative test: null chain", null) { //$NON-NLS-1$
				public void runTest() {
					testFindTrustAnchor8();
				}
			},
			/* addTrustAnchor tests */
			new KeyStoreTrustEngineTest("addTrustAnchor positive test: add with alias", null) { //$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", null) { //$NON-NLS-1$
				public void runTest() {
					testAddTrustAnchor2();
				}
			}, new KeyStoreTrustEngineTest("addTrustAnchor negative test: existing cert specified", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testAddTrustAnchor3();
				}
			}, new KeyStoreTrustEngineTest("addTrustAnchor negative test: existing alias specified", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testAddTrustAnchor4();
				}
			}
			/* removeTrustAnchor tests */
			, new KeyStoreTrustEngineTest("removeTrustAnchor positive test: remove by alias", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testRemoveTrustAnchor0();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor positive test: remove by cert", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testRemoveTrustAnchor1();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: cert not found", null) { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor2();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: by alias not found", null) { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor3();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: remove by null alias", null) { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor4();
				}
			}, new KeyStoreTrustEngineTest("removeTrustAnchor negative test: remove by null certificate", null) { //$NON-NLS-1$
				public void runTest() {
					testRemoveTrustAnchor5();
				}
			},
			/* getTrustAnchor tests*/
			new KeyStoreTrustEngineTest("getTrustAnchor positive test: get by alias", new String[] {"ca1_root"}) { //$NON-NLS-1$ //$NON-NLS-2$
				public void runTest() {
					testGetTrustAnchor0();
				}
			}, new KeyStoreTrustEngineTest("getTrustAnchor negative test: get by null alias", null) { //$NON-NLS-1$
				public void runTest() {
					testGetTrustAnchor1();
				}
			}, new KeyStoreTrustEngineTest("getTrustAnchor negative test: does not exist", null) { //$NON-NLS-1$
				public void runTest() {
					testGetTrustAnchor2();
				}
			},
			/* getAliases tests */
			new KeyStoreTrustEngineTest("getAliases positive test: get the alias list", new String[] {"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 (int i = 0; i < s_tests.length; i++) {
			suite.addTest(s_tests[i]);
		}
		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 (int i = 0; i < aliases.length; i++) {
				testStore.setCertificateEntry(aliases[i], getTestCertificate(aliases[i]));
			}
		}
		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"); //$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 certs = new ArrayList(aliases.length);
		for (int i = 0; i < aliases.length; i++) {
			certs.add(getTestCertificate(aliases[i]));
		}
		return (Certificate[]) 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(new String[] {"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(new String[] {"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(new String[] {"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(new String[] {"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(new String[] {"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(new String[] {"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
}
