/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.security.certificate.generator; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.util.Properties; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; @RunWith(value = MockitoJUnitRunner.class) public class KeyStoreFileTest { public static final String BOGUS_FILENAME = "not_keystore.jks"; public static final String KEYSTORE_TEMPLATE = "keystore-password_changeit.jks"; public static final String KEYSTORE_COPY = "workingCopy.jks"; public static final String ALIAS_DEMO_CA = "demorootca"; public static final char[] PASSWORD = "changeit".toCharArray(); public static final char[] BOGUS_PASSWORD = "ThisIsNotThePassword".toCharArray(); public static final String ALIAS_SAMPLE_PRIVATE_KEY_ENTRY = "sampleprivatekeyentry"; private static Properties properties; @BeforeClass public static void init() { properties = System.getProperties(); System.setProperty("javax.net.ssl.keyStoreType", "JKS"); } @AfterClass public static void tearDown() { System.setProperties(properties); } String getPathTo(String path) { URL resourcePath = getClass().getClassLoader() .getResource(path); if (resourcePath == null) { fail("Could not retrieve resource. Check the resources folder."); } return new File(resourcePath.getPath()).getPath(); } @Before public void setUp() throws IOException { refreshKeyStoreFile(); } //Test constructor. Null path to keyStore file. @Test(expected = IllegalArgumentException.class) public void constructorNullPath() throws Exception { KeyStoreFile.openFile(null, null); } //Test constructor. Invalid path to keyStore file. @Test(expected = CertificateGeneratorException.class) public void constructorInvalidPath() throws Exception { KeyStoreFile.openFile("", null); } //Test Constructor. Path is a directory, not a file. @Test(expected = CertificateGeneratorException.class) public void constructorPathIsDirectory() throws Exception { String anyDirectory = getPathTo(""); KeyStoreFile.openFile(anyDirectory, null); } //Test Constructor. File is not keyStore. @Test(expected = CertificateGeneratorException.class) public void constructorFileNotKeyStore() throws Exception { KeyStoreFile.openFile(getPathTo(BOGUS_FILENAME), null); } //Test Constructor. Password is null. @Test(expected = CertificateGeneratorException.class) public void constructorNullPassword() throws Exception { KeyStoreFile.openFile(getPathTo(KEYSTORE_COPY), null); } //Test Constructor. Password is wrong. @Test(expected = CertificateGeneratorException.class) public void constructorWrongPassword() throws Exception { KeyStoreFile.openFile(getPathTo(KEYSTORE_COPY), BOGUS_PASSWORD); } //Test Constructor. Valid file, valid password. @Test public void testConstructor() { KeyStoreFile keyStore = KeyStoreFile.openFile(getPathTo(KEYSTORE_COPY), PASSWORD); assertNotNull(keyStore.aliases()); assertThat("Missing key in keystore test file resource", keyStore.aliases(), hasItem(ALIAS_DEMO_CA)); } Path refreshKeyStoreFile() throws IOException { String stringToKeystoreTemplate = getPathTo(KEYSTORE_TEMPLATE); String stringToKeystoreCopy = getPathTo(KEYSTORE_COPY); Path pathToKeystoreTemplate = Paths.get(stringToKeystoreTemplate); Path pathToKeystoreCopy = Paths.get(stringToKeystoreCopy); return Files.copy(pathToKeystoreTemplate, pathToKeystoreCopy, REPLACE_EXISTING); } @Test public void addAndRemoveEntry() throws IOException, GeneralSecurityException { KeyStoreFile ksFile = KeyStoreFile.openFile(getPathTo(KEYSTORE_COPY), PASSWORD); //Get a cert from the keystore KeyStore.TrustedCertificateEntry demoCa = (KeyStore.TrustedCertificateEntry) ksFile.getEntry(ALIAS_DEMO_CA); assertThat("Could not retrieve Demo CA from keystore", demoCa, instanceOf(KeyStore.TrustedCertificateEntry.class)); assertThat(ksFile.isKey(ALIAS_DEMO_CA), is(false)); //Delete a cert from the file ksFile.deleteEntry(ALIAS_DEMO_CA); assertThat("Could not delete key from keystore", ksFile.aliases(), not(hasItem(ALIAS_DEMO_CA))); //Add a new entry to the file KeyStore.Entry pkEntry = ksFile.getEntry(ALIAS_SAMPLE_PRIVATE_KEY_ENTRY); assertThat("Could not find sample private key in keystore", ksFile.aliases(), hasItem(ALIAS_SAMPLE_PRIVATE_KEY_ENTRY)); String alias = "temp"; ksFile.setEntry(alias, pkEntry); assertThat("Did not add key to file as expected", ksFile.aliases(), hasItem(alias)); assertThat(ksFile.isKey(alias), is(true)); //Save and reload file ksFile.save(); ksFile = KeyStoreFile.openFile(getPathTo(KEYSTORE_COPY), PASSWORD); assertThat("Keystore file did not save the new key", ksFile.aliases(), hasItem(alias)); } }