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

pvillard 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 3a078c0c31 NIFI-11780 Added Certificate SAN Attributes to 
HandleHttpRequest
3a078c0c31 is described below

commit 3a078c0c31a487e27c2b93a9b97bd8acf143e931
Author: exceptionfactory <[email protected]>
AuthorDate: Fri Jul 21 13:04:48 2023 -0500

    NIFI-11780 Added Certificate SAN Attributes to HandleHttpRequest
    
    Signed-off-by: Pierre Villard <[email protected]>
    
    This closes #7521.
---
 .../processors/standard/HandleHttpRequest.java     |  22 +--
 .../standard/http/CertificateAttribute.java        |  44 ++++++
 .../http/CertificateAttributesProvider.java        |  33 +++++
 ...leHttpRequestCertificateAttributesProvider.java | 131 ++++++++++++++++++
 ...tpRequestCertificateAttributesProviderTest.java | 151 +++++++++++++++++++++
 5 files changed, 370 insertions(+), 11 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
index 39e598f880..20c06f1305 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/HandleHttpRequest.java
@@ -41,6 +41,9 @@ import org.apache.nifi.processor.ProcessSession;
 import org.apache.nifi.processor.Relationship;
 import org.apache.nifi.processor.exception.ProcessException;
 import org.apache.nifi.processor.util.StandardValidators;
+import org.apache.nifi.processors.standard.http.CertificateAttribute;
+import org.apache.nifi.processors.standard.http.CertificateAttributesProvider;
+import 
org.apache.nifi.processors.standard.http.HandleHttpRequestCertificateAttributesProvider;
 import org.apache.nifi.processors.standard.http.HttpProtocolStrategy;
 import org.apache.nifi.processors.standard.util.HTTPUtils;
 import org.apache.nifi.scheduling.ExecutionNode;
@@ -69,7 +72,6 @@ import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URLDecoder;
 import java.security.Principal;
-import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -122,6 +124,10 @@ import static 
javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
             + "unless the Processor is configured to use an SSLContext 
