openhab / openhab-addons

Add-ons for openHAB
https://www.openhab.org/
Eclipse Public License 2.0
1.85k stars 3.56k forks source link

[knx] support for KNX secure #8872

Open holgerfriedrich opened 3 years ago

holgerfriedrich commented 3 years ago

1) [open] Support for KNX data secure packets shall be added to OpenHAB. Reading and writing authenticated KNX packets should be possible. 2) [done] Support for KNX IP secure shall be added to OpenHAB. Using an encrypted connection to a IP secure interface or an IP secure router shall be possible.

Calimero library seems to have all the necessary prerequisites at hand in latest version (2.5M1). The process includes exporting an encrypted keyring from ETS software, decrypt it using the Calimero library functions in the OH knx binding, and use the corresponding group address keys from the keyring file.

Prerequesites

Suggested Approach

holgerfriedrich commented 3 years ago

I have already been playing around with this and willing to implement. If anyone is already working on this topic or wants to give some advice, it would be appreciated.

J-N-K commented 3 years ago

If there is no immediate need (i.e. bugs or security issues), we usually don't use snapshots of dependencies. Do you happen to know when Calimero 2.5 will be released? And thanks for the offer to implement that.

holgerfriedrich commented 3 years ago

@J-N-K thanks for letting me know. My PR is still WIP and far from finished. Decrypting secure PDUs using the exported keyring from ETS works fine with the Calimero snapshot. The more complicated thing is to setup a secure device needed for transmitting secure messages from openhab to other devices on the bus. I was not able to get this implemented properly yet. Once it is running, I will contact the author.

J-N-K commented 3 years ago

If you need help regarding the openHAB side, please ping me.

scholzi100 commented 3 years ago

Looks like Calimero got a milestone release ready. Following a release candidate some what soon. (Ref)

openhab-bot commented 3 years ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/enable-knx-binding-to-use-knx-ip-secure/13785/4

holgerfriedrich commented 2 years ago

I have put together a version which actually supports IP secure, i.e. secure tunneling (tested) and secure routing (untested). Data secure is working only passive (i.e. it can decrypt any received message, but not send successfully). Documentation can be found here: https://github.com/holgerfriedrich/openhab-addons/tree/pr-knx-data-secure/bundles/org.openhab.binding.knx#knx-secure Precompiled plugin for 3.2 and 3.3.x can be downloaded here: https://github.com/holgerfriedrich/openhab-addons/actions?query=event%3Apush+branch%3Apr-knx-data-secure

I could need help testing this, especially the secure routing feature as I do not have a secure router at hand. Event though the data secure write access seems to be still a way to go, I would try to get this merged, as the IP secure topic is a real benefit.

WDYT?

kaikreuzer commented 2 years ago

Hey @holgerfriedrich, thanks for looking into this and congrats for the progress! I agree that passive support alone is already worthwhile to merge, since secure and unsecure GAs can coexist. As long as sending secure messages does not work reliably, openHAB imho shouldn't even try it - I'd suggest to move this "experimental" feature then rather to a new/separate PR for those who want to help on early testing.

Unfortunately, I don't have a secure router either, so I cannot help testing here.

openhab-bot commented 2 years ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/knx-secure-initial-implementation/134133/1

slueder commented 2 years ago

Hallo Holger,

if you like, I am happy to support testing the secure tunnel functionality against a MDT SCN-IP000.03 interface. As I don't have a secure router setup I am limited to test the secure tunnel only.

Please let me know, if this is fine for you.

Keep up the good work and have a nice start into the week Sven

slueder commented 2 years ago

Hallo Holger,

is there a mismatch in the expected format of the keyring file ? According to Calimero project the keyring file should be in format key=value whereas the file created by ETS (version 6.0.3) is in XML ?

For reference this is the output of the file created by ETS version 6.0.3:

