eclipse-californium / californium

CoAP/DTLS Java Implementation
https://www.eclipse.org/californium/
Other
729 stars 367 forks source link

WIP: first implementation of draft-ietf-tls-dtls-connection-id-03 #824

Closed boaks closed 5 years ago

boaks commented 5 years ago

Just for those who are interested, I prepared a WIP branch for the draft-ietf-tls-dtls-connection-id-03 implementation. Currently the house keeping need a lot more work. Depending on the answer to my issue https://github.com/tlswg/dtls-conn-id/issues/28 it may get hard, if mixed usage is intended. That would require to update the peers ip-address after the record could be decrypted successfully.

boaks commented 5 years ago

https://github.com/eclipse/californium/tree/wip_add_dtls_cid

thomas-fossati commented 5 years ago

Build fails for me: see wip_add_dtls_cid-branch-build.log

boaks commented 5 years ago

RequestTest.testSetURIRejectsUnresolvableHost Expected exception: java.lang.IllegalArgumentException

    @Test(expected = IllegalArgumentException.class)
    public void testSetURIRejectsUnresolvableHost() {
        Request.newGet().setURI("coap://non-existing.host");
    }

Does nslookup non-existing.host work on your side? (And, yes, assuming that this MUST cause an error is also not "state of the art". But it's unfortunately not the only one, but one, which is not reported from too many others.)

Anyway, this unittest error seems to be irrelevant for testing cid.

Please try

mvn clean install -DskipTests=true

And: currently it's still mostly used with java 1.8 .Newer ones may not work :-).

boaks commented 5 years ago

First part is prepared as PR #852

boaks commented 5 years ago

I prepared a "interop workaround" for a go wip.

https://github.com/thomas-fossati/dtls/blob/master/CID.md

Starting the go server and using the sc-dtls-example-client "works on my machine" :-).

So, please git pull --force, build californium again and the cd to demo-apps/run.

Start the go-server as described in the link above (please adjust the port to listen to 5684) . Execute the sc-dtls-example-client-2.0.0-SNAPSHOT.jar in demo-apps/run using

java -jar sc-dtls-example-client-2.0.0-SNAPSHOT.jar

The go-server should display the "HELLO WORLD" message and typing something into the go-server console sends something back.

The go-client and scandium server still requires some work.

@thomas-fossati Did you find a answer to Does nslookup non-existing.host work on your side? or did you build it with mvn clean install -DskipTests=true?

thomas-fossati commented 5 years ago

@boaks thanks very much for the update.

I can confirm that the Scandium client interops OK with the go server.

I also fixed the signature verification bug that you spotted in the go client and tried it out with your example server. It works as well, which is cool :-)

thomas-fossati commented 5 years ago

@thomas-fossati Did you find a answer to

Does nslookup non-existing.host work on your side?

Yes, apparently my home ISP (TalkTalk UK) was intercepting NXDOMAIN answers and remap them to pristine A records to an external service (http://barefruit.com/).

I have to thank Californium/Scandium tests for spotting that out :-)

or did you build it with mvn clean install -DskipTests=true?

After I changed my recursive to Cloudflare's everything works fine.

boaks commented 5 years ago

@thomas-fossati

One issue is still confusing to me:

