Skip to content
Permalink
Browse files
Merge pull request #29 from jglick/self-signed-JENKINS-25333
[JENKINS-25333] Avoid hard dependency on non-Java-Platform APIs
  • Loading branch information
jglick committed Dec 19, 2016
2 parents 79bc5ac + 82deda0 commit 14b69f14db22af3b4f5b1078eb63290a98082eae
Showing with 106 additions and 25 deletions.
  1. +1 −0 .gitignore
  2. +1 −1 Jenkinsfile
  3. +57 −5 pom.xml
  4. +37 −18 src/java/winstone/HttpsConnectorFactory.java
  5. +10 −1 src/java/winstone/LocalStrings.properties
@@ -5,3 +5,4 @@ target
.classpath
.project
.settings
dependency-reduced-pom.xml
@@ -22,7 +22,7 @@ for (int i = 0; i < platforms.size(); ++i) {

stage('Build') {
withEnv([
"JAVA_HOME=${tool 'jdk7'}",
"JAVA_HOME=${tool 'jdk8'}",
"PATH+MVN=${tool 'mvn'}/bin",
'PATH+JDK=$JAVA_HOME/bin',
]) {
62 pom.xml
@@ -47,8 +47,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
<source>1.${java.level}</source>
<target>1.${java.level}</target>
</configuration>
</plugin>
<plugin>
@@ -79,6 +79,7 @@

<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/*Test.java</include>
@@ -92,6 +93,7 @@

<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
@@ -115,7 +117,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.1</version>
<version>1.4.1</version>
<executions>
<execution>
<goals>
@@ -124,12 +126,45 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[1.7,)</version>
<version>[1.${java.level},)</version>
</requireJavaVersion>
<enforceBytecodeVersion>
<maxJdkVersion>1.${java.level}</maxJdkVersion>
<ignoredScopes>
<ignoredScope>test</ignoredScope>
</ignoredScopes>
</enforceBytecodeVersion>
</rules>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.0-beta-6</version>
</dependency>
</dependencies>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.15</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<id>check</id>
</execution>
</executions>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java1${java.level}</artifactId>
</signature>
</configuration>
</plugin>

<plugin>
@@ -190,6 +225,23 @@
<tag>HEAD</tag>
</scm>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java17</artifactId>
<version>1.0</version>
<type>signature</type>
</dependency>
<dependency>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java18</artifactId>
<version>1.0</version>
<type>signature</type>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>commons-io</groupId>
@@ -248,6 +300,6 @@

<properties>
<jetty.version>9.2.15.v20160210</jetty.version>
<java.level>7</java.level>
</properties>
</project>

@@ -13,10 +13,6 @@
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.B64Code;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
import sun.security.x509.CertAndKeyGen;
import sun.security.x509.X500Name;
import winstone.cmdline.Option;

import javax.net.ssl.KeyManagerFactory;
@@ -27,6 +23,7 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
@@ -39,6 +36,7 @@
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Map;
import java.util.logging.Level;

/**
* Implements the main listener daemon thread. This is the class that gets
@@ -98,12 +96,27 @@ public boolean start(Map args, Server server) throws IOException {
this.keystorePassword = "changeit";
System.out.println("Using one-time self-signed certificate");

CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
ckg.generate(1024);
PrivateKey privKey = ckg.getPrivateKey();
X509Certificate cert;
PrivateKey privKey;
Object ckg;

X500Name xn = new X500Name("Test site", "Unknown", "Unknown", "Unknown");
X509Certificate cert = ckg.getSelfCertificate(xn, 3650L * 24 * 60 * 60);
try { // TODO switch to (shaded?) Bouncy Castle
// TODO: Cleanup when JDK 7 support is removed.
try {
ckg = Class.forName("sun.security.x509.CertAndKeyGen").getDeclaredConstructor(String.class, String.class, String.class).newInstance("RSA", "SHA1WithRSA", null);
} catch (ClassNotFoundException cnfe) {
// Java 8
ckg = Class.forName("sun.security.tools.keytool.CertAndKeyGen").getDeclaredConstructor(String.class, String.class, String.class).newInstance("RSA", "SHA1WithRSA", null);
}
ckg.getClass().getDeclaredMethod("generate", int.class).invoke(ckg, 1024);
privKey = (PrivateKey) ckg.getClass().getMethod("getPrivateKey").invoke(ckg);
Class<?> x500Name = Class.forName("sun.security.x509.X500Name");
Object xn = x500Name.getConstructor(String.class, String.class, String.class, String.class).newInstance("Test site", "Unknown", "Unknown", "Unknown");
cert = (X509Certificate) ckg.getClass().getMethod("getSelfCertificate", x500Name, long.class).invoke(ckg, xn, 3650L * 24 * 60 * 60);
} catch (Exception x) {
throw new WinstoneException(SSL_RESOURCES.getString("HttpsConnectorFactory.SelfSignedError"), x);
}
Logger.log(Level.WARNING, SSL_RESOURCES, "HttpsConnectorFactory.SelfSigned");

keystore = KeyStore.getInstance("JKS");
keystore.load(null);
@@ -168,15 +181,21 @@ private static PrivateKey readPEMRSAPrivateKey(Reader reader) throws IOException
reader.close();
}


DerInputStream dis = new DerInputStream(baos.toByteArray());
DerValue[] seq = dis.getSequence(0);

// int v = seq[0].getInteger();
BigInteger mod = seq[1].getBigInteger();
// pubExpo
BigInteger privExpo = seq[3].getBigInteger();
// p1, p2, exp1, exp2, crtCoef
BigInteger mod, privExpo;
try {
Class<?> disC = Class.forName("sun.security.util.DerInputStream");
Object dis = disC.getConstructor(byte[].class).newInstance((Object) baos.toByteArray());
Object[] seq = (Object[]) disC.getMethod("getSequence", int.class).invoke(dis, 0);
Method getBigInteger = seq[0].getClass().getMethod("getBigInteger");
// int v = seq[0].getInteger();
mod = (BigInteger) getBigInteger.invoke(seq[1]);
// pubExpo
// p1, p2, exp1, exp2, crtCoef
privExpo = (BigInteger) getBigInteger.invoke(seq[3]);
} catch (Exception x) {
throw new WinstoneException(SSL_RESOURCES.getString("HttpsConnectorFactory.LoadPrivateKeyError"), x);
}
Logger.log(Level.WARNING, SSL_RESOURCES, "HttpsConnectorFactory.LoadPrivateKey");

KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate (new RSAPrivateKeySpec(mod,privExpo));
@@ -142,4 +142,13 @@ HttpsListener.MissingNPN=SPDY support requires NPN specified in the -Xbootclassp

Ajp13ConnectorFactory.NotSupported=\
AJP support is removed in Winstone 3.0 due to Jetty 9 not supporting AJP. \
For reverse proxying, please use HTTP instead of AJP.
For reverse proxying, please use HTTP instead of AJP.

HttpsConnectorFactory.SelfSigned=\
Creating a self-signed certificate currently relies on unsupported APIs in the Oracle JRE.\n\
Please create your own certificate using supported tools instead and use --httpsKeyStore.
HttpsConnectorFactory.SelfSignedError=Failed to create a self-signed certificate; make one yourself.
HttpsConnectorFactory.LoadPrivateKey=\
Using the --httpsPrivateKey/--httpsCertificate options currently relies on unsupported APIs in the Oracle JRE.\n\
Please use --httpsKeyStore and related options instead.
HttpsConnectorFactory.LoadPrivateKeyError=Cannot load private key; try using a Java keystore instead.

0 comments on commit 14b69f1

Please sign in to comment.