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
8 package org.opendaylight.netconf.sal.connect.util;
10 import com.google.common.util.concurrent.FutureCallback;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import com.google.common.util.concurrent.MoreExecutors;
13 import com.google.common.util.concurrent.SettableFuture;
14 import java.util.List;
15 import java.util.concurrent.ExecutionException;
16 import java.util.stream.Collectors;
17 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
18 import org.opendaylight.mdsal.binding.api.DataBroker;
19 import org.opendaylight.mdsal.binding.api.WriteTransaction;
20 import org.opendaylight.mdsal.common.api.CommitInfo;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.KeystoreBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.NetconfKeystoreService;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKeyKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.opendaylight.yangtools.yang.common.RpcResult;
52 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 public class NetconfSalKeystoreService implements NetconfKeystoreService {
58 private static final Logger LOG = LoggerFactory.getLogger(NetconfSalKeystoreService.class);
60 private final DataBroker dataBroker;
61 private final AAAEncryptionService encryptionService;
63 private final InstanceIdentifier<Keystore> keystoreIid = InstanceIdentifier.create(Keystore.class);
65 public NetconfSalKeystoreService(final DataBroker dataBroker,
66 final AAAEncryptionService encryptionService) {
67 LOG.info("Starting NETCONF keystore service.");
69 this.dataBroker = dataBroker;
70 this.encryptionService = encryptionService;
75 private void initKeystore() {
76 final Keystore keystore = new KeystoreBuilder().build();
78 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
79 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, keystoreIid, keystore);
82 writeTransaction.commit().get();
83 LOG.debug("init keystore done");
84 } catch (InterruptedException | ExecutionException exception) {
85 LOG.error("Unable to initialize Netconf key-pair store.", exception);
90 public ListenableFuture<RpcResult<RemoveKeystoreEntryOutput>> removeKeystoreEntry(
91 final RemoveKeystoreEntryInput input) {
92 LOG.debug("Removing keypairs: {}", input);
94 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
96 for (final String id : input.getKeyId()) {
97 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
98 keystoreIid.child(KeyCredential.class, new KeyCredentialKey(id)));
101 final SettableFuture<RpcResult<RemoveKeystoreEntryOutput>> rpcResult = SettableFuture.create();
103 writeTransaction.commit().addCallback(new FutureCallback<CommitInfo>() {
105 public void onSuccess(final CommitInfo result) {
106 LOG.debug("remove-key-pair success. Input: {}", input);
107 rpcResult.set(RpcResultBuilder.success(new RemoveKeystoreEntryOutputBuilder().build()).build());
111 public void onFailure(final Throwable throwable) {
112 LOG.warn("remove-key-pair failed. Input: {}", input, throwable);
113 rpcResult.setException(throwable);
115 }, MoreExecutors.directExecutor());
121 public ListenableFuture<RpcResult<AddKeystoreEntryOutput>> addKeystoreEntry(final AddKeystoreEntryInput input) {
122 LOG.debug("Adding keypairs: {}", input);
124 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
125 final List<KeyCredential> keypairs = input.nonnullKeyCredential().values().stream()
126 .map(keypair -> new KeyCredentialBuilder(keypair)
127 .setPrivateKey(encryptionService.encrypt(keypair.getPrivateKey()))
128 .setPassphrase(encryptionService.encrypt(keypair.getPassphrase()))
130 .collect(Collectors.toList());
132 for (KeyCredential keypair : keypairs) {
133 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
134 keystoreIid.child(KeyCredential.class, keypair.key()), keypair);
137 final SettableFuture<RpcResult<AddKeystoreEntryOutput>> rpcResult = SettableFuture.create();
139 writeTransaction.commit().addCallback(new FutureCallback<CommitInfo>() {
141 public void onSuccess(final CommitInfo result) {
142 LOG.debug("add-key-pair success. Input: {}", input);
143 rpcResult.set(RpcResultBuilder.success(new AddKeystoreEntryOutputBuilder().build()).build());
147 public void onFailure(final Throwable throwable) {
148 LOG.warn("add-key-pair failed. Input: {}", input, throwable);
149 rpcResult.setException(throwable);
151 }, MoreExecutors.directExecutor());
157 public ListenableFuture<RpcResult<AddTrustedCertificateOutput>> addTrustedCertificate(
158 final AddTrustedCertificateInput input) {
159 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
161 for (TrustedCertificate certificate : input.nonnullTrustedCertificate().values()) {
162 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
163 keystoreIid.child(TrustedCertificate.class, certificate.key()), certificate);
166 final SettableFuture<RpcResult<AddTrustedCertificateOutput>> rpcResult = SettableFuture.create();
168 writeTransaction.commit().addCallback(new FutureCallback<CommitInfo>() {
170 public void onSuccess(final CommitInfo result) {
171 LOG.debug("add-trusted-certificate success. Input: {}", input);
172 rpcResult.set(RpcResultBuilder.success(new AddTrustedCertificateOutputBuilder().build()).build());
176 public void onFailure(final Throwable throwable) {
177 LOG.warn("add-trusted-certificate failed. Input: {}", input, throwable);
178 rpcResult.setException(throwable);
180 }, MoreExecutors.directExecutor());
186 public ListenableFuture<RpcResult<RemoveTrustedCertificateOutput>> removeTrustedCertificate(
187 final RemoveTrustedCertificateInput input) {
188 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
190 for (final String name : input.getName()) {
191 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
192 keystoreIid.child(TrustedCertificate.class, new TrustedCertificateKey(name)));
195 final SettableFuture<RpcResult<RemoveTrustedCertificateOutput>> rpcResult = SettableFuture.create();
197 writeTransaction.commit().addCallback(new FutureCallback<CommitInfo>() {
199 public void onSuccess(final CommitInfo result) {
200 LOG.debug("remove-trusted-certificate success. Input: {}", input);
201 rpcResult.set(RpcResultBuilder.success(new RemoveTrustedCertificateOutputBuilder().build()).build());
205 public void onFailure(final Throwable throwable) {
206 LOG.warn("remove-trusted-certificate failed. Input: {}", input, throwable);
207 rpcResult.setException(throwable);
209 }, MoreExecutors.directExecutor());
215 public ListenableFuture<RpcResult<AddPrivateKeyOutput>> addPrivateKey(final AddPrivateKeyInput input) {
216 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
218 for (PrivateKey key: input.nonnullPrivateKey().values()) {
219 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
220 keystoreIid.child(PrivateKey.class, key.key()), key);
223 final SettableFuture<RpcResult<AddPrivateKeyOutput>> rpcResult = SettableFuture.create();
225 writeTransaction.commit().addCallback(new FutureCallback<CommitInfo>() {
227 public void onSuccess(final CommitInfo result) {
228 LOG.debug("add-private-key success. Input: {}", input);
229 rpcResult.set(RpcResultBuilder.success(new AddPrivateKeyOutputBuilder().build()).build());
233 public void onFailure(final Throwable throwable) {
234 LOG.warn("add-private-key failed. Input: {}", input, throwable);
235 rpcResult.setException(throwable);
237 }, MoreExecutors.directExecutor());
243 public ListenableFuture<RpcResult<RemovePrivateKeyOutput>> removePrivateKey(final RemovePrivateKeyInput input) {
244 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
246 for (final String name : input.getName()) {
247 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
248 keystoreIid.child(PrivateKey.class, new PrivateKeyKey(name)));
251 final SettableFuture<RpcResult<RemovePrivateKeyOutput>> rpcResult = SettableFuture.create();
253 writeTransaction.commit().addCallback(new FutureCallback<CommitInfo>() {
255 public void onSuccess(final CommitInfo result) {
256 LOG.debug("remove-private-key success. Input: {}", input);
257 rpcResult.set(RpcResultBuilder.success(new RemovePrivateKeyOutputBuilder().build()).build());
261 public void onFailure(final Throwable throwable) {
262 LOG.warn("remove-private-key failed. Input: {}", input, throwable);
263 rpcResult.setException(throwable);
265 }, MoreExecutors.directExecutor());