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

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new c16dfbe  Original principal authorization for admin API (#2028)
c16dfbe is described below

commit c16dfbe178f31b5b9caa72c1084ff4d0ab275723
Author: Ivan Kelly <[email protected]>
AuthorDate: Thu Jun 28 18:04:06 2018 +0200

    Original principal authorization for admin API (#2028)
    
    * Original principal authorization for admin API
    
    The broker admin checks if the authenticated user is listed as a proxy
    user. If so, it checks looks for the header X-Original-Principal, and
    validates that the role is authorized to access the resource in
    question.
    
    There are two use cases:
    
    1. The proxy role is a normal role. In this case, if a resource is to
    be used via the proxy, the proxy user must be explicitly granted
    permission on the resource. So, to use the admin api for a tenant, the
    proxy role must be listed as a tenant admin.
    2. The proxy role is a superuser role. In this case, any resource can
    be used via the proxy as long as the user authorized with the proxy is
    authorized to use the resource. However, if the proxy is compromised,
    a bad actor has full access to the cluster.
    
    This patch is the first part of a fix for #1991.
    
    * Factor out some validation for original principal
    
    Also added a check that if original principal is set, it must have
    come from a role contained in proxyRoles.
---
 .../broker/admin/impl/PersistentTopicsBase.java    |   4 +-
 .../apache/pulsar/broker/service/ServerCnx.java    |   2 +-
 .../pulsar/broker/web/PulsarWebResource.java       |  65 ++++-
 .../pulsar/broker/admin/AdminApiTlsAuthTest.java   | 322 +++++++++++++++++++++
 .../apache/pulsar/broker/admin/NamespacesTest.java |  55 ++--
 .../authentication/tls-http/admin.cert.pem         |  26 ++
 .../authentication/tls-http/admin.key-pk8.pem      |  28 ++
 .../authentication/tls-http/broker.cert.pem        |  27 ++
 .../authentication/tls-http/broker.key-pk8.pem     |  28 ++
 .../resources/authentication/tls-http/ca.cert.pem  |  29 ++
 .../authentication/tls-http/proxy.cert.pem         |  26 ++
 .../authentication/tls-http/proxy.key-pk8.pem      |  28 ++
 .../authentication/tls-http/superproxy.cert.pem    |  26 ++
 .../authentication/tls-http/superproxy.key-pk8.pem |  28 ++
 .../client-keys/proxy.cert.pem                     |  26 ++
 .../client-keys/proxy.csr.pem                      |  15 +
 .../client-keys/proxy.key-pk8.pem                  |  28 ++
 .../client-keys/proxy.key.pem                      |  27 ++
 .../client-keys/superproxy.cert.pem                |  26 ++
 .../client-keys/superproxy.csr.pem                 |  15 +
 .../client-keys/superproxy.key-pk8.pem             |  28 ++
 .../client-keys/superproxy.key.pem                 |  27 ++
 tests/certificate-authority/index.txt              |   3 +
 tests/certificate-authority/index.txt.old          |   3 +
 tests/certificate-authority/newcerts/1002.pem      |  26 ++
 tests/certificate-authority/newcerts/1003.pem      |  26 ++
 tests/certificate-authority/newcerts/1004.pem      |  26 ++
 tests/certificate-authority/serial                 |   2 +-
 tests/certificate-authority/serial.old             |   2 +-
 29 files changed, 933 insertions(+), 41 deletions(-)

diff --git 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java
 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java
index a354008..946980a 100644
--- 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java
+++ 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java
@@ -1137,7 +1137,7 @@ public class PersistentTopicsBase extends AdminResource {
     }
 
     public static CompletableFuture<PartitionedTopicMetadata> 
getPartitionedTopicMetadata(PulsarService pulsar,
-            String clientAppId, AuthenticationDataSource authenticationData, 
TopicName topicName) {
+            String clientAppId, String originalPrincipal, 
AuthenticationDataSource authenticationData, TopicName topicName) {
         CompletableFuture<PartitionedTopicMetadata> metadataFuture = new 
CompletableFuture<>();
         try {
             // (1) authorize client
@@ -1145,7 +1145,7 @@ public class PersistentTopicsBase extends AdminResource {
                 checkAuthorization(pulsar, topicName, clientAppId, 
authenticationData);
             } catch (RestException e) {
                 try {
-                    validateAdminAccessForTenant(pulsar, clientAppId, 
topicName.getTenant());
+                    validateAdminAccessForTenant(pulsar, clientAppId, 
originalPrincipal, topicName.getTenant());
                 } catch (RestException authException) {
                     log.warn("Failed to authorize {} on cluster {}", 
clientAppId, topicName.toString());
                     throw new 
PulsarClientException(String.format("Authorization failed %s on topic %s with 
error %s",
diff --git 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
index fcf4045..4b45f72 100644
--- 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
+++ 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
@@ -324,7 +324,7 @@ public class ServerCnx extends PulsarHandler {
             isProxyAuthorizedFuture.thenApply(isProxyAuthorized -> {
                     if (isProxyAuthorized) {
                     getPartitionedTopicMetadata(getBrokerService().pulsar(),
-                            finalOriginalPrincipal != null ? 
finalOriginalPrincipal : authRole, authenticationData,
+                                                authRole, 
finalOriginalPrincipal, authenticationData,
                             topicName).handle((metadata, ex) -> {
                                     if (ex == null) {
                                         int partitions = metadata.partitions;
diff --git 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java
 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java
index 01dd7f9..c13b12f 100644
--- 
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java
+++ 
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java
@@ -71,6 +71,8 @@ public abstract class PulsarWebResource {
 
     private static final Logger log = 
LoggerFactory.getLogger(PulsarWebResource.class);
 
+    static final String ORIGINAL_PRINCIPAL_HEADER = "X-Original-Principal";
+
     @Context
     protected ServletContext servletContext;
 
@@ -126,6 +128,10 @@ public abstract class PulsarWebResource {
         return (String) 
httpRequest.getAttribute(AuthenticationFilter.AuthenticatedRoleAttributeName);
     }
 
+    public String originalPrincipal() {
+        return httpRequest.getHeader(ORIGINAL_PRINCIPAL_HEADER);
+    }
+
     public AuthenticationDataHttps clientAuthData() {
         return (AuthenticationDataHttps) 
httpRequest.getAttribute(AuthenticationFilter.AuthenticatedDataAttributeName);
     }
@@ -138,6 +144,25 @@ public abstract class PulsarWebResource {
         return appId != null;
     }
 
+    private static void validateOriginalPrincipal(Set<String> proxyRoles, 
String authenticatedPrincipal,
+                                                  String originalPrincipal) {
+        if (originalPrincipal != null) {
+            if (StringUtils.isBlank(originalPrincipal)) {
+                log.warn("Original principal empty in request authenticated as 
{}", authenticatedPrincipal);
+                throw new RestException(Status.UNAUTHORIZED, "Original 
principal cannot be empty if it is set");
+            }
+            if (proxyRoles.contains(originalPrincipal)) {
+                log.warn("Original principal {} cannot be a proxy role ({})", 
originalPrincipal, proxyRoles);
+                throw new RestException(Status.UNAUTHORIZED, "Original 
principal cannot be a proxy role");
+            }
+            if (!proxyRoles.contains(authenticatedPrincipal)) {
+                log.warn("Original principal can only be accepted from a 
client authenticated as a proxy. "
+                        + "{} is not part of proxyRoles", 
authenticatedPrincipal, proxyRoles);
+                throw new RestException(Status.UNAUTHORIZED, "Original 
principal only accepted from proxy");
+            }
+        }
+    }
+
     /**
      * Checks whether the user has Pulsar Super-User access to the system.
      *
@@ -151,7 +176,22 @@ public abstract class PulsarWebResource {
                 log.debug("[{}] Check super user access: Authenticated: {} -- 
Role: {}", uri.getRequestUri(),
                         isClientAuthenticated(appId), appId);
             }
-            if (!config().getSuperUserRoles().contains(appId)) {
+            String originalPrincipal = originalPrincipal();
+            
validateOriginalPrincipal(pulsar.getConfiguration().getProxyRoles(), appId, 
originalPrincipal);
+
+            if (pulsar.getConfiguration().getProxyRoles().contains(appId)) {
+                Set<String> superUserRoles = 
pulsar.getConfiguration().getSuperUserRoles();
+                boolean proxyAuthorized = superUserRoles.contains(appId);
+                boolean originalPrincipalAuthorized = 
superUserRoles.contains(originalPrincipal);
+
+                if (!proxyAuthorized || !originalPrincipalAuthorized) {
+                    throw new RestException(Status.UNAUTHORIZED,
+                            String.format("Proxy not authorized for super-user 
operation (proxy:%s,original:%s)",
+                                          appId, originalPrincipal));
+                }
+                log.debug("Successfully authorized {} (proxied by {}) as 
super-user",
+                          originalPrincipal, appId);
+            } else if (!config().getSuperUserRoles().contains(appId)) {
                 throw new RestException(Status.UNAUTHORIZED, "This operation 
requires super-user access");
             }
         }
@@ -167,7 +207,7 @@ public abstract class PulsarWebResource {
      */
     protected void validateAdminAccessForTenant(String tenant) {
         try {
-            validateAdminAccessForTenant(pulsar(), clientAppId(), tenant);
+            validateAdminAccessForTenant(pulsar(), clientAppId(), 
originalPrincipal(), tenant);
         } catch (RestException e) {
             throw e;
         } catch (Exception e) {
@@ -176,7 +216,8 @@ public abstract class PulsarWebResource {
         }
     }
 
-    protected static void validateAdminAccessForTenant(PulsarService pulsar, 
String clientAppId, String tenant)
+    protected static void validateAdminAccessForTenant(PulsarService pulsar, 
String clientAppId,
+                                                       String 
originalPrincipal, String tenant)
             throws RestException, Exception {
         if (log.isDebugEnabled()) {
             log.debug("check admin access on tenant: {} - Authenticated: {} -- 
role: {}", tenant,
@@ -198,7 +239,23 @@ public abstract class PulsarWebResource {
                 throw new RestException(Status.FORBIDDEN, "Need to 
authenticate to perform the request");
             }
 
-            if 
(pulsar.getConfiguration().getSuperUserRoles().contains(clientAppId)) {
+            
validateOriginalPrincipal(pulsar.getConfiguration().getProxyRoles(), 
clientAppId, originalPrincipal);
+
+            if 
(pulsar.getConfiguration().getProxyRoles().contains(clientAppId)) {
+                Set<String> superUserRoles = 
pulsar.getConfiguration().getSuperUserRoles();
+                Set<String> adminRoles = tenantInfo.getAdminRoles();
+                boolean proxyAuthorized = superUserRoles.contains(clientAppId) 
|| adminRoles.contains(clientAppId);
+                boolean originalPrincipalAuthorized
+                    = superUserRoles.contains(originalPrincipal) || 
adminRoles.contains(originalPrincipal);
+
+                if (!proxyAuthorized || !originalPrincipalAuthorized) {
+                    throw new RestException(Status.UNAUTHORIZED,
+                            String.format("Proxy not authorized to access 
resource (proxy:%s,original:%s)",
+                                          clientAppId, originalPrincipal));
+                }
+                log.debug("Successfully authorized {} (proxied by {}) on 
tenant {}",
+                          originalPrincipal, clientAppId, tenant);
+            } else if 
(pulsar.getConfiguration().getSuperUserRoles().contains(clientAppId)) {
                 // Super-user has access to configure all the policies
                 log.debug("granting access to super-user {} on tenant {}", 
clientAppId, tenant);
             } else {
diff --git 
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTlsAuthTest.java
 
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTlsAuthTest.java
new file mode 100644
index 0000000..24a07a3
--- /dev/null
+++ 
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTlsAuthTest.java
@@ -0,0 +1,322 @@
+/**
+ * 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.pulsar.broker.admin;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.List;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLContext;
+import javax.ws.rs.NotAuthorizedException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+
+import org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest;
+import org.apache.pulsar.client.admin.PulsarAdmin;
+import org.apache.pulsar.client.admin.PulsarAdminException;
+import org.apache.pulsar.client.admin.internal.JacksonConfigurator;
+import org.apache.pulsar.common.policies.data.TenantInfo;
+import org.apache.pulsar.common.util.SecurityUtility;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Slf4j
+public class AdminApiTlsAuthTest extends MockedPulsarServiceBaseTest {
+    private static String getTLSFile(String name) {
+        return 
String.format("./src/test/resources/authentication/tls-http/%s.pem", name);
+    }
+
+    @BeforeMethod
+    @Override
+    public void setup() throws Exception {
+        conf.setLoadBalancerEnabled(true);
+        conf.setTlsEnabled(true);
+        conf.setTlsCertificateFilePath(getTLSFile("broker.cert"));
+        conf.setTlsKeyFilePath(getTLSFile("broker.key-pk8"));
+        conf.setTlsTrustCertsFilePath(getTLSFile("ca.cert"));
+        conf.setAuthenticationEnabled(true);
+        conf.setAuthenticationProviders(
+                
ImmutableSet.of("org.apache.pulsar.broker.authentication.AuthenticationProviderTls"));
+        conf.setSuperUserRoles(ImmutableSet.of("admin", "superproxy"));
+        conf.setProxyRoles(ImmutableSet.of("proxy", "superproxy"));
+        conf.setAuthorizationEnabled(true);
+
+        super.internalSetup();
+    }
+
+    @AfterMethod
+    @Override
+    public void cleanup() throws Exception {
+        super.internalCleanup();
+    }
+
+    WebTarget buildWebClient(String user) throws Exception {
+        ClientConfig httpConfig = new ClientConfig();
+        httpConfig.property(ClientProperties.FOLLOW_REDIRECTS, true);
+        httpConfig.property(ClientProperties.ASYNC_THREADPOOL_SIZE, 8);
+        httpConfig.register(MultiPartFeature.class);
+
+        ClientBuilder clientBuilder = 
ClientBuilder.newBuilder().withConfig(httpConfig)
+            
.register(JacksonConfigurator.class).register(JacksonFeature.class);
+
+        X509Certificate trustCertificates[] = 
SecurityUtility.loadCertificatesFromPemFile(
+                getTLSFile("ca.cert"));
+        SSLContext sslCtx = SecurityUtility.createSslContext(
+                false, trustCertificates,
+                SecurityUtility.loadCertificatesFromPemFile(getTLSFile(user + 
".cert")),
+                SecurityUtility.loadPrivateKeyFromPemFile(getTLSFile(user + 
".key-pk8")));
+        
clientBuilder.sslContext(sslCtx).hostnameVerifier(NoopHostnameVerifier.INSTANCE);
+        Client client = clientBuilder.build();
+
+        return client.target(brokerUrlTls.toString());
+    }
+
+    PulsarAdmin buildAdminClient(String user) throws Exception {
+        return PulsarAdmin.builder()
+            .allowTlsInsecureConnection(false)
+            .enableTlsHostnameVerification(false)
+            .serviceHttpUrl(brokerUrlTls.toString())
+            
.authentication("org.apache.pulsar.client.impl.auth.AuthenticationTls",
+                            String.format("tlsCertFile:%s,tlsKeyFile:%s",
+                                          getTLSFile(user + ".cert"), 
getTLSFile(user + ".key-pk8")))
+            .tlsTrustCertsFilePath(getTLSFile("ca.cert")).build();
+    }
+
+    @Test
+    public void testSuperUserCanListTenants() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("foobar"),
+                                                        
ImmutableSet.of("test")));
+            Assert.assertEquals(ImmutableSet.of("tenant1"), 
admin.tenants().getTenants());
+        }
+    }
+
+    @Test
+    public void testProxyRoleCantListTenants() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("foobar"),
+                                                        
ImmutableSet.of("test")));
+        }
+        try (PulsarAdmin admin = buildAdminClient("proxy")) {
+            admin.tenants().getTenants();
+            Assert.fail("Shouldn't be able to list tenants");
+        } catch (PulsarAdminException.NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testProxyRoleCantListNamespacesEvenWithAccess() throws 
Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("proxy"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        try (PulsarAdmin admin = buildAdminClient("proxy")) {
+            admin.namespaces().getNamespaces("tenant1");
+            Assert.fail("Shouldn't be able to list namespaces");
+        } catch (PulsarAdminException.NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testAuthorizedUserAsOriginalPrincipal() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("proxy", "user1"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("proxy");
+        Assert.assertEquals(ImmutableSet.of("tenant1/ns1"),
+                            root.path("/admin/v2/namespaces").path("tenant1")
+                            .request(MediaType.APPLICATION_JSON)
+                            .header("X-Original-Principal", "user1")
+                            .get(new GenericType<List<String>>() {}));
+    }
+
+    @Test
+    public void testUnauthorizedUserAsOriginalPrincipal() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("proxy", "user1"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("proxy");
+        try {
+            root.path("/admin/v2/namespaces").path("tenant1")
+                .request(MediaType.APPLICATION_JSON)
+                .header("X-Original-Principal", "user2")
+                .get(new GenericType<List<String>>() {});
+            Assert.fail("user2 should not be authorized");
+        } catch (NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testAuthorizedUserAsOriginalPrincipalButProxyNotAuthorized() 
throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("user1"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("proxy");
+        try {
+            root.path("/admin/v2/namespaces").path("tenant1")
+                .request(MediaType.APPLICATION_JSON)
+                .header("X-Original-Principal", "user1")
+                .get(new GenericType<List<String>>() {});
+            Assert.fail("Shouldn't be able to list namespaces");
+        } catch (NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testAuthorizedUserAsOriginalPrincipalProxyIsSuperUser() throws 
Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("user1"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("superproxy");
+        Assert.assertEquals(ImmutableSet.of("tenant1/ns1"),
+                            root.path("/admin/v2/namespaces").path("tenant1")
+                            .request(MediaType.APPLICATION_JSON)
+                            .header("X-Original-Principal", "user1")
+                            .get(new GenericType<List<String>>() {}));
+    }
+
+    @Test
+    public void testUnauthorizedUserAsOriginalPrincipalProxyIsSuperUser() 
throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("user1"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("superproxy");
+        try {
+            root.path("/admin/v2/namespaces").path("tenant1")
+                .request(MediaType.APPLICATION_JSON)
+                .header("X-Original-Principal", "user2")
+                .get(new GenericType<List<String>>() {});
+            Assert.fail("user2 should not be authorized");
+        } catch (NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testProxyUserViaProxy() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("proxy"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("superproxy");
+        try {
+            root.path("/admin/v2/namespaces").path("tenant1")
+                .request(MediaType.APPLICATION_JSON)
+                .header("X-Original-Principal", "proxy")
+                .get(new GenericType<List<String>>() {});
+            Assert.fail("proxy should not be authorized");
+        } catch (NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testSuperProxyUserAndAdminCanListTenants() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("user1"),
+                                                        
ImmutableSet.of("test")));
+        }
+        WebTarget root = buildWebClient("superproxy");
+        Assert.assertEquals(ImmutableSet.of("tenant1"),
+                            root.path("/admin/v2/tenants")
+                            .request(MediaType.APPLICATION_JSON)
+                            .header("X-Original-Principal", "admin")
+                            .get(new GenericType<List<String>>() {}));
+    }
+
+    @Test
+    public void testSuperProxyUserAndNonAdminCannotListTenants() throws 
Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("proxy"),
+                                                        
ImmutableSet.of("test")));
+        }
+        WebTarget root = buildWebClient("superproxy");
+        try {
+            root.path("/admin/v2/tenants")
+                .request(MediaType.APPLICATION_JSON)
+                .header("X-Original-Principal", "user1")
+                .get(new GenericType<List<String>>() {});
+            Assert.fail("user1 should not be authorized");
+        } catch (NotAuthorizedException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testNonProxyCannotSetOriginalPrincipal() throws Exception {
+        try (PulsarAdmin admin = buildAdminClient("admin")) {
+            admin.tenants().createTenant("tenant1",
+                                         new 
TenantInfo(ImmutableSet.of("user1"),
+                                                        
ImmutableSet.of("test")));
+            admin.namespaces().createNamespace("tenant1/ns1");
+        }
+        WebTarget root = buildWebClient("admin");
+        try {
+            root.path("/admin/v2/namespaces").path("tenant1")
+                .request(MediaType.APPLICATION_JSON)
+                .header("X-Original-Principal", "user1")
+                .get(new GenericType<List<String>>() {});
+            Assert.fail("admin shouldn't be able to act as proxy even if it is 
superuser");
+        } catch (NotAuthorizedException e) {
+            // expected
+        }
+    }
+}
diff --git 
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespacesTest.java
 
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespacesTest.java
index 305c887..8584e5c 100644
--- 
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespacesTest.java
+++ 
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/NamespacesTest.java
@@ -132,6 +132,7 @@ public class NamespacesTest extends 
MockedPulsarServiceBaseTest {
         
doReturn(pulsar.getConfigurationCache().policiesCache()).when(namespaces).policiesCache();
         doReturn(false).when(namespaces).isRequestHttps();
         doReturn("test").when(namespaces).clientAppId();
+        doReturn(null).when(namespaces).originalPrincipal();
         doReturn(Sets.newTreeSet(Lists.newArrayList("use", "usw", "usc", 
"global"))).when(namespaces).clusters();
         doNothing().when(namespaces).validateAdminAccessForTenant("my-tenant");
         
doNothing().when(namespaces).validateAdminAccessForTenant("other-tenant");
@@ -991,8 +992,6 @@ public class NamespacesTest extends 
MockedPulsarServiceBaseTest {
             
ZkUtils.createFullPathOptimistic(pulsar.getConfigurationCache().getZooKeeper(), 
path, data.getBytes(),
                     ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
             namespaces.validateAdminAccessForTenant(property);
-        } catch (RestException e) {
-            fail("validateAdminAccessOnTenant failed");
         } finally {
             pulsar.getConfiguration().setAuthenticationEnabled(false);
             pulsar.getConfiguration().setAuthorizationEnabled(false);
@@ -1048,37 +1047,29 @@ public class NamespacesTest extends 
MockedPulsarServiceBaseTest {
 
     @Test
     public void testValidateTopicOwnership() throws Exception {
-        try {
-            URL localWebServiceUrl = new URL(pulsar.getWebServiceAddress());
-            String bundledNsLocal = "test-bundled-namespace-1";
-            BundlesData bundleData = new 
BundlesData(Lists.newArrayList("0x00000000", "0xffffffff"));
-            createBundledTestNamespaces(this.testTenant, 
this.testLocalCluster, bundledNsLocal, bundleData);
-            final NamespaceName testNs = NamespaceName.get(this.testTenant, 
this.testLocalCluster, bundledNsLocal);
-            OwnershipCache MockOwnershipCache = 
spy(pulsar.getNamespaceService().getOwnershipCache());
-            
doNothing().when(MockOwnershipCache).disableOwnership(any(NamespaceBundle.class));
-            Field ownership = 
NamespaceService.class.getDeclaredField("ownershipCache");
-            ownership.setAccessible(true);
-            ownership.set(pulsar.getNamespaceService(), MockOwnershipCache);
-            TopicName topicName = 
TopicName.get(testNs.getPersistentTopicName("my-topic"));
-            PersistentTopics topics = spy(new PersistentTopics());
-            topics.setServletContext(new MockServletContext());
-            topics.setPulsar(pulsar);
-            doReturn(false).when(topics).isRequestHttps();
-            doReturn("test").when(topics).clientAppId();
-            mockWebUrl(localWebServiceUrl, testNs);
-            doReturn("persistent").when(topics).domain();
-
-            try {
-                topics.validateTopicName(topicName.getTenant(), 
topicName.getCluster(),
-                        topicName.getNamespacePortion(), 
topicName.getEncodedLocalName());
-                topics.validateAdminOperationOnTopic(false);
-            } catch (RestException e) {
-                fail("validateAdminAccessOnTenant failed");
-            }
+        URL localWebServiceUrl = new URL(pulsar.getWebServiceAddress());
+        String bundledNsLocal = "test-bundled-namespace-1";
+        BundlesData bundleData = new 
BundlesData(Lists.newArrayList("0x00000000", "0xffffffff"));
+        createBundledTestNamespaces(this.testTenant, this.testLocalCluster, 
bundledNsLocal, bundleData);
+        final NamespaceName testNs = NamespaceName.get(this.testTenant, 
this.testLocalCluster, bundledNsLocal);
+        OwnershipCache MockOwnershipCache = 
spy(pulsar.getNamespaceService().getOwnershipCache());
+        
doNothing().when(MockOwnershipCache).disableOwnership(any(NamespaceBundle.class));
+        Field ownership = 
NamespaceService.class.getDeclaredField("ownershipCache");
+        ownership.setAccessible(true);
+        ownership.set(pulsar.getNamespaceService(), MockOwnershipCache);
+        TopicName topicName = 
TopicName.get(testNs.getPersistentTopicName("my-topic"));
+        PersistentTopics topics = spy(new PersistentTopics());
+        topics.setServletContext(new MockServletContext());
+        topics.setPulsar(pulsar);
+        doReturn(false).when(topics).isRequestHttps();
+        doReturn("test").when(topics).clientAppId();
+        doReturn(null).when(topics).originalPrincipal();
+        mockWebUrl(localWebServiceUrl, testNs);
+        doReturn("persistent").when(topics).domain();
 
-        } catch (RestException e) {
-            fail("validateAdminAccessOnTenant failed");
-        }
+        topics.validateTopicName(topicName.getTenant(), topicName.getCluster(),
+                                 topicName.getNamespacePortion(), 
topicName.getEncodedLocalName());
+        topics.validateAdminOperationOnTopic(false);
     }
 
     @Test
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/admin.cert.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/admin.cert.pem
new file mode 100644
index 0000000..0665edb
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/tls-http/admin.cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEZTCCAk2gAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyMjA4NTcwNloYDzIyOTIwNDA2MDg1NzA2WjAQMQ4wDAYDVQQD
+DAVhZG1pbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJw3Jfbn0xkW
+36kqQjES6Hn+YTZ2jXS5Co2MzsGBsIY0qJ2BbWHSSaMrja4IERUaCQp16SWxPmZ0
+srMm6ErDoap+O70CWXLT3ybYMV5aVwv3ca4uxsedzaw9MpFXfUDsJJ3yre1JpO+t
+A/QzJEGq1d6NN49InUP5kB1Rpay3vaxx8hduzqTO+E/Lptv92p6GjOpXi2icSjiA
+pgaan2ldGGKEKv2Sc2bfdIDkTq1yDyNmuPET0yD2dci106EW/mPyj81umPKG/o4K
+5W18yG/IhXw5W1zlgO1fWCuqva8NCBdu7s1c7hUX8DBx7km4/I7dllz/nYHIfCEQ
+Dmj38oQjYk8CAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIF
+oDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRp
+ZmljYXRlMB0GA1UdDgQWBBQTMzAAOJ9gXvQSS7Be3+qmrb1kVDAfBgNVHSMEGDAW
+gBRXC+nLI+i/Rz5Qej9FfqEYQ50VJzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYw
+FAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQAwy8f6hsG0
+85e3SOIztbUnaVxS7wzDeDzR3vCjpXpm4vTToYzN9zx3JHKSdJrB12emVxItwW/7
+bXqBk0n2EdQjRHCuebnY05eFMNGagMEEMVmSLOproQD7VsyALNxCss1JAyRikh70
+W7wgOVeAhqE53UqqrkzTE7Q+8Bag9t3FytHxApY17XglbWkiVcFpQwSURe9Emi3E
+aCJCryGJXrBNuCFXGzetSygDEy27+2FeH8S2XsMwUEGLqDDehzvMenVz1xjXtq+s
+KPkofAde52NHd4lLkSeBMSFnKe3V7Xxax2OEUsoQRF3bkbpcJSWsKS9ZAA2yrtuy
+Nz/aA1F42LuSFPAYQr1kcZ8eSS918RWz+BiJYU2JuUOPd1XUmJXVvZ4CJurWaC7+
+ZD51YdD8E245xd55fsA6/qLx3eE/Kp0dVq+Hxuz6b4yLET0zkGunOe4A3hnRgkOA
+XolXCL+VthhWtFGXn8CjpxDnzjahq69Io+dINehqd5aJEgvnHZIK2s7FTqqBBodU
+HhyAE94f64z7ziuRhEG54bmBF+MoGyPf6dVn1Mp3+o+YeQ5q6XlKgh+u8jMgmqRO
+ikdsVdMqopt/FXh9eFzvQrwOZFLK6JE/edUgb6xvS1jMF5zi2lIlIkq1RBQOr4HT
+XDwX4vRtfpDxpsetGVpeq9O07fbMvp+mkw==
+-----END CERTIFICATE-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/admin.key-pk8.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/admin.key-pk8.pem
new file mode 100644
index 0000000..6aaa22c
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/tls-http/admin.key-pk8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCcNyX259MZFt+p
+KkIxEuh5/mE2do10uQqNjM7BgbCGNKidgW1h0kmjK42uCBEVGgkKdeklsT5mdLKz
+JuhKw6Gqfju9Ally098m2DFeWlcL93GuLsbHnc2sPTKRV31A7CSd8q3tSaTvrQP0
+MyRBqtXejTePSJ1D+ZAdUaWst72scfIXbs6kzvhPy6bb/dqehozqV4tonEo4gKYG
+mp9pXRhihCr9knNm33SA5E6tcg8jZrjxE9Mg9nXItdOhFv5j8o/Nbpjyhv6OCuVt
+fMhvyIV8OVtc5YDtX1grqr2vDQgXbu7NXO4VF/Awce5JuPyO3ZZc/52ByHwhEA5o
+9/KEI2JPAgMBAAECggEAP+Ipq2Q4puz8wGBgu1LhMWp+9Nfcl1xI3YQ01VulBe0o
++2h/g96McKcSBJaV7cw84ENB+kEWpK2amrsRiemhBmkjIvOAAv50Jp2I6u4E5Qbn
+PXUxo1Z8UrCgKmHd/hvUCafByuUwBzf5AvebHyOu3JlhnD302mSHtAW8u/pUHd3D
+sxJaw1zwQvmlD5ryM2IVYSji7NYCXF0H6V7HfyohTCrQFEWEAdqEDcFR1BUwbPCE
+raq7sAiEy+cBUnfV3IOEAffOZy0vSR90/WwERcwrzCdZmpWpTqtbcqtdBPqsSQzX
+shDvXd0e43+FSJzCtQsSQ8WzIrp3rgKJUDA1pJQW4QKBgQDJdTcB6qZz8r+4q9gc
+q1KAJyMy01Vio1yaqYzXr0C9Z5FW1GhL+4fwer2y9JyD45sb/lP4reFj9S193BNR
+C8cdxM5GrWEpzaQ0Dt1s8P1UbU8G6r4NqwI6ORF3CxXZKfXivQcgqBurJGrBdjIC
+NwqAzSkX5flBbhfTlJuUH87k3wKBgQDGgjzdIWXab7FZfdUzzrtEwNooBiSEFixm
+UAwP5sxL8VkM9wzAKPEVDDQBBoKIga9OESif4S9UUo4tu65AYfxF9Om26K4QrVj8
+HT/U+lfT7xFmPd/GINIbeTSmW0w7Ehpj8SbcQI4Sb2lVE562FlHh7QbHZd0/X/2J
+nbgT9MRAkQKBgQCVPAN3o/+SPOzRPFtnQXJoBJYKfIrv+twKpjbzP5vRsvrzO33X
+a4kUF5iXDKU0/lJUtl42BXjFt0Xvyit1CiiCYNv9d0pW0UMmXSyiGxNOi3rTQOlw
+7pFD2Cqb6NZSfMbtI+I3ytBUQzHiBlCdW3CoYVJjpbSzR37W+WsWm0mEOQKBgQCq
+ANObFYUjA1DBMZCrY7rhcL/kUw5myI6RuK/71k7UIwd+oP0cfHOq8N6AmlCkE1xM
+4UkHU1SzRFhbNkZPARuJ1etqJ+8afTqd/3axMQyShkVCaG8CQQ1vVegPKFUqqaBM
+QzRioC6L/zoYEEt16buKXvHVRpmqMszxVE9XV+HS4QKBgDvs5qloOowS5kcWInrj
+yecu5MJvFf2IZpMw7EiKV8VUPeKaiUlqgFj9d9cotUIMauXgBq6f5NBRg7Ike60t
+/JJrPtqXY+gdFLjxcKMUVYhomFlQYYg/RJZUBrtkyKBP68abopCYmb59r3ixeNNf
+qA1F36mmFtzdjSdtH/dTTecN
+-----END PRIVATE KEY-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/broker.cert.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/broker.cert.pem
new file mode 100644
index 0000000..b5c7a5d
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/tls-http/broker.cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEkDCCAnigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyMjA4NTUzMloYDzIyOTIwNDA2MDg1NTMyWjAjMSEwHwYDVQQD
+DBhicm9rZXIucHVsc2FyLmFwYWNoZS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDQouKhZah4hMCqmg4aS5RhQG/Y1gA+yP9DGF9mlw35tfhfWs63
+EvNjEK4L/ZWSEV45L/wc6YV14RmM6bJ0V/0vXo4xmISbqptND/2kRIspkLZQ5F0O
+OQXVicqZLOc6igZQhRg8ANDYdTJUTF65DqauX4OJt3YMhF2FSt7jQtlj06IQBa01
++ARO9OotMJtBY+vIU5bV6JydfgkhQH9rIDI7AMeY5j02gGkJJrelfm+WoOsUez+X
+aqTN3/tF8+MBcFB3G04s1qc2CJPJM3YGxvxEtHqTGI14t9J8p5O7X9JHpcY8X00s
+bxa4FGbKgfDobbkJ+GgblWCkAcLN95sKTqtHAgMBAAGjgd0wgdowCQYDVR0TBAIw
+ADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2Vu
+ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUaxFvJrkEGqk8azTA
+DyVyTyTbJAIwQQYDVR0jBDowOIAUVwvpyyPov0c+UHo/RX6hGEOdFSehFaQTMBEx
+DzANBgNVBAMMBmZvb2JhcoIJANfih0+geeIMMA4GA1UdDwEB/wQEAwIFoDATBgNV
+HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEA35QDGclHzQtHs3yQ
+ZzNOSKisg5srTiIoQgRzfHrXfkthNFCnBzhKjBxqk3EIasVtvyGuk0ThneC1ai3y
+ZK3BivnMZfm1SfyvieFoqWetsxohWfcpOSVkpvO37P6v/NmmaTIGkBN3gxKCx0QN
+zqApLQyNTM++X3wxetYH/afAGUrRmBGWZuJheQpB9yZ+FB6BRp8YuYIYBzANJyW9
+spvXW03TpqX2AIoRBoGMLzK72vbhAbLWiCIfEYREhbZVRkP+yvD338cWrILlOEur
+x/n8L/FTmbf7mXzHg4xaQ3zg/5+0OCPMDPUBE4xWDBAbZ82hgOcTqfVjwoPgo2V0
+fbbx6redq44J3Vn5d9Xhi59fkpqEjHpX4xebr5iMikZsNTJMeLh0h3uf7DstuO9d
+mfnF5j+yDXCKb9XzCsTSvGCN+spmUh6RfSrbkw8/LrRvBUpKVEM0GfKSnaFpOaSS
+efM4UEi72FRjszzHEkdvpiLhYvihINLJmDXszhc3fCi42be/DGmUhuhTZWynOPmp
+0N0V/8/sGT5gh4fGEtGzS/8xEvZwO9uDlccJiG8Pi+aO0/K9urB9nppd/xKWXv3C
+cib/QrW0Qow4TADWC1fnGYCpFzzaZ2esPL2MvzOYXnW4/AbEqmb6Weatluai64ZK
+3N2cGJWRyvpvvmbP2hKCa4eLgEc=
+-----END CERTIFICATE-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/broker.key-pk8.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/broker.key-pk8.pem
new file mode 100644
index 0000000..2b51d01
--- /dev/null
+++ 
b/pulsar-broker/src/test/resources/authentication/tls-http/broker.key-pk8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDQouKhZah4hMCq
+mg4aS5RhQG/Y1gA+yP9DGF9mlw35tfhfWs63EvNjEK4L/ZWSEV45L/wc6YV14RmM
+6bJ0V/0vXo4xmISbqptND/2kRIspkLZQ5F0OOQXVicqZLOc6igZQhRg8ANDYdTJU
+TF65DqauX4OJt3YMhF2FSt7jQtlj06IQBa01+ARO9OotMJtBY+vIU5bV6Jydfgkh
+QH9rIDI7AMeY5j02gGkJJrelfm+WoOsUez+XaqTN3/tF8+MBcFB3G04s1qc2CJPJ
+M3YGxvxEtHqTGI14t9J8p5O7X9JHpcY8X00sbxa4FGbKgfDobbkJ+GgblWCkAcLN
+95sKTqtHAgMBAAECggEBALE1eMtfnk3nbAI74bih84D7C0Ug14p8jJv/qqBnsx4j
+WrgbWDMVrJa7Rym2FQHBMMfgIwKnso0iSeJvaPz683j1lk833YKe0VQOPgD1m0IN
+wV1J6mQ3OOZcKDIcerY1IBHqSmBEzR7dxIbnaxlCAX9gb0hdBK6zCwA5TMG5OQ5Y
+3cGOmevK5i2PiejhpruA8h7E48P1ATaGHUZif9YD724oi6AcilQ8H/DlOjZTvlmK
+r4aJ30f72NwGM8Ecet5CE2wyflAGtY0k+nChYkPRfy54u64Z/T9B53AvneFaj8jv
+yFepZgRTs2cWhEl0KQGuBHQ4+IeOfMt2LebhvjWW8YkCgYEA7BXVsnqPHKRDd8wP
+eNkolY4Fjdq4wu9ad+DaFiZcJuv7ugr+Kplltq6e4aU36zEdBYdPp/6KM/HGE/Xj
+bo0CELNUKs/Ny9H/UJc8DDbVEmoF3XGiIbKKq1T8NTXTETFnwrGkBFD8nl7YTsOF
+M4FZmSok0MhhkpEULAqxBS6YpQsCgYEA4jxM1egTVSWjTreg2UdYo2507jKa7maP
+PRtoPsNJzWNbOpfj26l3/8pd6oYKWck6se6RxIUxUrk3ywhNJIIOvWEC7TaOH1c9
+T4NQNcweqBW9+A1x5gyzT14gDaBfl45gs82vI+kcpVv/w2N3HZOQZX3yAUqWpfw2
+yw1uQDXtgDUCgYEAiYPWbBXTkp1j5z3nrT7g0uxc89n5USLWkYlZvxktCEbg4+dP
+UUT06EoipdD1F3wOKZA9p98uZT9pX2sUxOpBz7SFTEKq3xQ9IZZWFc9CoW08aVat
+V++FsnLYTa5CeXtLsy6CGTmLTDx2xrpAtlWb+QmBVFPD8fmrxFOd9STFKS0CgYAt
+6ztVN3OlFqyc75yQPXD6SxMkvdTAisSMDKIOCylRrNb5f5baIP2gR3zkeyxiqPtm
+3htsHfSy67EtXpP50wQW4Dft2eLi7ZweJXMEWFfomfEjBeeWYAGNHHe5DFIauuVZ
+2WexDEGqNpAlIm0s7aSjVPrn1DHbouOkNyenlMqN+QKBgQDVYVhk9widShSnCmUA
+G30moXDgj3eRqCf5T7NEr9GXD1QBD/rQSPh5agnDV7IYLpV7/wkYLI7l9x7mDwu+
+I9mRXkyAmTVEctLTdXQHt0jdJa5SfUaVEDUzQbr0fUjkmythTvqZ809+d3ELPeLI
+5qJ7jxgksHWji4lYfL4r4J6Zaw==
+-----END PRIVATE KEY-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/ca.cert.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/ca.cert.pem
new file mode 100644
index 0000000..0446700
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/tls-http/ca.cert.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIFCDCCAvCgAwIBAgIJANfih0+geeIMMA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
+BAMMBmZvb2JhcjAeFw0xODA2MjIwODQ2MjFaFw0zODA2MTcwODQ2MjFaMBExDzAN
+BgNVBAMMBmZvb2JhcjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOVU
+UpTPeXCeyfUiQS824l9s9krZd4R6TA4D97eQ9EWm2D7ppV4gPApHO8j5f+joo/b6
+Iso4aFlHpJ8VV2a5Ol7rjQw43MJHaBgwDxB1XWgsNdfoI7ebtp/BWg2nM3r8wm+Z
+gKenf9d1/1Ol+6yFUehkLkIXUvldiVegmmje8FnwhcDNE1eTrh66XqSJXEXqgBKu
+NqsoYcVak72OyOO1/N8CESoSdyBkbSiH5vJyo0AUCjn7tULga7fxojmqBZDog9Pg
+e5Fi/hbCrdinbxBrMgIxQ7wqXw2sw6iOWu4FU8Ih/CuF4xaQy2YP7MEk4Ff0LCY0
+KMhFMWU7550r/fz/C2l7fKhREyCQPa/bVE+dfxgZ/gCZ+p7vQ154hCCjpd+5bECv
+SN1bcVIPG6ngQu4vMXa7QRBi/Od40jSVGVJXYY6kXvrYatad7035w2GGGGkvMsQm
+y53yh4tqQfH7ulHqB0J5LebTQRp6nRizWigVCLjNkxJYI+Dj51qvT1zdyWEegKr1
+CthBfYzXlfjeH3xri1f0UABeC12n24Wkacd9af7zs7S3rYntEK444w/3fB0F62Lh
+SESfMLAmUH0dF5plRShrFUXz23nUeS8EYgWmnGkpf/HDzB67vdfAK0tfJEtmmY78
+q06OSgMr+AOOqaomh4Ez2ZQG592bS71G8MrE7r2/AgMBAAGjYzBhMB0GA1UdDgQW
+BBRXC+nLI+i/Rz5Qej9FfqEYQ50VJzAfBgNVHSMEGDAWgBRXC+nLI+i/Rz5Qej9F
+fqEYQ50VJzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
+9w0BAQsFAAOCAgEAYd2PxdV+YOaWcmMG1fK7CGwSzDOGsgC7hi4gWPiNsVbz6fwQ
+m5Ac7Zw76dzin8gzOPKST7B8WIoc7ZWrMnyh3G6A3u29Ec8iWahqGa91NPA3bOIl
+0ldXnXfa416+JL/Q5utpiV6W2XDaB53v9GqpMk4rOTS9kCFOiuH5ZU8P69jp9mq6
+7pI/+hWFr+21ibmXH6ANxRLd/5+AqojRUYowAu2997Z+xmbpwx/2Svciq3LNY/Vz
+s9DudUHCBHj/DPgNxsEUt8QNohjQkRbFTY0a1aXodJ/pm0Ehk2kf9KwYYYduR7ak
+6UmPIPrZg6FePNahxwMZ0RtgX7EXmpiiIH1q9BsulddWkrFQclevsWO3ONQVrDs2
+gwY0HQuCRCJ+xgS2cyGiGohW5MkIsg1aI0i0j5GIUSppCIYgirAGCairARbCjhcx
+pbMe8RTuBhCqO3R2wZ0wXu7P7/ArI/Ltm1dU6IeHUAUmeneVj5ie0SdA19mHTS2o
+lG77N0jy6eq2zyEwJE6tuS/tyP1xrxdzXCYY7f6X9aNfsuPVQTcnrFajvDv8R6uD
+YnRStVCdS6fZEP0JzsLrqp9bgLIRRsiqsVVBCgJdK1I/X59qk2EyCLXWSgk8T9XZ
+iux8LlPpskt30YYt1KhlWB9zVz7k0uYAwits5foU6RfCRDPAyOa1q/QOXk0=
+-----END CERTIFICATE-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/proxy.cert.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/proxy.cert.pem
new file mode 100644
index 0000000..6c2f429
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/tls-http/proxy.cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEZTCCAk2gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyNTEzNTYwNFoYDzIyOTIwNDA5MTM1NjA0WjAQMQ4wDAYDVQQD
+DAVwcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMieX78Yj8OW
+eBHAneRaCCoO8Qrpj8zGo7h9lCdmi1lBDh1uR2sDbotiHGfJzQn836WcYmyeAvfn
+qvgr9HCXmXdLgmJ3GT/LVu5GEm6msSDiZQPr9so5lQVioisK4UwJROQsE/J52cyR
+9o3H6M4FKb6QpoobKa62fSfTumwwulaYaDJuRRGoGIkcRuUQ59EWAaDkD3IcDpAn
+9mTbnE4Iz+JxSrsZ5DJ3X/m/AqyLWtj6GAfyK9a1dhNdlf2x4JZT1QNtojiBXt95
+OIZyRBNbHMFniq5gel6wdBkmJWutfcTct7wKa2LCxLpKoDIc1HWoL3+RUzOKxYIP
+0qXEQ3bmONkCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIF
+oDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRp
+ZmljYXRlMB0GA1UdDgQWBBSgsgfmDbXEkrrpHUC9GnDDjxaKizAfBgNVHSMEGDAW
+gBRXC+nLI+i/Rz5Qej9FfqEYQ50VJzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYw
+FAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQB+uZ2OWR+G
+sRqYHEeVqUI8G2p8Np8eC/onGpBL8Gj9SGxIQcIPtqHPUlCe9fd/96JOptOGRYEB
+BmUCaCmQ4IgMW6e6fArka5IB4XXIgHFXyQ6ImTvjDavzlVw06zn9S4dLwVzsRBg+
+GS9svtq23W+f5rEN5N+7LhtcbclfiG4VCCqDG5VhkzEok+SRamDI8rDRZtodMw0O
+/+L+xaaQPUPjX8KUlKn4uVpCDbxUzHonlCPzbkHHm5su0D4ysjJIy3/y3yow6JE/
+02L7PZkmkmw3/V+84T3X8/GD15sVUv/3v1gXEBxYwAs+RNTJ0APvMEMSvCq0AMfF
+bPMZBuAGNBG7lv7TovzHgGFKXT7du5OFF/qjAsEffhbo224CB96fgwvvndwHHBFh
+J06BvHZG1i9dDVhUKoB1owkWrE4RZv2ZKEtZYgizzSmzZRHtARo0t1Byc5djx1tX
+TkJOHshNqJZOY1ER0DPaVQgKI+PRTbEdj/xPGRX3ebSqDmilAfPXshqgElfch6Yl
+f2V58TyCnjXOibvkG9D5OyCdWLEECumOZgYar0KZgNfrvTOi1OKXnX1fsbh29fWA
+ICZRcdmjkz79zQXY2SuzCWlskuXPKAmW1AMqs+l6ormmKfzIUx3Yriy4LqIIYY1v
+uQD5vghZmd9HUg2KaXfSGD9stGCD8KhntA==
+-----END CERTIFICATE-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/proxy.key-pk8.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/proxy.key-pk8.pem
new file mode 100644
index 0000000..70e0107
--- /dev/null
+++ b/pulsar-broker/src/test/resources/authentication/tls-http/proxy.key-pk8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDInl+/GI/DlngR
+wJ3kWggqDvEK6Y/MxqO4fZQnZotZQQ4dbkdrA26LYhxnyc0J/N+lnGJsngL356r4
+K/Rwl5l3S4Jidxk/y1buRhJuprEg4mUD6/bKOZUFYqIrCuFMCUTkLBPyednMkfaN
+x+jOBSm+kKaKGymutn0n07psMLpWmGgybkURqBiJHEblEOfRFgGg5A9yHA6QJ/Zk
+25xOCM/icUq7GeQyd1/5vwKsi1rY+hgH8ivWtXYTXZX9seCWU9UDbaI4gV7feTiG
+ckQTWxzBZ4quYHpesHQZJiVrrX3E3Le8CmtiwsS6SqAyHNR1qC9/kVMzisWCD9Kl
+xEN25jjZAgMBAAECggEAJJyCbKVW1yLGlrbIGbw0cTh41Lz6+SvnBOwl9WrJU2iD
+4usVLXpa2iT1ehthx8jWJ6r6a0gK0qL8mH2tBj8kSpkFGmMRwIqjOqifBIJ3IMEw
+Hh8Z0p3fjDQL1D8QDohCgkFpAn8qOCMLE6S/35khnR1Yxytd1/yFqpcBFm1uFA85
+dYisjPqWm/IZIU5rH0zgKAIhtvl9abnoi93443EHsKpRAW1gwRXx9Aak7TV768bZ
+tELBsaTnXnNzamDiaimmxEOlqR9O0W8JE/31KFL26JcVmsTRG7sMpoUxCEMjOuGZ
+J30bXFZUW6NrDpFsQ7uTqD6TNn2971N8KFCLnC/JYQKBgQDo82axC7L7n7BYTu18
+dupeT7n5dTBD/I3l0KtT05xiZA8GZr2i+pt+/aWzCzK4/Ee4jb4/o8CRQRB5v5mo
+c9lc+BaoAIQiwiw+aufT+UojrcijrOMEL5Zk3zdZ2rcEoAsVvqtejNnwLCGI9Rnl
+gp7n9oRhwDIv9Fu09snUougE3wKBgQDceAGKUB8pGd3eEya/0jU9J60LsKbcJSsN
+4v1S5LiPtHOyhr0g4x/LibMP2PJhG3tJ1bgpaGmn9du2D20M6ukRhIYyn/7G+N+A
+oqryyvO1MMYnhc4IEQvWrzDnBM0hV2bdjp4s/1ASVHVRwk8+orqxysIJ1D75nnRX
+Tyfl6HgBRwKBgQCfVlWIhiMPv6OkU6BXgRNAHTJs8f5okmgQqNF3jgequRwZ2c6e
+muIfU6myNNel9lGsZ6+Y4g4GjMWTMT4OHeewkrUUhv3atIwEyaT2tc5DZ0wUwF2r
+cE1jg9bdbB/BVyMd5YRcMOWlRNpPTq8+8EB3E4RrREZPzMmplyBohGFFawKBgGjc
+P0dM8nU3E1rj2wNTdPUAYQL1Y3fDyeWR+BEsLkhTeNAJ2/y/akkB1oQMGMRtMMee
+ejhfrBkyC+1dCu4g8PffA4EirihvCMcDF7HhK+cbKrRzpNobWXkj3GuU0ggwrQFm
+Kv+V87y0JRTdCZnuBkQ3/vBz3fwWDJnWUVC9sA5TAoGBAN4t2gJCZax5yInUgyWi
+Tgumb2qVWsGBBLMTKIsrkK/KphzgAhHcVhDCybA79TmIM2FfIlpf6TE7Mv4NI055
+ZJzHX+GMT5Czy2Ku9MJD3PLTFN5MjYb6g92fKViLDMI6fwzTHB8xPJ7Ob9bV2srS
+ZlmKNXTkZFk3/orK4WdCZufz
+-----END PRIVATE KEY-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/superproxy.cert.pem 
b/pulsar-broker/src/test/resources/authentication/tls-http/superproxy.cert.pem
new file mode 100644
index 0000000..9656e2c
--- /dev/null
+++ 
b/pulsar-broker/src/test/resources/authentication/tls-http/superproxy.cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEajCCAlKgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyNjEzMjUxN1oYDzIyOTIwNDEwMTMyNTE3WjAVMRMwEQYDVQQD
+DApzdXBlcnByb3h5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA43Sn
+ys/h3wxJ/IBEzbJdQAKCxU4of5KgTDzFoOaS8C63Nwbjgy0qcWYdRDceP4lJIKSA
+1+JZ+R1opyrfVIC2D9oDJFIJTFfXy9G9VYDccwAONPgAamvRzBnYcEu8fqM+Ohle
+kZltKktAHnX3WtG3RyxEL5nYzlMlGwUXJu3Rxc9SlkYSxERzjWHikGqGmXLX2qB0
+k6oyxTrK+4+EHk3khbEIqyQZSOFbD7NMfnRy0CWFv/9T1shgjAIBCake6jY7lwaT
+S7JvbLfG6ABf5xHMxoWLXa2qwb+Ar43Ff9g8kKZwFOxMeGcwkzyJPBbWytFxaWn+
+R2RHhTaVCGc22CjdfQIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEB
+BAQDAgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFHEgLhfH0Z1QlLxeQbG7YZyBlz1MMB8GA1Ud
+IwQYMBaAFFcL6csj6L9HPlB6P0V+oRhDnRUnMA4GA1UdDwEB/wQEAwIF4DAdBgNV
+HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBAK9q
+3YnEa99Cq3Vo3g6PE/A/xOE97seVNuavqyBcVv9PrTydb5XG4jPkYU3xOYXIc8rA
+A4gzd+AsGO9rjGMPGGjQJI3JO/3BCeBJMkn50C/rM1yWVMHnVyFcJlg16xaWtj1e
+2Jk8egJW2gSYyF+N2TdzI7tOb002GNr36posnqO+IOoLapyHFBxxUjsPDRoo8fJn
+myWsV1Y9oRUZyJlfIAJsu85ew7gDBY2jaiEiopzour3uU3C0N7gYni2OmVwfr6J8
+R2/Jp43BSD5sYOW9RAJIEEXef+InYtz9HTJvKu2LsWwIBkaztk29tJcDE+1La6Sw
+0dF0YkUwnXoGQFjiV+8pXX3TF5glXKj1rU8WfNazF6lqslB6DmdgR3/FQ6Z2sE86
+d9hVtayZIGlzU0rWmBBtr++7Wo88nmzAtd/xbZMFG8U//+Q2AvJT2oVGtqM48+al
+rnsN/gYrLDr7RC14bHIuO1v6ZL/rAi7SPKrKYAyQVTAcRuW516SxxR6S1Xa1ITnh
+rwgKg13eQuwu3iigguIS9XL6nAXabBIxBxMl6o2YlyIPekKYIcQmpqhkavJ6VOgX
+iq9VdY6fIJVfmxNZuwM3/28k7UeUAfhI2SSVH4ZURbPiGGH2wukc1QkmtZ2cNa35
+C1y79aqJbIa3ErqLFPj/fM+34x8L7QHPq6RfaODa
+-----END CERTIFICATE-----
diff --git 
a/pulsar-broker/src/test/resources/authentication/tls-http/superproxy.key-pk8.pem
 
b/pulsar-broker/src/test/resources/authentication/tls-http/superproxy.key-pk8.pem
new file mode 100644
index 0000000..2e4140b
--- /dev/null
+++ 
b/pulsar-broker/src/test/resources/authentication/tls-http/superproxy.key-pk8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDjdKfKz+HfDEn8
+gETNsl1AAoLFTih/kqBMPMWg5pLwLrc3BuODLSpxZh1ENx4/iUkgpIDX4ln5HWin
+Kt9UgLYP2gMkUglMV9fL0b1VgNxzAA40+ABqa9HMGdhwS7x+oz46GV6RmW0qS0Ae
+dfda0bdHLEQvmdjOUyUbBRcm7dHFz1KWRhLERHONYeKQaoaZctfaoHSTqjLFOsr7
+j4QeTeSFsQirJBlI4VsPs0x+dHLQJYW//1PWyGCMAgEJqR7qNjuXBpNLsm9st8bo
+AF/nEczGhYtdrarBv4CvjcV/2DyQpnAU7Ex4ZzCTPIk8FtbK0XFpaf5HZEeFNpUI
+ZzbYKN19AgMBAAECggEBAM1JAwuD1drmj3wKFI8F1S2pVndXFCwXnP9RthiDIckO
+kKNkX0CMKgtQ20cu6+jyMgL5FaRCkWvJxCNkCU6OIENsQ3urYuL5QTWeZeBevhg4
+y5m43z8tcptgFD09zbEKCmaLcRO9wo3yfrs/QvE/58efxyajFs8YsZuSW5Px/msl
+AFN8qGY0q0lQbQPK8cPYT4OnW9isqEjkvHq1Q+ryv4cxsGWtBZYmJVeLVHzClihi
+lODdN6YsDcu9jLwsA8o2WSBRsbLHK6caW4FdEwgOLckc0EGGEU64VEB9ZOwgcwYQ
+M9mZDs2w7qk63YnDH4KmpoP0Oc8N+bG7Pkifd7f8HqECgYEA8esMQya6Qln4O7Qo
+aI8X9t5gCpq+bh/P+7vYdBR/9St5VtE/P0yuaQdT2e5t+Ei4ujqHvJ0GTPmqYIJf
+2DNvJMu8EnXv+nqKQCsyMc/nqQN1CcRGqZssH1V/ZIQLRUA0cN4hzE0eHITwp6U9
+vD/WaE3mKX/XHthIjc8hnuoajOkCgYEA8LIYMgyD3wClWOKe5TkBumI0KvA9tP90
+IFHu1wLNl0tKBpsXkzzxiav1FMX3K7B29vxukrs946KRESHzRg4c5ULPnMmwcQyx
+AortKJWrGVsna/QDWPRutXSN1XmnjKWsHmTpQQqLfaRvLW+Hd34+EVdVh9sVt/y9
+RucnBvxcX3UCgYBebm/U7pMaP2BkfcigN+sU1G0M9qaK+iQHkaXGehIQs62js/5K
+STZzjQawNR/8IPbqytodR/YjqflVvs6G6FzkMhrx4dORJLA+qB3pz8wP72eKLnGe
+1xF8EbWumNSFbbCKtkrfIuM0IriF2Dym9QxOnsnPPTXNtoNrx4TKMXu3sQKBgBq9
+noSI8WmoF7adTsvmnnOHj4YptKFUNCGXGLLYg+DII4xCVMct4SPLb+oD6Gb5Lu5X
+sy0oEkMk/3roy68/yCQMXSZtHeYhY9UFfD2jCyRBBUswC+MpHNeaAFv0LRIqIcoq
+qeNo+YBW8WcZ2fIDm3+vtTfntiz/rkOfUK2tAdI1AoGAL2LVDF5e1meSRocEoy8e
+gqrshrhg+KBqYmcjtd4Iup4WvR6uyH4qE9yFLLHFZ04pZzXLHcPfqgOSP8qTxgH3
+h0uqtcYmejS/yl6PbC9OPXcSkMgntRkTbU9Ug05ijfN9NRnW+8WXvi8Z6DKed1P1
+9PxwA75P9o0h00mMk8PQitQ=
+-----END PRIVATE KEY-----
diff --git a/tests/certificate-authority/client-keys/proxy.cert.pem 
b/tests/certificate-authority/client-keys/proxy.cert.pem
new file mode 100644
index 0000000..6c2f429
--- /dev/null
+++ b/tests/certificate-authority/client-keys/proxy.cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEZTCCAk2gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyNTEzNTYwNFoYDzIyOTIwNDA5MTM1NjA0WjAQMQ4wDAYDVQQD
+DAVwcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMieX78Yj8OW
+eBHAneRaCCoO8Qrpj8zGo7h9lCdmi1lBDh1uR2sDbotiHGfJzQn836WcYmyeAvfn
+qvgr9HCXmXdLgmJ3GT/LVu5GEm6msSDiZQPr9so5lQVioisK4UwJROQsE/J52cyR
+9o3H6M4FKb6QpoobKa62fSfTumwwulaYaDJuRRGoGIkcRuUQ59EWAaDkD3IcDpAn
+9mTbnE4Iz+JxSrsZ5DJ3X/m/AqyLWtj6GAfyK9a1dhNdlf2x4JZT1QNtojiBXt95
+OIZyRBNbHMFniq5gel6wdBkmJWutfcTct7wKa2LCxLpKoDIc1HWoL3+RUzOKxYIP
+0qXEQ3bmONkCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIF
+oDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRp
+ZmljYXRlMB0GA1UdDgQWBBSgsgfmDbXEkrrpHUC9GnDDjxaKizAfBgNVHSMEGDAW
+gBRXC+nLI+i/Rz5Qej9FfqEYQ50VJzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYw
+FAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQB+uZ2OWR+G
+sRqYHEeVqUI8G2p8Np8eC/onGpBL8Gj9SGxIQcIPtqHPUlCe9fd/96JOptOGRYEB
+BmUCaCmQ4IgMW6e6fArka5IB4XXIgHFXyQ6ImTvjDavzlVw06zn9S4dLwVzsRBg+
+GS9svtq23W+f5rEN5N+7LhtcbclfiG4VCCqDG5VhkzEok+SRamDI8rDRZtodMw0O
+/+L+xaaQPUPjX8KUlKn4uVpCDbxUzHonlCPzbkHHm5su0D4ysjJIy3/y3yow6JE/
+02L7PZkmkmw3/V+84T3X8/GD15sVUv/3v1gXEBxYwAs+RNTJ0APvMEMSvCq0AMfF
+bPMZBuAGNBG7lv7TovzHgGFKXT7du5OFF/qjAsEffhbo224CB96fgwvvndwHHBFh
+J06BvHZG1i9dDVhUKoB1owkWrE4RZv2ZKEtZYgizzSmzZRHtARo0t1Byc5djx1tX
+TkJOHshNqJZOY1ER0DPaVQgKI+PRTbEdj/xPGRX3ebSqDmilAfPXshqgElfch6Yl
+f2V58TyCnjXOibvkG9D5OyCdWLEECumOZgYar0KZgNfrvTOi1OKXnX1fsbh29fWA
+ICZRcdmjkz79zQXY2SuzCWlskuXPKAmW1AMqs+l6ormmKfzIUx3Yriy4LqIIYY1v
+uQD5vghZmd9HUg2KaXfSGD9stGCD8KhntA==
+-----END CERTIFICATE-----
diff --git a/tests/certificate-authority/client-keys/proxy.csr.pem 
b/tests/certificate-authority/client-keys/proxy.csr.pem
new file mode 100644
index 0000000..aad0180
--- /dev/null
+++ b/tests/certificate-authority/client-keys/proxy.csr.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICVTCCAT0CAQAwEDEOMAwGA1UEAwwFcHJveHkwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDInl+/GI/DlngRwJ3kWggqDvEK6Y/MxqO4fZQnZotZQQ4d
+bkdrA26LYhxnyc0J/N+lnGJsngL356r4K/Rwl5l3S4Jidxk/y1buRhJuprEg4mUD
+6/bKOZUFYqIrCuFMCUTkLBPyednMkfaNx+jOBSm+kKaKGymutn0n07psMLpWmGgy
+bkURqBiJHEblEOfRFgGg5A9yHA6QJ/Zk25xOCM/icUq7GeQyd1/5vwKsi1rY+hgH
+8ivWtXYTXZX9seCWU9UDbaI4gV7feTiGckQTWxzBZ4quYHpesHQZJiVrrX3E3Le8
+CmtiwsS6SqAyHNR1qC9/kVMzisWCD9KlxEN25jjZAgMBAAGgADANBgkqhkiG9w0B
+AQsFAAOCAQEAkW2koDlfwjf2nfq7pPWn9pePa3asV/1vURsHftMzUgvfvuM5X+Ss
+VyRZrbbcBIauRtumsB1r/vJDe0JzpQDVm3k/la9Muh6FZwiEjzl13JU1grdqBibs
+Ckd09R80VeJxQlYgIUA8nhURZQIDUVA6SQnQ8tw7lfCnPkM/iCCV3R4Zi0nD28SI
+HcFQ5pbpCiBLnQuGwgCMtq0s4iZfsBth4WvdSFmw+zoBG3XdrUBIidCXL1sIyc1v
+w4doOspzsiQvDN25nS5c1BwqYDeLhRSUJPm1rOWSL2Q7w3PHH/PqiRphRgI4ADbz
+96rhQoWIs4PoKgPpNU22CeEcEcMU9ws3Ow==
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/certificate-authority/client-keys/proxy.key-pk8.pem 
b/tests/certificate-authority/client-keys/proxy.key-pk8.pem
new file mode 100644
index 0000000..70e0107
--- /dev/null
+++ b/tests/certificate-authority/client-keys/proxy.key-pk8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDInl+/GI/DlngR
+wJ3kWggqDvEK6Y/MxqO4fZQnZotZQQ4dbkdrA26LYhxnyc0J/N+lnGJsngL356r4
+K/Rwl5l3S4Jidxk/y1buRhJuprEg4mUD6/bKOZUFYqIrCuFMCUTkLBPyednMkfaN
+x+jOBSm+kKaKGymutn0n07psMLpWmGgybkURqBiJHEblEOfRFgGg5A9yHA6QJ/Zk
+25xOCM/icUq7GeQyd1/5vwKsi1rY+hgH8ivWtXYTXZX9seCWU9UDbaI4gV7feTiG
+ckQTWxzBZ4quYHpesHQZJiVrrX3E3Le8CmtiwsS6SqAyHNR1qC9/kVMzisWCD9Kl
+xEN25jjZAgMBAAECggEAJJyCbKVW1yLGlrbIGbw0cTh41Lz6+SvnBOwl9WrJU2iD
+4usVLXpa2iT1ehthx8jWJ6r6a0gK0qL8mH2tBj8kSpkFGmMRwIqjOqifBIJ3IMEw
+Hh8Z0p3fjDQL1D8QDohCgkFpAn8qOCMLE6S/35khnR1Yxytd1/yFqpcBFm1uFA85
+dYisjPqWm/IZIU5rH0zgKAIhtvl9abnoi93443EHsKpRAW1gwRXx9Aak7TV768bZ
+tELBsaTnXnNzamDiaimmxEOlqR9O0W8JE/31KFL26JcVmsTRG7sMpoUxCEMjOuGZ
+J30bXFZUW6NrDpFsQ7uTqD6TNn2971N8KFCLnC/JYQKBgQDo82axC7L7n7BYTu18
+dupeT7n5dTBD/I3l0KtT05xiZA8GZr2i+pt+/aWzCzK4/Ee4jb4/o8CRQRB5v5mo
+c9lc+BaoAIQiwiw+aufT+UojrcijrOMEL5Zk3zdZ2rcEoAsVvqtejNnwLCGI9Rnl
+gp7n9oRhwDIv9Fu09snUougE3wKBgQDceAGKUB8pGd3eEya/0jU9J60LsKbcJSsN
+4v1S5LiPtHOyhr0g4x/LibMP2PJhG3tJ1bgpaGmn9du2D20M6ukRhIYyn/7G+N+A
+oqryyvO1MMYnhc4IEQvWrzDnBM0hV2bdjp4s/1ASVHVRwk8+orqxysIJ1D75nnRX
+Tyfl6HgBRwKBgQCfVlWIhiMPv6OkU6BXgRNAHTJs8f5okmgQqNF3jgequRwZ2c6e
+muIfU6myNNel9lGsZ6+Y4g4GjMWTMT4OHeewkrUUhv3atIwEyaT2tc5DZ0wUwF2r
+cE1jg9bdbB/BVyMd5YRcMOWlRNpPTq8+8EB3E4RrREZPzMmplyBohGFFawKBgGjc
+P0dM8nU3E1rj2wNTdPUAYQL1Y3fDyeWR+BEsLkhTeNAJ2/y/akkB1oQMGMRtMMee
+ejhfrBkyC+1dCu4g8PffA4EirihvCMcDF7HhK+cbKrRzpNobWXkj3GuU0ggwrQFm
+Kv+V87y0JRTdCZnuBkQ3/vBz3fwWDJnWUVC9sA5TAoGBAN4t2gJCZax5yInUgyWi
+Tgumb2qVWsGBBLMTKIsrkK/KphzgAhHcVhDCybA79TmIM2FfIlpf6TE7Mv4NI055
+ZJzHX+GMT5Czy2Ku9MJD3PLTFN5MjYb6g92fKViLDMI6fwzTHB8xPJ7Ob9bV2srS
+ZlmKNXTkZFk3/orK4WdCZufz
+-----END PRIVATE KEY-----
diff --git a/tests/certificate-authority/client-keys/proxy.key.pem 
b/tests/certificate-authority/client-keys/proxy.key.pem
new file mode 100644
index 0000000..1f73f97
--- /dev/null
+++ b/tests/certificate-authority/client-keys/proxy.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyJ5fvxiPw5Z4EcCd5FoIKg7xCumPzMajuH2UJ2aLWUEOHW5H
+awNui2IcZ8nNCfzfpZxibJ4C9+eq+Cv0cJeZd0uCYncZP8tW7kYSbqaxIOJlA+v2
+yjmVBWKiKwrhTAlE5CwT8nnZzJH2jcfozgUpvpCmihsprrZ9J9O6bDC6VphoMm5F
+EagYiRxG5RDn0RYBoOQPchwOkCf2ZNucTgjP4nFKuxnkMndf+b8CrIta2PoYB/Ir
+1rV2E12V/bHgllPVA22iOIFe33k4hnJEE1scwWeKrmB6XrB0GSYla619xNy3vApr
+YsLEukqgMhzUdagvf5FTM4rFgg/SpcRDduY42QIDAQABAoIBACScgmylVtcixpa2
+yBm8NHE4eNS8+vkr5wTsJfVqyVNog+LrFS16Wtok9XobYcfI1ieq+mtICtKi/Jh9
+rQY/JEqZBRpjEcCKozqonwSCdyDBMB4fGdKd34w0C9Q/EA6IQoJBaQJ/KjgjCxOk
+v9+ZIZ0dWMcrXdf8haqXARZtbhQPOXWIrIz6lpvyGSFOax9M4CgCIbb5fWm56Ivd
++ONxB7CqUQFtYMEV8fQGpO01e+vG2bRCwbGk515zc2pg4moppsRDpakfTtFvCRP9
+9ShS9uiXFZrE0Ru7DKaFMQhDIzrhmSd9G1xWVFujaw6RbEO7k6g+kzZ9ve9TfChQ
+i5wvyWECgYEA6PNmsQuy+5+wWE7tfHbqXk+5+XUwQ/yN5dCrU9OcYmQPBma9ovqb
+fv2lswsyuPxHuI2+P6PAkUEQeb+ZqHPZXPgWqACEIsIsPmrn0/lKI63Io6zjBC+W
+ZN83Wdq3BKALFb6rXozZ8CwhiPUZ5YKe5/aEYcAyL/RbtPbJ1KLoBN8CgYEA3HgB
+ilAfKRnd3hMmv9I1PSetC7Cm3CUrDeL9UuS4j7Rzsoa9IOMfy4mzD9jyYRt7SdW4
+KWhpp/Xbtg9tDOrpEYSGMp/+xvjfgKKq8srztTDGJ4XOCBEL1q8w5wTNIVdm3Y6e
+LP9QElR1UcJPPqK6scrCCdQ++Z50V08n5eh4AUcCgYEAn1ZViIYjD7+jpFOgV4ET
+QB0ybPH+aJJoEKjRd44HqrkcGdnOnpriH1OpsjTXpfZRrGevmOIOBozFkzE+Dh3n
+sJK1FIb92rSMBMmk9rXOQ2dMFMBdq3BNY4PW3WwfwVcjHeWEXDDlpUTaT06vPvBA
+dxOEa0RGT8zJqZcgaIRhRWsCgYBo3D9HTPJ1NxNa49sDU3T1AGEC9WN3w8nlkfgR
+LC5IU3jQCdv8v2pJAdaEDBjEbTDHnno4X6wZMgvtXQruIPD33wOBIq4obwjHAxex
+4SvnGyq0c6TaG1l5I9xrlNIIMK0BZir/lfO8tCUU3QmZ7gZEN/7wc938FgyZ1lFQ
+vbAOUwKBgQDeLdoCQmWseciJ1IMlok4Lpm9qlVrBgQSzEyiLK5CvyqYc4AIR3FYQ
+wsmwO/U5iDNhXyJaX+kxOzL+DSNOeWScx1/hjE+Qs8tirvTCQ9zy0xTeTI2G+oPd
+nylYiwzCOn8M0xwfMTyezm/W1drK0mZZijV05GRZN/6KyuFnQmbn8w==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certificate-authority/client-keys/superproxy.cert.pem 
b/tests/certificate-authority/client-keys/superproxy.cert.pem
new file mode 100644
index 0000000..9656e2c
--- /dev/null
+++ b/tests/certificate-authority/client-keys/superproxy.cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEajCCAlKgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyNjEzMjUxN1oYDzIyOTIwNDEwMTMyNTE3WjAVMRMwEQYDVQQD
+DApzdXBlcnByb3h5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA43Sn
+ys/h3wxJ/IBEzbJdQAKCxU4of5KgTDzFoOaS8C63Nwbjgy0qcWYdRDceP4lJIKSA
+1+JZ+R1opyrfVIC2D9oDJFIJTFfXy9G9VYDccwAONPgAamvRzBnYcEu8fqM+Ohle
+kZltKktAHnX3WtG3RyxEL5nYzlMlGwUXJu3Rxc9SlkYSxERzjWHikGqGmXLX2qB0
+k6oyxTrK+4+EHk3khbEIqyQZSOFbD7NMfnRy0CWFv/9T1shgjAIBCake6jY7lwaT
+S7JvbLfG6ABf5xHMxoWLXa2qwb+Ar43Ff9g8kKZwFOxMeGcwkzyJPBbWytFxaWn+
+R2RHhTaVCGc22CjdfQIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEB
+BAQDAgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFHEgLhfH0Z1QlLxeQbG7YZyBlz1MMB8GA1Ud
+IwQYMBaAFFcL6csj6L9HPlB6P0V+oRhDnRUnMA4GA1UdDwEB/wQEAwIF4DAdBgNV
+HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBAK9q
+3YnEa99Cq3Vo3g6PE/A/xOE97seVNuavqyBcVv9PrTydb5XG4jPkYU3xOYXIc8rA
+A4gzd+AsGO9rjGMPGGjQJI3JO/3BCeBJMkn50C/rM1yWVMHnVyFcJlg16xaWtj1e
+2Jk8egJW2gSYyF+N2TdzI7tOb002GNr36posnqO+IOoLapyHFBxxUjsPDRoo8fJn
+myWsV1Y9oRUZyJlfIAJsu85ew7gDBY2jaiEiopzour3uU3C0N7gYni2OmVwfr6J8
+R2/Jp43BSD5sYOW9RAJIEEXef+InYtz9HTJvKu2LsWwIBkaztk29tJcDE+1La6Sw
+0dF0YkUwnXoGQFjiV+8pXX3TF5glXKj1rU8WfNazF6lqslB6DmdgR3/FQ6Z2sE86
+d9hVtayZIGlzU0rWmBBtr++7Wo88nmzAtd/xbZMFG8U//+Q2AvJT2oVGtqM48+al
+rnsN/gYrLDr7RC14bHIuO1v6ZL/rAi7SPKrKYAyQVTAcRuW516SxxR6S1Xa1ITnh
+rwgKg13eQuwu3iigguIS9XL6nAXabBIxBxMl6o2YlyIPekKYIcQmpqhkavJ6VOgX
+iq9VdY6fIJVfmxNZuwM3/28k7UeUAfhI2SSVH4ZURbPiGGH2wukc1QkmtZ2cNa35
+C1y79aqJbIa3ErqLFPj/fM+34x8L7QHPq6RfaODa
+-----END CERTIFICATE-----
diff --git a/tests/certificate-authority/client-keys/superproxy.csr.pem 
b/tests/certificate-authority/client-keys/superproxy.csr.pem
new file mode 100644
index 0000000..316aeb2
--- /dev/null
+++ b/tests/certificate-authority/client-keys/superproxy.csr.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICWjCCAUICAQAwFTETMBEGA1UEAwwKc3VwZXJwcm94eTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAON0p8rP4d8MSfyARM2yXUACgsVOKH+SoEw8xaDm
+kvAutzcG44MtKnFmHUQ3Hj+JSSCkgNfiWfkdaKcq31SAtg/aAyRSCUxX18vRvVWA
+3HMADjT4AGpr0cwZ2HBLvH6jPjoZXpGZbSpLQB5191rRt0csRC+Z2M5TJRsFFybt
+0cXPUpZGEsREc41h4pBqhply19qgdJOqMsU6yvuPhB5N5IWxCKskGUjhWw+zTH50
+ctAlhb//U9bIYIwCAQmpHuo2O5cGk0uyb2y3xugAX+cRzMaFi12tqsG/gK+NxX/Y
+PJCmcBTsTHhnMJM8iTwW1srRcWlp/kdkR4U2lQhnNtgo3X0CAwEAAaAAMA0GCSqG
+SIb3DQEBCwUAA4IBAQDJtfKA9F+OCFnq3VTBCJAxPxFjic0X6VfvtSVqpL9JHXvs
+cRuNj95a8SR9XHQbMkJKpf4yU6xihPUnkazM7skoZOhKzqC9inBa+pAVdvxuzsG8
+G03rD2VEfLE0qHzwm06NVyP0gEjfmGOuizBGZkK82VeEUHSUqvqtzSlsxyFMqZk/
+X+ypHE3DFPS09IxxdDRdLapBhm0zvHaXArpiKpPUPWuPeb5VSPzT+/ru4MJRqZBL
+eToD1JP6dKPlKIFOSSwqyCGPZuE1HhEvY2B41oxAPt3wCSl6zOXaZ9RU/0HN3zgv
+zHoah245BIPzkU/7XBxjvijiTJIzJny5gpzhwu/L
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/certificate-authority/client-keys/superproxy.key-pk8.pem 
b/tests/certificate-authority/client-keys/superproxy.key-pk8.pem
new file mode 100644
index 0000000..2e4140b
--- /dev/null
+++ b/tests/certificate-authority/client-keys/superproxy.key-pk8.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDjdKfKz+HfDEn8
+gETNsl1AAoLFTih/kqBMPMWg5pLwLrc3BuODLSpxZh1ENx4/iUkgpIDX4ln5HWin
+Kt9UgLYP2gMkUglMV9fL0b1VgNxzAA40+ABqa9HMGdhwS7x+oz46GV6RmW0qS0Ae
+dfda0bdHLEQvmdjOUyUbBRcm7dHFz1KWRhLERHONYeKQaoaZctfaoHSTqjLFOsr7
+j4QeTeSFsQirJBlI4VsPs0x+dHLQJYW//1PWyGCMAgEJqR7qNjuXBpNLsm9st8bo
+AF/nEczGhYtdrarBv4CvjcV/2DyQpnAU7Ex4ZzCTPIk8FtbK0XFpaf5HZEeFNpUI
+ZzbYKN19AgMBAAECggEBAM1JAwuD1drmj3wKFI8F1S2pVndXFCwXnP9RthiDIckO
+kKNkX0CMKgtQ20cu6+jyMgL5FaRCkWvJxCNkCU6OIENsQ3urYuL5QTWeZeBevhg4
+y5m43z8tcptgFD09zbEKCmaLcRO9wo3yfrs/QvE/58efxyajFs8YsZuSW5Px/msl
+AFN8qGY0q0lQbQPK8cPYT4OnW9isqEjkvHq1Q+ryv4cxsGWtBZYmJVeLVHzClihi
+lODdN6YsDcu9jLwsA8o2WSBRsbLHK6caW4FdEwgOLckc0EGGEU64VEB9ZOwgcwYQ
+M9mZDs2w7qk63YnDH4KmpoP0Oc8N+bG7Pkifd7f8HqECgYEA8esMQya6Qln4O7Qo
+aI8X9t5gCpq+bh/P+7vYdBR/9St5VtE/P0yuaQdT2e5t+Ei4ujqHvJ0GTPmqYIJf
+2DNvJMu8EnXv+nqKQCsyMc/nqQN1CcRGqZssH1V/ZIQLRUA0cN4hzE0eHITwp6U9
+vD/WaE3mKX/XHthIjc8hnuoajOkCgYEA8LIYMgyD3wClWOKe5TkBumI0KvA9tP90
+IFHu1wLNl0tKBpsXkzzxiav1FMX3K7B29vxukrs946KRESHzRg4c5ULPnMmwcQyx
+AortKJWrGVsna/QDWPRutXSN1XmnjKWsHmTpQQqLfaRvLW+Hd34+EVdVh9sVt/y9
+RucnBvxcX3UCgYBebm/U7pMaP2BkfcigN+sU1G0M9qaK+iQHkaXGehIQs62js/5K
+STZzjQawNR/8IPbqytodR/YjqflVvs6G6FzkMhrx4dORJLA+qB3pz8wP72eKLnGe
+1xF8EbWumNSFbbCKtkrfIuM0IriF2Dym9QxOnsnPPTXNtoNrx4TKMXu3sQKBgBq9
+noSI8WmoF7adTsvmnnOHj4YptKFUNCGXGLLYg+DII4xCVMct4SPLb+oD6Gb5Lu5X
+sy0oEkMk/3roy68/yCQMXSZtHeYhY9UFfD2jCyRBBUswC+MpHNeaAFv0LRIqIcoq
+qeNo+YBW8WcZ2fIDm3+vtTfntiz/rkOfUK2tAdI1AoGAL2LVDF5e1meSRocEoy8e
+gqrshrhg+KBqYmcjtd4Iup4WvR6uyH4qE9yFLLHFZ04pZzXLHcPfqgOSP8qTxgH3
+h0uqtcYmejS/yl6PbC9OPXcSkMgntRkTbU9Ug05ijfN9NRnW+8WXvi8Z6DKed1P1
+9PxwA75P9o0h00mMk8PQitQ=
+-----END PRIVATE KEY-----
diff --git a/tests/certificate-authority/client-keys/superproxy.key.pem 
b/tests/certificate-authority/client-keys/superproxy.key.pem
new file mode 100644
index 0000000..b9dab24
--- /dev/null
+++ b/tests/certificate-authority/client-keys/superproxy.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA43Snys/h3wxJ/IBEzbJdQAKCxU4of5KgTDzFoOaS8C63Nwbj
+gy0qcWYdRDceP4lJIKSA1+JZ+R1opyrfVIC2D9oDJFIJTFfXy9G9VYDccwAONPgA
+amvRzBnYcEu8fqM+OhlekZltKktAHnX3WtG3RyxEL5nYzlMlGwUXJu3Rxc9SlkYS
+xERzjWHikGqGmXLX2qB0k6oyxTrK+4+EHk3khbEIqyQZSOFbD7NMfnRy0CWFv/9T
+1shgjAIBCake6jY7lwaTS7JvbLfG6ABf5xHMxoWLXa2qwb+Ar43Ff9g8kKZwFOxM
+eGcwkzyJPBbWytFxaWn+R2RHhTaVCGc22CjdfQIDAQABAoIBAQDNSQMLg9Xa5o98
+ChSPBdUtqVZ3VxQsF5z/UbYYgyHJDpCjZF9AjCoLUNtHLuvo8jIC+RWkQpFrycQj
+ZAlOjiBDbEN7q2Li+UE1nmXgXr4YOMuZuN8/LXKbYBQ9Pc2xCgpmi3ETvcKN8n67
+P0LxP+fHn8cmoxbPGLGbkluT8f5rJQBTfKhmNKtJUG0DyvHD2E+Dp1vYrKhI5Lx6
+tUPq8r+HMbBlrQWWJiVXi1R8wpYoYpTg3TemLA3LvYy8LAPKNlkgUbGyxyunGluB
+XRMIDi3JHNBBhhFOuFRAfWTsIHMGEDPZmQ7NsO6pOt2Jwx+CpqaD9DnPDfmxuz5I
+n3e3/B6hAoGBAPHrDEMmukJZ+Du0KGiPF/beYAqavm4fz/u72HQUf/UreVbRPz9M
+rmkHU9nubfhIuLo6h7ydBkz5qmCCX9gzbyTLvBJ17/p6ikArMjHP56kDdQnERqmb
+LB9Vf2SEC0VANHDeIcxNHhyE8KelPbw/1mhN5il/1x7YSI3PIZ7qGozpAoGBAPCy
+GDIMg98ApVjinuU5AbpiNCrwPbT/dCBR7tcCzZdLSgabF5M88Ymr9RTF9yuwdvb8
+bpK7PeOikREh80YOHOVCz5zJsHEMsQKK7SiVqxlbJ2v0A1j0brV0jdV5p4ylrB5k
+6UEKi32kby1vh3d+PhFXVYfbFbf8vUbnJwb8XF91AoGAXm5v1O6TGj9gZH3IoDfr
+FNRtDPamivokB5GlxnoSELOto7P+Skk2c40GsDUf/CD26sraHUf2I6n5Vb7Ohuhc
+5DIa8eHTkSSwPqgd6c/MD+9nii5xntcRfBG1rpjUhW2wirZK3yLjNCK4hdg8pvUM
+Tp7Jzz01zbaDa8eEyjF7t7ECgYAavZ6EiPFpqBe2nU7L5p5zh4+GKbShVDQhlxiy
+2IPgyCOMQlTHLeEjy2/qA+hm+S7uV7MtKBJDJP966MuvP8gkDF0mbR3mIWPVBXw9
+owskQQVLMAvjKRzXmgBb9C0SKiHKKqnjaPmAVvFnGdnyA5t/r7U357Ys/65Dn1Ct
+rQHSNQKBgC9i1QxeXtZnkkaHBKMvHoKq7Ia4YPigamJnI7XeCLqeFr0ersh+KhPc
+hSyxxWdOKWc1yx3D36oDkj/Kk8YB94dLqrXGJno0v8pej2wvTj13EpDIJ7UZE21P
+VINOYo3zfTUZ1vvFl74vGegynndT9fT8cAO+T/aNIdNJjJPD0IrU
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certificate-authority/index.txt 
b/tests/certificate-authority/index.txt
index 218830d..4d69c9b 100644
--- a/tests/certificate-authority/index.txt
+++ b/tests/certificate-authority/index.txt
@@ -1,2 +1,5 @@
 V      22920406085532Z         1000    unknown /CN=broker.pulsar.apache.org
 V      22920406085706Z         1001    unknown /CN=admin
+V      210318101354Z           1002    unknown /CN=ivan
+V      22920409135604Z         1003    unknown /CN=proxy
+V      22920410132517Z         1004    unknown /CN=superproxy
diff --git a/tests/certificate-authority/index.txt.old 
b/tests/certificate-authority/index.txt.old
index 5515351..c64268c 100644
--- a/tests/certificate-authority/index.txt.old
+++ b/tests/certificate-authority/index.txt.old
@@ -1 +1,4 @@
 V      22920406085532Z         1000    unknown /CN=broker.pulsar.apache.org
+V      22920406085706Z         1001    unknown /CN=admin
+V      210318101354Z           1002    unknown /CN=ivan
+V      22920409135604Z         1003    unknown /CN=proxy
diff --git a/tests/certificate-authority/newcerts/1002.pem 
b/tests/certificate-authority/newcerts/1002.pem
new file mode 100644
index 0000000..7602549
--- /dev/null
+++ b/tests/certificate-authority/newcerts/1002.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEYjCCAkqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMB4XDTE4MDYyMjEwMTM1NFoXDTIxMDMxODEwMTM1NFowDzENMAsGA1UEAwwE
+aXZhbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOYoffQM9SSMiSZt
+V167eR8ijudNmM44bAweDJk/RPAkJa7nnsunZm9otY/7sDWT5V2ZQAVHIFMa2qT/
+i2J7no62apzqazDX5g4k1YBtbXexBZvHo7l4NUdk5wGcvQYQ8cjprzS+hA7Iu4x9
+BN8KwKzbg0KS3vfhL0qRoPQZofP7Ao4H+g7Xb8785zU5RvsTLJKU5z3WpSishWG7
+ZSy58PaUrX51lg5D4RGJK6MfN1+p0uzA7pi/pwLzHQZDUl2wDvs1JBJKVQI6FBjK
+Zz78+vqEegA1oAXnhasiDNIcIyGlFApqGm+MuJtvMM2BgQd3VkCdK0glm0UMkUWr
+YSMkKMcCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIFoDAz
+BglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRpZmlj
+YXRlMB0GA1UdDgQWBBTDhMbwEtRTA67cYnyMQYMNivG5wDAfBgNVHSMEGDAWgBRX
+C+nLI+i/Rz5Qej9FfqEYQ50VJzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYwFAYI
+KwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQA0cpz3f/pI9E3Q
+oCVc7ohx8tAkWGFgg62LDn1Xa0/4zJ1XoJoOHqQRffXas0xX3xJKZuWMBtZg/uuR
+0HlcLv6oKDH8DBbU0XHigTF25JBgtmrUuQBth0zR0RMe3jYwmAMFuAfvI4i4ysXE
+h+v0oeVMZMnv8V2fCFpuiBA2hXm1qp6GbuFN7dmxjt6+POGxPkVLYNGS/5rLXaRp
+qIQ6TZvA4A71uERM/bizO8pV0aIKzdrJ/94wGlDFRlGkSkcRMRz9gaCqb368sy4P
+WFLOELC8WkfQ38g2fgXX31rt+E1r2yYzku/rnID3pj2OyDfPWKxQxGsZNbHz3VLU
+XJ70DJNMU8Iv003XlTcy30VvDMKqyYFiN86qS2Hr+z24eMq+fgIHZtE9rzoTQTau
+stxUn/YS8tozeEb7ABaBFZhRC5rkWJKI+0LSDiAkIhqq4cXzsN+fBfl94lXboFzr
+ta54Wpv5TRggikylFLyKERGECHmFp9dHnk7n2+3pU7ZZaG4S9ZZrEufJvc+mdRAy
+XgvKrXW7HphaRO7lwSZDABsuJ2blH8dW8kqvXOiklf72iCZIlVRsBpjm9eDvBXJd
+pfaObag9eKsmQTsO7CYf5gNxfDBPtSBpzElWlC+GF1EaGHVzPD+h+kFF9FLth/p+
+NUK5J+p271foXpiKDXVHFxhSQSPeFA==
+-----END CERTIFICATE-----
diff --git a/tests/certificate-authority/newcerts/1003.pem 
b/tests/certificate-authority/newcerts/1003.pem
new file mode 100644
index 0000000..6c2f429
--- /dev/null
+++ b/tests/certificate-authority/newcerts/1003.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEZTCCAk2gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyNTEzNTYwNFoYDzIyOTIwNDA5MTM1NjA0WjAQMQ4wDAYDVQQD
+DAVwcm94eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMieX78Yj8OW
+eBHAneRaCCoO8Qrpj8zGo7h9lCdmi1lBDh1uR2sDbotiHGfJzQn836WcYmyeAvfn
+qvgr9HCXmXdLgmJ3GT/LVu5GEm6msSDiZQPr9so5lQVioisK4UwJROQsE/J52cyR
+9o3H6M4FKb6QpoobKa62fSfTumwwulaYaDJuRRGoGIkcRuUQ59EWAaDkD3IcDpAn
+9mTbnE4Iz+JxSrsZ5DJ3X/m/AqyLWtj6GAfyK9a1dhNdlf2x4JZT1QNtojiBXt95
+OIZyRBNbHMFniq5gel6wdBkmJWutfcTct7wKa2LCxLpKoDIc1HWoL3+RUzOKxYIP
+0qXEQ3bmONkCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIF
+oDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0ZWQgQ2xpZW50IENlcnRp
+ZmljYXRlMB0GA1UdDgQWBBSgsgfmDbXEkrrpHUC9GnDDjxaKizAfBgNVHSMEGDAW
+gBRXC+nLI+i/Rz5Qej9FfqEYQ50VJzAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0lBBYw
+FAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4ICAQB+uZ2OWR+G
+sRqYHEeVqUI8G2p8Np8eC/onGpBL8Gj9SGxIQcIPtqHPUlCe9fd/96JOptOGRYEB
+BmUCaCmQ4IgMW6e6fArka5IB4XXIgHFXyQ6ImTvjDavzlVw06zn9S4dLwVzsRBg+
+GS9svtq23W+f5rEN5N+7LhtcbclfiG4VCCqDG5VhkzEok+SRamDI8rDRZtodMw0O
+/+L+xaaQPUPjX8KUlKn4uVpCDbxUzHonlCPzbkHHm5su0D4ysjJIy3/y3yow6JE/
+02L7PZkmkmw3/V+84T3X8/GD15sVUv/3v1gXEBxYwAs+RNTJ0APvMEMSvCq0AMfF
+bPMZBuAGNBG7lv7TovzHgGFKXT7du5OFF/qjAsEffhbo224CB96fgwvvndwHHBFh
+J06BvHZG1i9dDVhUKoB1owkWrE4RZv2ZKEtZYgizzSmzZRHtARo0t1Byc5djx1tX
+TkJOHshNqJZOY1ER0DPaVQgKI+PRTbEdj/xPGRX3ebSqDmilAfPXshqgElfch6Yl
+f2V58TyCnjXOibvkG9D5OyCdWLEECumOZgYar0KZgNfrvTOi1OKXnX1fsbh29fWA
+ICZRcdmjkz79zQXY2SuzCWlskuXPKAmW1AMqs+l6ormmKfzIUx3Yriy4LqIIYY1v
+uQD5vghZmd9HUg2KaXfSGD9stGCD8KhntA==
+-----END CERTIFICATE-----
diff --git a/tests/certificate-authority/newcerts/1004.pem 
b/tests/certificate-authority/newcerts/1004.pem
new file mode 100644
index 0000000..9656e2c
--- /dev/null
+++ b/tests/certificate-authority/newcerts/1004.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEajCCAlKgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwETEPMA0GA1UEAwwGZm9v
+YmFyMCAXDTE4MDYyNjEzMjUxN1oYDzIyOTIwNDEwMTMyNTE3WjAVMRMwEQYDVQQD
+DApzdXBlcnByb3h5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA43Sn
+ys/h3wxJ/IBEzbJdQAKCxU4of5KgTDzFoOaS8C63Nwbjgy0qcWYdRDceP4lJIKSA
+1+JZ+R1opyrfVIC2D9oDJFIJTFfXy9G9VYDccwAONPgAamvRzBnYcEu8fqM+Ohle
+kZltKktAHnX3WtG3RyxEL5nYzlMlGwUXJu3Rxc9SlkYSxERzjWHikGqGmXLX2qB0
+k6oyxTrK+4+EHk3khbEIqyQZSOFbD7NMfnRy0CWFv/9T1shgjAIBCake6jY7lwaT
+S7JvbLfG6ABf5xHMxoWLXa2qwb+Ar43Ff9g8kKZwFOxMeGcwkzyJPBbWytFxaWn+
+R2RHhTaVCGc22CjdfQIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEB
+BAQDAgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQg
+Q2VydGlmaWNhdGUwHQYDVR0OBBYEFHEgLhfH0Z1QlLxeQbG7YZyBlz1MMB8GA1Ud
+IwQYMBaAFFcL6csj6L9HPlB6P0V+oRhDnRUnMA4GA1UdDwEB/wQEAwIF4DAdBgNV
+HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBAK9q
+3YnEa99Cq3Vo3g6PE/A/xOE97seVNuavqyBcVv9PrTydb5XG4jPkYU3xOYXIc8rA
+A4gzd+AsGO9rjGMPGGjQJI3JO/3BCeBJMkn50C/rM1yWVMHnVyFcJlg16xaWtj1e
+2Jk8egJW2gSYyF+N2TdzI7tOb002GNr36posnqO+IOoLapyHFBxxUjsPDRoo8fJn
+myWsV1Y9oRUZyJlfIAJsu85ew7gDBY2jaiEiopzour3uU3C0N7gYni2OmVwfr6J8
+R2/Jp43BSD5sYOW9RAJIEEXef+InYtz9HTJvKu2LsWwIBkaztk29tJcDE+1La6Sw
+0dF0YkUwnXoGQFjiV+8pXX3TF5glXKj1rU8WfNazF6lqslB6DmdgR3/FQ6Z2sE86
+d9hVtayZIGlzU0rWmBBtr++7Wo88nmzAtd/xbZMFG8U//+Q2AvJT2oVGtqM48+al
+rnsN/gYrLDr7RC14bHIuO1v6ZL/rAi7SPKrKYAyQVTAcRuW516SxxR6S1Xa1ITnh
+rwgKg13eQuwu3iigguIS9XL6nAXabBIxBxMl6o2YlyIPekKYIcQmpqhkavJ6VOgX
+iq9VdY6fIJVfmxNZuwM3/28k7UeUAfhI2SSVH4ZURbPiGGH2wukc1QkmtZ2cNa35
+C1y79aqJbIa3ErqLFPj/fM+34x8L7QHPq6RfaODa
+-----END CERTIFICATE-----
diff --git a/tests/certificate-authority/serial 
b/tests/certificate-authority/serial
index 7d802a3..49bc272 100644
--- a/tests/certificate-authority/serial
+++ b/tests/certificate-authority/serial
@@ -1 +1 @@
-1002
+1005
diff --git a/tests/certificate-authority/serial.old 
b/tests/certificate-authority/serial.old
index dd11724..59c1122 100644
--- a/tests/certificate-authority/serial.old
+++ b/tests/certificate-authority/serial.old
@@ -1 +1 @@
-1001
+1004

Reply via email to