downloadFromApache(MavenObject.WICKET_GOOGLE_CHARTS, BuildType.RUNTIME);\r
downloadFromApache(MavenObject.MARKDOWNPAPERS, BuildType.RUNTIME);\r
downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.RUNTIME);\r
+ downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.RUNTIME);\r
\r
downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);\r
downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.RUNTIME);\r
downloadFromApache(MavenObject.WICKET_GOOGLE_CHARTS, BuildType.COMPILETIME);\r
downloadFromApache(MavenObject.MARKDOWNPAPERS, BuildType.COMPILETIME);\r
downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.COMPILETIME);\r
+ downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.COMPILETIME);\r
\r
downloadFromEclipse(MavenObject.JGIT, BuildType.COMPILETIME);\r
downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.COMPILETIME);\r
public static final MavenObject MARKDOWNPAPERS = new MavenObject("MarkdownPapers", "org/tautua/markdownpapers", "markdownpapers-core", "1.0.0", 87000, 58000, 278000, "feda63bd149f3315da210e397d45d02277038ad5", "a9a6c4d163af81e265a15138fcaeafa9829c6054", "f932656266a7f9593488d3f89e815d0af44d0853");\r
\r
public static final MavenObject BOUNCYCASTLE = new MavenObject("BouncyCastle", "org/bouncycastle", "bcprov-jdk16", "1.46", 1900000, 1400000, 4670000, "ce091790943599535cbb4de8ede84535b0c1260c", "d2b70567594225923450d7e3f80cd022c852725e", "873a6fe765f33fc27df498a5d1f5bf077e503b2f");\r
+ \r
+ public static final MavenObject BOUNCYCASTLE_MAIL = new MavenObject("BouncyCastle Mail", "org/bouncycastle", "bcmail-jdk16", "1.46", 502000, 420000, 482000, "08a9233bfd6ad38ea32df5e6ff91035b650584b9", "3ebd62bc56854767512dc5deec0a17795f2e671d", "3b7c5f3938f202311bdca0bf7ed46bc0118af081");\r
\r
public static final MavenObject JGIT = new MavenObject("JGit", "org/eclipse/jgit", "org.eclipse.jgit", "0.12.1", 1318000, 1354000, 2993000, "fd77699699b9651d2fc31c7ed63af98b14fc1975", "c8b3d84922c7802cfe6a661e13a002641a78583d", "5609aa3ce3ac3d52030befd27ddd2941f6c07570");\r
\r
\r
import java.io.BufferedReader;\r
import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
import java.io.IOException;\r
import java.io.InputStreamReader;\r
import java.io.OutputStream;\r
+import java.math.BigInteger;\r
import java.net.InetAddress;\r
import java.net.ServerSocket;\r
import java.net.Socket;\r
import java.net.URL;\r
import java.net.UnknownHostException;\r
+import java.security.KeyPair;\r
+import java.security.KeyPairGenerator;\r
+import java.security.KeyStore;\r
import java.security.ProtectionDomain;\r
+import java.security.SecureRandom;\r
+import java.security.Security;\r
+import java.security.cert.X509Certificate;\r
import java.text.MessageFormat;\r
import java.util.ArrayList;\r
+import java.util.Date;\r
import java.util.List;\r
\r
import org.apache.log4j.ConsoleAppender;\r
import org.apache.log4j.PatternLayout;\r
import org.apache.wicket.protocol.http.ContextParamWebApplicationFactory;\r
import org.apache.wicket.protocol.http.WicketFilter;\r
+import org.bouncycastle.asn1.x500.X500NameBuilder;\r
+import org.bouncycastle.asn1.x500.style.BCStyle;\r
+import org.bouncycastle.cert.X509v3CertificateBuilder;\r
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;\r
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;\r
+import org.bouncycastle.operator.ContentSigner;\r
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;\r
import org.eclipse.jetty.http.security.Constraint;\r
import org.eclipse.jetty.security.ConstraintMapping;\r
import org.eclipse.jetty.security.ConstraintSecurityHandler;\r
Connector httpConnector = createConnector(params.useNIO, params.port);\r
String bindInterface = fileSettings.getString(Keys.server.httpBindInterface, null);\r
if (!StringUtils.isEmpty(bindInterface)) {\r
- logger.warn(MessageFormat.format("Binding port {0} to {1}", params.port, bindInterface));\r
+ logger.warn(MessageFormat.format("Binding connector on port {0} to {1}", params.port, bindInterface));\r
httpConnector.setHost(bindInterface);\r
}\r
connectors.add(httpConnector);\r
}\r
\r
if (params.securePort > 0) {\r
- if (new File("keystore").exists()) {\r
- Connector secureConnector = createSSLConnector(params.useNIO, params.securePort, params.storePassword);\r
+ File keystore = new File("keystore");\r
+ if (!keystore.exists()) {\r
+ logger.info("Generating self-signed ssl certificate");\r
+ generateSelfSignedCertificate("localhost", keystore, params.storePassword);\r
+ }\r
+ if (keystore.exists()) {\r
+ Connector secureConnector = createSSLConnector(keystore, params.storePassword, params.useNIO, params.securePort);\r
String bindInterface = fileSettings.getString(Keys.server.httpsBindInterface, null);\r
if (!StringUtils.isEmpty(bindInterface)) {\r
- logger.warn(MessageFormat.format("Binding port {0} to {1}", params.port, bindInterface));\r
+ logger.warn(MessageFormat.format("Binding ssl connector on port {0} to {1}", params.securePort, bindInterface));\r
secureConnector.setHost(bindInterface);\r
}\r
connectors.add(secureConnector);\r
} else {\r
- logger.warn("Failed to find Keystore? Did you run \"makekeystore\"?");\r
+ logger.warn("Failed to find or load Keystore?");\r
logger.warn("SSL connector DISABLED.");\r
}\r
}\r
return connector;\r
}\r
\r
- private static Connector createSSLConnector(boolean useNIO, int port, String password) {\r
+ private static Connector createSSLConnector(File keystore, String password, boolean useNIO, int port) {\r
SslConnector connector;\r
if (useNIO) {\r
logger.info("Setting up NIO SslSelectChannelConnector on port " + port);\r
SslSelectChannelConnector ssl = new SslSelectChannelConnector();\r
ssl.setSoLingerTime(-1);\r
- ssl.setThreadPool(new QueuedThreadPool(20));\r
+ ssl.setThreadPool(new QueuedThreadPool(20)); \r
connector = ssl;\r
} else {\r
logger.info("Setting up NIO SslSocketConnector on port " + port);\r
SslSocketConnector ssl = new SslSocketConnector();\r
connector = ssl;\r
}\r
- connector.setKeystore("keystore");\r
+ connector.setAllowRenegotiate(true);\r
+ connector.setKeystore(keystore.getAbsolutePath());\r
connector.setPassword(password);\r
connector.setPort(port);\r
connector.setMaxIdleTime(30000);\r
return connector;\r
}\r
+ \r
+ private static void generateSelfSignedCertificate(String hostname, File keystore, String keystorePassword) {\r
+ try {\r
+ Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());\r
+\r
+ final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;\r
+ \r
+ KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");\r
+ kpGen.initialize(1024, new SecureRandom());\r
+ KeyPair pair = kpGen.generateKeyPair();\r
+\r
+ // Generate self-signed certificate\r
+ X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);\r
+ builder.addRDN(BCStyle.OU, Constants.NAME);\r
+ builder.addRDN(BCStyle.O, Constants.NAME);\r
+ builder.addRDN(BCStyle.CN, hostname);\r
+\r
+ Date notBefore = new Date(System.currentTimeMillis() - 1*24*60*60*1000l);\r
+ Date notAfter = new Date(System.currentTimeMillis() + 10*365*24*60*60*1000l);\r
+ BigInteger serial = BigInteger.valueOf(System.currentTimeMillis());\r
+\r
+ X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(builder.build(), serial, notBefore, notAfter, builder.build(), pair.getPublic());\r
+ ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption").setProvider(BC).build(pair.getPrivate());\r
+ X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certGen.build(sigGen));\r
+ cert.checkValidity(new Date());\r
+ cert.verify(cert.getPublicKey());\r
+\r
+ // Save to keystore \r
+ KeyStore store = KeyStore.getInstance("JKS");\r
+ if (keystore.exists()) {\r
+ FileInputStream fis = new FileInputStream(keystore);\r
+ store.load(fis, keystorePassword.toCharArray());\r
+ } else {\r
+ store.load(null);\r
+ }\r
+ store.setKeyEntry(hostname, pair.getPrivate(), keystorePassword.toCharArray(), new java.security.cert.Certificate[] { cert });\r
+ store.store(new FileOutputStream(keystore), keystorePassword.toCharArray());\r
+ } catch (Throwable t) {\r
+ t.printStackTrace();\r
+ throw new RuntimeException("Failed to generate self-signed certificate!", t);\r
+ }\r
+ }\r
\r
/**\r
* Recursively delete a folder and its contents.\r