NIFI-4222 - Adding CN by default in SANs for generated certificates with tls-toolkit

This closes #2042.

Signed-off-by: Andy LoPresto <alopresto@apache.org>
This commit is contained in:
Pierre Villard 2017-07-29 12:38:14 +02:00 committed by Andy LoPresto
parent 9c4fdd4ef3
commit 9f1267e949
No known key found for this signature in database
GPG Key ID: 6EC293152D90B61D
3 changed files with 25 additions and 13 deletions

View File

@ -17,7 +17,6 @@
package org.apache.nifi.toolkit.tls.standalone; 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.CertificateUtils;
import org.apache.nifi.security.util.KeystoreType; import org.apache.nifi.security.util.KeystoreType;
import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.security.util.KeyStoreUtils;
@ -181,8 +180,7 @@ public class TlsToolkitStandalone {
tlsClientConfig.setTrustStorePassword(instanceDefinition.getTrustStorePassword()); tlsClientConfig.setTrustStorePassword(instanceDefinition.getTrustStorePassword());
TlsClientManager tlsClientManager = new TlsClientManager(tlsClientConfig); TlsClientManager tlsClientManager = new TlsClientManager(tlsClientConfig);
KeyPair keyPair = TlsHelper.generateKeyPair(keyPairAlgorithm, keySize); KeyPair keyPair = TlsHelper.generateKeyPair(keyPairAlgorithm, keySize);
Extensions sanDnsExtensions = StringUtils.isBlank(tlsClientConfig.getDomainAlternativeNames()) Extensions sanDnsExtensions = TlsHelper.createDomainAlternativeNamesExtensions(tlsClientConfig.getDomainAlternativeNames(), tlsClientConfig.calcDefaultDn(hostname));
? null : TlsHelper.createDomainAlternativeNamesExtensions(tlsClientConfig.getDomainAlternativeNames());
tlsClientManager.addPrivateKeyToKeyStore(keyPair, NIFI_KEY, CertificateUtils.generateIssuedCertificate(tlsClientConfig.calcDefaultDn(hostname), tlsClientManager.addPrivateKeyToKeyStore(keyPair, NIFI_KEY, CertificateUtils.generateIssuedCertificate(tlsClientConfig.calcDefaultDn(hostname),
keyPair.getPublic(), sanDnsExtensions, certificate, caKeyPair, signingAlgorithm, days), certificate); keyPair.getPublic(), sanDnsExtensions, certificate, caKeyPair, signingAlgorithm, days), certificate);
tlsClientManager.setCertificateEntry(NIFI_CERT, certificate); tlsClientManager.setCertificateEntry(NIFI_CERT, certificate);

View File

@ -42,6 +42,8 @@ import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.ExtensionsGenerator;
@ -199,22 +201,30 @@ public class TlsHelper {
JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name(requestedDn), keyPair.getPublic()); JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Name(requestedDn), keyPair.getPublic());
// add Subject Alternative Name(s) // add Subject Alternative Name(s)
if(StringUtils.isNotBlank(domainAlternativeNames)) { try {
try { jcaPKCS10CertificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, createDomainAlternativeNamesExtensions(domainAlternativeNames, requestedDn));
jcaPKCS10CertificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, createDomainAlternativeNamesExtensions(domainAlternativeNames)); } catch (IOException e) {
} catch (IOException e) { throw new OperatorCreationException("Error while adding " + domainAlternativeNames + " as Subject Alternative Name.", e);
throw new OperatorCreationException("Error while adding " + domainAlternativeNames + " as Subject Alternative Name.", e);
}
} }
JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm); JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm);
return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate()))); return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate())));
} }
public static Extensions createDomainAlternativeNamesExtensions(String domainAlternativeNames) throws IOException { public static Extensions createDomainAlternativeNamesExtensions(String domainAlternativeNames, String requestedDn) throws IOException {
List<GeneralName> namesList = new ArrayList<>(); List<GeneralName> namesList = new ArrayList<>();
for(String alternativeName : domainAlternativeNames.split(",")) {
namesList.add(new GeneralName(GeneralName.dNSName, alternativeName)); try {
final String cn = IETFUtils.valueToString(new X500Name(requestedDn).getRDNs(BCStyle.CN)[0].getFirst().getValue());
namesList.add(new GeneralName(GeneralName.dNSName, cn));
} catch (Exception e) {
throw new IOException("Failed to extract CN from request DN: " + requestedDn, e);
}
if(StringUtils.isNotBlank(domainAlternativeNames)) {
for(String alternativeName : domainAlternativeNames.split(",")) {
namesList.add(new GeneralName(GeneralName.dNSName, alternativeName));
}
} }
GeneralNames subjectAltNames = new GeneralNames(namesList.toArray(new GeneralName [] {})); GeneralNames subjectAltNames = new GeneralNames(namesList.toArray(new GeneralName [] {}));

View File

@ -52,6 +52,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.security.util.CertificateUtils; import org.apache.nifi.security.util.CertificateUtils;
import org.apache.nifi.toolkit.tls.configuration.TlsConfig; import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
@ -319,9 +320,12 @@ public class TlsHelperTest {
assert subjectName.equals(DN); assert subjectName.equals(DN);
List<String> extractedSans = extractSanFromCsr(csrWithSan); List<String> extractedSans = extractSanFromCsr(csrWithSan);
assert extractedSans.size() == SAN_COUNT; assert extractedSans.size() == SAN_COUNT + 1;
List<String> formattedSans = SAN_ENTRIES.stream().map(s -> "DNS: " + s).collect(Collectors.toList()); List<String> formattedSans = SAN_ENTRIES.stream().map(s -> "DNS: " + s).collect(Collectors.toList());
assert extractedSans.containsAll(formattedSans); assert extractedSans.containsAll(formattedSans);
// We check that the SANs also contain the CN
assert extractedSans.contains("DNS: localhost");
} }
private List<String> extractSanFromCsr(JcaPKCS10CertificationRequest csr) { private List<String> extractSanFromCsr(JcaPKCS10CertificationRequest csr) {