Subject: [core] Seeking input on Implementations of RFC 7250 "Using Raw Public Keys in TLS and DTLS"

From: Hannes Tschofenig <[email-masked]>
Date: Thu, 27 Aug 2015 21:25:44 +0200

Hi all,

let me start with the request first before I provide a little bit of
background.

We are trying to figure out what implementations of TLS/DTLS stacks had
been doing with regard to RFC 7250.

In private conversations I learned that two implementations ran into
problems with the encoding of the subjectPublicKeyInfo structure, which
is carried inside the Certificate message.

Here is the issue: RFC 7250 defines the Certificate structure in the
following way:

1  opaque ASN.1Cert<1..2^24-1>;
2  struct {
3    select(certificate_type){
4        // certificate type defined in this document.
5        case RawPublicKey:
6           opaque ASN.1_subjectPublicKeyInfo<1..2^24-1>;
7        // X.509 certificate defined in RFC 5246
8        case X.509:
9           ASN.1Cert certificate_list<0..2^24-1>;
10       // Additional certificate type based on
11       // "TLS Certificate Types" subregistry
12    };
13 } Certificate;

You may notice the case statement that distinguishes the handling of
X.509 certificates and the newly defined raw public key structure.
Line 6 does not use the ASN.1Cert type structure, which is defined in
line 1.

As a concrete example, if your SubjectPublicKey info is 128 bytes,
denoted by xx ... xx, then your payload is:
16 03 03 00 86 0b 00 00 83 00 00 80 xx ... xx

Here is the breakdown for a payload using TLS 1.2.

 * record header 16 03 03 00 86

1 byte content type indicating the handshake message (0x16), 2 byte
version length field indicating TLS 1.2 (0x03, 0x03), followed by a 2
byte length field (0x00,0x86) indicating 134 bytes.

 * handshake header 0b 00 00 83

The handshake type (0x0b) is followed by 3 bytes (0x00, 0x00, 0x83) for
the length field indicating 131 bytes.

 * Certificate: 00 00 80 xx ... xx

3 byte length field (0x00, 0x00, 0x80) indicating 128 bytes, followed by
the actual SubjectPublicKeyInfo structure -- denoted as xx ... xx.

The encoding of the X.509 structure on the other hand is a little
different. It contains two length fields in sequence since there might
be a list of certificates conveyed in the structure and the definition
provides the length of the entire sequence followed by the length of the
first certificate, followed by the certificate payload, the length of
the second certificate + 2nd certificate and so on.

Implementers have interpreted the above definition in such a way that it
always contains two length fields, also in the raw public key case.

Hence, my question to the folks on the list: Do you have an
implementation of RFC 7250 and what you have you implemented. Please
drop me/us a message.

Ciao
Hannes

---

From: Hauke Mehrtens <[email-masked]>
Date: Thu, 27 Aug 2015 22:08:49 +0200

On 08/27/2015 09:25 PM, Hannes Tschofenig wrote:
> Hi all,
> 
> let me start with the request first before I provide a little bit
> of background.
> 
> We are trying to figure out what implementations of TLS/DTLS stacks
> had been doing with regard to RFC 7250.
> 
> In private conversations I learned that two implementations ran
> into problems with the encoding of the subjectPublicKeyInfo
> structure, which is carried inside the Certificate message.
> 
> Here is the issue: RFC 7250 defines the Certificate structure in
> the following way:
> 
> 1  opaque ASN.1Cert<1..2^24-1>; 2  struct { 3
> select(certificate_type){ 4        // certificate type defined in
> this document. 5        case RawPublicKey: 6           opaque
> ASN.1_subjectPublicKeyInfo<1..2^24-1>; 7        // X.509
> certificate defined in RFC 5246 8        case X.509: 9
> ASN.1Cert certificate_list<0..2^24-1>; 10       // Additional
> certificate type based on 11       // "TLS Certificate Types"
> subregistry 12    }; 13 } Certificate;
> 
> You may notice the case statement that distinguishes the handling
> of X.509 certificates and the newly defined raw public key
> structure. Line 6 does not use the ASN.1Cert type structure, which
> is defined in line 1.
> 
> denoted by xx ... xx, then your payload is: 16 03 03 00 86 0b 00 00
> 83 00 00 80 xx ... xx
> 
> 1 byte content type indicating the handshake message (0x16), 2
> byte version length field indicating TLS 1.2 (0x03, 0x03), followed
> by a 2 byte length field (0x00,0x86) indicating 134 bytes.
> 
> The handshake type (0x0b) is followed by 3 bytes (0x00, 0x00, 0x83)
> for the length field indicating 131 bytes.
> 
> 3 byte length field (0x00, 0x00, 0x80) indicating 128 bytes,
> followed by the actual SubjectPublicKeyInfo structure -- denoted as
> xx ... xx.
> 
> different. It contains two length fields in sequence since there
> might be a list of certificates conveyed in the structure and the
> definition provides the length of the entire sequence followed by
> the length of the first certificate, followed by the certificate
> payload, the length of the second certificate + 2nd certificate and
> so on.
> 
> Implementers have interpreted the above definition in such a way
> that it always contains two length fields, also in the raw public
> key case.
> 
> implementation of RFC 7250 and what you have you implemented.
> Please drop me/us a message.
> 
> Ciao Hannes

There are 2 (or 3) DTLS implementations I know of and they are
compatible to each other at least they were 1.5 years ago.

tinydtls: http://tinydtls.sourceforge.net/
Californium: https://eclipse.org/californium/
wireshark dissector for DTLS and TLS

I am not aware of any other publicly available raw public key DTLS or
TLS implementations.

They are all implementing a 3 bytes certificates length over all
certificates, followed by a 3 bytes certificate length over the next
certificate. They implemented it in the way it was supposed to be for
x509 certificates only and not for raw public keys.

I haven't looked at the current code my information is 1.5 years old.

Hauke