package org.jolokia.jvmagent.security;/* * * Copyright 2015 Roland Huss * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.*; import java.security.*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.util.Enumeration; import org.jolokia.Version; import org.testng.annotations.Test; import static org.testng.Assert.*; /** * @author roland * @since 01/10/15 */ public class KeyStoreUtilTest { public static final String CA_CERT_SUBJECT_DN_CN = "CN=ca.test.jolokia.org"; public static final String SERVER_CERT_SUBJECT_DN = "CN=Server Cert signed and with extended key usage server, C=DE, ST=Franconia, L=Pegnitz, OU=Test, O=jolokia.org"; public static final String CA_ALIAS = "cn=ca.test.jolokia.org,c=de,st=bavaria,l=pegnitz,1.2.840.113549.1.9.1=#1612726f6c616e64406a6f6c6f6b69612e6f7267,ou=dev,o=jolokia"; public static final String SERVER_ALIAS = "cn=server cert signed and with extended key usage server,c=de,st=franconia,l=pegnitz,ou=test,o=jolokia.org"; @Test public void testTrustStore() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { File caPem = getTempFile("ca/cert.pem"); KeyStore keystore = createKeyStore(); KeyStoreUtil.updateWithCaPem(keystore, caPem); Enumeration<String> aliases = keystore.aliases(); String alias = aliases.nextElement(); assertFalse(aliases.hasMoreElements()); assertTrue(alias.contains("ca.test.jolokia.org")); X509Certificate cert = (X509Certificate) keystore.getCertificate(alias); cert.checkValidity(); assertTrue(cert.getSubjectDN().getName().contains(CA_CERT_SUBJECT_DN_CN)); RSAPublicKey key = (RSAPublicKey) cert.getPublicKey(); assertEquals(key.getAlgorithm(),"RSA"); } @Test public void testKeyStore() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, InvalidKeySpecException, UnrecoverableKeyException { File serverPem = getTempFile("server/cert.pem"); File keyPem = getTempFile("server/key.pem"); KeyStore keystore = createKeyStore(); KeyStoreUtil.updateWithServerPems(keystore, serverPem, keyPem, "RSA", new char[0]); Enumeration<String> aliases = keystore.aliases(); String alias = aliases.nextElement(); assertFalse(aliases.hasMoreElements()); assertTrue(alias.contains("server")); X509Certificate cert = (X509Certificate) keystore.getCertificate(alias); cert.checkValidity(); assertEquals(cert.getSubjectDN().getName(), SERVER_CERT_SUBJECT_DN); RSAPrivateCrtKey key = (RSAPrivateCrtKey) keystore.getKey(alias, new char[0]); assertEquals("RSA",key.getAlgorithm()); RSAPublicKey pubKey = (RSAPublicKey) cert.getPublicKey(); assertEquals("RSA",pubKey.getAlgorithm()); } @Test public void testBoth() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, InvalidKeySpecException, InvalidKeyException, NoSuchProviderException, SignatureException { File caPem = getTempFile("ca/cert.pem"); File serverPem = getTempFile("server/cert.pem"); File keyPem = getTempFile("server/key.pem"); KeyStore keystore = createKeyStore(); KeyStoreUtil.updateWithCaPem(keystore, caPem); KeyStoreUtil.updateWithServerPems(keystore, serverPem, keyPem, "RSA", new char[0]); X509Certificate caCert = (X509Certificate) keystore.getCertificate(CA_ALIAS); X509Certificate serverCert = (X509Certificate) keystore.getCertificate(SERVER_ALIAS); // Check that server cert is signed by ca serverCert.verify(caCert.getPublicKey()); } @Test public void testInvalid() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, InvalidKeySpecException { for (String file : new String[]{"invalid/base64.pem", "invalid/begin.pem", "invalid/end.pem"}) { File invalidPem = getTempFile(file); KeyStore keystore = createKeyStore(); try { KeyStoreUtil.updateWithCaPem(keystore, invalidPem); fail(); } catch (Exception exp) { } try { KeyStoreUtil.updateWithServerPems(keystore, getTempFile("server/cert.pem"), invalidPem, "RSA", new char[0]); fail(); } catch (Exception exp) { } } } @Test public void testSelfSignedCertificate() throws Exception { KeyStore keystore = createKeyStore(); KeyStoreUtil.updateWithSelfSignedServerCertificate(keystore); X509Certificate cert = (X509Certificate) keystore.getCertificate("jolokia-agent"); assertNotNull(cert); assertEquals(cert.getSubjectDN().getName(), "CN=Jolokia Agent " + Version.getAgentVersion() + ", OU=JVM, O=jolokia.org, L=Pegnitz, ST=Franconia, C=DE"); assertEquals(cert.getSubjectDN(), cert.getIssuerDN()); } // ======================================================== private KeyStore createKeyStore() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(null); return keystore; } private File getTempFile(String path) throws IOException { InputStream is = this.getClass().getResourceAsStream("/certs/" + path); File dest = File.createTempFile("cert-", "pem"); LineNumberReader reader = new LineNumberReader(new InputStreamReader(is)); FileWriter writer = new FileWriter(dest); try { String line; while ((line = reader.readLine()) != null) { writer.write(line + "\n"); } return dest; } finally { writer.close(); reader.close(); } } }