2 * ============LICENSE_START====================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
22 package org.onap.aaf.cadi.config;
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;
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;
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;
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";
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;
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;
75 // Change Key Algorithms for IBM's VM. Could put in others, if needed.
77 if(System.getProperty("java.vm.vendor").equalsIgnoreCase("IBM Corporation")) {
78 SslKeyManagerFactoryAlgorithm = "IbmX509";
80 SslKeyManagerFactoryAlgorithm = "SunX509";
85 public SecurityInfo(final Access access) throws CadiException {
88 // reuse DME2 Properties for convenience if specific Properties don't exist
90 initializeKeyManager();
92 initializeTrustManager();
94 default_alias = access.getProperty(Config.CADI_ALIAS, null);
96 initializeTrustMasks();
98 String https_protocols = Config.logProp(access, Config.CADI_PROTOCOLS,
99 access.getProperty(HTTPS_PROTOCOLS, HTTPS_PROTOCOLS_DEFAULT)
101 System.setProperty(HTTPS_PROTOCOLS, https_protocols);
102 System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, https_protocols);
103 if("1.7".equals(System.getProperty("java.specification.version")) && https_protocols.contains("TLSv1.2")) {
104 System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
107 ctx = SSLContext.getInstance("TLS");
108 ctx.init(km, tm, null);
109 SSLContext.setDefault(ctx);
110 scf = ctx.getSocketFactory();
111 } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) {
112 throw new CadiException(e);
119 public SSLSocketFactory getSSLSocketFactory() {
123 public SSLContext getSSLContext() {
130 public X509KeyManager[] getKeyManagers() {
134 public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException {
135 for(X509TrustManager xtm : tm) {
136 xtm.checkClientTrusted(certarr, SECURITY_ALGO);
140 public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException {
141 for(X509TrustManager xtm : tm) {
142 xtm.checkServerTrusted(certarr, SECURITY_ALGO);
146 public void setSocketFactoryOn(HttpsURLConnection hsuc) {
147 hsuc.setSSLSocketFactory(scf);
148 if(maskHV != null && !maskHV.equals(hsuc.getHostnameVerifier())) {
149 hsuc.setHostnameVerifier(maskHV);
153 protected void initializeKeyManager() throws CadiException, IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException {
154 String keyStore = access.getProperty(Config.CADI_KEYSTORE, null);
155 if(keyStore != null && !new File(keyStore).exists()) {
156 throw new CadiException(keyStore + " does not exist");
159 String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
160 keyStorePasswd = (keyStorePasswd == null) ? null : access.decrypt(keyStorePasswd, false);
162 String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD, null);
163 keyPasswd = (keyPasswd == null) ? keyStorePasswd : access.decrypt(keyPasswd, false);
165 KeyManagerFactory kmf = KeyManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
166 if(keyStore == null || keyStorePasswd == null) {
167 km = new X509KeyManager[0];
169 ArrayList<X509KeyManager> kmal = new ArrayList<X509KeyManager>();
171 for(String ksname : keyStore.split(REGEX_COMMA)) {
172 file = new File(ksname);
173 String keystoreFormat;
174 if(ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) {
175 keystoreFormat = "PKCS12";
177 keystoreFormat = "JKS";
180 FileInputStream fis = new FileInputStream(file);
182 KeyStore ks = KeyStore.getInstance(keystoreFormat);
183 ks.load(fis, keyStorePasswd.toCharArray());
184 kmf.init(ks, keyPasswd.toCharArray());
190 for(KeyManager km : kmf.getKeyManagers()) {
191 if(km instanceof X509KeyManager) {
192 kmal.add((X509KeyManager)km);
195 km = new X509KeyManager[kmal.size()];
200 protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException {
201 String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, null);
202 if(trustStore != null && !new File(trustStore).exists()) {
203 throw new CadiException(trustStore + " does not exist");
206 String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
207 trustStorePasswd = (trustStorePasswd == null) ? "changeit"/*defacto Java Trust Pass*/ : access.decrypt(trustStorePasswd, false);
209 TrustManagerFactory tmf = TrustManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
210 if(trustStore != null) {
212 for(String tsname : trustStore.split(REGEX_COMMA)) {
213 file = new File(tsname);
215 FileInputStream fis = new FileInputStream(file);
217 KeyStore ts = KeyStore.getInstance("JKS");
218 ts.load(fis, trustStorePasswd.toCharArray());
226 TrustManager tms[] = tmf.getTrustManagers();
227 if(tms != null && tms.length>0) {
228 tm = new X509TrustManager[tms.length];
229 for(int i = 0; i < tms.length; ++i) {
231 tm[i] = (X509TrustManager)tms[i];
232 } catch (ClassCastException e) {
233 access.log(Level.WARN, "Non X509 TrustManager", tm[i].getClass().getName(), "skipped in SecurityInfo");
241 protected void initializeTrustMasks() throws AccessException {
242 String tips = access.getProperty(Config.CADI_TRUST_MASKS, null);
244 access.log(Level.INIT, "Explicitly accepting valid X509s from", tips);
245 String[] ipsplit = tips.split(REGEX_COMMA);
246 trustMasks = new NetMask[ipsplit.length];
247 for(int i = 0; i < ipsplit.length; ++i) {
249 trustMasks[i] = new NetMask(ipsplit[i]);
250 } catch (MaskFormatException e) {
251 throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS, e);
256 if(trustMasks != null) {
257 final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier();
258 HttpsURLConnection.setDefaultHostnameVerifier(maskHV = new HostnameVerifier() {
260 public boolean verify(final String urlHostName, final SSLSession session) {
262 // This will pick up /etc/host entries as well as DNS
263 InetAddress ia = InetAddress.getByName(session.getPeerHost());
264 for(NetMask tmask : trustMasks) {
265 if(tmask.isInNet(ia.getHostAddress())) {
269 } catch (UnknownHostException e) {
270 // It's ok. do normal Verify
272 return origHV.verify(urlHostName, session);