Remove Tabs, per Jococo
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / config / SecurityInfo.java
index 2d252ea..8dbc38e 100644 (file)
@@ -53,226 +53,318 @@ import org.onap.aaf.cadi.CadiException;
 import org.onap.aaf.cadi.Access.Level;
 import org.onap.aaf.cadi.util.MaskFormatException;
 import org.onap.aaf.cadi.util.NetMask;
+import org.onap.aaf.cadi.util.Split;
 
 public class SecurityInfo {
-       private static final String SECURITY_ALGO = "RSA";
-       private static final String HTTPS_PROTOCOLS = "https.protocols";
-       private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols";
+    private static final String SECURITY_ALGO = "RSA";
+    private static final String HTTPS_PROTOCOLS = "https.protocols";
+    private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols";
+    private static final String INITIALIZING_ERR_FMT = "Error initializing %s: %s";
+    private static final String LOADED_FROM_CADI_PROPERTIES = "%s loaded from CADI Properties";
+    private static final String LOADED_FROM_SYSTEM_PROPERTIES = "%s loaded from System Properties";
 
-       public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2";
-       public static final String REGEX_COMMA = "\\s*,\\s*";
-       public static final String SslKeyManagerFactoryAlgorithm;
-       
-       private SSLSocketFactory scf;
-       private X509KeyManager[] km;
-       private X509TrustManager[] tm;
-       public final String default_alias;
-       private NetMask[] trustMasks;
-       private SSLContext ctx;
-       private HostnameVerifier maskHV;
-       public final Access access;
+    public static final String SSL_KEY_MANAGER_FACTORY_ALGORITHM;
+    
+    private SSLSocketFactory socketFactory;
+    private X509KeyManager[] x509KeyManager;
+    private X509TrustManager[] x509TrustManager;
+    public final String defaultAlias;
+    public final String defaultClientAlias;
+    private NetMask[] trustMasks;
+    private SSLContext context;
+    private HostnameVerifier maskHV;
+    public final Access access;
 
-       // Change Key Algorithms for IBM's VM.  Could put in others, if needed.
-       static {
-               if(System.getProperty("java.vm.vendor").equalsIgnoreCase("IBM Corporation")) {
-                       SslKeyManagerFactoryAlgorithm = "IbmX509";
-               } else {
-                       SslKeyManagerFactoryAlgorithm = "SunX509";
-               }
-       }
-       
+    // Change Key Algorithms for IBM's VM.  Could put in others, if needed.
+    static {
+        if ("IBM Corporation".equalsIgnoreCase(System.getProperty("java.vm.vendor"))) {
+            SSL_KEY_MANAGER_FACTORY_ALGORITHM = "IbmX509";
+        } else {
+            SSL_KEY_MANAGER_FACTORY_ALGORITHM = "SunX509";
+        }
+    }
+    
 
-       public SecurityInfo(final Access access) throws CadiException {
-               try {
-                       this.access = access;
-                       // reuse DME2 Properties for convenience if specific Properties don't exist
-                       
-                       initializeKeyManager();
-                       
-                       initializeTrustManager();
-                       
-                       default_alias = access.getProperty(Config.CADI_ALIAS, null);
-                       
-                       initializeTrustMasks();
+    public SecurityInfo(final Access access) throws CadiException {
+        String msgHelp = "";
+        try {
+            this.access = access;
+            // reuse DME2 Properties for convenience if specific Properties don't exist
+            
+            String str = access.getProperty(Config.CADI_ALIAS, null);
+            if(str==null || str.isEmpty()) {
+                defaultAlias = null;
+            } else {
+                defaultAlias = str;
+            }
+            
+            str = access.getProperty(Config.CADI_CLIENT_ALIAS, null);
+            if(str==null) {
+                defaultClientAlias = defaultAlias;
+            } else if(str.isEmpty()) {
+                // intentionally off, i.e. cadi_client_alias=
+                defaultClientAlias = null;
+            } else {
+                defaultClientAlias = str;
+            }
 
-                       String https_protocols = Config.logProp(access, Config.CADI_PROTOCOLS,
-                                               access.getProperty(HTTPS_PROTOCOLS, HTTPS_PROTOCOLS_DEFAULT)
-                                               );
-                       System.setProperty(HTTPS_PROTOCOLS, https_protocols);
-                       System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, https_protocols);
-                       if("1.7".equals(System.getProperty("java.specification.version")) && https_protocols.contains("TLSv1.2")) {
-                               System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
-                       }                       
+            msgHelp = String.format(INITIALIZING_ERR_FMT,"Keystore", access.getProperty(Config.CADI_KEYSTORE, ""));
+            initializeKeyManager();
+            
+            msgHelp = String.format(INITIALIZING_ERR_FMT,"Truststore", access.getProperty(Config.CADI_TRUSTSTORE, ""));
+            initializeTrustManager();
+            
 
-                       ctx = SSLContext.getInstance("TLS");
-                       ctx.init(km, tm, null);
-                       SSLContext.setDefault(ctx);
-                       scf = ctx.getSocketFactory();
-               } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) {
-                       throw new CadiException(e);
-               }
-       }
+            msgHelp = String.format(INITIALIZING_ERR_FMT,"Trustmasks", access.getProperty(Config.CADI_TRUST_MASKS, ""));
+            initializeTrustMasks();
 
-       /**
-        * @return the scf
-        */
-       public SSLSocketFactory getSSLSocketFactory() {
-               return scf;
-       }
+            msgHelp = String.format(INITIALIZING_ERR_FMT,"HTTP Protocols", "access properties");
+            setHTTPProtocols(access);
+            
+            msgHelp = String.format(INITIALIZING_ERR_FMT,"Context", "TLS");
+            context = SSLContext.getInstance("TLS");
+            context.init(x509KeyManager, x509TrustManager, null);
+            SSLContext.setDefault(context);
+            socketFactory = context.getSocketFactory();
+        } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) {
+            throw new CadiException(msgHelp,e);
+        }
+    }
 
