2 * Copyright 2016-2017, Nokia Corporation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm;
19 import com.google.gson.Gson;
20 import com.google.gson.JsonParseException;
21 import com.google.gson.annotations.SerializedName;
22 import com.nokia.cbam.lcn.v32.JSON;
23 import io.reactivex.Observable;
24 import okhttp3.OkHttpClient;
25 import okhttp3.RequestBody;
26 import okhttp3.ResponseBody;
27 import org.junit.After;
28 import org.junit.Before;
29 import org.junit.Test;
30 import retrofit2.Converter;
31 import retrofit2.Retrofit;
32 import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
33 import retrofit2.converter.gson.GsonConverterFactory;
34 import retrofit2.http.GET;
35 import retrofit2.http.Headers;
37 import javax.xml.bind.annotation.XmlAccessType;
38 import javax.xml.bind.annotation.XmlAccessorType;
39 import javax.xml.bind.annotation.XmlElement;
40 import javax.xml.bind.annotation.XmlRootElement;
41 import java.io.IOException;
42 import java.lang.annotation.Annotation;
43 import java.lang.reflect.Type;
44 import java.nio.file.Files;
45 import java.nio.file.Path;
46 import java.nio.file.Paths;
47 import java.util.Base64;
49 import static junit.framework.TestCase.*;
50 import static org.springframework.test.util.ReflectionTestUtils.setField;
52 interface TestService {
54 "Content-Type:application/json"
57 Observable<TestResource> subscriptionsGet();
60 @XmlRootElement(name = "Subscription")
61 @XmlAccessorType(XmlAccessType.FIELD)
63 @XmlElement(name = "id")
65 public String id = null;
68 class GsonCustomConverterFactory extends Converter.Factory {
69 private final Gson gson;
70 private final GsonConverterFactory gsonConverterFactory;
72 private GsonCustomConverterFactory(Gson gson) {
74 throw new NullPointerException("gson == null");
76 this.gsonConverterFactory = GsonConverterFactory.create(gson);
79 public static GsonCustomConverterFactory create(Gson gson) {
80 return new GsonCustomConverterFactory(gson);
84 public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
85 if (type.equals(String.class))
86 return new GsonResponseBodyConverterToString<Object>(gson, type);
88 return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
92 public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
93 return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
97 class GsonResponseBodyConverterToString<T> implements Converter<ResponseBody, T> {
98 private final Gson gson;
99 private final Type type;
101 GsonResponseBodyConverterToString(Gson gson, Type type) {
107 public T convert(ResponseBody value) throws IOException {
108 String returned = value.string();
110 return gson.fromJson(returned, type);
111 } catch (JsonParseException e) {
117 public class TestCbamSecurityProvider extends TestBase {
118 CbamSecurityProvider securityProvider = new CbamSecurityProvider() {
121 HttpTestServer testServer = new HttpTestServer();
125 public void init() throws Exception {
126 setField(securityProvider, "skipCertificateVerification", true);
127 setField(securityProvider, "skipHostnameVerification", true);
128 testServer = new HttpTestServer();
130 url = testServer._server.getURI().toString();
134 public void testServer() throws Exception {
139 * test skipping certificate and skipping hostname verification
142 public void testSkipHostAndSkipCertifiacateVerification() throws Exception {
143 setField(securityProvider, "skipCertificateVerification", true);
144 setField(securityProvider, "skipHostnameVerification", true);
146 TestResource testResource = fireRequest();
148 assertEquals("1234", testResource.id);
150 securityProvider.buildTrustManager().checkClientTrusted(null, null);
152 //no security exception is thrown
156 * test skipping certificate and doing hostname verification
159 public void testHostAndSkipCertifiacateVerification() throws Exception {
160 setField(securityProvider, "skipCertificateVerification", true);
161 setField(securityProvider, "skipHostnameVerification", false);
162 url = url.replace("127.0.0.1", "localhost");
163 TestResource testResource = fireRequest();
164 assertEquals("1234", testResource.id);
168 * test skipping certificate and doing hostname verification
169 * (if hostname is invalid exception is propagated)
172 public void testHostAndSkipCertifiacateVerificationNegativeCase() throws Exception {
173 setField(securityProvider, "skipCertificateVerification", true);
174 setField(securityProvider, "skipHostnameVerification", false);
175 //url = url.replace("127.0.0.1", "localhost");
179 } catch (Exception e) {
180 assertEquals(javax.net.ssl.SSLPeerUnverifiedException.class, e.getCause().getClass());
181 assertTrue(e.getCause().getMessage().contains("Hostname 127.0.0.1 not verified"));
186 * test certificate and hostname verification
189 public void testHostAndCertifiacateVerification() throws Exception {
190 Path jksPath = Paths.get(TestCbamTokenProvider.class.getResource("/unittests/localhost.cert.pem").toURI());
191 String cert = Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath));
192 setField(securityProvider, "trustedCertificates", cert);
193 setField(securityProvider, "skipCertificateVerification", false);
194 setField(securityProvider, "skipHostnameVerification", false);
195 url = url.replace("127.0.0.1", "localhost");
196 TestResource testResource = fireRequest();
197 assertEquals("1234", testResource.id);
201 * test certificate and hostname verification
202 * (not trusted certificate)
205 public void testHostAndCertifiacateVerificationNegative() throws Exception {
206 Path jksPath = Paths.get(TestCbamTokenProvider.class.getResource("/unittests/sample.cert.pem").toURI());
207 String cert = Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath));
208 setField(securityProvider, "trustedCertificates", cert);
209 setField(securityProvider, "skipCertificateVerification", false);
210 setField(securityProvider, "skipHostnameVerification", false);
211 url = url.replace("127.0.0.1", "localhost");
215 } catch (Exception e) {
216 assertEquals(javax.net.ssl.SSLHandshakeException.class, e.getCause().getClass());
217 assertTrue(e.getCause().getMessage().contains("unable to find valid certification path to requested target"));
222 * test certificate and hostname verification
225 public void testSkipHostAndCertifiacateVerification() throws Exception {
226 Path jksPath = Paths.get(TestCbamTokenProvider.class.getResource("/unittests/localhost.cert.pem").toURI());
227 String cert = Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath));
228 setField(securityProvider, "trustedCertificates", cert);
229 setField(securityProvider, "skipCertificateVerification", false);
230 setField(securityProvider, "skipHostnameVerification", true);
231 //url = url.replace("127.0.0.1", "localhost");
232 TestResource testResource = fireRequest();
233 assertEquals("1234", testResource.id);
237 * empty trusted pem results in error if verification is required
240 public void testEmptyTrustStoreWhenCheckingIsRequired() throws Exception {
241 setField(securityProvider, "trustedCertificates", "");
242 setField(securityProvider, "skipCertificateVerification", false);
244 securityProvider.buildTrustManager();
246 } catch (Exception e) {
247 assertEquals("If the skipCertificateVerification is set to false (default) the trustedCertificates can not be empty", e.getMessage());
252 * invalid PEM results in fast fail error
255 public void testInvalidPem() throws Exception {
256 setField(securityProvider, "trustedCertificates", "______");
257 setField(securityProvider, "skipCertificateVerification", false);
259 securityProvider.buildTrustManager();
261 } catch (Exception e) {
262 assertEquals("The trustedCertificates must be a base64 encoded collection of PEM certificates", e.getMessage());
267 * invalid PEM results in fast fail error
270 public void testEmptyInvalidPem() throws Exception {
271 setField(securityProvider, "trustedCertificates", "a3VrdQo=");
272 setField(securityProvider, "skipCertificateVerification", false);
274 securityProvider.buildTrustManager();
276 } catch (Exception e) {
277 assertEquals("No certificate can be extracted from kuku\n", e.getMessage());
282 * bad certificate content results in fast fail error
285 public void testEmptyInvalidPemContent() throws Exception {
286 String badCert = "-----BEGIN CERTIFICATE-----\nXXXXXX\n-----END CERTIFICATE-----";
287 setField(securityProvider, "trustedCertificates", Base64.getEncoder().encodeToString(badCert.getBytes()));
288 setField(securityProvider, "skipCertificateVerification", false);
290 securityProvider.buildTrustManager();
292 } catch (Exception e) {
293 assertEquals("Unable to create keystore", e.getMessage());
298 * bad certificate content results in fast fail error for SSL socket factory
301 public void testEmptyInvalidPemContentSSl() throws Exception {
302 String badCert = "-----BEGIN CERTIFICATE-----\nXXXXXX\n-----END CERTIFICATE-----";
303 setField(securityProvider, "trustedCertificates", Base64.getEncoder().encodeToString(badCert.getBytes()));
304 setField(securityProvider, "skipCertificateVerification", false);
306 securityProvider.buildSSLSocketFactory();
308 } catch (Exception e) {
309 assertEquals("Unable to create SSL socket factory", e.getMessage());
313 private TestResource fireRequest() {
314 OkHttpClient client =
315 new OkHttpClient.Builder()
316 .sslSocketFactory(securityProvider.buildSSLSocketFactory(), securityProvider.buildTrustManager())
317 .hostnameVerifier(securityProvider.buildHostnameVerifier()).build();
318 TestService test1 = new Retrofit.Builder().baseUrl(url).client(client)
319 .addConverterFactory(GsonCustomConverterFactory.create(new JSON().getGson()))
320 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build().create(TestService.class);
321 testServer.respones.add("{ \"id\" : \"1234\" } ");
322 testServer.codes.add(200);
323 TestService test = test1;
324 return test.subscriptionsGet().blockingFirst();