From bfdd73eb11d1f69c7bd484d564bc8e6abf4e07fe Mon Sep 17 00:00:00 2001 From: Oleksandr Zharov Date: Thu, 9 Nov 2023 17:59:01 +0100 Subject: [PATCH] Enforce base64 encoding for netconf-keystore Changed type to binary for all leafs that are claiming their type as base64. We are no more reusing groupings for RPC. Purpose of it is to left all RPC logic untouched by this patch. JIRA: NETCONF-1186 Change-Id: I870427af766c55a5e65b336046e64f048c2b7fdd Signed-off-by: Oleksandr Zharov --- .../CallHomeMountTlsAuthProvider.java | 1 - .../impl/MountPointEndToEndTest.java | 2 +- .../keystore/legacy/impl/ConfigListener.java | 8 +- .../legacy/impl/DefaultAddKeystoreEntry.java | 25 +++--- .../legacy/impl/DefaultAddPrivateKey.java | 23 ++++-- .../impl/DefaultAddTrustedCertificate.java | 23 ++++-- .../impl/DefaultNetconfKeystoreService.java | 19 ++--- .../impl/DefaultRemoveKeystoreEntry.java | 14 ++-- .../legacy/impl/DefaultRemovePrivateKey.java | 14 ++-- .../impl/DefaultRemoveTrustedCertificate.java | 14 ++-- .../keystore/legacy/impl/RpcSingleton.java | 12 +-- .../netconf/keystore/legacy/package-info.java | 2 +- .../src/main/yang/netconf-keystore.yang | 79 +++++++++++++++++-- .../legacy/impl/NetconfKeystoreRpcsTest.java | 20 ++--- .../DefaultSslContextFactoryProviderTest.java | 25 +++--- 15 files changed, 182 insertions(+), 99 deletions(-) diff --git a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeMountTlsAuthProvider.java b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeMountTlsAuthProvider.java index 1a2d469b1e..b18c47788e 100644 --- a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeMountTlsAuthProvider.java +++ b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeMountTlsAuthProvider.java @@ -41,7 +41,6 @@ import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - @Component(service = CallHomeTlsAuthProvider.class, immediate = true) @Singleton public final class CallHomeMountTlsAuthProvider extends CallHomeTlsAuthProvider implements AutoCloseable { diff --git a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java index fcadab47e1..cbc5839beb 100644 --- a/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java +++ b/apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java @@ -110,7 +110,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.ConnectionOper.ConnectionStatus; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.credentials.credentials.LoginPwUnencryptedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.credentials.credentials.login.pw.unencrypted.LoginPasswordUnencryptedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev231121.NetconfNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev231121.NetconfNodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.GetTopInput; diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/ConfigListener.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/ConfigListener.java index f697281267..3314b18233 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/ConfigListener.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/ConfigListener.java @@ -15,10 +15,10 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.netconf.keystore.legacy.impl.DefaultNetconfKeystoreService.ConfigStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -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.keystore.entry.KeyCredential; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.keystore.entry.KeyCredential; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddKeystoreEntry.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddKeystoreEntry.java index d40e02a258..93d8dcc2d9 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddKeystoreEntry.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddKeystoreEntry.java @@ -18,13 +18,13 @@ import java.util.Base64; import org.opendaylight.aaa.encrypt.AAAEncryptionService; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -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.rev231109.AddKeystoreEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddKeystoreEntryInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddKeystoreEntryOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddKeystoreEntryOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.keystore.entry.KeyCredential; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.keystore.entry.KeyCredentialBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -54,9 +54,10 @@ final class DefaultAddKeystoreEntry extends AbstractRpc implements AddKeystoreEn for (var credential : plain.values()) { final var keyId = credential.getKeyId(); try { - encrypted.add(new KeyCredentialBuilder(credential) - .setPrivateKey(encryptString(credential.getPrivateKey())) - .setPassphrase(encryptString(credential.getPassphrase())) + encrypted.add(new KeyCredentialBuilder() + .setKeyId(credential.getKeyId()) + .setPrivateKey(encryptToBytes(credential.getPrivateKey())) + .setPassphrase(encryptToBytes(credential.getPassphrase())) .build()); } catch (GeneralSecurityException e) { LOG.debug("Cannot decrypt key credential {}}", credential, e); @@ -78,7 +79,7 @@ final class DefaultAddKeystoreEntry extends AbstractRpc implements AddKeystoreEn }, MoreExecutors.directExecutor()); } - private String encryptString(final String plain) throws GeneralSecurityException { - return Base64.getEncoder().encodeToString(encryptionService.encrypt(plain.getBytes(StandardCharsets.UTF_8))); + private byte[] encryptToBytes(final String plain) throws GeneralSecurityException { + return Base64.getEncoder().encode(encryptionService.encrypt(plain.getBytes(StandardCharsets.UTF_8))); } } \ No newline at end of file diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddPrivateKey.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddPrivateKey.java index f3dfc18611..6d0c56a83e 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddPrivateKey.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddPrivateKey.java @@ -9,14 +9,16 @@ package org.opendaylight.netconf.keystore.legacy.impl; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import java.nio.charset.StandardCharsets; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKeyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKeyOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKeyOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKeyBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; @@ -40,8 +42,15 @@ final class DefaultAddPrivateKey extends AbstractRpc implements AddPrivateKey { LOG.debug("Adding private keys: {}", keys); final var tx = newTransaction(); for (var key : keys.values()) { + final var base64key = new PrivateKeyBuilder() + .setName(key.getName()) + .setData(key.getData().getBytes(StandardCharsets.UTF_8)) + .setCertificateChain(key.getCertificateChain().stream() + .map(cert -> cert.getBytes(StandardCharsets.UTF_8)).toList()) + .build(); + tx.put(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.create(Keystore.class).child(PrivateKey.class, key.key()), key); + InstanceIdentifier.create(Keystore.class).child(PrivateKey.class, base64key.key()), base64key); } return tx.commit().transform(commitInfo -> { diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddTrustedCertificate.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddTrustedCertificate.java index 2e433369cc..f4c23cbf3e 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddTrustedCertificate.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddTrustedCertificate.java @@ -9,14 +9,16 @@ package org.opendaylight.netconf.keystore.legacy.impl; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import java.nio.charset.StandardCharsets; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificateInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificateOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificateOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificateBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; @@ -40,9 +42,14 @@ final class DefaultAddTrustedCertificate extends AbstractRpc implements AddTrust LOG.debug("Updating trusted certificates: {}", certs); final var tx = newTransaction(); for (var certificate : certs.values()) { + final var base64certificate = new TrustedCertificateBuilder() + .setName(certificate.getName()) + .setCertificate(certificate.getCertificate().getBytes(StandardCharsets.UTF_8)) + .build(); + tx.put(LogicalDatastoreType.CONFIGURATION, - InstanceIdentifier.create(Keystore.class).child(TrustedCertificate.class, certificate.key()), - certificate); + InstanceIdentifier.create(Keystore.class).child(TrustedCertificate.class, base64certificate.key()), + base64certificate); } return tx.commit().transform(commitInfo -> { diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultNetconfKeystoreService.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultNetconfKeystoreService.java index b7632b702b..a5ae834e1f 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultNetconfKeystoreService.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultNetconfKeystoreService.java @@ -39,10 +39,10 @@ import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider; import org.opendaylight.netconf.keystore.legacy.CertifiedPrivateKey; import org.opendaylight.netconf.keystore.legacy.NetconfKeystore; import org.opendaylight.netconf.keystore.legacy.NetconfKeystoreService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -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.keystore.entry.KeyCredential; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.keystore.entry.KeyCredential; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificate; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.concepts.Mutable; @@ -163,7 +163,7 @@ public final class DefaultNetconfKeystoreService implements NetconfKeystoreServi final byte[] keyBytes; try { - keyBytes = base64Decode(key.requireData()); + keyBytes = base64Decode(new String(key.requireData(), StandardCharsets.UTF_8)); } catch (IllegalArgumentException e) { LOG.debug("Failed to decode private key {}", keyName, e); failure = updateFailure(failure, e); @@ -191,7 +191,7 @@ public final class DefaultNetconfKeystoreService implements NetconfKeystoreServi for (int i = 0, size = certChain.size(); i < size; i++) { final byte[] bytes; try { - bytes = base64Decode(certChain.get(i)); + bytes = base64Decode(new String(certChain.get(i), StandardCharsets.UTF_8)); } catch (IllegalArgumentException e) { LOG.debug("Failed to decode certificate chain item {} for private key {}", i, keyName, e); failure = updateFailure(failure, e); @@ -219,7 +219,7 @@ public final class DefaultNetconfKeystoreService implements NetconfKeystoreServi final byte[] bytes; try { - bytes = base64Decode(cert.requireCertificate()); + bytes = base64Decode(new String(cert.requireCertificate(), StandardCharsets.UTF_8)); } catch (IllegalArgumentException e) { LOG.debug("Failed to decode trusted certificate {}", certName, e); failure = updateFailure(failure, e); @@ -243,7 +243,8 @@ public final class DefaultNetconfKeystoreService implements NetconfKeystoreServi final var keyId = cred.requireKeyId(); final String passPhrase; try { - passPhrase = decryptString(requireNonNullElse(cred.getPassphrase(), "")); + passPhrase = decryptString(requireNonNullElse(new String(cred.getPassphrase(), StandardCharsets.UTF_8), + "")); } catch (GeneralSecurityException e) { LOG.debug("Failed to decrypt pass phrase for {}", keyId, e); failure = updateFailure(failure, e); @@ -252,7 +253,7 @@ public final class DefaultNetconfKeystoreService implements NetconfKeystoreServi final String privateKey; try { - privateKey = decryptString(cred.getPrivateKey()); + privateKey = decryptString(new String(cred.getPrivateKey(), StandardCharsets.UTF_8)); } catch (GeneralSecurityException e) { LOG.debug("Failed to decrypt private key for {}", keyId, e); failure = updateFailure(failure, e); diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveKeystoreEntry.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveKeystoreEntry.java index b7b1bba8c1..02f103e8c4 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveKeystoreEntry.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveKeystoreEntry.java @@ -12,13 +12,13 @@ import com.google.common.util.concurrent.MoreExecutors; import java.util.stream.Collectors; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutputBuilder; -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.KeyCredentialKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveKeystoreEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveKeystoreEntryInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveKeystoreEntryOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveKeystoreEntryOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.keystore.entry.KeyCredential; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.keystore.entry.KeyCredentialKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemovePrivateKey.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemovePrivateKey.java index 7d3e7d6557..2c6abebd97 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemovePrivateKey.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemovePrivateKey.java @@ -12,13 +12,13 @@ import com.google.common.util.concurrent.MoreExecutors; import java.util.stream.Collectors; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutputBuilder; -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.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemovePrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemovePrivateKeyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemovePrivateKeyOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemovePrivateKeyOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKeyKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveTrustedCertificate.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveTrustedCertificate.java index 292fb19cad..5765064537 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveTrustedCertificate.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveTrustedCertificate.java @@ -12,13 +12,13 @@ import com.google.common.util.concurrent.MoreExecutors; import java.util.stream.Collectors; import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutputBuilder; -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.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveTrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveTrustedCertificateInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveTrustedCertificateOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveTrustedCertificateOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificateKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/RpcSingleton.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/RpcSingleton.java index 08b1079d3d..39168c3c43 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/RpcSingleton.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/RpcSingleton.java @@ -18,12 +18,12 @@ import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.singleton.api.ClusterSingletonService; import org.opendaylight.mdsal.singleton.api.ServiceGroupIdentifier; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddKeystoreEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveKeystoreEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemovePrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.RemoveTrustedCertificate; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.Rpc; import org.slf4j.Logger; diff --git a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/package-info.java b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/package-info.java index 8ed81de1b8..4d244657e7 100644 --- a/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/package-info.java +++ b/keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/package-info.java @@ -7,7 +7,7 @@ */ /** * Access to key and trust material stored in - * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.NetconfKeystoreData}. + * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.NetconfKeystoreData}. * The primary access interface is {@link NetconfKeystoreService}, which allows subscription to receive updates about * {@link NetconfKeystore}. */ diff --git a/keystore/keystore-legacy/src/main/yang/netconf-keystore.yang b/keystore/keystore-legacy/src/main/yang/netconf-keystore.yang index 5494ebe43e..0846034a2e 100644 --- a/keystore/keystore-legacy/src/main/yang/netconf-keystore.yang +++ b/keystore/keystore-legacy/src/main/yang/netconf-keystore.yang @@ -2,6 +2,10 @@ module netconf-keystore { namespace "urn:opendaylight:netconf:keystore"; prefix "keystore"; + revision "2023-11-09" { + description "Using binary type instead of string for base64 leafs."; + } + revision "2017-10-17" { description "Initial revision of the Netconf SBP keystore."; } @@ -12,6 +16,30 @@ module netconf-keystore { RPCs for adding/removing key entries."; grouping keystore-entry { + list key-credential { + key key-id; + + leaf key-id { + type string; + } + + leaf private-key { + description "Binary array of Base64 encoded private key that should be used for authentication with a + netconf device. Do not include a public key as that is calculated from the private key. + Used for writing directly into the data store, encrypted key expected."; + type binary; + } + + leaf passphrase { + description "If the provided key is encrypted by a passphrase this needs to be included. Leave empty + if the key does not have a passphrase. + Used for writing directly into the data store, encrypted passphrase expected."; + type binary; + } + } + } + + grouping rpc-keystore-entry { list key-credential { key key-id; @@ -22,22 +50,41 @@ module netconf-keystore { leaf private-key { description "Base64 encoded private key that should be used for authentication with a netconf device. Do not include a public key as that is calculated from the private key. - DO NOT write this directly into the data store, use the provided RPCs as these will - encrypt the key before the entry is written into the data store."; + Used for RPCs only. Will encrypt the key before the entry is written into the data store."; type string; } leaf passphrase { description "If the provided key is encrypted by a passphrase this needs to be included. Leave empty if the key does not have a passphrase. - DO NOT write write this directly into the data store, use the provided RPCs as these will - encrypt the passphrase before the entry is written into the data store."; + Used for RPCs only. Will encrypt the passphrase before the entry is written into the data + store."; type string; } } } grouping private-keys { + list private-key { + key name; + description "A private key."; + leaf name { + type string; + } + leaf data { + description "Binary array of Base64 encoded private key."; + type binary; + } + 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, binary data encoded using the Base64 format."; + type binary; + ordered-by user; + } + } + } + + grouping rpc-private-keys { list private-key { key name; description "A private key."; @@ -66,10 +113,26 @@ module netconf-keystore { type string; } leaf certificate { - description "An X.509 v3 certificate structure as specified by RFC5280, encoded using + description "An X.509 v3 certificate structure as specified by RFC5280, binary data encoded using the Base64 format."; + type binary; + } + } + } + + grouping rpc-trusted-certificates { + list trusted-certificate { + key name; + description "A list of trusted certificate. These certificates 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; + } } } @@ -83,7 +146,7 @@ module netconf-keystore { description "Use this rpc to add a single or multiple new keys into the keystore. The private key and passphrase will both be encrypted before they are written into the data store."; input { - uses keystore-entry; + uses rpc-keystore-entry; } } @@ -99,7 +162,7 @@ module netconf-keystore { rpc add-private-key { description "Add a list of private keys into the keystore."; input { - uses private-keys; + uses rpc-private-keys; } } @@ -115,7 +178,7 @@ module netconf-keystore { rpc add-trusted-certificate { description "Add a list of trusted certificates into the keystore."; input { - uses trusted-certificates; + uses rpc-trusted-certificates; } } diff --git a/keystore/keystore-legacy/src/test/java/org/opendaylight/netconf/keystore/legacy/impl/NetconfKeystoreRpcsTest.java b/keystore/keystore-legacy/src/test/java/org/opendaylight/netconf/keystore/legacy/impl/NetconfKeystoreRpcsTest.java index 1b1e845da8..358ff59342 100644 --- a/keystore/keystore-legacy/src/test/java/org/opendaylight/netconf/keystore/legacy/impl/NetconfKeystoreRpcsTest.java +++ b/keystore/keystore-legacy/src/test/java/org/opendaylight/netconf/keystore/legacy/impl/NetconfKeystoreRpcsTest.java @@ -27,16 +27,16 @@ import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.binding.api.WriteTransaction; import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.netconf.api.xml.XmlUtil; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInputBuilder; -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.PrivateKeyBuilder; -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.trusted.certificates.TrustedCertificate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKeyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddPrivateKeyInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificateInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.AddTrustedCertificateInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.rpc._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.rpc._private.keys.PrivateKeyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.rpc._private.keys.PrivateKeyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.rpc.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.rpc.trusted.certificates.TrustedCertificateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.rpc.trusted.certificates.TrustedCertificateKey; import org.opendaylight.yangtools.concepts.ObjectRegistration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; diff --git a/plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultSslContextFactoryProviderTest.java b/plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultSslContextFactoryProviderTest.java index e42e451f0d..98a0a2dc7f 100644 --- a/plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultSslContextFactoryProviderTest.java +++ b/plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultSslContextFactoryProviderTest.java @@ -15,6 +15,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; +import java.nio.charset.StandardCharsets; import java.security.KeyStoreException; import java.util.ArrayList; import java.util.List; @@ -34,13 +35,13 @@ import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider; import org.opendaylight.netconf.api.xml.XmlUtil; import org.opendaylight.netconf.keystore.legacy.impl.DefaultNetconfKeystoreService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore; -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.PrivateKeyBuilder; -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.trusted.certificates.TrustedCertificate; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.Keystore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKeyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109._private.keys.PrivateKeyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev231109.trusted.certificates.TrustedCertificateKey; import org.opendaylight.yangtools.concepts.Registration; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -166,12 +167,13 @@ class DefaultSslContextFactoryProviderTest { for (int i = 0; i < nodeList.getLength(); i++) { if (nodeList.item(i) instanceof Element element) { final var keyName = element.getElementsByTagName(XML_ELEMENT_NAME).item(0).getTextContent(); - final var keyData = element.getElementsByTagName(XML_ELEMENT_DATA).item(0).getTextContent(); + final var keyData = element.getElementsByTagName(XML_ELEMENT_DATA).item(0).getTextContent() + .getBytes(StandardCharsets.UTF_8); final var certNodes = element.getElementsByTagName(XML_ELEMENT_CERT_CHAIN); - final var certChain = new ArrayList(); + final var certChain = new ArrayList(); for (int j = 0; j < certNodes.getLength(); j++) { if (certNodes.item(j) instanceof Element certNode) { - certChain.add(certNode.getTextContent()); + certChain.add(certNode.getTextContent().getBytes(StandardCharsets.UTF_8)); } } @@ -194,7 +196,8 @@ class DefaultSslContextFactoryProviderTest { for (int i = 0; i < nodeList.getLength(); i++) { if (nodeList.item(i) instanceof Element element) { final var certName = element.getElementsByTagName(XML_ELEMENT_NAME).item(0).getTextContent(); - final var certData = element.getElementsByTagName(XML_ELEMENT_CERT).item(0).getTextContent(); + final var certData = element.getElementsByTagName(XML_ELEMENT_CERT).item(0).getTextContent() + .getBytes(StandardCharsets.UTF_8); trustedCertificates.add(new TrustedCertificateBuilder() .withKey(new TrustedCertificateKey(certName)) -- 2.36.6