-       public SSLContext getSSLContext() {
-               return ctx;
-       }
+    public static void setHTTPProtocols(Access access) {
+        String httpsProtocols = System.getProperty(Config.HTTPS_PROTOCOLS);
+        if(httpsProtocols!=null) {
+            access.printf(Level.INIT, LOADED_FROM_SYSTEM_PROPERTIES, HTTPS_PROTOCOLS);
+        } else {
+            httpsProtocols = access.getProperty(Config.HTTPS_PROTOCOLS,null);
+            if(httpsProtocols!=null) {
+                access.printf(Level.INIT, LOADED_FROM_CADI_PROPERTIES, HTTPS_PROTOCOLS);
+            } else {
+                httpsProtocols = access.getProperty(HTTPS_PROTOCOLS, Config.HTTPS_PROTOCOLS_DEFAULT);
+                access.printf(Level.INIT, "%s set by %s in CADI Properties",Config.HTTPS_PROTOCOLS,Config.CADI_PROTOCOLS);
+            }
+            // This needs to be set when people do  not.
+            System.setProperty(HTTPS_PROTOCOLS, httpsProtocols);
+        }
+        String httpsClientProtocols = System.getProperty(JDK_TLS_CLIENT_PROTOCOLS,null); 
+        if(httpsClientProtocols!=null) {
+            access.printf(Level.INIT, LOADED_FROM_SYSTEM_PROPERTIES, JDK_TLS_CLIENT_PROTOCOLS);
+        } else {
+            httpsClientProtocols = access.getProperty(Config.HTTPS_CLIENT_PROTOCOLS, null);
+            if(httpsClientProtocols!=null) {
+                access.printf(Level.INIT, LOADED_FROM_CADI_PROPERTIES, Config.HTTPS_CLIENT_PROTOCOLS);
+            } else {
+                httpsClientProtocols = Config.HTTPS_PROTOCOLS_DEFAULT;
+                access.printf(Level.INIT, "%s set from %s",Config.HTTPS_CLIENT_PROTOCOLS, "Default Protocols");
+            }
+            System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, httpsClientProtocols);
+        }
+    }
 
-       /**
-        * @return the km
-        */
-       public X509KeyManager[] getKeyManagers() {
-               return km;
-       }
+    /**
+     * @return the scf
+     */
+    public SSLSocketFactory getSSLSocketFactory() {
+        return socketFactory;
+    }
 
-       public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException {
-               for(X509TrustManager xtm : tm) {
-                       xtm.checkClientTrusted(certarr, SECURITY_ALGO);
-               }
-       }
+    public SSLContext getSSLContext() {
+        return context;
+    }
 
