Skip to content

Commit

Permalink
Merge branch 'support_ec_keys' of github.com:pascal-hofmann/mockserve…
Browse files Browse the repository at this point in the history
…r into pascal-hofmann-support_ec_keys
  • Loading branch information
jamesdbloom committed Aug 21, 2022
2 parents 2a96a04 + ab1b1b6 commit 6f0125d
Show file tree
Hide file tree
Showing 18 changed files with 197 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.PrivateKey;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -348,7 +348,7 @@ private NettyHttpClient getNettyHttpClient() {
clientSslContextBuilderFunction =
sslContextBuilder -> {
try {
RSAPrivateKey key = privateKeyFromPEMFile(configuration.controlPlanePrivateKeyPath());
PrivateKey key = privateKeyFromPEMFile(configuration.controlPlanePrivateKeyPath());
X509Certificate[] keyCertChain = x509ChainFromPEMFile(configuration.controlPlaneX509CertificatePath()).toArray(new X509Certificate[0]);
X509Certificate[] trustCertCollection = nettySslContextFactory.trustCertificateChain(configuration.controlPlaneTLSMutualAuthenticationCAChain());
sslContextBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package org.mockserver.socket.tls;

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.mockserver.file.FileReader;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.PrivateKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
Expand Down Expand Up @@ -73,17 +77,20 @@ public static KeySpec keySpecFromPEM(final String pem) {
return new PKCS8EncodedKeySpec(privateKeyBytesFromPEM(pem));
}

public static RSAPrivateKey privateKeyFromPEMFile(String filename) {
public static PrivateKey privateKeyFromPEMFile(String filename) {
try {
return privateKeyFromPEM(FileReader.readFileFromClassPathOrPath(filename));
} catch (Exception e) {
throw new RuntimeException("Exception reading private key from PEM file", e);
}
}

public static RSAPrivateKey privateKeyFromPEM(String pem) {
public static PrivateKey privateKeyFromPEM(String pem) {
try {
return (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(keySpecFromPEM(pem));

PEMParser pemParser = new PEMParser(new StringReader(pem));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
return converter.getPrivateKey(PrivateKeyInfo.getInstance(pemParser.readObject()));
} catch (Exception e) {
throw new RuntimeException("Exception reading private key from PEM file", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.PrivateKey;
import java.util.*;

import static org.apache.commons.lang3.StringUtils.isBlank;
Expand All @@ -57,7 +57,7 @@ public class BCKeyAndCertificateFactory implements KeyAndCertificateFactory {

private PrivateKey privateKey;
private X509Certificate x509Certificate;
private RSAPrivateKey certificateAuthorityPrivateKey;
private PrivateKey certificateAuthorityPrivateKey;
private X509Certificate certificateAuthorityX509Certificate;

public BCKeyAndCertificateFactory(Configuration configuration, MockServerLogger mockServerLogger) {
Expand Down Expand Up @@ -101,7 +101,7 @@ private String certificateAuthorityPrivateKeyPath() {
/**
* load ca private key
*/
private RSAPrivateKey certificateAuthorityPrivateKey() {
private PrivateKey certificateAuthorityPrivateKey() {
if (certificateAuthorityPrivateKey == null) {
if (dynamicallyUpdateCertificateAuthority()) {
buildAndSaveCertificateAuthorityPrivateKeyAndX509Certificate();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
see [generate_custom_certifcates](src/test/resources/org/mockserver/netty/integration/tls/generate_custom_certificates.md) for instructions on how to generate these certificates
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

import javax.net.ssl.SSLException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.PrivateKey;
import java.util.Collections;

import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
Expand Down Expand Up @@ -88,7 +88,7 @@ public static void startServer() {
nettySslContextFactory.withClientSslContextBuilderFunction(
sslContextBuilder -> {
try {
RSAPrivateKey key = privateKeyFromPEMFile(ConfigurationProperties.controlPlanePrivateKeyPath());
PrivateKey key = privateKeyFromPEMFile(ConfigurationProperties.controlPlanePrivateKeyPath());
X509Certificate[] keyCertChain = x509ChainFromPEMFile(ConfigurationProperties.controlPlaneX509CertificatePath()).toArray(new X509Certificate[0]);
X509Certificate[] trustCertCollection = nettySslContextFactory.trustCertificateChain(ConfigurationProperties.controlPlaneTLSMutualAuthenticationCAChain());
sslContextBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.mockserver.netty.integration.tls.inbound;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.mockserver.testing.integration.mock.AbstractBasicMockingSameJVMIntegrationTest;

import static org.mockserver.configuration.ConfigurationProperties.certificateAuthorityCertificate;
import static org.mockserver.configuration.ConfigurationProperties.certificateAuthorityPrivateKey;
import static org.mockserver.configuration.ConfigurationProperties.privateKeyPath;
import static org.mockserver.configuration.ConfigurationProperties.x509CertificatePath;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.stop.Stop.stopQuietly;

/**
* @author pascal-hofmann
*/
public class CustomPrivateKeyAndCertificateWithECKeysMockingIntegrationTest extends AbstractBasicMockingSameJVMIntegrationTest {

private static int mockServerPort;
private static String originalCertificateAuthorityCertificate;
private static String originalCertificateAuthorityPrivateKey;
private static String originalPrivateKeyPath;
private static String originalX509CertificatePath;

@BeforeClass
public static void startServer() {
// save original value
originalCertificateAuthorityCertificate = certificateAuthorityCertificate();
originalCertificateAuthorityPrivateKey = certificateAuthorityPrivateKey();
originalPrivateKeyPath = privateKeyPath();
originalX509CertificatePath = x509CertificatePath();

// set new values
certificateAuthorityCertificate("org/mockserver/netty/integration/tls/ec/ca.pem");
certificateAuthorityPrivateKey("org/mockserver/netty/integration/tls/ec/ca-key-pkcs8.pem");
privateKeyPath("org/mockserver/netty/integration/tls/ec/leaf-key-pkcs8.pem");
x509CertificatePath("org/mockserver/netty/integration/tls/ec/leaf-cert.pem");

mockServerClient = startClientAndServer();
mockServerPort = mockServerClient.getPort();
}

@AfterClass
public static void stopServer() {
stopQuietly(mockServerClient);

// set back to original value
certificateAuthorityCertificate(originalCertificateAuthorityCertificate);
certificateAuthorityPrivateKey(originalCertificateAuthorityPrivateKey);
privateKeyPath(originalPrivateKeyPath);
x509CertificatePath(originalX509CertificatePath);
}

@Override
public int getServerPort() {
return mockServerPort;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "UK",
"L": "London",
"O": "MockServer",
"CN": "www.mockserver.com"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgYYWHA2muEszTvTfd
gMLtANU7g3vJFvOvu29OlSA9+LehRANCAAQMVjmPw4w5QdEh/RkOca5W+1uSajwH
jMWFw3QM44ltecE0rfXMlx9EgUwOmvwgS/flzicbp71O24ylW4TxF4DP
-----END PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIGGFhwNprhLM07033YDC7QDVO4N7yRbzr7tvTpUgPfi3oAoGCCqGSM49
AwEHoUQDQgAEDFY5j8OMOUHRIf0ZDnGuVvtbkmo8B4zFhcN0DOOJbXnBNK31zJcf
RIFMDpr8IEv35c4nG6e9TtuMpVuE8ReAzw==
-----END EC PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBqjCCAVCgAwIBAgIUIOLrgCyQHOjdGLM5btVSA7QygbwwCgYIKoZIzj0EAwIw
MzELMAkGA1UEBhMCVUsxDzANBgNVBAcTBkxvbmRvbjETMBEGA1UEChMKTW9ja1Nl
cnZlcjAeFw0yMjA3MDYwMDQ3MDBaFw0yNzA3MDUwMDQ3MDBaMDMxCzAJBgNVBAYT
AlVLMQ8wDQYDVQQHEwZMb25kb24xEzARBgNVBAoTCk1vY2tTZXJ2ZXIwWTATBgcq
hkjOPQIBBggqhkjOPQMBBwNCAAQMVjmPw4w5QdEh/RkOca5W+1uSajwHjMWFw3QM
44ltecE0rfXMlx9EgUwOmvwgS/flzicbp71O24ylW4TxF4DPo0IwQDAOBgNVHQ8B
Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVE1DEs/YuwgSe1wD
4/13ATIuR30wCgYIKoZIzj0EAwIDSAAwRQIhAKUh8DIaZAQxqSCP8A8hURgnplIc
6+izhDnVp5xtWiBKAiAU8+KfCsS+zL/gwvV8cnY5W+Gw1dWEqRvGIy+4057vfQ==
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"hosts": [
"example.com",
"www.example.com",
"https://www.example.com",
"localhost",
"127.0.0.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "UK",
"L": "London",
"O": "MockServer",
"CN": "www.mockserver.com"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
To generate these certificates, follow the instructions in
[generate_custom_certifcates](../generate_custom_certificates.md) but use these key settings instead:

```
"key": {
"algo": "ecdsa",
"size": 256
},
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIICGzCCAcGgAwIBAgIUdWxKTU18GRCME/wOGM4Tlia1WNQwCgYIKoZIzj0EAwIw
MzELMAkGA1UEBhMCVUsxDzANBgNVBAcTBkxvbmRvbjETMBEGA1UEChMKTW9ja1Nl
cnZlcjAeFw0yMjA3MDYwMDQ5MDBaFw0yMzA3MDYwMDQ5MDBaMDMxCzAJBgNVBAYT
AlVLMQ8wDQYDVQQHEwZMb25kb24xEzARBgNVBAoTCk1vY2tTZXJ2ZXIwWTATBgcq
hkjOPQIBBggqhkjOPQMBBwNCAATn+jJTL/MzRe6DQtPnBdvZn7JEFP06gEuNmTB6
sZQUGvfDjx/HRfvHDp1dW3CzyPvs0H7Z0027XbVMTD2DGnr8o4GyMIGvMA4GA1Ud
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T
AQH/BAIwADAdBgNVHQ4EFgQUQYBTX8Lg+jLXOwlmo0LAa6mxFpcwUQYDVR0RBEow
SIILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYIJbG9jYWxob3N0hwR/AAAB
hhdodHRwczovL3d3dy5leGFtcGxlLmNvbTAKBggqhkjOPQQDAgNIADBFAiAl0noW
hQd0uGksqvEj2Wc6w/3Fi5SiVHrn3cygGsWqTgIhAMGtvHJNRE7PaK0V2ISULnXr
ZaA7BweVjGAD8JQAUS0s
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIBqjCCAVCgAwIBAgIUIOLrgCyQHOjdGLM5btVSA7QygbwwCgYIKoZIzj0EAwIw
MzELMAkGA1UEBhMCVUsxDzANBgNVBAcTBkxvbmRvbjETMBEGA1UEChMKTW9ja1Nl
cnZlcjAeFw0yMjA3MDYwMDQ3MDBaFw0yNzA3MDUwMDQ3MDBaMDMxCzAJBgNVBAYT
AlVLMQ8wDQYDVQQHEwZMb25kb24xEzARBgNVBAoTCk1vY2tTZXJ2ZXIwWTATBgcq
hkjOPQIBBggqhkjOPQMBBwNCAAQMVjmPw4w5QdEh/RkOca5W+1uSajwHjMWFw3QM
44ltecE0rfXMlx9EgUwOmvwgS/flzicbp71O24ylW4TxF4DPo0IwQDAOBgNVHQ8B
Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVE1DEs/YuwgSe1wD
4/13ATIuR30wCgYIKoZIzj0EAwIDSAAwRQIhAKUh8DIaZAQxqSCP8A8hURgnplIc
6+izhDnVp5xtWiBKAiAU8+KfCsS+zL/gwvV8cnY5W+Gw1dWEqRvGIy+4057vfQ==
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICGzCCAcGgAwIBAgIUdWxKTU18GRCME/wOGM4Tlia1WNQwCgYIKoZIzj0EAwIw
MzELMAkGA1UEBhMCVUsxDzANBgNVBAcTBkxvbmRvbjETMBEGA1UEChMKTW9ja1Nl
cnZlcjAeFw0yMjA3MDYwMDQ5MDBaFw0yMzA3MDYwMDQ5MDBaMDMxCzAJBgNVBAYT
AlVLMQ8wDQYDVQQHEwZMb25kb24xEzARBgNVBAoTCk1vY2tTZXJ2ZXIwWTATBgcq
hkjOPQIBBggqhkjOPQMBBwNCAATn+jJTL/MzRe6DQtPnBdvZn7JEFP06gEuNmTB6
sZQUGvfDjx/HRfvHDp1dW3CzyPvs0H7Z0027XbVMTD2DGnr8o4GyMIGvMA4GA1Ud
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T
AQH/BAIwADAdBgNVHQ4EFgQUQYBTX8Lg+jLXOwlmo0LAa6mxFpcwUQYDVR0RBEow
SIILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYIJbG9jYWxob3N0hwR/AAAB
hhdodHRwczovL3d3dy5leGFtcGxlLmNvbTAKBggqhkjOPQQDAgNIADBFAiAl0noW
hQd0uGksqvEj2Wc6w/3Fi5SiVHrn3cygGsWqTgIhAMGtvHJNRE7PaK0V2ISULnXr
ZaA7BweVjGAD8JQAUS0s
-----END CERTIFICATE-----

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgW/VkDCWlWqD4pds6
+V797DqUk2HnZtXibwTIgElChcmhRANCAATn+jJTL/MzRe6DQtPnBdvZn7JEFP06
gEuNmTB6sZQUGvfDjx/HRfvHDp1dW3CzyPvs0H7Z0027XbVMTD2DGnr8
-----END PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFv1ZAwlpVqg+KXbOvle/ew6lJNh52bV4m8EyIBJQoXJoAoGCCqGSM49
AwEHoUQDQgAE5/oyUy/zM0Xug0LT5wXb2Z+yRBT9OoBLjZkwerGUFBr3w48fx0X7
xw6dXVtws8j77NB+2dNNu121TEw9gxp6/A==
-----END EC PRIVATE KEY-----

0 comments on commit 6f0125d

Please sign in to comment.