<?xml version="1.0" encoding="utf-8"?>
<Keyring Project="Home" CreatedBy="6.0.3" Created="2022-04-05T09:25:34" Signature="MODiSG1B5CyWtWNbkU/fhw==" xmlns="http://knx.org/xml/keyring/1">
  <Backbone MulticastAddress="224.0.23.12" />
  <Interface IndividualAddress="1.1.2" Type="Tunneling" Host="1.1.1" UserID="2" Password="<masked>" Authentication="<masked>" />
  <Interface IndividualAddress="1.1.3" Type="Tunneling" Host="1.1.1" UserID="3" Password="<masked>" Authentication="<masked>" />
  <Interface IndividualAddress="1.1.4" Type="Tunneling" Host="1.1.1" UserID="4" Password="<masked>" Authentication="<masked>" />
  <Interface IndividualAddress="1.1.5" Type="Tunneling" Host="1.1.1" UserID="5" Password="<masked>" Authentication="<masked>" />
  <Devices>
    <Device IndividualAddress="1.1.1" ToolKey="<masked>" ManagementPassword="<masked>" Authentication="<masked>" SequenceNumber="0" />
  </Devices>
</Keyring>

Reason for my question is that I am getting a

tuwien.auto.calimero.secure.KnxSecureException: keyring signature mismatch (invalid keyring or wrong password)

message in the log, although the used keyringPasswort in knx.things is identical to the password used to export the keyring in ETS.

holgerfriedrich commented 2 years ago

Hi @slueder ,

if you like, I am happy to support testing the secure tunnel functionality against a MDT SCN-IP000.03 interface. As I don't have a secure router setup I am limited to test the secure tunnel only.

Thanks for testing this, your help is highly appreciated!

is there a mismatch in the expected format of the keyring file ? According to Calimero project the keyring file should be in format key=value whereas the file created by ETS (version 6.0.3) is in XML ?

Your keyring file looks perfectly vaild. Did you copy the keyring file without any modification? The signature only protects the content and ignores formatting changes, e.g. line endings or extra lines. I would expect that something went wrong with the password... (the one you set in ETS during the export). Any special characters, spaces, etc? How did you configure the binding, UI or config files?

btw: you can also skip the keyring file and set the config options tunnelDeviceAuthentication, tunnelUserPassword, tunnelUserId

slueder commented 2 years ago

Good morning, Holger,

Did you copy the keyring file without any modification?

Yes, the SHA1 checksums of the keyring file on the ETS system and OpenHAB are identical.

Any special characters, spaces, etc?

Simple password abcd used during backup.

How did you configure the binding, UI or config files?

Fresh installation of OpenHAB 3.2 with 3.3-SNAPSHOT knx binding, manual configuration, details following.

OpenHAB console output of bundle:list:

262 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Daikin Binding
263 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Helios Binding
265 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Sonos Binding
266 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Velux Binding
267 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Configuration UPnP Discovery
268 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Configuration USB-Serial Discovery
269 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Configuration USB-Serial Discovery for Linux using sysfs scanning
270 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Configuration USB-Serial Discovery using ser2net mDNS scanning
271 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Configuration Serial
272 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Serial Transport
273 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Serial Transport for RXTX
274 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: Serial Transport for RFC2217
275 │ Active │  80 │ 3.2.0                 │ openHAB Core :: Bundles :: UPnP Transport
276 │ Active │  80 │ 3.2.0                 │ openHAB Add-ons :: Bundles :: Persistence Service :: RRD4j
277 │ Active │  80 │ 3.2.0                 │ openHAB UI :: Bundles :: Basic UI
278 │ Active │  80 │ 3.2.0                 │ openHAB UI :: Bundles :: HABPanel UI
279 │ Active │  80 │ 3.2.0                 │ openHAB UI :: Bundles :: Icon Set :: Classic
280 │ Active │  80 │ 3.3.0.202204040419    │ openHAB Add-ons :: Bundles :: KNX Binding

The 3.2 version of KNX bindings has been uninstalled using bundle:uninstall