-       public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException {
-               for(X509TrustManager xtm : tm) {
-                       xtm.checkServerTrusted(certarr, SECURITY_ALGO);
-               }
-       }
+    /**
+     * @return the km
+     */
+    public X509KeyManager[] getKeyManagers() {
+        return x509KeyManager;
+    }
 
-       public void setSocketFactoryOn(HttpsURLConnection hsuc) {
-               hsuc.setSSLSocketFactory(scf);
-               if(maskHV != null && !maskHV.equals(hsuc.getHostnameVerifier())) {
-                       hsuc.setHostnameVerifier(maskHV);
-               }
-       }
-       
-       protected void initializeKeyManager() throws CadiException, IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException {
-               String keyStore = access.getProperty(Config.CADI_KEYSTORE, null);
-               if(keyStore != null && !new File(keyStore).exists()) {
-                       throw new CadiException(keyStore + " does not exist");
-               }
+    public void checkClientTrusted(X509Certificate[] certarr) throws CertificateException {
+        for (X509TrustManager xtm : x509TrustManager) {
+            xtm.checkClientTrusted(certarr, SECURITY_ALGO);
+        }
+    }
 
-               String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
-               keyStorePasswd = (keyStorePasswd == null) ? null : access.decrypt(keyStorePasswd, false);
+    public void checkServerTrusted(X509Certificate[] certarr) throws CertificateException {
+        for (X509TrustManager xtm : x509TrustManager) {
+            xtm.checkServerTrusted(certarr, SECURITY_ALGO);
+        }
+    }
 
-               String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD, null);
-               keyPasswd = (keyPasswd == null) ? keyStorePasswd : access.decrypt(keyPasswd, false);
+    public void setSocketFactoryOn(HttpsURLConnection hsuc) {
+        hsuc.setSSLSocketFactory(socketFactory);
+        if (maskHV != null && !maskHV.equals(hsuc.getHostnameVerifier())) {
+            hsuc.setHostnameVerifier(maskHV);
+        }
+    }
+    
+    protected void initializeKeyManager() throws CadiException, IOException, NoSuchAlgorithmException, KeyStoreException, CertificateException, UnrecoverableKeyException {
+        String keyStore = access.getProperty(Config.CADI_KEYSTORE, null);
+        if(keyStore==null) {
+            return;
+        } else if (!new File(keyStore).exists()) {
+            throw new CadiException(keyStore + " does not exist");
+        }
 
-               KeyManagerFactory kmf = KeyManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
-               if(keyStore == null || keyStorePasswd == null) { 
-                       km = new X509KeyManager[0];
-               } else {
-                       ArrayList<X509KeyManager> kmal = new ArrayList<X509KeyManager>();
-                       File file;
-                       for(String ksname : keyStore.split(REGEX_COMMA)) {
-                               file = new File(ksname);
-                               String keystoreFormat;
-                               if(ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) {
-                                       keystoreFormat = "PKCS12";
-                               } else {
-                                       keystoreFormat = "JKS";
-                               }
-                               if(file.exists()) {
-                                       FileInputStream fis = new FileInputStream(file);
-                                       try {
-                                               KeyStore ks = KeyStore.getInstance(keystoreFormat);
-                                               ks.load(fis, keyStorePasswd.toCharArray());
-                                               kmf.init(ks, keyPasswd.toCharArray());
-                                       } finally {
-                                               fis.close();
-                                       }
-                               }
-                       }
-                       for(KeyManager km : kmf.getKeyManagers()) {
-                               if(km instanceof X509KeyManager) {
-                                       kmal.add((X509KeyManager)km);
-                               }
-                       }
-                       km = new X509KeyManager[kmal.size()];
-                       kmal.toArray(km);
-               }
-       }
+        String keyStorePasswd = access.getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
+        keyStorePasswd = (keyStorePasswd == null) ? null : access.decrypt(keyStorePasswd, false);
+        if (keyStore == null || keyStorePasswd == null) { 
+            x509KeyManager = new X509KeyManager[0];
+            return;
+        }
 
-       protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException {
-               String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, null);
-               if(trustStore != null && !new File(trustStore).exists()) {
-                       throw new CadiException(trustStore + " does not exist");
-               }
+        String keyPasswd = access.getProperty(Config.CADI_KEY_PASSWORD, null);
+        keyPasswd = (keyPasswd == null) ? keyStorePasswd : access.decrypt(keyPasswd, false);
 
