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

yuzhou pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/rocketmq.git


The following commit(s) were added to refs/heads/develop by this push:
     new 4a29b7e0bf [ISSUE #10077] Support password-encrypted private keys for 
Proxy TLS (#10078)
4a29b7e0bf is described below

commit 4a29b7e0bf145be4fdb3001295f1bab520f67d84
Author: majialong <[email protected]>
AuthorDate: Fri Mar 13 14:27:49 2026 +0800

    [ISSUE #10077] Support password-encrypted private keys for Proxy TLS 
(#10078)
    
    * [ISSUE #10077] Support password-encrypted private keys for Proxy TLS
    
    * Fix bazel error
    
    * Fix unit test
    
    * Add comments
---
 docs/cn/Configuration_TLS.md                       | 43 ++++++++++++++++-
 docs/en/Configuration_TLS.md                       | 41 +++++++++++++++-
 proxy/BUILD.bazel                                  |  2 +-
 .../apache/rocketmq/proxy/config/ProxyConfig.java  |  9 ++++
 .../proxy/grpc/ProxyAndTlsProtocolNegotiator.java  |  4 +-
 .../proxy/remoting/RemotingProtocolServer.java     |  2 +
 .../grpc/ProxyAndTlsProtocolNegotiatorTest.java    | 55 +++++++++++++++++++++-
 proxy/src/test/resources/certs/client.key          | 17 +++++++
 proxy/src/test/resources/certs/client.pem          | 19 ++++++++
 proxy/src/test/resources/certs/server.key          | 16 +++++++
 proxy/src/test/resources/certs/server.pem          | 19 ++++++++
 11 files changed, 221 insertions(+), 6 deletions(-)

diff --git a/docs/cn/Configuration_TLS.md b/docs/cn/Configuration_TLS.md
index 46daf5d3ef..fe83710db9 100644
--- a/docs/cn/Configuration_TLS.md
+++ b/docs/cn/Configuration_TLS.md
@@ -126,6 +126,45 @@ public class ExampleProducer {
 
         // Send messages as usual.
         producer.shutdown();
-    }    
+    }
 }
-```
\ No newline at end of file
+```
+
+## 5 Proxy TLS 配置
+
+RocketMQ Proxy 使用 `rmq-proxy.json`(而非 `tls.properties`)进行 TLS 配置。Proxy 的 gRPC 
和 Remoting 协议端口均支持 TLS。
+
+### 5.1 配置 rmq-proxy.json
+
+在 `distribution/conf/rmq-proxy.json` 中添加 TLS 相关字段:
+
+```json
+{
+  "rocketMQClusterName": "DefaultCluster",
+  "tlsTestModeEnable": false,
+  "tlsKeyPath": "/opt/certFiles/server.key",
+  "tlsKeyPassword": "123456",
+  "tlsCertPath": "/opt/certFiles/server.pem"
+}
+```
+
+| 字段 | 类型 | 默认值 | 说明 |
+|------|------|--------|------|
+| `tlsTestModeEnable` | boolean | `true` | 是否使用自签名测试证书,生产环境需设为 `false` |
+| `tlsKeyPath` | string | `${PROXY_HOME}/conf/tls/rocketmq.key` | 
服务端私钥文件路径(PKCS#8 PEM 格式) |
+| `tlsKeyPassword` | string | `""` | 加密私钥的密码,私钥未加密时留空 |
+| `tlsCertPath` | string | `${PROXY_HOME}/conf/tls/rocketmq.crt` | 
服务端证书链文件路径(X.509 PEM 格式) |
+| `tlsCertWatchIntervalMs` | int | `3600000` | 证书文件变更检测间隔(毫秒) |
+
+### 5.2 配置 Proxy 启动参数
+
+编辑 `runproxy.sh`(或启动 Proxy 的脚本),启用 TLS enforcing 模式:
+
+```shell
+JAVA_OPT="${JAVA_OPT} -Dtls.server.mode=enforcing"
+```
+
+三种 TLS 模式说明:
+- `disabled` - 不支持 TLS,拒绝所有 TLS 握手请求
+- `permissive` - TLS 可选,同时接受 TLS 和非 TLS 连接
+- `enforcing` - 强制 TLS,拒绝非 TLS 连接
\ No newline at end of file
diff --git a/docs/en/Configuration_TLS.md b/docs/en/Configuration_TLS.md
index f9716f92f5..54a63f4ab1 100644
--- a/docs/en/Configuration_TLS.md
+++ b/docs/en/Configuration_TLS.md
@@ -118,6 +118,45 @@ public class ExampleProducer {
 
         // Send messages as usual.
         producer.shutdown();
-    }    
+    }
 }
 ```
+
+## 5 Proxy TLS Configuration
+
+RocketMQ Proxy uses `rmq-proxy.json` (not `tls.properties`) for TLS 
configuration. The proxy supports TLS for both its gRPC and Remoting protocol 
endpoints.
+
+### 5.1 Configure rmq-proxy.json
+
+Add TLS-related fields to `distribution/conf/rmq-proxy.json`:
+
+```json
+{
+  "rocketMQClusterName": "DefaultCluster",
+  "tlsTestModeEnable": false,
+  "tlsKeyPath": "/opt/certFiles/server.key",
+  "tlsKeyPassword": "123456",
+  "tlsCertPath": "/opt/certFiles/server.pem"
+}
+```
+
+| Field | Type | Default | Description |
+|-------|------|---------|-------------|
+| `tlsTestModeEnable` | boolean | `true` | Use self-signed certificates for 
testing. Set to `false` for production. |
+| `tlsKeyPath` | string | `${PROXY_HOME}/conf/tls/rocketmq.key` | Path to the 
server private key file (PKCS#8 PEM format). |
+| `tlsKeyPassword` | string | `""` | Password for the encrypted private key. 
Leave empty if the key is not encrypted. |
+| `tlsCertPath` | string | `${PROXY_HOME}/conf/tls/rocketmq.crt` | Path to the 
server certificate chain file (X.509 PEM format). |
+| `tlsCertWatchIntervalMs` | int | `3600000` | Interval in milliseconds to 
check for certificate file changes. |
+
+### 5.2 Update Proxy JVM parameters
+
+Edit `runproxy.sh` (or the script that launches the proxy) to enable TLS 
enforcing mode:
+
+```shell
+JAVA_OPT="${JAVA_OPT} -Dtls.server.mode=enforcing"
+```
+
+The three available TLS modes are:
+- `disabled` - TLS is not supported; incoming TLS handshakes are rejected.
+- `permissive` - TLS is optional; the proxy accepts both TLS and non-TLS 
connections.
+- `enforcing` - TLS is required; non-TLS connections are rejected.
diff --git a/proxy/BUILD.bazel b/proxy/BUILD.bazel
index 5d7fe24435..c0655ec698 100644
--- a/proxy/BUILD.bazel
+++ b/proxy/BUILD.bazel
@@ -75,7 +75,7 @@ java_library(
         "src/test/resources/rmq-proxy-home/conf/broker.conf",
         "src/test/resources/rmq-proxy-home/conf/logback_proxy.xml",
         "src/test/resources/rmq-proxy-home/conf/rmq-proxy.json",
-    ],
+    ] + glob(["src/test/resources/certs/*.pem"]) + 
glob(["src/test/resources/certs/*.key"]),
     visibility = ["//visibility:public"],
     deps = [
            "//auth",
diff --git 
a/proxy/src/main/java/org/apache/rocketmq/proxy/config/ProxyConfig.java 
b/proxy/src/main/java/org/apache/rocketmq/proxy/config/ProxyConfig.java
index cc75947966..d44b82aff5 100644
--- a/proxy/src/main/java/org/apache/rocketmq/proxy/config/ProxyConfig.java
+++ b/proxy/src/main/java/org/apache/rocketmq/proxy/config/ProxyConfig.java
@@ -81,6 +81,7 @@ public class ProxyConfig implements ConfigFile {
      */
     private boolean tlsTestModeEnable = true;
     private String tlsKeyPath = ConfigurationManager.getProxyHome() + 
"/conf/tls/rocketmq.key";
+    private String tlsKeyPassword = "";
     private String tlsCertPath = ConfigurationManager.getProxyHome() + 
"/conf/tls/rocketmq.crt";
     private int tlsCertWatchIntervalMs = 60 * 60 * 1000; // 1 hour
     /**
@@ -501,6 +502,14 @@ public class ProxyConfig implements ConfigFile {
         this.tlsKeyPath = tlsKeyPath;
     }
 
+    public String getTlsKeyPassword() {
+        return tlsKeyPassword;
+    }
+
+    public void setTlsKeyPassword(String tlsKeyPassword) {
+        this.tlsKeyPassword = tlsKeyPassword;
+    }
+
     public String getTlsCertPath() {
         return tlsCertPath;
     }
diff --git 
a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java
 
b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java
index 43e2c8ae34..4222dacaad 100644
--- 
a/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java
+++ 
b/proxy/src/main/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiator.java
@@ -123,12 +123,14 @@ public class ProxyAndTlsProtocolNegotiator implements 
InternalProtocolNegotiator
         } else {
             String tlsCertPath = 
ConfigurationManager.getProxyConfig().getTlsCertPath();
             String tlsKeyPath = 
ConfigurationManager.getProxyConfig().getTlsKeyPath();
+            String tlsKeyPassword = 
ConfigurationManager.getProxyConfig().getTlsKeyPassword();
             try (InputStream serverKeyInputStream = Files.newInputStream(
                 Paths.get(tlsKeyPath));
                  InputStream serverCertificateStream = Files.newInputStream(
                      Paths.get(tlsCertPath))) {
                 sslContext = GrpcSslContexts.forServer(serverCertificateStream,
-                        serverKeyInputStream)
+                        serverKeyInputStream,
+                        StringUtils.isNotBlank(tlsKeyPassword) ? 
tlsKeyPassword : null)
                     .trustManager(InsecureTrustManagerFactory.INSTANCE)
                     .clientAuth(ClientAuth.NONE)
                     .build();
diff --git 
a/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java
 
b/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java
index da130769ab..a01c23fce6 100644
--- 
a/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java
+++ 
b/proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java
@@ -118,6 +118,8 @@ public class RemotingProtocolServer implements 
StartAndShutdown, RemotingProxyOu
         System.setProperty(TlsSystemConfig.TLS_SERVER_CERTPATH, 
config.getTlsCertPath());
         TlsSystemConfig.tlsServerKeyPath = config.getTlsKeyPath();
         System.setProperty(TlsSystemConfig.TLS_SERVER_KEYPATH, 
config.getTlsKeyPath());
+        TlsSystemConfig.tlsServerKeyPassword = config.getTlsKeyPassword();
+        System.setProperty(TlsSystemConfig.TLS_SERVER_KEYPASSWORD, 
config.getTlsKeyPassword());
         this.tlsCertificateManager = tlsCertificateManager;
         this.tlsReloadHandler = new RemotingTlsReloadHandler();
 
diff --git 
a/proxy/src/test/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiatorTest.java
 
b/proxy/src/test/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiatorTest.java
index 9034da7f36..2509f26b44 100644
--- 
a/proxy/src/test/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiatorTest.java
+++ 
b/proxy/src/test/java/org/apache/rocketmq/proxy/grpc/ProxyAndTlsProtocolNegotiatorTest.java
@@ -20,8 +20,15 @@ import io.grpc.Attributes;
 import io.grpc.netty.shaded.io.netty.buffer.ByteBuf;
 import io.grpc.netty.shaded.io.netty.buffer.Unpooled;
 import io.grpc.netty.shaded.io.netty.handler.codec.haproxy.HAProxyTLV;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
 import org.apache.rocketmq.proxy.config.ConfigurationManager;
+import org.apache.rocketmq.proxy.config.ProxyConfig;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -39,6 +46,15 @@ public class ProxyAndTlsProtocolNegotiatorTest {
         negotiator = new ProxyAndTlsProtocolNegotiator();
     }
 
+    @After
+    public void tearDown() {
+        ProxyConfig proxyConfig = ConfigurationManager.getProxyConfig();
+        proxyConfig.setTlsTestModeEnable(true);
+        proxyConfig.setTlsKeyPath("");
+        proxyConfig.setTlsCertPath("");
+        proxyConfig.setTlsKeyPassword("");
+    }
+
     @Test
     public void handleHAProxyTLV() {
         ByteBuf content = Unpooled.buffer();
@@ -46,4 +62,41 @@ public class ProxyAndTlsProtocolNegotiatorTest {
         HAProxyTLV haProxyTLV = new HAProxyTLV((byte) 0xE1, content);
         negotiator.handleHAProxyTLV(haProxyTLV, Attributes.newBuilder());
     }
-}
\ No newline at end of file
+
+    @Test
+    public void testLoadSslContextWithUnencryptedKey() throws Exception {
+        configureTls("server.key", "server.pem", "");
+        ProxyAndTlsProtocolNegotiator.loadSslContext();
+    }
+
+    @Test
+    public void testLoadSslContextWithEncryptedKey() throws Exception {
+        // "1234" is the password of certs/client.key, inherited from remoting 
module test resources
+        configureTls("client.key", "client.pem", "1234");
+        ProxyAndTlsProtocolNegotiator.loadSslContext();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testLoadSslContextWithWrongPassword() throws Exception {
+        configureTls("client.key", "client.pem", "wrong_password");
+        ProxyAndTlsProtocolNegotiator.loadSslContext();
+    }
+
+    private void configureTls(String keyFile, String certFile, String 
password) throws IOException {
+        ProxyConfig proxyConfig = ConfigurationManager.getProxyConfig();
+        proxyConfig.setTlsTestModeEnable(false);
+        proxyConfig.setTlsKeyPath(getCertsPath(keyFile));
+        proxyConfig.setTlsCertPath(getCertsPath(certFile));
+        proxyConfig.setTlsKeyPassword(password);
+    }
+
+    private static String getCertsPath(String fileName) throws IOException {
+        File tempFile = File.createTempFile(fileName, null);
+        tempFile.deleteOnExit();
+        try (InputStream is = ProxyAndTlsProtocolNegotiatorTest.class
+            .getClassLoader().getResourceAsStream("certs/" + fileName)) {
+            Files.copy(is, tempFile.toPath(), 
StandardCopyOption.REPLACE_EXISTING);
+        }
+        return tempFile.getAbsolutePath();
+    }
+}
diff --git a/proxy/src/test/resources/certs/client.key 
b/proxy/src/test/resources/certs/client.key
new file mode 100644
index 0000000000..c30daea2b9
--- /dev/null
+++ b/proxy/src/test/resources/certs/client.key
@@ -0,0 +1,17 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIICoTAbBgkqhkiG9w0BBQMwDgQI1vtPpDhOYRcCAggABIICgMHwgw0p9fx95R/+
+cWnNdEq8I3ZOOy2wDjammFvPrYXcCJzS3Xg/0GDJ8pdJRKrI7253e4u3mxf5oMuY
+RrvpB3KfdelU1k/5QKqOxL/N0gQafQLViN53f6JelyBEAmO1UxQtKZtkTrdZg8ZP
+0u1cPPWxmgNdn1Xx3taMw+Wo05ysHjnHJhOEDQ2WT3VXigiRmFSX3H567yjYMRD+
+zmvBq+qqR9JPbH9Cn7X1oRXX6c8VsZHWF/Ds0I4i+5zJxsSIuNZxjZw9XXNgXtFv
+7FEFC0HDgDQQUY/FNPUbmjQUp1y0YxoOBjlyIqBIx5FWxu95p2xITS0OimQPFT0o
+IngaSb+EKRDhqpLxxIVEbDdkQrdRqcmmLGJioAysExTBDsDwkaEJGOp44bLDM4QW
+SIA9SB01omuCXgn7RjUyVXb5g0Lz+Nvsfp1YXUkPDO9hILfz3eMHDSW7/FzbB81M
+r8URaTagQxBZnvIoCoWszLDXn3JwEjpZEA6y55Naptps3mMRf7+XMt42lX0e4y9a
+ogNu5Zw/RZD9YcaTjC2z5XeKiMCs1Ymhy9iuzbo+eRGESqzvUE4VirtsiEwxJRci
+JHAvuAl3X4XnpTty4ahOU+DihM9lALxdU68CN9++7mx581pYuvjzrV+Z5+PuptZX
+AjCZmkZLDh8TCHSzWRqvP/Hcvo9BjW8l1Lq6tOa222PefSNCc6gs6Hq+jUghbabZ
+/ux4WuFc0Zd6bfQWAZohSvd78/ixsdJPNGm2OP+LUIrEDKIkLuH1PM0uq4wzJZNu
+Bo7oJ5iFWF67u3MC8oq+BqOVKDNWaCMi7iiSrN2XW8FBo/rpx4Lf/VYREL+Y0mP6
+vzJrZqw=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/proxy/src/test/resources/certs/client.pem 
b/proxy/src/test/resources/certs/client.pem
new file mode 100644
index 0000000000..cb6580d900
--- /dev/null
+++ b/proxy/src/test/resources/certs/client.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDATCCAekCAQIwDQYJKoZIhvcNAQEFBQAwfDELMAkGA1UEBhMCemgxCzAJBgNV
+BAgMAnpqMQswCQYDVQQHDAJoejEPMA0GA1UECgwGYXBhY2hlMREwDwYDVQQLDAhy
+b2NrZXRtcTEOMAwGA1UEAwwFeXVrb24xHzAdBgkqhkiG9w0BCQEWEHl1a29uQGFw
+YWNoZS5vcmcwIBcNMTgwMTE2MDYxNjQ0WhgPMjExNzEyMjMwNjE2NDRaMIGSMQsw
+CQYDVQQGEwJDTjERMA8GA1UECAwIWmhlamlhbmcxETAPBgNVBAcMCEhhbmd6aG91
+MQ8wDQYDVQQKDAZhcGFjaGUxETAPBgNVBAsMCHJvY2tldG1xMRgwFgYDVQQDDA9h
+cGFjaGUgcm9ja2V0bXExHzAdBgkqhkiG9w0BCQEWEHl1a29uQGFwYWNoZS5vcmcw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjPlSjZk37XLBJBc5G/qQNsNdVD
+vZnEGntrqW0UuHjF2T/LPtsGOavLP5wCHvn2zwMR2eCXZwKdKIzSvk0L3XOjH/XY
+OLgRa3cg90lV7Wzn9UMGq3nOjFtjIODPjtz3lwYAuAt1MH+K0E+ChuCFBgFqdY9U
+E0suW3DX0Mt/WB3pAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFGPaZKyCZzQihKj
+n/7I1J0wKl1HrU7N4sOie8E+ntcpKeX9zKYAou/4Iy0qwgxgRsnucB1rDous560a
++8DFDU8+FnikK9cQtKfQqu4F266IkkXolviZMSfkmB+NIsByIl95eMJlQHVlAvnX
+vnpGdhD/Jhs+acE1VHhO6K+8omKLA6Og8MmYGRwmnBLcxIvqoSNDlEShfQyjaECg
+I4bEi4ZhH3lSHE46FybJdoxDbj9IjHWqpOnjM23EOyfd1zcwOZJA7a54kfOpiTjz
+wrtes5yoQznun5WtGcLM8ZmyaQ+Jr3j6NyZhOwULzK1+A8YUsW6Ww39xTxQoIHEQ
+7eirb54=
+-----END CERTIFICATE-----
diff --git a/proxy/src/test/resources/certs/server.key 
b/proxy/src/test/resources/certs/server.key
new file mode 100644
index 0000000000..30df69619e
--- /dev/null
+++ b/proxy/src/test/resources/certs/server.key
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOsmp4YtrIRsBdBQ
+LyPImafCRynTJls3NNF4g6nZr9e0efBY830gw9kBebcm603sdZNl95fzRr2+srXi
+5FJbG7Fmq1+F0xLNK/kKWirGtNMT2DubmhVdKyXYJSvInoGRkrQzbOG0MdAyzE6Q
+O6OjjNN+xGkmadWyCyNF6S8YqMJTAgMBAAECgYEAj0OlnOIG0Ube4+N2VN7KfqKm
+qJy0Ka6gx14dGUY/E7Qo9n27GujzaSq09RkJExiVKZBeIH1fBAtC5f2uDV7kpy0l
+uNpTpQkbw0g2EQLxDsVwaUEYbu+t9qVeXoDd1vFeoXHBuRwvI9UW1BrxVtvKODia
+5StU8Lw4yjcm2lQalwECQQD/sKj56thIsIY7D9qBHk7fnFLd8aYzhnP2GsbZX4V/
+T1KHRxr/8MqdNQX53DE5qcyM/Mqu95FIpTAniUtvcBujAkEA62+fAMYFTAEWj4Z4
+vCmcoPqfVPWhBKFR/wo3L8uUARiIzlbYNU3LIqC2s16QO50+bLUd41oVHNw9Y+uM
+fxQpkQJACg/WpncSadHghmR6UchyjCQnsqo2wyJQX+fv2VAD/d2OPtqSem3sW0Fh
+6dI7cax36zhrdXUyl2xAt92URV9hBwJALX93sdWSxnpbWsc449wCydVFH00MnfFz
+AB+ARLtJ0eBk58M+qyZqgDmgtQ8sPmkH3EgwC3SoKdiiAIJPt2s1EQJBAKnISZZr
+qB2F2PfAW2JJbQlrPyVzkxhv9XYdiVNOErmuxLFae3AI7nECgGuFBtvmeqzm2yRj
+7RBMCmzyWG7MF3o=
+-----END PRIVATE KEY-----
diff --git a/proxy/src/test/resources/certs/server.pem 
b/proxy/src/test/resources/certs/server.pem
new file mode 100644
index 0000000000..0187247af2
--- /dev/null
+++ b/proxy/src/test/resources/certs/server.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDATCCAekCAQIwDQYJKoZIhvcNAQEFBQAwfDELMAkGA1UEBhMCemgxCzAJBgNV
+BAgMAnpqMQswCQYDVQQHDAJoejEPMA0GA1UECgwGYXBhY2hlMREwDwYDVQQLDAhy
+b2NrZXRtcTEOMAwGA1UEAwwFeXVrb24xHzAdBgkqhkiG9w0BCQEWEHl1a29uQGFw
+YWNoZS5vcmcwIBcNMTgwMTE2MDYxMzQ5WhgPMjExNzEyMjMwNjEzNDlaMIGSMQsw
+CQYDVQQGEwJDTjERMA8GA1UECAwIWmhlamlhbmcxETAPBgNVBAcMCEhhbmd6aG91
+MQ8wDQYDVQQKDAZhcGFjaGUxETAPBgNVBAsMCHJvY2tldG1xMRgwFgYDVQQDDA9h
+cGFjaGUgcm9ja2V0bXExHzAdBgkqhkiG9w0BCQEWEHl1a29uQGFwYWNoZS5vcmcw
+gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOsmp4YtrIRsBdBQLyPImafCRynT
+Jls3NNF4g6nZr9e0efBY830gw9kBebcm603sdZNl95fzRr2+srXi5FJbG7Fmq1+F
+0xLNK/kKWirGtNMT2DubmhVdKyXYJSvInoGRkrQzbOG0MdAyzE6QO6OjjNN+xGkm
+adWyCyNF6S8YqMJTAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAAzbwXyAULmXitiU
++8/2vbUZQlzB/nXY52OIq7qu3F55hE5qlHkcVxG2JZjO3p5UETwOyNUpU4dpu3uT
+7WSdygH4Iagl87ILpGsob9pAf0joAbaXAY4sGDhg+WjR5JInAxbmT+QWZ+4NTuLQ
+fSudUSJrv+HmUlmcVOvLiNStgt9rbtcgJAvpVwY+iCv0HQziFuQxmOkDv09ZLzu/
+lxCMqnbgkEFYkwdntN6MVk38K3MovszedGO/n19hNOFss7nn5XDEeEnc6BqKGdck
+YDoy6amohY0Ds0o0gJ2rq0Y8Gjl9spQ3oeXpoNUoz84OF4KIBRTzSMv8CrmqPdFY
+Zd2MGjw=
+-----END CERTIFICATE-----

Reply via email to