Skip to content

Commit 972f348

Browse files
committed
Merge pull request #368 from jekh/add-useecc-option-in-core-and-standalone
Add useEcc convenience option to BrowserMobProxyServer and REST API
2 parents 13282ec + e55239c commit 972f348

File tree

3 files changed

+47
-21
lines changed

3 files changed

+47
-21
lines changed

browsermob-core-littleproxy/src/main/java/net/lightbody/bmp/BrowserMobProxyServer.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import net.lightbody.bmp.filters.UnregisterRequestFilter;
3232
import net.lightbody.bmp.filters.WhitelistFilter;
3333
import net.lightbody.bmp.mitm.KeyStoreFileCertificateSource;
34+
import net.lightbody.bmp.mitm.keys.ECKeyGenerator;
3435
import net.lightbody.bmp.mitm.keys.RSAKeyGenerator;
3536
import net.lightbody.bmp.mitm.manager.ImpersonatingMitmManager;
3637
import net.lightbody.bmp.proxy.ActivityMonitor;
@@ -97,7 +98,8 @@ public class BrowserMobProxyServer implements BrowserMobProxy, LegacyProxyServer
9798
private static final HarNameVersion HAR_CREATOR_VERSION = new HarNameVersion("BrowserMob Proxy", "2.1.0-beta-4-littleproxy");
9899

99100
/* Default MITM resources */
100-
private static final String KEYSTORE_RESOURCE = "/sslSupport/ca-keystore-rsa.p12";
101+
private static final String RSA_KEYSTORE_RESOURCE = "/sslSupport/ca-keystore-rsa.p12";
102+
private static final String EC_KEYSTORE_RESOURCE = "/sslSupport/ca-keystore-ec.p12";
101103
private static final String KEYSTORE_TYPE = "PKCS12";
102104
private static final String KEYSTORE_PRIVATE_KEY_ALIAS = "key";
103105
private static final String KEYSTORE_PASSWORD = "password";
@@ -248,6 +250,11 @@ public class BrowserMobProxyServer implements BrowserMobProxy, LegacyProxyServer
248250
*/
249251
private volatile boolean trustAllServers = true;
250252

253+
/**
254+
* When true, use Elliptic Curve keys and certificates when impersonating upstream servers.
255+
*/
256+
private volatile boolean useEcc = false;
257+
251258
/**
252259
* Resolver to use when resolving hostnames to IP addresses. This is a bridge between {@link org.littleshoot.proxy.HostResolver} and
253260
* {@link net.lightbody.bmp.proxy.dns.AdvancedHostResolver}. It allows the resolvers to be changed on-the-fly without re-bootstrapping the
@@ -377,8 +384,12 @@ public int getMaximumResponseBufferSizeInBytes() {
377384
if (!mitmDisabled) {
378385
if (mitmManager == null) {
379386
mitmManager = ImpersonatingMitmManager.builder()
380-
.rootCertificateSource(new KeyStoreFileCertificateSource(KEYSTORE_TYPE, KEYSTORE_RESOURCE, KEYSTORE_PRIVATE_KEY_ALIAS, KEYSTORE_PASSWORD))
381-
.serverKeyGenerator(new RSAKeyGenerator())
387+
.rootCertificateSource(new KeyStoreFileCertificateSource(
388+
KEYSTORE_TYPE,
389+
useEcc ? EC_KEYSTORE_RESOURCE : RSA_KEYSTORE_RESOURCE,
390+
KEYSTORE_PRIVATE_KEY_ALIAS,
391+
KEYSTORE_PASSWORD))
392+
.serverKeyGenerator(useEcc ? new ECKeyGenerator() : new RSAKeyGenerator())
382393
.trustAllServers(trustAllServers)
383394
.build();
384395
}
@@ -1421,6 +1432,10 @@ public boolean isMitmDisabled() {
14211432
return this.mitmDisabled;
14221433
}
14231434

1435+
public void setUseEcc(boolean useEcc) {
1436+
this.useEcc = useEcc;
1437+
}
1438+
14241439
/**
14251440
* Adds the basic browsermob-proxy filters, except for the relatively-expensive HAR capture filter.
14261441
*/
@@ -1563,5 +1578,4 @@ public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerCont
15631578
});
15641579
}
15651580
}
1566-
15671581
}