Service"),
     @WritesAttribute(attribute = "http.issuer.dn", description = "The 
Distinguished Name of the entity that issued the Subject's certificate. "
             + "This value will not be populated unless the Processor is 
configured to use an SSLContext Service"),
+    @WritesAttribute(attribute = "http.certificate.sans.N.name", description = 
"X.509 Client Certificate Subject Alternative Name value from mutual TLS 
authentication. "
+            + "The attribute name has a zero-based index ordered according to 
the content of Client Certificate"),
+    @WritesAttribute(attribute = "http.certificate.sans.N.nameType", 
description = "X.509 Client Certificate Subject Alternative Name type from 
mutual TLS authentication. "
+            + "The attribute name has a zero-based index ordered according to 
the content of Client Certificate. The attribute value is one of the General 
Names from RFC 3280 Section 4.1.2.7"),
     @WritesAttribute(attribute = "http.headers.XXX", description = "Each of 
the HTTP Headers that is received in the request will be added as an "
             + "attribute, prefixed with \"http.headers.\" For example, if the 
request contains an HTTP Header named \"x-my-header\", then the value "
             + "will be added to an attribute named 
\"http.headers.x-my-header\""),
@@ -343,6 +349,7 @@ public class HandleHttpRequest extends AbstractProcessor {
     private final AtomicBoolean initialized = new AtomicBoolean(false);
     private final AtomicBoolean runOnPrimary = new AtomicBoolean(false);
     private final AtomicReference<Set<String>> parameterToAttributesReference 
= new AtomicReference<>(null);
+    private final CertificateAttributesProvider certificateAttributesProvider 
= new HandleHttpRequestCertificateAttributesProvider();
 
     @Override
     protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
@@ -756,22 +763,15 @@ public class HandleHttpRequest extends AbstractProcessor {
           putAttribute(attributes, "http.principal.name", principal.getName());
       }
 
-      final X509Certificate[] certs = (X509Certificate[]) 
request.getAttribute("javax.servlet.request.X509Certificate");
-      if (certs != null && certs.length > 0) {
-          final X509Certificate cert = certs[0];
-          final String subjectDn = cert.getSubjectDN().getName();
-          final String issuerDn = cert.getIssuerDN().getName();
-
-          putAttribute(attributes, HTTPUtils.HTTP_SSL_CERT, subjectDn);
-          putAttribute(attributes, "http.issuer.dn", issuerDn);
-      }
+      final Map<String, String> certificateAttributes = 
certificateAttributesProvider.getCertificateAttributes(request);
+      attributes.putAll(certificateAttributes);
 
       return session.putAllAttributes(flowFile, attributes);
     }
 
     private void forwardFlowFile(final ProcessSession session, final long 
start, final HttpServletRequest request, final FlowFile flowFile) {
       final long receiveMillis = 
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
-      final String subjectDn = flowFile.getAttribute(HTTPUtils.HTTP_SSL_CERT);
+      final String subjectDn = 
flowFile.getAttribute(CertificateAttribute.HTTP_SUBJECT_DN.getName());
       session.getProvenanceReporter().receive(flowFile, 
HTTPUtils.getURI(flowFile.getAttributes()),
           "Received from " + request.getRemoteAddr() + (subjectDn == null ? "" 
: " with DN=" + subjectDn), receiveMillis);
       session.transfer(flowFile, REL_SUCCESS);
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/CertificateAttribute.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/CertificateAttribute.java
new file mode 100644
index 0000000000..1b4be1f4ad
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/CertificateAttribute.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.nifi.processors.standard.http;
+
+/**
+ * X.509 Client Certificate FlowFile Attribute Names
+ */
+public enum CertificateAttribute {
+    /** Certificate Subject Distinguished Name */
+    HTTP_SUBJECT_DN("http.subject.dn"),
+
+    /** Certificate Issuer Distinguished Name */
+    HTTP_ISSUER_DN("http.issuer.dn"),
+
+    /** Certificate Subject Distinguished Name */
+    HTTP_CERTIFICATE_PARSING_EXCEPTION("http.certificate.parsing.exception"),
+
+    /** Certificate Subject Alternative Names */
+    HTTP_CERTIFICATE_SANS("http.certificate.sans");
+
+    private final String name;
+
+    CertificateAttribute(final String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/CertificateAttributesProvider.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/CertificateAttributesProvider.java
new file mode 100644
index 0000000000..78fe286079
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/CertificateAttributesProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.nifi.processors.standard.http;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * Provider abstraction for reading X.509 Client Certificates from an HTTP 
Servlet Request and returning FlowFile attributes
+ */
+public interface CertificateAttributesProvider {
+    /**
+     * Get X.509 Client Certificate Attributes
+     *
+     * @param request HTTP Servlet Request
+     * @return Map of Client Certificate Attributes or empty when no client 
certificate found
+     */
+    Map<String, String> getCertificateAttributes(HttpServletRequest request);
+}
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
new file mode 100644
index 0000000000..a3b75d7b96
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProvider.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.nifi.processors.standard.http;
+
+import javax.servlet.http.HttpServletRequest;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Certificate Attributes Provider for HandleHttpRequest reads the first X.509 
Certificate presented
+ */
+public class HandleHttpRequestCertificateAttributesProvider implements 
CertificateAttributesProvider {
+    protected static final String REQUEST_CERTIFICATES_ATTRIBUTE_NAME = 
"javax.servlet.request.X509Certificate";
+
+    private static final String SAN_NAME_TYPE_FORMAT = "%s.%d.nameType";
+
+    private static final String SAN_NAME_FORMAT = "%s.%d.name";
+
+    private static final Map<String, String> GENERAL_NAME_TYPES = new 
LinkedHashMap<>();
+
+    static {
+        // General Name types defined in RFC 3280 Section 4.2.1.7 */
+        GENERAL_NAME_TYPES.put("0", "otherName");
+        GENERAL_NAME_TYPES.put("1", "rfc822Name");
+        GENERAL_NAME_TYPES.put("2", "dNSName");
+        GENERAL_NAME_TYPES.put("3", "x400Address");
+        GENERAL_NAME_TYPES.put("4", "directoryName");
+        GENERAL_NAME_TYPES.put("5", "ediPartyName");
+        GENERAL_NAME_TYPES.put("6", "uniformResourceIdentifier");
+        GENERAL_NAME_TYPES.put("7", "iPAddress");
+        GENERAL_NAME_TYPES.put("8", "registeredID");
+    }
+
+    @Override
+    public Map<String, String> getCertificateAttributes(final 
HttpServletRequest request) {
+        Objects.requireNonNull(request, "HTTP Servlet Request required");
+
+        final Map<String, String> attributes;
+
+        final Object requestCertificates = 
request.getAttribute(REQUEST_CERTIFICATES_ATTRIBUTE_NAME);
+        if (requestCertificates instanceof X509Certificate[]) {
+            final X509Certificate[] certificates = (X509Certificate[]) 
requestCertificates;
+            if (certificates.length == 0) {
+                attributes = Collections.emptyMap();
+            } else {
+                final X509Certificate clientCertificate = certificates[0];
+                attributes = getCertificateAttributes(clientCertificate);
+            }
+        } else {
+            attributes = Collections.emptyMap();
+        }
+
+        return attributes;
+    }
+
+    private Map<String, String> getCertificateAttributes(final X509Certificate 
certificate) {
+        final Map<String, String> attributes = new LinkedHashMap<>();
+
+        final String subjectPrincipal = 
certificate.getSubjectX500Principal().getName();
+        final String issuerPrincipal = 
certificate.getIssuerX500Principal().getName();
+
+        attributes.put(CertificateAttribute.HTTP_SUBJECT_DN.getName(), 
subjectPrincipal);
+        attributes.put(CertificateAttribute.HTTP_ISSUER_DN.getName(), 
issuerPrincipal);
+
+        try {
+            final Collection<List<?>> subjectAlternativeNames = 
certificate.getSubjectAlternativeNames();
+
+            if (subjectAlternativeNames != null) {
+                final Map<String, String> subjectAlternativeNameAttributes = 
getSubjectAlternativeNameAttributes(subjectAlternativeNames);
+                attributes.putAll(subjectAlternativeNameAttributes);
+            }
+        } catch (final CertificateParsingException e) {
+            
attributes.put(CertificateAttribute.HTTP_CERTIFICATE_PARSING_EXCEPTION.getName(),
 e.getMessage());
+        }
+
+        return attributes;
+    }
+
+    private Map<String, String> getSubjectAlternativeNameAttributes(final 
Collection<List<?>> subjectAlternativeNames) {
+        final Map<String, String> attributes = new LinkedHashMap<>();
+
+        int subjectAlternativeNameIndex = 0;
+        for (final List<?> subjectAlternativeTypeName : 
subjectAlternativeNames) {
+            final String nameTypeAttributeKey = 
String.format(SAN_NAME_TYPE_FORMAT, 
CertificateAttribute.HTTP_CERTIFICATE_SANS.getName(), 
subjectAlternativeNameIndex);
+            final String nameType = 
subjectAlternativeTypeName.get(0).toString();
+            final String generalNameType = 
GENERAL_NAME_TYPES.getOrDefault(nameType, nameType);
+            attributes.put(nameTypeAttributeKey, generalNameType);
+
+            final String nameAttributeKey = String.format(SAN_NAME_FORMAT, 
CertificateAttribute.HTTP_CERTIFICATE_SANS.getName(), 
subjectAlternativeNameIndex);
+            final Object name = subjectAlternativeTypeName.get(1);
+            final String serializedName = getSerializedName(name);
+            attributes.put(nameAttributeKey, serializedName);
+
+            subjectAlternativeNameIndex++;
+        }
+
+        return attributes;
+    }
+
+    private String getSerializedName(final Object name) {
+        final String serializedName;
+        if (name instanceof byte[]) {
+            final byte[] encodedName = (byte[]) name;
+            serializedName = Base64.getEncoder().encodeToString(encodedName);
+        } else {
+            serializedName = name.toString();
+        }
+        return serializedName;
+    }
+}
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
new file mode 100644
index 0000000000..3e4df7c283
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/http/HandleHttpRequestCertificateAttributesProviderTest.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.nifi.processors.standard.http;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import javax.security.auth.x500.X500Principal;
+import javax.servlet.http.HttpServletRequest;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class HandleHttpRequestCertificateAttributesProviderTest {
+    private static final X500Principal SUBJECT_PRINCIPAL = new 
X500Principal("CN=subject, OU=users");
+
+    private static final X500Principal ISSUER_PRINCIPAL = new 
X500Principal("CN=issuer, OU=authorities");
+
+    private static final String RFC_822_NAME_GENERAL_NAME = "rfc822Name";
+
+    private static final String DNS_NAME_GENERAL_NAME = "dNSName";
+
+    private static final Integer RFC_822_NAME_TYPE = 1;
+
+    private static final String EMAIL_ADDRESS = 
"[email protected]";
+
+    private static final Integer DNS_NAME_TYPE = 2;
+
+    private static final String DNS_NAME = "localhost.localdomain";
+
+    private static final String FIRST_SAN_NAME_ATTRIBUTE_KEY = 
"http.certificate.sans.0.name";
+
+    private static final String FIRST_SAN_NAME_TYPE_ATTRIBUTE_KEY = 
"http.certificate.sans.0.nameType";
+
+    private static final String SECOND_SAN_NAME_ATTRIBUTE_KEY = 
"http.certificate.sans.1.name";
+
+    private static final String SECOND_SAN_NAME_TYPE_ATTRIBUTE_KEY = 
"http.certificate.sans.1.nameType";
+
+    private static final String PARSING_EXCEPTION_MESSAGE = "SAN parsing 
failed";
+
+    @Mock
+    private HttpServletRequest request;
+
+    @Mock
+    private X509Certificate certificate;
+
+    private HandleHttpRequestCertificateAttributesProvider provider;
+
+    @BeforeEach
+    void setProvider() {
+        provider = new HandleHttpRequestCertificateAttributesProvider();
+    }
+
+    @Test
+    void testCertificatesNotFound() {
+        final Map<String, String> attributes = 
provider.getCertificateAttributes(request);
+
+        assertTrue(attributes.isEmpty());
+    }
+
+    @Test
+    void testCertificatesFound() {
+        final X509Certificate[] certificates = new 
X509Certificate[]{certificate};
+        
when(request.getAttribute(eq(HandleHttpRequestCertificateAttributesProvider.REQUEST_CERTIFICATES_ATTRIBUTE_NAME))).thenReturn(certificates);
+
+        
when(certificate.getSubjectX500Principal()).thenReturn(SUBJECT_PRINCIPAL);
+        
when(certificate.getIssuerX500Principal()).thenReturn(ISSUER_PRINCIPAL);
+
+        final Map<String, String> attributes = 
provider.getCertificateAttributes(request);
+
+        assertSubjectIssuerFound(attributes);
+    }
+
+    @Test
+    void testCertificatesFoundParsingException() throws 
CertificateParsingException {
+        final X509Certificate[] certificates = new 
X509Certificate[]{certificate};
+        
when(request.getAttribute(eq(HandleHttpRequestCertificateAttributesProvider.REQUEST_CERTIFICATES_ATTRIBUTE_NAME))).thenReturn(certificates);
+
+        
when(certificate.getSubjectX500Principal()).thenReturn(SUBJECT_PRINCIPAL);
+        
when(certificate.getIssuerX500Principal()).thenReturn(ISSUER_PRINCIPAL);
+
+        when(certificate.getSubjectAlternativeNames()).thenThrow(new 
CertificateParsingException(PARSING_EXCEPTION_MESSAGE));
+
+        final Map<String, String> attributes = 
provider.getCertificateAttributes(request);
+
+        assertSubjectIssuerFound(attributes);
+
+        
assertEquals(attributes.get(CertificateAttribute.HTTP_CERTIFICATE_PARSING_EXCEPTION.getName()),
 PARSING_EXCEPTION_MESSAGE);
+    }
+
+    @Test
+    void testCertificateSubjectAlternativeNamesFound() throws 
CertificateParsingException {
+        final X509Certificate[] certificates = new 
X509Certificate[]{certificate};
+        
when(request.getAttribute(eq(HandleHttpRequestCertificateAttributesProvider.REQUEST_CERTIFICATES_ATTRIBUTE_NAME))).thenReturn(certificates);
+
+        
when(certificate.getSubjectX500Principal()).thenReturn(SUBJECT_PRINCIPAL);
+        
when(certificate.getIssuerX500Principal()).thenReturn(ISSUER_PRINCIPAL);
+
+        final Collection<List<?>> subjectAlternativeNames = new ArrayList<>();
+
+        final List<?> emailAddressName = Arrays.asList(RFC_822_NAME_TYPE, 
EMAIL_ADDRESS);
+        subjectAlternativeNames.add(emailAddressName);
+
+        final List<?> dnsName = Arrays.asList(DNS_NAME_TYPE, DNS_NAME);
+        subjectAlternativeNames.add(dnsName);
+
+        
when(certificate.getSubjectAlternativeNames()).thenReturn(subjectAlternativeNames);
+
+        final Map<String, String> attributes = 
provider.getCertificateAttributes(request);
+
+        assertSubjectIssuerFound(attributes);
+
+        assertEquals(attributes.get(FIRST_SAN_NAME_ATTRIBUTE_KEY), 
EMAIL_ADDRESS);
+        assertEquals(attributes.get(FIRST_SAN_NAME_TYPE_ATTRIBUTE_KEY), 
RFC_822_NAME_GENERAL_NAME);
+
+        assertEquals(attributes.get(SECOND_SAN_NAME_ATTRIBUTE_KEY), DNS_NAME);
+        assertEquals(attributes.get(SECOND_SAN_NAME_TYPE_ATTRIBUTE_KEY), 
DNS_NAME_GENERAL_NAME);
+    }
+
+    private void assertSubjectIssuerFound(final Map<String, String> 
attributes) {
+        assertEquals(SUBJECT_PRINCIPAL.getName(), 
attributes.get(CertificateAttribute.HTTP_SUBJECT_DN.getName()));
+        assertEquals(ISSUER_PRINCIPAL.getName(), 
attributes.get(CertificateAttribute.HTTP_ISSUER_DN.getName()));
+    }
+}

Reply via email to