
com.floragunn.searchguard.tools.tlstool.tasks.CreateNodeCertificate Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of search-guard-tlstool Show documentation
Show all versions of search-guard-tlstool Show documentation
SSL/TLS certificate generation and validation tool for Search Guard
The newest version!
/*
* Copyright 2017-2018 floragunn GmbH
*
* 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 com.floragunn.searchguard.tools.tlstool.tasks;
import java.io.File;
import java.security.KeyPair;
import java.util.Date;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.CertIOException;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import com.floragunn.searchguard.tools.tlstool.Config;
import com.floragunn.searchguard.tools.tlstool.Context;
import com.floragunn.searchguard.tools.tlstool.ToolException;
public class CreateNodeCertificate extends CreateNodeCertificateBase {
private static int generatedCertificateCount = 0;
private static boolean passwordAutoGenerated = false;
private Config.Node nodeConfig;
private File certificateFile;
private File httpCertificateFile;
public CreateNodeCertificate(Context ctx, Config.Node nodeConfig) {
super(ctx, nodeConfig);
this.nodeConfig = nodeConfig;
}
@Override
public void run() throws ToolException {
privateKeyFile = new File(ctx.getTargetDirectory(), getNodeFileName(nodeConfig) + ".key");
certificateFile = new File(ctx.getTargetDirectory(), getNodeFileName(nodeConfig) + ".pem");
httpPrivateKeyFile = new File(ctx.getTargetDirectory(), getNodeFileName(nodeConfig) + "_http.key");
httpCertificateFile = new File(ctx.getTargetDirectory(), getNodeFileName(nodeConfig) + "_http.pem");
configSnippetFile = new File(ctx.getTargetDirectory(),
getNodeFileName(nodeConfig) + "_elasticsearch_config_snippet.yml");
if (!checkFileOverwrite("certificate", nodeConfig.getDn(), privateKeyFile, certificateFile, httpPrivateKeyFile,
httpCertificateFile)) {
return;
}
createTransportCertificate();
if (ctx.getConfig().getDefaults().isHttpsEnabled()) {
if (ctx.getConfig().getDefaults().isReuseTransportCertificatesForHttp()) {
addTransportCertificateToConfigAsHttpCertificate();
} else {
createRestCertificate();
}
} else {
nodeResultConfig.setHttpsEnabled(false);
}
addOutputFile(configSnippetFile, createConfigSnippetComment(), createConfigSnippet());
}
private String createConfigSnippetComment() {
return "# This is a configuration snippet for the node " + getNodeFileName(nodeConfig) + "\n"
+ "# This snippet needs to be inserted into the file config/elasticsearch.yml of the respective node.\n"
+ "# If the config file already contains SearchGuard configuration, this needs to be replaced.\n"
+ "# Furthermore, you need to copy the files referenced below into the same directory.\n"
+ "# Please refer to http://docs.search-guard.com/latest/configuring-tls for further configuration of your installation.\n\n\n";
}
private void createTransportCertificate() throws ToolException {
try {
KeyPair nodeKeyPair = generateKeyPair(nodeConfig);
SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(nodeKeyPair.getPublic().getEncoded());
X500Name subjectName = createDn(nodeConfig.getDn(), "node");
Date validityStartDate = new Date(System.currentTimeMillis());
Date validityEndDate = getEndDate(validityStartDate, nodeConfig.getValidityDays());
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(ctx.getSigningCertificate().getSubject(),
ctx.nextId(), validityStartDate, validityEndDate, subjectName, subPubKeyInfo);
JcaX509ExtensionUtils extUtils = getExtUtils();
builder.addExtension(Extension.authorityKeyIdentifier, false,
extUtils.createAuthorityKeyIdentifier(ctx.getSigningCertificate()))
.addExtension(Extension.subjectKeyIdentifier, false,
extUtils.createSubjectKeyIdentifier(nodeKeyPair.getPublic()))
.addExtension(Extension.basicConstraints, true, new BasicConstraints(false))
.addExtension(Extension.keyUsage, true,
new KeyUsage(
KeyUsage.digitalSignature | KeyUsage.nonRepudiation | KeyUsage.keyEncipherment))
.addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(
new KeyPurposeId[] { KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth }));
builder.addExtension(Extension.subjectAlternativeName, false,
new DERSequence(createSubjectAlternativeNameList(true)));
X509CertificateHolder nodeCertificate = builder
.build(new JcaContentSignerBuilder(ctx.getConfig().getDefaults().getSignatureAlgorithm())
.setProvider(ctx.getSecurityProvider()).build(ctx.getSigningPrivateKey()));
String privateKeyPassword = getPassword(nodeConfig.getPkPassword());
addEncryptedOutputFile(privateKeyFile, privateKeyPassword, nodeKeyPair.getPrivate());
if (ctx.getConfig().getCa().getIntermediate() == null) {
addOutputFile(certificateFile, nodeCertificate);
} else {
addOutputFile(certificateFile, nodeCertificate, ctx.getSigningCertificate());
}
nodeResultConfig.setTransportPemCertFilePath(certificateFile.getName());
nodeResultConfig.setTransportPemKeyFilePath(privateKeyFile.getName());
nodeResultConfig.setTransportPemKeyPassword(privateKeyPassword);
nodeResultConfig.setTransportPemTrustedCasFilePath(ctx.getRootCaFile().getName());
generatedCertificateCount++;
if (isPasswordAutoGenerationEnabled(nodeConfig.getPkPassword())) {
passwordAutoGenerated = true;
}
} catch (CertIOException | OperatorCreationException e) {
throw new ToolException("Error while composing certificate for " + nodeConfig, e);
}
}
private void createRestCertificate() throws ToolException {
try {
KeyPair nodeKeyPair = generateKeyPair(nodeConfig);
SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(nodeKeyPair.getPublic().getEncoded());
X500Name subjectName = createDn(nodeConfig.getDn(), "node");
Date validityStartDate = new Date(System.currentTimeMillis());
Date validityEndDate = getEndDate(validityStartDate, nodeConfig.getValidityDays());
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(ctx.getSigningCertificate().getSubject(),
ctx.nextId(), validityStartDate, validityEndDate, subjectName, subPubKeyInfo);
JcaX509ExtensionUtils extUtils = getExtUtils();
builder.addExtension(Extension.authorityKeyIdentifier, false,
extUtils.createAuthorityKeyIdentifier(ctx.getSigningCertificate()))
.addExtension(Extension.subjectKeyIdentifier, false,
extUtils.createSubjectKeyIdentifier(nodeKeyPair.getPublic()))
.addExtension(Extension.basicConstraints, true, new BasicConstraints(false))
.addExtension(Extension.keyUsage, true,
new KeyUsage(
KeyUsage.digitalSignature | KeyUsage.nonRepudiation | KeyUsage.keyEncipherment))
.addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(
new KeyPurposeId[] { KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth }));
builder.addExtension(Extension.subjectAlternativeName, false,
new DERSequence(createSubjectAlternativeNameList(false)));
X509CertificateHolder nodeCertificate = builder
.build(new JcaContentSignerBuilder(ctx.getConfig().getDefaults().getSignatureAlgorithm())
.setProvider(ctx.getSecurityProvider()).build(ctx.getSigningPrivateKey()));
String privateKeyPassword = getPassword(nodeConfig.getPkPassword());
addEncryptedOutputFile(httpPrivateKeyFile, privateKeyPassword, nodeKeyPair.getPrivate());
if (ctx.getConfig().getCa().getIntermediate() == null) {
addOutputFile(httpCertificateFile, nodeCertificate);
} else {
addOutputFile(httpCertificateFile, nodeCertificate, ctx.getSigningCertificate());
}
nodeResultConfig.setHttpPemCertFilePath(httpCertificateFile.getName());
nodeResultConfig.setHttpPemKeyFilePath(httpPrivateKeyFile.getName());
nodeResultConfig.setHttpPemKeyPassword(privateKeyPassword);
nodeResultConfig.setHttpPemTrustedCasFilePath(ctx.getRootCaFile().getName());
generatedCertificateCount++;
if (isPasswordAutoGenerationEnabled(nodeConfig.getPkPassword())) {
passwordAutoGenerated = true;
}
} catch (CertIOException | OperatorCreationException e) {
throw new ToolException("Error while composing HTTP certificate for " + nodeConfig, e);
}
}
private void addTransportCertificateToConfigAsHttpCertificate() {
nodeResultConfig.setHttpPemCertFilePath(nodeResultConfig.getTransportPemCertFilePath());
nodeResultConfig.setHttpPemKeyFilePath(nodeResultConfig.getTransportPemKeyFilePath());
nodeResultConfig.setHttpPemKeyPassword(nodeResultConfig.getTransportPemKeyPassword());
nodeResultConfig.setHttpPemTrustedCasFilePath(nodeResultConfig.getTransportPemTrustedCasFilePath());
}
public static int getGeneratedCertificateCount() {
return generatedCertificateCount;
}
public static boolean isPasswordAutoGenerated() {
return passwordAutoGenerated;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy