solution: allow TLS configuration for proxy

This commit is contained in:
Igor Artamonov
2020-03-20 20:22:01 -04:00
parent 26f8dd294e
commit d4bd180e23
25 changed files with 882 additions and 72 deletions

View File

@@ -0,0 +1,191 @@
/**
* Copyright (c) 2020 ETCDEV GmbH
*
* Licensed 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 io.emeraldpay.dshackle
import io.emeraldpay.dshackle.config.AuthConfig
import io.netty.handler.ssl.ClientAuth
import io.netty.handler.ssl.OpenSslServerContext
import spock.lang.Specification
import sun.security.x509.X509CertImpl
class TlsSetupSpec extends Specification {
TlsSetup tlsSetup = new TlsSetup(new FileResolver(new File("src/test/resources/tls-local")))
def "TLS disabled"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: false
)
when:
def act = tlsSetup.setupServer("test", config)
then:
act == null
}
def "TLS enabled"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "127.0.0.1.p8.key"
)
when:
def act = tlsSetup.setupServer("test", config)
then:
act != null
act.server
!act.client
with((OpenSslServerContext) act) {
act.clientAuth == ClientAuth.NONE
with((X509CertImpl) keyCertChain[0]) {
getIssuerDN().name == "CN=ca.myhost.dev, OU=Blockchain CA, O=My Company"
}
}
}
def "TLS enabled and required from client"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "127.0.0.1.p8.key",
clientRequire: true,
clientCa: "ca.myhost.dev.crt"
)
when:
def act = tlsSetup.setupServer("test", config)
then:
act != null
act.server
!act.client
with((OpenSslServerContext) act) {
act.clientAuth == ClientAuth.REQUIRE
with((X509CertImpl) keyCertChain[0]) {
getIssuerDN().name == "CN=ca.myhost.dev, OU=Blockchain CA, O=My Company"
}
}
}
def "Fail if certificate not set"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
key: "127.0.0.1.p8.key",
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
t.message == "Certificate not set"
}
def "Fail if certificate key not set"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt"
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
t.message == "Certificate Key not set"
}
def "Fail if certificate not exists"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "none.crt",
key: "127.0.0.1.p8.key",
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
}
def "Fail if certificate key not exists"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "none.p8.key",
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
}
def "Fail if certificate key is invalid"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "127.0.0.1.key",
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
}
def "Fail if client certificate not set but required"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "127.0.0.1.p8.key",
clientRequire: true
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
}
def "Fail if client certificate not exists"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "127.0.0.1.p8.key",
clientRequire: true,
clientCa: "none.crt"
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
}
def "Fail if client certificate is invalid"() {
setup:
def config = new AuthConfig.ServerTlsAuth(
enabled: true,
certificate: "127.0.0.1.crt",
key: "127.0.0.1.p8.key",
clientRequire: true,
clientCa: "ca.myhost.dev.key"
)
when:
tlsSetup.setupServer("test", config)
then:
def t = thrown(IllegalArgumentException)
}
}

View File

@@ -0,0 +1,62 @@
package io.emeraldpay.dshackle.config
import spock.lang.Specification
class AuthConfigReaderSpec extends Specification {
AuthConfigReader reader = new AuthConfigReader()
def "Read basic-auth for client"() {
setup:
def yaml =
"basic-auth:\n" +
" username: 9c199ad8f281f20154fc258fe41a6814\n" +
" password: 258fe4149c199ad8f2811a68f20154fc"
when:
def act = reader.readClientBasicAuth(reader.readNode(yaml))
then:
act != null
act.username == "9c199ad8f281f20154fc258fe41a6814"
act.password == "258fe4149c199ad8f2811a68f20154fc"
}
def "Read tls for client"() {
setup:
def yaml =
"tls:\n" +
" ca: /etc/ca.myservice.com.crt\n" +
" certificate: /etc/client1.myservice.com.crt\n" +
" key: /etc/client1.myservice.com.key"
when:
def act = reader.readClientTls(reader.readNode(yaml))
then:
act != null
act.ca == "/etc/ca.myservice.com.crt"
act.certificate == "/etc/client1.myservice.com.crt"
act.key == "/etc/client1.myservice.com.key"
}
def "Read tls for server"() {
setup:
def yaml =
"tls:\n" +
" enabled: true\n" +
" server:\n" +
" certificate: \"/etc/client1.myservice.com.crt\"\n" +
" key: \"/etc/client1.myservice.com.key\"\n" +
" client:\n" +
" require: false\n" +
" ca: /etc/ca.myservice.com.crt"
when:
def act = reader.readServerTls(reader.readNode(yaml))
then:
act != null
act.enabled != null
act.enabled
act.certificate == "/etc/client1.myservice.com.crt"
act.key == "/etc/client1.myservice.com.key"
act.clientRequire != null
!act.clientRequire
act.clientCa == "/etc/ca.myservice.com.crt"
}
}

View File

@@ -64,7 +64,7 @@ class UpstreamsConfigReaderSpec extends Specification {
with((UpstreamsConfig.EthereumConnection)connection) {
rpc.url == new URI("https://mainnet.infura.io/v3/fa28c968191849c1aff541ad1d8511f2")
rpc.basicAuth != null
with((UpstreamsConfig.BasicAuth)rpc.basicAuth) {
with((AuthConfig.ClientBasicAuth) rpc.basicAuth) {
username == "4fc258fe41a68149c199ad8f281f2015"
password == "1a68f20154fc258fe4149c199ad8f281"
}

View File

@@ -17,6 +17,7 @@ package io.emeraldpay.dshackle.proxy
import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common
import io.emeraldpay.dshackle.TlsSetup
import io.emeraldpay.dshackle.config.ProxyConfig
import io.emeraldpay.dshackle.rpc.NativeCall
import io.emeraldpay.dshackle.test.TestingCommons
@@ -42,7 +43,8 @@ class ProxyServerSpec extends Specification {
new ProxyConfig(),
new ReadRpcJson(TestingCommons.objectMapper()),
writeRpcJson,
nativeCall
nativeCall,
new TlsSetup(TestingCommons.fileResolver())
)
def call = new ProxyCall(ProxyCall.RpcType.SINGLE)

View File

@@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.Version
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import io.emeraldpay.dshackle.FileResolver
import io.emeraldpay.dshackle.cache.Caches
import io.emeraldpay.dshackle.cache.CachesFactory
import io.emeraldpay.dshackle.upstream.AggregatedUpstream
@@ -79,4 +80,8 @@ class TestingCommons {
static CachesFactory emptyCaches() {
return new CachesFactory(objectMapper(), new StandardEnvironment())
}
static FileResolver fileResolver() {
return new FileResolver(new File("src/test/resources"))
}
}

View File

@@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE-----
MIIEmDCCAoCgAwIBAgIQDTubkUXjTKQ5k1GApHel5jANBgkqhkiG9w0BAQsFADBF
MRMwEQYDVQQKEwpNeSBDb21wYW55MRYwFAYDVQQLEw1CbG9ja2NoYWluIENBMRYw
FAYDVQQDEw1jYS5teWhvc3QuZGV2MB4XDTIwMDMyMDIzMTEyN1oXDTIxMDkyMDIz
MTAzNFowRTETMBEGA1UEChMKTXkgQ29tcGFueTEaMBgGA1UECxMRQmxvY2tjaGFp
biBTZXJ2ZXIxEjAQBgNVBAMTCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBANMdYDhfCvUhcEPcKIQXvxFrIy2HUOM9soplutOAUv6dbTOs
TeCcpUVgt62sJZcPnE2Iy1nYHeVl+N7vuovUxtzYtfW4rGWprjth4rVcRHkWPwz5
QcyH6GwxsUi/0dEtboOxyqqf3W5C+V0+AJYGZ/bI94pGFOMC4+2HTkF8gCDORWKu
SG67SqiD9HL0LDrEdpq+IJOevW7t/Oqz+DWcO+VAi1T62xup4JL+WJI1UGtDPeET
0SRq3kXb8n4te58Y6NXjyodYlon+BESY42JPw4Uw6rjcmDHQVphg5Dtl343OcfN9
CNehtXavuszQdRU9uY1RUdVsvg44xhR60huFJ80CAwEAAaOBgzCBgDAOBgNVHQ8B
Af8EBAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQW
BBT9J7UEZRalIioijC1h4WsrRr9bpDAfBgNVHSMEGDAWgBRkRRFBxmIJWihWWm42
q3T1nI5IYDAPBgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4ICAQAC3AN0
8Ptp6xCOhZ8ja/RLKdF97WGyJS04KoPXyyB0qmh1zpYzHtcUcy6Zw41CiwS9d+7s
XfEi780ifmL9XOGxNWTFBvwLMJGq4ukdt//q/y5nhNdINbbZ+LNvZna9gPEBW0cK
YR5HEqMMk2eW2Lgo/pg4ska7leI/7ESoVqehNv3Pt9ewVLq38xecRC1K/Q2Z6vlU
zt+RbLYW7W7jIXc/cH7TUCDG9sT4tRptTlJdq9sBPVFFBXEZ+QZlY6b0ipeelqnL
Wrbsc8XWc/WogEEovBgDpqtqas+jfPI5x9DnopfaSeMP9m9BXYEk+D2nnukw5anp
tid4kSqTUOL8q8wTkEnvTd8nqXfFTC3H+Xe5OMGifXkJTRoQsqFS4M/2jLI36MpN
KHlNG3O5B1ML+vB0SedxaOD4PwWYQwq0kDWMOHOhe4OwyGgdr8MmPCzNFLbx5ppm
apMAco1RXzN/MaBJsYaq5MrTJw4XF8H1CMIEb4GHWb/9gLf4cPetFWzud48eg+YL
XADs+uzCGB0+lDMllVpyU+BSZtDUF77PWk1C5/33JNMg8Wzdj/tXs489B6AG1yED
fqcihzkQNp5WvwCtO5gY/+AYWZQ/zD0ICqjPfzofs7rb+s3qi8mRVfJJ/qOdGzxw
9NZPNkcfB8utd/pGbr4jEeHh+8Ds9vUgZFLXNw==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA0x1gOF8K9SFwQ9wohBe/EWsjLYdQ4z2yimW604BS/p1tM6xN
4JylRWC3rawllw+cTYjLWdgd5WX43u+6i9TG3Ni19bisZamuO2HitVxEeRY/DPlB
zIfobDGxSL/R0S1ug7HKqp/dbkL5XT4AlgZn9sj3ikYU4wLj7YdOQXyAIM5FYq5I
brtKqIP0cvQsOsR2mr4gk569bu386rP4NZw75UCLVPrbG6ngkv5YkjVQa0M94RPR
JGreRdvyfi17nxjo1ePKh1iWif4ERJjjYk/DhTDquNyYMdBWmGDkO2Xfjc5x830I
16G1dq+6zNB1FT25jVFR1Wy+DjjGFHrSG4UnzQIDAQABAoIBAQCX1uj9ol4fMI2u
QQpi9zFVNdl3RXvH9PgU0lYtCH6o4lFIeQUKJ6A25fk10Dq5C2E/4sNfOzFFbLIy
pfll2QOuk69LrCdSd1f5Hc4Q4uvcq0Nt8ViB4r4oExWPXWdrK2HxFk7NqW15gHIZ
vh5tyO29cY2Yxg7/t3R3wnlmYEVHUcS7HmhzgDveNzA0VLza3765ntgwXypY8N2j
heEQC1h5kMCurcKJyRXmlsXPRWizX0UBWDrMHFeqyhrH0BlRSFTNC3sKmyYaJQmp
daPNRr4zO0yfm8utVSbNHX2OM5DpIO1Ecq9Sd43QI+ATAtxFrhPoYK1rwll267CV
cJCRbz+BAoGBAPzz/1Xq8s1lGZ6eWz7H1JlzxYLH+TzQfrV1ym7xJgR/b3rVXiJ+
D+qL8zUJDa5xZyflXB7zCg4I7ALmNwMJzVLdIOpEntHK2NtRJ2rp4qH+kMXojays
zOGYfbRLNVe+mgAK9Pu8eOi8NzXqkB/S8rml3xqSOpUFsvlc2qiYhGdXAoGBANWo
XcQDpisRFcrn3J0+pKU57ZIRjxyOTDlEwH7k+x+PprCRFki80kW22u4l22FdDaip
s4vCuAm5tmEogEjINU6ZhSKHxonjaGXfzuZ3gAMk/PN7zFazlgfYEKng+fa1YuZ+
3Ubzq6py8enoffJ/PSF/lClKlV5sxjyilxeZmOd7AoGBAMtaJHUf0l4I3tXDnLsV
zvYmOixvMxEO1C5xKXKS7utCv45SJcE48vat17FVO+h3RmSuYKaI4BZ0Wbfi92q7
4JKzLpjm3X7uwfNehH/Q0t9EVYKk9/BPYs4h1zywEYwesJNEO7p8w/7mAMSZc5AB
+BwDGx6zW+EdmcoaOba8FgU1AoGAV2WftWaoukUq3O0rWUceolenznBQUiYDGAn/
k+imsKpaTS+MJgTXHp1FwNTLgHBH/g4s26azEYdeCzA+CYecBqLVyuIvXIghVErQ
n4WSX7bpoc+qLm0Xme3QIy1cEobwBckvSq6yMe8C9eOcYW2a2/EL8jgIEa/9ByCb
HZQ+77ECgYEAxR1eoxc/XV9rcftdaRl7+Db9Qvnhfwu7MFQ3lgomol1N1ckSjwnO
wo/HX4+8cMS5QN11d8l2hf+7TyuRCrQBLrYYkrVWb4Z+ote3ejrAsDg90xjOFYWf
MWSy7kPeDl3JTEdNPFIIa28EQhZYupD0ihBoVspz2eQ1Y66BOfqC9nU=
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDTHWA4Xwr1IXBD
3CiEF78RayMth1DjPbKKZbrTgFL+nW0zrE3gnKVFYLetrCWXD5xNiMtZ2B3lZfje
77qL1Mbc2LX1uKxlqa47YeK1XER5Fj8M+UHMh+hsMbFIv9HRLW6Dscqqn91uQvld
PgCWBmf2yPeKRhTjAuPth05BfIAgzkVirkhuu0qog/Ry9Cw6xHaaviCTnr1u7fzq
s/g1nDvlQItU+tsbqeCS/liSNVBrQz3hE9Ekat5F2/J+LXufGOjV48qHWJaJ/gRE
mONiT8OFMOq43Jgx0FaYYOQ7Zd+NznHzfQjXobV2r7rM0HUVPbmNUVHVbL4OOMYU
etIbhSfNAgMBAAECggEBAJfW6P2iXh8wja5BCmL3MVU12XdFe8f0+BTSVi0Ifqji
UUh5BQonoDbl+TXQOrkLYT/iw187MUVssjKl+WXZA66Tr0usJ1J3V/kdzhDi69yr
Q23xWIHivigTFY9dZ2srYfEWTs2pbXmAchm+Hm3I7b1xjZjGDv+3dHfCeWZgRUdR
xLseaHOAO943MDRUvNrfvrme2DBfKljw3aOF4RALWHmQwK6twonJFeaWxc9FaLNf
RQFYOswcV6rKGsfQGVFIVM0LewqbJholCal1o81GvjM7TJ+by61VJs0dfY4zkOkg
7URyr1J3jdAj4BMC3EWuE+hgrWvCWXbrsJVwkJFvP4ECgYEA/PP/VeryzWUZnp5b
PsfUmXPFgsf5PNB+tXXKbvEmBH9vetVeIn4P6ovzNQkNrnFnJ+VcHvMKDgjsAuY3
AwnNUt0g6kSe0crY21Enauniof6QxeiNrKzM4Zh9tEs1V76aAAr0+7x46Lw3NeqQ
H9LyuaXfGpI6lQWy+VzaqJiEZ1cCgYEA1ahdxAOmKxEVyufcnT6kpTntkhGPHI5M
OUTAfuT7H4+msJEWSLzSRbba7iXbYV0NqKmzi8K4Cbm2YSiASMg1TpmFIofGieNo
Zd/O5neAAyT883vMVrOWB9gQqeD59rVi5n7dRvOrqnLx6eh98n89IX+UKUqVXmzG
PKKXF5mY53sCgYEAy1okdR/SXgje1cOcuxXO9iY6LG8zEQ7ULnEpcpLu60K/jlIl
wTjy9q3XsVU76HdGZK5gpojgFnRZt+L3arvgkrMumObdfu7B816Ef9DS30RVgqT3
8E9iziHXPLARjB6wk0Q7unzD/uYAxJlzkAH4HAMbHrNb4R2Zyho5trwWBTUCgYBX
ZZ+1Zqi6RSrc7StZRx6iV6fOcFBSJgMYCf+T6KawqlpNL4wmBNcenUXA1MuAcEf+
DizbprMRh14LMD4Jh5wGotXK4i9ciCFUStCfhZJftumhz6oubReZ7dAjLVwShvAF
yS9KrrIx7wL145xhbZrb8QvyOAgRr/0HIJsdlD7vsQKBgQDFHV6jFz9dX2tx+11p
GXv4Nv1C+eF/C7swVDeWCiaiXU3VyRKPCc7Cj8dfj7xwxLlA3XV3yXaF/7tPK5EK
tAEuthiStVZvhn6i17d6OsCwOD3TGM4VhZ8xZLLuQ94OXclMR008UghrbwRCFli6
kPSKEGhWynPZ5DVjroE5+oL2dQ==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFSjCCAzKgAwIBAgIBATANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQKEwpNeSBD
b21wYW55MRYwFAYDVQQLEw1CbG9ja2NoYWluIENBMRYwFAYDVQQDEw1jYS5teWhv
c3QuZGV2MB4XDTIwMDMyMDIzMTAzNloXDTIxMDkyMDIzMTAzNFowRTETMBEGA1UE
ChMKTXkgQ29tcGFueTEWMBQGA1UECxMNQmxvY2tjaGFpbiBDQTEWMBQGA1UEAxMN
Y2EubXlob3N0LmRldjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL+v
wvbjRXpdjlBioUFFnnL3uCgfVMHw1zad8z36bBXr/MQDjAVgTfGrzI3FM3YVPTqb
peS7DuVfXOr+ULBU/mq6QuRgLTk9ynVbqcezajECtLZgbudkStF4ESFArjuaJ3IY
kYtL8TEKID31+EJIDyjZOwBjb87QoPaEICTIXLDYkoFv3heg9k8npYItWiKJpuJp
BSj23gCBm8zx/uqTZQOa1bEhhSBSI/okmM0dy+rGgquwZamH1HVH5xm7rok/wYry
EVb1AAT+j42Ug0qihF8mJrvlXLaN0G0QHAiqCf+wnS3DzBnaLPVLNcGJSeY6O8m+
HdCo+/y8WBJU6y+50HFk4qLVAoTYswn3X362W3q48DeCjvImty3g2vvfsVqvKkVd
bQy6C4ok3PXjXyhaxdFNx8f4SUXuXIfXyUMdSt2MNN0r4QY8KAWC9Kkic75Ui8sG
wHw2sBtEQxj1EX/QRAiqWeLT5J/CL3fHhmas+NaICeU3lH7pyLgKjs8+aZ44g9dt
g+AHEBqQvFMRW6wcIJLlWPT4zUo//LWGIbnSUGzz34frzVljg5f/ZsxxTTa10qGT
VOb6Jdln12JvnlObMdr45HSFFAXZrJB+g3z6/K9mFml29Py6dnDgQAFdlRW/LLns
4yEx5YXYrkCRse5PUHqt/APVvUp9kbWGnSB0EeoNAgMBAAGjRTBDMA4GA1UdDwEB
/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRkRRFBxmIJWihW
Wm42q3T1nI5IYDANBgkqhkiG9w0BAQsFAAOCAgEAFsXRgMoPT4RYSaB9oO2e/1vc
3e2rkNG2Bd3twKV33r8hUuqH9lm1EcBOIoWkWSZC4bbAvNtaoTm/pEHgBjKHTiPg
liVCuL66OmXWpL0LjGibialKeyowMkJ5S4K/p7vdPvIYA7jAxL7LNDwcoLyMm+22
GmCqrFp8tmy3ELj1uJe5fvI69WME7zGG6rLRGVT+Hc7gtKwk/iDIPvCF4UkQ0Jai
8RWlNy4G5BBSMCY8AWkRsnmVg/njZr8e/CMuOlLbRtSX8Nx/JAoR8bwszy7N0vCi
OkTELZNjo7w0lXWtINxNb5ySnHF6WSxFjmdiAgWv0ka/KBtR/+9PMMTv1g0y6c5W
dQpSTCJyzHhYb8Yu12tj1jaZDrqT0rRD8klZTuPxDtIbuhnpairjIRygRsVOEtYv
RXFWdjp/keD0A41TNtGj5eNsACPBOcYZlsb9AGqqmSQfRJ4R+YJGsBnECmIZpsva
VvX2eKI7jAZcYjHZIzqASnNFxlIM8jTxi2ifpS/7T93/RIl2Es5PJ3SX+FniOtN5
ajlzWSo7SVvgaYOOeOybKZq4cBmQ/R3XAnK1NSgMgHWZv1NOgHZEhC9kpvj0QQnE
WzjC3KDBLzhRpe678C5iorf9FXMkvYfb1NVl5UYYa9/C4aaj4Jt4SiaIaqsq27fP
wkLM79un1zrcbPHQUcA=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
/rUweL14cs7iUki+lWEGjjvXmOFkORI=
-----END PRIVATE KEY-----