Output of knx.things:

Bridge knx:ip:bridge "SCN-IP000.03"@"KNX" [
    type="SECURETUNNEL",
    keyringFile="Home.knxkeys",
    keyringPasswort="abcd",
    tunnelSourceAddr="1.1.2",
    ipAddress="192.168.48.221",
    localIp="192.168.48.16",
    autoReconnectPeriod=30
] {
    Thing device generic [
        address="1.1.20",
        fetch=true,
        pingInterval=300,
        readInterval=300
    ] {
        Type rollershutter : test "Test" [ upDown="1/0/0", stopMove="1/1/0", position="1/2/0" ]
    }
}

Output of OpenHAB log:

 2022-04-06 06:16:23.930 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:device:bridge:generic' changed from OFFLINE (BRIDGE_OFFLINE) to UNINITIALIZED
2022-04-06 06:16:23.951 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:device:bridge:generic' changed from UNINITIALIZED to UNINITIALIZED (HANDLER_MISSING_ERROR)
2022-04-06 06:16:23.955 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:ip:bridge' changed from OFFLINE (CONFIGURATION_ERROR): KNX security: keyring signature mismatch (invalid keyring or wrong password) to UNINITIALIZED
2022-04-06 06:16:23.968 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:ip:bridge' changed from UNINITIALIZED to UNINITIALIZED (HANDLER_MISSING_ERROR)
2022-04-06 06:16:23.981 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'knx.things'
2022-04-06 06:16:24.067 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:ip:bridge' changed from UNINITIALIZED to INITIALIZING
2022-04-06 06:16:24.077 [INFO ] [nternal.handler.IPBridgeThingHandler] - KNX secure: keyring is configured, opening may take some time
2022-04-06 06:16:24.082 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:device:bridge:generic' changed from UNINITIALIZED to UNINITIALIZED (BRIDGE_UNINITIALIZED)
2022-04-06 06:16:25.001 [WARN ] [nternal.handler.IPBridgeThingHandler] - tuwien.auto.calimero.secure.KnxSecureException: keyring signature mismatch (invalid keyring or wrong password)
2022-04-06 06:16:25.006 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:ip:bridge' changed from INITIALIZING to OFFLINE (CONFIGURATION_ERROR): KNX security: keyring signature mismatch (invalid keyring or wrong password)
2022-04-06 06:16:25.013 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:device:bridge:generic' changed from UNINITIALIZED (BRIDGE_UNINITIALIZED) to INITIALIZING
2022-04-06 06:16:25.026 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'knx:device:bridge:generic' changed from INITIALIZING to OFFLINE (BRIDGE_OFFLINE)
2022-04-06 06:16:25.083 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'knx.things'

keyring file created by ETS (password used abcd):

