Add transport-tls 00/102300/63
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 7 Sep 2022 09:48:51 +0000 (11:48 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 11 Apr 2023 22:14:29 +0000 (22:14 +0000)
Add NETCONF transport implementation based on TCP+TLS.

JIRA: NETCONF-590
Change-Id: I5e0d6ddce30971dd5f2b0918600b9410aa439c08
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
22 files changed:
artifacts/pom.xml
transport/pom.xml
transport/transport-tls/pom.xml [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/ConfigUtils.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsClientFeatureProvider.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsCommonFeatureProvider.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsServerFeatureProvider.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/KeyStoreUtils.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/KeyUtils.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/SSLEngineFactory.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSClient.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSServer.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSTransportChannel.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSTransportStack.java [new file with mode: 0644]
transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/package-info.java [new file with mode: 0644]
transport/transport-tls/src/main/yang/iana-tls-cipher-suite-algs@2022-06-16.yang [new file with mode: 0644]
transport/transport-tls/src/main/yang/ietf-tls-client@2022-12-12.yang [new file with mode: 0644]
transport/transport-tls/src/main/yang/ietf-tls-common@2022-12-12.yang [new file with mode: 0644]
transport/transport-tls/src/main/yang/ietf-tls-server@2022-12-12.yang [new file with mode: 0644]
transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/ConfigUtilsTest.java [new file with mode: 0644]
transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/TestUtils.java [new file with mode: 0644]
transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/TlsClientServerTest.java [new file with mode: 0644]

index b3f74728968d3da9ac597484f4541a34c0bb5d12..7640af80e5a319e22601dd17367041ed803cee79 100644 (file)
                 <artifactId>transport-tcp</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.netconf</groupId>
+                <artifactId>transport-tls</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- YANG models -->
             <!-- RFC5277 NETCONF Event Notifications -->
index 26bead3f4cba93c818d2d0b279c76c527b4615a6..c5cd53988fbe1930a20b15074bdada05d324cf2e 100644 (file)
@@ -31,5 +31,6 @@
     <modules>
         <module>transport-api</module>
         <module>transport-tcp</module>
+        <module>transport-tls</module>
     </modules>
 </project>
diff --git a/transport/transport-tls/pom.xml b/transport/transport-tls/pom.xml
new file mode 100644 (file)
index 0000000..93644d3
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.netconf</groupId>
+        <artifactId>netconf-parent</artifactId>
+        <version>5.0.4-SNAPSHOT</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>transport-tls</artifactId>
+    <name>${project.artifactId}</name>
+    <packaging>bundle</packaging>
+    <description>NETCONF TLS transport</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-handler</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kohsuke.metainf-services</groupId>
+            <artifactId>metainf-services</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>keystore-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>transport-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>transport-tcp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.netconf</groupId>
+            <artifactId>truststore-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+        </dependency>
+        <!-- testing -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk18on</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport-native-epoll</artifactId>
+            <classifier>linux-x86_64</classifier>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/ConfigUtils.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/ConfigUtils.java
new file mode 100644 (file)
index 0000000..78c4255
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import static org.opendaylight.netconf.transport.tls.KeyStoreUtils.buildX509Certificate;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.EC_ALGORITHM;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.RSA_ALGORITHM;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.buildPrivateKey;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.buildPublicKeyFromSshEncoding;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.buildX509PublicKey;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.validateKeyPair;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.validatePublicKey;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.AsymmetricKeyPairGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.EcPrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.RsaPrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.SshPublicKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.SubjectPublicKeyInfoFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.asymmetric.key.pair.grouping._private.key.type.CleartextPrivateKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212.LocalOrKeystoreAsymmetricKeyGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212.LocalOrKeystoreEndEntityCertWithKeyGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212.LocalOrTruststoreCertsGrouping;
+
+final class ConfigUtils {
+
+    static final char[] EMPTY_SECRET = new char[0];
+    static final String DEFAULT_PRIVATE_KEY_ALIAS = "private";
+    static final String DEFAULT_CERTIFICATE_ALIAS = "certificate";
+
+    private ConfigUtils() {
+        // utility class
+    }
+
+    /**
+     * Builds X.509 certificates based on configuration data provided then sets them to given key store.
+     *
+     * @param keyStore key store
+     * @param caCerts CA certificates configuration
+     * @param eeCerts EE certificates configuration
+     * @throws UnsupportedConfigurationException if error occurs
+     */
+    static void setX509Certificates(final @NonNull KeyStore keyStore,
+            final @Nullable LocalOrTruststoreCertsGrouping caCerts,
+            final @Nullable LocalOrTruststoreCertsGrouping eeCerts) throws UnsupportedConfigurationException {
+        var certMap = ImmutableMap.<String, Certificate>builder()
+                .putAll(extractCertificates(caCerts, "ca-"))
+                .putAll(extractCertificates(eeCerts, "ee-")).build();
+        for (var entry : certMap.entrySet()) {
+            try {
+                keyStore.setCertificateEntry(entry.getKey(), entry.getValue());
+            } catch (KeyStoreException e) {
+                throw new UnsupportedConfigurationException("Failed to load certificate", e);
+            }
+        }
+    }
+
+    private static Map<String, Certificate> extractCertificates(
+            @Nullable final LocalOrTruststoreCertsGrouping certs,
+            @NonNull final String aliasPrefix) throws UnsupportedConfigurationException {
+        if (certs == null) {
+            return Map.of();
+        }
+        final var local = ofType(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore
+                        .rev221212.local.or.truststore.certs.grouping.local.or.truststore.Local.class,
+                certs.getLocalOrTruststore());
+        final var localDef = local.getLocalDefinition();
+        if (localDef == null) {
+            throw new UnsupportedConfigurationException("Missing local definition in " + local);
+        }
+        final var mapBuilder = ImmutableMap.<String, Certificate>builder();
+        for (var cert : localDef.nonnullCertificate().values()) {
+            try {
+                final var alias = aliasPrefix + cert.requireName();
+                mapBuilder.put(alias, buildX509Certificate(cert.requireCertData().getValue()));
+            } catch (IOException | CertificateException e) {
+                throw new UnsupportedConfigurationException("Failed to parse certificate " + cert, e);
+            }
+        }
+        return mapBuilder.build();
+    }
+
+    /**
+     * Builds asymmetric key pair from configuration data provided, validates it then puts into given key store.
+     *
+     * @param keyStore keystore
+     * @param input configuration
+     * @throws UnsupportedConfigurationException if key pair is not set to key store
+     */
+    static void setAsymmetricKey(final @NonNull KeyStore keyStore,
+            final @NonNull LocalOrKeystoreAsymmetricKeyGrouping input)
+            throws UnsupportedConfigurationException {
+
+        final var local = ofType(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212
+                        .local.or.keystore.asymmetric.key.grouping.local.or.keystore.Local.class,
+                input.getLocalOrKeystore());
+        final var localDef = local.getLocalDefinition();
+        if (localDef == null) {
+            throw new UnsupportedConfigurationException("Missing local definition in " + local);
+        }
+        final var keyPair = extractKeyPair(localDef);
+        /*
+            ietf-crypto-types:grouping asymmetric-key-pair-grouping
+            "A private key and its associated public key.  Implementations
+            SHOULD ensure that the two keys are a matching pair."
+         */
+        validateKeyPair(keyPair.getPublic(), keyPair.getPrivate());
+        try {
+            // FIXME
+            // below line throws an exception bc keyStore does not support private key without certificate chain
+            // (belongs to implementation of raw public key feature support)
+            keyStore.setKeyEntry(DEFAULT_PRIVATE_KEY_ALIAS, keyPair.getPrivate(), EMPTY_SECRET, null);
+        } catch (KeyStoreException e) {
+            throw new UnsupportedConfigurationException("Failed to load private key", e);
+        }
+    }
+
+    /**
+     * Builds asymmetric key pair and associated certificate from configuration data provided, validates
+     * then puts into given key store.
+     *
+     * @param keyStore key store
+     * @param input configuration
+     * @throws UnsupportedConfigurationException if key pair and certificate are not set to key store
+     */
+    static void setEndEntityCertificateWithKey(final @NonNull KeyStore keyStore,
+            final @NonNull LocalOrKeystoreEndEntityCertWithKeyGrouping input) throws UnsupportedConfigurationException {
+        final var local = ofType(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212
+                        .local.or.keystore.end.entity.cert.with.key.grouping.local.or.keystore.Local.class,
+                input.getLocalOrKeystore());
+        final var localDef = local.getLocalDefinition();
+        if (localDef == null) {
+            throw new UnsupportedConfigurationException("Missing local definition in " + local);
+        }
+        final var keyPair = extractKeyPair(localDef);
+        final Certificate certificate;
+        try {
+            certificate = buildX509Certificate(localDef.requireCertData().getValue());
+        } catch (IOException | CertificateException e) {
+            throw new UnsupportedConfigurationException("Failed to load certificate" + localDef, e);
+        }
+        /*
+          ietf-crypto-types:asymmetric-key-pair-with-cert-grouping
+          "A private/public key pair and an associated certificate.
+          Implementations SHOULD assert that certificates contain the matching public key."
+         */
+        validateKeyPair(keyPair.getPublic(), keyPair.getPrivate());
+        validatePublicKey(keyPair.getPublic(), certificate);
+        try {
+            keyStore.setCertificateEntry(DEFAULT_CERTIFICATE_ALIAS, certificate);
+            keyStore.setKeyEntry(DEFAULT_PRIVATE_KEY_ALIAS, keyPair.getPrivate(),
+                    EMPTY_SECRET, new Certificate[]{certificate});
+        } catch (KeyStoreException e) {
+            throw new UnsupportedConfigurationException("Failed to load certificate and/or private key", e);
+        }
+    }
+
+    private static KeyPair extractKeyPair(final AsymmetricKeyPairGrouping input)
+            throws UnsupportedConfigurationException {
+
+        final var privateKeyFormat = input.getPrivateKeyFormat();
+        final String keyAlgorithm;
+        if (EcPrivateKeyFormat.VALUE.equals(privateKeyFormat)) {
+            keyAlgorithm = EC_ALGORITHM;
+        } else if (RsaPrivateKeyFormat.VALUE.equals(privateKeyFormat)) {
+            keyAlgorithm = RSA_ALGORITHM;
+        } else {
+            throw new UnsupportedConfigurationException("Unsupported private key format " + privateKeyFormat);
+        }
+        final byte[] privateKeyBytes;
+        if (input.getPrivateKeyType() instanceof CleartextPrivateKey clearText) {
+            privateKeyBytes = clearText.requireCleartextPrivateKey();
+        } else {
+            throw new UnsupportedConfigurationException("Unsupported private key type " + input.getPrivateKeyType());
+        }
+        final var privateKey = buildPrivateKey(keyAlgorithm, privateKeyBytes);
+
+        final var publicKeyFormat = input.getPublicKeyFormat();
+        final boolean isSshPublicKey;
+        if (SubjectPublicKeyInfoFormat.VALUE.equals(publicKeyFormat)) {
+            isSshPublicKey = false;
+        } else if (SshPublicKeyFormat.VALUE.equals(publicKeyFormat)) {
+            isSshPublicKey = true;
+        } else {
+            throw new UnsupportedConfigurationException("Unsupported public key format " + publicKeyFormat);
+        }
+        final var publicKey = isSshPublicKey ? buildPublicKeyFromSshEncoding(input.getPublicKey())
+                : buildX509PublicKey(keyAlgorithm, input.getPublicKey());
+        return new KeyPair(publicKey, privateKey);
+    }
+
+    private static <T> T ofType(final Class<T> expectedType, final Object obj)
+            throws UnsupportedConfigurationException {
+        if (!expectedType.isInstance(obj)) {
+            throw new UnsupportedConfigurationException("Expected type: " + expectedType
+                    + " actual: " + obj.getClass());
+        }
+        return expectedType.cast(obj);
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsClientFeatureProvider.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsClientFeatureProvider.java
new file mode 100644 (file)
index 0000000..21e1bef
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.ClientIdentX509Cert;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.IetfTlsClientData;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.ServerAuthX509Cert;
+import org.opendaylight.yangtools.yang.binding.YangFeature;
+import org.opendaylight.yangtools.yang.binding.YangFeatureProvider;
+
+/**
+ * Baseline features supported from {@code ietf-tls-client.yang}.
+ */
+@MetaInfServices
+@NonNullByDefault
+public final class IetfTlsClientFeatureProvider implements YangFeatureProvider<IetfTlsClientData> {
+    @Override
+    public Class<IetfTlsClientData> boundModule() {
+        return IetfTlsClientData.class;
+    }
+
+    @Override
+    public Set<? extends YangFeature<?, IetfTlsClientData>> supportedFeatures() {
+        // FIXME: tls-client-keepalives
+        // FIXME: client-ident-raw-public-key
+        // FIXME: client-ident-tls13-epsk
+        // FIXME: server-auth-raw-public-key
+        // FIXME: server-auth-tls13-epsk
+        return Set.of(ClientIdentX509Cert.VALUE, ServerAuthX509Cert.VALUE);
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsCommonFeatureProvider.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsCommonFeatureProvider.java
new file mode 100644 (file)
index 0000000..604877d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.HelloParams;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.IetfTlsCommonData;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.Tls12$F;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.Tls12$I;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.Tls13$F;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.Tls13$I;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.TlsVersionBase;
+import org.opendaylight.yangtools.yang.binding.YangFeature;
+import org.opendaylight.yangtools.yang.binding.YangFeatureProvider;
+
+/**
+ * Baseline features supported from {@code ietf-tls-common.yang}.
+ */
+@MetaInfServices
+@NonNullByDefault
+public final class IetfTlsCommonFeatureProvider implements YangFeatureProvider<IetfTlsCommonData> {
+    private static final Map<TlsVersionBase, String> TLS_VERSIONS =
+        Map.of(Tls12$I.VALUE, "TLSv1.2", Tls13$I.VALUE, "TLSv1.3");
+
+    @Override
+    public Class<IetfTlsCommonData> boundModule() {
+        return IetfTlsCommonData.class;
+    }
+
+    @Override
+    public Set<? extends YangFeature<?, IetfTlsCommonData>> supportedFeatures() {
+        // Note: do not advertize TLS versions not present in TLS_VERSIONS!
+        return Set.of(HelloParams.VALUE, Tls12$F.VALUE, Tls13$F.VALUE);
+    }
+
+    static @Nullable String algorithmNameOf(final TlsVersionBase version) {
+        return TLS_VERSIONS.get(version);
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsServerFeatureProvider.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/IetfTlsServerFeatureProvider.java
new file mode 100644 (file)
index 0000000..d29068b
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.ClientAuthSupported;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.ClientAuthX509Cert;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.IetfTlsServerData;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.ServerIdentX509Cert;
+import org.opendaylight.yangtools.yang.binding.YangFeature;
+import org.opendaylight.yangtools.yang.binding.YangFeatureProvider;
+
+/**
+ * Baseline features supported from {@code ietf-tls-server.yang}.
+ */
+@MetaInfServices
+@NonNullByDefault
+public final class IetfTlsServerFeatureProvider implements YangFeatureProvider<IetfTlsServerData> {
+    @Override
+    public Class<IetfTlsServerData> boundModule() {
+        return IetfTlsServerData.class;
+    }
+
+    @Override
+    public Set<? extends YangFeature<?, IetfTlsServerData>> supportedFeatures() {
+        // FIXME: tls-server-keepalives
+        // FIXME: server-ident-raw-public-key
+        // FIXME: server-ident-tls13-epsk
+        // FIXME: client-auth-raw-public-key
+        // FIXME: client-auth-tls13-epsk
+        return Set.of(ServerIdentX509Cert.VALUE, ClientAuthSupported.VALUE, ClientAuthX509Cert.VALUE);
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/KeyStoreUtils.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/KeyStoreUtils.java
new file mode 100644 (file)
index 0000000..59f5c30
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManagerFactory;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+
+final class KeyStoreUtils {
+    private static final char[] EMPTY_SECRET = new char[0];
+
+    private KeyStoreUtils() {
+        // utility class
+    }
+
+    /**
+     * Creates and initializes new key store instance.
+     *
+     * @return key store instance
+     * @throws UnsupportedConfigurationException if key store cannot be instantiated
+     */
+    static KeyStore newKeyStore() throws UnsupportedConfigurationException {
+        final KeyStore keyStore;
+        try {
+            keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+            keyStore.load(null, null);
+        } catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
+            throw new UnsupportedConfigurationException("Cannot instantiate key store", e);
+        }
+        return keyStore;
+    }
+
+    /**
+     * Instantiates key manager factory, initializes it with key store instance provided.
+     *
+     * @param keyStore key store instance
+     * @return key manager factory instance
+     * @throws UnsupportedConfigurationException if key manager factory cannot be instantiated
+     */
+    static @NonNull KeyManagerFactory buildKeyManagerFactory(final @NonNull KeyStore keyStore)
+            throws UnsupportedConfigurationException {
+        try {
+            final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(keyStore, EMPTY_SECRET);
+            return kmf;
+        } catch (NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException e) {
+            throw new UnsupportedConfigurationException("Cannot instantiate key manager", e);
+        }
+    }
+
+    /**
+     * Instantiates trust manager factory, initializes it with key store instance provided.
+     *
+     * @param keyStore key store
+     * @return trust manager factory instance
+     * @throws UnsupportedConfigurationException if trust manager factory cannot be instantiated
+     */
+    static @NonNull TrustManagerFactory buildTrustManagerFactory(final @NonNull KeyStore keyStore)
+            throws UnsupportedConfigurationException {
+        try {
+            final var tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(keyStore);
+            return tmf;
+        } catch (NoSuchAlgorithmException | KeyStoreException e) {
+            throw new UnsupportedConfigurationException("Cannot instantiate trust manager", e);
+        }
+    }
+
+    /**
+     * Builds X509 Certificate instance.
+     *
+     * @param bytes certificate encoded
+     * @return certificate instance
+     * @throws CertificateException if certificate error occurs
+     * @throws IOException if input read error occurs
+     */
+    static Certificate buildX509Certificate(final byte[] bytes)
+            throws CertificateException, IOException {
+        try (var in = new ByteArrayInputStream(bytes)) {
+            return CertificateFactory.getInstance("X.509").generateCertificate(in);
+        }
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/KeyUtils.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/KeyUtils.java
new file mode 100644 (file)
index 0000000..787f870
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Objects;
+import java.util.concurrent.ThreadLocalRandom;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.crypto.params.RSAKeyParameters;
+import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
+import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+
+final class KeyUtils {
+    static final String RSA_ALGORITHM = "RSA";
+    static final String EC_ALGORITHM = "EC";
+
+    private KeyUtils() {
+        // utility class
+    }
+
+    static PrivateKey buildPrivateKey(final String keyAlgorithm, final byte[] bytes)
+            throws UnsupportedConfigurationException {
+        try {
+            return KeyFactory.getInstance(keyAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(bytes));
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new UnsupportedConfigurationException("Cannot build private key for " + keyAlgorithm, e);
+        }
+    }
+
+    static PublicKey buildX509PublicKey(final String keyAlgorithm, final byte[] bytes)
+            throws UnsupportedConfigurationException {
+        try {
+            return KeyFactory.getInstance(keyAlgorithm).generatePublic(new X509EncodedKeySpec(bytes));
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
+            throw new UnsupportedConfigurationException("Cannot build private key for " + keyAlgorithm, e);
+        }
+    }
+
+    static PublicKey buildPublicKeyFromSshEncoding(final byte[] bytes) throws UnsupportedConfigurationException {
+        try {
+            var parsed = OpenSSHPublicKeyUtil.parsePublicKey(bytes);
+            var converted = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(parsed).getEncoded();
+            if (parsed instanceof RSAKeyParameters rsaParams && !rsaParams.isPrivate()) {
+                return buildX509PublicKey(RSA_ALGORITHM, converted);
+            }
+            if (parsed instanceof ECPublicKeyParameters ecParams && !ecParams.isPrivate()) {
+                return buildX509PublicKey(EC_ALGORITHM, converted);
+            }
+            throw new UnsupportedConfigurationException("Invalid OpenSSH public key; "
+                    + "Expected RSA or EC public key; Current:" + parsed);
+        } catch (IOException e) {
+            throw new UnsupportedConfigurationException("Cannot parse OpenSSH public key", e);
+        }
+    }
+
+    static void validateKeyPair(final PublicKey publicKey, final PrivateKey privateKey)
+            throws UnsupportedConfigurationException {
+        final String signAlgorithm;
+        if (privateKey instanceof RSAPrivateKey) {
+            signAlgorithm = "SHA256withRSA";
+        } else if (privateKey instanceof ECPrivateKey) {
+            signAlgorithm = "SHA256withECDSA";
+        } else {
+            throw new UnsupportedConfigurationException("Unsupported key type " + privateKey);
+        }
+        try {
+            // test data
+            final byte[] original = new byte[1024];
+            ThreadLocalRandom.current().nextBytes(original);
+            // sign using the private key
+            final Signature signature = Signature.getInstance(signAlgorithm);
+            signature.initSign(privateKey);
+            signature.update(original);
+            final byte[] signed = signature.sign();
+            // verify using the public key
+            signature.initVerify(publicKey);
+            signature.update(original);
+            if (!signature.verify(signed)) {
+                throw new UnsupportedConfigurationException("Private key mismatches Public key");
+            }
+        } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
+            throw new UnsupportedConfigurationException("Key pair validation failed", e);
+        }
+    }
+
+    static void validatePublicKey(final PublicKey publicKey, final Certificate certificate)
+            throws UnsupportedConfigurationException {
+        if (!Objects.equals(publicKey, certificate.getPublicKey())) {
+            throw new UnsupportedConfigurationException("Certificate mismatches Public key");
+        }
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/SSLEngineFactory.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/SSLEngineFactory.java
new file mode 100644 (file)
index 0000000..a35ff52
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import static org.opendaylight.netconf.transport.tls.KeyStoreUtils.newKeyStore;
+
+import io.netty.handler.ssl.SslHandler;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.HelloParamsGrouping;
+
+/**
+ * A pre-configured factory for creating {@link SslHandler}s.
+ */
+final class SSLEngineFactory {
+    private static final char[] EMPTY_CHARS = new char[0];
+
+    private final SSLContext sslContext;
+
+    private SSLEngineFactory(final HelloParamsGrouping helloParams) throws UnsupportedConfigurationException {
+        final KeyStore keyStore = newKeyStore();
+
+        // FIXME: store keys
+
+        final KeyManagerFactory kmf;
+        try {
+            kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        } catch (NoSuchAlgorithmException e) {
+            throw new UnsupportedConfigurationException("Cannot instantiate key manager", e);
+        }
+        try {
+            kmf.init(keyStore, EMPTY_CHARS);
+        } catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException e) {
+            throw new UnsupportedConfigurationException("Cannot initialize key manager", e);
+        }
+
+        final TrustManagerFactory tmf;
+        try {
+            tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        } catch (NoSuchAlgorithmException e) {
+            throw new UnsupportedConfigurationException("Cannot instantiate trust manager", e);
+        }
+        try {
+            tmf.init(keyStore);
+        } catch (KeyStoreException e) {
+            throw new UnsupportedConfigurationException("Cannot initialize trust manager", e);
+        }
+
+        try {
+            sslContext = SSLContext.getInstance("TLS");
+        } catch (NoSuchAlgorithmException e) {
+            throw new UnsupportedConfigurationException("TLS context cannot be allocated", e);
+        }
+        try {
+            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+        } catch (KeyManagementException e) {
+            throw new UnsupportedConfigurationException("TLS context cannot be initialized", e);
+        }
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSClient.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSClient.java
new file mode 100644 (file)
index 0000000..e20f6b7
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.netconf.transport.api.TransportChannelListener;
+import org.opendaylight.netconf.transport.api.TransportStack;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.netconf.transport.tcp.TCPClient;
+import org.opendaylight.netconf.transport.tcp.TCPServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.client.rev221212.TcpClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev221212.TcpServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.TlsClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.client.identity.auth.type.Certificate;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.client.identity.auth.type.RawPublicKey;
+
+/**
+ * A {@link TransportStack} acting as a TLS client.
+ */
+public final class TLSClient extends TLSTransportStack {
+    private TLSClient(final TransportChannelListener listener, final SslContext sslContext) {
+        super(listener, sslContext);
+    }
+
+    public static @NonNull ListenableFuture<TLSClient> connect(final TransportChannelListener listener,
+            final Bootstrap bootstrap, final TcpClientGrouping connectParams, final TlsClientGrouping clientParams)
+            throws UnsupportedConfigurationException {
+        final var client = newClient(listener, clientParams);
+        return transformUnderlay(client, TCPClient.connect(client.asListener(), bootstrap, connectParams));
+    }
+
+    public static @NonNull ListenableFuture<TLSClient> listen(final TransportChannelListener listener,
+            final ServerBootstrap bootstrap, final TcpServerGrouping listenParams, final TlsClientGrouping clientParams)
+            throws UnsupportedConfigurationException {
+        final var client = newClient(listener, clientParams);
+        return transformUnderlay(client, TCPServer.listen(client.asListener(), bootstrap, listenParams));
+    }
+
+    private static TLSClient newClient(final TransportChannelListener listener, final TlsClientGrouping clientParams)
+            throws UnsupportedConfigurationException {
+        final var builder = SslContextBuilder.forClient();
+
+        final var clientIdentity = clientParams.getClientIdentity();
+        if (clientIdentity != null) {
+            final var authType = clientIdentity.getAuthType();
+            if (authType instanceof Certificate cert) {
+                // if-feature "client-ident-x509-cert"
+                final var certificate = cert.getCertificate();
+                if (certificate == null) {
+                    throw new UnsupportedConfigurationException("Missing certificate in " + cert);
+                }
+                builder.keyManager(newKeyManager(certificate));
+            } else if (authType instanceof RawPublicKey rawKey) {
+                // if-feature "client-ident-raw-public-key"
+                final var rawPrivateKey = rawKey.getRawPrivateKey();
+                if (rawPrivateKey == null) {
+                    throw new UnsupportedConfigurationException("Missing key in " + rawKey);
+                }
+                builder.keyManager(newKeyManager(rawPrivateKey));
+            } else if (authType != null) {
+                throw new UnsupportedConfigurationException("Unsupported client authentication type " + authType);
+            }
+        }
+
+        final var serverAuth = clientParams.getServerAuthentication();
+        if (serverAuth != null) {
+            // CA && EE X509 certificates : if-feature "server-ident-x509-cert"
+            // Raw public key : if-feature "server-ident-raw-public-key"
+            final var trustManager = newTrustManager(serverAuth.getCaCerts(), serverAuth.getEeCerts(),
+                    serverAuth.getRawPublicKeys());
+            if (trustManager == null) {
+                throw new UnsupportedOperationException("No server authentication methods in " + serverAuth);
+            }
+            builder.trustManager(trustManager);
+        }
+
+        return new TLSClient(listener, buildSslContext(builder, clientParams.getHelloParams()));
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSServer.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSServer.java
new file mode 100644 (file)
index 0000000..0c7cc60
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.handler.ssl.ClientAuth;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.netconf.transport.api.TransportChannelListener;
+import org.opendaylight.netconf.transport.api.TransportStack;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.netconf.transport.tcp.TCPClient;
+import org.opendaylight.netconf.transport.tcp.TCPServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.client.rev221212.TcpClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev221212.TcpServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.TlsServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.tls.server.grouping.server.identity.auth.type.Certificate;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.tls.server.grouping.server.identity.auth.type.RawPrivateKey;
+
+/**
+ * A {@link TransportStack} acting as a TLS server.
+ */
+public final class TLSServer extends TLSTransportStack {
+    private TLSServer(final TransportChannelListener listener, final SslContext sslContext) {
+        super(listener, sslContext);
+    }
+
+    public static @NonNull ListenableFuture<TLSServer> connect(final TransportChannelListener listener,
+            final Bootstrap bootstrap, final TcpClientGrouping connectParams, final TlsServerGrouping serverParams)
+            throws UnsupportedConfigurationException {
+        final var server = newServer(listener, serverParams);
+        return transformUnderlay(server, TCPClient.connect(server.asListener(), bootstrap, connectParams));
+    }
+
+    public static @NonNull ListenableFuture<TLSServer> listen(final TransportChannelListener listener,
+            final ServerBootstrap bootstrap, final TcpServerGrouping listenParams, final TlsServerGrouping serverParams)
+            throws UnsupportedConfigurationException {
+        final var server = newServer(listener, serverParams);
+        return transformUnderlay(server, TCPServer.listen(server.asListener(), bootstrap, listenParams));
+    }
+
+    private static TLSServer newServer(final TransportChannelListener listener, final TlsServerGrouping serverParams)
+            throws UnsupportedConfigurationException {
+        final var serverIdentity = serverParams.getServerIdentity();
+        if (serverIdentity == null) {
+            throw new UnsupportedConfigurationException("Missing server identity");
+        }
+        final SslContextBuilder builder;
+        final var authType = serverIdentity.getAuthType();
+        if (authType instanceof Certificate cert) {
+            // if-feature "server-ident-x509-cert"
+            final var certificate = cert.getCertificate();
+            if (certificate == null) {
+                throw new UnsupportedConfigurationException("Missing certificate in " + cert);
+            }
+            builder = SslContextBuilder.forServer(newKeyManager(certificate));
+        } else if (authType instanceof RawPrivateKey rawKey) {
+            // if-feature "server-ident-raw-public-key"
+            final var rawPrivateKey = rawKey.getRawPrivateKey();
+            if (rawPrivateKey == null) {
+                throw new UnsupportedConfigurationException("Missing key in " + rawKey);
+            }
+            builder = SslContextBuilder.forServer(newKeyManager(rawPrivateKey));
+        } else if (authType != null) {
+            throw new UnsupportedConfigurationException("Unsupported server authentication type " + authType);
+        } else {
+            throw new UnsupportedConfigurationException("Missing server authentication type");
+        }
+
+        final var clientAuth = serverParams.getClientAuthentication();
+        if (clientAuth != null) {
+            // CA && EE Certs : if-feature "client-ident-x509-cert"
+            // Raw public keys : if-feature "client-ident-raw-public-key"
+            final var trustManager = newTrustManager(clientAuth.getCaCerts(), clientAuth.getEeCerts(),
+                    clientAuth.getRawPublicKeys());
+            if (trustManager == null) {
+                throw new UnsupportedOperationException("No client authentication methods in " + clientAuth);
+            }
+            builder.clientAuth(ClientAuth.REQUIRE).trustManager(trustManager);
+        } else {
+            builder.clientAuth(ClientAuth.NONE);
+        }
+        return new TLSServer(listener, buildSslContext(builder, serverParams.getHelloParams()));
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSTransportChannel.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSTransportChannel.java
new file mode 100644 (file)
index 0000000..336e863
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import org.opendaylight.netconf.transport.api.AbstractOverlayTransportChannel;
+import org.opendaylight.netconf.transport.api.TransportChannel;
+
+final class TLSTransportChannel extends AbstractOverlayTransportChannel {
+    TLSTransportChannel(final TransportChannel tcp) {
+        super(tcp);
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSTransportStack.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/TLSTransportStack.java
new file mode 100644 (file)
index 0000000..3c4ed1e
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import static java.util.Objects.requireNonNull;
+import static org.opendaylight.netconf.transport.tls.ConfigUtils.setAsymmetricKey;
+import static org.opendaylight.netconf.transport.tls.ConfigUtils.setEndEntityCertificateWithKey;
+import static org.opendaylight.netconf.transport.tls.ConfigUtils.setX509Certificates;
+import static org.opendaylight.netconf.transport.tls.KeyStoreUtils.buildKeyManagerFactory;
+import static org.opendaylight.netconf.transport.tls.KeyStoreUtils.buildTrustManagerFactory;
+import static org.opendaylight.netconf.transport.tls.KeyStoreUtils.newKeyStore;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import java.security.KeyStore;
+import java.util.List;
+import java.util.Set;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.TrustManagerFactory;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.netconf.transport.api.AbstractOverlayTransportStack;
+import org.opendaylight.netconf.transport.api.TransportChannel;
+import org.opendaylight.netconf.transport.api.TransportChannelListener;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.CipherSuiteAlgBase;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsAes128CcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsAes128GcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsAes256GcmSha384;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsChacha20Poly1305Sha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDhePskWithAes128Ccm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDhePskWithAes128GcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDhePskWithAes256Ccm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDhePskWithAes256GcmSha384;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDhePskWithChacha20Poly1305Sha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDheRsaWithAes128Ccm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDheRsaWithAes128GcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDheRsaWithAes256Ccm;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDheRsaWithAes256GcmSha384;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsDheRsaWithChacha20Poly1305Sha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdheEcdsaWithAes128GcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdheEcdsaWithAes256GcmSha384;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdheEcdsaWithChacha20Poly1305Sha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdhePskWithAes128CcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdhePskWithAes128GcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdhePskWithAes256GcmSha384;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdhePskWithChacha20Poly1305Sha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdheRsaWithAes128GcmSha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdheRsaWithAes256GcmSha384;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana.tls.cipher.suite.algs.rev220616.TlsEcdheRsaWithChacha20Poly1305Sha256;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212.LocalOrKeystoreAsymmetricKeyGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212.LocalOrKeystoreEndEntityCertWithKeyGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.HelloParamsGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.common.rev221212.TlsVersionBase;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212.LocalOrTruststoreCertsGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212.LocalOrTruststorePublicKeysGrouping;
+
+/**
+ * Base class for TLS TransportStacks.
+ */
+public abstract sealed class TLSTransportStack extends AbstractOverlayTransportStack<TLSTransportChannel>
+        permits TLSClient, TLSServer {
+
+    private static final ImmutableMap<CipherSuiteAlgBase, String> CIPHER_SUITES =
+            ImmutableMap.<CipherSuiteAlgBase, String>builder()
+                    .put(TlsAes128CcmSha256.VALUE, "TLS_AES_128_CCM_SHA256")
+                    .put(TlsAes128GcmSha256.VALUE, "TLS_AES_128_GCM_SHA256")
+                    .put(TlsAes256GcmSha384.VALUE, "TLS_AES_256_GCM_SHA384")
+                    .put(TlsChacha20Poly1305Sha256.VALUE, "TLS_CHACHA20_POLY1305_SHA256")
+                    .put(TlsDhePskWithAes128Ccm.VALUE, "TLS_DHE_PSK_WITH_AES_128_CCM")
+                    .put(TlsDhePskWithAes128GcmSha256.VALUE, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256")
+                    .put(TlsDhePskWithAes256Ccm.VALUE, "TLS_DHE_PSK_WITH_AES_256_CCM")
+                    .put(TlsDhePskWithAes256GcmSha384.VALUE, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384")
+                    .put(TlsDhePskWithChacha20Poly1305Sha256.VALUE, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256")
+                    .put(TlsDheRsaWithAes128Ccm.VALUE, "TLS_DHE_RSA_WITH_AES_128_CCM")
+                    .put(TlsDheRsaWithAes128GcmSha256.VALUE, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256")
+                    .put(TlsDheRsaWithAes256Ccm.VALUE, "TLS_DHE_RSA_WITH_AES_256_CCM")
+                    .put(TlsDheRsaWithAes256GcmSha384.VALUE, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384")
+                    .put(TlsDheRsaWithChacha20Poly1305Sha256.VALUE, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256")
+                    .put(TlsEcdheEcdsaWithAes128GcmSha256.VALUE, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256")
+                    .put(TlsEcdheEcdsaWithAes256GcmSha384.VALUE, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384")
+                    .put(TlsEcdheEcdsaWithChacha20Poly1305Sha256.VALUE, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256")
+                    .put(TlsEcdhePskWithAes128CcmSha256.VALUE, "TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256")
+                    .put(TlsEcdhePskWithAes128GcmSha256.VALUE, "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256")
+                    .put(TlsEcdhePskWithAes256GcmSha384.VALUE, "TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384")
+                    .put(TlsEcdhePskWithChacha20Poly1305Sha256.VALUE, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256")
+                    .put(TlsEcdheRsaWithAes128GcmSha256.VALUE, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
+                    .put(TlsEcdheRsaWithAes256GcmSha384.VALUE, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384")
+                    .put(TlsEcdheRsaWithChacha20Poly1305Sha256.VALUE, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")
+                    .build();
+
+    private volatile @NonNull SslContext sslContext;
+
+    TLSTransportStack(final TransportChannelListener listener, final SslContext sslContext) {
+        super(listener);
+        this.sslContext = requireNonNull(sslContext);
+    }
+
+    @Override
+    protected final void onUnderlayChannelEstablished(final TransportChannel underlayChannel) {
+        final var channel = underlayChannel.channel();
+        final var sslHandler = sslContext.newHandler(channel.alloc());
+
+        channel.pipeline().addLast(sslHandler);
+        sslHandler.handshakeFuture().addListener(future -> {
+            final var cause = future.cause();
+            if (cause != null) {
+                notifyTransportChannelFailed(cause);
+                channel.close();
+            } else {
+                addTransportChannel(new TLSTransportChannel(underlayChannel));
+            }
+        });
+    }
+
+    final void setSslContext(final SslContext sslContext) {
+        this.sslContext = requireNonNull(sslContext);
+    }
+
+    static KeyManagerFactory newKeyManager(
+            final @NonNull LocalOrKeystoreEndEntityCertWithKeyGrouping endEntityCert
+    ) throws UnsupportedConfigurationException {
+        final var keyStore = newKeyStore();
+        setEndEntityCertificateWithKey(keyStore, endEntityCert);
+        return buildKeyManagerFactory(keyStore);
+    }
+
+    static KeyManagerFactory newKeyManager(final @NonNull LocalOrKeystoreAsymmetricKeyGrouping rawPrivateKey)
+            throws UnsupportedConfigurationException {
+        final var keyStore = newKeyStore();
+        setAsymmetricKey(keyStore, rawPrivateKey);
+        return buildKeyManagerFactory(keyStore);
+    }
+
+    // FIXME: should be TrustManagerBuilder
+    protected static @Nullable TrustManagerFactory newTrustManager(
+            final @Nullable LocalOrTruststoreCertsGrouping caCerts,
+            final @Nullable LocalOrTruststoreCertsGrouping eeCerts,
+            final @Nullable LocalOrTruststorePublicKeysGrouping publicKeys) throws UnsupportedConfigurationException {
+
+        if (publicKeys != null) {
+            // FIXME: implement this and advertize server-auth-raw-public-key from IetfTlsClientFeatureProvider
+            throw new UnsupportedConfigurationException("Public key authentication not implemented");
+        }
+        if (caCerts != null || eeCerts != null) {
+            // X.509 certificates
+            final KeyStore keyStore = newKeyStore();
+            setX509Certificates(keyStore, caCerts, eeCerts);
+            return buildTrustManagerFactory(keyStore);
+        }
+        return null;
+    }
+
+    static SslContext buildSslContext(final SslContextBuilder builder, final HelloParamsGrouping helloParams)
+            throws UnsupportedConfigurationException {
+        if (helloParams != null) {
+            final var tlsVersions = helloParams.getTlsVersions();
+            if (tlsVersions != null) {
+                final var versions = tlsVersions.getTlsVersion();
+                if (versions != null && !versions.isEmpty()) {
+                    builder.protocols(createTlsStrings(versions));
+                }
+            }
+            final var cipherSuites = helloParams.getCipherSuites();
+            if (cipherSuites != null) {
+                final var ciphers = cipherSuites.getCipherSuite();
+                if (ciphers != null && !ciphers.isEmpty()) {
+                    builder.ciphers(createCipherStrings(ciphers));
+                }
+            }
+        }
+        try {
+            return builder.build();
+        } catch (SSLException e) {
+            throw new UnsupportedConfigurationException("Cannot instantiate TLS context", e);
+        }
+    }
+
+    private static String[] createTlsStrings(final Set<TlsVersionBase> versions)
+            throws UnsupportedConfigurationException {
+        // FIXME: cache these
+        final var ret = new String[versions.size()];
+        int idx = 0;
+        for (var version : versions) {
+            final var str = IetfTlsCommonFeatureProvider.algorithmNameOf(version);
+            if (str == null) {
+                throw new UnsupportedConfigurationException("Unhandled TLS version " + version);
+            }
+            ret[idx++] = str;
+        }
+        return ret;
+    }
+
+    private static ImmutableList<String> createCipherStrings(final List<CipherSuiteAlgBase> ciphers)
+            throws UnsupportedConfigurationException {
+        // FIXME: cache these
+        final var builder = ImmutableList.<String>builderWithExpectedSize(ciphers.size());
+        for (var cipher : ciphers) {
+            final var str = CIPHER_SUITES.get(cipher);
+            if (str == null) {
+                throw new UnsupportedConfigurationException("Unhandled cipher suite " + cipher);
+            }
+            builder.add(str);
+        }
+        return builder.build();
+    }
+}
diff --git a/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/package-info.java b/transport/transport-tls/src/main/java/org/opendaylight/netconf/transport/tls/package-info.java
new file mode 100644 (file)
index 0000000..8352857
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * NETCONF Secure Transport over TLS, as detailed in <a href="https://www.rfc-editor.org/rfc/rfc7589">RFC7589</a>.
+ * Configuration follows <a href="https://datatracker.ietf.org/doc/html/draft-ietf-netconf-tls-client-server-29">
+ * draft-ietf-netconf-tls-client-server</a>.
+ */
+package org.opendaylight.netconf.transport.tls;
\ No newline at end of file
diff --git a/transport/transport-tls/src/main/yang/iana-tls-cipher-suite-algs@2022-06-16.yang b/transport/transport-tls/src/main/yang/iana-tls-cipher-suite-algs@2022-06-16.yang
new file mode 100644 (file)
index 0000000..78d310d
--- /dev/null
@@ -0,0 +1,3778 @@
+module iana-tls-cipher-suite-algs {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:iana-tls-cipher-suite-algs";
+  prefix tlscsa;
+
+  organization
+    "Internet Assigned Numbers Authority (IANA)";
+
+  contact
+    "Postal: ICANN
+             12025 Waterfront Drive, Suite 300
+             Los Angeles, CA  90094-2536
+             United States of America
+     Tel:    +1 310 301 5800
+     Email:  iana@iana.org";
+
+  description
+    "This module defines identities for the Cipher Suite
+     algorithms defined in the 'TLS Cipher Suites' sub-registry
+     of the 'Transport Layer Security (TLS) Parameters' registry
+     maintained by IANA.
+
+     Copyright (c) 2022 IETF Trust and the persons identified as
+     authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with
+     or without modification, is permitted pursuant to, and
+     subject to the license terms contained in, the Revised
+     BSD License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     The initial version of this YANG module is part of RFC FFFF
+     (https://www.rfc-editor.org/info/rfcFFFF); see the RFC
+     itself for full legal notices.";
+
+  revision 2022-06-16 {
+   description
+      "Updated to reflect contents of the public key algorithms
+       registry on June 16, 2022.";
+  }
+
+  revision 2021-06-02 {
+    description
+      "Initial version";
+    reference
+      "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers";
+  }
+
+  // Typedefs
+
+  typedef cipher-suite-algorithm-ref {
+    type identityref {
+      base "cipher-suite-alg-base";
+    }
+    description
+      "A reference to a TLS cipher suite algorithm identifier.";
+  }
+  // Identities
+
+  identity cipher-suite-alg-base {
+    description
+      "Base identity used to identify TLS cipher suites.";
+  }
+
+  identity tls-null-with-null-null {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-NULL-WITH-NULL-NULL";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-null-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-NULL-MD5";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-NULL-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-export-with-rc4-40-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-EXPORT-WITH-RC4-40-MD5";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+  identity tls-rsa-with-rc4-128-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-RC4-128-MD5";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-rsa-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-RC4-128-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-rsa-export-with-rc2-cbc-40-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-EXPORT-WITH-RC2-CBC-40-MD5";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-rsa-with-idea-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-RSA-WITH-IDEA-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-export-with-des40-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-EXPORT-WITH-DES40-CBC-SHA";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-rsa-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-RSA-WITH-DES-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-dss-export-with-des40-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-EXPORT-WITH-DES40-CBC-SHA";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-dh-dss-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-DH-DSS-WITH-DES-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-rsa-export-with-des40-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-EXPORT-WITH-DES40-CBC-SHA";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-dh-rsa-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-DH-RSA-WITH-DES-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-dss-export-with-des40-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-EXPORT-WITH-DES40-CBC-SHA";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-dhe-dss-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-DHE-DSS-WITH-DES-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-rsa-export-with-des40-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-EXPORT-WITH-DES40-CBC-SHA";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-dhe-rsa-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-DHE-RSA-WITH-DES-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-anon-export-with-rc4-40-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-EXPORT-WITH-RC4-40-MD5";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-dh-anon-with-rc4-128-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-RC4-128-MD5";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-dh-anon-export-with-des40-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-EXPORT-WITH-DES40-CBC-SHA";
+    reference
+      "RFC 4346:
+         The TLS Protocol Version 1.1";
+  }
+
+  identity tls-dh-anon-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status obsolete;
+    description
+      "TLS-DH-ANON-WITH-DES-CBC-SHA";
+    reference
+      "RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)
+       RFC 5469:
+         DES and IDEA Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-krb5-with-des-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-DES-CBC-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-RC4-128-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-krb5-with-idea-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-IDEA-CBC-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-with-des-cbc-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-DES-CBC-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-with-3des-ede-cbc-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-3DES-EDE-CBC-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-with-rc4-128-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-RC4-128-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-krb5-with-idea-cbc-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-WITH-IDEA-CBC-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-export-with-des-cbc-40-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-EXPORT-WITH-DES-CBC-40-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-export-with-rc2-cbc-40-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-EXPORT-WITH-RC2-CBC-40-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-export-with-rc4-40-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-EXPORT-WITH-RC4-40-SHA";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-krb5-export-with-des-cbc-40-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-EXPORT-WITH-DES-CBC-40-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-export-with-rc2-cbc-40-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-EXPORT-WITH-RC2-CBC-40-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-krb5-export-with-rc4-40-md5 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-KRB5-EXPORT-WITH-RC4-40-MD5";
+    reference
+      "RFC 2712:
+         Addition of Kerberos Cipher Suites to
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-psk-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-NULL-SHA";
+    reference
+      "RFC 4785:
+         Pre-Shared Key Cipher Suites with NULL Encryption for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-NULL-SHA";
+    reference
+      "RFC 4785:
+         Pre-Shared Key Cipher Suites with NULL Encryption for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-NULL-SHA";
+    reference
+      "RFC 4785:
+         Pre-Shared Key Cipher Suites with NULL Encryption for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+  identity tls-dh-dss-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-rsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-dss-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-rsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-anon-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-dss-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-rsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-dss-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-rsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-anon-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-null-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-NULL-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-aes-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-256-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-dss-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-rsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-dss-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-camellia-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-dss-with-camellia-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-CAMELLIA-128-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-rsa-with-camellia-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-CAMELLIA-128-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-dss-with-camellia-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-camellia-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-anon-with-camellia-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-CAMELLIA-128-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-dss-with-aes-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-AES-256-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-rsa-with-aes-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-AES-256-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-dss-with-aes-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dhe-rsa-with-aes-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-anon-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-dh-anon-with-aes-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-AES-256-CBC-SHA256";
+    reference
+      "RFC 5246:
+         The Transport Layer Security (TLS) Protocol Version 1.2";
+  }
+
+  identity tls-rsa-with-camellia-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-dss-with-camellia-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-CAMELLIA-256-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-rsa-with-camellia-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-CAMELLIA-256-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-dss-with-camellia-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-camellia-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-anon-with-camellia-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-CAMELLIA-256-CBC-SHA";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-psk-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-RC4-128-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-psk-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-RC4-128-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-dhe-psk-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-RC4-128-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-rsa-psk-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-seed-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-SEED-CBC-SHA";
+    reference
+      "RFC 4162:
+         Addition of SEED Ciphersuites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-seed-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-SEED-CBC-SHA";
+    reference
+      "RFC 4162:
+         Addition of SEED Ciphersuites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-seed-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-SEED-CBC-SHA";
+    reference
+      "RFC 4162:
+         Addition of SEED Ciphersuites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-seed-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-SEED-CBC-SHA";
+    reference
+      "RFC 4162:
+         Addition of SEED Ciphersuites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-seed-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-SEED-CBC-SHA";
+    reference
+      "RFC 4162:
+         Addition of SEED Ciphersuites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-seed-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-SEED-CBC-SHA";
+    reference
+      "RFC 4162:
+         Addition of SEED Ciphersuites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-rsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dh-rsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dh-rsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-dss-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-dss-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dh-dss-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dh-dss-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dh-anon-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-dh-anon-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5288:
+         AES-GCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-psk-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-dhe-psk-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-dhe-psk-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-psk-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-psk-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-psk-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-psk-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-psk-with-null-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-NULL-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-psk-with-null-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-NULL-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-dhe-psk-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-dhe-psk-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-dhe-psk-with-null-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-NULL-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-dhe-psk-with-null-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-NULL-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-psk-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-psk-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-psk-with-null-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-NULL-SHA256";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-psk-with-null-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-NULL-SHA384";
+    reference
+      "RFC 5487:
+         Pre-Shared Key Cipher Suites for Transport Layer Security
+         (TLS) with SHA-256/384 and AES Galois Counter Mode";
+  }
+
+  identity tls-rsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-dss-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-rsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-dss-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-anon-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-rsa-with-camellia-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-dss-with-camellia-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-CAMELLIA-256-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-rsa-with-camellia-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-CAMELLIA-256-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-dss-with-camellia-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-camellia-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-dh-anon-with-camellia-256-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-CAMELLIA-256-CBC-SHA256";
+    reference
+      "RFC 5932:
+         Camellia Cipher Suites for TLS";
+  }
+
+  identity tls-sm4-gcm-sm3 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SM4-GCM-SM3";
+    reference
+      "RFC 8998:
+         ShangMi (SM) Cipher Suites for Transport Layer Security
+         (TLS) Protocol Version 1.3";
+  }
+  identity tls-sm4-ccm-sm3 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SM4-CCM-SM3";
+    reference
+      "RFC 8998:
+         ShangMi (SM) Cipher Suites for Transport Layer Security
+         (TLS) Protocol Version 1.3";
+  }
+
+  identity tls-empty-renegotiation-info-scsv {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-EMPTY-RENEGOTIATION-INFO-SCSV";
+    reference
+      "RFC 5746:
+         Transport Layer Security (TLS)
+         Renegotiation Indication Extension";
+  }
+
+  identity tls-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-AES-128-GCM-SHA256";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  identity tls-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-AES-256-GCM-SHA384";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  identity tls-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+  identity tls-aes-128-ccm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-AES-128-CCM-SHA256";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  identity tls-aes-128-ccm-8-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-AES-128-CCM-8-SHA256";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  identity tls-fallback-scsv {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-FALLBACK-SCSV";
+    reference
+      "RFC 7507:
+         TLS Fallback Signaling Cipher Suite Value (SCSV)
+         for Preventing Protocol Downgrade Attacks";
+  }
+
+  identity tls-ecdh-ecdsa-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-NULL-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-ecdsa-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-RC4-128-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-ecdh-ecdsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-ecdsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-ecdsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-ecdsa-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-NULL-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-ecdsa-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-ecdhe-ecdsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-rsa-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-NULL-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-rsa-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-RC4-128-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-ecdh-rsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-rsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-rsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-rsa-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-NULL-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-rsa-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-RC4-128-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-ecdhe-rsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-rsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdhe-rsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-anon-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ANON-WITH-NULL-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-anon-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ANON-WITH-RC4-128-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-ecdh-anon-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ANON-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-anon-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ANON-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-ecdh-anon-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ANON-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 8422:
+         Elliptic Curve Cryptography (ECC) Cipher Suites for
+         Transport Layer Security (TLS) Versions 1.2 and Earlier";
+  }
+
+  identity tls-srp-sha-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-rsa-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-RSA-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-dss-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-DSS-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-rsa-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-RSA-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-dss-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-DSS-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+  identity tls-srp-sha-rsa-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-RSA-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-srp-sha-dss-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SRP-SHA-DSS-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5054:
+         Using SRP for TLS Authentication";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-ecdsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-ecdsa-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-rsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-rsa-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-rsa-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+  identity tls-ecdh-rsa-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-ecdsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-ecdsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-rsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-rsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-rsa-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdh-rsa-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 5289:
+         TLS Elliptic Curve Cipher Suites with SHA-256/384
+         and AES Galois Counter Mode";
+  }
+
+  identity tls-ecdhe-psk-with-rc4-128-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-RC4-128-SHA";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)
+       RFC 6347:
+         Datagram Transport Layer Security version 1.2";
+  }
+
+  identity tls-ecdhe-psk-with-3des-ede-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-aes-128-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-aes-256-cbc-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-aes-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-aes-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-null-sha {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-NULL-SHA";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-null-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-NULL-SHA256";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-null-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-NULL-SHA384";
+    reference
+      "RFC 5489:
+         ECDHE_PSK Ciphersuites for Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+  identity tls-ecdh-rsa-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-aria-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-ARIA-128-GCM-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-aria-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-aria-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-ARIA-128-CBC-SHA256";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+  identity tls-ecdhe-psk-with-aria-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384";
+    reference
+      "RFC 6209:
+         Addition of the ARIA Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-rsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-RSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-dss-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-DSS-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-dss-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-DSS-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dh-anon-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DH-ANON-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-ecdsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-rsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdh-rsa-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-camellia-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-camellia-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+  identity tls-psk-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-camellia-128-cbc-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-camellia-256-cbc-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384";
+    reference
+      "RFC 6367:
+         Addition of the Camellia Cipher Suites to
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-with-aes-128-ccm {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-128-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-rsa-with-aes-256-ccm {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-256-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-128-ccm {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-RSA-WITH-AES-128-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-256-ccm {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-RSA-WITH-AES-256-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-rsa-with-aes-128-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-128-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-rsa-with-aes-256-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-WITH-AES-256-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-128-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-AES-128-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-rsa-with-aes-256-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-DHE-RSA-WITH-AES-256-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-with-aes-128-ccm {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-128-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-with-aes-256-ccm {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-256-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-psk-with-aes-128-ccm {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-PSK-WITH-AES-128-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-dhe-psk-with-aes-256-ccm {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-PSK-WITH-AES-256-CCM";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-with-aes-128-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-128-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-with-aes-256-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-AES-256-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-dhe-with-aes-128-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-DHE-WITH-AES-128-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-psk-dhe-with-aes-256-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-DHE-WITH-AES-256-CCM-8";
+    reference
+      "RFC 6655:
+         AES-CCM Cipher Suites for TLS";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-128-ccm {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-128-CCM";
+    reference
+      "RFC 7251:
+         AES-CCM ECC Cipher Suites for TLS";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-256-ccm {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-256-CCM";
+    reference
+      "RFC 7251:
+         AES-CCM ECC Cipher Suites for TLS";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-128-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8";
+    reference
+      "RFC 7251:
+         AES-CCM ECC Cipher Suites for TLS";
+  }
+
+  identity tls-ecdhe-ecdsa-with-aes-256-ccm-8 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8";
+    reference
+      "RFC 7251:
+         AES-CCM ECC Cipher Suites for TLS";
+  }
+
+  identity tls-eccpwd-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECCPWD-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 8492:
+         Secure Password Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-eccpwd-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECCPWD-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 8492:
+         Secure Password Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-eccpwd-with-aes-128-ccm-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECCPWD-WITH-AES-128-CCM-SHA256";
+    reference
+      "RFC 8492:
+         Secure Password Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-eccpwd-with-aes-256-ccm-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECCPWD-WITH-AES-256-CCM-SHA384";
+    reference
+      "RFC 8492:
+         Secure Password Ciphersuites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-sha256-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SHA256-SHA256";
+    reference
+      "RFC 9150:
+         TLS 1.3 Authentication and Integrity-Only Cipher Suites";
+  }
+
+  identity tls-sha384-sha384 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-SHA384-SHA384";
+    reference
+      "RFC 9150:
+         TLS 1.3 Authentication and Integrity-Only Cipher Suites";
+  }
+
+  identity tls-gostr341112-256-with-kuznyechik-ctr-omac {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-GOSTR341112-256-WITH-KUZNYECHIK-CTR-OMAC";
+    reference
+      "RFC 9189:
+         GOST Cipher Suites for Transport Layer Security (TLS)
+         Protocol Version 1.2";
+  }
+
+  identity tls-gostr341112-256-with-magma-ctr-omac {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-GOSTR341112-256-WITH-MAGMA-CTR-OMAC";
+    reference
+      "RFC 9189:
+         GOST Cipher Suites for Transport Layer Security (TLS)
+         Protocol Version 1.2";
+  }
+
+  identity tls-gostr341112-256-with-28147-cnt-imit {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-GOSTR341112-256-WITH-28147-CNT-IMIT";
+    reference
+      "RFC 9189:
+         GOST Cipher Suites for Transport Layer Security (TLS)
+         Protocol Version 1.2";
+  }
+
+  identity tls-ecdhe-rsa-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-ecdsa-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-rsa-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-psk-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-PSK-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-dhe-psk-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-rsa-psk-with-chacha20-poly1305-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256";
+    reference
+      "RFC 7905:
+         ChaCha20-Poly1305 Cipher Suites for
+         Transport Layer Security (TLS)";
+  }
+
+  identity tls-ecdhe-psk-with-aes-128-gcm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-128-GCM-SHA256";
+    reference
+      "RFC 8442:
+         ECDHE_PSK with AES-GCM and AES-CCM Cipher Suites";
+  }
+
+  identity tls-ecdhe-psk-with-aes-256-gcm-sha384 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-256-GCM-SHA384";
+    reference
+      "RFC 8442:
+         ECDHE_PSK with AES-GCM and AES-CCM Cipher Suites";
+  }
+
+  identity tls-ecdhe-psk-with-aes-128-ccm-8-sha256 {
+    base cipher-suite-alg-base;
+    status deprecated;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-128-CCM-8-SHA256";
+    reference
+      "RFC 8442:
+         ECDHE_PSK with AES-GCM and AES-CCM Cipher Suites";
+  }
+  identity tls-ecdhe-psk-with-aes-128-ccm-sha256 {
+    base cipher-suite-alg-base;
+    description
+      "TLS-ECDHE-PSK-WITH-AES-128-CCM-SHA256";
+    reference
+      "RFC 8442:
+         ECDHE_PSK with AES-GCM and AES-CCM Cipher Suites";
+  }
+
+  // Protocol-accessible Nodes
+
+  container supported-algorithms {
+    config false;
+    description
+      "A container for a list of cipher suite algorithms supported
+       by the server.";
+    leaf-list supported-algorithm {
+      type cipher-suite-algorithm-ref;
+      description
+        "A cipher suite algorithm supported by the server.";
+    }
+  }
+
+}
diff --git a/transport/transport-tls/src/main/yang/ietf-tls-client@2022-12-12.yang b/transport/transport-tls/src/main/yang/ietf-tls-client@2022-12-12.yang
new file mode 100644 (file)
index 0000000..00b7ad3
--- /dev/null
@@ -0,0 +1,522 @@
+module ietf-tls-client {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-tls-client";
+  prefix tlsc;
+
+  import ietf-netconf-acm {
+    prefix nacm;
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+
+  import ietf-crypto-types {
+    prefix ct;
+    reference
+      "RFC AAAA: YANG Data Types and Groupings for Cryptography";
+  }
+
+  import ietf-truststore {
+    prefix ts;
+    reference
+      "RFC BBBB: A YANG Data Model for a Truststore";
+  }
+
+  import ietf-keystore {
+    prefix ks;
+    reference
+      "RFC CCCC: A YANG Data Model for a Keystore";
+  }
+
+  import ietf-tls-common {
+    prefix tlscmn;
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG List:  NETCONF WG list <mailto:netconf@ietf.org>
+     WG Web:   https://datatracker.ietf.org/wg/netconf
+     Author:   Kent Watsen <mailto:kent+ietf@watsen.net>
+     Author:   Jeff Hartley <mailto:jeff.hartley@commscope.com>";
+
+  description
+    "This module defines reusable groupings for TLS clients that
+     can be used as a basis for specific TLS client instances.
+
+     Copyright (c) 2022 IETF Trust and the persons identified
+     as authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with
+     or without modification, is permitted pursuant to, and
+     subject to the license terms contained in, the Revised
+     BSD License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC FFFF
+     (https://www.rfc-editor.org/info/rfcFFFF); see the RFC
+     itself for full legal notices.
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
+     'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
+     'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
+     are to be interpreted as described in BCP 14 (RFC 2119)
+     (RFC 8174) when, and only when, they appear in all
+     capitals, as shown here.";
+
+  revision 2022-12-12 {
+    description
+      "Initial version";
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  // Features
+
+  feature tls-client-keepalives {
+    description
+      "Per socket TLS keepalive parameters are configurable for
+       TLS clients on the server implementing this feature.";
+  }
+
+  feature client-ident-x509-cert {
+    description
+      "Indicates that the client supports identifying itself
+       using X.509 certificates.";
+    reference
+      "RFC 5280:
+         Internet X.509 Public Key Infrastructure Certificate
+         and Certificate Revocation List (CRL) Profile";
+  }
+
+  feature client-ident-raw-public-key {
+    description
+      "Indicates that the client supports identifying itself
+       using raw public keys.";
+    reference
+      "RFC 7250:
+         Using Raw Public Keys in Transport Layer Security (TLS)
+         and Datagram Transport Layer Security (DTLS)";
+  }
+
+  feature client-ident-tls12-psk {
+    description
+      "Indicates that the client supports identifying itself
+       using TLS-1.2 PSKs (pre-shared or pairwise-symmetric keys).";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for Transport Layer Security
+         (TLS)";
+  }
+
+  feature client-ident-tls13-epsk {
+    description
+      "Indicates that the client supports identifying itself
+       using TLS-1.3 External PSKs (pre-shared keys).";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  feature server-auth-x509-cert {
+    description
+      "Indicates that the client supports authenticating servers
+       using X.509 certificates.";
+    reference
+      "RFC 5280:
+         Internet X.509 Public Key Infrastructure Certificate
+         and Certificate Revocation List (CRL) Profile";
+  }
+
+  feature server-auth-raw-public-key {
+    description
+      "Indicates that the client supports authenticating servers
+       using raw public keys.";
+    reference
+      "RFC 7250:
+         Using Raw Public Keys in Transport Layer Security (TLS)
+         and Datagram Transport Layer Security (DTLS)";
+  }
+  feature server-auth-tls12-psk {
+    description
+      "Indicates that the client supports authenticating servers
+       using PSKs (pre-shared or pairwise-symmetric keys).";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for Transport Layer Security
+         (TLS)";
+  }
+
+  feature server-auth-tls13-epsk {
+    description
+      "Indicates that the client supports authenticating servers
+       using TLS-1.3 External PSKs (pre-shared keys).";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  // Groupings
+
+  grouping tls-client-grouping {
+    description
+      "A reusable grouping for configuring a TLS client without
+       any consideration for how an underlying TCP session is
+       established.
+
+       Note that this grouping uses fairly typical descendant
+       node names such that a stack of 'uses' statements will
+       have name conflicts.  It is intended that the consuming
+       data model will resolve the issue (e.g., by wrapping
+       the 'uses' statement in a container called
+       'tls-client-parameters').  This model purposely does
+       not do this itself so as to provide maximum flexibility
+       to consuming models.";
+
+    container client-identity {
+      nacm:default-deny-write;
+      presence
+        "Indicates that a TLS-level client identity has been
+         configured.  This statement is present so the mandatory
+         descendant do not imply that this node must be configured.";
+      description
+        "Identity credentials the TLS client MAY present when
+         establishing a connection to a TLS server.  If not
+         configured, then client authentication is presumed to
+         occur a protocol layer above TLS.  When configured,
+         and requested by the TLS server when establishing a
+         TLS session, these credentials are passed in the
+         Certificate message defined in Section 7.4.2 of
+         RFC 5246 and Section 4.4.2 in RFC 8446.";
+      reference
+        "RFC 5246: The Transport Layer Security (TLS)
+                   Protocol Version 1.2
+         RFC 8446: The Transport Layer Security (TLS)
+                   Protocol Version 1.3
+         RFC CCCC: A YANG Data Model for a Keystore";
+      choice auth-type {
+        mandatory true;
+        description
+          "A choice amongst authentication types, of which one must
+           be enabled (via its associated 'feature') and selected.";
+        case certificate {
+          if-feature "client-ident-x509-cert";
+          container certificate {
+            description
+              "Specifies the client identity using a certificate.";
+            uses
+              ks:local-or-keystore-end-entity-cert-with-key-grouping{
+              refine "local-or-keystore/local/local-definition" {
+                must 'derived-from-or-self(public-key-format,'
+                   + ' "ct:subject-public-key-info-format")';
+              }
+              refine "local-or-keystore/keystore/keystore-reference"
+                   + "/asymmetric-key" {
+                must 'derived-from-or-self(deref(.)/../ks:public-'
+                   + 'key-format, "ct:subject-public-key-info-'
+                   + 'format")';
+              }
+            }
+          }
+        }
+        case raw-public-key {
+          if-feature "client-ident-raw-public-key";
+          container raw-private-key {
+            description
+              "Specifies the client identity using a raw
+               private key.";
+            uses ks:local-or-keystore-asymmetric-key-grouping {
+              refine "local-or-keystore/local/local-definition" {
+                must 'derived-from-or-self(public-key-format,'
+                   + ' "ct:subject-public-key-info-format")';
+              }
+              refine "local-or-keystore/keystore/keystore-reference"{
+                must 'derived-from-or-self(deref(.)/../ks:public-'
+                   + 'key-format, "ct:subject-public-key-info-'
+                   + 'format")';
+              }
+            }
+          }
+        }
+        case tls12-psk {
+          if-feature "client-ident-tls12-psk";
+          container tls12-psk {
+            description
+              "Specifies the client identity using a PSK (pre-shared
+               or pairwise-symmetric key).";
+            uses ks:local-or-keystore-symmetric-key-grouping;
+            leaf id {
+              type string;
+              description
+                "The key 'psk_identity' value used in the TLS
+                 'ClientKeyExchange' message.";
+              reference
+                "RFC 4279: Pre-Shared Key Ciphersuites for
+                           Transport Layer Security (TLS)";
+            }
+          }
+        }
+        case tls13-epsk {
+          if-feature "client-ident-tls13-epsk";
+          container tls13-epsk {
+            description
+              "An External Pre-Shared Key (EPSK) is established
+              or provisioned out-of-band, i.e., not from a TLS
+              connection.  An EPSK is a tuple of (Base Key,
+              External Identity, Hash).  External PSKs MUST NOT
+              be imported for (D)TLS 1.2 or prior versions.  When
+              PSKs are provisioned out of band, the PSK identity
+              and the KDF hash algorithm to be used with the PSK
+              MUST also be provisioned.
+
+              The structure of this container is designed
+              to satisfy the requirements of RFC 8446
+              Section 4.2.11, the recommendations from I-D
+              ietf-tls-external-psk-guidance Section 6,
+              and the EPSK input fields detailed in I-D
+              draft-ietf-tls-external-psk-importer
+              Section 3.1.  The base-key is based upon
+              ks:local-or-keystore-symmetric-key-grouping
+              in order to provide users with flexible and
+              secure storage options.";
+            reference
+              "RFC 8446: The Transport Layer Security (TLS)
+                         Protocol Version 1.3
+               I-D.ietf-tls-external-psk-importer:
+                         Importing External PSKs for TLS
+               I-D.ietf-tls-external-psk-guidance:
+                         Guidance for External PSK Usage in TLS";
+            uses ks:local-or-keystore-symmetric-key-grouping;
+            leaf external-identity {
+              type string;
+              mandatory true;
+              description
+                "As per Section 4.2.11 of RFC 8446, and Section 4.1
+                 of I-D. ietf-tls-external-psk-guidance:
+                 A sequence of bytes used to identify an EPSK. A
+                 label for a pre-shared key established externally.";
+              reference
+                "RFC 8446: The Transport Layer Security (TLS)
+                           Protocol Version 1.3
+                 I-D.ietf-tls-external-psk-guidance:
+                           Guidance for External PSK Usage in TLS";
+            }
+            leaf hash {
+              type tlscmn:epsk-supported-hash;
+              mandatory true;
+              description
+                "As per Section 4.2.11 of RFC 8446, for externally
+                 established PSKs, the Hash algorithm MUST be set
+                 when the PSK is established or default to SHA-256
+                 if no such algorithm is defined.  The server MUST
+                 ensure that it selects a compatible PSK (if any)
+                 and cipher suite.  Each PSK MUST only be used with
+                 a single hash function.";
+              reference
+                "RFC 8446: The Transport Layer Security (TLS)
+                           Protocol Version 1.3";
+            }
+            leaf context {
+              type string;
+              description
+                "As per Section 4.1 of I-D.
+                 ietf-tls-external-psk-guidance: Context may include
+                 information about peer roles or identities to
+                 mitigate Selfie-style reflection attacks [Selfie].
+                 If the EPSK is a key derived from some other
+                 protocol or sequence of protocols, context
+                 MUST include a channel binding for the deriving
+                 protocols [RFC5056].  The details of this binding
+                 are protocol specific.";
+              reference
+                "I-D.ietf-tls-external-psk-importer:
+                           Importing External PSKs for TLS
+                 I-D.ietf-tls-external-psk-guidance:
+                           Guidance for External PSK Usage in TLS";
+            }
+            leaf target-protocol {
+              type uint16;
+              description
+                "As per Section 3.1 of I-D.
+                 ietf-tls-external-psk-guidance:
+                 The protocol for which a PSK is imported for use.";
+              reference
+                "I-D.ietf-tls-external-psk-importer:
+                           Importing External PSKs for TLS";
+            }
+            leaf target-kdf {
+              type uint16;
+              description
+                "As per Section 3.1 of I-D.
+                 ietf-tls-external-psk-guidance:
+                 The specific Key Derivation Function (KDF) for which
+                 a PSK is imported for use.";
+              reference
+                "I-D.ietf-tls-external-psk-importer:
+                           Importing External PSKs for TLS";
+            }
+          }
+        }
+      }
+    } // container client-identity
+
+    container server-authentication {
+      nacm:default-deny-write;
+      must 'ca-certs or ee-certs or raw-public-keys or tls12-psks
+        or tls13-epsks';
+      description
+        "Specifies how the TLS client can authenticate TLS servers.
+         Any combination of credentials is additive and unordered.
+
+         Note that no configuration is required for PSK (pre-shared
+         or pairwise-symmetric key) based authentication as the key
+         is necessarily the same as configured in the '../client-
+         identity' node.";
+      container ca-certs {
+        if-feature "server-auth-x509-cert";
+        presence
+          "Indicates that CA certificates have been configured.
+           This statement is present so the mandatory descendant
+           nodes do not imply that this node must be configured.";
+        description
+          "A set of certificate authority (CA) certificates used by
+           the TLS client to authenticate TLS server certificates.
+           A server certificate is authenticated if it has a valid
+           chain of trust to a configured CA certificate.";
+        reference
+          "RFC BBBB: A YANG Data Model for a Truststore";
+        uses ts:local-or-truststore-certs-grouping;
+      }
+      container ee-certs {
+        if-feature "server-auth-x509-cert";
+        presence
+          "Indicates that EE certificates have been configured.
+           This statement is present so the mandatory descendant
+           nodes do not imply that this node must be configured.";
+        description
+          "A set of server certificates (i.e., end entity
+           certificates) used by the TLS client to authenticate
+           certificates presented by TLS servers.  A server
+           certificate is authenticated if it is an exact
+           match to a configured server certificate.";
+        reference
+          "RFC BBBB: A YANG Data Model for a Truststore";
+        uses ts:local-or-truststore-certs-grouping;
+      }
+      container raw-public-keys {
+        if-feature "server-auth-raw-public-key";
+        presence
+          "Indicates that raw public keys have been configured.
+           This statement is present so the mandatory descendant
+           nodes do not imply that this node must be configured.";
+        description
+          "A set of raw public keys used by the TLS client to
+           authenticate raw public keys presented by the TLS
+           server.  A raw public key is authenticated if it
+           is an exact match to a configured raw public key.";
+        reference
+          "RFC BBBB: A YANG Data Model for a Truststore";
+        uses ts:local-or-truststore-public-keys-grouping {
+          refine "local-or-truststore/local/local-definition/"
+               + "public-key" {
+            must 'derived-from-or-self(public-key-format,'
+               + ' "ct:subject-public-key-info-format")';
+          }
+          refine "local-or-truststore/truststore/truststore-"
+               + "reference" {
+            must 'not(deref(.)/../ts:public-key/ts:public-key-'
+               + 'format[not(derived-from-or-self(., "ct:subject-'
+               + 'public-key-info-format"))])';
+          }
+        }
+      }
+      leaf tls12-psks {
+        if-feature "server-auth-tls12-psk";
+        type empty;
+        description
+          "Indicates that the TLS client can authenticate TLS servers
+           using configure PSKs (pre-shared or pairwise-symmetric
+           keys).
+
+           No configuration is required since the PSK value is the
+           same as PSK value configured in the 'client-identity'
+           node.";
+      }
+      leaf tls13-epsks {
+        if-feature "server-auth-tls13-epsk";
+        type empty;
+        description
+          "Indicates that the TLS client can authenticate TLS servers
+           using configured external PSKs (pre-shared keys).
+
+           No configuration is required since the PSK value is the
+           same as PSK value configured in the 'client-identity'
+           node.";
+      }
+    } // container server-authentication
+
+    container hello-params {
+      nacm:default-deny-write;
+      if-feature "tlscmn:hello-params";
+      uses tlscmn:hello-params-grouping;
+      description
+        "Configurable parameters for the TLS hello message.";
+    } // container hello-params
+
+    container keepalives {
+      nacm:default-deny-write;
+      if-feature "tls-client-keepalives";
+      description
+        "Configures the keepalive policy for the TLS client.";
+      leaf peer-allowed-to-send {
+        type empty;
+        description
+          "Indicates that the remote TLS server is allowed to send
+           HeartbeatRequest messages, as defined by RFC 6520
+           to this TLS client.";
+        reference
+          "RFC 6520: Transport Layer Security (TLS) and Datagram
+           Transport Layer Security (DTLS) Heartbeat Extension";
+      }
+      container test-peer-aliveness {
+        presence
+          "Indicates that the TLS client proactively tests the
+           aliveness of the remote TLS server.";
+        description
+          "Configures the keep-alive policy to proactively test
+           the aliveness of the TLS server.  An unresponsive
+           TLS server is dropped after approximately max-wait
+           * max-attempts seconds.  The TLS client MUST send
+           HeartbeatRequest messages, as defined by RFC 6520.";
+        reference
+          "RFC 6520: Transport Layer Security (TLS) and Datagram
+           Transport Layer Security (DTLS) Heartbeat Extension";
+        leaf max-wait {
+          type uint16 {
+            range "1..max";
+          }
+          units "seconds";
+          default "30";
+          description
+            "Sets the amount of time in seconds after which if
+             no data has been received from the TLS server, a
+             TLS-level message will be sent to test the
+             aliveness of the TLS server.";
+        }
+        leaf max-attempts {
+          type uint8;
+          default "3";
+          description
+            "Sets the maximum number of sequential keep-alive
+             messages that can fail to obtain a response from
+             the TLS server before assuming the TLS server is
+             no longer alive.";
+        }
+      }
+    }
+  } // grouping tls-client-grouping
+
+}
diff --git a/transport/transport-tls/src/main/yang/ietf-tls-common@2022-12-12.yang b/transport/transport-tls/src/main/yang/ietf-tls-common@2022-12-12.yang
new file mode 100644 (file)
index 0000000..7c6c0c4
--- /dev/null
@@ -0,0 +1,311 @@
+module ietf-tls-common {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-tls-common";
+  prefix tlscmn;
+
+  import iana-tls-cipher-suite-algs {
+    prefix tlscsa;
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and SSH Servers";
+  }
+
+  import ietf-crypto-types {
+    prefix ct;
+    reference
+      "RFC AAAA: YANG Data Types and Groupings for Cryptography";
+  }
+
+  import ietf-keystore {
+    prefix ks;
+    reference
+      "RFC CCCC: A YANG Data Model for a Keystore";
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG List:  NETCONF WG list <mailto:netconf@ietf.org>
+     WG Web:   https://datatracker.ietf.org/wg/netconf
+     Author:   Kent Watsen <mailto:kent+ietf@watsen.net>
+     Author:   Jeff Hartley <mailto:jeff.hartley@commscope.com>
+     Author:   Gary Wu <mailto:garywu@cisco.com>";
+
+   description
+    "This module defines a common features and groupings for
+     Transport Layer Security (TLS).
+
+     Copyright (c) 2022 IETF Trust and the persons identified
+     as authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with
+     or without modification, is permitted pursuant to, and
+     subject to the license terms contained in, the Revised
+     BSD License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC FFFF
+     (https://www.rfc-editor.org/info/rfcFFFF); see the RFC
+     itself for full legal notices.
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
+     'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
+     'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
+     are to be interpreted as described in BCP 14 (RFC 2119)
+     (RFC 8174) when, and only when, they appear in all
+     capitals, as shown here.";
+
+  revision 2022-12-12 {
+    description
+      "Initial version";
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  // Features
+
+  feature tls10 {
+    status "obsolete";
+    description
+      "TLS Protocol Version 1.0 is supported.  TLS 1.0 is obsolete
+       and thus it is NOT RECOMMENDED to enable this feature.";
+    reference
+      "RFC 2246: The TLS Protocol Version 1.0";
+  }
+
+  feature tls11 {
+    status "obsolete";
+    description
+      "TLS Protocol Version 1.1 is supported.  TLS 1.1 is obsolete
+       and thus it is NOT RECOMMENDED to enable this feature.";
+    reference
+      "RFC 4346: The Transport Layer Security (TLS) Protocol
+                 Version 1.1";
+  }
+
+  feature tls12 {
+    status "deprecated";
+    description
+      "TLS Protocol Version 1.2 is supported  TLS 1.2 is obsolete
+       and thus it is NOT RECOMMENDED to enable this feature.";
+    reference
+      "RFC 5246: The Transport Layer Security (TLS) Protocol
+                 Version 1.2";
+  }
+
+  feature tls13 {
+    description
+      "TLS Protocol Version 1.3 is supported.";
+    reference
+      "RFC 8446: The Transport Layer Security (TLS)
+                 Protocol Version 1.3";
+  }
+
+  feature hello-params {
+    description
+      "TLS hello message parameters are configurable.";
+  }
+
+  feature public-key-generation {
+    description
+      "Indicates that the server implements the
+       'generate-public-key' RPC.";
+  }
+
+  // Identities
+
+  identity tls-version-base {
+    description
+      "Base identity used to identify TLS protocol versions.";
+  }
+
+  identity tls10 {
+    if-feature "tls10";
+    base tls-version-base;
+    status "obsolete";
+    description
+      "TLS Protocol Version 1.0.";
+    reference
+      "RFC 2246: The TLS Protocol Version 1.0";
+  }
+
+  identity tls11 {
+    if-feature "tls11";
+    base tls-version-base;
+    status "obsolete";
+    description
+      "TLS Protocol Version 1.1.";
+    reference
+      "RFC 4346: The Transport Layer Security (TLS) Protocol
+                 Version 1.1";
+  }
+
+  identity tls12 {
+    if-feature "tls12";
+    base tls-version-base;
+    status "deprecated";
+    description
+      "TLS Protocol Version 1.2.";
+    reference
+      "RFC 5246: The Transport Layer Security (TLS) Protocol
+                 Version 1.2";
+  }
+
+  identity tls13 {
+    if-feature "tls13";
+    base tls-version-base;
+    description
+      "TLS Protocol Version 1.3.";
+    reference
+      "RFC 8446: The Transport Layer Security (TLS)
+                 Protocol Version 1.3";
+  }
+
+  typedef epsk-supported-hash {
+    type enumeration {
+      enum sha-256 {
+        description
+          "The SHA-256 Hash.";
+      }
+      enum sha-384 {
+        description
+          "The SHA-384 Hash.";
+      }
+    }
+    description
+      "As per Section 4.2.11 of RFC 8446, the hash algorithm
+       supported by an instance of an External Pre-Shared
+       Key (EPSK).";
+    reference
+      "RFC 8446: The Transport Layer Security (TLS)
+                 Protocol Version 1.3
+       I-D.ietf-tls-external-psk-importer: Importing
+                 External PSKs for TLS
+       I-D.ietf-tls-external-psk-guidance: Guidance
+                 for External PSK Usage in TLS";
+  }
+
+  // Groupings
+
+  grouping hello-params-grouping {
+    description
+      "A reusable grouping for TLS hello message parameters.";
+    reference
+      "RFC 5246: The Transport Layer Security (TLS) Protocol
+                 Version 1.2
+       RFC 8446: The Transport Layer Security (TLS) Protocol
+                 Version 1.3";
+    container tls-versions {
+      description
+        "Parameters regarding TLS versions.";
+      leaf-list tls-version {
+        type identityref {
+          base tls-version-base;
+        }
+        description
+          "Acceptable TLS protocol versions.
+
+           If this leaf-list is not configured (has zero elements)
+           the acceptable TLS protocol versions are implementation-
+           defined.";
+      }
+    }
+    container cipher-suites {
+      description
+        "Parameters regarding cipher suites.";
+      leaf-list cipher-suite {
+        type identityref {
+          base tlscsa:cipher-suite-alg-base;
+        }
+        ordered-by user;
+        description
+          "Acceptable cipher suites in order of descending
+           preference.  The configured host key algorithms should
+           be compatible with the algorithm used by the configured
+           private key.  Please see Section 5 of RFC FFFF for
+           valid combinations.
+
+           If this leaf-list is not configured (has zero elements)
+           the acceptable cipher suites are implementation-
+           defined.";
+        reference
+          "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+      }
+    }
+  } // hello-params-grouping
+
+  rpc generate-public-key {
+    if-feature "public-key-generation";
+    description
+      "Requests the device to generate an public key using
+       the specified key algorithm.";
+    input {
+      leaf algorithm {
+        type tlscsa:cipher-suite-algorithm-ref;
+        mandatory true;
+        description
+          "The cipher suite algorithm that the generated key is
+           to work with.  Implementations derive the public key
+           algorithm from the cipher suite algorithm.  Example:
+           cipher suite 'tls-rsa-with-aes-256-cbc-sha256' maps
+           to the RSA public key.";
+      }
+      leaf bits {
+        type uint16;
+        description
+          "Specifies the number of bits in the key to create.
+           For RSA keys, the minimum size is 1024 bits and
+           the default is 3072 bits. Generally, 3072 bits is
+           considered sufficient. DSA keys must be exactly 1024
+           bits as specified by FIPS 186-2.  For elliptical
+           keys, the 'bits' value determines the key length
+           of the curve (e.g., 256, 384 or 521), where valid
+           values supported by the server are conveyed via an
+           unspecified mechanism.  For some public algorithms,
+           the keys have a fixed length and the 'bits' value,
+           if specified, will be ignored.";
+      }
+      choice private-key-encoding {
+        default cleartext;
+        description
+          "A choice amongst optional private key handling.";
+        case cleartext {
+          leaf cleartext {
+            type empty;
+            description
+              "Indicates that the private key is to be returned
+               as a cleartext value.";
+          }
+        }
+        case encrypt {
+          if-feature "ct:private-key-encryption";
+          container encrypt-with {
+            description
+               "Indicates that the key is to be encrypted using
+                the specified symmetric or asymmetric key.";
+            uses ks:encrypted-by-choice-grouping;
+          }
+        }
+        case hide {
+          if-feature "ct:hidden-keys";
+          leaf hide {
+            type empty;
+            description
+              "Indicates that the private key is to be hidden.
+
+               Unlike the 'cleartext' and 'encrypt' options, the
+               key returned is a placeholder for an internally
+               stored key.  See the 'Support for Built-in Keys'
+               section in RFC CCCC for information about hidden
+               keys.";
+          }
+        }
+      }
+    }
+    output {
+      uses ct:asymmetric-key-pair-grouping;
+    }
+  } // end generate-public-key
+
+}
diff --git a/transport/transport-tls/src/main/yang/ietf-tls-server@2022-12-12.yang b/transport/transport-tls/src/main/yang/ietf-tls-server@2022-12-12.yang
new file mode 100644 (file)
index 0000000..4fb37ef
--- /dev/null
@@ -0,0 +1,526 @@
+module ietf-tls-server {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-tls-server";
+  prefix tlss;
+
+  import ietf-netconf-acm {
+    prefix nacm;
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+
+  import ietf-crypto-types {
+    prefix ct;
+    reference
+      "RFC AAAA: YANG Data Types and Groupings for Cryptography";
+  }
+
+  import ietf-truststore {
+    prefix ts;
+    reference
+      "RFC BBBB: A YANG Data Model for a Truststore";
+  }
+
+  import ietf-keystore {
+    prefix ks;
+    reference
+      "RFC CCCC: A YANG Data Model for a Keystore";
+  }
+
+  import ietf-tls-common {
+    prefix tlscmn;
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG List:  NETCONF WG list <mailto:netconf@ietf.org>
+     WG Web:   https://datatracker.ietf.org/wg/netconf
+     Author:   Kent Watsen <mailto:kent+ietf@watsen.net>
+     Author:   Jeff Hartley <mailto:jeff.hartley@commscope.com>";
+
+  description
+    "This module defines reusable groupings for TLS servers that
+     can be used as a basis for specific TLS server instances.
+
+     Copyright (c) 2022 IETF Trust and the persons identified
+     as authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with
+     or without modification, is permitted pursuant to, and
+     subject to the license terms contained in, the Revised
+     BSD License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC FFFF
+     (https://www.rfc-editor.org/info/rfcFFFF); see the RFC
+     itself for full legal notices.
+
+     The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
+     'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
+     'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
+     are to be interpreted as described in BCP 14 (RFC 2119)
+     (RFC 8174) when, and only when, they appear in all
+     capitals, as shown here.";
+
+  revision 2022-12-12 {
+    description
+      "Initial version";
+    reference
+      "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers";
+  }
+
+  // Features
+
+  feature tls-server-keepalives {
+    description
+      "Per socket TLS keepalive parameters are configurable for
+       TLS servers on the server implementing this feature.";
+  }
+
+  feature server-ident-x509-cert {
+    description
+      "Indicates that the server supports identifying itself
+       using X.509 certificates.";
+    reference
+      "RFC 5280:
+         Internet X.509 Public Key Infrastructure Certificate
+         and Certificate Revocation List (CRL) Profile";
+  }
+
+  feature server-ident-raw-public-key {
+    description
+      "Indicates that the server supports identifying itself
+       using raw public keys.";
+    reference
+      "RFC 7250:
+         Using Raw Public Keys in Transport Layer Security (TLS)
+         and Datagram Transport Layer Security (DTLS)";
+  }
+
+  feature server-ident-tls12-psk {
+    description
+      "Indicates that the server supports identifying itself
+       using TLS-1.2 PSKs (pre-shared or pairwise-symmetric keys).";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for Transport Layer Security
+         (TLS)";
+  }
+
+  feature server-ident-tls13-epsk {
+    description
+      "Indicates that the server supports identifying itself
+       using TLS-1.3 External PSKs (pre-shared keys).";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  feature client-auth-supported {
+    description
+      "Indicates that the configuration for how to authenticate
+       clients can be configured herein.  TLS-level client
+       authentication may not be needed when client authentication
+       is expected to occur only at another protocol layer.";
+  }
+
+  feature client-auth-x509-cert {
+    description
+      "Indicates that the server supports authenticating clients
+       using X.509 certificates.";
+    reference
+      "RFC 5280:
+         Internet X.509 Public Key Infrastructure Certificate
+         and Certificate Revocation List (CRL) Profile";
+  }
+
+  feature client-auth-raw-public-key {
+    description
+      "Indicates that the server supports authenticating clients
+       using raw public keys.";
+    reference
+      "RFC 7250:
+         Using Raw Public Keys in Transport Layer Security (TLS)
+         and Datagram Transport Layer Security (DTLS)";
+  }
+
+  feature client-auth-tls12-psk {
+    description
+      "Indicates that the server supports authenticating clients
+       using PSKs (pre-shared or pairwise-symmetric keys).";
+    reference
+      "RFC 4279:
+         Pre-Shared Key Ciphersuites for Transport Layer Security
+         (TLS)";
+  }
+
+  feature client-auth-tls13-epsk {
+    description
+      "Indicates that the server supports authenticating clients
+       using TLS-1.3 External PSKs (pre-shared keys).";
+    reference
+      "RFC 8446:
+         The Transport Layer Security (TLS) Protocol Version 1.3";
+  }
+
+  // Groupings
+
+  grouping tls-server-grouping {
+    description
+      "A reusable grouping for configuring a TLS server without
+       any consideration for how underlying TCP sessions are
+       established.
+
+       Note that this grouping uses fairly typical descendant
+       node names such that a stack of 'uses' statements will
+       have name conflicts.  It is intended that the consuming
+       data model will resolve the issue (e.g., by wrapping
+       the 'uses' statement in a container called
+       'tls-server-parameters').  This model purposely does
+       not do this itself so as to provide maximum flexibility
+       to consuming models.";
+
+    container server-identity {
+      nacm:default-deny-write;
+      description
+        "A locally-defined or referenced end-entity certificate,
+         including any configured intermediate certificates, the
+         TLS server will present when establishing a TLS connection
+         in its Certificate message, as defined in Section 7.4.2
+         in RFC 5246 and Section 4.4.2 in RFC 8446.";
+      reference
+        "RFC 5246: The Transport Layer Security (TLS) Protocol
+                   Version 1.2
+         RFC 8446: The Transport Layer Security (TLS) Protocol
+                   Version 1.3
+         RFC CCCC: A YANG Data Model for a Keystore";
+      choice auth-type {
+        mandatory true;
+        description
+          "A choice amongst authentication types, of which one must
+           be enabled (via its associated 'feature') and selected.";
+        case certificate {
+          if-feature "server-ident-x509-cert";
+          container certificate {
+            description
+              "Specifies the server identity using a certificate.";
+            uses
+              ks:local-or-keystore-end-entity-cert-with-key-grouping{
+              refine "local-or-keystore/local/local-definition" {
+                must 'derived-from-or-self(public-key-format,'
+                   + ' "ct:subject-public-key-info-format")';
+              }
+              refine "local-or-keystore/keystore/keystore-reference"
+                   + "/asymmetric-key" {
+                must 'derived-from-or-self(deref(.)/../ks:public-'
+                   + 'key-format, "ct:subject-public-key-info-'
+                   + 'format")';
+              }
+            }
+          }
+        }
+        case raw-private-key {
+          if-feature "server-ident-raw-public-key";
+          container raw-private-key {
+            description
+              "Specifies the server identity using a raw
+               private key.";
+            uses ks:local-or-keystore-asymmetric-key-grouping {
+              refine "local-or-keystore/local/local-definition" {
+                must 'derived-from-or-self(public-key-format,'
+                   + ' "ct:subject-public-key-info-format")';
+              }
+              refine "local-or-keystore/keystore/keystore-reference"{
+                must 'derived-from-or-self(deref(.)/../ks:public-'
+                   + 'key-format, "ct:subject-public-key-info-'
+                   + 'format")';
+              }
+            }
+          }
+        }
+        case tls12-psk {
+          if-feature "server-ident-tls12-psk";
+          container tls12-psk {
+            description
+              "Specifies the server identity using a PSK (pre-shared
+               or pairwise-symmetric key).";
+            uses ks:local-or-keystore-symmetric-key-grouping;
+            leaf id_hint {
+              type string;
+              description
+                "The key 'psk_identity_hint' value used in the TLS
+                 'ServerKeyExchange' message.";
+              reference
+                "RFC 4279: Pre-Shared Key Ciphersuites for
+                           Transport Layer Security (TLS)";
+            }
+          }
+        }
+        case tls13-epsk {
+          if-feature "server-ident-tls13-epsk";
+          container tls13-epsk {
+            description
+              "An External Pre-Shared Key (EPSK) is established
+              or provisioned out-of-band, i.e., not from a TLS
+              connection.  An EPSK is a tuple of (Base Key,
+              External Identity, Hash).  External PSKs MUST
+              NOT be imported for (D)TLS 1.2 or prior versions.
+              When PSKs are provisioned out of band, the PSK
+              identity and the KDF hash algorithm to be used
+              with the PSK MUST also be provisioned.
+
+              The structure of this container is designed
+              to satisfy the requirements of RFC 8446
+              Section 4.2.11, the recommendations from
+              I-D ietf-tls-external-psk-guidance Section 6,
+              and the EPSK input fields detailed in
+              I-D draft-ietf-tls-external-psk-importer
+              Section 3.1.  The base-key is based upon
+              ks:local-or-keystore-symmetric-key-grouping
+              in order to provide users with flexible and
+              secure storage options.";
+            reference
+              "RFC 8446: The Transport Layer Security (TLS)
+                         Protocol Version 1.3
+               I-D.ietf-tls-external-psk-importer: Importing
+                         External PSKs for TLS
+               I-D.ietf-tls-external-psk-guidance: Guidance
+                         for External PSK Usage in TLS";
+            uses ks:local-or-keystore-symmetric-key-grouping;
+            leaf external-identity {
+              type string;
+              mandatory true;
+              description
+                "As per Section 4.2.11 of RFC 8446, and Section 4.1
+                 of I-D. ietf-tls-external-psk-guidance: A sequence
+                 of bytes used to identify an EPSK. A label for a
+                 pre-shared key established externally.";
+              reference
+                "RFC 8446: The Transport Layer Security (TLS)
+                           Protocol Version 1.3
+                 I-D.ietf-tls-external-psk-guidance:
+                           Guidance for External PSK Usage in TLS";
+            }
+            leaf hash {
+              type tlscmn:epsk-supported-hash;
+              mandatory true;
+              description
+                "As per Section 4.2.11 of RFC 8446, for externally
+                 established PSKs, the Hash algorithm MUST be set
+                 when the PSK is established or default to SHA-256
+                 if no such algorithm is defined.  The server MUST
+                 ensure that it selects a compatible PSK (if any)
+                 and cipher suite.  Each PSK MUST only be used
+                 with a single hash function.";
+              reference
+                "RFC 8446: The Transport Layer Security (TLS)
+                           Protocol Version 1.3";
+            }
+            leaf context {
+              type string;
+              description
+                "As per Section 4.1 of I-D.
+                 ietf-tls-external-psk-guidance: Context
+                 may include information about peer roles or
+                 identities to mitigate Selfie-style reflection
+                 attacks [Selfie].  If the EPSK is a key derived
+                 from some other protocol or sequence of protocols,
+                 context MUST include a channel binding for the
+                 deriving protocols [RFC5056].  The details of
+                 this binding are protocol specific.";
+              reference
+                "I-D.ietf-tls-external-psk-importer:
+                           Importing External PSKs for TLS
+                 I-D.ietf-tls-external-psk-guidance:
+                           Guidance for External PSK Usage in TLS";
+            }
+            leaf target-protocol {
+              type uint16;
+              description
+                "As per Section 3.1 of I-D.
+                 ietf-tls-external-psk-guidance: The protocol
+                 for which a PSK is imported for use.";
+              reference
+                "I-D.ietf-tls-external-psk-importer:
+                           Importing External PSKs for TLS";
+            }
+            leaf target-kdf {
+              type uint16;
+              description
+                "As per Section 3.1 of I-D.
+                 ietf-tls-external-psk-guidance: The specific Key
+                 Derivation Function (KDF) for which a PSK is
+                 imported for use.";
+              reference
+                "I-D.ietf-tls-external-psk-importer:
+                           Importing External PSKs for TLS";
+            }
+          }
+        }
+      }
+    } // container server-identity
+
+    container client-authentication {
+      if-feature "client-auth-supported";
+      nacm:default-deny-write;
+      must 'ca-certs or ee-certs or raw-public-keys or tls12-psks
+        or tls13-epsks';
+      presence
+        "Indicates that client authentication is supported (i.e.,
+         that the server will request clients send certificates).
+         If not configured, the TLS server SHOULD NOT request the
+         TLS clients provide authentication credentials.";
+      description
+        "Specifies how the TLS server can authenticate TLS clients.
+         Any combination of credentials is additive and unordered.
+
+         Note that no configuration is required for PSK (pre-shared
+         or pairwise-symmetric key) based authentication as the key
+         is necessarily the same as configured in the '../server-
+         identity' node.";
+      container ca-certs {
+        if-feature "client-auth-x509-cert";
+        presence
+          "Indicates that CA certificates have been configured.
+           This statement is present so the mandatory descendant
+           nodes do not imply that this node must be configured.";
+        description
+          "A set of certificate authority (CA) certificates used by
+           the TLS server to authenticate TLS client certificates.
+           A client certificate is authenticated if it has a valid
+           chain of trust to a configured CA certificate.";
+        reference
+          "RFC BBBB: A YANG Data Model for a Truststore";
+        uses ts:local-or-truststore-certs-grouping;
+      }
+      container ee-certs {
+        if-feature "client-auth-x509-cert";
+        presence
+          "Indicates that EE certificates have been configured.
+           This statement is present so the mandatory descendant
+           nodes do not imply that this node must be configured.";
+        description
+          "A set of client certificates (i.e., end entity
+           certificates) used by the TLS server to authenticate
+           certificates presented by TLS clients. A client
+           certificate is authenticated if it is an exact
+           match to a configured client certificate.";
+        reference
+          "RFC BBBB: A YANG Data Model for a Truststore";
+        uses ts:local-or-truststore-certs-grouping;
+      }
+      container raw-public-keys {
+        if-feature "client-auth-raw-public-key";
+        presence
+          "Indicates that raw public keys have been configured.
+           This statement is present so the mandatory descendant
+           nodes do not imply that this node must be configured.";
+        description
+          "A set of raw public keys used by the TLS server to
+           authenticate raw public keys presented by the TLS
+           client.  A raw public key is authenticated if it
+           is an exact match to a configured raw public key.";
+        reference
+          "RFC BBBB: A YANG Data Model for a Truststore";
+        uses ts:local-or-truststore-public-keys-grouping {
+          refine "local-or-truststore/local/local-definition/"
+               + "public-key" {
+            must 'derived-from-or-self(public-key-format,'
+               + ' "ct:subject-public-key-info-format")';
+          }
+          refine "local-or-truststore/truststore/truststore-"
+               + "reference" {
+            must 'not(deref(.)/../ts:public-key/ts:public-key-'
+               + 'format[not(derived-from-or-self(., "ct:subject-'
+               + 'public-key-info-format"))])';
+          }
+        }
+      }
+      leaf tls12-psks {
+        if-feature "client-auth-tls12-psk";
+        type empty;
+        description
+          "Indicates that the TLS server can authenticate TLS clients
+           using configured PSKs (pre-shared or pairwise-symmetric
+           keys).
+
+           No configuration is required since the PSK value is the
+           same as PSK value configured in the 'server-identity'
+           node.";
+      }
+      leaf tls13-epsks {
+        if-feature "client-auth-tls13-epsk";
+        type empty;
+        description
+          "Indicates that the TLS 1.3 server can authenticate TLS
+           clients using configured external PSKs (pre-shared keys).
+
+           No configuration is required since the PSK value is the
+           same as PSK value configured in the 'server-identity'
+           node.";
+      }
+    } // container client-authentication
+
+    container hello-params {
+      nacm:default-deny-write;
+      if-feature "tlscmn:hello-params";
+      uses tlscmn:hello-params-grouping;
+      description
+        "Configurable parameters for the TLS hello message.";
+    } // container hello-params
+
+    container keepalives {
+      nacm:default-deny-write;
+      if-feature "tls-server-keepalives";
+      description
+        "Configures the keepalive policy for the TLS server.";
+      leaf peer-allowed-to-send {
+        type empty;
+        description
+          "Indicates that the remote TLS client is allowed to send
+           HeartbeatRequest messages, as defined by RFC 6520
+           to this TLS server.";
+        reference
+          "RFC 6520: Transport Layer Security (TLS) and Datagram
+           Transport Layer Security (DTLS) Heartbeat Extension";
+      }
+      container test-peer-aliveness {
+        presence
+          "Indicates that the TLS server proactively tests the
+           aliveness of the remote TLS client.";
+        description
+          "Configures the keep-alive policy to proactively test
+           the aliveness of the TLS client.  An unresponsive
+           TLS client is dropped after approximately max-wait
+           * max-attempts seconds.";
+        leaf max-wait {
+          type uint16 {
+            range "1..max";
+          }
+          units "seconds";
+          default "30";
+          description
+            "Sets the amount of time in seconds after which if
+             no data has been received from the TLS client, a
+             TLS-level message will be sent to test the
+             aliveness of the TLS client.";
+        }
+        leaf max-attempts {
+          type uint8;
+          default "3";
+          description
+            "Sets the maximum number of sequential keep-alive
+             messages that can fail to obtain a response from
+             the TLS client before assuming the TLS client is
+             no longer alive.";
+        }
+      }
+    } // container keepalives
+  } // grouping tls-server-grouping
+
+}
diff --git a/transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/ConfigUtilsTest.java b/transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/ConfigUtilsTest.java
new file mode 100644 (file)
index 0000000..acd9df1
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.opendaylight.netconf.transport.tls.ConfigUtils.DEFAULT_CERTIFICATE_ALIAS;
+import static org.opendaylight.netconf.transport.tls.ConfigUtils.DEFAULT_PRIVATE_KEY_ALIAS;
+import static org.opendaylight.netconf.transport.tls.ConfigUtils.EMPTY_SECRET;
+import static org.opendaylight.netconf.transport.tls.TestUtils.buildAsymmetricKeyGrouping;
+import static org.opendaylight.netconf.transport.tls.TestUtils.buildEndEntityCertWithKeyGrouping;
+import static org.opendaylight.netconf.transport.tls.TestUtils.buildLocalOrTruststore;
+import static org.opendaylight.netconf.transport.tls.TestUtils.generateX509CertData;
+
+import java.security.KeyStore;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.EcPrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.PrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.PublicKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.RsaPrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.SshPublicKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.SubjectPublicKeyInfoFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.server.authentication.CaCerts;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.server.authentication.CaCertsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.server.authentication.EeCerts;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.server.authentication.EeCertsBuilder;
+
+class ConfigUtilsTest {
+
+    private KeyStore keyStore;
+
+    @BeforeEach
+    void setup() throws Exception {
+        keyStore = KeyStoreUtils.newKeyStore();
+    }
+
+    @Test
+    void setX509Certificates() throws Exception {
+        final var rsaCertData = generateX509CertData("RSA");
+        final var ecCertData = generateX509CertData("EC");
+
+        // not defined -- ignore
+        ConfigUtils.setX509Certificates(keyStore, null, null);
+        assertFalse(keyStore.aliases().hasMoreElements());
+
+        // defined
+        final var localOrTruststore = buildLocalOrTruststore(
+                Map.of("cert-rsa", rsaCertData.certBytes(), "cert-ec", ecCertData.certBytes()));
+        final CaCerts caCerts = new CaCertsBuilder().setLocalOrTruststore(localOrTruststore).build();
+        final EeCerts eeCerts = new EeCertsBuilder().setLocalOrTruststore(localOrTruststore).build();
+        ConfigUtils.setX509Certificates(keyStore, caCerts, eeCerts);
+
+        final List<String> aliases = Collections.list(keyStore.aliases());
+        final Set<String> expectedAliases = Set.of("ca-cert-rsa", "ca-cert-ec", "ee-cert-rsa", "ee-cert-ec");
+        assertNotNull(aliases);
+        assertEquals(4, aliases.size());
+        assertEquals(expectedAliases, Set.copyOf(aliases));
+        for (String alias : aliases) {
+            assertTrue(keyStore.isCertificateEntry(alias));
+            assertNotNull(keyStore.getCertificate(alias));
+        }
+    }
+
+    @ParameterizedTest(name = "Set private key from pair: {0}")
+    @MethodSource("asymmetricKeyArgs")
+    @Disabled
+        // raw public key is not implemented yet
+    void setPrivateKeyFromKeyPair(final String testDesc,
+            final PublicKeyFormat publicKeyFormat, final byte[] publicKeyBytes,
+            final PrivateKeyFormat privateKeyFormat, final byte[] privateKeyBytes,
+            final byte[] certificateBytes) throws Exception {
+        final var rawPrivateKey = buildAsymmetricKeyGrouping(publicKeyFormat, publicKeyBytes,
+                privateKeyFormat, privateKeyBytes);
+        ConfigUtils.setAsymmetricKey(keyStore, rawPrivateKey);
+        assertTrue(keyStore.containsAlias(DEFAULT_PRIVATE_KEY_ALIAS));
+        assertTrue(keyStore.isKeyEntry(DEFAULT_PRIVATE_KEY_ALIAS));
+        assertNotNull(keyStore.getKey(DEFAULT_PRIVATE_KEY_ALIAS, EMPTY_SECRET));
+    }
+
+    @ParameterizedTest(name = "End entity certificate: {0}")
+    @MethodSource("asymmetricKeyArgs")
+    void setEndEntityCertificateWithKey(final String testDesc,
+            final PublicKeyFormat publicKeyFormat, final byte[] publicKeyBytes,
+            final PrivateKeyFormat privateKeyFormat, final byte[] privateKeyBytes,
+            final byte[] certificateBytes) throws Exception {
+        final var endEntityCert = buildEndEntityCertWithKeyGrouping(publicKeyFormat, publicKeyBytes,
+                privateKeyFormat, privateKeyBytes, certificateBytes);
+        ConfigUtils.setEndEntityCertificateWithKey(keyStore, endEntityCert);
+
+        assertTrue(keyStore.containsAlias(DEFAULT_PRIVATE_KEY_ALIAS));
+        assertTrue(keyStore.isKeyEntry(DEFAULT_PRIVATE_KEY_ALIAS));
+        assertNotNull(keyStore.getKey(DEFAULT_PRIVATE_KEY_ALIAS, EMPTY_SECRET));
+
+        assertTrue(keyStore.containsAlias(DEFAULT_CERTIFICATE_ALIAS));
+        assertTrue(keyStore.isCertificateEntry(DEFAULT_CERTIFICATE_ALIAS));
+        assertNotNull(keyStore.getCertificate(DEFAULT_CERTIFICATE_ALIAS));
+    }
+
+    private static Stream<Arguments> asymmetricKeyArgs() throws Exception {
+        // (test case descriptor, public key format, public key bytes, private key format, private key bytes,
+        // certificate bytes)
+        final var rsaCertData = generateX509CertData("RSA");
+        final var ecCertData = generateX509CertData("EC");
+        return Stream.of(
+                Arguments.of("RSA / subject-public-key-info",
+                        SubjectPublicKeyInfoFormat.VALUE, rsaCertData.publicKey(),
+                        RsaPrivateKeyFormat.VALUE, rsaCertData.privateKey(),
+                        rsaCertData.certBytes()),
+                Arguments.of("RSA / ssh-public-key",
+                        SshPublicKeyFormat.VALUE, rsaCertData.sshPublicKey(),
+                        RsaPrivateKeyFormat.VALUE, rsaCertData.privateKey(),
+                        rsaCertData.certBytes()),
+                Arguments.of("EC / subject-public-key-info",
+                        SubjectPublicKeyInfoFormat.VALUE, ecCertData.publicKey(),
+                        EcPrivateKeyFormat.VALUE, ecCertData.privateKey(),
+                        ecCertData.certBytes()),
+                Arguments.of("EC / ssh-public-key",
+                        SshPublicKeyFormat.VALUE, ecCertData.sshPublicKey(),
+                        EcPrivateKeyFormat.VALUE, ecCertData.privateKey(),
+                        ecCertData.certBytes())
+        );
+    }
+}
diff --git a/transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/TestUtils.java b/transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/TestUtils.java
new file mode 100644 (file)
index 0000000..6f55460
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
+import org.bouncycastle.crypto.util.PublicKeyFactory;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.EndEntityCertCms;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.PrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.PublicKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.TrustAnchorCertCms;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.asymmetric.key.pair.grouping._private.key.type.CleartextPrivateKeyBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212.LocalOrKeystoreAsymmetricKeyGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212.LocalOrKeystoreEndEntityCertWithKeyGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.tls.server.grouping.server.identity.auth.type.raw._private.key.RawPrivateKeyBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212.local.or.truststore.certs.grouping.LocalOrTruststore;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212.local.or.truststore.certs.grouping.local.or.truststore.local.local.definition.CertificateBuilder;
+
+public final class TestUtils {
+    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
+
+    private TestUtils() {
+        // utility class
+    }
+
+    public static LocalOrTruststore buildLocalOrTruststore(Map<String, byte[]> certNameToBytesMap) {
+        final var certMap = certNameToBytesMap.entrySet().stream()
+                .map(entry -> new CertificateBuilder()
+                        .setName(entry.getKey())
+                        .setCertData(new TrustAnchorCertCms(entry.getValue()))
+                        .build()
+                ).collect(Collectors.toMap(cert -> cert.key(), cert -> cert));
+        final var localDef = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212
+                .local.or.truststore.certs.grouping.local.or.truststore.local.LocalDefinitionBuilder()
+                .setCertificate(certMap).build();
+        return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.truststore.rev221212
+                .local.or.truststore.certs.grouping.local.or.truststore.LocalBuilder()
+                .setLocalDefinition(localDef).build();
+    }
+
+    public static LocalOrKeystoreAsymmetricKeyGrouping buildAsymmetricKeyGrouping(
+            final PublicKeyFormat publicKeyFormat, final byte[] publicKeyBytes,
+            final PrivateKeyFormat privateKeyFormat, final byte[] privateKeyBytes) {
+        final var localDef = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212
+                .local.or.keystore.asymmetric.key.grouping.local.or.keystore.local.LocalDefinitionBuilder()
+                .setPublicKeyFormat(publicKeyFormat)
+                .setPublicKey(publicKeyBytes)
+                .setPrivateKeyFormat(privateKeyFormat)
+                .setPrivateKeyType(new CleartextPrivateKeyBuilder().setCleartextPrivateKey(privateKeyBytes).build())
+                .build();
+        return new RawPrivateKeyBuilder()
+                .setLocalOrKeystore(
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212
+                                .local.or.keystore.asymmetric.key.grouping.local.or.keystore.LocalBuilder()
+                                .setLocalDefinition(localDef).build())
+                .build();
+    }
+
+    public static LocalOrKeystoreEndEntityCertWithKeyGrouping buildEndEntityCertWithKeyGrouping(
+            final PublicKeyFormat publicKeyFormat, final byte[] publicKeyBytes,
+            final PrivateKeyFormat privateKeyFormat, final byte[] privateKeyBytes, final byte[] certificateBytes) {
+        final var localDef = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212
+                .local.or.keystore.end.entity.cert.with.key.grouping.local.or.keystore.local.LocalDefinitionBuilder()
+                .setPublicKeyFormat(publicKeyFormat)
+                .setPublicKey(publicKeyBytes)
+                .setPrivateKeyFormat(privateKeyFormat)
+                .setPrivateKeyType(new CleartextPrivateKeyBuilder().setCleartextPrivateKey(privateKeyBytes).build())
+                .setCertData(new EndEntityCertCms(certificateBytes))
+                .build();
+        return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212
+                .tls.server.grouping.server.identity.auth.type.certificate.CertificateBuilder()
+                .setLocalOrKeystore(
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.keystore.rev221212
+                                .local.or.keystore.end.entity.cert.with.key.grouping.local.or.keystore.LocalBuilder()
+                                .setLocalDefinition(localDef).build())
+                .build();
+    }
+
+    public static X509CertData generateX509CertData(final String algorithm) throws Exception {
+        final var keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
+        if (isRSA(algorithm)) {
+            keyPairGenerator.initialize(new RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4), SECURE_RANDOM);
+        } else {
+            keyPairGenerator.initialize(new ECGenParameterSpec("secp256r1"), SECURE_RANDOM);
+        }
+        final var keyPair = keyPairGenerator.generateKeyPair();
+        final var certificate = generateCertificate(keyPair, isRSA(algorithm) ? "SHA256withRSA" : "SHA256withECDSA");
+        final var publicKeyBytes = keyPair.getPublic().getEncoded();
+        final var privateKeyBytes = keyPair.getPrivate().getEncoded();
+        return new X509CertData(certificate.getEncoded(), publicKeyBytes, privateKeyBytes,
+                OpenSSHPublicKeyUtil.encodePublicKey(PublicKeyFactory.createKey(publicKeyBytes)));
+    }
+
+    private static X509Certificate generateCertificate(final KeyPair keyPair, final String hashAlgorithm)
+            throws Exception {
+        final var now = Instant.now();
+        final var contentSigner = new JcaContentSignerBuilder(hashAlgorithm).build(keyPair.getPrivate());
+
+        final var x500Name = new X500Name("CN=TestCertificate");
+        final var certificateBuilder = new JcaX509v3CertificateBuilder(x500Name,
+                BigInteger.valueOf(now.toEpochMilli()),
+                Date.from(now), Date.from(now.plus(Duration.ofDays(365))),
+                x500Name,
+                keyPair.getPublic());
+        return new JcaX509CertificateConverter()
+                .setProvider(new BouncyCastleProvider()).getCertificate(certificateBuilder.build(contentSigner));
+    }
+
+    public static boolean isRSA(final String algorithm) {
+        return KeyUtils.RSA_ALGORITHM.equals(algorithm);
+    }
+
+    public record X509CertData(byte[] certBytes, byte[] publicKey, byte[] privateKey, byte[] sshPublicKey) {
+    }
+}
diff --git a/transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/TlsClientServerTest.java b/transport/transport-tls/src/test/java/org/opendaylight/netconf/transport/tls/TlsClientServerTest.java
new file mode 100644 (file)
index 0000000..87b752b
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.tls;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.EC_ALGORITHM;
+import static org.opendaylight.netconf.transport.tls.KeyUtils.RSA_ALGORITHM;
+import static org.opendaylight.netconf.transport.tls.TestUtils.buildEndEntityCertWithKeyGrouping;
+import static org.opendaylight.netconf.transport.tls.TestUtils.buildLocalOrTruststore;
+import static org.opendaylight.netconf.transport.tls.TestUtils.generateX509CertData;
+import static org.opendaylight.netconf.transport.tls.TestUtils.isRSA;
+
+import io.netty.channel.Channel;
+import io.netty.channel.EventLoopGroup;
+import io.netty.handler.ssl.SslHandler;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.opendaylight.netconf.transport.api.TransportChannel;
+import org.opendaylight.netconf.transport.api.TransportChannelListener;
+import org.opendaylight.netconf.transport.tcp.NettyTransportSupport;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.EcPrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.RsaPrivateKeyFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev221212.SubjectPublicKeyInfoFormat;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.client.rev221212.TcpClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev221212.TcpServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.TlsClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.ClientIdentityBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212.tls.client.grouping.ServerAuthenticationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.TlsServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.tls.server.grouping.ClientAuthenticationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212.tls.server.grouping.ServerIdentityBuilder;
+import org.opendaylight.yangtools.yang.common.Uint16;
+
+@ExtendWith(MockitoExtension.class)
+class TlsClientServerTest {
+
+    @Mock
+    private TcpClientGrouping tcpClientConfig;
+    @Mock
+    private TlsClientGrouping tlsClientConfig;
+    @Mock
+    private TransportChannelListener clientListener;
+    @Mock
+    private TcpServerGrouping tcpServerConfig;
+    @Mock
+    private TlsServerGrouping tlsServerConfig;
+    @Mock
+    private TransportChannelListener serverListener;
+
+    @Captor
+    ArgumentCaptor<TransportChannel> clientTransportChannelCaptor;
+    @Captor
+    ArgumentCaptor<TransportChannel> serverTransportChannelCaptor;
+
+    private static EventLoopGroup group;
+    private ServerSocket socket;
+
+    @BeforeAll
+    static void beforeAll() {
+        group = NettyTransportSupport.newEventLoopGroup("IntegrationTest");
+    }
+
+    @AfterAll
+    static void afterAll() {
+        group.shutdownGracefully();
+        group = null;
+    }
+
+    @BeforeEach
+    void beforeEach() throws IOException {
+
+        // create temp socket to get available port for test
+        socket = new ServerSocket(0);
+        final var localAddress = IetfInetUtil.INSTANCE.ipAddressFor(InetAddress.getLoopbackAddress());
+        final var localPort = new PortNumber(Uint16.valueOf(socket.getLocalPort()));
+        socket.close();
+
+        when(tcpServerConfig.getLocalAddress()).thenReturn(localAddress);
+        when(tcpServerConfig.requireLocalAddress()).thenCallRealMethod();
+        when(tcpServerConfig.getLocalPort()).thenReturn(localPort);
+        when(tcpServerConfig.requireLocalPort()).thenCallRealMethod();
+
+        when(tcpClientConfig.getRemoteAddress()).thenReturn(new Host(localAddress));
+        when(tcpClientConfig.requireRemoteAddress()).thenCallRealMethod();
+        when(tcpClientConfig.getRemotePort()).thenReturn(localPort);
+        when(tcpClientConfig.requireRemotePort()).thenCallRealMethod();
+    }
+
+    @ParameterizedTest(name = "TLS using X.509 certificates: {0}")
+    @ValueSource(strings = {RSA_ALGORITHM, EC_ALGORITHM})
+    void itWithCertificateConfig(final String algorithm) throws Exception {
+
+        final var data = generateX509CertData(algorithm);
+
+        // common config parts
+        var localOrKeystore = buildEndEntityCertWithKeyGrouping(
+                SubjectPublicKeyInfoFormat.VALUE, data.publicKey(),
+                isRSA(algorithm) ? RsaPrivateKeyFormat.VALUE : EcPrivateKeyFormat.VALUE,
+                data.privateKey(), data.certBytes()).getLocalOrKeystore();
+        var localOrTrustStore = buildLocalOrTruststore(Map.of("cert", data.certBytes()));
+
+        // client config
+        final var clientIdentity = new ClientIdentityBuilder()
+                .setAuthType(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212
+                        .tls.client.grouping.client.identity.auth.type.CertificateBuilder()
+                        .setCertificate(
+                                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212
+                                        .tls.client.grouping.client.identity.auth.type.certificate.CertificateBuilder()
+                                        .setLocalOrKeystore(localOrKeystore)
+                                        .build()).build()).build();
+        final var serverAuth = new ServerAuthenticationBuilder().setCaCerts(
+                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.client.rev221212
+                        .tls.client.grouping.server.authentication.CaCertsBuilder()
+                        .setLocalOrTruststore(localOrTrustStore).build()).build();
+        when(tlsClientConfig.getClientIdentity()).thenReturn(clientIdentity);
+        when(tlsClientConfig.getServerAuthentication()).thenReturn(serverAuth);
+
+        // server config
+        final var serverIdentity = new ServerIdentityBuilder()
+                .setAuthType(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212
+                        .tls.server.grouping.server.identity.auth.type.CertificateBuilder()
+                        .setCertificate(
+                                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212
+                                        .tls.server.grouping.server.identity.auth.type.certificate.CertificateBuilder()
+                                        .setLocalOrKeystore(localOrKeystore)
+                                        .build()).build()).build();
+        final var clientAuth = new ClientAuthenticationBuilder().setCaCerts(
+                new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev221212
+                        .tls.server.grouping.client.authentication.CaCertsBuilder()
+                        .setLocalOrTruststore(localOrTrustStore).build()).build();
+        when(tlsServerConfig.getServerIdentity()).thenReturn(serverIdentity);
+        when(tlsServerConfig.getClientAuthentication()).thenReturn(clientAuth);
+
+        integrationTest();
+    }
+
+    private void integrationTest() throws Exception {
+        // start server
+        final var server = TLSServer.listen(serverListener, NettyTransportSupport.newServerBootstrap().group(group),
+                tcpServerConfig, tlsServerConfig).get(2, TimeUnit.SECONDS);
+        try {
+            // connect with client
+            final var client = TLSClient.connect(clientListener, NettyTransportSupport.newBootstrap().group(group),
+                    tcpClientConfig, tlsClientConfig).get(2, TimeUnit.SECONDS);
+            try {
+                verify(serverListener, timeout(500))
+                        .onTransportChannelEstablished(serverTransportChannelCaptor.capture());
+                verify(clientListener, timeout(500))
+                        .onTransportChannelEstablished(clientTransportChannelCaptor.capture());
+                // validate channels are in expected state
+                var serverChannel = assertChannel(serverTransportChannelCaptor.getAllValues());
+                var clientChannel = assertChannel(clientTransportChannelCaptor.getAllValues());
+                // validate channels are connecting same sockets
+                assertEquals(serverChannel.remoteAddress(), clientChannel.localAddress());
+                assertEquals(serverChannel.localAddress(), clientChannel.remoteAddress());
+
+            } finally {
+                client.shutdown().get(2, TimeUnit.SECONDS);
+            }
+        } finally {
+            server.shutdown().get(2, TimeUnit.SECONDS);
+        }
+    }
+
+    private static Channel assertChannel(List<TransportChannel> transportChannels) {
+        assertNotNull(transportChannels);
+        assertEquals(1, transportChannels.size());
+        final var channel = assertInstanceOf(TLSTransportChannel.class, transportChannels.get(0)).channel();
+        assertNotNull(channel);
+        assertTrue(channel.isOpen()); // connection is open
+        assertNotNull(channel.pipeline().get(SslHandler.class)); //  has an SSL handler within a pipeline
+        return channel;
+    }
+}