-               String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
-               trustStorePasswd = (trustStorePasswd == null) ? "changeit"/*defacto Java Trust Pass*/ : access.decrypt(trustStorePasswd, false);
+        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM);
 
-               TrustManagerFactory tmf = TrustManagerFactory.getInstance(SslKeyManagerFactoryAlgorithm);
-               if(trustStore != null) {
-                       File file;
-                       for(String tsname : trustStore.split(REGEX_COMMA)) {
-                               file = new File(tsname);
-                               if(file.exists()) {
-                                       FileInputStream fis = new FileInputStream(file);
-                                       try {
-                                               KeyStore ts = KeyStore.getInstance("JKS");
-                                               ts.load(fis, trustStorePasswd.toCharArray());
-                                               tmf.init(ts); 
-                                       } finally {
-                                               fis.close();
-                                       }
-                               }
-                       }
+        ArrayList<X509KeyManager> keyManagers = new ArrayList<>();
+        File file;
+        for (String ksname : Split.splitTrim(',', keyStore)) {
+            String keystoreFormat;
+            if (ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) {
+                keystoreFormat = "PKCS12";
+            } else {
+                keystoreFormat = "JKS";
+            }
 
-                       TrustManager tms[] = tmf.getTrustManagers();
-                       if(tms != null) {
-                               tm = new X509TrustManager[(tms == null) ? 0 : tms.length];
-                               for(int i = 0; i < tms.length; ++i) {
-                                       try {
-                                               tm[i] = (X509TrustManager)tms[i];
-                                       } catch (ClassCastException e) {
-                                               access.log(Level.WARN, "Non X509 TrustManager", tm[i].getClass().getName(), "skipped in SecurityInfo");
-                                       }
-                               }
-                       }
-               }
+            file = new File(ksname);
+            if (file.exists()) {
+                FileInputStream fis = new FileInputStream(file);
+                try {
+                    KeyStore ks = KeyStore.getInstance(keystoreFormat);
+                    ks.load(fis, keyStorePasswd.toCharArray());
+                    keyManagerFactory.init(ks, keyPasswd.toCharArray());
+                } finally {
+                    fis.close();
+                }
+            }
+        }
+        
+        StringBuilder sb = null;
+        for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) {
+            if (keyManager instanceof X509KeyManager) {
+                X509KeyManager xkm = (X509KeyManager)keyManager;
+                keyManagers.add(xkm);
+                if(defaultAlias!=null) {
+                    sb=new StringBuilder("X509 Chain\n");
+                    x509Info(sb,xkm.getCertificateChain(defaultAlias));
+                }
+                if(defaultClientAlias!=null && !defaultClientAlias.equals(defaultAlias)) {
+                    if(sb==null) {
+                        sb = new StringBuilder();
+                    } else {
+                        sb.append('\n');
+                    }
+                    sb.append("X509 Client Chain\n");
+                    x509Info(sb,xkm.getCertificateChain(defaultAlias));
+                }
+            }
+        }
+        x509KeyManager = new X509KeyManager[keyManagers.size()];
+        keyManagers.toArray(x509KeyManager);
+        
+        if(sb!=null) {
+            access.log(Level.INIT, sb);
+        }
+    }
+    
+    private void x509Info(StringBuilder sb, X509Certificate[] chain) {
+        if(chain!=null) {
+            int i=0;
+            for(X509Certificate x : chain) {
+                sb.append("  ");
+                sb.append(i++);
+                sb.append(')');
+                sb.append("\n    Subject: ");
+                sb.append(x.getSubjectDN());
+                sb.append("\n    Issuer : ");
+                sb.append(x.getIssuerDN());
+                sb.append("\n    Expires: ");
+                sb.append(x.getNotAfter());
+                sb.append('\n');
+            }
+        }
+    }
 