browsermob-rest/src/main/java/net/lightbody/bmp/proxy/ProxyManager.java

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,38 +129,48 @@ public void onRemoval(RemovalNotification<Integer, LegacyProxyServer> removal) {
129129
}
130130
}
131131

132-
public LegacyProxyServer create(Map<String, String> options, Integer port, String bindAddr) {
132+
public LegacyProxyServer create(Map<String, String> options, Integer port, String bindAddr, boolean useEcc) {
133133
LOG.debug("Instantiate ProxyServer...");
134134
LegacyProxyServer proxy = proxyServerProvider.get();
135135

136+
if (useEcc) {
137+
if (proxy instanceof BrowserMobProxyServer) {
138+
LOG.info("Using Elliptic Curve Cryptography for certificate impersonation");
139+
140+
((BrowserMobProxyServer)proxy).setUseEcc(true);
141+
} else {
142+
LOG.warn("Cannot use Eliiptic Curve Cryptography with legacy ProxyServer implementation. Using default RSA certificates.");
143+
}
144+
}
145+
136146
if (options != null) {
137147
LOG.debug("Apply options `{}` to new ProxyServer...", options);
138148
proxy.setOptions(options);
139149
}
140-
141-
if (bindAddr != null) {
150+
151+
if (bindAddr != null) {
142152
LOG.debug("Bind ProxyServer to `{}`...", bindAddr);
143153
InetAddress inetAddress;
144154
try {
145155
inetAddress = InetAddress.getByName(bindAddr);
146156
} catch (UnknownHostException e) {
147157
LOG.error("Unable to bind proxy to address: " + bindAddr + "; proxy will not be created.", e);
148-
158+
149159
throw new RuntimeException("Unable to bind proxy to address: ", e);
150160
}
151-
161+
152162
proxy.setLocalHost(inetAddress);
153163
}
154-
155-
if (port != null) {
156-
return startProxy(proxy, port);
157-
}
158-
164+
165+
if (port != null) {
166+
return startProxy(proxy, port);
167+
}
168+
159169
while(proxies.size() <= maxPort-minPort){
160170
LOG.debug("Use next available port for new ProxyServer...");
161-
port = nextPort();
171+
port = nextPort();
162172
try{
163-
return startProxy(proxy, port);
173+
return startProxy(proxy, port);
164174
}catch(ProxyExistsException ex){
165175
LOG.debug("Proxy already exists at port {}", port);
166176
}
@@ -169,19 +179,19 @@ public LegacyProxyServer create(Map<String, String> options, Integer port, Strin
169179
}
170180

171181
public LegacyProxyServer create(Map<String, String> options, Integer port) {
172-
return create(options, port, null);
182+
return create(options, port, null, false);
173183
}
174184

175185
public LegacyProxyServer create(Map<String, String> options) {
176-
return create(options, null, null);
186+
return create(options, null, null, false);
177187
}
178188

179189
public LegacyProxyServer create() {
180-
return create(null, null, null);
190+
return create(null, null, null, false);
181191
}
182192

183193
public LegacyProxyServer create(int port) {
184-
return create(null, port, null);
194+
return create(null, port, null, false);
185195
}
186196

187197
public LegacyProxyServer get(int port) {

browsermob-rest/src/main/java/net/lightbody/bmp/proxy/bricks/ProxyResource.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,13 @@ public Reply<?> newProxy(Request<String> request) {
8585

8686
String paramBindAddr = request.param("bindAddress");
8787
Integer paramPort = request.param("port") == null ? null : Integer.parseInt(request.param("port"));
88+
String useEccString = request.param("useEcc");
89+
boolean useEcc = Boolean.parseBoolean(useEccString);
8890
LOG.debug("POST proxy instance on bindAddress `{}` & port `{}`",
8991
paramBindAddr, paramPort);
9092
LegacyProxyServer proxy;
9193
try{
92-
proxy = proxyManager.create(options, paramPort, paramBindAddr);
94+
proxy = proxyManager.create(options, paramPort, paramBindAddr, useEcc);
9395
}catch(ProxyExistsException ex){
9496
return Reply.with(new ProxyDescriptor(ex.getPort())).status(455).as(Json.class);
9597
}catch(ProxyPortsExhaustedException ex){

0 commit comments

Comments
 (0)