aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2018-09-20 12:04:03 +0200
committerPiotr Jaszczyk <piotr.jaszczyk@nokia.com>2018-09-24 14:25:32 +0200
commit069dcc194fd049e1c52e60d03ce2a9c0553289a7 (patch)
tree7916a4fa6b15734301c1e78bb8a20adf22532b4f
parent7b269674526a267f14895df8b825f3b59b30b98a (diff)
Use JDK security provider
Replace netty-tcnative bindings for OpenSSL with JDK provided implementation by default. Change-Id: I59a4797ce43d15a791eab00bfd25cb730a271207 Issue-ID: DCAEGEN2-816 Signed-off-by: Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
-rw-r--r--docker-compose.yml14
-rw-r--r--hv-collector-core/pom.xml11
-rw-r--r--hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/factory/ServerFactory.kt6
-rw-r--r--hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt3
-rw-r--r--hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt103
-rw-r--r--hv-collector-core/src/test/resources/logback-test.xml2
-rw-r--r--hv-collector-core/src/test/resources/ssl/ca.crt21
-rw-r--r--hv-collector-core/src/test/resources/ssl/server.crt19
-rw-r--r--hv-collector-core/src/test/resources/ssl/server.key28
-rw-r--r--hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/impl/config/ArgDcaeAppSimConfiguration.kt2
-rw-r--r--hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt24
-rw-r--r--hv-collector-main/Dockerfile3
-rw-r--r--hv-collector-main/pom.xml8
-rw-r--r--hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt76
-rw-r--r--hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfigurationTest.kt99
-rw-r--r--hv-collector-ssl/pom.xml118
-rw-r--r--hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ClientSslContextFactory.kt52
-rw-r--r--hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactory.kt50
-rw-r--r--hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SslContextFactory.kt (renamed from hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt)33
-rw-r--r--hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/utils.kt79
-rw-r--r--hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/impl/SslFactories.kt55
-rw-r--r--hv-collector-ssl/src/test/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactoryTest.kt163
-rw-r--r--hv-collector-ssl/src/test/resources/logback-test.xml35
-rw-r--r--hv-collector-ssl/src/test/resources/ssl/ca.crt21
-rw-r--r--hv-collector-ssl/src/test/resources/ssl/server.crt19
-rw-r--r--hv-collector-ssl/src/test/resources/ssl/server.key28
-rw-r--r--hv-collector-ssl/src/test/resources/ssl/server.ks.pkcs12bin0 -> 2389 bytes
-rw-r--r--hv-collector-ssl/src/test/resources/ssl/trust.pkcs12bin0 -> 1096 bytes
-rw-r--r--hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt26
-rw-r--r--hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt24
-rw-r--r--hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt30
-rw-r--r--hv-collector-xnf-simulator/Dockerfile2
-rw-r--r--hv-collector-xnf-simulator/pom.xml13
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/adapters/VesHvClient.kt15
-rw-r--r--hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/config/ArgXnfSimulatorConfiguration.kt64
-rw-r--r--hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgXnfSimulatorConfiurationTest.kt181
-rw-r--r--pom.xml22
-rw-r--r--ssl/.gitignore3
-rw-r--r--ssl/Makefile-openssl (renamed from ssl/Makefile)12
-rw-r--r--ssl/README.md26
-rwxr-xr-xssl/gen-certs.sh58
41 files changed, 948 insertions, 600 deletions
diff --git a/docker-compose.yml b/docker-compose.yml
index f37c823a..fb8ff566 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -39,7 +39,9 @@ services:
"-cp", "*:", "org.onap.dcae.collectors.veshv.main.MainKt"]
command: ["--listen-port", "6061",
"--health-check-api-port", "6060",
- "--config-url", "http://consul:8500/v1/kv/veshv-config"]
+ "--config-url", "http://consul:8500/v1/kv/veshv-config",
+ "--key-store-password", "onaponap",
+ "--trust-store-password", "onaponap"]
healthcheck:
test: curl -f http://localhost:6060/health/ready || exit 1
interval: 10s
@@ -59,7 +61,11 @@ services:
# dockerfile: Dockerfile
ports:
- "6062:6062/tcp"
- command: ["--listen-port", "6062", "--ves-host", "ves-hv-collector", "--ves-port", "6061"]
+ command: ["--listen-port", "6062",
+ "--ves-host", "ves-hv-collector",
+ "--ves-port", "6061",
+ "--key-store-password", "onaponap",
+ "--trust-store-password", "onaponap"]
depends_on:
- ves-hv-collector
volumes:
@@ -72,6 +78,8 @@ services:
# dockerfile: Dockerfile
ports:
- "6063:6063/tcp"
- command: ["--listen-port", "6063", "--kafka-bootstrap-servers", "kafka:9092", "--kafka-topics", "ves_hvRanMeas"]
+ command: ["--listen-port", "6063",
+ "--kafka-bootstrap-servers", "kafka:9092",
+ "--kafka-topics", "ves_hvRanMeas"]
depends_on:
- kafka
diff --git a/hv-collector-core/pom.xml b/hv-collector-core/pom.xml
index 9f4afe4b..edc3e2f2 100644
--- a/hv-collector-core/pom.xml
+++ b/hv-collector-core/pom.xml
@@ -64,6 +64,11 @@
<dependencies>
<dependency>
<groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-ssl</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
<artifactId>hv-collector-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
@@ -114,12 +119,6 @@
<artifactId>reactor-kafka</artifactId>
</dependency>
<dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-tcnative-boringssl-static</artifactId>
- <scope>runtime</scope>
- <classifier>${os.detected.classifier}</classifier>
- </dependency>
- <dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
</dependency>
diff --git a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/factory/ServerFactory.kt b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/factory/ServerFactory.kt
index 32fe6eb6..dce933ab 100644
--- a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/factory/ServerFactory.kt
+++ b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/factory/ServerFactory.kt
@@ -21,9 +21,9 @@ package org.onap.dcae.collectors.veshv.factory
import org.onap.dcae.collectors.veshv.boundary.CollectorProvider
import org.onap.dcae.collectors.veshv.boundary.Server
-import org.onap.dcae.collectors.veshv.model.ServerConfiguration
import org.onap.dcae.collectors.veshv.impl.socket.NettyTcpServer
-import org.onap.dcae.collectors.veshv.impl.socket.SslContextFactory
+import org.onap.dcae.collectors.veshv.model.ServerConfiguration
+import org.onap.dcae.collectors.veshv.ssl.boundary.ServerSslContextFactory
/**
* @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
@@ -31,5 +31,5 @@ import org.onap.dcae.collectors.veshv.impl.socket.SslContextFactory
*/
object ServerFactory {
fun createNettyTcpServer(serverConfiguration: ServerConfiguration, collectorProvider: CollectorProvider): Server =
- NettyTcpServer(serverConfiguration, SslContextFactory(), collectorProvider)
+ NettyTcpServer(serverConfiguration, ServerSslContextFactory(), collectorProvider)
}
diff --git a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt
index b4ad4b7d..ede5a667 100644
--- a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt
+++ b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt
@@ -25,6 +25,7 @@ import io.netty.handler.ssl.SslContext
import org.onap.dcae.collectors.veshv.boundary.CollectorProvider
import org.onap.dcae.collectors.veshv.boundary.Server
import org.onap.dcae.collectors.veshv.model.ServerConfiguration
+import org.onap.dcae.collectors.veshv.ssl.boundary.ServerSslContextFactory
import org.onap.dcae.collectors.veshv.utils.NettyServerHandle
import org.onap.dcae.collectors.veshv.utils.ServerHandle
import org.onap.dcae.collectors.veshv.utils.logging.Logger
@@ -43,7 +44,7 @@ import java.util.function.BiFunction
* @since May 2018
*/
internal class NettyTcpServer(private val serverConfig: ServerConfiguration,
- private val sslContextFactory: SslContextFactory,
+ private val sslContextFactory: ServerSslContextFactory,
private val collectorProvider: CollectorProvider) : Server {
override fun start(): IO<ServerHandle> = IO {
diff --git a/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt b/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt
deleted file mode 100644
index deb4e183..00000000
--- a/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * dcaegen2-collectors-veshv
- * ================================================================================
- * Copyright (C) 2018 NOKIA
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-package org.onap.dcae.collectors.veshv.impl.socket
-
-import io.netty.handler.ssl.ClientAuth
-import io.netty.handler.ssl.ReferenceCountedOpenSslContext
-import io.netty.handler.ssl.SslContextBuilder
-import org.assertj.core.api.Assertions.assertThat
-import org.jetbrains.spek.api.Spek
-import org.jetbrains.spek.api.dsl.describe
-import org.jetbrains.spek.api.dsl.given
-import org.jetbrains.spek.api.dsl.it
-import org.jetbrains.spek.api.dsl.on
-import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
-import java.nio.file.Paths
-import kotlin.test.assertTrue
-
-/**
- * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
- * @since June 2018
- */
-object SslContextFactoryTest : Spek({
- describe("SslContextFactory") {
- given("config without disabled SSL") {
- val sampleConfig = SecurityConfiguration(
- privateKey = Paths.get("/", "tmp", "pk.pem"),
- cert = Paths.get("/", "tmp", "cert.crt"),
- trustedCert = Paths.get("/", "tmp", "clientCa.crt"))
-
- val cut = object : SslContextFactory() {
- override fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration): SslContextBuilder {
- return SslContextBuilder.forServer(resource("/ssl/ca.crt"), resource("/ssl/server.key"))
- }
-
- private fun resource(path: String) = SslContextFactoryTest.javaClass.getResourceAsStream(path)
- }
-
- on("creation of SSL context") {
- val result = cut.createSslContext(sampleConfig)
-
- it("should be server context") {
- assertTrue(result.exists {
- it.isServer
- })
- }
-
- it("should use OpenSSL provider") {
- assertTrue(result.isDefined())
- }
-
- /*
- * It is too important to leave it untested on unit level.
- * Because of the Netty API design we need to do it this way.
- */
- it("should turn on client authentication") {
- val clientAuth: ClientAuth = ReferenceCountedOpenSslContext::class.java
- .getDeclaredField("clientAuth")
- .run {
- isAccessible = true
- get(result.orNull()) as ClientAuth
- }
- assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE)
- }
- }
- }
-
- given("config with SSL disabled") {
- val securityConfiguration = SecurityConfiguration(
- sslDisable = true,
- privateKey = Paths.get("sample", "key"),
- cert = Paths.get("sample", "cert"),
- trustedCert = Paths.get("/", "sample", "trusted", "cert")
- )
- val cut = SslContextFactory()
-
- on("creation of SSL context") {
- val result = cut.createSslContext(securityConfiguration)
-
- it("should not create any SSL context ") {
- assertThat(result.isDefined()).isFalse()
- }
- }
- }
-
- }
-})
diff --git a/hv-collector-core/src/test/resources/logback-test.xml b/hv-collector-core/src/test/resources/logback-test.xml
index 84abc9d3..9a4eacfe 100644
--- a/hv-collector-core/src/test/resources/logback-test.xml
+++ b/hv-collector-core/src/test/resources/logback-test.xml
@@ -32,4 +32,4 @@
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING-FILE"/>
</root>
-</configuration> \ No newline at end of file
+</configuration>
diff --git a/hv-collector-core/src/test/resources/ssl/ca.crt b/hv-collector-core/src/test/resources/ssl/ca.crt
deleted file mode 100644
index 29057f26..00000000
--- a/hv-collector-core/src/test/resources/ssl/ca.crt
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDbDCCAlSgAwIBAgIJANad+zi5MeDSMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
-BAYTAlBMMQswCQYDVQQIDAJETDEQMA4GA1UEBwwHV3JvY2xhdzEOMAwGA1UECgwF
-Tm9raWExDTALBgNVBAsMBE1BTk8wHhcNMTgwNjAxMTMwOTE2WhcNMTkwNjAxMTMw
-OTE2WjBLMQswCQYDVQQGEwJQTDELMAkGA1UECAwCREwxEDAOBgNVBAcMB1dyb2Ns
-YXcxDjAMBgNVBAoMBU5va2lhMQ0wCwYDVQQLDARNQU5PMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEArqcdlj5G4OTByGfZQ+vvdFX2ZPGKKUmUV6JYjbQH
-v9C131WD2GFpbE9fAXG+R0n9c+0mbqUj3rnHzB6g5zUJBCJZXk4mM9KTq5iUfFU1
-uSQGWVCkgqmWijCROR2Eqm+v/vaSCqj77EuDEqmLe8EkFOaOKGMMdlJYYfPAyExu
-k1qfmeXGzD0c/YR6ks72GW2q2xWDujvddOuxAC7CYa1iLTYSh39KLfDuoOvktqI0
-syCTyPExvmltJsb9N3AN78g+TObfAWGnkpD+QHlB1X52DU0S05+8OUkhV43aX1cd
-8cIQrCvJUL/FPKe3AKgyEbLjbhkQhGQhOyjM1ptKuMucSwIDAQABo1MwUTAdBgNV
-HQ4EFgQUBtX8BzxCxBS7ZTTL0pe8XcSp+McwHwYDVR0jBBgwFoAUBtX8BzxCxBS7
-ZTTL0pe8XcSp+McwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA
-niw6/qRG5ULJ6OTUd4kvw4i42EV3aV9ypd+EIzv3IuqNZBu4vqYoUSRoc1n6YwPZ
-YcDq0xrVi5uw8zRR8M4/GhhT4jGLxjPHD1Jby7IyuPzByBsMJUNfdjYHjebEC820
-WJ8nbHaGm3cJVB4zMlJd5gA5+R8vp4OQmQsULxoWhDn09X4IXb/izOSK5YClf/XB
-W2mQyYeAb+2H7q9fT5VVJved6h2BZsmq+SQSKlXnBMIvEjpgh7RLUuuANMgival6
-NlSezPQD9iuyj9g2Xz3z8ggRGahYPSKAb6+fg3TGg/Vokd4GYEMflfC2tw+eM07n
-oTa03o8tD9V4paP/vx7cUg==
------END CERTIFICATE-----
diff --git a/hv-collector-core/src/test/resources/ssl/server.crt b/hv-collector-core/src/test/resources/ssl/server.crt
deleted file mode 100644
index 0af22e29..00000000
--- a/hv-collector-core/src/test/resources/ssl/server.crt
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDEjCCAfoCCQDSzpBZljMk+jANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJQ
-TDELMAkGA1UECAwCREwxEDAOBgNVBAcMB1dyb2NsYXcxDjAMBgNVBAoMBU5va2lh
-MQ0wCwYDVQQLDARNQU5PMB4XDTE4MDYwMTEzMDkxNloXDTE5MDUyNzEzMDkxNlow
-SzELMAkGA1UEBhMCUEwxCzAJBgNVBAgMAkRMMRAwDgYDVQQHDAdXcm9jbGF3MQ4w
-DAYDVQQKDAVOb2tpYTENMAsGA1UECwwETUFOTzCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAOdOjGM8+5+ArMawknY+QPTO4Q//QuRi46OxkU28DshayG1o
-pyCoKD6zYB4Q7cgSY8xrwX7Ct6QINaGefSddKdDJl4zzjiVCUK7vaKxaOK2hOl7k
-Iq7HuvAG6TaO7CaeBFafGNxpocgC2WkoZCIqQ32gXHjU5mpTrzwtUyX91Xc43puP
-nHGBz6XDVlV52DvJQ1v9xed4bM70DgSg3FcD77mcPDbr98UvPa477RKeAz8eAc+J
-jxMg8uNGYX0sthGEcOiOf1Dz8UeMU1M2Qw6MGDqrW+RMaM9K8/mlbQ/SFqoPg4MD
-q3zbQie0IzfanQuygz9Zy7dDAVgzmjrX8/tf+nMCAwEAATANBgkqhkiG9w0BAQsF
-AAOCAQEALPII5UXwBSNGcVa14t3NUUb0jtXdtmKr6sRMqFdR81tREcJHGnMauxO9
-IuECQuDkIRkv2XR+Swn2vZdOkYtHSAHSRLxPUhwjYKFC7uTd6T1ljTiYJ/NtGCV3
-75n0qh2aneCXr9KVExK6KzYVFJKMKmbEJludaQrM/Z+kDXGwwUMcyb8LLO+avgek
-ke1796f0MJ56csHejT9V69/6zc07T/zn0gVcR42AnMr/MzhAkiqUOhy0Cxzek0Xv
-72/1PKaf2r9F+WtjQuPRd6LJrM7yTnkzLz7xK+yX17mycIN4KsVf8zhrsCgVJZGL
-kLkC4O9faHnrtj0qqV+BPhyF1Ii95w==
------END CERTIFICATE-----
diff --git a/hv-collector-core/src/test/resources/ssl/server.key b/hv-collector-core/src/test/resources/ssl/server.key
deleted file mode 100644
index 033c99af..00000000
--- a/hv-collector-core/src/test/resources/ssl/server.key
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnToxjPPufgKzG
-sJJ2PkD0zuEP/0LkYuOjsZFNvA7IWshtaKcgqCg+s2AeEO3IEmPMa8F+wrekCDWh
-nn0nXSnQyZeM844lQlCu72isWjitoTpe5CKux7rwBuk2juwmngRWnxjcaaHIAtlp
-KGQiKkN9oFx41OZqU688LVMl/dV3ON6bj5xxgc+lw1ZVedg7yUNb/cXneGzO9A4E
-oNxXA++5nDw26/fFLz2uO+0SngM/HgHPiY8TIPLjRmF9LLYRhHDojn9Q8/FHjFNT
-NkMOjBg6q1vkTGjPSvP5pW0P0haqD4ODA6t820IntCM32p0LsoM/Wcu3QwFYM5o6
-1/P7X/pzAgMBAAECggEAYBIL1Rv7FqCHIm8sJdhtekCC0fYffmRkUBTsWPEG4shx
-/p886x9st74g6dv2JuccdEc9Mr0FMSgHvnzpVnQnbgSM4Yo3O9pzUHU3cH54lAUn
-DUqL7TQfvJniOzrZcqCnBKNH3CQzgbNNQZP5IweSyJbWUYl7uiXP3pqksl7fToiS
-JBSKzKphwtHRUHS3RCwN118N5RyZH+0LZi0EAOjxi1BVqmKQos0Zr8Gnl/7nHF+g
-oRG4vgDZUopNEGX5AELvMBq/hbSrfGT1z+wJkOtoRdinRMGFKO528vCqhEr629Sh
-FFUOv3xL7HUEEnDu97I0TxK1o6C5fG/QbeP9viiJIQKBgQD2upLpuyP6iTCdAl/S
-lLmQxwEUyD3vhF4oG+B0jKyNkzO7QzM695HH/bXV9GnRH+9HPgxLqtozVpztsuu2
-MXrac2tmJR9OiSchJwgDRvhSUyezEULFAzsIaSeGK16wrcT6xqwVeKumsKp1dW7I
-n0w5NxC/N2U87ffjmyOwldOAHwKBgQDv/58mMUutViwicw8ddRJP38QZs804vm7R
-YFb5sqt6L7hcSQCszVXdjHP2v/GeK+jl0vZrGS932kY3T2+FhA8ClbKByVdaFzXj
-PSEuY/Ow+ebGrlBPBH6sPN4Uvc00MEk1eZXRL8IaT32xJnq2vF4M7SvGNFeH39tc
-qOq9VqrrLQKBgQCRzdYN6/qqDrK8xm9sGVnD9eZsqpz3U2j1GOw+0/cQvyG+E0tO
-GIl8/zCa3JI/9DhKCJ/pg3DpD9EzIx3qkDkCqVyZg2yJ08Fc9RzmGuWaeOuoBZZI
-qM0U/ldOEYkmrboPXKLLGYGOwy4otZofUwwPb7wk1A6uwA5S4hZoP1I6jwKBgQCS
-yfH5ViVHO3F7EIyqI7SzjdVPMx3OGwuEnDwWNSWUciN8rlnvVxexjfpPbU7Gw2yL
-RODa2GikEajoo3k+XGsh1ZV8tDztKU0YU4c77H5cPDzeQDd2XPVtOz1Jylz8Epx0
-TI1JiMBbf0sNUs+zfLq5hUZE0DbJMC3nGpmYfK3FcQKBgQCFlXdwWzhu33HHa+wc
-X7JT0m8W81ex08ndNOCgdYqgOxmZ+VhK8WN91sj3N0X9nMsfSJ9WTRib+FVa8D4M
-e7hOddjrKxNcqAhjbnxeCHLExq9kYdjeXa0dS9ywP89nMlGm7qja7+9DSBPisRPe
-lcaTvr7E/zSTHK5WDBCzOsV3lQ==
------END PRIVATE KEY-----
diff --git a/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/impl/config/ArgDcaeAppSimConfiguration.kt b/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/impl/config/ArgDcaeAppSimConfiguration.kt
index d5f55605..d0820616 100644
--- a/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/impl/config/ArgDcaeAppSimConfiguration.kt
+++ b/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/impl/config/ArgDcaeAppSimConfiguration.kt
@@ -31,6 +31,8 @@ import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KAFKA_SERVERS
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KAFKA_TOPICS
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.LISTEN_PORT
+import org.onap.dcae.collectors.veshv.utils.commandline.intValue
+import org.onap.dcae.collectors.veshv.utils.commandline.stringValue
class ArgDcaeAppSimConfiguration : ArgBasedConfiguration<DcaeAppSimConfiguration>(DefaultParser()) {
override val cmdLineOptionsList: List<CommandLineOption> = listOf(
diff --git a/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt b/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt
index e409eb7a..7f566a6d 100644
--- a/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt
+++ b/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt
@@ -19,6 +19,8 @@
*/
package org.onap.dcae.collectors.veshv.domain
+import arrow.core.Option
+import java.io.InputStream
import java.nio.file.Path
/**
@@ -27,6 +29,22 @@ import java.nio.file.Path
*/
data class SecurityConfiguration(
val sslDisable: Boolean = false,
- val privateKey: Path,
- val cert: Path,
- val trustedCert: Path)
+ val keys: Option<SslKeys>)
+
+sealed class SslKeys
+
+data class OpenSslKeys(val privateKey: Path,
+ val cert: Path,
+ val trustedCert: Path) : SslKeys()
+
+data class JdkKeys(val keyStore: StreamProvider,
+ val keyStorePassword: CharArray,
+ val trustStore: StreamProvider,
+ val trustStorePassword: CharArray) : SslKeys() {
+ fun forgetPasswords() {
+ keyStorePassword.fill('x')
+ trustStorePassword.fill('x')
+ }
+}
+
+typealias StreamProvider = () -> InputStream
diff --git a/hv-collector-main/Dockerfile b/hv-collector-main/Dockerfile
index 8216ac46..746deb51 100644
--- a/hv-collector-main/Dockerfile
+++ b/hv-collector-main/Dockerfile
@@ -6,8 +6,7 @@ LABEL license.url="http://www.apache.org/licenses/LICENSE-2.0"
LABEL maintainer="Nokia Wroclaw ONAP Team"
RUN apt-get update \
- && apt-get install -y --no-install-recommends curl \
- && apt-get install -y --no-install-recommends netcat \
+ && apt-get install -y --no-install-recommends curl netcat \
&& apt-get clean
WORKDIR /opt/ves-hv-collector
diff --git a/hv-collector-main/pom.xml b/hv-collector-main/pom.xml
index ed37515d..571821a6 100644
--- a/hv-collector-main/pom.xml
+++ b/hv-collector-main/pom.xml
@@ -117,12 +117,18 @@
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
+ <!-- See comment in main pom
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ <classifier>${os.detected.classifier}</classifier>
+ </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
- <scope>runtime</scope>
<classifier>${os.detected.classifier}</classifier>
</dependency>
+ -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-jmx</artifactId>
diff --git a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt
index 26230cd3..d6ff9efa 100644
--- a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt
+++ b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfiguration.kt
@@ -22,25 +22,31 @@ package org.onap.dcae.collectors.veshv.main
import arrow.core.ForOption
import arrow.core.Option
import arrow.core.fix
+import arrow.core.monad
import arrow.instances.extensions
import arrow.typeclasses.binding
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.DefaultParser
-import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
import org.onap.dcae.collectors.veshv.model.ConfigurationProviderParams
import org.onap.dcae.collectors.veshv.model.ServerConfiguration
+import org.onap.dcae.collectors.veshv.ssl.boundary.createSecurityConfiguration
import org.onap.dcae.collectors.veshv.utils.commandline.ArgBasedConfiguration
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CERT_FILE
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CONSUL_CONFIG_URL
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CONSUL_FIRST_REQUEST_DELAY
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CONSUL_REQUEST_INTERVAL
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.DUMMY_MODE
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.HEALTH_CHECK_API_PORT
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.IDLE_TIMEOUT_SEC
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KEY_STORE_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KEY_STORE_PASSWORD
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.LISTEN_PORT
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.PRIVATE_KEY_FILE
import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.SSL_DISABLE
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_CERT_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_STORE_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_STORE_PASSWORD
+import org.onap.dcae.collectors.veshv.utils.commandline.hasOption
+import org.onap.dcae.collectors.veshv.utils.commandline.intValue
+import org.onap.dcae.collectors.veshv.utils.commandline.longValue
+import org.onap.dcae.collectors.veshv.utils.commandline.stringValue
import java.time.Duration
internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration>(DefaultParser()) {
@@ -51,34 +57,33 @@ internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration
CONSUL_FIRST_REQUEST_DELAY,
CONSUL_REQUEST_INTERVAL,
SSL_DISABLE,
- PRIVATE_KEY_FILE,
- CERT_FILE,
- TRUST_CERT_FILE,
+ KEY_STORE_FILE,
+ KEY_STORE_PASSWORD,
+ TRUST_STORE_FILE,
+ TRUST_STORE_PASSWORD,
IDLE_TIMEOUT_SEC,
DUMMY_MODE
)
override fun getConfiguration(cmdLine: CommandLine): Option<ServerConfiguration> =
- ForOption extensions {
- binding {
- val healthCheckApiPort = cmdLine.intValue(
- HEALTH_CHECK_API_PORT,
- DefaultValues.HEALTH_CHECK_API_PORT
- )
- val listenPort = cmdLine.intValue(LISTEN_PORT).bind()
- val idleTimeoutSec = cmdLine.longValue(IDLE_TIMEOUT_SEC, DefaultValues.IDLE_TIMEOUT_SEC)
- val dummyMode = cmdLine.hasOption(DUMMY_MODE)
- val security = createSecurityConfiguration(cmdLine)
- val configurationProviderParams = createConfigurationProviderParams(cmdLine).bind()
- ServerConfiguration(
- healthCheckApiPort = healthCheckApiPort,
- listenPort = listenPort,
- configurationProviderParams = configurationProviderParams,
- securityConfiguration = security,
- idleTimeout = Duration.ofSeconds(idleTimeoutSec),
- dummyMode = dummyMode)
- }.fix()
- }
+ Option.monad().binding {
+ val healthCheckApiPort = cmdLine.intValue(
+ HEALTH_CHECK_API_PORT,
+ DefaultValues.HEALTH_CHECK_API_PORT
+ )
+ val listenPort = cmdLine.intValue(LISTEN_PORT).bind()
+ val idleTimeoutSec = cmdLine.longValue(IDLE_TIMEOUT_SEC, DefaultValues.IDLE_TIMEOUT_SEC)
+ val dummyMode = cmdLine.hasOption(DUMMY_MODE)
+ val security = createSecurityConfiguration(cmdLine).bind()
+ val configurationProviderParams = createConfigurationProviderParams(cmdLine).bind()
+ ServerConfiguration(
+ healthCheckApiPort = healthCheckApiPort,
+ listenPort = listenPort,
+ configurationProviderParams = configurationProviderParams,
+ securityConfiguration = security,
+ idleTimeout = Duration.ofSeconds(idleTimeoutSec),
+ dummyMode = dummyMode)
+ }.fix()
private fun createConfigurationProviderParams(cmdLine: CommandLine): Option<ConfigurationProviderParams> =
ForOption extensions {
@@ -100,27 +105,10 @@ internal class ArgVesHvConfiguration : ArgBasedConfiguration<ServerConfiguration
}.fix()
}
- private fun createSecurityConfiguration(cmdLine: CommandLine): SecurityConfiguration {
- val sslDisable = cmdLine.hasOption(SSL_DISABLE)
- val pkFile = cmdLine.stringValue(PRIVATE_KEY_FILE, DefaultValues.PRIVATE_KEY_FILE)
- val certFile = cmdLine.stringValue(CERT_FILE, DefaultValues.CERT_FILE)
- val trustCertFile = cmdLine.stringValue(TRUST_CERT_FILE, DefaultValues.TRUST_CERT_FILE)
-
- return SecurityConfiguration(
- sslDisable = sslDisable,
- privateKey = stringPathToPath(pkFile),
- cert = stringPathToPath(certFile),
- trustedCert = stringPathToPath(trustCertFile)
- )
- }
-
internal object DefaultValues {
const val HEALTH_CHECK_API_PORT = 6060
const val CONSUL_FIRST_REQUEST_DELAY = 10L
const val CONSUL_REQUEST_INTERVAL = 5L
- const val PRIVATE_KEY_FILE = "/etc/ves-hv/server.key"
- const val CERT_FILE = "/etc/ves-hv/server.crt"
- const val TRUST_CERT_FILE = "/etc/ves-hv/trust.crt"
const val IDLE_TIMEOUT_SEC = 60L
}
}
diff --git a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfigurationTest.kt b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfigurationTest.kt
index 26507197..0cf0bb2c 100644
--- a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfigurationTest.kt
+++ b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgVesHvConfigurationTest.kt
@@ -19,20 +19,20 @@
*/
package org.onap.dcae.collectors.veshv.main
+import arrow.core.identity
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe
import org.jetbrains.spek.api.dsl.given
import org.jetbrains.spek.api.dsl.it
import org.jetbrains.spek.api.dsl.on
-import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
-import org.onap.dcae.collectors.veshv.main.ArgVesHvConfiguration.DefaultValues
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
import org.onap.dcae.collectors.veshv.model.ServerConfiguration
import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingFailure
import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingSuccess
import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentError
-import java.nio.file.Paths
import java.time.Duration
+import kotlin.test.assertNotNull
/**
* @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
@@ -45,9 +45,8 @@ object ArgVesHvConfigurationTest : Spek({
val firstRequestDelay = "10"
val requestInterval = "5"
val listenPort = "6969"
- val pk = Paths.get("/", "etc", "ves", "pk.pem")
- val cert = Paths.get("/", "etc", "ssl", "certs", "ca-bundle.crt")
- val trustCert = Paths.get("/", "etc", "ves", "trusted.crt")
+ val keyStorePassword = "kspass"
+ val trustStorePassword = "tspass"
beforeEachTest {
cut = ArgVesHvConfiguration()
@@ -58,15 +57,17 @@ object ArgVesHvConfigurationTest : Spek({
lateinit var result: ServerConfiguration
beforeEachTest {
- result = cut.parseExpectingSuccess("--ssl-disable",
+ result = cut.parseExpectingSuccess(
"--health-check-api-port", healthCheckApiPort,
"--listen-port", listenPort,
"--config-url", configurationUrl,
"--first-request-delay", firstRequestDelay,
"--request-interval", requestInterval,
- "--private-key-file", pk.toFile().absolutePath,
- "--cert-file", cert.toFile().absolutePath,
- "--trust-cert-file", trustCert.toFile().absolutePath)
+ "--key-store", "/tmp/keys.p12",
+ "--trust-store", "/tmp/trust.p12",
+ "--key-store-password", keyStorePassword,
+ "--trust-store-password", trustStorePassword
+ )
}
it("should set proper health check api port") {
@@ -93,69 +94,13 @@ object ArgVesHvConfigurationTest : Spek({
}
it("should set proper security configuration") {
- assertThat(result.securityConfiguration).isEqualTo(
- SecurityConfiguration(sslDisable = true, privateKey = pk, cert = cert, trustedCert = trustCert)
- )
- }
- }
-
- given("some parameters are present in the short form") {
- lateinit var result: ServerConfiguration
-
- beforeEachTest {
- result = cut.parseExpectingSuccess(
- "-p", listenPort, "-c", configurationUrl, "-d", firstRequestDelay
- )
- }
+ assertThat(result.securityConfiguration.sslDisable).isFalse()
- it("should set proper port") {
- assertThat(result.listenPort).isEqualTo(listenPort.toInt())
- }
-
- it("should set proper first consul request delay") {
- assertThat(result.configurationProviderParams.firstRequestDelay)
- .isEqualTo(Duration.ofSeconds(firstRequestDelay.toLong()))
- }
-
- it("should set proper config url") {
- assertThat(result.configurationProviderParams.configurationUrl)
- .isEqualTo(configurationUrl)
- }
- }
-
- given("all optional parameters are absent") {
- lateinit var result: ServerConfiguration
-
- beforeEachTest {
- result = cut.parseExpectingSuccess(
- "--listen-port", listenPort, "--config-url", configurationUrl
- )
- }
-
- it("should set default first consul request delay") {
- assertThat(result.configurationProviderParams.firstRequestDelay)
- .isEqualTo(Duration.ofSeconds(DefaultValues.CONSUL_FIRST_REQUEST_DELAY))
- }
-
- it("should set default consul request interval") {
- assertThat(result.configurationProviderParams.requestInterval)
- .isEqualTo(Duration.ofSeconds(DefaultValues.CONSUL_REQUEST_INTERVAL))
- }
-
- on("security config") {
- val securityConfiguration = result.securityConfiguration
-
- it("should set default trust cert file") {
- assertThat(securityConfiguration.trustedCert.toString()).isEqualTo(DefaultValues.TRUST_CERT_FILE)
- }
-
- it("should set default server cert file") {
- assertThat(securityConfiguration.cert.toString()).isEqualTo(DefaultValues.CERT_FILE)
- }
-
- it("should set default private key file") {
- assertThat(securityConfiguration.privateKey.toString()).isEqualTo(DefaultValues.PRIVATE_KEY_FILE)
- }
+ val keys = result.securityConfiguration.keys.orNull() as JdkKeys
+ assertNotNull(keys.keyStore)
+ assertNotNull(keys.trustStore)
+ assertThat(keys.keyStorePassword).isEqualTo(keyStorePassword.toCharArray())
+ assertThat(keys.trustStorePassword).isEqualTo(trustStorePassword.toCharArray())
}
}
@@ -166,10 +111,7 @@ object ArgVesHvConfigurationTest : Spek({
"--config-url", configurationUrl,
"--ssl-disable",
"--first-request-delay", firstRequestDelay,
- "--request-interval", requestInterval,
- "--private-key-file", pk.toFile().absolutePath,
- "--cert-file", cert.toFile().absolutePath,
- "--trust-cert-file", trustCert.toFile().absolutePath)
+ "--request-interval", requestInterval)
).isInstanceOf(WrongArgumentError::class.java)
}
}
@@ -179,10 +121,7 @@ object ArgVesHvConfigurationTest : Spek({
"--listen-port", listenPort,
"--ssl-disable",
"--first-request-delay", firstRequestDelay,
- "--request-interval", requestInterval,
- "--private-key-file", pk.toFile().absolutePath,
- "--cert-file", cert.toFile().absolutePath,
- "--trust-cert-file", trustCert.toFile().absolutePath)
+ "--request-interval", requestInterval)
).isInstanceOf(WrongArgumentError::class.java)
}
}
diff --git a/hv-collector-ssl/pom.xml b/hv-collector-ssl/pom.xml
new file mode 100644
index 00000000..f5ea00ca
--- /dev/null
+++ b/hv-collector-ssl/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ ============LICENSE_START=======================================================
+ ~ dcaegen2-collectors-veshv
+ ~ ================================================================================
+ ~ Copyright (C) 2018 NOKIA
+ ~ ================================================================================
+ ~ 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.
+ ~ ============LICENSE_END=========================================================
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+
+ <parent>
+ <groupId>org.onap.dcaegen2.collectors.hv-ves</groupId>
+ <artifactId>ves-hv-collector</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>hv-collector-ssl</artifactId>
+ <description>VES HighVolume Collector :: SSL</description>
+
+ <properties>
+ <skipAnalysis>false</skipAnalysis>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>kotlin-maven-plugin</artifactId>
+ <groupId>org.jetbrains.kotlin</groupId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <groupId>org.apache.maven.plugins</groupId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-domain</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-utils</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-test-utils</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-tcnative-boringssl-static</artifactId>
+ <classifier>${os.detected.classifier}</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.arrow-kt</groupId>
+ <artifactId>arrow-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.arrow-kt</groupId>
+ <artifactId>arrow-syntax</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.spek</groupId>
+ <artifactId>spek-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.spek</groupId>
+ <artifactId>spek-junit-platform-engine</artifactId>
+ </dependency>
+ </dependencies>
+
+
+</project>
diff --git a/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ClientSslContextFactory.kt b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ClientSslContextFactory.kt
new file mode 100644
index 00000000..0ad3d7b4
--- /dev/null
+++ b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ClientSslContextFactory.kt
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.ssl.boundary
+
+import io.netty.handler.ssl.SslContextBuilder
+import io.netty.handler.ssl.SslProvider
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
+import org.onap.dcae.collectors.veshv.domain.OpenSslKeys
+import org.onap.dcae.collectors.veshv.ssl.impl.SslFactories.keyManagerFactory
+import org.onap.dcae.collectors.veshv.ssl.impl.SslFactories.trustManagerFactory
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since September 2018
+ */
+open class ClientSslContextFactory : SslContextFactory() {
+
+ override fun openSslContext(openSslKeys: OpenSslKeys) = SslContextBuilder.forClient()
+ .keyManager(openSslKeys.cert.toFile(), openSslKeys.privateKey.toFile())
+ .trustManager(openSslKeys.trustedCert.toFile())
+ .sslProvider(SslProvider.OPENSSL)!!
+
+ override fun jdkContext(jdkKeys: JdkKeys) =
+ try {
+ val kmf = keyManagerFactory(jdkKeys)
+ val tmf = trustManagerFactory(jdkKeys)
+ SslContextBuilder.forClient()
+ .keyManager(kmf)
+ .trustManager(tmf)
+ .sslProvider(SslProvider.JDK)!!
+ } finally {
+ jdkKeys.forgetPasswords()
+ }
+
+}
diff --git a/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactory.kt b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactory.kt
new file mode 100644
index 00000000..d26937fc
--- /dev/null
+++ b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactory.kt
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.ssl.boundary
+
+import io.netty.handler.ssl.SslContextBuilder
+import io.netty.handler.ssl.SslProvider
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
+import org.onap.dcae.collectors.veshv.domain.OpenSslKeys
+import org.onap.dcae.collectors.veshv.ssl.impl.SslFactories.keyManagerFactory
+import org.onap.dcae.collectors.veshv.ssl.impl.SslFactories.trustManagerFactory
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since September 2018
+ */
+open class ServerSslContextFactory : SslContextFactory() {
+
+ override fun openSslContext(openSslKeys: OpenSslKeys) = SslContextBuilder
+ .forServer(openSslKeys.cert.toFile(), openSslKeys.privateKey.toFile())
+ .trustManager(openSslKeys.trustedCert.toFile())
+ .sslProvider(SslProvider.OPENSSL)!!
+
+ override fun jdkContext(jdkKeys: JdkKeys) =
+ try {
+ val kmf = keyManagerFactory(jdkKeys)
+ val tmf = trustManagerFactory(jdkKeys)
+ SslContextBuilder.forServer(kmf)
+ .trustManager(tmf)
+ .sslProvider(SslProvider.JDK)!!
+ } finally {
+ jdkKeys.forgetPasswords()
+ }
+}
diff --git a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SslContextFactory.kt
index 3f7238f4..1fa20229 100644
--- a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt
+++ b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SslContextFactory.kt
@@ -17,29 +17,40 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.dcae.collectors.veshv.impl.socket
+package org.onap.dcae.collectors.veshv.ssl.boundary
import arrow.core.Option
import io.netty.handler.ssl.ClientAuth
import io.netty.handler.ssl.SslContext
import io.netty.handler.ssl.SslContextBuilder
-import io.netty.handler.ssl.SslProvider
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
+import org.onap.dcae.collectors.veshv.domain.OpenSslKeys
import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
-
-internal open class SslContextFactory {
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since September 2018
+ */
+abstract class SslContextFactory {
fun createSslContext(secConfig: SecurityConfiguration): Option<SslContext> =
if (secConfig.sslDisable) {
Option.empty()
} else {
- Option.just(createSslContextWithConfiguredCerts(secConfig)
- .sslProvider(SslProvider.OPENSSL)
- .clientAuth(ClientAuth.REQUIRE)
- .build())
+ createSslContextWithConfiguredCerts(secConfig)
+ .map { builder ->
+ builder.clientAuth(ClientAuth.REQUIRE)
+ .build()
+ }
}
- protected open fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration): SslContextBuilder =
- SslContextBuilder.forServer(secConfig.cert.toFile(), secConfig.privateKey.toFile())
- .trustManager(secConfig.trustedCert.toFile())
+ protected open fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration): Option<SslContextBuilder> =
+ secConfig.keys.map { keys ->
+ when (keys) {
+ is JdkKeys -> jdkContext(keys)
+ is OpenSslKeys -> openSslContext(keys)
+ }
+ }
+ protected abstract fun openSslContext(openSslKeys: OpenSslKeys): SslContextBuilder
+ protected abstract fun jdkContext(jdkKeys: JdkKeys): SslContextBuilder
}
diff --git a/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/utils.kt b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/utils.kt
new file mode 100644
index 00000000..2f2d02ec
--- /dev/null
+++ b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/utils.kt
@@ -0,0 +1,79 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.ssl.boundary
+
+import arrow.core.None
+import arrow.core.Option
+import arrow.core.Some
+import arrow.core.fix
+import arrow.core.monad
+import arrow.typeclasses.binding
+import org.apache.commons.cli.CommandLine
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption
+import org.onap.dcae.collectors.veshv.utils.commandline.hasOption
+import org.onap.dcae.collectors.veshv.utils.commandline.stringValue
+import java.io.File
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since September 2018
+ */
+
+
+const val KEY_STORE_FILE = "/etc/ves-hv/server.p12"
+const val TRUST_STORE_FILE = "/etc/ves-hv/trust.p12"
+
+fun createSecurityConfiguration(cmdLine: CommandLine): Option<SecurityConfiguration> {
+ val sslDisable = cmdLine.hasOption(CommandLineOption.SSL_DISABLE)
+
+ return if (sslDisable) disabledSecurityConfiguration(sslDisable) else enabledSecurityConfiguration(cmdLine)
+}
+
+private fun disabledSecurityConfiguration(sslDisable: Boolean): Some<SecurityConfiguration> {
+ return Some(SecurityConfiguration(
+ sslDisable = sslDisable,
+ keys = None
+ ))
+}
+
+private fun enabledSecurityConfiguration(cmdLine: CommandLine): Option<SecurityConfiguration> {
+ return Option.monad().binding {
+ val ksFile = cmdLine.stringValue(CommandLineOption.KEY_STORE_FILE, KEY_STORE_FILE)
+ val ksPass = cmdLine.stringValue(CommandLineOption.KEY_STORE_PASSWORD).bind()
+ val tsFile = cmdLine.stringValue(CommandLineOption.TRUST_STORE_FILE, TRUST_STORE_FILE)
+ val tsPass = cmdLine.stringValue(CommandLineOption.TRUST_STORE_PASSWORD).bind()
+
+ val keys = JdkKeys(
+ keyStore = streamFromFile(ksFile),
+ keyStorePassword = ksPass.toCharArray(),
+ trustStore = streamFromFile(tsFile),
+ trustStorePassword = tsPass.toCharArray()
+ )
+
+ SecurityConfiguration(
+ sslDisable = false,
+ keys = Some(keys)
+ )
+ }.fix()
+}
+
+private fun streamFromFile(file: String) = { File(file).inputStream() }
diff --git a/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/impl/SslFactories.kt b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/impl/SslFactories.kt
new file mode 100644
index 00000000..4a73a2aa
--- /dev/null
+++ b/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/impl/SslFactories.kt
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.ssl.impl
+
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
+import org.onap.dcae.collectors.veshv.domain.StreamProvider
+import java.security.KeyStore
+import javax.net.ssl.KeyManagerFactory
+import javax.net.ssl.TrustManagerFactory
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since September 2018
+ */
+internal object SslFactories {
+
+ fun trustManagerFactory(jdkKeys: JdkKeys): TrustManagerFactory? {
+ val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
+ val ts = loadKeyStoreFromFile(jdkKeys.trustStore, jdkKeys.trustStorePassword)
+ tmf.init(ts)
+ return tmf
+ }
+
+ fun keyManagerFactory(jdkKeys: JdkKeys): KeyManagerFactory? {
+ val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
+ val ks = loadKeyStoreFromFile(jdkKeys.keyStore, jdkKeys.keyStorePassword)
+ kmf.init(ks, jdkKeys.keyStorePassword)
+ return kmf
+ }
+
+ private fun loadKeyStoreFromFile(streamProvider: StreamProvider, password: CharArray): KeyStore {
+ val ks = KeyStore.getInstance("pkcs12")
+ streamProvider().use {
+ ks.load(it, password)
+ }
+ return ks
+ }
+}
diff --git a/hv-collector-ssl/src/test/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactoryTest.kt b/hv-collector-ssl/src/test/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactoryTest.kt
new file mode 100644
index 00000000..b4d72353
--- /dev/null
+++ b/hv-collector-ssl/src/test/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/ServerSslContextFactoryTest.kt
@@ -0,0 +1,163 @@
+/*
+ * ============LICENSE_START=======================================================
+ * dcaegen2-collectors-veshv
+ * ================================================================================
+ * Copyright (C) 2018 NOKIA
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.dcae.collectors.veshv.ssl.boundary
+
+import arrow.core.Left
+import arrow.core.Option
+import arrow.core.Right
+import arrow.core.Some
+import arrow.core.toOption
+import io.netty.handler.ssl.ClientAuth
+import io.netty.handler.ssl.JdkSslContext
+import io.netty.handler.ssl.ReferenceCountedOpenSslContext
+import io.netty.handler.ssl.SslContextBuilder
+import org.assertj.core.api.Assertions
+import org.assertj.core.api.Assertions.assertThat
+import org.jetbrains.spek.api.Spek
+import org.jetbrains.spek.api.dsl.describe
+import org.jetbrains.spek.api.dsl.given
+import org.jetbrains.spek.api.dsl.it
+import org.jetbrains.spek.api.dsl.on
+import org.onap.dcae.collectors.veshv.domain.JdkKeys
+import org.onap.dcae.collectors.veshv.domain.OpenSslKeys
+import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+import java.nio.file.Paths
+import kotlin.test.assertTrue
+
+/**
+ * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
+ * @since June 2018
+ */
+object ServerSslContextFactoryTest : Spek({
+ val PASSWORD = "onap"
+
+ describe("SslContextFactory (OpenSSL)") {
+ val keys = OpenSslKeys(
+ privateKey = Paths.get("/", "tmp", "pk.pem"),
+ cert = Paths.get("/", "tmp", "cert.crt"),
+ trustedCert = Paths.get("/", "tmp", "clientCa.crt"))
+
+ given("config with security enabled") {
+ val sampleConfig = SecurityConfiguration(keys = Some(keys))
+
+ val cut = object : ServerSslContextFactory() {
+ override fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration) =
+ SslContextBuilder.forServer(resource("/ssl/ca.crt"), resource("/ssl/server.key")).toOption()
+
+ private fun resource(path: String) = ServerSslContextFactoryTest.javaClass.getResourceAsStream(path)
+ }
+
+ on("creation of SSL context") {
+ val result = cut.createSslContext(sampleConfig)
+
+ it("should be server context") {
+ assertTrue(result.exists {
+ it.isServer
+ })
+ }
+
+ it("should use OpenSSL provider") {
+ assertTrue(result.isDefined())
+ }
+
+ /*
+ * It is too important to leave it untested on unit level.
+ * Because of the Netty API design we need to do it this way.
+ */
+ it("should turn on client authentication") {
+ val clientAuth: ClientAuth = ReferenceCountedOpenSslContext::class.java
+ .getDeclaredField("clientAuth")
+ .run {
+ isAccessible = true
+ get(result.orNull()) as ClientAuth
+ }
+ Assertions.assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE)
+ }
+ }
+ }
+
+ given("config with SSL disabled") {
+ val securityConfiguration = SecurityConfiguration(
+ sslDisable = true,
+ keys = Some(keys)
+ )
+ val cut = ServerSslContextFactory()
+
+ on("creation of SSL context") {
+ val result = cut.createSslContext(securityConfiguration)
+
+ it("should not create any SSL context ") {
+ assertThat(result.isDefined()).isFalse()
+ }
+ }
+ }
+ }
+
+ describe("SslContextFactory (JDK)") {
+ val keys = JdkKeys(
+ keyStore = resourceStreamProvider("/ssl/server.ks.pkcs12"),
+ keyStorePassword = PASSWORD.toCharArray(),
+ trustStore = resourceStreamProvider("/ssl/trust.pkcs12"),
+ trustStorePassword = PASSWORD.toCharArray()
+ )
+
+ given("config without disabled SSL") {
+ val sampleConfig = SecurityConfiguration(keys = Some(keys))
+ val cut = ServerSslContextFactory()
+
+ on("creation of SSL context") {
+ val result = cut.createSslContext(sampleConfig)
+
+ it("should work") {
+ assertTrue(result.isDefined())
+ }
+
+ it("should be server context") {
+ assertTrue(result.exists {
+ it.isServer
+ })
+ }
+
+ /*
+ * It is too important to leave it untested on unit level.
+ * Because of the Netty API design we need to do it this way.
+ */
+ it("should turn on client authentication") {
+ val clientAuth: ClientAuth = JdkSslContext::class.java
+ .getDeclaredField("clientAuth")
+ .run {
+ isAccessible = true
+ get(result.orNull()) as ClientAuth
+ }
+ Assertions.assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE)
+ }
+
+ it("should clear passwords so heap dumps won't contain them") {
+ val xedPassword = PASSWORD.toCharArray()
+ xedPassword.fill('x')
+ Assertions.assertThat(keys.keyStorePassword).isEqualTo(xedPassword)
+ Assertions.assertThat(keys.trustStorePassword).isEqualTo(xedPassword)
+ }
+ }
+ }
+ }
+})
+
+fun resourceStreamProvider(resource: String) = { ServerSslContextFactoryTest::class.java.getResourceAsStream(resource) }
diff --git a/hv-collector-ssl/src/test/resources/logback-test.xml b/hv-collector-ssl/src/test/resources/logback-test.xml
new file mode 100644
index 00000000..9a4eacfe
--- /dev/null
+++ b/hv-collector-ssl/src/test/resources/logback-test.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <property name="LOG_FILE"
+ value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}ves-hv.log}"/>
+ <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} %-5level [%-40.40logger{10}] - %msg%n"/>
+
+ <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>
+ %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} %highlight(%-5level) [%-40.40logger{10}] - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <appender name="ROLLING-FILE"
+ class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <encoder>
+ <pattern>${FILE_LOG_PATTERN}</pattern>
+ </encoder>
+ <file>${LOG_FILE}</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
+ <maxFileSize>50MB</maxFileSize>
+ <maxHistory>30</maxHistory>
+ <totalSizeCap>10GB</totalSizeCap>
+ </rollingPolicy>
+ </appender>
+
+ <logger name="org.onap.dcae.collectors.veshv" level="TRACE"/>
+
+ <root level="INFO">
+ <appender-ref ref="CONSOLE"/>
+ <appender-ref ref="ROLLING-FILE"/>
+ </root>
+</configuration>
diff --git a/hv-collector-ssl/src/test/resources/ssl/ca.crt b/hv-collector-ssl/src/test/resources/ssl/ca.crt
new file mode 100644
index 00000000..f9a05b90
--- /dev/null
+++ b/hv-collector-ssl/src/test/resources/ssl/ca.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDbDCCAlSgAwIBAgIJAMsh09jY3jSBMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
+BAYTAlBMMQswCQYDVQQIDAJETDEQMA4GA1UEBwwHV3JvY2xhdzEOMAwGA1UECgwF
+Tm9raWExDTALBgNVBAsMBE1BTk8wHhcNMTgwODEzMTE1OTE5WhcNMTkwODEzMTE1
+OTE5WjBLMQswCQYDVQQGEwJQTDELMAkGA1UECAwCREwxEDAOBgNVBAcMB1dyb2Ns
+YXcxDjAMBgNVBAoMBU5va2lhMQ0wCwYDVQQLDARNQU5PMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAyIs4sk5SlBRltDHZDDIGHdazzdduPRKdDBMUTE5i
+++iZe1MU9WnbPWgbnfj/1DN+VbbJEa32agDXBhS9mPiSrflDe8oqPPk12miiflsY
+TxGxY1bjH58kRNey164fPznzc9LqKqV1brUPktgBkHumM4zPVZYue5cp1T2FiWcE
+nFdqOKK2F0mdby+Pim9JHil34YcvavOlMXULkqayR7hxfUIAmMZtl59BKVx9BcKD
+9Sv9TQYRIYHhymrKnwIb8RolDaDdVUnr2ryREjZ8WfoBsOpraIYDUjKijF5FlgLs
+Fp8wcIflF6JyMbtchTm5acQZkcqK1AGYTD1wxT33E2pdDQIDAQABo1MwUTAdBgNV
+HQ4EFgQUOL9AR068MxqYCsKkEfgDzF2HrY8wHwYDVR0jBBgwFoAUOL9AR068MxqY
+CsKkEfgDzF2HrY8wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA
+OXNDDqrk8bTJfy78mkMZame/bLEUQ2h4EvWT6trd5XYNfPwQW/u6laLJAtLFbzth
+lpNBRK//sK+AYgwDURq0HcW5YczhgzZbfG9ab1J/7GUrFJh+DHL3bNL1YFX84JbI
+coUbxaJFkmIvlQDLWDYfpQ/gNwUbuUPZjGZC2bWobZw9sRC+e51TIoAmgZwvTElC
+v3vD2BwbIs7C4ylrIQU9Q1rY17MeWH9m8ZhEX1C4W4+N54V6jJ7czE9HQEnapeEu
+5rmEoDqP191x+tOxp/Xg8j+wcAK/dVy1Q3xQQZCW84rv0TBHbdaAPamBLUzHeW3W
+F7BpnVhn1NfYVOKx5W0NfA==
+-----END CERTIFICATE-----
diff --git a/hv-collector-ssl/src/test/resources/ssl/server.crt b/hv-collector-ssl/src/test/resources/ssl/server.crt
new file mode 100644
index 00000000..2b06108b
--- /dev/null
+++ b/hv-collector-ssl/src/test/resources/ssl/server.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDEjCCAfoCCQCId29lGbm5LjANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJQ
+TDELMAkGA1UECAwCREwxEDAOBgNVBAcMB1dyb2NsYXcxDjAMBgNVBAoMBU5va2lh
+MQ0wCwYDVQQLDARNQU5PMB4XDTE4MDgxMzEyMDAyNFoXDTE5MDgwODEyMDAyNFow
+SzELMAkGA1UEBhMCUEwxCzAJBgNVBAgMAkRMMRAwDgYDVQQHDAdXcm9jbGF3MQ4w
+DAYDVQQKDAVOb2tpYTENMAsGA1UECwwETUFOTzCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALbblOyqeJayotBiY6aZnGWnMHCHNTileJF8hkFS5P5qM9BU
+XH7NW/p5wSNcQWBB81HrRVneHpm6zfZtUPtcqXC4vpTk/sy3WT8rlEU+uv1YYVP8
+r0jxXr1WZ8sGcxOjhiMMRpMqImoALRak3ombtktfMc2Yeab4J25941wpDSQoUjT8
+LlXhfyjbBijum0LY+cqsuV5qk2qrzo0ZLD6m51aaWEyeysQ/3JanYKvPZDKdvAYN
++98ud6d/rjdWIJXwxEGp1fpW0p+fHOUhjMB1a5gkPDIpU68ME6BZJ3xJZb1qqXLS
+pkUitMIWZSWx5xNhcifsnxWyhZfnhd8GnxU3Lf8CAwEAATANBgkqhkiG9w0BAQsF
+AAOCAQEAJCrPdc8R7kBOmeIPyVX8QBOsrVTBBDzhskpi51nMsAKvcGjtYdXknYPj
+bw3YVASE2efrq5QWHC0maIxDAHzI/kmWGH8F0s8S6QRH/7fstvxaNaSArzQB/thW
+qIWs7AufUSsLMwtcXQ6KdYNbnaMwTynuuK+ANilcLvV8GxRAzXgFdoWZ2OuJRyzu
+BWQZS49WanyqX1kDLMsrLtdJyl/yVEfsmDcUyhapuuGwtconkWK/CVrJlV1vh1Z+
+Svh9IfvAF7WPPpGsM/y9+hGNtK6sPVUKl4acBzIAv6aN1QS5H4zRvtbwv7xpUp4M
+P84PY3lv1X3NJCGrfVByh2lFWParKA==
+-----END CERTIFICATE-----
diff --git a/hv-collector-ssl/src/test/resources/ssl/server.key b/hv-collector-ssl/src/test/resources/ssl/server.key
new file mode 100644
index 00000000..40e25932
--- /dev/null
+++ b/hv-collector-ssl/src/test/resources/ssl/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC225TsqniWsqLQ
+YmOmmZxlpzBwhzU4pXiRfIZBUuT+ajPQVFx+zVv6ecEjXEFgQfNR60VZ3h6Zus32
+bVD7XKlwuL6U5P7Mt1k/K5RFPrr9WGFT/K9I8V69VmfLBnMTo4YjDEaTKiJqAC0W
+pN6Jm7ZLXzHNmHmm+CdufeNcKQ0kKFI0/C5V4X8o2wYo7ptC2PnKrLleapNqq86N
+GSw+pudWmlhMnsrEP9yWp2Crz2QynbwGDfvfLnenf643ViCV8MRBqdX6VtKfnxzl
+IYzAdWuYJDwyKVOvDBOgWSd8SWW9aqly0qZFIrTCFmUlsecTYXIn7J8VsoWX54Xf
+Bp8VNy3/AgMBAAECggEATzN4o7GKnast/hg/lU9/gEAUKQlHMgvp1woalHy1FsUl
+QBzqGzoTlr/Zudkhr/Gg1GCVH0Gn+2n//7aFlvohoeNDGPa+rijUDRpxFDUBhO4c
+6eXOfkedg2DDgBqBCYaQeOm+P8vGMCd3YBF1GiFJqgfHaIecWYeufJsmOSrGuFvK
+1OvHpvg4/FLLQqgVcVO812kD4UwSOKnZVnPuZ3pzQviUZvO8ZxI/LkzQB1EdH6u3
+rBtiGslYkiKl5cGpH39/Dx2nKhHfvSnkfsm7koB00Bl41yy61GPwdl4XUwg8LUhX
+TbsuoIPGTJX/2FUMn0UnAdDJm29hE4eyHyYOhew8gQKBgQDlAeUcnFr9uxe0i7cg
+6ctJlNIKJjlA1tH4qIMEytdn06STo9g2j8X5HVE0FX/3+gAYDtEVICTF66w8Y474
+aeazvf+TCfkxtEOiH2afvaNkIkfzKR0ceB48DECT0DCF7xha5rJVf/W4GpCz2WkZ
+ojDzw5ZVvzbx/FaF9A/IseJ63wKBgQDMaSjiephhdlCERGPdwWMg3AfthEX/VHM0
+YugbVjjYjDbn2pMkntW2hUuVXP8HD+9DnQZo0/c/hxe28Q5b+2fjZephdctnY8tL
+XWbaEerM2lxEjmrpA4jYTBZJ9nMsxkEYHGHb5I586aS2YaZ12e7DoKMFdl0EZzvi
+zGPIxSzQ4QKBgAxVv8t8uIH2M96rr997+FEsTOvzBx5w87pbCUOW0WdsRO8W4ix+
+LgGvDJKrncrzklG5apWit5hZi1ttWWQUADMqRrvay6tbtFDlNBfilQxttEZqroC8
+D5TYbBoKGrL8H+m1h2GHlOqns6ecTEbvL4fRvyU7OXBrURXCAZ+jxTktAoGACbQI
+O9AEAcRjCBRTBUjT0tB/E9hOllNE8LytNfb+1dC6HoFysK9Vh8eGEf4LISOxgO0o
+S7ucJgjcqFODEfy6LsI8wQmdcTf8g4RYiIuHMNhAvwRfsNX5HgNmn3Yye3Khzmoy
+fwS3etiAeCPkif2hZunuMykuOzJHVnnLVtF9UiECgYEA41d7FgUcnfPIyA5xLg7K
+lRgjFMsc68uzoCBQww2kio0HNJpdOPBJlg6oHHfYKriv2r9793jETRVwjSNPlKZb
+vqm9yhnbXuahYBZSgdo2W+NbhP6IbJ0vrF4t9g6byjancQptaCjNIr9St9g+Ugly
+8m0n3gIT/+Lr+it63cgk8SA=
+-----END PRIVATE KEY-----
diff --git a/hv-collector-ssl/src/test/resources/ssl/server.ks.pkcs12 b/hv-collector-ssl/src/test/resources/ssl/server.ks.pkcs12
new file mode 100644
index 00000000..a97eb65a
--- /dev/null
+++ b/hv-collector-ssl/src/test/resources/ssl/server.ks.pkcs12
Binary files differ
diff --git a/hv-collector-ssl/src/test/resources/ssl/trust.pkcs12 b/hv-collector-ssl/src/test/resources/ssl/trust.pkcs12
new file mode 100644
index 00000000..01b61373
--- /dev/null
+++ b/hv-collector-ssl/src/test/resources/ssl/trust.pkcs12
Binary files differ
diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
index 44d425ea..da5ff918 100644
--- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
+++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt
@@ -55,31 +55,5 @@ abstract class ArgBasedConfiguration<T>(private val parser: CommandLineParser) {
protected abstract fun getConfiguration(cmdLine: CommandLine): Option<T>
- protected fun CommandLine.longValue(cmdLineOpt: CommandLineOption, default: Long): Long =
- longValue(cmdLineOpt).getOrElse { default }
-
- protected fun CommandLine.stringValue(cmdLineOpt: CommandLineOption, default: String): String =
- optionValue(cmdLineOpt).getOrElse { default }
-
- protected fun CommandLine.intValue(cmdLineOpt: CommandLineOption, default: Int): Int =
- intValue(cmdLineOpt).getOrElse { default }
-
- protected fun CommandLine.intValue(cmdLineOpt: CommandLineOption): Option<Int> =
- optionValue(cmdLineOpt).map(String::toInt)
-
- private fun CommandLine.longValue(cmdLineOpt: CommandLineOption): Option<Long> =
- optionValue(cmdLineOpt).map(String::toLong)
-
- protected fun CommandLine.stringValue(cmdLineOpt: CommandLineOption): Option<String> =
- optionValue(cmdLineOpt)
-
- protected fun CommandLine.hasOption(cmdLineOpt: CommandLineOption): Boolean =
- this.hasOption(cmdLineOpt.option.opt) ||
- System.getenv(cmdLineOpt.environmentVariableName()) != null
-
protected fun stringPathToPath(path: String): Path = Paths.get(File(path).toURI())
-
- private fun CommandLine.optionValue(cmdLineOpt: CommandLineOption) = Option.fromNullablesChain(
- getOptionValue(cmdLineOpt.option.opt),
- { System.getenv(cmdLineOpt.environmentVariableName()) })
}
diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
index 9379c409..288a578d 100644
--- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
+++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt
@@ -88,22 +88,28 @@ enum class CommandLineOption(val option: Option, val required: Boolean = false)
.desc("Disable SSL encryption")
.build()
),
- PRIVATE_KEY_FILE(Option.builder("k")
- .longOpt("private-key-file")
+ KEY_STORE_FILE(Option.builder("k")
+ .longOpt("key-store")
.hasArg()
- .desc("File with private key in PEM format")
+ .desc("Key store in PKCS12 format")
.build()
),
- CERT_FILE(Option.builder("e")
- .longOpt("cert-file")
+ KEY_STORE_PASSWORD(Option.builder("kp")
+ .longOpt("key-store-password")
.hasArg()
- .desc("File with certificate bundle")
+ .desc("Key store password")
.build()
),
- TRUST_CERT_FILE(Option.builder("t")
- .longOpt("trust-cert-file")
+ TRUST_STORE_FILE(Option.builder("t")
+ .longOpt("trust-store")
.hasArg()
- .desc("File with trusted certificate bundle for trusting connections")
+ .desc("File with trusted certificate bundle in PKCS12 format")
+ .build()
+ ),
+ TRUST_STORE_PASSWORD(Option.builder("tp")
+ .longOpt("trust-store-password")
+ .hasArg()
+ .desc("Trust store password")
.build()
),
IDLE_TIMEOUT_SEC(Option.builder("i")
diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt
index 718ebf8b..ba4c0802 100644
--- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt
+++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt
@@ -19,9 +19,13 @@
*/
package org.onap.dcae.collectors.veshv.utils.commandline
+import arrow.core.Option
+import arrow.core.getOrElse
import arrow.effects.IO
import arrow.syntax.function.curried
+import org.apache.commons.cli.CommandLine
import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure
+import org.onap.dcae.collectors.veshv.utils.arrow.fromNullablesChain
/**
* @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
@@ -34,3 +38,29 @@ fun handleWrongArgumentError(programName: String, err: WrongArgumentError): IO<U
}.flatMap { ExitFailure(2).io() }
val handleWrongArgumentErrorCurried = ::handleWrongArgumentError.curried()
+
+fun CommandLine.longValue(cmdLineOpt: CommandLineOption, default: Long): Long =
+ longValue(cmdLineOpt).getOrElse { default }
+
+fun CommandLine.stringValue(cmdLineOpt: CommandLineOption, default: String): String =
+ optionValue(cmdLineOpt).getOrElse { default }
+
+fun CommandLine.intValue(cmdLineOpt: CommandLineOption, default: Int): Int =
+ intValue(cmdLineOpt).getOrElse { default }
+
+fun CommandLine.intValue(cmdLineOpt: CommandLineOption): Option<Int> =
+ optionValue(cmdLineOpt).map(String::toInt)
+
+fun CommandLine.longValue(cmdLineOpt: CommandLineOption): Option<Long> =
+ optionValue(cmdLineOpt).map(String::toLong)
+
+fun CommandLine.stringValue(cmdLineOpt: CommandLineOption): Option<String> =
+ optionValue(cmdLineOpt)
+
+fun CommandLine.hasOption(cmdLineOpt: CommandLineOption): Boolean =
+ this.hasOption(cmdLineOpt.option.opt) ||
+ System.getenv(cmdLineOpt.environmentVariableName()) != null
+
+private fun CommandLine.optionValue(cmdLineOpt: CommandLineOption) = Option.fromNullablesChain(
+ getOptionValue(cmdLineOpt.option.opt),
+ { System.getenv(cmdLineOpt.environmentVariableName()) }) \ No newline at end of file
diff --git a/hv-collector-xnf-simulator/Dockerfile b/hv-collector-xnf-simulator/Dockerfile
index 53406459..ed9dd9b4 100644
--- a/hv-collector-xnf-simulator/Dockerfile
+++ b/hv-collector-xnf-simulator/Dockerfile
@@ -6,7 +6,7 @@ LABEL license.url="http://www.apache.org/licenses/LICENSE-2.0"
LABEL maintainer="Nokia Wroclaw ONAP Team"
RUN apt-get update \
- && apt-get install -y --no-install-recommends curl \
+ && apt-get install -y --no-install-recommends curl \
&& apt-get clean
WORKDIR /opt/ves-hv-client-simulator
diff --git a/hv-collector-xnf-simulator/pom.xml b/hv-collector-xnf-simulator/pom.xml
index cfe1dc14..b3de6b2d 100644
--- a/hv-collector-xnf-simulator/pom.xml
+++ b/hv-collector-xnf-simulator/pom.xml
@@ -87,6 +87,11 @@
</dependency>
<dependency>
<groupId>${project.parent.groupId}</groupId>
+ <artifactId>hv-collector-ssl</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.parent.groupId}</groupId>
<artifactId>hv-collector-utils</artifactId>
<version>${project.parent.version}</version>
</dependency>
@@ -121,12 +126,18 @@
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
+ <!-- See comment in main pom
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ <classifier>${os.detected.classifier}</classifier>
+ </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
- <scope>runtime</scope>
<classifier>${os.detected.classifier}</classifier>
</dependency>
+ -->
<dependency>
<groupId>com.nhaarman</groupId>
<artifactId>mockito-kotlin</artifactId>
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/adapters/VesHvClient.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/adapters/VesHvClient.kt
index af71e9ce..7a280c10 100644
--- a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/adapters/VesHvClient.kt
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/adapters/VesHvClient.kt
@@ -28,6 +28,7 @@ import org.onap.dcae.collectors.veshv.domain.WireFrameMessage
import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
import org.onap.dcae.collectors.veshv.domain.WireFrameEncoder
import org.onap.dcae.collectors.veshv.simulators.xnf.impl.config.SimulatorConfiguration
+import org.onap.dcae.collectors.veshv.ssl.boundary.ClientSslContextFactory
import org.onap.dcae.collectors.veshv.utils.arrow.asIo
import org.onap.dcae.collectors.veshv.utils.logging.Logger
import org.reactivestreams.Publisher
@@ -37,7 +38,6 @@ import reactor.core.publisher.ReplayProcessor
import reactor.ipc.netty.NettyOutbound
import reactor.ipc.netty.tcp.TcpClient
-
/**
* @author Jakub Dudycz <jakub.dudycz@nokia.com>
* @since June 2018
@@ -92,18 +92,7 @@ class VesHvClient(private val configuration: SimulatorConfiguration) {
}
private fun createSslContext(config: SecurityConfiguration): Option<SslContext> =
- if (config.sslDisable) {
- Option.empty()
- } else {
- Option.just(
- SslContextBuilder.forClient()
- .keyManager(config.cert.toFile(), config.privateKey.toFile())
- .trustManager(config.trustedCert.toFile())
- .sslProvider(SslProvider.OPENSSL)
- .clientAuth(ClientAuth.REQUIRE)
- .build()
- )
- }
+ ClientSslContextFactory().createSslContext(config)
private fun NettyOutbound.logConnectionClosed(): NettyOutbound {
context().onClose {
diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/config/ArgXnfSimulatorConfiguration.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/config/ArgXnfSimulatorConfiguration.kt
index 56d6212a..3d8dc948 100644
--- a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/config/ArgXnfSimulatorConfiguration.kt
+++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/impl/config/ArgXnfSimulatorConfiguration.kt
@@ -19,16 +19,24 @@
*/
package org.onap.dcae.collectors.veshv.simulators.xnf.impl.config
-import arrow.core.ForOption
import arrow.core.Option
import arrow.core.fix
-import arrow.instances.extensions
+import arrow.core.monad
import arrow.typeclasses.binding
import org.apache.commons.cli.CommandLine
import org.apache.commons.cli.DefaultParser
-import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
+import org.onap.dcae.collectors.veshv.ssl.boundary.createSecurityConfiguration
import org.onap.dcae.collectors.veshv.utils.commandline.ArgBasedConfiguration
-import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.*
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KEY_STORE_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.KEY_STORE_PASSWORD
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.LISTEN_PORT
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.SSL_DISABLE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_STORE_FILE
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_STORE_PASSWORD
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.VES_HV_HOST
+import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.VES_HV_PORT
+import org.onap.dcae.collectors.veshv.utils.commandline.intValue
+import org.onap.dcae.collectors.veshv.utils.commandline.stringValue
/**
@@ -41,42 +49,22 @@ internal class ArgXnfSimulatorConfiguration : ArgBasedConfiguration<SimulatorCon
VES_HV_HOST,
LISTEN_PORT,
SSL_DISABLE,
- PRIVATE_KEY_FILE,
- CERT_FILE,
- TRUST_CERT_FILE
- )
+ KEY_STORE_FILE,
+ KEY_STORE_PASSWORD,
+ TRUST_STORE_FILE,
+ TRUST_STORE_PASSWORD)
override fun getConfiguration(cmdLine: CommandLine): Option<SimulatorConfiguration> =
- ForOption extensions {
- binding {
- val listenPort = cmdLine.intValue(LISTEN_PORT).bind()
- val vesHost = cmdLine.stringValue(VES_HV_HOST).bind()
- val vesPort = cmdLine.intValue(VES_HV_PORT).bind()
+ Option.monad().binding {
+ val listenPort = cmdLine.intValue(LISTEN_PORT).bind()
+ val vesHost = cmdLine.stringValue(VES_HV_HOST).bind()
+ val vesPort = cmdLine.intValue(VES_HV_PORT).bind()
- SimulatorConfiguration(
- listenPort,
- vesHost,
- vesPort,
- parseSecurityConfig(cmdLine))
- }.fix()
- }
+ SimulatorConfiguration(
+ listenPort,
+ vesHost,
+ vesPort,
+ createSecurityConfiguration(cmdLine).bind())
+ }.fix()
- private fun parseSecurityConfig(cmdLine: CommandLine): SecurityConfiguration {
- val sslDisable = cmdLine.hasOption(SSL_DISABLE)
- val pkFile = cmdLine.stringValue(PRIVATE_KEY_FILE, DefaultValues.PRIVATE_KEY_FILE)
- val certFile = cmdLine.stringValue(CERT_FILE, DefaultValues.CERT_FILE)
- val trustCertFile = cmdLine.stringValue(TRUST_CERT_FILE, DefaultValues.TRUST_CERT_FILE)
-
- return SecurityConfiguration(
- sslDisable = sslDisable,
- privateKey = stringPathToPath(pkFile),
- cert = stringPathToPath(certFile),
- trustedCert = stringPathToPath(trustCertFile))
- }
-
- internal object DefaultValues {
- const val PRIVATE_KEY_FILE = "/etc/ves-hv/client.key"
- const val CERT_FILE = "/etc/ves-hv/client.crt"
- const val TRUST_CERT_FILE = "/etc/ves-hv/trust.crt"
- }
}
diff --git a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgXnfSimulatorConfiurationTest.kt b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgXnfSimulatorConfiurationTest.kt
deleted file mode 100644
index 69caf727..00000000
--- a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgXnfSimulatorConfiurationTest.kt
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * dcaegen2-collectors-veshv
- * ================================================================================
- * Copyright (C) 2018 NOKIA
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-package org.onap.dcae.collectors.veshv.main.config
-
-import org.assertj.core.api.Assertions.assertThat
-import org.jetbrains.spek.api.Spek
-import org.jetbrains.spek.api.dsl.describe
-import org.jetbrains.spek.api.dsl.given
-import org.jetbrains.spek.api.dsl.it
-import org.jetbrains.spek.api.dsl.on
-import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
-import org.onap.dcae.collectors.veshv.simulators.xnf.impl.config.ArgXnfSimulatorConfiguration
-import org.onap.dcae.collectors.veshv.simulators.xnf.impl.config.ArgXnfSimulatorConfiguration.DefaultValues
-import org.onap.dcae.collectors.veshv.simulators.xnf.impl.config.SimulatorConfiguration
-import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingFailure
-import org.onap.dcae.collectors.veshv.tests.utils.parseExpectingSuccess
-import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentError
-import java.nio.file.Paths
-import kotlin.test.assertTrue
-
-
-object ArgXnfSimulatorConfiurationTest : Spek({
- lateinit var cut: ArgXnfSimulatorConfiguration
- val listenPort = "4321"
- val vesHost = "localhost"
- val vesPort = "1234"
- val pk = Paths.get("/", "etc", "ves", "pk.pem")
- val cert = Paths.get("/", "etc", "ssl", "certs", "ca-bundle.crt")
- val trustCert = Paths.get("/", "etc", "ves", "trusted.crt")
-
- beforeEachTest {
- cut = ArgXnfSimulatorConfiguration()
- }
-
- describe("parsing arguments") {
- lateinit var result: SimulatorConfiguration
-
- given("all parameters are present in the long form") {
-
- beforeEachTest {
- result = cut.parseExpectingSuccess("--ssl-disable",
- "--listen-port", listenPort,
- "--ves-host", vesHost,
- "--ves-port", vesPort,
- "--private-key-file", pk.toFile().absolutePath,
- "--cert-file", cert.toFile().absolutePath,
- "--trust-cert-file", trustCert.toFile().absolutePath)
- }
-
- it("should set proper listen port") {
- assertThat(result.listenPort).isEqualTo(listenPort.toInt())
- }
-
- it("should set proper ves host") {
- assertThat(result.vesHost).isEqualTo(vesHost)
- }
-
- it("should set proper ves port") {
- assertThat(result.vesPort).isEqualTo(vesPort.toInt())
- }
-
- it("should set proper security configuration") {
- assertThat(result.security).isEqualTo(
- SecurityConfiguration(sslDisable = true, privateKey = pk, cert = cert, trustedCert = trustCert)
- )
- }
- }
-
- given("some parameters are present in the short form") {
-
- beforeEachTest {
- result = cut.parseExpectingSuccess("-p", listenPort, "-h", vesHost, "--ves-port", vesPort)
- }
-
- it("should set proper listen port") {
- assertThat(result.listenPort).isEqualTo(listenPort.toInt())
- }
-
- it("should set proper ves host") {
- assertThat(result.vesHost).isEqualTo(vesHost)
- }
-
- it("should set proper ves port") {
- assertThat(result.vesPort).isEqualTo(vesPort.toInt())
- }
- }
-
- given("all optional parameters are absent") {
-
- beforeEachTest {
- result = cut.parseExpectingSuccess("-p", listenPort, "-h", vesHost, "-v", vesPort)
- }
-
- on("security config") {
- val securityConfiguration = result.security
-
- it("should set default trust cert file") {
- assertThat(securityConfiguration.trustedCert.toString()).isEqualTo(DefaultValues.TRUST_CERT_FILE)
- }
-
- it("should set default server cert file") {
- assertThat(securityConfiguration.cert.toString()).isEqualTo(DefaultValues.CERT_FILE)
- }
-
- it("should set default private key file") {
- assertThat(securityConfiguration.privateKey.toString()).isEqualTo(DefaultValues.PRIVATE_KEY_FILE)
- }
- }
- }
-
- given("disabled ssl certs together with all other parameters") {
- beforeEachTest {
- result = cut.parseExpectingSuccess("--ssl-disable",
- "--listen-port", listenPort,
- "--ves-port", "888",
- "--ves-host", vesHost,
- "--private-key-file", pk.toFile().absolutePath,
- "--cert-file", cert.toFile().absolutePath,
- "--trust-cert-file", trustCert.toFile().absolutePath)
- }
-
- on("security config") {
- val securityConfiguration = result.security
-
- it("should set ssl disable to true") {
- assertTrue(securityConfiguration.sslDisable)
- }
-
- it("should set proper security configuration") {
- assertThat(securityConfiguration).isEqualTo(
- SecurityConfiguration(
- sslDisable = true,
- privateKey = pk,
- cert = cert,
- trustedCert = trustCert)
- )
- }
- }
- }
-
- describe("required parameter is absent") {
- given("ves port is missing") {
- it("should throw exception") {
- assertThat(cut.parseExpectingFailure("-p", listenPort, "-h", vesHost))
- .isInstanceOf(WrongArgumentError::class.java)
- }
- }
-
- given("ves host is missing") {
- it("should throw exception") {
- assertThat(cut.parseExpectingFailure("-p", listenPort, "-v", vesPort))
- .isInstanceOf(WrongArgumentError::class.java)
- }
- }
-
- given("listen port is missing") {
- it("should throw exception") {
- assertThat(cut.parseExpectingFailure("-h", vesHost, "-v", vesPort))
- .isInstanceOf(WrongArgumentError::class.java)
- }
- }
- }
- }
-})
diff --git a/pom.xml b/pom.xml
index a71f942e..71f02fb4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,7 @@
<module>hv-collector-domain</module>
<module>hv-collector-health-check</module>
<module>hv-collector-main</module>
+ <module>hv-collector-ssl</module>
<module>hv-collector-test-utils</module>
<module>hv-collector-utils</module>
<module>hv-collector-ves-message-generator</module>
@@ -64,7 +65,7 @@
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
<build-helper-maven-plugin.version>1.7</build-helper-maven-plugin.version>
<jacoco.version>0.8.2</jacoco.version>
- <jacoco.minimum.coverage>66</jacoco.minimum.coverage>
+ <jacoco.minimum.coverage>60</jacoco.minimum.coverage>
<!-- Protocol buffers -->
<protobuf.version>3.5.1</protobuf.version>
@@ -586,16 +587,31 @@
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
- <version>Bismuth-SR10</version>
+ <!-- remember to update netty native bindings versions -->
+ <version>Bismuth-SR11</version>
<type>pom</type>
<scope>import</scope>
</dependency>
+
+ <!--
+ Disable native extensions (ssl and epoll) on production for now.
+ Might be reintroduced if performance tests prove there is some performance issue.
+ -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
- <version>2.0.8.Final</version>
+ <version>2.0.15.Final</version>
+ <scope>runtime</scope>
+ <classifier>${os.detected.classifier}</classifier>
+ </dependency>
+ <!--
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-transport-native-epoll</artifactId>
+ <version>4.1.29.Final</version>
<classifier>${os.detected.classifier}</classifier>
</dependency>
+ -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
diff --git a/ssl/.gitignore b/ssl/.gitignore
index 598dc753..23888eb0 100644
--- a/ssl/.gitignore
+++ b/ssl/.gitignore
@@ -2,3 +2,6 @@
*.key
*.srl
*.csr
+*.pkcs12
+*.p12
+
diff --git a/ssl/Makefile b/ssl/Makefile-openssl
index 28326505..09802ce4 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile-openssl
@@ -1,12 +1,13 @@
FILE=sample
-CA_PASSWD=onap
+PASSWD=onaponap
+CA_PASSWD=onaponap
SUBJ=/C=PL/ST=DL/L=Wroclaw/O=Nokia/OU=MANO
CA=trust
sign: $(FILE).crt
clean:
- rm -f *.crt *.key *.srl *.csr
+ rm -f *.crt *.key *.srl *.csr *.pkcs12
generate-ca-certificate: $(CA).crt
@@ -16,6 +17,11 @@ create-public-key: $(FILE).pub
create-sign-request: $(FILE).csr
+create-key-store: $(FILE).ks.pkcs12
+
+create-trust-store: $(CA).crt
+ openssl pkcs12 -export -in $(CA).crt -CAfile $(CA).crt -out $(CA).pkcs12 -nokeys -noiter -nomaciter -passout pass:$(PASSWD)
+
$(CA).crt:
openssl req -new -x509 -keyout $(CA).key -out $(CA).crt -days 365 -passout pass:$(CA_PASSWD) -subj "$(SUBJ)"
@@ -31,3 +37,5 @@ $(FILE).csr: $(FILE).key
$(FILE).crt: $(CA).crt $(FILE).csr
openssl x509 -req -days 360 -in $(FILE).csr -CA $(CA).crt -CAkey $(CA).key -out $(FILE).crt -CAcreateserial -passin pass:$(CA_PASSWD)
+$(FILE).ks.pkcs12: $(FILE).key $(FILE).crt $(CA).crt
+ openssl pkcs12 -export -in $(FILE).crt -inkey $(FILE).key -CAfile $(CA).crt -out $(FILE).ks.pkcs12 -noiter -nomaciter -passout pass:$(PASSWD)
diff --git a/ssl/README.md b/ssl/README.md
index efba6107..c2819d24 100644
--- a/ssl/README.md
+++ b/ssl/README.md
@@ -1,5 +1,23 @@
# Generating SSL certificates
+## Java keytool way (recommended)
+
+To generate:
+
+```shell
+./gen-certs.sh
+```
+
+To clean (remove generated files):
+
+```shell
+./gen-certs.sh clean
+```
+
+## OpenSSL way (currently might not work)
+
+> Add `-f Makefile-openssl` to each command
+
Typical usage:
```shell
@@ -7,6 +25,14 @@ make FILE=client
make FILE=server
```
+or (to generate PKCS12 key and trust stores):
+
+```shell
+make create-key-store FILE=client
+make create-key-store FILE=server
+make create-trust-store
+```
+
Will generate CA certificate and signed client and server certificates.
More "low-level" usage:
diff --git a/ssl/gen-certs.sh b/ssl/gen-certs.sh
new file mode 100755
index 00000000..b4f78227
--- /dev/null
+++ b/ssl/gen-certs.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+
+set -eu -o pipefail -o xtrace
+
+STORE_PASS=onaponap
+CN_PREFIX=dcaegen2-hvves
+DNAME_PREFIX="C=PL,ST=DL,L=Wroclaw,O=Nokia,OU=MANO,CN=${CN_PREFIX}"
+TRUST=trust
+
+store_opts="-storetype PKCS12 -storepass ${STORE_PASS} -noprompt"
+
+function gen_key() {
+ local key_name="$1"
+ local ca="$2"
+ local keystore="-keystore ${key_name}.p12 ${store_opts}"
+ keytool -genkey -alias ${key_name} \
+ ${keystore} \
+ -keyalg RSA \
+ -validity 730 \
+ -keysize 2048 \
+ -dname "${DNAME_PREFIX}-${key_name}"
+ keytool -import -trustcacerts -alias ${ca} -file ${ca}.crt ${keystore}
+
+ keytool -certreq -alias ${key_name} -keyalg RSA ${keystore} | \
+ keytool -alias ${ca} -gencert -ext "san=dns:${CN_PREFIX}-${ca}" ${store_opts} -keystore ${ca}.p12 | \
+ keytool -alias ${key_name} -importcert ${keystore}
+}
+
+
+function gen_ca() {
+ local ca="$1"
+ keytool -genkeypair ${store_opts} -alias ${ca} -dname "${DNAME_PREFIX}-${ca}" -keystore ${ca}.p12
+ keytool -export -alias ${ca} -file ${ca}.crt ${store_opts} -keystore ${ca}.p12
+}
+
+function gen_truststore() {
+ local trusted_ca="$1"
+ keytool -import -trustcacerts -alias ca -file ${trusted_ca}.crt ${store_opts} -keystore ${TRUST}.p12
+}
+
+function clean() {
+ rm -f *.crt *.p12
+}
+
+if [[ $# -eq 0 ]]; then
+ gen_ca ca
+ gen_ca untrustedca
+ gen_truststore ca
+ gen_key client ca
+ gen_key server ca
+ gen_key untrustedclient untrustedca
+elif [[ $1 == "clean" ]]; then
+ clean
+else
+ echo "usage: $0 [clean]"
+ exit 1
+fi
+