Skip to content
This repository has been archived by the owner on Feb 24, 2022. It is now read-only.

Bug/ssl context need client mode #195

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,12 @@ sudo: required
install: true
language: java

jdk: openjdk8

services:
- docker

before_install:
- curl -s "https://get.sdkman.io" | bash
- source "$HOME/.sdkman/bin/sdkman-init.sh"
- sdk version
- mkdir -p "$HOME/.sdkman/etc"
- echo "sdkman_auto_answer=true" > "$HOME/.sdkman/etc/config"
- echo "sdkman_auto_selfupdate=true" >> "$HOME/.sdkman/etc/config"
- sdk install java 8.0.242.hs-adpt

script:
- sdk use java 8.0.242.hs-adpt
- java -version
- ./gradlew ci

Expand Down
6 changes: 5 additions & 1 deletion src/main/java/mousio/etcd4j/transport/EtcdNettyClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
import java.util.Map;
import java.util.concurrent.CancellationException;

import javax.net.ssl.SSLEngine;

/**
* @author Jurriaan Mous
* @author Luca Burgazzoli
Expand Down Expand Up @@ -150,7 +152,9 @@ public void initChannel(SocketChannel ch) throws Exception {
if (securityContext.hasNettySsl()) {
p.addLast(securityContext.nettySslContext().newHandler(ch.alloc()));
} else if (securityContext.hasSsl()) {
p.addLast(new SslHandler(securityContext.sslContext().createSSLEngine()));
SSLEngine sslEngine = securityContext.sslContext().createSSLEngine();
sslEngine.setUseClientMode(true);
p.addLast(new SslHandler(sslEngine));
}
p.addLast("codec", new HttpClientCodec());
p.addLast("auth", new HttpBasicAuthHandler());
Expand Down
58 changes: 56 additions & 2 deletions src/test/java/mousio/etcd4j/security/EtcdKeystoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,38 @@

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeoutException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import mousio.client.exceptions.SecurityContextException;
import mousio.etcd4j.EtcdClient;
import mousio.etcd4j.EtcdSecurityContext;
import mousio.etcd4j.responses.EtcdAuthenticationException;
import mousio.etcd4j.responses.EtcdException;
import mousio.etcd4j.responses.EtcdKeysResponse;
import mousio.etcd4j.support.EtcdCluster;
import mousio.etcd4j.support.EtcdClusterFactory;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
Expand All @@ -37,6 +53,8 @@ public class EtcdKeystoreTest {
private static final String KS_PASSWORD = "dummy_password";
private static final String KS_LOCATION = "dummy_ks";
private static final String TS_LOCATION = "dummy_ts";

private static EtcdCluster CLUSTER;

@Rule
public ExpectedException expectedEx = ExpectedException.none();
Expand All @@ -46,6 +64,17 @@ public class EtcdKeystoreTest {
TRUSTSTORE_PATH = new File("src/test/resources/certs/truststore.jks").getAbsolutePath();
}

@BeforeClass
public static void setUpCluster() {
CLUSTER = EtcdClusterFactory.buildCluster(EtcdKeystoreTest.class.getName(), 1, true);
CLUSTER.start();
}

@AfterClass
public static void tearDownCluster() {
CLUSTER.close();
}

protected void cleanup(EtcdClient etcd) {
try {
for (EtcdKeysResponse.EtcdNode node: etcd.getAll().send().get().getNode().getNodes()) {
Expand Down Expand Up @@ -80,16 +109,41 @@ public void testInvalidTruststoreFormat() throws UnsupportedEncodingException, S
SecurityContextBuilder.forKeystoreAndTruststore(stream, KS_PASSWORD, stream, KS_PASSWORD, "SunX509");
}

@Ignore
@Test
public void testSslCliAgainstSslEtcd() throws SecurityContextException, URISyntaxException, IOException, EtcdAuthenticationException, TimeoutException, EtcdException {
// expected to work only on a secured etcd
URI[] endpoints = CLUSTER.endpoints();

EtcdClient etcd = new EtcdClient(SecurityContextBuilder.forKeystoreAndTruststore(
KEYSTORE_PATH,
KEYSTORE_PASS,
TRUSTSTORE_PATH,
TRUSTSTORE_PASS
), new URI(SECURED_ETCD_SERVICE));
), endpoints);

etcd.put("/test", "1234").send().get();
assertNotNull(etcd.version());
cleanup(etcd);
}

@Test
public void testSSLContextClientModeSetSslEtcd() throws SecurityContextException, URISyntaxException, IOException, EtcdAuthenticationException, TimeoutException, EtcdException, NoSuchAlgorithmException, KeyStoreException, CertificateException, KeyManagementException {
// expected to work only on a secured etcd using SSLContext with Custom TrustManager
URI[] endpoints = CLUSTER.endpoints();

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(new FileInputStream(TRUSTSTORE_PATH), TRUSTSTORE_PASS.toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
TrustManager[] trustManagers = tmf.getTrustManagers();

sslContext.init(null, trustManagers, null);
EtcdSecurityContext securityContext = new EtcdSecurityContext(sslContext);

EtcdClient etcd = new EtcdClient(securityContext, endpoints);

etcd.put("/test", "1234").send().get();
assertNotNull(etcd.version());
Expand Down
15 changes: 15 additions & 0 deletions src/test/resources/ssl/cert/etcd0-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDC06SsY60qbmKS7O09ATdJiCRdleXnb5MCz8tUR7rgYCgPxh//
PK+INi5gmLpQg2eJ69aWLBO3NuOOyGedyyyvYmlg1jd6kNS4ZW7D1Bjq0POBhU/t
kKtkEmHyocEn6mbgoyWOFPN0/raPz0SaN3/53E4j57j+TF+KIWkwB2n3CwIDAQAB
AoGABkByXVHJgb4PDbXqmvWKB6MFv7cKrJWI+yMd3DN9DKwpPPBXoIIbA9zxOgpM
mD7POL7HoQQDEfMB9Ff78zVM1rmL9khUUwLstzVlhQPpgJK4ZvMEH/V90AsfolQ2
qp1iQHLiYZ8JZYM6k6fqw6bJgAAVNhpCs9A04CIHAZ4JcqECQQDwBBg4bt6YkZ0c
hzXq/h/DHzIZFxHMlog4W6S16iN80gMy3fst/aif9jdrlH9CogWNz1h36YMjXNtM
8x0sI6G7AkEAz80kD8WGRXkEYr6aRkmZudaKp54kPhVm/29svNo0BMmYR2YRFhFd
RoQaPx4Url3ML6vvKw5oLmeOdhpU833C8QJAUgzUStZ7+iQtVYdTg1YEfau4cKNW
Tl5XiwypLhcwsocI2ObR61L/xk9hesF1D85bn7L2R2fokLo5rgCeRGyZ6QJBAJW6
pL9Qfj1Uw5o66IK4ybGkKug4BLlPRpXLPbieKVlBwR3BJ5KVFHaY/Sh5jkFNiLDY
3E5T5TF6oKXst0VzWqECQQCJQSKapWi62G7QlrrfpxOGG2JBajGVUqg1js8E2Cc9
Fwjfg/cmiDURVJ7ik8ZXkwKnnPnglqUeBU/eETarGUGx
-----END RSA PRIVATE KEY-----
15 changes: 15 additions & 0 deletions src/test/resources/ssl/cert/etcd0.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICWDCCAcGgAwIBAgIJAOYLKcaq9CKfMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcxMjI4MTQ1MjA3WhcNMTgxMjI4MTQ1MjA3WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQDC06SsY60qbmKS7O09ATdJiCRdleXnb5MCz8tUR7rgYCgPxh//PK+INi5gmLpQ
g2eJ69aWLBO3NuOOyGedyyyvYmlg1jd6kNS4ZW7D1Bjq0POBhU/tkKtkEmHyocEn
6mbgoyWOFPN0/raPz0SaN3/53E4j57j+TF+KIWkwB2n3CwIDAQABo1AwTjAdBgNV
HQ4EFgQUV5ckHk6DPSisP0Qr2J+gvT12Z+cwHwYDVR0jBBgwFoAUV5ckHk6DPSis
P0Qr2J+gvT12Z+cwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA8rH3L
s5mCIumE3Bd8It6nDBjnoB5OYKOrx1rEEAHR7iB1ZCZiyBY00p187APcKphdHsaF
OIcXPSE9HD0aHizB1hKZmD4fLfA1YGgkG6FZTaCFsrpDPmExZ6HRyZhucPRwo/u/
n2RE9blqo7WsT+gvj4Kng/oYrOxIMEDfQQlgOQ==
-----END CERTIFICATE-----
1 change: 1 addition & 0 deletions src/test/resources/testcontainers.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ryuk.container.image=testcontainersofficial/ryuk