[DMAAP-DR] Remove cadi/aaf from dr-node
[dmaap/datarouter.git] / datarouter-node / src / main / java / org / onap / dmaap / datarouter / node / utils / NodeTlsManager.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2022 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.dmaap.datarouter.node.utils;
22
23 import com.att.eelf.configuration.EELFLogger;
24 import com.att.eelf.configuration.EELFManager;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.security.KeyStore;
28 import java.security.KeyStoreException;
29 import java.security.NoSuchAlgorithmException;
30 import java.security.cert.CertificateException;
31 import java.security.cert.X509Certificate;
32 import java.util.Enumeration;
33 import java.util.Properties;
34 import javax.naming.InvalidNameException;
35 import javax.naming.ldap.LdapName;
36 import javax.naming.ldap.Rdn;
37 import org.onap.dmaap.datarouter.node.eelf.EelfMsgs;
38
39 public class NodeTlsManager {
40
41     private static final EELFLogger eelfLogger = EELFManager.getInstance().getLogger(NodeTlsManager.class);
42
43     private String keyStoreType;
44     private String keyStorefile;
45     private String keyStorePassword;
46     private String keyManagerPassword;
47     private final String[] enabledProtocols;
48
49     public NodeTlsManager(Properties properties) {
50         enabledProtocols = properties.getProperty("NodeHttpsProtocols",
51             "TLSv1.1|TLSv1.2").trim().split("\\|");
52         setUpKeyStore(properties);
53         setUpTrustStore(properties);
54     }
55
56     private void setUpKeyStore(Properties properties) {
57         keyStoreType = properties.getProperty("KeyStoreType", "PKCS12");
58         keyStorefile = properties.getProperty("KeyStorePath");
59         keyStorePassword = properties.getProperty("KeyStorePass");
60         keyManagerPassword = properties.getProperty("KeyManagerPass");
61     }
62
63     private void setUpTrustStore(Properties properties) {
64         String trustStoreType = properties.getProperty("TrustStoreType", "jks");
65         String trustStoreFile = properties.getProperty("TrustStorePath");
66         String trustStorePassword = properties.getProperty("TrustStorePass");
67         if (trustStoreFile != null && trustStoreFile.length() > 0) {
68             eelfLogger.info("TrustStore found. Loading {} file {} to System Properties.", trustStoreType, trustStoreFile);
69             System.setProperty("javax.net.ssl.trustStoreType", trustStoreType);
70             System.setProperty("javax.net.ssl.trustStore", trustStoreFile);
71             System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
72             return;
73         }
74         eelfLogger.error("TrustStore not found. Falling back to 1 way TLS");
75     }
76
77     public String getKeyStoreType() {
78         return keyStoreType;
79     }
80
81     public String getKeyStorefile() {
82         return keyStorefile;
83     }
84
85     public String getKeyStorePassword() {
86         return keyStorePassword;
87     }
88
89     public String getKeyManagerPassword() {
90         return keyManagerPassword;
91     }
92
93     public String[] getEnabledProtocols() {
94         return enabledProtocols;
95     }
96
97     /**
98      * Get the CN value of the first private key entry with a certificate.
99      *
100      * @return CN of the certificate subject or null
101      */
102     public String getMyNameFromCertificate() {
103         return getCanonicalName(this.keyStoreType, this.keyStorefile, this.keyStorePassword);
104     }
105
106     private String getCanonicalName(String kstype, String ksfile, String kspass) {
107         KeyStore ks;
108         try {
109             ks = KeyStore.getInstance(kstype);
110             if (loadKeyStore(ksfile, kspass, ks)) {
111                 return (null);
112             }
113         } catch (Exception e) {
114             NodeUtils.setIpAndFqdnForEelf("getCanonicalName");
115             eelfLogger.error(EelfMsgs.MESSAGE_KEYSTORE_LOAD_ERROR, e, ksfile);
116             return (null);
117         }
118         return (getCanonicalName(ks));
119     }
120
121     private String getCanonicalName(KeyStore ks) {
122         try {
123             Enumeration<String> aliases = ks.aliases();
124             while (aliases.hasMoreElements()) {
125                 String name = getNameFromSubject(ks, aliases);
126                 if (name != null) {
127                     return name;
128                 }
129             }
130         } catch (Exception e) {
131             eelfLogger.error("NODE0402 Error extracting my name from my keystore file " + e);
132         }
133         return (null);
134     }
135
136     private boolean loadKeyStore(String ksfile, String kspass, KeyStore ks)
137         throws NoSuchAlgorithmException, CertificateException {
138         try (FileInputStream fileInputStream = new FileInputStream(ksfile)) {
139             ks.load(fileInputStream, kspass.toCharArray());
140         } catch (IOException ioException) {
141             eelfLogger.error("IOException occurred while opening FileInputStream: " + ioException.getMessage(),
142                 ioException);
143             return true;
144         }
145         return false;
146     }
147
148     private String getNameFromSubject(KeyStore ks, Enumeration<String> aliases) throws KeyStoreException {
149         String alias = aliases.nextElement();
150         String nameFromSubject = null;
151         if (ks.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
152             X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
153             if (cert != null) {
154                 String subject = cert.getSubjectX500Principal().getName();
155                 try {
156                     LdapName ln = new LdapName(subject);
157                     for (Rdn rdn : ln.getRdns()) {
158                         if (rdn.getType().equalsIgnoreCase("CN")) {
159                             nameFromSubject = rdn.getValue().toString();
160                         }
161                     }
162                 } catch (InvalidNameException e) {
163                     eelfLogger.error("No valid CN not found for dr-node cert", e);
164                 }
165             }
166         }
167         return nameFromSubject;
168     }
169 }