-
Notifications
You must be signed in to change notification settings - Fork 25k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support PKCS#11 tokens as keystores and truststores #34063
Changes from 6 commits
9c18d80
6f6eb3a
430b998
8a0b64e
365d675
92248a1
5fda332
6dde2f7
2df67f4
c37c5e3
efe542c
60da02b
777554b
41c74ac
4ec50c6
ba90235
88f80c3
6604aa1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -400,8 +400,9 @@ The path to the Java Keystore file that contains a private key and certificate. | |
`ssl.key` and `ssl.keystore.path` may not be used at the same time. | ||
|
||
`ssl.keystore.type`:: | ||
The format of the keystore file. Should be either `jks` to use the Java | ||
Keystore format, or `PKCS12` to use PKCS#12 files. The default is `jks`. | ||
The format of the keystore file. Should be `jks` to use the Java | ||
Keystore format, `PKCS12` to use PKCS#12 files, or `PKCS11` to use a PKCS#11 token. | ||
The default is `jks`. | ||
|
||
`ssl.keystore.password`:: | ||
The password to the keystore. | ||
|
@@ -426,8 +427,9 @@ The password to the truststore. | |
The password to the truststore. | ||
|
||
`ssl.truststore.type`:: | ||
The format of the keystore file. Should be either `jks` to use the Java | ||
Keystore format, or `PKCS12` to use PKCS#12 files. The default is `jks`. | ||
The format of the keystore file. Should be `jks` to use the Java | ||
Keystore format, `PKCS12` to use PKCS#12 files, or `PKCS11` to use a PKCS#11 token. | ||
The default is `jks`. | ||
|
||
`ssl.verification_mode`:: | ||
Indicates the type of verification when using `ldaps` to protect against man | ||
|
@@ -649,8 +651,9 @@ The path to the Java Keystore file that contains a private key and certificate. | |
`ssl.key` and `ssl.keystore.path` cannot be used at the same time. | ||
|
||
`ssl.keystore.type`:: | ||
The format of the keystore file. Should be either `jks` to use the Java | ||
Keystore format, or `PKCS12` to use PKCS#12 files. The default is `jks`. | ||
The format of the keystore file. Should be `jks` to use the Java | ||
Keystore format, `PKCS12` to use PKCS#12 files, or `PKCS11` to use a PKCS#11 token. | ||
The default is `jks`. | ||
|
||
`ssl.truststore.password`:: | ||
The password to the truststore. | ||
|
@@ -664,8 +667,9 @@ The path to the Java Keystore file that contains the certificates to trust. | |
same time. | ||
|
||
`ssl.truststore.type`:: | ||
The format of the truststore file. Should be either `jks` to use the Java | ||
Keystore format, or `PKCS12` to use PKCS#12 files. The default is `jks`. | ||
The format of the truststore file. Should be `jks` to use the Java | ||
Keystore format, `PKCS12` to use PKCS#12 files, or `PKCS11` to use a PKCS#11 token. | ||
The default is `jks`. | ||
|
||
`ssl.verification_mode`:: | ||
Indicates the type of verification when using `ldaps` to protect against man | ||
|
@@ -1062,7 +1066,7 @@ Must be either a Java Keystore (jks) or a PKCS#12 file. | |
same time. | ||
|
||
`ssl.truststore.type`:: | ||
The type of the truststore (`ssl.truststore.path`). Must be either `jks` or | ||
The type of the truststore (`ssl.truststore.path`). Must be either `jks` or | ||
`PKCS12`. If the keystore path ends in ".p12", ".pfx" or "pkcs12", this setting | ||
defaults to `PKCS12`. Otherwise, it defaults to `jks`. | ||
|
||
|
@@ -1316,6 +1320,29 @@ a PKCS#12 container includes trusted certificate ("anchor") entries look for | |
`openssl pkcs12 -info` output, or `trustedCertEntry` in the | ||
`keytool -list` output. | ||
|
||
===== PKCS#11 tokens | ||
|
||
When using a PKCS#11 cryptographic token, which contain the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/contain/contains ? |
||
private key, certificate, and certificates that should be trusted, use | ||
the following settings: | ||
|
||
`xpack.ssl.keystore.type`:: | ||
Set this to `PKCS11`. | ||
|
||
`xpack.ssl.truststore.type`:: | ||
Set this to `PKCS11`. | ||
|
||
|
||
[[pkcs11-truststore-note]] | ||
[NOTE] | ||
When configuring the PKCS#11 token that your JVM is configured to use as | ||
a keystore or a truststore for Elasticsearch, the PIN for the token needs | ||
to be configured via the appropriate JVM setting (`-Djavax.net.ssl.trustStorePassword`). | ||
Since there can only be one PKCS#11 token configured, only one keystore and | ||
jaymode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
truststore will be usable for configuration in Elasticsearch. This in turn means | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/Elasticsearch/{es} |
||
that only one certificate can be used for TLS both in the transport and the | ||
http layer. | ||
|
||
[[http-tls-ssl-settings]] | ||
:ssl-prefix: xpack.security.http | ||
:component: HTTP | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,14 +7,21 @@ | |
|
||
import org.elasticsearch.ElasticsearchException; | ||
import org.elasticsearch.common.Nullable; | ||
import org.elasticsearch.common.settings.SecureString; | ||
import org.elasticsearch.env.Environment; | ||
import org.elasticsearch.xpack.core.ssl.cert.CertificateInfo; | ||
|
||
import javax.net.ssl.X509ExtendedTrustManager; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.security.GeneralSecurityException; | ||
import java.security.KeyStore; | ||
import java.security.KeyStoreException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.cert.CertificateException; | ||
import java.security.cert.X509Certificate; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
|
@@ -58,6 +65,38 @@ abstract class TrustConfig { | |
*/ | ||
public abstract int hashCode(); | ||
|
||
/** | ||
* Loads and returns the appropriate {@link KeyStore} for the given configuration. The KeyStore can be backed by a file | ||
* in any format that the Security Provider might support, or a cryptographic software or hardware token in the case | ||
* of a PKCS#11 Provider. | ||
* | ||
* @param environment the environment to resolve files against or null in the case of running in a transport client | ||
* @param storePath the path to the {@link KeyStore} to load, or null if a PKCS11 token is configured as the keystore/truststore | ||
* of the JVM | ||
* @param storeType the type of the {@link KeyStore} | ||
* @param storePassword the password to be used for decrypting the {@link KeyStore} | ||
* @return the loaded KeyStore to be used as a keystore or a truststore | ||
* @throws KeyStoreException if an instance of the specified type cannot be loaded | ||
* @throws CertificateException if any of the certificates in the keystore could not be loaded | ||
* @throws NoSuchAlgorithmException if the algorithm used to check the integrity of the keystore cannot be found | ||
* @throws IOException if there is an I/O issue with the KeyStore data or the password is incorrect | ||
*/ | ||
KeyStore getStore(@Nullable Environment environment, @Nullable String storePath, String storeType, SecureString storePassword) | ||
throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { | ||
if (null != storePath) { | ||
try (InputStream in = Files.newInputStream(CertParsingUtils.resolvePath(storePath, environment))) { | ||
KeyStore ks = KeyStore.getInstance(storeType); | ||
ks.load(in, storePassword.getChars()); | ||
return ks; | ||
} | ||
} else if (storeType.equalsIgnoreCase("pkcs11")) { | ||
KeyStore ks = KeyStore.getInstance(storeType); | ||
ks.load(null, storePassword.getChars()); | ||
return ks; | ||
} | ||
throw new IllegalArgumentException("keystore.path or truststore.path can only be empty when using a PKCS#11 token"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add unit tests for this method? At least one with an expectThrows for this IAE. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, thanks |
||
} | ||
|
||
/** | ||
* A trust configuration that is a combination of a trust configuration with the default JDK trust configuration. This trust | ||
* configuration returns a trust manager verifies certificates against both the default JDK trusted configurations and the specific | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for calling out PKCS11 in the settings is that the implementation now includes specific handling if this is set as the keystore.type ( As opposed to for instance
BCFKS
which can be used with the BouncyCastle FIPS Security Provider if configured, but handled transparently )