cat ../misc/Home.knxkeys
<?xml version="1.0" encoding="utf-8"?>
<Keyring Project="Home" CreatedBy="6.0.3" Created="2022-04-06T03:40:40" Signature="IagJW1/gVYR7XcJ+0YG4Ug==" xmlns="http://knx.org/xml/keyring/1">
  <Backbone MulticastAddress="224.0.23.12" />
  <Interface IndividualAddress="1.1.2" Type="Tunneling" Host="1.1.1" UserID="2" Password="N5tgowh7jBNXa5WJm1ZJgf7eoQ2hWop845iy8mJNmPQ=" Authentication="REPm+eIoorWztB0IJ3/NqoL7mD3hByWiTqk5wXsFGk0=" />
  <Interface IndividualAddress="1.1.3" Type="Tunneling" Host="1.1.1" UserID="3" Password="mwpc6Bhb4umr+W9neTJcWiWdA9jAWsRS644sDIFguxk=" Authentication="JFYkGpOU1gzkHHEGlE0OKqkkjmLhNBXW6OEfSYIOGiA=" />
  <Interface IndividualAddress="1.1.4" Type="Tunneling" Host="1.1.1" UserID="4" Password="Y/fNmOKQtBmspnczPIFu+P8c+za8LdYiImQOnbc8UnQ=" Authentication="MV6DvRq5llQdz4lv6KBy9aA+B/FWzQhBQxpG2rhL/FQ=" />
  <Interface IndividualAddress="1.1.5" Type="Tunneling" Host="1.1.1" UserID="5" Password="EwuRXJD5NeJXyNMB6cV0MoOHUkZ9yBQ8fD6npHNlVMA=" Authentication="fFxn4GBCqhdKtbJoCu2AQ0dC7lWJFEt4EQ8z7I9CYAo=" />
  <Devices>
    <Device IndividualAddress="1.1.1" ToolKey="p5VBAABG3osG5wR4mJp5PQ==" ManagementPassword="eIwl/mI0iv+9/oIiFLRCR/A3mLrDRtSpoqCmfisD8XY=" Authentication="iV+aDTIt9P3qi1gpDMIxXb+ZkVIKzskqrutTlAk2Ask=" SequenceNumber="0" />
    <Device IndividualAddress="1.1.7" ToolKey="bQT0yn+JdpL7JtjnXSU1+g==" ManagementPassword="35UBH0jbPYXaeooWZpv62SjUTy0sn4kbLTrBc14o2SI=" Authentication="l1+XSb77khweJ2/HdpP5PIbJeJyYBgZzS71kTIwTvIg=" SequenceNumber="133893905511" />
  </Devices>

Sha1 of keyring file (identical with the one created on ETS system):

sha1sum ../misc/Home.knxkeys
e98dbbcbb466a0b7669fdc6d1b7be8510e1d9385  ../misc/Home.knxkeys

btw: you can also skip the keyring file and set the config options tunnelDevAuth, tunnelPasswort. tunnelUser

Yes, would be happy to test this alternate way as well, but have issues in looking up the tunnelDevAuth value.

Screenshot of ETS: ETS IP Interface Properties Tunnel Channel 1

This would give me tunnelUser = 2 as it is the first tunnel (can also be looked up in keyring file), tunnelPassword is probably the one listed in clear-text, but no idea where to find the tunnelDevAuth information. Maybe you can point me to where I can get this value from ?

Thanks a lot in advance for your support Sven

holgerfriedrich commented 2 years ago

Hi @slueder, sorry I got the identifiers wrong in my comment above. tunnelDeviceAuthentication, tunnelUserPassword, tunnelUserId. tunnelUserPassword is as in the screenshot, tunnelUserId should be 2 according to the keyring. You will find the password for tunnelDeviceAuthentication on the device itself (not the tunnel), for me it is visible in the tab IP and named authentication code. For the keyring problem: Maybe you could you try a longer password?

slueder commented 2 years ago

Hi Holger,

quick status update: using tunnelDeviceAuthentication, tunnelUserPassword and tunnelUserId worked.

Using the keyring export feature still throws keyring signature mismatch errors even when using longer or more complex password. But this is not important anymore now that the approach using the three configuration settings above is working. For this test I removed / re-added the IP interface in ETS and reset the IP interface to factory defaults.

In the mean time ETS6.0.4 was also released which seems to fix issues with invalid passwords (in ETS 6.0.3 the passwords generated by ETS were containing a space at the beginning which caused issues so that you manually needed to regenerate these passwords with proper values).

All in all thank you for the really good work done here and if there is anything you want me to test, please let me know.

Sven

holgerfriedrich commented 2 years ago

@slueder Hi Sven, thanks! I think the way to go is to roll out the secure tunneling as a first step, as proposed in PR #12434. Maybe we move our discussion there as well....

holgerfriedrich commented 2 years ago

Separated out the IP secure part, see #12709. Data security part still has issues and currently requires 2.6-SNAPSHOT release of the Calimero library.

openhab-bot commented 1 year ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/ipsecure-router-knx-binding-online-until-i-enable-another-thing/146894/5