Fix callhome device "DISCONNECTED" status 37/110637/3
authorOleksandr Zharov <oleksandr.zharov@pantheon.tech>
Mon, 11 Mar 2024 15:58:51 +0000 (16:58 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 13 Mar 2024 13:48:53 +0000 (14:48 +0100)
Fixed error when callhome device always has status "DISCONNECTED"
after adding it to allowed devices. This issue arose after refactoring
AuthorizedKeysDecoder class to use plain KeyStore access to acquire
provides. New code did not specify what exact provider we want to use
and thus caused confusion - instead of Bouncy Castle KeyFactory that
was used before new code returned Sun KeyFactory. That result in next
issue with searching for valid host key when adding new device and
all other errors that described in logs attached to Jira ticket.

JIRA: NETCONF-1249
Change-Id: I5689fa6ad173a5b7cd99f0210a366b77db74b0d5
Signed-off-by: Oleksandr Zharov <oleksandr.zharov@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/AuthorizedKeysDecoder.java

index e666ed1d1a3c6dacc0c0e53fdb1ec6d0931f7046..6f6e9d82cd6734ef07f4644cd8f716e3e65bbd98 100644 (file)
@@ -17,7 +17,9 @@ import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
 import java.security.KeyFactory;
 import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
 import java.security.PublicKey;
+import java.security.Security;
 import java.security.interfaces.DSAPublicKey;
 import java.security.interfaces.RSAPublicKey;
 import java.security.spec.DSAPublicKeySpec;
@@ -28,6 +30,7 @@ import java.util.Arrays;
 import org.bouncycastle.jce.ECNamedCurveTable;
 import org.bouncycastle.jce.ECPointUtil;
 import org.bouncycastle.jce.interfaces.ECPublicKey;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
 import org.bouncycastle.jce.spec.ECNamedCurveSpec;
 import org.eclipse.jdt.annotation.NonNull;
@@ -57,13 +60,24 @@ final class AuthorizedKeysDecoder {
     private static final String KEY_TYPE_ECDSA = "ecdsa-sha2-" + ECDSA_SUPPORTED_CURVE_NAME;
     private static final byte[] KEY_TYPE_ECDSA_BYTES = KEY_TYPE_ECDSA.getBytes(StandardCharsets.UTF_8);
 
-    private static final KeyFactory RSA_FACTORY = loadOrWarn("RSA");
-    private static final KeyFactory DSA_FACTORY = loadOrWarn("DSA");
-    private static final KeyFactory EC_FACTORY = loadOrWarn("EC");
+    private static final KeyFactory RSA_FACTORY;
+    private static final KeyFactory DSA_FACTORY;
+    private static final KeyFactory EC_FACTORY;
 
-    private static KeyFactory loadOrWarn(final String algorithm) {
+    static {
+        // Default provider fails to validate keys, see https://jira.opendaylight.org/browse/NETCONF-1249
+        var bcprov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
+        if (bcprov == null) {
+            bcprov = new BouncyCastleProvider();
+        }
+        RSA_FACTORY = loadOrWarn("RSA", bcprov);
+        DSA_FACTORY = loadOrWarn("DSA", bcprov);
+        EC_FACTORY = loadOrWarn("EC", bcprov);
+    }
+
+    private static KeyFactory loadOrWarn(final String algorithm, final Provider provider) {
         try {
-            return KeyFactory.getInstance(algorithm);
+            return KeyFactory.getInstance(algorithm, provider);
         } catch (NoSuchAlgorithmException e) {
             LOG.warn("KeyFactory for {} not found", algorithm, e);
             return null;