From: LiGuosheng
Date: Tue, 30 Jan 2018 09:35:11 +0000 (+0800)
Subject: jira NETCONF-489 Add TLS support for connecting to a netconf device
X-Git-Tag: release/oxygen~17
X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=0aa5fcbdb5cc193fee432a3320d9839595363e74;p=netconf.git
jira NETCONF-489 Add TLS support for connecting to a netconf device
The X.509 certificate yang model definition and rpc implementation.
Change-Id: Ic125707f80a23f21e183fa732adfb0083f853bca
Signed-off-by: Li guosheng
---
diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/util/NetconfSalKeystoreService.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/util/NetconfSalKeystoreService.java
index 7cb9216a57..88d8efddee 100644
--- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/util/NetconfSalKeystoreService.java
+++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/util/NetconfSalKeystoreService.java
@@ -23,13 +23,21 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.KeystoreBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.NetconfKeystoreService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKeyKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
@@ -140,4 +148,126 @@ public class NetconfSalKeystoreService implements NetconfKeystoreService {
return rpcResult;
}
+
+ @Override
+ public Future> addTrustedCertificate(AddTrustedCertificateInput input) {
+ final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+
+ for (TrustedCertificate certificate : input.getTrustedCertificate()) {
+ writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
+ keystoreIid.child(TrustedCertificate.class, certificate.getKey()), certificate);
+ }
+
+ final SettableFuture> rpcResult = SettableFuture.create();
+
+ final CheckedFuture submit = writeTransaction.submit();
+ Futures.addCallback(submit, new FutureCallback() {
+ @Override
+ public void onSuccess(@Nullable Void result) {
+ LOG.debug("add-trusted-certificate success. Input: {}", input);
+ final RpcResult success = RpcResultBuilder.success().build();
+ rpcResult.set(success);
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("add-trusted-certificate failed. Input: {}", input, throwable);
+ rpcResult.setException(throwable);
+ }
+ }, MoreExecutors.directExecutor());
+
+ return rpcResult;
+ }
+
+ @Override
+ public Future> removeTrustedCertificate(RemoveTrustedCertificateInput input) {
+ final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+ final List names = input.getName();
+
+ for (final String name : names) {
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
+ keystoreIid.child(TrustedCertificate.class, new TrustedCertificateKey(name)));
+ }
+
+ final SettableFuture> rpcResult = SettableFuture.create();
+
+ final CheckedFuture submit = writeTransaction.submit();
+ Futures.addCallback(submit, new FutureCallback() {
+ @Override
+ public void onSuccess(@Nullable Void result) {
+ LOG.debug("remove-trusted-certificate success. Input: {}", input);
+ final RpcResult success = RpcResultBuilder.success().build();
+ rpcResult.set(success);
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("remove-trusted-certificate failed. Input: {}", input, throwable);
+ rpcResult.setException(throwable);
+ }
+ }, MoreExecutors.directExecutor());
+
+ return rpcResult;
+ }
+
+ @Override
+ public Future> addPrivateKey(AddPrivateKeyInput input) {
+ final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+
+ for (PrivateKey key: input.getPrivateKey()) {
+ writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
+ keystoreIid.child(PrivateKey.class, key.getKey()), key);
+ }
+
+ final SettableFuture> rpcResult = SettableFuture.create();
+
+ final CheckedFuture submit = writeTransaction.submit();
+ Futures.addCallback(submit, new FutureCallback() {
+ @Override
+ public void onSuccess(@Nullable Void result) {
+ LOG.debug("add-private-key success. Input: {}", input);
+ final RpcResult success = RpcResultBuilder.success().build();
+ rpcResult.set(success);
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("add-private-key failed. Input: {}", input, throwable);
+ rpcResult.setException(throwable);
+ }
+ }, MoreExecutors.directExecutor());
+
+ return rpcResult;
+ }
+
+ @Override
+ public Future> removePrivateKey(RemovePrivateKeyInput input) {
+ final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
+ final List names = input.getName();
+
+ for (final String name : names) {
+ writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
+ keystoreIid.child(PrivateKey.class, new PrivateKeyKey(name)));
+ }
+
+ final SettableFuture> rpcResult = SettableFuture.create();
+
+ final CheckedFuture submit = writeTransaction.submit();
+ Futures.addCallback(submit, new FutureCallback() {
+ @Override
+ public void onSuccess(@Nullable Void result) {
+ LOG.debug("remove-private-key success. Input: {}", input);
+ final RpcResult success = RpcResultBuilder.success().build();
+ rpcResult.set(success);
+ }
+
+ @Override
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("remove-private-key failed. Input: {}", input, throwable);
+ rpcResult.setException(throwable);
+ }
+ }, MoreExecutors.directExecutor());
+
+ return rpcResult;
+ }
}
diff --git a/netconf/sal-netconf-connector/src/main/yang/netconf-keystore.yang b/netconf/sal-netconf-connector/src/main/yang/netconf-keystore.yang
index d3da9f4306..dba3b35ba5 100644
--- a/netconf/sal-netconf-connector/src/main/yang/netconf-keystore.yang
+++ b/netconf/sal-netconf-connector/src/main/yang/netconf-keystore.yang
@@ -37,8 +37,45 @@ module netconf-keystore {
}
}
+ grouping private-keys {
+ list private-key {
+ key name;
+ description "A private key.";
+ leaf name {
+ type string;
+ }
+ leaf data {
+ description "Base64 encoded private key.";
+ type string;
+ }
+ leaf-list certificate-chain {
+ description "A certificate chain for this public key. Each certificate is an X.509 v3 certificate
+ structure as specified by RFC5280, encoded using the Base64 format.";
+ type string;
+ }
+ }
+ }
+
+ grouping trusted-certificates {
+ list trusted-certificate {
+ key name;
+ description "A list of trusted certificate. These cerfitifcates can be used by a server to
+ authenticate clients, or by clients to authenticate servers.";
+ leaf name {
+ type string;
+ }
+ leaf certificate {
+ description "An X.509 v3 certificate structure as specified by RFC5280, encoded using
+ the Base64 format.";
+ type string;
+ }
+ }
+ }
+
container keystore {
uses keystore-entry;
+ uses private-keys;
+ uses trusted-certificates;
}
rpc add-keystore-entry {
@@ -57,4 +94,36 @@ module netconf-keystore {
}
}
}
+
+ rpc add-private-key {
+ description "Add a list of private keys into the keystore.";
+ input {
+ uses private-keys;
+ }
+ }
+
+ rpc remove-private-key {
+ description "Remove a list of private keys from the datastore.";
+ input {
+ leaf-list name {
+ type string;
+ }
+ }
+ }
+
+ rpc add-trusted-certificate {
+ description "Add a list of trusted certificates into the keystore.";
+ input {
+ uses trusted-certificates;
+ }
+ }
+
+ rpc remove-trusted-certificate {
+ description "Remove a list of trusted certificates from the datastore.";
+ input {
+ leaf-list name {
+ type string;
+ }
+ }
+ }
}
\ No newline at end of file