Skip to content

Commit

Permalink
NIFI-3490 added SAN option for TLS toolkit in standalone mode
Browse files Browse the repository at this point in the history
This closes apache#1530.

Signed-off-by: Andy LoPresto <[email protected]>
  • Loading branch information
pvillard31 authored and alopresto committed Mar 7, 2017
1 parent b7f946e commit bf112d0
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public TlsClientConfig(TlsConfig tlsConfig) {
setDnPrefix(tlsConfig.getDnPrefix());
setDnSuffix(tlsConfig.getDnSuffix());
setReorderDn(tlsConfig.getReorderDn());
setDomainAlternativeNames(tlsConfig.getDomainAlternativeNames());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public TlsCertificateAuthorityClientCommandLine(InputStreamFactory inputStreamFa
super(DESCRIPTION);
this.inputStreamFactory = inputStreamFactory;
addOptionWithArg("C", CERTIFICATE_DIRECTORY, "The file to write the CA certificate to", DEFAULT_CERTIFICATE_DIRECTORY);
addOptionWithArg("S", SUBJECT_ALTERNATIVE_NAMES, "Comma-separated list of domains to use as Subject Alternative Names in the certificate");
addOptionWithArg(null, SUBJECT_ALTERNATIVE_NAMES, "Comma-separated list of domains to use as Subject Alternative Names in the certificate");
}

public static void main(String[] args) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.nifi.toolkit.tls.standalone;

import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.security.util.CertificateUtils;
import org.apache.nifi.security.util.KeystoreType;
import org.apache.nifi.security.util.KeyStoreUtils;
Expand All @@ -29,6 +30,7 @@
import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
import org.apache.nifi.toolkit.tls.util.TlsHelper;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
import org.bouncycastle.util.io.pem.PemWriter;
import org.slf4j.Logger;
Expand Down Expand Up @@ -179,8 +181,10 @@ public void createNifiKeystoresAndTrustStores(StandaloneConfig standaloneConfig)
tlsClientConfig.setTrustStorePassword(instanceDefinition.getTrustStorePassword());
TlsClientManager tlsClientManager = new TlsClientManager(tlsClientConfig);
KeyPair keyPair = TlsHelper.generateKeyPair(keyPairAlgorithm, keySize);
Extensions sanDnsExtensions = StringUtils.isBlank(tlsClientConfig.getDomainAlternativeNames())
? null : TlsHelper.createDomainAlternativeNamesExtensions(tlsClientConfig.getDomainAlternativeNames());
tlsClientManager.addPrivateKeyToKeyStore(keyPair, NIFI_KEY, CertificateUtils.generateIssuedCertificate(tlsClientConfig.calcDefaultDn(hostname),
keyPair.getPublic(), null, certificate, caKeyPair, signingAlgorithm, days), certificate);
keyPair.getPublic(), sanDnsExtensions, certificate, caKeyPair, signingAlgorithm, days), certificate);
tlsClientManager.setCertificateEntry(NIFI_CERT, certificate);
tlsClientManager.addClientConfigurationWriter(new NifiPropertiesTlsClientConfigWriter(niFiPropertiesWriterFactory, new File(hostDir, "nifi.properties"),
hostname, instanceDefinition.getNumber()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.apache.commons.cli.CommandLine;
import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
Expand Down Expand Up @@ -58,6 +59,7 @@ public class TlsToolkitStandaloneCommandLine extends BaseCommandLine {
public static final String GLOBAL_PORT_SEQUENCE_ARG = "globalPortSequence";
public static final String NIFI_DN_PREFIX_ARG = "nifiDnPrefix";
public static final String NIFI_DN_SUFFIX_ARG = "nifiDnSuffix";
public static final String SUBJECT_ALTERNATIVE_NAMES = "subjectAlternativeNames";

public static final String DEFAULT_OUTPUT_DIRECTORY = calculateDefaultOutputDirectory(Paths.get("."));

Expand Down Expand Up @@ -86,6 +88,7 @@ protected static String calculateDefaultOutputDirectory(Path currentPath) {
private boolean overwrite;
private String dnPrefix;
private String dnSuffix;
private String domainAlternativeNames;

public TlsToolkitStandaloneCommandLine() {
this(new PasswordUtil());
Expand All @@ -104,6 +107,7 @@ protected TlsToolkitStandaloneCommandLine(PasswordUtil passwordUtil) {
addOptionWithArg("B", CLIENT_CERT_PASSWORD_ARG, "Password for client certificate. Must either be one value or one for each client DN. (autogenerate if not specified)");
addOptionWithArg("G", GLOBAL_PORT_SEQUENCE_ARG, "Use sequential ports that are calculated for all hosts according to the provided hostname expressions. " +
"(Can be specified multiple times, MUST BE SAME FROM RUN TO RUN.)");
addOptionWithArg(null, SUBJECT_ALTERNATIVE_NAMES, "Comma-separated list of domains to use as Subject Alternative Names in the certificate");
addOptionWithArg(null, NIFI_DN_PREFIX_ARG, "String to prepend to hostname(s) when determining DN.", TlsConfig.DEFAULT_DN_PREFIX);
addOptionWithArg(null, NIFI_DN_SUFFIX_ARG, "String to append to hostname(s) when determining DN.", TlsConfig.DEFAULT_DN_SUFFIX);
addOptionNoArg("O", OVERWRITE_ARG, "Overwrite existing host output.");
Expand Down Expand Up @@ -133,6 +137,7 @@ protected CommandLine doParse(String... args) throws CommandLineParseException {

dnPrefix = commandLine.getOptionValue(NIFI_DN_PREFIX_ARG, TlsConfig.DEFAULT_DN_PREFIX);
dnSuffix = commandLine.getOptionValue(NIFI_DN_SUFFIX_ARG, TlsConfig.DEFAULT_DN_SUFFIX);
domainAlternativeNames = commandLine.getOptionValue(SUBJECT_ALTERNATIVE_NAMES);

Stream<String> globalOrderExpressions = null;
if (commandLine.hasOption(GLOBAL_PORT_SEQUENCE_ARG)) {
Expand Down Expand Up @@ -228,6 +233,7 @@ public StandaloneConfig createConfig() {
standaloneConfig.setDays(getDays());
standaloneConfig.setDnPrefix(dnPrefix);
standaloneConfig.setDnSuffix(dnSuffix);
standaloneConfig.setDomainAlternativeNames(domainAlternativeNames);
standaloneConfig.initDefaults();

return standaloneConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
Expand Down Expand Up @@ -198,15 +201,7 @@ public static JcaPKCS10CertificationRequest generateCertificationRequest(String
// add Subject Alternative Name(s)
if(StringUtils.isNotBlank(domainAlternativeNames)) {
try {
List<GeneralName> namesList = new ArrayList<>();
for(String alternativeName : domainAlternativeNames.split(",")) {
namesList.add(new GeneralName(GeneralName.dNSName, alternativeName));
}

GeneralNames subjectAltNames = new GeneralNames(namesList.toArray(new GeneralName [] {}));
ExtensionsGenerator extGen = new ExtensionsGenerator();
extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
jcaPKCS10CertificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
jcaPKCS10CertificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, createDomainAlternativeNamesExtensions(domainAlternativeNames));
} catch (IOException e) {
throw new OperatorCreationException("Error while adding " + domainAlternativeNames + " as Subject Alternative Name.", e);
}
Expand All @@ -215,4 +210,17 @@ public static JcaPKCS10CertificationRequest generateCertificationRequest(String
JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm);
return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate())));
}

public static Extensions createDomainAlternativeNamesExtensions(String domainAlternativeNames) throws IOException {
List<GeneralName> namesList = new ArrayList<>();
for(String alternativeName : domainAlternativeNames.split(",")) {
namesList.add(new GeneralName(GeneralName.dNSName, alternativeName));
}

GeneralNames subjectAltNames = new GeneralNames(namesList.toArray(new GeneralName [] {}));
ExtensionsGenerator extGen = new ExtensionsGenerator();
extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
return extGen.generate();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ public void testSigningAlgorithm() throws CommandLineParseException, IOException
assertEquals(testSigningAlgorithm, tlsToolkitStandaloneCommandLine.createConfig().getSigningAlgorithm());
}

@Test
public void testSAN() throws CommandLineParseException, IOException {
String dnsSAN = "nifi.apache.org";
tlsToolkitStandaloneCommandLine.parse("--subjectAlternativeNames", dnsSAN);
assertEquals(dnsSAN, tlsToolkitStandaloneCommandLine.createConfig().getDomainAlternativeNames());
}

@Test
public void testDaysNotInteger() {
try {
Expand Down

0 comments on commit bf112d0

Please sign in to comment.