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 java.io.IOException;
25 import java.lang.annotation.Annotation;
26 import java.lang.reflect.Type;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.util.Base64;
31 import javax.xml.bind.annotation.XmlAccessType;
32 import javax.xml.bind.annotation.XmlAccessorType;
33 import javax.xml.bind.annotation.XmlElement;
34 import javax.xml.bind.annotation.XmlRootElement;
35 import okhttp3.OkHttpClient;
36 import okhttp3.RequestBody;
37 import okhttp3.ResponseBody;
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Test;
41 import retrofit2.Converter;
42 import retrofit2.Retrofit;
43 import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
44 import retrofit2.converter.gson.GsonConverterFactory;
45 import retrofit2.http.GET;
46 import retrofit2.http.Headers;
48 import static junit.framework.TestCase.*;
49 import static org.springframework.test.util.ReflectionTestUtils.setField;
51 interface TestService {
53 "Content-Type:application/json"
56 Observable<TestResource> subscriptionsGet();
59 @XmlRootElement(name = "Subscription")
60 @XmlAccessorType(XmlAccessType.FIELD)
62 @XmlElement(name = "id")
64 public String id = null;
67 class GsonCustomConverterFactory extends Converter.Factory {
68 private final Gson gson;
69 private final GsonConverterFactory gsonConverterFactory;
71 private GsonCustomConverterFactory(Gson gson) {
73 throw new NullPointerException("gson == null");
75 this.gsonConverterFactory = GsonConverterFactory.create(gson);
78 public static GsonCustomConverterFactory create(Gson gson) {
79 return new GsonCustomConverterFactory(gson);
83 public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
84 if (type.equals(String.class))
85 return new GsonResponseBodyConverterToString<Object>(gson, type);
87 return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
91 public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
92 return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
96 class GsonResponseBodyConverterToString<T> implements Converter<ResponseBody, T> {
97 private final Gson gson;
98 private final Type type;
100 GsonResponseBodyConverterToString(Gson gson, Type type) {
106 public T convert(ResponseBody value) throws IOException {
107 String returned = value.string();
109 return gson.fromJson(returned, type);
110 } catch (JsonParseException e) {
116 public class TestGenericSecurityProvider extends TestBase {
117 GenericSecurityProvider securityProvider = new CbamSecurityProvider() {
120 HttpTestServer testServer = new HttpTestServer();
124 public void init() throws Exception {
125 setField(securityProvider, "skipCertificateVerification", true);
126 setField(securityProvider, "skipHostnameVerification", true);
127 testServer = new HttpTestServer();
129 url = testServer._server.getURI().toString();
133 public void testServer() throws Exception {
138 * test skipping certificate and skipping hostname verification
141 public void testSkipHostAndSkipCertifiacateVerification() throws Exception {
142 setField(securityProvider, "skipCertificateVerification", true);
143 setField(securityProvider, "skipHostnameVerification", true);
145 TestResource testResource = fireRequest();
147 assertEquals("1234", testResource.id);
149 securityProvider.buildTrustManager().checkClientTrusted(null, null);
151 //no security exception is thrown
155 * test skipping certificate and doing hostname verification
158 public void testHostAndSkipCertifiacateVerification() throws Exception {
159 setField(securityProvider, "skipCertificateVerification", true);
160 setField(securityProvider, "skipHostnameVerification", false);
161 url = url.replace("127.0.0.1", "localhost");
162 TestResource testResource = fireRequest();
163 assertEquals("1234", testResource.id);
167 * test skipping certificate and doing hostname verification
168 * (if hostname is invalid exception is propagated)
171 public void testHostAndSkipCertifiacateVerificationNegativeCase() throws Exception {
172 setField(securityProvider, "skipCertificateVerification", true);
173 setField(securityProvider, "skipHostnameVerification", false);
174 //url = url.replace("127.0.0.1", "localhost");
178 } catch (Exception e) {
179 assertEquals(javax.net.ssl.SSLPeerUnverifiedException.class, e.getCause().getClass());
180 assertTrue(e.getCause().getMessage().contains("Hostname 127.0.0.1 not verified"));
185 * test certificate and hostname verification
188 public void testHostAndCertifiacateVerification() throws Exception {
189 Path jksPath = Paths.get(TestCbamTokenProvider.class.getResource("/unittests/localhost.cert.pem").toURI());
190 String cert = Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath));
191 setField(securityProvider, "trustedCertificates", cert);
192 setField(securityProvider, "skipCertificateVerification", false);
193 setField(securityProvider, "skipHostnameVerification", false);
194 url = url.replace("127.0.0.1", "localhost");
195 TestResource testResource = fireRequest();
196 assertEquals("1234", testResource.id);
200 * test certificate and hostname verification
201 * (not trusted certificate)
204 public void testHostAndCertifiacateVerificationNegative() throws Exception {
205 Path jksPath = Paths.get(TestCbamTokenProvider.class.getResource("/unittests/sample.cert.pem").toURI());
206 String cert = Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath));
207 setField(securityProvider, "trustedCertificates", cert);
208 setField(securityProvider, "skipCertificateVerification", false);
209 setField(securityProvider, "skipHostnameVerification", false);
210 url = url.replace("127.0.0.1", "localhost");
214 } catch (Exception e) {
215 assertEquals(javax.net.ssl.SSLHandshakeException.class, e.getCause().getClass());
216 assertTrue(e.getCause().getMessage().contains("unable to find valid certification path to requested target"));
221 * test certificate and hostname verification
224 public void testSkipHostAndCertifiacateVerification() throws Exception {
225 Path jksPath = Paths.get(TestCbamTokenProvider.class.getResource("/unittests/localhost.cert.pem").toURI());
226 String cert = Base64.getEncoder().encodeToString(Files.readAllBytes(jksPath));
227 setField(securityProvider, "trustedCertificates", cert);
228 setField(securityProvider, "skipCertificateVerification", false);
229 setField(securityProvider, "skipHostnameVerification", true);
230 //url = url.replace("127.0.0.1", "localhost");
231 TestResource testResource = fireRequest();
232 assertEquals("1234", testResource.id);
236 * empty trusted pem results in error if verification is required
239 public void testEmptyTrustStoreWhenCheckingIsRequired() throws Exception {
240 setField(securityProvider, "trustedCertificates", "");
241 setField(securityProvider, "skipCertificateVerification", false);
243 securityProvider.buildTrustManager();
245 } catch (Exception e) {
246 assertEquals("If the skipCertificateVerification is set to false (default) the trustedCertificates can not be empty", e.getMessage());
251 * invalid PEM results in fast fail error
254 public void testInvalidPem() throws Exception {
255 setField(securityProvider, "trustedCertificates", "______");
256 setField(securityProvider, "skipCertificateVerification", false);
258 securityProvider.buildTrustManager();
260 } catch (Exception e) {
261 assertEquals("The trustedCertificates must be a base64 encoded collection of PEM certificates", e.getMessage());
266 * invalid PEM results in fast fail error
269 public void testEmptyInvalidPem() throws Exception {
270 setField(securityProvider, "trustedCertificates", "a3VrdQo=");
271 setField(securityProvider, "skipCertificateVerification", false);
273 securityProvider.buildTrustManager();
275 } catch (Exception e) {
276 assertEquals("No certificate can be extracted from kuku\n", e.getMessage());
281 * bad certificate content results in fast fail error
284 public void testEmptyInvalidPemContent() throws Exception {
285 String badCert = "-----BEGIN CERTIFICATE-----\nXXXXXX\n-----END CERTIFICATE-----";
286 setField(securityProvider, "trustedCertificates", Base64.getEncoder().encodeToString(badCert.getBytes()));
287 setField(securityProvider, "skipCertificateVerification", false);
289 securityProvider.buildTrustManager();
291 } catch (Exception e) {
292 assertEquals("Unable to create keystore", e.getMessage());
297 * bad certificate content results in fast fail error for SSL socket factory
300 public void testEmptyInvalidPemContentSSl() throws Exception {
301 String badCert = "-----BEGIN CERTIFICATE-----\nXXXXXX\n-----END CERTIFICATE-----";
302 setField(securityProvider, "trustedCertificates", Base64.getEncoder().encodeToString(badCert.getBytes()));
303 setField(securityProvider, "skipCertificateVerification", false);
305 securityProvider.buildSSLSocketFactory();
307 } catch (Exception e) {
308 assertEquals("Unable to create SSL socket factory", e.getMessage());
312 private TestResource fireRequest() {
313 OkHttpClient client =
314 new OkHttpClient.Builder()
315 .sslSocketFactory(securityProvider.buildSSLSocketFactory(), securityProvider.buildTrustManager())
316 .hostnameVerifier(securityProvider.buildHostnameVerifier()).build();
317 TestService test1 = new Retrofit.Builder().baseUrl(url).client(client)
318 .addConverterFactory(GsonCustomConverterFactory.create(new JSON().getGson()))
319 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build().create(TestService.class);
320 testServer.respones.add("{ \"id\" : \"1234\" } ");
321 testServer.codes.add(200);
322 TestService test = test1;
323 return test.subscriptionsGet().blockingFirst();