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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.dmaap.datarouter.node.utils;
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;
39 public class NodeTlsManager {
41 private static final EELFLogger eelfLogger = EELFManager.getInstance().getLogger(NodeTlsManager.class);
43 private String keyStoreType;
44 private String keyStorefile;
45 private String keyStorePassword;
46 private String keyManagerPassword;
47 private final String[] enabledProtocols;
49 public NodeTlsManager(Properties properties) {
50 enabledProtocols = properties.getProperty("NodeHttpsProtocols",
51 "TLSv1.1|TLSv1.2").trim().split("\\|");
52 setUpKeyStore(properties);
53 setUpTrustStore(properties);
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");
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);
74 eelfLogger.error("TrustStore not found. Falling back to 1 way TLS");
77 public String getKeyStoreType() {
81 public String getKeyStorefile() {
85 public String getKeyStorePassword() {
86 return keyStorePassword;
89 public String getKeyManagerPassword() {
90 return keyManagerPassword;
93 public String[] getEnabledProtocols() {
94 return enabledProtocols;
98 * Get the CN value of the first private key entry with a certificate.
100 * @return CN of the certificate subject or null
102 public String getMyNameFromCertificate() {
103 return getCanonicalName(this.keyStoreType, this.keyStorefile, this.keyStorePassword);
106 private String getCanonicalName(String kstype, String ksfile, String kspass) {
109 ks = KeyStore.getInstance(kstype);
110 if (loadKeyStore(ksfile, kspass, ks)) {
113 } catch (Exception e) {
114 NodeUtils.setIpAndFqdnForEelf("getCanonicalName");
115 eelfLogger.error(EelfMsgs.MESSAGE_KEYSTORE_LOAD_ERROR, e, ksfile);
118 return (getCanonicalName(ks));
121 private String getCanonicalName(KeyStore ks) {
123 Enumeration<String> aliases = ks.aliases();
124 while (aliases.hasMoreElements()) {
125 String name = getNameFromSubject(ks, aliases);
130 } catch (Exception e) {
131 eelfLogger.error("NODE0402 Error extracting my name from my keystore file " + e);
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(),
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);
154 String subject = cert.getSubjectX500Principal().getName();
156 LdapName ln = new LdapName(subject);
157 for (Rdn rdn : ln.getRdns()) {
158 if (rdn.getType().equalsIgnoreCase("CN")) {
159 nameFromSubject = rdn.getValue().toString();
162 } catch (InvalidNameException e) {
163 eelfLogger.error("No valid CN not found for dr-node cert", e);
167 return nameFromSubject;