#2 Option to provide trusted CA certificate
This commit is contained in:
@ -30,10 +30,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
@ -65,11 +63,12 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
|
||||
private final ObjectMapper jsonMapper;
|
||||
|
||||
private final String baseURL; /* Base URL of Vault */
|
||||
private final String baseURL; /* Base URL of Vault */
|
||||
private final SSLContext sslContext; /* Custom SSLSocketFactory */
|
||||
|
||||
private boolean authorized = false; /* authorization status */
|
||||
private String token; /* current token */
|
||||
private long tokenTTL = 0; /* expiration time for current token */
|
||||
private boolean authorized = false; /* authorization status */
|
||||
private String token; /* current token */
|
||||
private long tokenTTL = 0; /* expiration time for current token */
|
||||
|
||||
/**
|
||||
* Create connector using hostname and schema.
|
||||
@ -93,12 +92,12 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create connector using hostname, schame, port and path.
|
||||
* Create connector using hostname, schema, port and path.
|
||||
*
|
||||
* @param hostname The hostname
|
||||
* @param useTLS If TRUE, use HTTPS, otherwise HTTP
|
||||
* @param port The port
|
||||
* @param prefix HTTP API prefix (default: /v1/"
|
||||
* @param prefix HTTP API prefix (default: /v1/)
|
||||
*/
|
||||
public HTTPVaultConnector(String hostname, boolean useTLS, Integer port, String prefix) {
|
||||
this(((useTLS) ? "https" : "http") +
|
||||
@ -107,13 +106,40 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create connector using hostname, schema, port, path and trusted certificate.
|
||||
*
|
||||
* @param hostname The hostname
|
||||
* @param useTLS If TRUE, use HTTPS, otherwise HTTP
|
||||
* @param port The port
|
||||
* @param prefix HTTP API prefix (default: /v1/)
|
||||
* @param sslContext Custom SSL Context
|
||||
*/
|
||||
public HTTPVaultConnector(String hostname, boolean useTLS, Integer port, String prefix, SSLContext sslContext) {
|
||||
this(((useTLS) ? "https" : "http") +
|
||||
"://" + hostname +
|
||||
((port != null) ? ":" + port : "") +
|
||||
prefix,
|
||||
sslContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create connector using full URL.
|
||||
*
|
||||
* @param baseURL The URL
|
||||
*/
|
||||
public HTTPVaultConnector(String baseURL) {
|
||||
this(baseURL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create connector using full URL and trusted certificate.
|
||||
*
|
||||
* @param baseURL The URL
|
||||
*/
|
||||
public HTTPVaultConnector(String baseURL, SSLContext sslContext) {
|
||||
this.baseURL = baseURL;
|
||||
this.sslContext = sslContext;
|
||||
this.jsonMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
@ -669,7 +695,7 @@ public class HTTPVaultConnector implements VaultConnector {
|
||||
base.addHeader("accept", "application/json");
|
||||
|
||||
HttpResponse response = null;
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLContext(sslContext).build()) {
|
||||
response = httpClient.execute(base);
|
||||
/* Check if response is valid */
|
||||
if (response == null)
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2016 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package de.stklcode.jvault.connector.exception;
|
||||
|
||||
/**
|
||||
* Exception thrown on errors with TLS connection.
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public class TlsException extends VaultConnectorException {
|
||||
private Integer statusCode;
|
||||
private String response;
|
||||
|
||||
public TlsException() {
|
||||
}
|
||||
|
||||
public TlsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TlsException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public TlsException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public Integer getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getResponse() {
|
||||
return response;
|
||||
}
|
||||
}
|
@ -17,12 +17,26 @@
|
||||
package de.stklcode.jvault.connector.factory;
|
||||
|
||||
import de.stklcode.jvault.connector.HTTPVaultConnector;
|
||||
import de.stklcode.jvault.connector.exception.TlsException;
|
||||
import de.stklcode.jvault.connector.exception.VaultConnectorException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.*;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* Vault Connector Factory implementation for HTTP Vault connectors.
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.1
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.1
|
||||
*/
|
||||
public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
public static final String DEFAULT_HOST = "127.0.0.1";
|
||||
@ -34,6 +48,7 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
private Integer port;
|
||||
private boolean tls;
|
||||
private String prefix;
|
||||
private SSLContext sslContext;
|
||||
|
||||
/**
|
||||
* Default empty constructor.
|
||||
@ -48,8 +63,9 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
|
||||
/**
|
||||
* Set hostname (default: 127.0.0.1)
|
||||
* @param host Hostname or IP address
|
||||
* @return self
|
||||
*
|
||||
* @param host Hostname or IP address
|
||||
* @return self
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withHost(String host) {
|
||||
this.host = host;
|
||||
@ -58,8 +74,9 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
|
||||
/**
|
||||
* Set port (default: 8200)
|
||||
* @param port Vault TCP port
|
||||
* @return self
|
||||
*
|
||||
* @param port Vault TCP port
|
||||
* @return self
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withPort(Integer port) {
|
||||
this.port = port;
|
||||
@ -68,8 +85,9 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
|
||||
/**
|
||||
* Set TLS usage (default: TRUE)
|
||||
* @param useTLS use TLS or not
|
||||
* @return self
|
||||
*
|
||||
* @param useTLS use TLS or not
|
||||
* @return self
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withTLS(boolean useTLS) {
|
||||
this.tls = useTLS;
|
||||
@ -78,7 +96,8 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
|
||||
/**
|
||||
* Convenience Method for TLS usage (enabled by default)
|
||||
* @return self
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withTLS() {
|
||||
return withTLS(true);
|
||||
@ -86,7 +105,8 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
|
||||
/**
|
||||
* Convenience Method for NOT using TLS
|
||||
* @return self
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withoutTLS() {
|
||||
return withTLS(false);
|
||||
@ -94,16 +114,98 @@ public class HTTPVaultConnectorFactory extends VaultConnectorFactory {
|
||||
|
||||
/**
|
||||
* Set API prefix. Default is "/v1/" and changes should not be necessary for current state of development.
|
||||
* @param prefix Vault API prefix (default: "/v1/"
|
||||
* @return self
|
||||
*
|
||||
* @param prefix Vault API prefix (default: "/v1/"
|
||||
* @return self
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a trusted CA certifiate for HTTPS connections.
|
||||
*
|
||||
* @param cert path to certificate file
|
||||
* @return self
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withTrustedCA(Path cert) throws VaultConnectorException {
|
||||
return withSslContext(createSslContext(cert));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom SSL context.
|
||||
* Overwrites certificates set by {@link #withTrustedCA}.
|
||||
*
|
||||
* @param sslContext the SSL context
|
||||
* @return self
|
||||
* @since 0.4.0
|
||||
*/
|
||||
public HTTPVaultConnectorFactory withSslContext(SSLContext sslContext) {
|
||||
this.sslContext = sslContext;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HTTPVaultConnector build() {
|
||||
return new HTTPVaultConnector(host, tls, port, prefix);
|
||||
return new HTTPVaultConnector(host, tls, port, prefix, sslContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create SSL Context trusting only provided certificate.
|
||||
*
|
||||
* @param trustedCert Path to trusted CA certificate
|
||||
* @return SSL context
|
||||
* @throws TlsException on errors
|
||||
* @since 0.4.0
|
||||
*/
|
||||
private SSLContext createSslContext(Path trustedCert) throws TlsException {
|
||||
try {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, createTrustManager(trustedCert), new SecureRandom());
|
||||
return context;
|
||||
} catch (NoSuchAlgorithmException | KeyManagementException e) {
|
||||
throw new TlsException("Unable to intialize SSLContext", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a custom TrustManager for given CA certificate file.
|
||||
*
|
||||
* @param trustedCert Path to trusted CA certificate
|
||||
* @return TrustManger
|
||||
* @throws TlsException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
private TrustManager[] createTrustManager(Path trustedCert) throws TlsException {
|
||||
try {
|
||||
/* Create Keystore with trusted certificate */
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, null);
|
||||
keyStore.setCertificateEntry("trustedCert", certificateFromFile(trustedCert));
|
||||
/* Initialize TrustManager */
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(keyStore);
|
||||
return tmf.getTrustManagers();
|
||||
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
|
||||
throw new TlsException("Unable to initialize TrustManager", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read given certificate file to X.509 certificate.
|
||||
*
|
||||
* @param certFile Path to certificate file
|
||||
* @return X.509 Certificate object
|
||||
* @throws TlsException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
private X509Certificate certificateFromFile(Path certFile) throws TlsException {
|
||||
try (InputStream is = Files.newInputStream(certFile)) {
|
||||
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
|
||||
} catch (IOException | CertificateException e) {
|
||||
throw new TlsException("Unable to read certificate.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package de.stklcode.jvault.connector.factory;
|
||||
|
||||
import de.stklcode.jvault.connector.VaultConnector;
|
||||
import de.stklcode.jvault.connector.exception.VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Abstract Vault Connector Factory interface.
|
||||
|
Reference in New Issue
Block a user