1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.config;
\r
25 import java.io.File;
\r
26 import java.io.FileInputStream;
\r
27 import java.io.IOException;
\r
28 import java.net.InetAddress;
\r
29 import java.net.UnknownHostException;
\r
30 import java.rmi.AccessException;
\r
31 import java.security.GeneralSecurityException;
\r
32 import java.security.KeyStore;
\r
33 import java.security.cert.CertificateException;
\r
34 import java.security.cert.X509Certificate;
\r
35 import java.util.ArrayList;
\r
37 import javax.net.ssl.HostnameVerifier;
\r
38 import javax.net.ssl.HttpsURLConnection;
\r
39 import javax.net.ssl.KeyManager;
\r
40 import javax.net.ssl.KeyManagerFactory;
\r
41 import javax.net.ssl.SSLContext;
\r
42 import javax.net.ssl.SSLSession;
\r
43 import javax.net.ssl.SSLSocketFactory;
\r
44 import javax.net.ssl.TrustManager;
\r
45 import javax.net.ssl.TrustManagerFactory;
\r
46 import javax.net.ssl.X509KeyManager;
\r
47 import javax.net.ssl.X509TrustManager;
\r
49 import org.onap.aaf.cadi.Access;
\r
50 import org.onap.aaf.cadi.Access.Level;
\r
51 import org.onap.aaf.cadi.util.MaskFormatException;
\r
52 import org.onap.aaf.cadi.util.NetMask;
\r
54 public class SecurityInfo {
\r
55 private static final String SECURITY_ALGO = "RSA";
\r
56 private static final String HTTPS_PROTOCOLS = "https.protocols";
\r
57 private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols";
\r
59 public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2";
\r
60 public static final String REGEX_COMMA = "\\s*,\\s*";
\r
61 public static final String SslKeyManagerFactoryAlgorithm;
\r
63 private SSLSocketFactory scf;
\r
64 private X509KeyManager[] km;
\r
65 private X509TrustManager[] tm;
\r
66 public final String default_alias;
\r
67 private NetMask[] trustMasks;
\r
68 private SSLContext ctx;
\r
69 private HostnameVerifier maskHV;
\r
71 // Change Key Algorithms for IBM's VM. Could put in others, if needed.
\r
73 if(System.getProperty("java.vm.vendor").equalsIgnoreCase("IBM Corporation")) {
\r
74 SslKeyManagerFactoryAlgorithm = "IbmX509";
\r
76 SslKeyManagerFactoryAlgorithm = "SunX509";
\r
81 public SecurityInfo(final Access access) throws GeneralSecurityException, IOException {
\r
82 // reuse DME2 Properties for convenience if specific Properties don't exist
\r
83 String keyStore = access.getProperty(Config.CADI_KEYSTORE,
\r
84 access.getProperty(Config.AFT_DME2_KEYSTORE,null));
\r
85 String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD,
\r
86 access.getProperty(Config.AFT_DME2_KEYSTORE_PASSWORD, null));
\r
87 keyStorePasswd = keyStorePasswd==null?null:access.decrypt(keyStorePasswd,false);
\r
88 String trustStore = access.getProperty(Config.CADI_TRUSTSTORE,
\r
89 access.getProperty(Config.AFT_DME2_TRUSTSTORE, null));
\r
90 String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD,
\r
91 access.getProperty(Config.AFT_DME2_TRUSTSTORE_PASSWORD,null));
\r
92 trustStorePasswd = trustStorePasswd==null?null:access.decrypt(trustStorePasswd,false);
\r
93 default_alias = access.getProperty(Config.CADI_ALIAS,
\r
94 access.getProperty(Config.AFT_DME2_CLIENT_SSL_CERT_ALIAS,null));
\r
96 String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD,null);
\r
97 keyPasswd = keyPasswd==null?keyStorePasswd:access.decrypt(keyPasswd,false);
\r
98 String tips=access.getProperty(Config.CADI_TRUST_MASKS, null);
\r
100 access.log(Level.INIT,"Explicitly accepting valid X509s from",tips);
\r
101 String[] ipsplit = tips.split(REGEX_COMMA);
\r
102 trustMasks = new NetMask[ipsplit.length];
\r
103 for(int i=0;i<ipsplit.length;++i) {
\r
105 trustMasks[i]=new NetMask(ipsplit[i]);
\r
106 } catch (MaskFormatException e) {
\r
107 throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS,e);
\r
111 String https_protocols = Config.logProp(access,Config.CADI_PROTOCOLS,
\r
112 access.getProperty(Config.AFT_DME2_SSL_INCLUDE_PROTOCOLS,
\r
113 access.getProperty(HTTPS_PROTOCOLS,HTTPS_PROTOCOLS_DEFAULT)
\r
115 System.setProperty(HTTPS_PROTOCOLS,https_protocols);
\r
116 System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, https_protocols);
\r
118 KeyManagerFactory kmf = KeyManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
\r
122 if(keyStore==null || keyStorePasswd == null) {
\r
123 km = new X509KeyManager[0];
\r
125 ArrayList<X509KeyManager> kmal = new ArrayList<X509KeyManager>();
\r
126 for(String ksname : keyStore.split(REGEX_COMMA)) {
\r
127 file = new File(ksname);
\r
128 String keystoreFormat;
\r
129 if(ksname.endsWith("pkcs12")) {
\r
130 keystoreFormat = "PKCS12";
\r
132 keystoreFormat = "JKS";
\r
134 if(file.exists()) {
\r
135 FileInputStream fis = new FileInputStream(file);
\r
137 KeyStore ks = KeyStore.getInstance(keystoreFormat);
\r
138 ks.load(fis, keyStorePasswd.toCharArray());
\r
139 kmf.init(ks, keyPasswd.toCharArray());
\r
145 for(KeyManager km : kmf.getKeyManagers()) {
\r
146 if(km instanceof X509KeyManager) {
\r
147 kmal.add((X509KeyManager)km);
\r
150 km = new X509KeyManager[kmal.size()];
\r
154 TrustManagerFactory tmf = TrustManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
\r
155 if(trustStore!=null) {
\r
156 for(String tsname : trustStore.split(REGEX_COMMA)) {
\r
157 file = new File(tsname);
\r
158 if(file.exists()) {
\r
159 FileInputStream fis = new FileInputStream(file);
\r
161 KeyStore ts = KeyStore.getInstance("JKS");
\r
162 ts.load(fis, trustStorePasswd.toCharArray());
\r
169 TrustManager tms[] = tmf.getTrustManagers();
\r
170 tm = new X509TrustManager[tms==null?0:tms.length];
\r
171 for(int i=0;i<tms.length;++i) {
\r
173 tm[i]=(X509TrustManager)tms[i];
\r
174 } catch (ClassCastException e) {
\r
175 access.log(Level.WARN, "Non X509 TrustManager", tm[i].getClass().getName(),"skipped in SecurityInfo");
\r
180 if(trustMasks!=null) {
\r
181 final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier();
\r
182 HttpsURLConnection.setDefaultHostnameVerifier(maskHV = new HostnameVerifier() {
\r
184 public boolean verify(final String urlHostName, final SSLSession session) {
\r
186 // This will pick up /etc/host entries as well as DNS
\r
187 InetAddress ia = InetAddress.getByName(session.getPeerHost());
\r
188 for(NetMask tmask : trustMasks) {
\r
189 if(tmask.isInNet(ia.getHostAddress())) {
\r
193 } catch (UnknownHostException e) {
\r
194 // It's ok. do normal Verify
\r
196 return origHV.verify(urlHostName,session);
\r
200 ctx = SSLContext.getInstance("TLS");
\r
201 ctx.init(km, tm, null);
\r
202 SSLContext.setDefault(ctx);
\r
203 scf = ctx.getSocketFactory();
\r
209 public SSLSocketFactory getSSLSocketFactory() {
\r
213 public SSLContext getSSLContext() {
\r
220 public X509KeyManager[] getKeyManagers() {
\r
224 public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException {
\r
225 for(X509TrustManager xtm : tm) {
\r
226 xtm.checkClientTrusted(certarr, SECURITY_ALGO);
\r
230 public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException {
\r
231 for(X509TrustManager xtm : tm) {
\r
232 xtm.checkServerTrusted(certarr, SECURITY_ALGO);
\r
236 public void setSocketFactoryOn(HttpsURLConnection hsuc) {
\r
237 hsuc.setSSLSocketFactory(scf);
\r
238 if(maskHV!=null && !maskHV.equals(hsuc.getHostnameVerifier())) {
\r
239 hsuc.setHostnameVerifier(maskHV);
\r