If I use the go-server, it seems that "exactly 1 byte more" must be used, otherwise I get a disconnected with "unhandled wrapped content type: 33" (I added the Println

func (h *hub) readLoop(conn net.Conn) {
    b := make([]byte, bufSize)
    for {
        n, err := conn.Read(b)
        if err != nil {
            fmt.Println("Failed to get message", conn.RemoteAddr(), err)
            h.unregister(conn)
            return
        }
        fmt.Printf("Got message: %s\n", string(b[:n]))
    }
}

The 33 is the last real payload byte I sent, If add one more byte, it works.

But using the go-client, it works without that extra byte. Any idea?

boaks commented 5 years ago

OK, the go-client receives RFC6347 packages, therefore it works without the extra byte.

Philago commented 5 years ago

Hello Achim,

I am very interested in a support of the DTLS connection ID in Californium/Leshan.

(1) Do you have an idea of when it may be available in an official Californium/Leshan release ?

(2) Besides I am interested by using the connection ID in Leshan as well to identify a device.

From LwM2M 1.0.2 specifications: "Upon receiving a “Register” operation from the LwM2M Client, the LwM2M Server records the connection information of the registration message (e.g., source IP address and port or MSISDN) and uses this information for all future interactions with that LwM2M Client."

If the IP adress of my device changes, I'll have to perform a new registration of my device on the platform and I do not want to do that. The connection ID seems a good fit for me as "connection information" When a device registers on the platform, the platforms records the IP adress and may record the connectiond ID as well and associate it to the provided endpoint name. When notifications arrive on the platform, based on the connection ID received, the platform may know which device is communicating. The platform may update the IP address of the device during a register update for instance.

What do you think of such an approach in Leshan ?

Thank you very much and have a good day.

Philippe

boaks commented 5 years ago

(1) Milestone - depending on @sbernard31 opinion - californium 2.0.0-M14 may be released Friday next week. (1) Release - we currently discus the scope of californium 2.0.0 - my assumption is early summer. We will see ...

(2) That's a difficult question. Let's hope, that it already works "magically" with the proper "EndpointContextMatcher". Wait for M14 and then I'm sure @sbernard31 and I will do our best to make it working.

boaks commented 5 years ago

@Philago

Do you still require to "disable the DTLS anti replay mechanism" (issue #653) ?

sbernard31 commented 5 years ago

@Philago, let's open a ticket at https://github.com/eclipse/leshan to discus about that. I didn't think too much about that but this is something we should address (and possible this will works out of the box).

About,

If the IP adress of my device changes, I'll have to perform a new registration of my device on the platform and I do not want to do that

This is not the case with Leshan : as long as you are using the "good identity" we accept client request, but the client MUST use an Registration Update to let know to the server its new IP address as specify in the specification. Here you can find some explanation about how this works for observations but I should write a more generic documentation about connection / session / registration life time.

Philago commented 5 years ago

Hello @boaks and @sbernard31 ,

and thank you for you answers.

@boaks : yes I am still interested in disabling the anti replay mechanism or at least to have the possibility to configure the size of the receive window

@sbernard31 : I think that there is someting I do not understand. What is a good identity ? Or from the first link you provided : "We currently accept notifications if the DTLS identity is the same as the one linked to the registration. So this means if you do a full handshake, meaning having a new DTLS connection/session, we will accept your notification as long as you are using the good DTLS identity. This allow to keep observation relationship after a restart even if you don't persist DTLS connection or session." What is the DTLS identity ? (The session ID ? The IP/port source/dest ? Both ? Something else ?)

I understand that my notifications are going to be accepted as long as I use the same DTLS identity as established during my registration. I may understand how it works if I resume my DTLS session. But I do not understand how it works if have to perform a new full DTLS handshake. How can you keep the registration of the device if the IP address is changing ? For me a DTLS session is identified by its source/dest IP/ports, if one of them changes, the session is lost. Same for the registration, the platform keeps track of my source IP/port along with the client end point name, if it changes and if the DTLS session is changing as well (since the source IP address changed), I do not see how it works.

So the connection ID may be a good fit indeed (replacing the current DTLS identity ?), enabling to receive notifications (non confirmable) from a device whatever its source IP address/port. The update of the IP address of the device being performed during a register update, as long as the connection ID received is the same. But let's talk about that in a new ticket.

sbernard31 commented 5 years ago

Some quick answer, but if this is sill not clear please open a ticket at https://github.com/eclipse/leshan. because we are a bit out of topic here...

What is the DTLS identity ?

For PSK, the PSK Identity For RPK, the public key For X509, the CN=endpoint

For me a DTLS session is identified by its source/dest IP/ports ?

Session is identified by SessionID. DTLS connection is identify by source/dest/port (or CID).

I do not see how it works.

We only take care of "DTLS identity" in Leshan. Imagine your device identifies itself using PSK. As long as the device is using the same identity (PSK ID), we consider we face the same peer. This means it can do a full handshake, an abbreviated one, or nothing (CID), we don't care as we only check "DTLS identity".

Philago commented 5 years ago

Thank you for your answer, it's crystal clear now

boaks commented 5 years ago

@thomas-fossati

In the meantime I was able to test your update. The FINISH seems to be still a HANDSHAKE record instead of a TLS_CID record. All other issues are solved.

boaks commented 5 years ago

The wip, except of the go-workaround, is mainly merged into 2.0.x. The issue #653 is addressed in PR #906. If any issues related to leshan occurs, don't hesitate to report them in a new issue.