b4d72353373a2ceab7646194d1e5f47b33191cfd
[dcaegen2/collectors/hv-ves.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * dcaegen2-collectors-veshv
4  * ================================================================================
5  * Copyright (C) 2018 NOKIA
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.dcae.collectors.veshv.ssl.boundary
21
22 import arrow.core.Left
23 import arrow.core.Option
24 import arrow.core.Right
25 import arrow.core.Some
26 import arrow.core.toOption
27 import io.netty.handler.ssl.ClientAuth
28 import io.netty.handler.ssl.JdkSslContext
29 import io.netty.handler.ssl.ReferenceCountedOpenSslContext
30 import io.netty.handler.ssl.SslContextBuilder
31 import org.assertj.core.api.Assertions
32 import org.assertj.core.api.Assertions.assertThat
33 import org.jetbrains.spek.api.Spek
34 import org.jetbrains.spek.api.dsl.describe
35 import org.jetbrains.spek.api.dsl.given
36 import org.jetbrains.spek.api.dsl.it
37 import org.jetbrains.spek.api.dsl.on
38 import org.onap.dcae.collectors.veshv.domain.JdkKeys
39 import org.onap.dcae.collectors.veshv.domain.OpenSslKeys
40 import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration
41 import java.nio.file.Paths
42 import kotlin.test.assertTrue
43
44 /**
45  * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
46  * @since June 2018
47  */
48 object ServerSslContextFactoryTest : Spek({
49     val PASSWORD = "onap"
50
51     describe("SslContextFactory (OpenSSL)") {
52         val keys = OpenSslKeys(
53                 privateKey = Paths.get("/", "tmp", "pk.pem"),
54                 cert = Paths.get("/", "tmp", "cert.crt"),
55                 trustedCert = Paths.get("/", "tmp", "clientCa.crt"))
56
57         given("config with security enabled") {
58             val sampleConfig = SecurityConfiguration(keys = Some(keys))
59
60             val cut = object : ServerSslContextFactory() {
61                 override fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration) =
62                     SslContextBuilder.forServer(resource("/ssl/ca.crt"), resource("/ssl/server.key")).toOption()
63
64                 private fun resource(path: String) = ServerSslContextFactoryTest.javaClass.getResourceAsStream(path)
65             }
66
67             on("creation of SSL context") {
68                 val result = cut.createSslContext(sampleConfig)
69
70                 it("should be server context") {
71                     assertTrue(result.exists {
72                         it.isServer
73                     })
74                 }
75
76                 it("should use OpenSSL provider") {
77                     assertTrue(result.isDefined())
78                 }
79
80                 /*
81                  * It is too important to leave it untested on unit level.
82                  * Because of the Netty API design we need to do it this way.
83                  */
84                 it("should turn on client authentication") {
85                     val clientAuth: ClientAuth = ReferenceCountedOpenSslContext::class.java
86                             .getDeclaredField("clientAuth")
87                             .run {
88                                 isAccessible = true
89                                 get(result.orNull()) as ClientAuth
90                             }
91                     Assertions.assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE)
92                 }
93             }
94         }
95
96         given("config with SSL disabled") {
97             val securityConfiguration = SecurityConfiguration(
98                     sslDisable = true,
99                     keys = Some(keys)
100             )
101             val cut = ServerSslContextFactory()
102
103             on("creation of SSL context") {
104                 val result = cut.createSslContext(securityConfiguration)
105
106                 it("should not create any SSL context ") {
107                     assertThat(result.isDefined()).isFalse()
108                 }
109             }
110         }
111     }
112
113     describe("SslContextFactory (JDK)") {
114         val keys = JdkKeys(
115                 keyStore = resourceStreamProvider("/ssl/server.ks.pkcs12"),
116                 keyStorePassword = PASSWORD.toCharArray(),
117                 trustStore = resourceStreamProvider("/ssl/trust.pkcs12"),
118                 trustStorePassword = PASSWORD.toCharArray()
119         )
120
121         given("config without disabled SSL") {
122             val sampleConfig = SecurityConfiguration(keys = Some(keys))
123             val cut = ServerSslContextFactory()
124
125             on("creation of SSL context") {
126                 val result = cut.createSslContext(sampleConfig)
127
128                 it("should work") {
129                     assertTrue(result.isDefined())
130                 }
131
132                 it("should be server context") {
133                     assertTrue(result.exists {
134                         it.isServer
135                     })
136                 }
137
138                 /*
139                  * It is too important to leave it untested on unit level.
140                  * Because of the Netty API design we need to do it this way.
141                  */
142                 it("should turn on client authentication") {
143                     val clientAuth: ClientAuth = JdkSslContext::class.java
144                             .getDeclaredField("clientAuth")
145                             .run {
146                                 isAccessible = true
147                                 get(result.orNull()) as ClientAuth
148                             }
149                     Assertions.assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE)
150                 }
151
152                 it("should clear passwords so heap dumps won't contain them") {
153                     val xedPassword = PASSWORD.toCharArray()
154                     xedPassword.fill('x')
155                     Assertions.assertThat(keys.keyStorePassword).isEqualTo(xedPassword)
156                     Assertions.assertThat(keys.trustStorePassword).isEqualTo(xedPassword)
157                 }
158             }
159         }
160     }
161 })
162
163 fun resourceStreamProvider(resource: String) = { ServerSslContextFactoryTest::class.java.getResourceAsStream(resource) }