-       }
-       
-       protected void initializeTrustMasks() throws AccessException {
-               String tips = access.getProperty(Config.CADI_TRUST_MASKS, null);
-               if(tips != null) {
-                       access.log(Level.INIT, "Explicitly accepting valid X509s from", tips);
-                       String[] ipsplit = tips.split(REGEX_COMMA);
-                       trustMasks = new NetMask[ipsplit.length];
-                       for(int i = 0; i < ipsplit.length; ++i) {
-                               try {
-                                       trustMasks[i] = new NetMask(ipsplit[i]);
-                               } catch (MaskFormatException e) {
-                                       throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS, e);
-                               }
-                       }
-               }
-               
-               if(trustMasks != null) {
-                       final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier();
-                       HttpsURLConnection.setDefaultHostnameVerifier(maskHV = new HostnameVerifier() {
-                               @Override
-                               public boolean verify(final String urlHostName, final SSLSession session) {
-                                       try {
-                                               // This will pick up /etc/host entries as well as DNS
-                                               InetAddress ia = InetAddress.getByName(session.getPeerHost());
-                                               for(NetMask tmask : trustMasks) {
-                                                       if(tmask.isInNet(ia.getHostAddress())) {
-                                                               return true;
-                                                       }
-                                               }
-                                       } catch (UnknownHostException e) {
-                                               // It's ok. do normal Verify
-                                       }
-                                       return origHV.verify(urlHostName, session);
-                               };
-                       });
-               }
-       }
-       
+    protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException {
+        String trustStore = access.getProperty(Config.CADI_TRUSTSTORE, null);
+        if(trustStore==null) {
+            return; 
+        } else if(!new File(trustStore).exists()) {
+            throw new CadiException(trustStore + " does not exist");
+        }
+
+        String trustStorePasswd = access.getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
+        trustStorePasswd = (trustStorePasswd == null ) ? "changeit"/*defacto Java Trust Pass*/ : access.decrypt(trustStorePasswd, false);
+
+        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM);
+        File file;
+        for (String trustStoreName : Split.splitTrim(',',trustStore)) {
+            file = new File(trustStoreName);
+            if (file.exists()) {
+                FileInputStream fis = new FileInputStream(file);
+                try {
+                    KeyStore ts = KeyStore.getInstance("JKS");
+                    ts.load(fis, trustStorePasswd.toCharArray());
+                    trustManagerFactory.init(ts); 
+                } finally {
+                    fis.close();
+                }
+            }
+        }
+
+        TrustManager trustManagers[] = trustManagerFactory.getTrustManagers();
+        if (trustManagers == null || trustManagers.length == 0) {
+            return;
+        }
+
+        x509TrustManager = new X509TrustManager[trustManagers.length];
+        for (int i = 0; i < trustManagers.length; ++i) {
+            try {
+                x509TrustManager[i] = (X509TrustManager)trustManagers[i];
+            } catch (ClassCastException e) {
+                access.log(Level.WARN, "Non X509 TrustManager", x509TrustManager[i].getClass().getName(), "skipped in SecurityInfo");
+            }
+        }
+    }
+    
+    protected void initializeTrustMasks() throws AccessException {
+        String tips = access.getProperty(Config.CADI_TRUST_MASKS, null);
+        if (tips == null) {
+            return;
+        }
+
+        access.log(Level.INIT, "Explicitly accepting valid X509s from", tips);
+        String[] ipsplit = Split.splitTrim(',', tips);
+        trustMasks = new NetMask[ipsplit.length];
+        for (int i = 0; i < ipsplit.length; ++i) {
+            try {
+                trustMasks[i] = new NetMask(ipsplit[i]);
+            } catch (MaskFormatException e) {
+                throw new AccessException("Invalid IP Mask in " + Config.CADI_TRUST_MASKS, e);
+            }
+        }
+    
+        final HostnameVerifier origHV = HttpsURLConnection.getDefaultHostnameVerifier();
+        maskHV = new HostnameVerifier() {
+            @Override
+            public boolean verify(final String urlHostName, final SSLSession session) {
+                try {
+                    // This will pick up /etc/host entries as well as DNS
+                    InetAddress ia = InetAddress.getByName(session.getPeerHost());
+                    for (NetMask tmask : trustMasks) {
+                        if (tmask.isInNet(ia.getHostAddress())) {
+                            return true;
+                        }
+                    }
+                } catch (UnknownHostException e) {
+                    // It's ok. do normal Verify
+                }
+                return origHV.verify(urlHostName, session);
+            };
+        };
+        HttpsURLConnection.setDefaultHostnameVerifier(maskHV);
+    }
+    
 }