Skip to content

GNMI app accepts corrupted client key #2357

@ihrasko

Description

@ihrasko

Describe the bug
GNMI app accepts corrupted client key (correct one with manual harm, for example). Error occurs only when we are trying to connect device. device is not connected but user has not info about its status in GNMI topology. The logs are the only info.

Branch
main

To Reproduce
Steps to reproduce the behavior:

  1. Generate correct keys and certs.
  2. Manipulate keys and certs manually - break them :)
  3. Add manipulated keys to GNMI keystore.
  4. Try to add GBNMI device to topology.

For previous steps please follow https://github.com/PANTHEONtech/lighty/blob/main/lighty-examples/lighty-gnmi-community-restconf-app/README.md.
See also: #2355

Expected behavior
Keys are rejected when they are propagated to controller's keystore.

Logs

ERROR [opendaylight-cluster-data-notification-dispatcher-72] (DataTreeChangeListenerActor.java:99) - member-1-shard-topology-config: Error notifying listener BindingDOMDataTreeChangeListenerAdapter{listener=io.lighty.gnmi.southbound.listener.GnmiNodeListener@6d53245f}
org.bouncycastle.util.encoders.DecoderException: unable to decode base64 string: Index 3067 out of bounds for length 3067
        at org.bouncycastle.util.encoders.Base64.decode(Unknown Source)
        at org.bouncycastle.util.io.pem.PemReader.loadObject(Unknown Source)
        at org.bouncycastle.util.io.pem.PemReader.readPemObject(Unknown Source)
        at org.bouncycastle.openssl.PEMParser.readObject(Unknown Source)
        at io.lighty.aaa.util.AAAConfigUtils.decodePrivateKey(AAAConfigUtils.java:87)
        at io.lighty.gnmi.southbound.device.session.security.KeystoreGnmiSecurityProvider.getKeyPair(KeystoreGnmiSecurityProvider.java:103)
        at io.lighty.gnmi.southbound.device.session.security.KeystoreGnmiSecurityProvider.getSecurityWithCertificates(KeystoreGnmiSecurityProvider.java:86)
        at io.lighty.gnmi.southbound.device.session.security.KeystoreGnmiSecurityProvider.getSecurityFromKeystoreId(KeystoreGnmiSecurityProvider.java:75)
        at io.lighty.gnmi.southbound.device.session.security.KeystoreGnmiSecurityProvider.getSecurity(KeystoreGnmiSecurityProvider.java:47)
        at io.lighty.gnmi.southbound.device.connection.DeviceConnectionInitializer.initConnection(DeviceConnectionInitializer.java:66)
        at io.lighty.gnmi.southbound.device.connection.DeviceConnectionManager.connectDevice(DeviceConnectionManager.java:90)
        at io.lighty.gnmi.southbound.listener.GnmiNodeListener.connectNode(GnmiNodeListener.java:107)
        at io.lighty.gnmi.southbound.listener.GnmiNodeListener.onDataTreeChanged(GnmiNodeListener.java:75)
        at org.opendaylight.mdsal.binding.dom.adapter.BindingDOMDataTreeChangeListenerAdapter.onDataTreeChanged(BindingDOMDataTreeChangeListenerAdapter.java:56)
        at org.opendaylight.controller.cluster.datastore.DataTreeChangeListenerActor.dataTreeChanged(DataTreeChangeListenerActor.java:97)
        at org.opendaylight.controller.cluster.datastore.DataTreeChangeListenerActor.handleReceive(DataTreeChangeListenerActor.java:55)
        at org.apache.pekko.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:33)
        at org.apache.pekko.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:29)
        at scala.PartialFunction.applyOrElse(PartialFunction.scala:214)
        at scala.PartialFunction.applyOrElse$(PartialFunction.scala:213)
        at org.apache.pekko.japi.pf.UnitCaseStatement.applyOrElse(CaseStatements.scala:29)
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:269)
        at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:270)
        at org.apache.pekko.actor.Actor.aroundReceive(Actor.scala:547)
        at org.apache.pekko.actor.Actor.aroundReceive$(Actor.scala:545)
        at org.apache.pekko.actor.AbstractActor.aroundReceive(AbstractActor.scala:229)
        at org.apache.pekko.actor.ActorCell.receiveMessage(ActorCell.scala:590)
        at org.apache.pekko.actor.ActorCell.invoke(ActorCell.scala:557)
        at org.apache.pekko.dispatch.Mailbox.processMailbox(Mailbox.scala:280)
        at org.apache.pekko.dispatch.Mailbox.run(Mailbox.scala:241)
        at org.apache.pekko.dispatch.Mailbox.exec(Mailbox.scala:253)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Caused by: java.lang.StringIndexOutOfBoundsException: Index 3067 out of bounds for length 3067
        at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
        at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
        at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
        at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
        at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
        at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
        at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
        at java.base/java.lang.String.checkIndex(String.java:4832)
        at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:46)
        at java.base/java.lang.String.charAt(String.java:1555)
        at org.bouncycastle.util.encoders.Base64Encoder.decode(Unknown Source)
        ... 36 more

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions