From: Mathieu Baudier Date: Thu, 9 Feb 2017 09:19:15 +0000 (+0100) Subject: Improve SSL X-Git-Tag: argeo-commons-2.1.60~13 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=dfd5f2b82a7ab5e8333cb3fcaf6f9a8655a50355 Improve SSL --- diff --git a/demo/argeo_node_rap.properties b/demo/argeo_node_rap.properties index 1bd514624..54b4735e5 100644 --- a/demo/argeo_node_rap.properties +++ b/demo/argeo_node_rap.properties @@ -41,7 +41,7 @@ org.osgi.service.http.port=7070 #org.eclipse.equinox.http.jetty.log.stderr.threshold=info # HTTPS -#org.osgi.service.http.port.secure=7073 +org.osgi.service.http.port.secure=7073 #org.eclipse.equinox.http.jetty.https.enabled=true #org.eclipse.equinox.http.jetty.ssl.keystore=../../ssl/server.jks #org.eclipse.equinox.http.jetty.ssl.keystore=data/node.p12 diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsSecurity.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsSecurity.java index 7e1834a44..168b199ba 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsSecurity.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsSecurity.java @@ -1,6 +1,5 @@ package org.argeo.cms.internal.kernel; -import java.io.File; import java.io.IOException; import java.net.Inet6Address; import java.net.InetAddress; @@ -61,7 +60,6 @@ class CmsSecurity implements KernelConstants { private GSSCredential acceptorCredentials; private Path nodeKeyTab = KernelUtils.getOsgiInstancePath("node/krb5.keytab"); - private File keyStoreFile; public CmsSecurity() { if (!DeployConfig.isInitialized()) // first init @@ -246,10 +244,6 @@ class CmsSecurity implements KernelConstants { // Security.removeProvider(SECURITY_PROVIDER); } - File getNodeKeyStore() { - return keyStoreFile; - } - public synchronized int getSecurityLevel() { return securityLevel; } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/FirstInit.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/FirstInit.java index aa9cf7fe8..a8ef66a90 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/FirstInit.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/FirstInit.java @@ -5,12 +5,19 @@ import static org.argeo.cms.internal.kernel.KernelUtils.getFrameworkProp; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.net.InetAddress; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyStore; import java.util.ArrayList; +import java.util.Arrays; import java.util.Dictionary; import java.util.Hashtable; import java.util.List; +import javax.security.auth.x500.X500Principal; + import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -48,7 +55,8 @@ class FirstInit { String httpPort = getFrameworkProp("org.osgi.service.http.port"); String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure"); /// TODO make it more generic - String httpHost = getFrameworkProp("org.eclipse.equinox.http.jetty.http.host"); + String httpHost = getFrameworkProp(JettyConstants.PROPERTY_PREFIX + '.' + JettyConstants.HTTP_HOST); + String httpsHost = getFrameworkProp(JettyConstants.PROPERTY_PREFIX + '.' + JettyConstants.HTTPS_HOST); final Hashtable props = new Hashtable(); // try { @@ -60,16 +68,23 @@ class FirstInit { if (httpsPort != null) { props.put(JettyConstants.HTTPS_PORT, httpsPort); props.put(JettyConstants.HTTPS_ENABLED, true); + Path keyStorePath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_KEYSTORE_PATH); + String keyStorePassword = getFrameworkProp( + JettyConstants.PROPERTY_PREFIX + '.' + JettyConstants.SSL_PASSWORD); + if (keyStorePassword == null) + keyStorePassword = "changeit"; + if (!Files.exists(keyStorePath)) + createSelfSignedKeyStore(keyStorePath); props.put(JettyConstants.SSL_KEYSTORETYPE, "PKCS12"); - props.put(JettyConstants.SSL_KEYSTORE, "../../ssl/server.p12"); - // jettyProps.put(JettyConstants.SSL_KEYSTORE, - // nodeSecurity.getHttpServerKeyStore().getCanonicalPath()); - props.put(JettyConstants.SSL_PASSWORD, "changeit"); + props.put(JettyConstants.SSL_KEYSTORE, keyStorePath.toString()); + props.put(JettyConstants.SSL_PASSWORD, keyStorePassword); props.put(JettyConstants.SSL_WANTCLIENTAUTH, true); } - if (httpHost != null) { + if (httpHost != null) props.put(JettyConstants.HTTP_HOST, httpHost); - } + if (httpsHost != null) + props.put(JettyConstants.HTTPS_HOST, httpHost); + props.put(NodeConstants.CN, NodeConstants.DEFAULT); } return props; @@ -185,4 +200,30 @@ class FirstInit { } } + private void createSelfSignedKeyStore(Path keyStorePath) { + // for (Provider provider : Security.getProviders()) + // System.out.println(provider.getName()); + File keyStoreFile = keyStorePath.toFile(); + char[] ksPwd = "changeit".toCharArray(); + char[] keyPwd = Arrays.copyOf(ksPwd, ksPwd.length); + if (!keyStoreFile.exists()) { + try { + keyStoreFile.getParentFile().mkdirs(); + KeyStore keyStore = PkiUtils.getKeyStore(keyStoreFile, ksPwd); + PkiUtils.generateSelfSignedCertificate(keyStore, + new X500Principal("CN=" + InetAddress.getLocalHost().getHostName() + ",OU=UNSECURE,O=UNSECURE"), + 1024, keyPwd); + PkiUtils.saveKeyStore(keyStoreFile, ksPwd, keyStore); + if (log.isDebugEnabled()) + log.debug("Created self-signed unsecure keystore " + keyStoreFile); + } catch (Exception e) { + if (keyStoreFile.length() == 0) + keyStoreFile.delete(); + log.error("Cannot create keystore " + keyStoreFile, e); + } + } else { + throw new CmsException("Keystore " + keyStorePath + " already exists"); + } + } + } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java index 12c17833d..cbe46b453 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java @@ -9,11 +9,12 @@ public interface KernelConstants { String DIR_NODE = "node"; String DIR_REPOS = "repos"; String DIR_TRANSACTIONS = "transactions"; - String DIR_PKI = "pki"; - String DIR_PKI_PRIVATE = DIR_PKI + "/private"; + // String DIR_PKI = "pki"; + // String DIR_PKI_PRIVATE = DIR_PKI + "/private"; // Files - String DEPLOY_CONFIG_PATH = KernelConstants.DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif"; + String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif"; + String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".p12"; // Security // String DEFAULT_SECURITY_KEY = "argeo"; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/PkiUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/PkiUtils.java index 050b7d4d7..031515caa 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/PkiUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/PkiUtils.java @@ -41,7 +41,7 @@ class PkiUtils { kpGen.initialize(keySize, new SecureRandom()); KeyPair pair = kpGen.generateKeyPair(); Date notBefore = new Date(System.currentTimeMillis() - 10000); - Date notAfter = new Date(System.currentTimeMillis() + 24L * 3600 * 1000); + Date notAfter = new Date(System.currentTimeMillis() + 365 * 24L * 3600 * 1000); BigInteger serial = BigInteger.valueOf(System.currentTimeMillis()); X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(x500Principal, serial, notBefore, notAfter, x500Principal, pair.getPublic()); @@ -92,67 +92,71 @@ class PkiUtils { long begin = System.currentTimeMillis(); for (int i = 512; i < 1024; i = i + 2) { try { - KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM,provider); + KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM, provider); keyGen.initialize(i, secureRandom); keyGen.generateKeyPair(); } catch (Exception e) { System.err.println(i + " : " + e.getMessage()); } } - System.out.println( (System.currentTimeMillis() - begin) + " ms"); + System.out.println((System.currentTimeMillis() - begin) + " ms"); -// // String text = "a"; -// String text = "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest"; -// try { -// System.out.println(text); -// PrivateKey privateKey; -// PublicKey publicKey; -// char[] password = "changeit".toCharArray(); -// String alias = "CN=test"; -// KeyStore keyStore = KeyStore.getInstance("pkcs12"); -// File p12file = new File("test.p12"); -// p12file.delete(); -// if (!p12file.exists()) { -// keyStore.load(null); -// generateSelfSignedCertificate(keyStore, new X500Principal(alias), 513, password); -// try (OutputStream out = new FileOutputStream(p12file)) { -// keyStore.store(out, password); -// } -// } -// try (InputStream in = new FileInputStream(p12file)) { -// keyStore.load(in, password); -// privateKey = (PrivateKey) keyStore.getKey(alias, password); -// publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey(); -// } -// // KeyPair key; -// // final KeyPairGenerator keyGen = -// // KeyPairGenerator.getInstance(ALGORITHM); -// // keyGen.initialize(4096, new SecureRandom()); -// // long begin = System.currentTimeMillis(); -// // key = keyGen.generateKeyPair(); -// // System.out.println((System.currentTimeMillis() - begin) + " ms"); -// // keyStore.load(null); -// // keyStore.setKeyEntry("test", key.getPrivate(), password, null); -// // try(OutputStream out=new FileOutputStream(p12file)) { -// // keyStore.store(out, password); -// // } -// // privateKey = key.getPrivate(); -// // publicKey = key.getPublic(); -// -// Cipher encrypt = Cipher.getInstance(ALGORITHM); -// encrypt.init(Cipher.ENCRYPT_MODE, publicKey); -// byte[] encrypted = encrypt.doFinal(text.getBytes()); -// String encryptedBase64 = Base64.getEncoder().encodeToString(encrypted); -// System.out.println(encryptedBase64); -// byte[] encryptedFromBase64 = Base64.getDecoder().decode(encryptedBase64); -// -// Cipher decrypt = Cipher.getInstance(ALGORITHM); -// decrypt.init(Cipher.DECRYPT_MODE, privateKey); -// byte[] decrypted = decrypt.doFinal(encryptedFromBase64); -// System.out.println(new String(decrypted)); -// } catch (Exception e) { -// e.printStackTrace(); -// } + // // String text = "a"; + // String text = + // "testtesttesttesttesttesttesttesttesttesttesttesttesttesttest"; + // try { + // System.out.println(text); + // PrivateKey privateKey; + // PublicKey publicKey; + // char[] password = "changeit".toCharArray(); + // String alias = "CN=test"; + // KeyStore keyStore = KeyStore.getInstance("pkcs12"); + // File p12file = new File("test.p12"); + // p12file.delete(); + // if (!p12file.exists()) { + // keyStore.load(null); + // generateSelfSignedCertificate(keyStore, new X500Principal(alias), + // 513, password); + // try (OutputStream out = new FileOutputStream(p12file)) { + // keyStore.store(out, password); + // } + // } + // try (InputStream in = new FileInputStream(p12file)) { + // keyStore.load(in, password); + // privateKey = (PrivateKey) keyStore.getKey(alias, password); + // publicKey = keyStore.getCertificateChain(alias)[0].getPublicKey(); + // } + // // KeyPair key; + // // final KeyPairGenerator keyGen = + // // KeyPairGenerator.getInstance(ALGORITHM); + // // keyGen.initialize(4096, new SecureRandom()); + // // long begin = System.currentTimeMillis(); + // // key = keyGen.generateKeyPair(); + // // System.out.println((System.currentTimeMillis() - begin) + " ms"); + // // keyStore.load(null); + // // keyStore.setKeyEntry("test", key.getPrivate(), password, null); + // // try(OutputStream out=new FileOutputStream(p12file)) { + // // keyStore.store(out, password); + // // } + // // privateKey = key.getPrivate(); + // // publicKey = key.getPublic(); + // + // Cipher encrypt = Cipher.getInstance(ALGORITHM); + // encrypt.init(Cipher.ENCRYPT_MODE, publicKey); + // byte[] encrypted = encrypt.doFinal(text.getBytes()); + // String encryptedBase64 = + // Base64.getEncoder().encodeToString(encrypted); + // System.out.println(encryptedBase64); + // byte[] encryptedFromBase64 = + // Base64.getDecoder().decode(encryptedBase64); + // + // Cipher decrypt = Cipher.getInstance(ALGORITHM); + // decrypt.init(Cipher.DECRYPT_MODE, privateKey); + // byte[] decrypted = decrypt.doFinal(encryptedFromBase64); + // System.out.println(new String(decrypted)); + // } catch (Exception e) { + // e.printStackTrace(); + // } }