Add spring security to mitigate cve-2017-4995
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / main / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / vnfm / CbamSecurityProvider.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm;
17
18 import com.google.common.base.Joiner;
19 import com.google.common.io.BaseEncoding;
20 import org.apache.http.conn.ssl.DefaultHostnameVerifier;
21 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.StoreLoader;
22 import org.slf4j.Logger;
23 import org.springframework.beans.factory.annotation.Value;
24 import org.springframework.stereotype.Component;
25 import org.springframework.util.StringUtils;
26
27 import javax.net.ssl.*;
28 import java.nio.charset.StandardCharsets;
29 import java.security.KeyStore;
30 import java.security.SecureRandom;
31 import java.security.cert.CertificateException;
32 import java.security.cert.X509Certificate;
33 import java.util.Set;
34
35 import static java.util.UUID.randomUUID;
36 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
37 import static org.slf4j.LoggerFactory.getLogger;
38
39 /**
40  * Responsible for providing a token to access CBAM APIs
41  */
42 @Component
43 public class CbamSecurityProvider {
44     private static Logger logger = getLogger(CbamSecurityProvider.class);
45     @Value("${trustedCertificates}")
46     private String trustedCertificates;
47     @Value("${skipCertificateVerification}")
48     private boolean skipCertificateVerification;
49     @Value("${skipHostnameVerification}")
50     private boolean skipHostnameVerification;
51
52     protected HostnameVerifier buildHostnameVerifier() {
53         if (skipHostnameVerification) {
54             return (hostname, session) -> true;
55         } else {
56             return new DefaultHostnameVerifier();
57         }
58     }
59
60     protected SSLSocketFactory buildSSLSocketFactory() {
61         try {
62             TrustManager[] trustManagers = new X509TrustManager[]{buildTrustManager()};
63             SSLContext sslContext = SSLContext.getInstance("TLS");
64             sslContext.init(null, trustManagers, new SecureRandom());
65             return sslContext.getSocketFactory();
66         } catch (Exception e) {
67             throw buildFatalFailure(logger, "Unable to create SSL socket factory", e);
68         }
69     }
70
71     protected X509TrustManager buildTrustManager() {
72         if (skipCertificateVerification) {
73             return new AllTrustedTrustManager();
74         } else {
75             if (StringUtils.isEmpty(trustedCertificates)) {
76                 throw buildFatalFailure(logger, "If the skipCertificateVerification is set to false (default) the trustedCertificates can not be empty");
77             }
78             Set<String> trustedPems;
79             String content;
80             try {
81                 content = new String(BaseEncoding.base64().decode(trustedCertificates), StandardCharsets.UTF_8);
82                 trustedPems = StoreLoader.getCertifacates(content);
83             } catch (Exception e) {
84                 throw buildFatalFailure(logger, "The trustedCertificates must be a base64 encoded collection of PEM certificates", e);
85             }
86             if (trustedPems.isEmpty()) {
87                 throw buildFatalFailure(logger, "No certificate can be extracted from " + content);
88             }
89             try {
90                 KeyStore keyStore = StoreLoader.loadStore(Joiner.on("\n").join(trustedPems), randomUUID().toString(), randomUUID().toString());
91                 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
92                 trustManagerFactory.init(keyStore);
93                 return (X509TrustManager) trustManagerFactory.getTrustManagers()[0];
94             } catch (Exception e) {
95                 throw buildFatalFailure(logger, "Unable to create keystore", e);
96             }
97         }
98     }
99
100     private static class AllTrustedTrustManager implements X509TrustManager {
101         @Override
102         public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
103             //no need to check certificates if everything is trusted
104         }
105
106         @Override
107         public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
108             //no need to check certificates if everything is trusted
109         }
110
111         @Override
112         public X509Certificate[] getAcceptedIssuers() {
113             return new X509Certificate[0];
114         }
115     }
116
117 }