Commit 4d7cc835 authored by Nils Bandener's avatar Nils Bandener
Browse files

Merge branch 'revert-4da8f5f0' into 'master'

Revert "Merge branch 'pkcs1-support' into 'master'"

See merge request search-guard/search-guard-suite!82
parents 4da8f5f0 248ed19e
floragunn GmbH
Copyright 2015-2020 floragunn GmbH
Copyright 2015-2017 floragunn GmbH
This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).
......@@ -10,7 +10,4 @@ This product includes software developed by The Legion of the Bouncy Castle Inc.
This product includes software developed by Amazon.com, Inc.
(https://github.com/opendistro-for-elasticsearch/security)
This product includes software developed by AOL Inc. and Groovenauts, Inc.
(https://github.com/groovenauts/jmeter_oauth_plugin)
See THIRD-PARTY.txt for additional third party licenses used by this product.
\ No newline at end of file
......@@ -68,12 +68,6 @@
<artifactId>bcpg-jdk15on</artifactId>
<version>${bc.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>${bc.version}</version>
</dependency>
<!-- provided scoped deps -->
<dependency>
......
......@@ -95,10 +95,10 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
private SslContext transportServerSslContext;
private SslContext transportClientSslContext;
private X509Certificate[] currentTransportCerts;
private X509Certificate[] currentHttpCerts;
private X509Certificate[] currentTransportTrustedCerts;
private X509Certificate[] currentHttpTrustedCerts;
private X509Certificate[] transportCerts;
private X509Certificate[] httpCerts;
private X509Certificate[] transportTrustedCerts;
private X509Certificate[] httpTrustedCerts;
private final Environment env;
......@@ -336,15 +336,15 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
throw new ElasticsearchException("No truststore configured for server");
}
onNewCerts("Transport", currentTransportCerts, transportKeystoreCert, currentTransportTrustedCerts, trustedTransportCertificates);
onNewCerts("Transport", transportCerts, transportKeystoreCert, transportTrustedCerts, trustedTransportCertificates);
transportServerSslContext = buildSSLServerContext(transportKeystoreKey, transportKeystoreCert,
trustedTransportCertificates, getEnabledSSLCiphers(this.sslTransportServerProvider, false),
this.sslTransportServerProvider, ClientAuth.REQUIRE);
transportClientSslContext = buildSSLClientContext(transportKeystoreKey, transportKeystoreCert,
trustedTransportCertificates, getEnabledSSLCiphers(sslTransportClientProvider, false),
sslTransportClientProvider);
setCurrentTransportSSLCerts(transportKeystoreCert);
setCurrentTransportTrustedCerts(trustedTransportCertificates);
setTransportSSLCerts(transportKeystoreCert);
} catch (final Exception e) {
logExplanation(e);
......@@ -354,45 +354,28 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
} else if (rawPemCertFilePath != null) {
//file path to the pem encoded X509 certificate including its chain (which *may* include the root certificate but,
//if there any intermediates, must contain them)
final String pemTransportCertFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMCERT_FILEPATH,
final String pemCertFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMCERT_FILEPATH,
true);
//file path for the pem encoded PKCS1 or PKCS8 key for the certificate
final String pemTransportKeyFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_FILEPATH, true);
//file path to the pem encoded X509 root certificate (or multiple certificates if we should trust more than one root)
final String pemTransportTrustedCasFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH,
final String pemKey = resolve(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_FILEPATH, true);
final String trustedCas = resolve(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH,
true);
try {
//X509 certificate including its chain (which *may* include the root certificate but,
//if there any intermediates, must contain them)
final X509Certificate[] transportCertsChain = PemKeyReader.loadCertificatesFromFile(pemTransportCertFilePath);
//root certificate (or multiple certificates if we should trust more than one root)
final X509Certificate[] transportTrustedCaCerts = pemTransportTrustedCasFilePath != null ? PemKeyReader.loadCertificatesFromFile(pemTransportTrustedCasFilePath) : null;
//maybe null id the private key is not encrypted
final String pemKeyPassword = settings.get(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_PASSWORD);
//PKCS1 or PKCS8 key for the certificate
final PrivateKey transportCertPrivateKey = PemKeyReader.loadKeyFromFile(pemKeyPassword, pemTransportKeyFilePath);
onNewCerts("Transport", currentTransportCerts, transportCertsChain, currentTransportTrustedCerts, transportTrustedCaCerts);
//The server needs to send its certificate including its chain (which *may* contain the root cert) to the client
transportServerSslContext = buildSSLServerContext(transportCertPrivateKey, transportCertsChain, transportTrustedCaCerts,
final File pemKeyFile = new File(pemKey);
final File pemCertFile = new File(pemCertFilePath);
final File trustedCasFile = new File(trustedCas);
final X509Certificate[] transportKeystoreCerts = new X509Certificate[]{ PemKeyReader.loadCertificateFromFile(pemCertFilePath) };
X509Certificate[] newTrustedCerts = trustedCas != null ? PemKeyReader.loadCertificatesFromFile(trustedCas) : null;
onNewCerts("Transport", transportCerts, transportKeystoreCerts, transportTrustedCerts, newTrustedCerts);
transportServerSslContext = buildSSLServerContext(pemKeyFile, pemCertFile, trustedCasFile,
settings.get(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_PASSWORD),
getEnabledSSLCiphers(this.sslTransportServerProvider, false),
this.sslTransportServerProvider, ClientAuth.REQUIRE);
//The client needs to send its certificate including its chain (which *may* contain the root cert) to the server
transportClientSslContext = buildSSLClientContext(transportCertPrivateKey, transportCertsChain, transportTrustedCaCerts,
transportClientSslContext = buildSSLClientContext(pemKeyFile, pemCertFile, trustedCasFile,
settings.get(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_PASSWORD),
getEnabledSSLCiphers(sslTransportClientProvider, false), sslTransportClientProvider);
setCurrentTransportSSLCerts(transportCertsChain);
setCurrentTransportTrustedCerts(transportTrustedCaCerts);
setTransportSSLCerts(transportKeystoreCerts);
} catch (final Exception e) {
logExplanation(e);
throw new ElasticsearchSecurityException(
......@@ -498,11 +481,10 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
trustedHTTPCertificates = SSLCertificateHelper.exportRootCertificates(ts, truststoreAlias);
}
onNewCerts("HTTP", currentHttpCerts, httpKeystoreCert, currentHttpTrustedCerts, trustedHTTPCertificates);
onNewCerts("HTTP", httpCerts, httpKeystoreCert, httpTrustedCerts, trustedHTTPCertificates);
httpSslContext = buildSSLServerContext(httpKeystoreKey, httpKeystoreCert, trustedHTTPCertificates,
getEnabledSSLCiphers(this.sslHTTPProvider, true), sslHTTPProvider, httpClientAuthMode);
setCurrentHttpSSLCerts(httpKeystoreCert);
setCurrentHttpTrustedCerts(trustedHTTPCertificates);
setHttpSSLCerts(httpKeystoreCert);
} catch (final Exception e) {
logExplanation(e);
......@@ -511,45 +493,26 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
}
} else if (rawPemCertFilePath != null) {
//file path to the pem encoded X509 certificate including its chain (which *may* include the root certificate but,
//if there any intermediates, must contain them)
final String pemHttpCertFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMCERT_FILEPATH,
true);
//file path for the pem encoded PKCS1 or PKCS8 key for the certificate
final String pemHttpKeyFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMKEY_FILEPATH, true);
//file path to the pem encoded X509 root certificate (or multiple certificates if we should trust more than one root)
final String pemHttpTrustedCasFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH,
true);
final String trustedCas = resolve(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH,
false);
if (httpClientAuthMode == ClientAuth.REQUIRE) {
checkPath(pemHttpTrustedCasFilePath, SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH);
checkPath(trustedCas, SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMTRUSTEDCAS_FILEPATH);
}
try {
//X509 certificate including its chain (which *may* include the root certificate but,
//if there any intermediates, must contain them)
final X509Certificate[] httpCertsChain = PemKeyReader.loadCertificatesFromFile(pemHttpCertFilePath);
final String pemCertFilePath = resolve(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMCERT_FILEPATH, true);
final String pemKey = resolve(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMKEY_FILEPATH, true);
final X509Certificate[] httpKeystoreCert = new X509Certificate[]{ PemKeyReader.loadCertificateFromFile(pemCertFilePath) };
X509Certificate[] newHttpTrustedCerts = trustedCas != null ? PemKeyReader.loadCertificatesFromFile(trustedCas) : null;
//root certificate (or multiple certificates if we should trust more than one root)
final X509Certificate[] httpTrustedCaCerts = pemHttpTrustedCasFilePath != null ? PemKeyReader.loadCertificatesFromFile(pemHttpTrustedCasFilePath) : null;
//maybe null id the private key is not encrypted
final String pemKeyPassword = settings.get(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMKEY_PASSWORD);
//PKCS1 or PKCS8 key for the certificate
final PrivateKey httpCertPrivateKey = PemKeyReader.loadKeyFromFile(pemKeyPassword, pemHttpKeyFilePath);
onNewCerts("HTTP", currentHttpCerts,
httpCertsChain, currentHttpTrustedCerts, httpTrustedCaCerts);
httpSslContext = buildSSLServerContext(httpCertPrivateKey, httpCertsChain,
httpTrustedCaCerts,
onNewCerts("HTTP", httpCerts,
httpKeystoreCert, httpTrustedCerts, newHttpTrustedCerts);
httpSslContext = buildSSLServerContext(new File(pemKey), new File(pemCertFilePath),
trustedCas == null ? null : new File(trustedCas),
settings.get(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_PEMKEY_PASSWORD),
getEnabledSSLCiphers(this.sslHTTPProvider, true), sslHTTPProvider, httpClientAuthMode);
setCurrentHttpSSLCerts(httpCertsChain);
setCurrentHttpTrustedCerts(httpTrustedCaCerts);
setHttpSSLCerts(httpKeystoreCert);
this.httpTrustedCerts = newHttpTrustedCerts;
} catch (final Exception e) {
......@@ -649,30 +612,22 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
return sslTransportClientProvider == null ? null : sslTransportClientProvider.toString();
}
private void setCurrentHttpSSLCerts(X509Certificate[] httpKeystoreCert) {
currentHttpCerts = httpKeystoreCert;
private void setHttpSSLCerts(X509Certificate[] httpKeystoreCert) {
httpCerts = httpKeystoreCert;
}
@Override
public X509Certificate[] getHttpCerts() {
return currentHttpCerts;
return httpCerts;
}
@Override
public X509Certificate[] getTransportCerts() {
return currentTransportCerts;
return transportCerts;
}
private void setCurrentTransportSSLCerts(X509Certificate[] transportKeystoreCert) {
currentTransportCerts = transportKeystoreCert;
}
private void setCurrentHttpTrustedCerts(X509Certificate[] httpTrustedCerts) {
this.currentHttpTrustedCerts = httpTrustedCerts;
}
private void setCurrentTransportTrustedCerts(X509Certificate[] transportTrustedCerts) {
this.currentTransportTrustedCerts = transportTrustedCerts;
private void setTransportSSLCerts(X509Certificate[] transportKeystoreCert) {
transportCerts = transportKeystoreCert;
}
private void logOpenSSLInfos() {
......@@ -846,6 +801,22 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
return buildSSLContext0(_sslContextBuilder);
}
private SslContext buildSSLServerContext(final File _key, final File _cert, final File _trustedCerts,
final String pwd, final Iterable<String> ciphers, final SslProvider sslProvider, final ClientAuth authMode)
throws SSLException {
final SslContextBuilder _sslContextBuilder = SslContextBuilder.forServer(_cert, _key, pwd).ciphers(ciphers)
.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED)
.clientAuth(Objects.requireNonNull(authMode)) // https://github.com/netty/netty/issues/4722
.sessionCacheSize(0).sessionTimeout(0).sslProvider(sslProvider);
if (_trustedCerts != null) {
_sslContextBuilder.trustManager(_trustedCerts);
}
return buildSSLContext0(_sslContextBuilder);
}
private SslContext buildSSLClientContext(final PrivateKey _key, final X509Certificate[] _cert,
final X509Certificate[] _trustedCerts, final Iterable<String> ciphers, final SslProvider sslProvider)
throws SSLException {
......@@ -858,6 +829,17 @@ public class DefaultSearchGuardKeyStore implements SearchGuardKeyStore {
}
private SslContext buildSSLClientContext(final File _key, final File _cert, final File _trustedCerts,
final String pwd, final Iterable<String> ciphers, final SslProvider sslProvider) throws SSLException {
final SslContextBuilder _sslClientContextBuilder = SslContextBuilder.forClient().ciphers(ciphers)
.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED).sessionCacheSize(0).sessionTimeout(0)
.sslProvider(sslProvider).trustManager(_trustedCerts).keyManager(_cert, _key, pwd);
return buildSSLContext0(_sslClientContextBuilder);
}
private SslContext buildSSLContext0(final SslContextBuilder sslContextBuilder) throws SSLException {
final SecurityManager sm = System.getSecurityManager();
......
......@@ -27,7 +27,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.ImmutableMap;
import org.apache.logging.log4j.LogManager;
......@@ -79,7 +78,6 @@ public class SearchGuardSSLInfoAction extends BaseRestHandler {
final Boolean showDn = request.paramAsBoolean("show_dn", Boolean.FALSE);
final Boolean showServerCerts = request.paramAsBoolean("show_server_certs", Boolean.FALSE);
final Boolean showFullServerCerts = request.paramAsBoolean("show_full_server_certs", Boolean.FALSE);
@Override
public void accept(RestChannel channel) throws Exception {
......@@ -122,10 +120,10 @@ public class SearchGuardSSLInfoAction extends BaseRestHandler {
builder.field("ssl_openssl_supports_hostname_validation", false);
}
if (showServerCerts == Boolean.TRUE || showFullServerCerts == Boolean.TRUE) {
if (showServerCerts == Boolean.TRUE) {
if (sgks != null) {
builder.field("http_certificates_list", generateCertDetailList(sgks.getHttpCerts(), showFullServerCerts));
builder.field("transport_certificates_list", generateCertDetailList(sgks.getTransportCerts(), showFullServerCerts));
builder.field("http_certificates_list", generateCertDetailList(sgks.getHttpCerts()));
builder.field("transport_certificates_list", generateCertDetailList(sgks.getTransportCerts()));
} else {
builder.field("message", "keystore is not initialized");
}
......@@ -155,15 +153,12 @@ public class SearchGuardSSLInfoAction extends BaseRestHandler {
};
}
private List<Map<String, String>> generateCertDetailList(final X509Certificate[] certs, final boolean fullChain) {
private List<Map<String, String>> generateCertDetailList(final X509Certificate[] certs) {
if (certs == null) {
return null;
}
return Arrays
.stream(certs)
.limit(fullChain?certs.length:1)
.map(cert -> {
return Arrays.stream(certs)
.map(cert -> {
final String issuerDn = cert != null && cert.getIssuerX500Principal() != null ? cert.getIssuerX500Principal().getName(): "";
final String subjectDn = cert != null && cert.getSubjectX500Principal() != null ? cert.getSubjectX500Principal().getName(): "";
......
......@@ -6,13 +6,16 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCSException;
import javax.crypto.NoSuchPaddingException;
import com.floragunn.searchguard.support.PemKeyReader;
......@@ -69,7 +72,8 @@ public class ClientAuthCredentials {
return certKeyPem(in, password);
} catch (FileNotFoundException e) {
throw new GenericSSLConfigException("Could not find certificate key file " + file, e);
} catch (IOException e) {
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeySpecException | InvalidAlgorithmParameterException | KeyException
| IOException e) {
throw new GenericSSLConfigException("Error while reading certificate key file " + file, e);
}
}
......@@ -78,12 +82,9 @@ public class ClientAuthCredentials {
return certKeyPem(path.toFile(), password);
}
public Builder certKeyPem(InputStream inputStream, String password) throws GenericSSLConfigException {
try {
authenticationKey = PemKeyReader.toPrivateKey(inputStream, password);
} catch (OperatorCreationException | IOException | PKCSException e) {
throw new GenericSSLConfigException("Could not load private key", e);
}
public Builder certKeyPem(InputStream inputStream, String password) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException {
authenticationKey = PemKeyReader.toPrivateKey(inputStream, password);
return this;
}
......
......@@ -17,48 +17,112 @@
package com.floragunn.searchguard.support;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyException;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.bc.BcPEMDecryptorProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
import org.bouncycastle.operator.InputDecryptorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException;
import org.bouncycastle.util.encoders.Base64;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
public final class PemKeyReader {
//private static final String[] EMPTY_STRING_ARRAY = new String[0];
protected static final Logger log = LogManager.getLogger(PemKeyReader.class);
static final String JKS = "JKS";
static final String PKCS12 = "PKCS12";
private static final Pattern KEY_PATTERN = Pattern.compile(
"-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+" + // Header
"([a-z0-9+/=\\r\\n]+)" + // Base64 text
"-+END\\s+.*PRIVATE\\s+KEY[^-]*-+", // Footer
Pattern.CASE_INSENSITIVE);
private static byte[] readPrivateKey(File file) throws KeyException {
try {
InputStream in = new FileInputStream(file);
try {
return readPrivateKey(in);
} finally {
safeClose(in);
}
} catch (FileNotFoundException e) {
throw new KeyException("could not fine key file: " + file);
}
}
private static byte[] readPrivateKey(InputStream in) throws KeyException {
String content;
try {
content = readContent(in);
} catch (IOException e) {
throw new KeyException("failed to read key input stream", e);
}
Matcher m = KEY_PATTERN.matcher(content);
if (!m.find()) {
throw new KeyException("could not find a PKCS #8 private key in input stream" +
" (see http://netty.io/wiki/sslcontextbuilder-and-private-key.html for more information)");
}
return Base64.decode(m.group(1));
}
private static String readContent(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
byte[] buf = new byte[8192];
for (;;) {
int ret = in.read(buf);
if (ret < 0) {
break;
}
out.write(buf, 0, ret);
}
return out.toString(StandardCharsets.US_ASCII.name());
} finally {
safeClose(out);
}
}
private static void safeClose(InputStream in) {
try {
......@@ -67,56 +131,67 @@ public final class PemKeyReader {
//ignore
}
}
private static void safeClose(OutputStream out) {
try {
out.close();
} catch (IOException e) {
//ignore
}
}
public static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws IOException, OperatorCreationException, PKCSException {
public static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException {
if (keyFile == null) {
return null;
}
InputStream in = new FileInputStream(keyFile);
try {
return getPrivateKeyFromByteBuffer(in, keyPassword);
} finally {
safeClose(in);
}
return getPrivateKeyFromByteBuffer(PemKeyReader.readPrivateKey(keyFile), keyPassword);
}
public static PrivateKey toPrivateKey(InputStream in, String keyPassword) throws IOException, OperatorCreationException, PKCSException {
public static PrivateKey toPrivateKey(InputStream in, String keyPassword) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException {
if (in == null) {
return null;
}
return getPrivateKeyFromByteBuffer(in, keyPassword);
return getPrivateKeyFromByteBuffer(PemKeyReader.readPrivateKey(in), keyPassword);
}
//return null if there is no private key found in InputStream
private static PrivateKey getPrivateKeyFromByteBuffer(InputStream in, String keyPassword) throws IOException, OperatorCreationException, PKCSException {
private static PrivateKey getPrivateKeyFromByteBuffer(byte[] encodedKey, String keyPassword) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException {
final JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
try(final PEMParser pemParser = new PEMParser(new InputStreamReader(in, StandardCharsets.US_ASCII))) {
final Object object = pemParser.readObject();
PKCS8EncodedKeySpec encodedKeySpec = generateKeySpec(keyPassword == null ? null : keyPassword.toCharArray(), encodedKey);
try {
return KeyFactory.getInstance("RSA").generatePrivate(encodedKeySpec);
} catch (InvalidKeySpecException ignore) {
try {
return KeyFactory.getInstance("DSA").generatePrivate(encodedKeySpec);
} catch (InvalidKeySpecException ignore2) {
try {
return KeyFactory.getInstance("EC").generatePrivate(encodedKeySpec);
} catch (InvalidKeySpecException e) {
throw new InvalidKeySpecException("Neither RSA, DSA nor EC worked", e);
}
}
}
}
private static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException,
InvalidKeyException, InvalidAlgorithmParameterException {
if(object == null) {
return null;
} else if(object instanceof PEMKeyPair) {
return converter.getKeyPair((PEMKeyPair) object).getPrivate();