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