solution: allow TLS configuration for proxy
This commit is contained in:
191
src/test/groovy/io/emeraldpay/dshackle/TlsSetupSpec.groovy
Normal file
191
src/test/groovy/io/emeraldpay/dshackle/TlsSetupSpec.groovy
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user