2 * Copyright (c) 2016, 2017 Inocybe Technologies. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.aaa.cert.impl;
11 import java.io.IOException;
12 import java.security.KeyManagementException;
13 import java.security.KeyStore;
14 import java.security.KeyStoreException;
15 import java.security.NoSuchAlgorithmException;
16 import java.security.UnrecoverableKeyException;
17 import javax.net.ssl.KeyManagerFactory;
18 import javax.net.ssl.SSLContext;
19 import javax.net.ssl.TrustManagerFactory;
20 import javax.xml.parsers.DocumentBuilder;
21 import javax.xml.parsers.DocumentBuilderFactory;
22 import javax.xml.parsers.ParserConfigurationException;
23 import javax.xml.transform.Transformer;
24 import javax.xml.transform.TransformerException;
25 import javax.xml.transform.TransformerFactory;
26 import javax.xml.transform.dom.DOMSource;
27 import javax.xml.transform.stream.StreamResult;
28 import org.apache.commons.lang3.RandomStringUtils;
29 import org.opendaylight.aaa.cert.api.IAaaCertProvider;
30 import org.opendaylight.aaa.cert.api.ICertificateManager;
31 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
32 import org.opendaylight.mdsal.binding.api.DataBroker;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.AaaCertServiceConfig;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.AaaCertServiceConfigBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.aaa.cert.service.config.CtlKeystore;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.aaa.cert.service.config.CtlKeystoreBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.aaa.cert.service.config.TrustKeystore;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.yang.aaa.cert.rev151126.aaa.cert.service.config.TrustKeystoreBuilder;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import org.w3c.dom.Document;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.NodeList;
44 import org.xml.sax.SAXException;
47 * CertificateManagerService implements ICertificateManager and work as adapter
48 * to which AaaCertProvider is used.
53 public class CertificateManagerService implements ICertificateManager {
55 private static final Logger LOG = LoggerFactory.getLogger(CertificateManagerService.class);
57 private static final String DEFAULT_CONFIG_FILE_PATH = "etc" + File.separator + "opendaylight" + File.separator
58 + "datastore" + File.separator + "initial" + File.separator + "config" + File.separator
59 + "aaa-cert-config.xml";
60 private static final int PWD_LENGTH = 12;
61 private final IAaaCertProvider aaaCertProvider;
63 public CertificateManagerService(AaaCertServiceConfig aaaCertServiceConfig, final DataBroker dataBroker,
64 final AAAEncryptionService encryptionSrv) {
65 if (aaaCertServiceConfig == null) {
66 throw new IllegalArgumentException("Certificate Manager service configuration is null");
68 if (aaaCertServiceConfig.getUseConfig()) {
69 if (aaaCertServiceConfig.getCtlKeystore() != null
70 && aaaCertServiceConfig.getCtlKeystore().getStorePassword() != null
71 && aaaCertServiceConfig.getCtlKeystore().getStorePassword().isEmpty()) {
72 LOG.debug("Set keystores password");
73 final String ctlPwd = RandomStringUtils.random(PWD_LENGTH, true, true);
74 final String trustPwd = RandomStringUtils.random(PWD_LENGTH, true, true);
75 updateCertManagerSrvConfig(ctlPwd, trustPwd);
76 final CtlKeystore ctlKeystore = new CtlKeystoreBuilder(aaaCertServiceConfig.getCtlKeystore())
77 .setStorePassword(ctlPwd).build();
78 final TrustKeystore trustKeystore = new TrustKeystoreBuilder(aaaCertServiceConfig.getTrustKeystore())
79 .setStorePassword(trustPwd).build();
80 aaaCertServiceConfig = new AaaCertServiceConfigBuilder(aaaCertServiceConfig).setCtlKeystore(ctlKeystore)
81 .setTrustKeystore(trustKeystore).build();
83 if (aaaCertServiceConfig.getUseMdsal()) {
84 aaaCertProvider = new DefaultMdsalSslData(new AaaCertMdsalProvider(dataBroker, encryptionSrv),
85 aaaCertServiceConfig.getBundleName(), aaaCertServiceConfig.getCtlKeystore(),
86 aaaCertServiceConfig.getTrustKeystore());
87 LOG.debug("Using default mdsal SslData as aaaCertProvider");
89 aaaCertProvider = new AaaCertProvider(aaaCertServiceConfig.getCtlKeystore(),
90 aaaCertServiceConfig.getTrustKeystore());
91 LOG.debug("Using default keystore files as aaaCertProvider");
93 aaaCertProvider.createKeyStores();
94 LOG.info("Certificate Manager service has been initialized");
96 aaaCertProvider = null;
98 "Certificate Manager service has not been initialized,"
99 + " change the initial aaa-cert-config data and restart Opendaylight");
104 public KeyStore getODLKeyStore() {
105 return aaaCertProvider.getODLKeyStore();
109 public KeyStore getTrustKeyStore() {
110 return aaaCertProvider.getTrustKeyStore();
114 public String[] getCipherSuites() {
115 return aaaCertProvider.getCipherSuites();
119 public String getCertificateTrustStore(final String storePasswd, final String alias, final boolean withTag) {
120 return aaaCertProvider.getCertificateTrustStore(storePasswd, alias, withTag);
124 public String getODLKeyStoreCertificate(final String storePasswd, final boolean withTag) {
125 return aaaCertProvider.getODLKeyStoreCertificate(storePasswd, withTag);
129 public String genODLKeyStoreCertificateReq(final String storePasswd, final boolean withTag) {
130 return aaaCertProvider.genODLKeyStoreCertificateReq(storePasswd, withTag);
134 public SSLContext getServerContext() {
135 SSLContext serverContext = null;
137 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
138 kmf.init(aaaCertProvider.getODLKeyStore(),
139 aaaCertProvider.getOdlKeyStoreInfo().getStorePassword().toCharArray());
140 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
141 tmf.init(aaaCertProvider.getTrustKeyStore());
143 serverContext = SSLContext.getInstance(KeyStoreConstant.TLS_PROTOCOL);
144 serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
145 } catch (final NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException
146 | KeyManagementException e) {
147 LOG.error("Error while creating SSLContext ", e);
149 return serverContext;
153 public String[] getTlsProtocols() {
154 return aaaCertProvider.getTlsProtocols();
158 public boolean importSslDataKeystores(final String odlKeystoreName, final String odlKeystorePwd,
159 final String odlKeystoreAlias, final String trustKeystoreName, final String trustKeystorePwd,
160 final String[] cipherSuites, final String tlsProtocols) {
161 DefaultMdsalSslData mdsalCertProvider = (DefaultMdsalSslData) aaaCertProvider;
162 if (mdsalCertProvider == null) {
163 LOG.debug("aaaCertProvider is not MD-Sal Certificate Provider");
166 return mdsalCertProvider.importSslDataKeystores(odlKeystoreName, odlKeystorePwd, odlKeystoreAlias,
167 trustKeystoreName, trustKeystorePwd, cipherSuites, tlsProtocols);
171 public void exportSslDataKeystores() {
172 DefaultMdsalSslData mdsalCertProvider = (DefaultMdsalSslData) aaaCertProvider;
173 if (mdsalCertProvider == null) {
174 LOG.debug("aaaCertProvider is not MD-Sal Certificate Provider");
177 mdsalCertProvider.exportSslDataKeystores();
180 private static void updateCertManagerSrvConfig(final String ctlPwd, final String trustPwd) {
182 LOG.debug("Update Certificate manager service config file");
183 final File configFile = new File(DEFAULT_CONFIG_FILE_PATH);
184 if (configFile.exists()) {
185 final String storePwdTag = "store-password";
186 final String ctlStoreTag = "ctlKeystore";
187 final String trustStoreTag = "trustKeystore";
188 final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
189 final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
190 final Document doc = docBuilder.parse(configFile);
191 final NodeList ndList = doc.getElementsByTagName(storePwdTag);
192 for (int i = 0; i < ndList.getLength(); i++) {
193 final Node nd = ndList.item(i);
194 if (nd.getParentNode() != null && nd.getParentNode().getNodeName().equals(ctlStoreTag)) {
195 nd.setTextContent(ctlPwd);
196 } else if (nd.getParentNode() != null && nd.getParentNode().getNodeName().equals(trustStoreTag)) {
197 nd.setTextContent(trustPwd);
200 final TransformerFactory transformerFactory = TransformerFactory.newInstance();
201 final Transformer transformer = transformerFactory.newTransformer();
202 final DOMSource source = new DOMSource(doc);
203 final StreamResult result = new StreamResult(new File(DEFAULT_CONFIG_FILE_PATH));
204 transformer.transform(source, result);
206 LOG.warn("The Certificate manager service config file does not exist {}", DEFAULT_CONFIG_FILE_PATH);
208 } catch (ParserConfigurationException | TransformerException | SAXException | IOException e) {
209 LOG.error("Error while updating Certificate manager service config file", e);