You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ex...@apache.org on 2021/02/01 21:13:10 UTC

[nifi] branch main updated: NIFI-7783 Add CA Common Name as DNS Subject Alternative Name

This is an automated email from the ASF dual-hosted git repository.

exceptionfactory pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 5fea917  NIFI-7783 Add CA Common Name as DNS Subject Alternative Name
5fea917 is described below

commit 5fea9179c474e775ae94c27e99b179941827afa9
Author: Moncef Abboud <mo...@gmail.com>
AuthorDate: Fri Dec 4 11:33:56 2020 +0100

    NIFI-7783 Add CA Common Name as DNS Subject Alternative Name
    
    This closes #4709
    
    Signed-off-by: David Handermann <ex...@apache.org>
---
 .../nifi/security/util/CertificateUtils.java       | 23 ++++++++++++++++++++++
 .../nifi/security/util/CertificateUtilsTest.groovy | 15 ++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
index d3383ec..0e4d387 100644
--- a/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
+++ b/nifi-commons/nifi-security-utils/src/main/java/org/apache/nifi/security/util/CertificateUtils.java
@@ -56,6 +56,7 @@ import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
 import org.bouncycastle.asn1.x500.RDN;
 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.BasicConstraints;
 import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
 import org.bouncycastle.asn1.x509.Extension;
@@ -63,6 +64,8 @@ import org.bouncycastle.asn1.x509.Extensions;
 import org.bouncycastle.asn1.x509.KeyPurposeId;
 import org.bouncycastle.asn1.x509.KeyUsage;
 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
 import org.bouncycastle.cert.CertIOException;
 import org.bouncycastle.cert.X509CertificateHolder;
 import org.bouncycastle.cert.X509v3CertificateBuilder;
@@ -469,6 +472,12 @@ public final class CertificateUtils {
             // (2) extendedKeyUsage extension
             certBuilder.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(new KeyPurposeId[]{KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth}));
 
+            // (3) subjectAlternativeName extension. Include CN as a SAN entry if it exists.
+            final String cn = getCommonName(dn);
+            if (StringUtils.isNotBlank(cn)) {
+                certBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(new GeneralName(GeneralName.dNSName, cn)));
+            }
+
             // Sign the certificate
             X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
             return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder);
@@ -625,6 +634,20 @@ public final class CertificateUtils {
         }
     }
 
+    /**
+     * Extracts the common name from the given DN.
+     *
+     * @param dn the distinguished name to evaluate
+     * @return the common name if it exists, null otherwise.
+     */
+    public static String getCommonName(final String dn) {
+        RDN[] rdns = new X500Name(dn).getRDNs(BCStyle.CN);
+        if (rdns.length == 0) {
+            return null;
+        }
+        return  IETFUtils.valueToString(rdns[0].getFirst().getValue());
+    }
+
     private CertificateUtils() {
     }
 }
diff --git a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy
index f9fa704..03ab118 100644
--- a/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy
+++ b/nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy
@@ -433,6 +433,15 @@ class CertificateUtilsTest extends GroovyTestCase {
     }
 
     @Test
+    void testGetCommonName(){
+        String dn1 = "CN=testDN,O=testOrg"
+        String dn2 = "O=testDN,O=testOrg"
+
+        assertEquals("testDN", CertificateUtils.getCommonName(dn1))
+        assertNull(CertificateUtils.getCommonName(dn2))
+    }
+
+    @Test
     void testShouldGenerateSelfSignedCert() throws Exception {
         String dn = "CN=testDN,O=testOrg"
 
@@ -451,6 +460,12 @@ class CertificateUtilsTest extends GroovyTestCase {
         assertEquals(SIGNATURE_ALGORITHM.toUpperCase(), x509Certificate.getSigAlgName().toUpperCase())
         assertEquals("RSA", x509Certificate.getPublicKey().getAlgorithm())
 
+        assertEquals(1, x509Certificate.getSubjectAlternativeNames().size())
+
+        GeneralName gn = x509Certificate.getSubjectAlternativeNames().iterator().next()
+        assertEquals(GeneralName.dNSName, gn.getTagNo())
+        assertEquals("testDN", gn.getName().toString())
+
         x509Certificate.checkValidity()
     }