Clean up Sonar results 2
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / config / SecurityInfo.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
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  */
21
22 package org.onap.aaf.cadi.config;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.net.InetAddress;
28 import java.net.UnknownHostException;
29 import java.rmi.AccessException;
30 import java.security.KeyManagementException;
31 import java.security.KeyStore;
32 import java.security.KeyStoreException;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.UnrecoverableKeyException;
35 import java.security.cert.CertificateException;
36 import java.security.cert.X509Certificate;
37 import java.util.ArrayList;
38
39 import javax.net.ssl.HostnameVerifier;
40 import javax.net.ssl.HttpsURLConnection;
41 import javax.net.ssl.KeyManager;
42 import javax.net.ssl.KeyManagerFactory;
43 import javax.net.ssl.SSLContext;
44 import javax.net.ssl.SSLSession;
45 import javax.net.ssl.SSLSocketFactory;
46 import javax.net.ssl.TrustManager;
47 import javax.net.ssl.TrustManagerFactory;
48 import javax.net.ssl.X509KeyManager;
49 import javax.net.ssl.X509TrustManager;
50
51 import org.onap.aaf.cadi.Access;
52 import org.onap.aaf.cadi.CadiException;
53 import org.onap.aaf.cadi.Access.Level;
54 import org.onap.aaf.cadi.util.MaskFormatException;
55 import org.onap.aaf.cadi.util.NetMask;
56
57 public class SecurityInfo {
58         private static final String SECURITY_ALGO = "RSA";
59         private static final String HTTPS_PROTOCOLS = "https.protocols";
60         private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols";
61
62         public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2";
63         public static final String REGEX_COMMA = "\\s*,\\s*";
64         public static final String SslKeyManagerFactoryAlgorithm;
65         
66         private SSLSocketFactory scf;
67         private X509KeyManager[] km;
68         private X509TrustManager[] tm;
69         public final String default_alias;
70         private NetMask[] trustMasks;
71         private SSLContext ctx;
72         private HostnameVerifier maskHV;
73         public final Access access;
74
75         // Change Key Algorithms for IBM's VM.  Could put in others, if needed.
76         static {
77                 if(System.getProperty("java.vm.vendor").equalsIgnoreCase("IBM Corporation")) {
78                         SslKeyManagerFactoryAlgorithm = "IbmX509";
79                 } else {
80                         SslKeyManagerFactoryAlgorithm = "SunX509";
81                 }
82         }
83         
84
85         public SecurityInfo(final Access access) throws CadiException {
86                 try {
87                         this.access = access;
88                         // reuse DME2 Properties for convenience if specific Properties don't exist
89                         String keyStore = access.getProperty(Config.CADI_KEYSTORE,null);
90                         if(keyStore!=null && !new File(keyStore).exists()) {
91                                 throw new CadiException(keyStore + " does not exist");
92                         }
93                         String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
94                         keyStorePasswd = keyStorePasswd==null?null:access.decrypt(keyStorePasswd,false);
95                         String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, null);
96                         if(trustStore!=null && !new File(trustStore).exists()) {
97                                 throw new CadiException(trustStore + " does not exist");
98                         }
99                         String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
100                         trustStorePasswd = trustStorePasswd==null?"changeit"/*defacto Java Trust Pass*/:access.decrypt(trustStorePasswd,false);
101                         default_alias = access.getProperty(Config.CADI_ALIAS,null);
102                         
103                         String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD,null);
104                         keyPasswd = keyPasswd==null?keyStorePasswd:access.decrypt(keyPasswd,false);
105                         String tips=access.getProperty(Config.CADI_TRUST_MASKS, null);
106                         if(tips!=null) {
107                                 access.log(Level.INIT,"Explicitly accepting valid X509s from",tips);
108                                 String[] ipsplit = tips.split(REGEX_COMMA);
109                                 trustMasks = new NetMask[ipsplit.length];
110                                 for(int i=0;i<ipsplit.length;++i) {
111                                         try {
112                                                 trustMasks[i]=new NetMask(ipsplit[i]);
113                                         } catch (MaskFormatException e) {
114                                                 throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS,e);
115                                         }
116                                 }
117                         }
118                         String https_protocols = Config.logProp(access,Config.CADI_PROTOCOLS,
119                                                 access.getProperty(HTTPS_PROTOCOLS,HTTPS_PROTOCOLS_DEFAULT)
120                                                 );
121                         System.setProperty(HTTPS_PROTOCOLS,https_protocols);
122                         System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, https_protocols);
123                         if("1.7".equals(System.getProperty("java.specification.version")) && https_protocols.contains("TLSv1.2")) {
124                                 System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
125                         }
126                         
127                         KeyManagerFactory kmf = KeyManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
128                         File file;
129         
130         
131                         if(keyStore==null || keyStorePasswd == null) { 
132                                 km = new X509KeyManager[0];
133                         } else {
134                                 ArrayList<X509KeyManager> kmal = new ArrayList<X509KeyManager>();
135                                 for(String ksname : keyStore.split(REGEX_COMMA)) {
136                                         file = new File(ksname);
137                                         String keystoreFormat;
138                                         if(ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) {
139                                                 keystoreFormat = "PKCS12";
140                                         } else {
141                                                 keystoreFormat = "JKS";
142                                         }
143                                         if(file.exists()) {
144                                                 FileInputStream fis = new FileInputStream(file);
145                                                 try {
146                                                         KeyStore ks = KeyStore.getInstance(keystoreFormat);
147                                                         ks.load(fis, keyStorePasswd.toCharArray());
148                                                         kmf.init(ks, keyPasswd.toCharArray());
149                                                 } finally {
150                                                         fis.close();
151                                                 }
152                                         }
153                                 }
154                                 for(KeyManager km : kmf.getKeyManagers()) {
155                                         if(km instanceof X509KeyManager) {
156                                                 kmal.add((X509KeyManager)km);
157                                         }
158                                 }
159                                 km = new X509KeyManager[kmal.size()];
160                                 kmal.toArray(km);
161                         }
162         
163                         TrustManagerFactory tmf = TrustManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
164                         if(trustStore!=null) {
165                                 for(String tsname : trustStore.split(REGEX_COMMA)) {
166                                         file = new File(tsname);
167                                         if(file.exists()) {
168                                                 FileInputStream fis = new FileInputStream(file);
169                                                 try {
170                                                         KeyStore ts = KeyStore.getInstance("JKS");
171                                                         ts.load(fis, trustStorePasswd.toCharArray());
172                                                         tmf.init(ts); 
173                                                 } finally {
174                                                         fis.close();
175                                                 }
176                                         }
177                                 }
178                                 TrustManager tms[] = tmf.getTrustManagers();
179                                 if(tms!=null) {
180                                         tm = new X509TrustManager[tms==null?0:tms.length];
181                                         for(int i=0;i<tms.length;++i) {
182                                                 try {
183                                                         tm[i]=(X509TrustManager)tms[i];
184                                                 } catch (ClassCastException e) {
185                                                         access.log(Level.WARN, "Non X509 TrustManager", tm[i].getClass().getName(),"skipped in SecurityInfo");
186                                                 }
187                                         }
188                                 }
189                         }
190                         
191                         if(trustMasks!=null) {
192                                 final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier();
193                                 HttpsURLConnection.setDefaultHostnameVerifier(maskHV = new HostnameVerifier() {
194                                         @Override
195                                         public boolean verify(final String urlHostName, final SSLSession session) {
196                                                 try {
197                                                         // This will pick up /etc/host entries as well as DNS
198                                                         InetAddress ia = InetAddress.getByName(session.getPeerHost());
199                                                         for(NetMask tmask : trustMasks) {
200                                                                 if(tmask.isInNet(ia.getHostAddress())) {
201                                                                         return true;
202                                                                 }
203                                                         }
204                                                 } catch (UnknownHostException e) {
205                                                         // It's ok. do normal Verify
206                                                 }
207                                                 return origHV.verify(urlHostName,session);
208                                         };
209                                 });
210                         }
211                         ctx = SSLContext.getInstance("TLS");
212                         ctx.init(km, tm, null);
213                         SSLContext.setDefault(ctx);
214                         scf = ctx.getSocketFactory();
215                 } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) {
216                         throw new CadiException(e);
217                 }
218         }
219
220         /**
221          * @return the scf
222          */
223         public SSLSocketFactory getSSLSocketFactory() {
224                 return scf;
225         }
226
227         public SSLContext getSSLContext() {
228                 return ctx;
229         }
230
231         /**
232          * @return the km
233          */
234         public X509KeyManager[] getKeyManagers() {
235                 return km;
236         }
237
238         public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException {
239                 for(X509TrustManager xtm : tm) {
240                         xtm.checkClientTrusted(certarr, SECURITY_ALGO);
241                 }
242         }
243
244         public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException {
245                 for(X509TrustManager xtm : tm) {
246                         xtm.checkServerTrusted(certarr, SECURITY_ALGO);
247                 }
248         }
249
250         public void setSocketFactoryOn(HttpsURLConnection hsuc) {
251                 hsuc.setSSLSocketFactory(scf);
252                 if(maskHV!=null && !maskHV.equals(hsuc.getHostnameVerifier())) {
253                         hsuc.setHostnameVerifier(maskHV);
254                 }
255         }
256
257 }