Repository: incubator-slider Updated Branches: refs/heads/develop 053c3c111 -> 00542b8f1 Updated Tags: refs/tags/tag_2014_11_01_pre-SLIDER-531-merge [created] 6ef24ade4
SLIDER-585 add API for keystore generation and some method renaming for clarity Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/4344600c Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/4344600c Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/4344600c Branch: refs/heads/develop Commit: 4344600c1b55b13c17980d7b1c6d08a6f6f99fdc Parents: bbd09a2 Author: Jon Maron <jma...@hortonworks.com> Authored: Tue Feb 3 11:29:11 2015 -0500 Committer: Jon Maron <jma...@hortonworks.com> Committed: Tue Feb 3 11:29:11 2015 -0500 ---------------------------------------------------------------------- .../providers/agent/AgentProviderService.java | 2 +- .../services/security/CertificateManager.java | 38 ++++++- .../server/services/security/SecurityUtils.java | 10 +- .../security/TestCertificateManager.java | 102 ++++++++++++++++++- 4 files changed, 133 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/4344600c/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java index 439b5b6..ad8ef43 100644 --- a/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java +++ b/slider-core/src/main/java/org/apache/slider/providers/agent/AgentProviderService.java @@ -463,7 +463,7 @@ public class AgentProviderService extends AbstractProviderService implements CertificateManager certMgr = new CertificateManager(); String hostname = container.getNodeId().getHost(); String containerId = container.getId().toString(); - certMgr.generateAgentCertificate(hostname, containerId); + certMgr.generateContainerCertificate(hostname, containerId); LocalResource agentCertResource = fileSystem.createAmResource( uploadSecurityResource( CertificateManager.getAgentCertficateFilePath(containerId), http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/4344600c/slider-core/src/main/java/org/apache/slider/server/services/security/CertificateManager.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/services/security/CertificateManager.java b/slider-core/src/main/java/org/apache/slider/server/services/security/CertificateManager.java index 812f39f..4473b74 100644 --- a/slider-core/src/main/java/org/apache/slider/server/services/security/CertificateManager.java +++ b/slider-core/src/main/java/org/apache/slider/server/services/security/CertificateManager.java @@ -71,7 +71,7 @@ public class CertificateManager { LOG.info("Certificate exists:" + certExists); if (!certExists) { - generateServerCertificate(); + generateAMKeystore(); } } @@ -178,11 +178,12 @@ public class CertificateManager { } - public synchronized void generateAgentCertificate(String agentHostname, String containerId) { - LOG.info("Generation of agent certificate for {}", agentHostname); + public synchronized void generateContainerCertificate(String hostname, + String containerId) { + LOG.info("Generation of agent certificate for {}", hostname); String srvrKstrDir = SecurityUtils.getSecurityDir(); - Object[] scriptArgs = {srvrKstrDir, agentHostname, containerId}; + Object[] scriptArgs = {srvrKstrDir, hostname, containerId}; try { String command = MessageFormat.format(GEN_AGENT_KEY, scriptArgs); @@ -195,7 +196,29 @@ public class CertificateManager { } } - private void generateServerCertificate() throws SliderException { + public synchronized void generateContainerKeystore(String hostname, + String containerId, + String keystorePass) + throws SliderException { + LOG.info("Generation of container keystore for container {} on {}", + containerId, hostname); + + generateContainerCertificate(hostname, containerId); + + // come up with correct args to invoke keystore command + String srvrKstrDir = SecurityUtils.getSecurityDir(); + String containerCrtName = containerId + ".crt"; + String containerKeyName = containerId + ".key"; + String kstrName = String.format("%s-%s.p12", hostname, containerId); + + Object[] scriptArgs = {keystorePass, srvrKstrDir, containerKeyName, + containerCrtName, kstrName}; + + String command = MessageFormat.format(EXPRT_KSTR, scriptArgs); + runCommand(command); + } + + private void generateAMKeystore() throws SliderException { LOG.info("Generation of server certificate"); String srvrKstrDir = SecurityUtils.getSecurityDir(); @@ -345,6 +368,11 @@ public class CertificateManager { String agentCrtReqName = containerId + ".csr"; String agentCrtName = containerId + ".crt"; + // server certificate must exist already + if (!(new File(srvrKstrDir, srvrCrtName).exists())) { + throw new SliderException("CA certificate not generated"); + } + Object[] scriptArgs = {srvrKstrDir, agentCrtReqName, agentCrtName, srvrCrtPass, srvrKeyName, srvrCrtName}; http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/4344600c/slider-core/src/main/java/org/apache/slider/server/services/security/SecurityUtils.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/services/security/SecurityUtils.java b/slider-core/src/main/java/org/apache/slider/server/services/security/SecurityUtils.java index d525058..107b56e 100644 --- a/slider-core/src/main/java/org/apache/slider/server/services/security/SecurityUtils.java +++ b/slider-core/src/main/java/org/apache/slider/server/services/security/SecurityUtils.java @@ -77,7 +77,7 @@ public class SecurityUtils { + "default_keyfile = privkey.pem\n" + "distinguished_name = req_distinguished_name\n" + "attributes = req_attributes\n" - + "x509_extensions = v3_ca# The extentions to add to the self signed cert\n" + + "x509_extensions = jdk7_ca# The extentions to add to the self signed cert\n" + "\n" + "string_mask = utf8only\n" + "\n" @@ -116,12 +116,6 @@ public class SecurityUtils { + "[ jdk7_ca ]\n" + "subjectKeyIdentifier = hash\n" + "authorityKeyIdentifier = keyid:always,issuer:always\n" - + "basicConstraints = CA:true\n" - + "[ v3_ca ]\n" - + "subjectKeyIdentifier=hash\n" - + "\n" - + "authorityKeyIdentifier=keyid:always,issuer:always\n" - + "\n" + "basicConstraints = CA:true"; private static final String PASS_TOKEN = "pass:"; @@ -189,7 +183,7 @@ public class SecurityUtils { return securityDir; } - public static void initializeSecurityParameters(MapOperations configMap) { + public static void initializeSecurityParameters(MapOperations configMap) { initializeSecurityParameters(configMap, false); } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/4344600c/slider-core/src/test/java/org/apache/slider/server/services/security/TestCertificateManager.java ---------------------------------------------------------------------- diff --git a/slider-core/src/test/java/org/apache/slider/server/services/security/TestCertificateManager.java b/slider-core/src/test/java/org/apache/slider/server/services/security/TestCertificateManager.java index 816a34b..39b6545 100644 --- a/slider-core/src/test/java/org/apache/slider/server/services/security/TestCertificateManager.java +++ b/slider-core/src/test/java/org/apache/slider/server/services/security/TestCertificateManager.java @@ -26,6 +26,14 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Enumeration; /** * @@ -34,10 +42,11 @@ public class TestCertificateManager { @Rule public TemporaryFolder workDir = new TemporaryFolder(); private File secDir; + private CertificateManager certMan; @Before public void setup() throws Exception { - CertificateManager certMan = new CertificateManager(); + certMan = new CertificateManager(); MapOperations compOperations = new MapOperations(); secDir = new File(workDir.getRoot(), SliderKeys.SECURITY_DIR); File keystoreFile = new File(secDir, SliderKeys.KEYSTORE_FILE_NAME); @@ -49,13 +58,96 @@ public class TestCertificateManager { @Test public void testServerCertificateGenerated() throws Exception { File serverCrt = new File(secDir, SliderKeys.CRT_FILE_NAME); - Assert.assertTrue("Server CRD does not exist:" + serverCrt,serverCrt.exists()); + Assert.assertTrue("Server CRD does not exist:" + serverCrt, + serverCrt.exists()); } @Test - public void testKeystoreGenerated() throws Exception { - File keystore = new File(secDir, SliderKeys.KEYSTORE_FILE_NAME); - Assert.assertTrue("Keystore does not exist: " + keystore, keystore.exists()); + public void testAMKeystoreGenerated() throws Exception { + File keystoreFile = new File(secDir, SliderKeys.KEYSTORE_FILE_NAME); + Assert.assertTrue("Keystore does not exist: " + keystoreFile, + keystoreFile.exists()); + InputStream is = null; + try { + + is = new FileInputStream(keystoreFile); + KeyStore keystore = KeyStore.getInstance("pkcs12"); + String password = SecurityUtils.getKeystorePass(); + keystore.load(is, password.toCharArray()); + + Certificate certificate = keystore.getCertificate("1"); + Assert.assertNotNull(certificate); + + if (certificate instanceof X509Certificate) { + X509Certificate x509cert = (X509Certificate) certificate; + + // Get subject + Principal principal = x509cert.getSubjectDN(); + String subjectDn = principal.getName(); + Assert.assertEquals("wrong DN", + "O=Default Company Ltd, L=Default City, ST=Default Province, C=XX", + subjectDn); + + // Get issuer + principal = x509cert.getIssuerDN(); + String issuerDn = principal.getName(); + Assert.assertEquals("wrong Issuer DN", + "O=Default Company Ltd, L=Default City, ST=Default Province, C=XX", + issuerDn); + } + } finally { + if(null != is) { + is.close(); + } + } + } + + @Test + public void testContainerCertificateGeneration() throws Exception { + certMan.generateContainerCertificate("localhost", "container1"); + Assert.assertTrue("container certificate not generated", + new File(secDir, "container1.crt").exists()); + } + + @Test + public void testContainerKeystoreGeneration() throws Exception { + certMan.generateContainerKeystore("localhost", "container1", "password"); + File keystoreFile = new File(secDir, "localhost-container1.p12"); + Assert.assertTrue("container keystore not generated", + keystoreFile.exists()); + + InputStream is = null; + try { + + is = new FileInputStream(keystoreFile); + KeyStore keystore = KeyStore.getInstance("pkcs12"); + String password = "password"; + keystore.load(is, password.toCharArray()); + + Certificate certificate = keystore.getCertificate("1"); + Assert.assertNotNull(certificate); + + if (certificate instanceof X509Certificate) { + X509Certificate x509cert = (X509Certificate) certificate; + + // Get subject + Principal principal = x509cert.getSubjectDN(); + String subjectDn = principal.getName(); + Assert.assertEquals("wrong DN", "CN=container1, OU=localhost", + subjectDn); + + // Get issuer + principal = x509cert.getIssuerDN(); + String issuerDn = principal.getName(); + Assert.assertEquals("wrong Issuer DN", + "O=Default Company Ltd, L=Default City, ST=Default Province, C=XX", + issuerDn); + } + } finally { + if(null != is) { + is.close(); + } + } } }