Skip to content

Commit

Permalink
Moved the writable key store source (used when browser proxying HTTPS…
Browse files Browse the repository at this point in the history
…) to the java8 sources to avoid breaking older Android builds in the java7 build with use of Path, Paths etc. from java.nio
  • Loading branch information
tomakehurst committed Jul 2, 2020
1 parent d597aaf commit e2809eb
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 69 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.github.tomakehurst.wiremock.common.ssl;
package com.github.tomakehurst.wiremock.jetty94;

import com.github.tomakehurst.wiremock.common.ssl.ReadOnlyFileOrClasspathKeyStoreSource;
import com.google.common.io.Resources;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Files;
Expand All @@ -23,37 +22,10 @@
import static java.nio.file.attribute.PosixFilePermission.*;
import static java.nio.file.attribute.PosixFilePermissions.asFileAttribute;

public class FileOrClasspathKeyStoreSource extends KeyStoreSource {
public class WritableFileOrClasspathKeyStoreSource extends ReadOnlyFileOrClasspathKeyStoreSource {

private final String path;

public FileOrClasspathKeyStoreSource(String path, String keyStoreType, char[] keyStorePassword) {
super(keyStoreType, keyStorePassword);
this.path = path;
}

@SuppressWarnings("UnstableApiUsage")
@Override
protected InputStream createInputStream() {
try {
if (exists()) {
return new FileInputStream(path);
} else {
try {
URL pathUrl = new URL(path);
return pathUrl.openStream();
} catch (MalformedURLException ignored) {
return Resources.getResource(path).openStream();
}
}
} catch (IOException e) {
return throwUnchecked(e, InputStream.class);
}
}

@Override
public boolean exists() {
return new File(path).isFile();
public WritableFileOrClasspathKeyStoreSource(String path, String keyStoreType, char[] keyStorePassword) {
super(path, keyStoreType, keyStorePassword);
}

@Override
Expand Down Expand Up @@ -83,22 +55,4 @@ private static Path createKeystoreFile(Path path) {
return throwUnchecked(e, Path.class);
}
}

public String getPath() {
return path;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
FileOrClasspathKeyStoreSource that = (FileOrClasspathKeyStoreSource) o;
return path.equals(that.path);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), path);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

import com.github.tomakehurst.wiremock.common.ssl.KeyStoreSettings;

import java.nio.file.Paths;
import java.io.File;
import java.util.List;
import java.util.Objects;

import static java.util.Collections.emptyList;

public final class BrowserProxySettings {

public static final String DEFAULT_CA_KEYSTORE_PATH = Paths.get(
System.getProperty("user.home"))
.resolve(".wiremock")
.resolve("ca-keystore.jks")
.toFile().getAbsolutePath();
public static final String DEFAULT_CA_KEYSTORE_PATH = new File(
System.getProperty("user.home") + File.separatorChar
+ ".wiremock" + File.separatorChar
+ "ca-keystore.jks" + File.separatorChar
).getAbsolutePath();
public static final String DEFAULT_CA_KESTORE_PASSWORD = "password";

public static BrowserProxySettings DISABLED = new Builder().build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public KeyStoreSettings(KeyStoreSource keyStoreSource) {

public KeyStoreSettings(String path, String password, String type) {
this(
path != null && password != null && type != null ? new FileOrClasspathKeyStoreSource(
path != null && password != null && type != null ? KeyStoreSourceFactory.getAppropriateForJreVersion(
path,
type,
password.toCharArray()) :
Expand All @@ -40,8 +40,8 @@ public KeyStoreSettings(String path, String password, String type) {
}

public String path() {
if (keyStoreSource instanceof FileOrClasspathKeyStoreSource) {
return ((FileOrClasspathKeyStoreSource) keyStoreSource).getPath();
if (keyStoreSource instanceof ReadOnlyFileOrClasspathKeyStoreSource) {
return ((ReadOnlyFileOrClasspathKeyStoreSource) keyStoreSource).getPath();
}

return "(no path - custom keystore source)";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.github.tomakehurst.wiremock.common.ssl;

import com.github.tomakehurst.wiremock.common.Exceptions;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class KeyStoreSourceFactory {

@SuppressWarnings("unchecked")
public static KeyStoreSource getAppropriateForJreVersion(String path, String keyStoreType, char[] keyStorePassword) {
try {
final Class<?extends KeyStoreSource> theClass = (Class<? extends KeyStoreSource>) Class.forName("com.github.tomakehurst.wiremock.jetty94.WritableFileOrClasspathKeyStoreSource");
return safelyGetConstructor(theClass, String.class, String.class, char[].class).newInstance(path, keyStoreType, keyStorePassword);
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
return new ReadOnlyFileOrClasspathKeyStoreSource(path, keyStoreType, keyStorePassword);
}
}

@SuppressWarnings("unchecked")
private static <T> Constructor<T> safelyGetConstructor(Class<T> clazz, Class<?>... parameterTypes) {
try {
return clazz.getConstructor(parameterTypes);
} catch (NoSuchMethodException e) {
return Exceptions.throwUnchecked(e, Constructor.class);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.github.tomakehurst.wiremock.common.ssl;

import com.google.common.io.Resources;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
import java.util.Objects;

import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;

public class ReadOnlyFileOrClasspathKeyStoreSource extends KeyStoreSource {

protected final String path;

public ReadOnlyFileOrClasspathKeyStoreSource(String path, String keyStoreType, char[] keyStorePassword) {
super(keyStoreType, keyStorePassword);
this.path = path;
}

@SuppressWarnings("UnstableApiUsage")
@Override
protected InputStream createInputStream() {
try {
if (exists()) {
return new FileInputStream(path);
} else {
try {
URL pathUrl = new URL(path);
return pathUrl.openStream();
} catch (MalformedURLException ignored) {
return Resources.getResource(path).openStream();
}
}
} catch (IOException e) {
return throwUnchecked(e, InputStream.class);
}
}

@Override
public boolean exists() {
return new File(path).isFile();
}

@Override
public void save(KeyStore keyStore) {}

public String getPath() {
return path;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
ReadOnlyFileOrClasspathKeyStoreSource that = (ReadOnlyFileOrClasspathKeyStoreSource) o;
return path.equals(that.path);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), path);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
package com.github.tomakehurst.wiremock.core;

import com.github.tomakehurst.wiremock.common.*;
import com.github.tomakehurst.wiremock.common.ssl.FileOrClasspathKeyStoreSource;
import com.github.tomakehurst.wiremock.common.ssl.KeyStoreSettings;
import com.github.tomakehurst.wiremock.common.ssl.KeyStoreSourceFactory;
import com.github.tomakehurst.wiremock.extension.Extension;
import com.github.tomakehurst.wiremock.extension.ExtensionLoader;
import com.github.tomakehurst.wiremock.http.CaseInsensitiveKey;
Expand Down Expand Up @@ -579,7 +579,7 @@ public boolean getStubCorsEnabled() {
public BrowserProxySettings browserProxySettings() {
KeyStoreSettings keyStoreSettings = caKeyStoreSettings != null ?
caKeyStoreSettings :
new KeyStoreSettings(new FileOrClasspathKeyStoreSource(caKeystorePath, caKeystoreType, caKeystorePassword.toCharArray()));
new KeyStoreSettings(KeyStoreSourceFactory.getAppropriateForJreVersion(caKeystorePath, caKeystoreType, caKeystorePassword.toCharArray()));

return new BrowserProxySettings.Builder()
.enabled(browserProxyingEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
package com.github.tomakehurst.wiremock.standalone;

import com.github.tomakehurst.wiremock.common.*;
import com.github.tomakehurst.wiremock.common.BrowserProxySettings;
import com.github.tomakehurst.wiremock.common.ssl.FileOrClasspathKeyStoreSource;
import com.github.tomakehurst.wiremock.common.ssl.KeyStoreSettings;
import com.github.tomakehurst.wiremock.common.ssl.KeyStoreSourceFactory;
import com.github.tomakehurst.wiremock.core.MappingsSaver;
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.core.WireMockApp;
Expand Down Expand Up @@ -50,12 +49,15 @@
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
import static com.github.tomakehurst.wiremock.common.ProxySettings.NO_PROXY;
import static com.github.tomakehurst.wiremock.common.BrowserProxySettings.DEFAULT_CA_KESTORE_PASSWORD;
import static com.github.tomakehurst.wiremock.common.BrowserProxySettings.DEFAULT_CA_KEYSTORE_PATH;
import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
import static com.github.tomakehurst.wiremock.common.ProxySettings.NO_PROXY;
import static com.github.tomakehurst.wiremock.core.WireMockApp.MAPPINGS_ROOT;
import static com.github.tomakehurst.wiremock.extension.ExtensionLoader.valueAssignableFrom;
import static com.github.tomakehurst.wiremock.http.CaseInsensitiveKey.TO_CASE_INSENSITIVE_KEYS;
Expand Down Expand Up @@ -601,7 +603,7 @@ public boolean getStubCorsEnabled() {
@Override
public BrowserProxySettings browserProxySettings() {
KeyStoreSettings keyStoreSettings = new KeyStoreSettings(
new FileOrClasspathKeyStoreSource(
KeyStoreSourceFactory.getAppropriateForJreVersion(
(String) optionSet.valueOf(HTTPS_CA_KEYSTORE),
(String) optionSet.valueOf(HTTPS_CA_KEYSTORE_TYPE),
((String) optionSet.valueOf(HTTPS_CA_KEYSTORE_PASSWORD)).toCharArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class KeyStoreSourceTest {

@Test
public void loadsAPasswordProtectedJksKeyStore() throws Exception {
KeyStoreSource keyStoreSource = new FileOrClasspathKeyStoreSource(
KeyStoreSource keyStoreSource = new ReadOnlyFileOrClasspathKeyStoreSource(
"test-keystore-pwd",
"jks",
"nondefaultpass".toCharArray()
Expand Down

0 comments on commit e2809eb

Please sign in to comment.