Enforce base64 encoding for netconf-keystore 96/108896/22
authorOleksandr Zharov <oleksandr.zharov@pantheon.tech>
Thu, 9 Nov 2023 16:59:01 +0000 (17:59 +0100)
committerIvan Hrasko <ivan.hrasko@pantheon.tech>
Tue, 6 Feb 2024 13:52:15 +0000 (13:52 +0000)
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 <oleksandr.zharov@pantheon.tech>
15 files changed:
apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeMountTlsAuthProvider.java
apps/netconf-topology-singleton/src/test/java/org/opendaylight/netconf/topology/singleton/impl/MountPointEndToEndTest.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/ConfigListener.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddKeystoreEntry.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddPrivateKey.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultAddTrustedCertificate.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultNetconfKeystoreService.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveKeystoreEntry.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemovePrivateKey.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/DefaultRemoveTrustedCertificate.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/impl/RpcSingleton.java
keystore/keystore-legacy/src/main/java/org/opendaylight/netconf/keystore/legacy/package-info.java
keystore/keystore-legacy/src/main/yang/netconf-keystore.yang
keystore/keystore-legacy/src/test/java/org/opendaylight/netconf/keystore/legacy/impl/NetconfKeystoreRpcsTest.java
plugins/netconf-client-mdsal/src/test/java/org/opendaylight/netconf/client/mdsal/impl/DefaultSslContextFactoryProviderTest.java

index 1a2d469b1e62a997bdb8103fcebb58c2f975c1be..b18c47788e05e1f9e5a269d3079a0eff7861d67e 100644 (file)
@@ -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 {
index fcadab47e1d5aa6a0e5ceb7a1df009a633152b3e..cbc5839beb7742eb51333349b51b1bf83120f5ec 100644 (file)
@@ -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;
index f6972812671be8444e4b644c2dc4f5536f7c548b..3314b18233f0235af092788516c543da427b04c4 100644 (file)
@@ -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;
 
index d40e02a258d7f190067dcb8b87c96c93d340cc6d..93d8dcc2d9a98a415b99f91962ef6854b2288516 100644 (file)
@@ -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
index f3dfc18611bbaa52bfe151be7f57985da59a1aa2..6d0c56a83e83561093ba94c4a5b97238d4cffa36 100644 (file)
@@ -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 -> {
index 2e433369ccbc3d5f3a0e266203d30b601b85bf37..f4c23cbf3e01854302e6b4d5f5f899405ec3c484 100644 (file)
@@ -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 -> {
index b7632b702b7239a52623abc0101e201339f26216..a5ae834e1f7ead8012f8f6ca65b4e088326fc178 100644 (file)
@@ -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);
index b7b1bba8c1c3efeac6f9cfa5c5f74311b23601b0..02f103e8c4462fbe7a2873cb571659776bd83398 100644 (file)
@@ -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;
index 7d3e7d6557744b242197e57c9dcdf2f1eb7311cf..2c6abebd97e1133a5aee685eb66f69e2df41865e 100644 (file)
@@ -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;
index 292fb19cada7885d3b3f6ab5813deede1ab8dc15..57650645372a8fb1fd2547145ec5a3e602b70537 100644 (file)
@@ -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;
index 08b1079d3d43aa2c2f800372befcab70ae625a0f..39168c3c43a83a05ffee85870e87c64d6a81935d 100644 (file)
@@ -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;
index 8ed81de1b86335fc4f3ba5e0b1a63d240b910916..4d244657e7b0c52317eccad41fa595856165de2f 100644 (file)
@@ -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}.
  */
index 5494ebe43e7fd43d15e975a087a0e1cb29799b23..0846034a2eaf9a20e60c109af41b2d08915fe994 100644 (file)
@@ -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;
         }
     }
 
index 1b1e845da86bbf8cea99fa967995bab2c60c5826..358ff59342bf51723600acec44159716525ca0d8 100644 (file)
@@ -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;
index e42e451f0d13279df49286d9613f4c435fc520f9..98a0a2dc7f0272a86a1fee9be4939bce962a43a5 100644 (file)
@@ -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<String>();
+                final var certChain = new ArrayList<byte[]>();
                 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))