2 * Copyright (c) 2017 Cisco Systems, Inc. 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
9 package org.opendaylight.netconf.sal.connect.util;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.MoreExecutors;
15 import com.google.common.util.concurrent.SettableFuture;
16 import java.util.List;
17 import java.util.concurrent.Future;
18 import java.util.stream.Collectors;
19 import javax.annotation.Nullable;
20 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.KeystoreBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.NetconfKeystoreService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKeyKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.opendaylight.yangtools.yang.common.RpcResult;
43 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 public class NetconfSalKeystoreService implements NetconfKeystoreService {
49 private static final Logger LOG = LoggerFactory.getLogger(NetconfSalKeystoreService.class);
51 private final DataBroker dataBroker;
52 private final AAAEncryptionService encryptionService;
54 private final InstanceIdentifier<Keystore> keystoreIid = InstanceIdentifier.create(Keystore.class);
56 public NetconfSalKeystoreService(final DataBroker dataBroker,
57 final AAAEncryptionService encryptionService) {
58 LOG.info("Starting NETCONF keystore service.");
60 this.dataBroker = dataBroker;
61 this.encryptionService = encryptionService;
66 private void initKeystore() {
67 final Keystore keystore = new KeystoreBuilder().build();
69 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
70 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, keystoreIid, keystore);
72 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
76 LOG.debug("init keystore done");
77 } catch (TransactionCommitFailedException exception) {
78 LOG.error("Unable to initialize Netconf key-pair store.", exception);
83 public Future<RpcResult<Void>> removeKeystoreEntry(final RemoveKeystoreEntryInput input) {
84 LOG.debug("Removing keypairs: {}", input);
86 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
87 final List<String> ids = input.getKeyId();
89 for (final String id : ids) {
90 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
91 keystoreIid.child(KeyCredential.class, new KeyCredentialKey(id)));
94 final SettableFuture<RpcResult<Void>> rpcResult = SettableFuture.create();
96 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
97 Futures.addCallback(submit, new FutureCallback<Void>() {
99 public void onSuccess(@Nullable final Void result) {
100 LOG.debug("remove-key-pair success. Input: {}");
101 final RpcResult<Void> success = RpcResultBuilder.<Void>success().build();
102 rpcResult.set(success);
106 public void onFailure(final Throwable throwable) {
107 LOG.warn("remove-key-pair failed. Input: {}", input, throwable);
108 rpcResult.setException(throwable);
110 }, MoreExecutors.directExecutor());
116 public Future<RpcResult<Void>> addKeystoreEntry(final AddKeystoreEntryInput input) {
117 LOG.debug("Adding keypairs: {}", input);
119 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
120 final List<KeyCredential> keypairs = input.getKeyCredential().stream().map(keypair ->
121 new KeyCredentialBuilder(keypair)
122 .setPrivateKey(encryptionService.encrypt(keypair.getPrivateKey()))
123 .setPassphrase(encryptionService.encrypt(keypair.getPassphrase()))
124 .build()).collect(Collectors.toList());
126 for (KeyCredential keypair : keypairs) {
127 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
128 keystoreIid.child(KeyCredential.class, keypair.getKey()), keypair);
131 final SettableFuture<RpcResult<Void>> rpcResult = SettableFuture.create();
133 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
134 Futures.addCallback(submit, new FutureCallback<Void>() {
136 public void onSuccess(@Nullable final Void result) {
137 LOG.debug("add-key-pair success. Input: {}");
138 final RpcResult<Void> success = RpcResultBuilder.<Void>success().build();
139 rpcResult.set(success);
143 public void onFailure(final Throwable throwable) {
144 LOG.warn("add-key-pair failed. Input: {}", input, throwable);
145 rpcResult.setException(throwable);
147 }, MoreExecutors.directExecutor());
153 public Future<RpcResult<Void>> addTrustedCertificate(AddTrustedCertificateInput input) {
154 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
156 for (TrustedCertificate certificate : input.getTrustedCertificate()) {
157 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
158 keystoreIid.child(TrustedCertificate.class, certificate.getKey()), certificate);
161 final SettableFuture<RpcResult<Void>> rpcResult = SettableFuture.create();
163 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
164 Futures.addCallback(submit, new FutureCallback<Void>() {
166 public void onSuccess(@Nullable Void result) {
167 LOG.debug("add-trusted-certificate success. Input: {}", input);
168 final RpcResult<Void> success = RpcResultBuilder.<Void>success().build();
169 rpcResult.set(success);
173 public void onFailure(final Throwable throwable) {
174 LOG.warn("add-trusted-certificate failed. Input: {}", input, throwable);
175 rpcResult.setException(throwable);
177 }, MoreExecutors.directExecutor());
183 public Future<RpcResult<Void>> removeTrustedCertificate(RemoveTrustedCertificateInput input) {
184 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
185 final List<String> names = input.getName();
187 for (final String name : names) {
188 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
189 keystoreIid.child(TrustedCertificate.class, new TrustedCertificateKey(name)));
192 final SettableFuture<RpcResult<Void>> rpcResult = SettableFuture.create();
194 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
195 Futures.addCallback(submit, new FutureCallback<Void>() {
197 public void onSuccess(@Nullable Void result) {
198 LOG.debug("remove-trusted-certificate success. Input: {}", input);
199 final RpcResult<Void> success = RpcResultBuilder.<Void>success().build();
200 rpcResult.set(success);
204 public void onFailure(final Throwable throwable) {
205 LOG.warn("remove-trusted-certificate failed. Input: {}", input, throwable);
206 rpcResult.setException(throwable);
208 }, MoreExecutors.directExecutor());
214 public Future<RpcResult<Void>> addPrivateKey(AddPrivateKeyInput input) {
215 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
217 for (PrivateKey key: input.getPrivateKey()) {
218 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
219 keystoreIid.child(PrivateKey.class, key.getKey()), key);
222 final SettableFuture<RpcResult<Void>> rpcResult = SettableFuture.create();
224 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
225 Futures.addCallback(submit, new FutureCallback<Void>() {
227 public void onSuccess(@Nullable Void result) {
228 LOG.debug("add-private-key success. Input: {}", input);
229 final RpcResult<Void> success = RpcResultBuilder.<Void>success().build();
230 rpcResult.set(success);
234 public void onFailure(final Throwable throwable) {
235 LOG.warn("add-private-key failed. Input: {}", input, throwable);
236 rpcResult.setException(throwable);
238 }, MoreExecutors.directExecutor());
244 public Future<RpcResult<Void>> removePrivateKey(RemovePrivateKeyInput input) {
245 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
246 final List<String> names = input.getName();
248 for (final String name : names) {
249 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
250 keystoreIid.child(PrivateKey.class, new PrivateKeyKey(name)));
253 final SettableFuture<RpcResult<Void>> rpcResult = SettableFuture.create();
255 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
256 Futures.addCallback(submit, new FutureCallback<Void>() {
258 public void onSuccess(@Nullable Void result) {
259 LOG.debug("remove-private-key success. Input: {}", input);
260 final RpcResult<Void> success = RpcResultBuilder.<Void>success().build();
261 rpcResult.set(success);
265 public void onFailure(final Throwable throwable) {
266 LOG.warn("remove-private-key failed. Input: {}", input, throwable);
267 rpcResult.setException(throwable);
269 }, MoreExecutors.directExecutor());