Subject: [TLS] Two notes on TLS 1.2 after implementing it in GnuTLS

From: Simon Josefsson <[email-masked]>
Date: Sun, 26 Nov 2006 12:37:59 +0100

Hello.  I have implemented TLS 1.2 in GnuTLS following
draft-ietf-tls-rfc4346-bis-02.txt.  I was able to connect successfully
to https://www.mikestoolbox.net:4433/ (thanks Mike!) so I believe my
implementation is ready enough that I can write down some of my
thoughts on the draft.

1.  It would have reduced implementation time if there were a list of
protocol syntax changes.  For example, it took me some debugging to
understand that CertificateRequest was modified from (RFC 4346):

      struct {
          ClientCertificateType certificate_types<1..2^8-1>;
          DistinguishedName certificate_authorities<0..2^16-1>;
      } CertificateRequest;

into

       struct {
           ClientCertificateType certificate_types<1..2^8-1>;
           HashType certificate_hash<1..2^8-1>;
           DistinguishedName certificate_authorities<0..2^16-1>;
       } CertificateRequest;

In general I recommend to add new fields to the end of a structure
instead of in the middle of it.  It makes version-aware parsers
cleaner.

2.  The modification to change RSA signing was to change:

   In RSA signing, a 36-byte structure of two hashes (one SHA and one
   MD5) is signed (encrypted with the private key).  It is encoded with
   PKCS #1 block type 1, as described in [PKCS1A].

into:

   In RSA signing, the output of the chosen hash function is encoded as
   a PKCS #1 DigestInfo and then signed using block type 01 as described
   in Section 8.1 as described in [PKCS1A].

This could be improved with some helpful discussion to guide
implementers.  PKCS1A is under-specified and even incorrect here.  Is
there a reason we don't reference PKCS1B here?

DigestInfo mis-handling was the cause of the recent bugs that affected
OpenSSL, Mozilla NSS, GnuTLS and several proprietary TLS libraries for
X.509 signature validations.  It would be unfortunate if TLS 1.2
introduce the same problem into TLS itself.

The problems with PKCS1A are:

1) It uses BER encoding, when PKCS1B correctly changed this to DER.

2) It doesn't specify whether the parameters field should be NULL or
omitted for non-MD2/MD4/MD5 algorithms.

I don't think there is any controversy around 1).  DER should be used.

Whether to use a DigestInfo.AlgorithmIdentifier.parameters field that
is NULL or omitted seems somewhat problematic.  PKCS1A says regarding
MD2/MD4/MD5:

             For these object identifiers, the parameters field of the
             digestAlgorithm value should be NULL.

It doesn't say anything about other hashes.  PKCS1B says:

   The parameters field associated with id-sha1, id-sha256, id-sha384,
   and id-sha512 should be omitted, but if present, shall have a value
   of type NULL.

However the example in PKCS1B uses NULL:

      SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.

Further, appendix H of PKCS1B contains additional discussions:

   *  The requirement that the parameters in an AlgorithmIdentifier
      value for id-sha1, id-sha256, id-sha384, and id-sha512 be NULL was
      changed to a recommendation that the parameters be omitted (while
      still allowing the parameters to be NULL). This is to align with
      the definitions originally promulgated by NIST. Implementations
      MUST accept AlgorithmIdentifier values both without parameters and
      with NULL parameters.

I note that Mike's server required a NULL here.  I initially didn't
send one, my ASN.1 library computed a DER encoding with an omitted
parameters field.  For reference, that DER code is:

  SHA-1: 30 1f 30 07 06 05 2b 0e 03 02 1a 04 14 || H

Mike's server didn't accept this.

This will leads to interoperability problems with TLS 1.2 unless the
specification is more explicit about the problem.

I suggest adding after this paragraph:

   In RSA signing, the output of the chosen hash function is encoded as
   a PKCS #1 DigestInfo and then signed using block type 01 as described
   in Section 8.1 as described in [PKCS1A].

This new paragraph:

   As discussed in [PKCS1B], the DigestInfo MUST be DER encoded and
   for digest algorithms without parameters (which include SHA-1) the
   DigestInfo.AlgorithmIdentifier.parameters field SHOULD be omitted
   but implementations MUST accept both without parameters and with
   NULL parameters.

Other text instead would be fine, but I strongly believe that this
problem should be mentioned explicitly because we have seen that it
has serious failure modes (false positives in RSA signature
verification).

For the record, I wouldn't have any problem with saying that the
parameters field MUST be omitted -- the fewer choices the better.
However, that would be a taking things a bit further than PKCS1B.

Thanks,
Simon

_______________________________________________
TLS mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/tls

---

From: Mike <[email-masked]>
Date: Wed, 29 Nov 2006 04:53:54 -0800

> specification is more explicit about the problem.

I have to admit I don't understand this issue.  That's because I
didn't write any RSA code myself.  I used to use OpenSSL for SSL/TLS,
but was never sure if my code was correct, so I decided to write my
own implementation.  However, I am comfortable with the functions in
OpenSSL's libcrypto, so I used that for all public-key algorithms and
bulk encryption.

Perhaps I need to write my own RSA code instead of relying on OpenSSL
EVP functions for signing/verifying?

Mike

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 29 Nov 2006 14:20:40 +0100

> EVP functions for signing/verifying?

It seems better if the WG clarify how TLS 1.2 should work here first,
and then we both can decide if and how to update our implementations.

Alternatives:

1) Find an external spec that is clear on how the DigestInfo is
   encoded.  Using PKCS1B instead of PKCS1A would solve the problem.
   That would imply DER encoding and omitted parameters field, and
   acceptance of both omitted and NULL parameters.

2) Clarify that DER encoding is used and:

   A) unused parameters MUST be omitted.

   B) unused parameters MUST be encoded as NULL.

   C) unused parameters MUST be omitted and NULL parameters MUST be
      accepted.

   D) unused parameters MUST be encoded as NULL and omitted parameters
      MUST be accepted.

   E) unused parameters MUST be encoded as NULL or omitted, and both
      alternatives MUST be accepted.

There are probably more choices.

I believe some clarification regarding this may be useful even if 1)
is chosen.  Many people are still using PKCS#1 RSA implementations
that were written on the old standard.

I currently prefer choice 1) together with additional text such as:

Other thoughts?

/Simon

---

From: <[email-masked]>
Date: Wed, 29 Nov 2006 15:32:29 +0200

Simon Josefsson wrote:

>    In RSA signing, a 36-byte structure of two hashes (one SHA and 
>    one MD5) is signed (encrypted with the private key).  It is 
>    encoded with PKCS #1 block type 1, as described in [PKCS1A].
> 
> into:
> 
>    In RSA signing, the output of the chosen hash function is 
>    encoded as a PKCS #1 DigestInfo and then signed using block 
>    type 01 as described in Section 8.1 as described in [PKCS1A].
> 
> implementers.  PKCS1A is under-specified and even incorrect here.  
> Is there a reason we don't reference PKCS1B here?

Some time ago, I suggested to Eric that we should change to PKCS#1
v2.1 terminology [PKCS1B], since IMHO it's a big improvement
over the old terminology. My proposal was simply:
  
   In RSA signing, the opaque vector contains the signature generated
   using the RSASSA-PKCS1-v1_5 signature scheme defined in
   [PKCS1B]. Note that earlier versions of TLS used a different RSA
   signature scheme.

The proposed text can also be found from our new issue tracker (yes,
we started one so that we don't accidentally forget things):
http://www1.tools.ietf.org/wg/tls/trac/ticket/1

> DigestInfo mis-handling was the cause of the recent bugs that
> affected OpenSSL, Mozilla NSS, GnuTLS and several proprietary TLS
> libraries for X.509 signature validations.  It would be unfortunate
> if TLS 1.2 introduce the same problem into TLS itself.
> 
>       value for id-sha1, id-sha256, id-sha384, and id-sha512 
>       be NULL was changed to a recommendation that the parameters be 
>       omitted (while still allowing the parameters to be NULL). 
>       This is to align with the definitions originally promulgated 
>       by NIST. Implementations MUST accept AlgorithmIdentifier values 
>       both without  parameters and with NULL parameters.

There's text in PKCS#1 errata regarding this topic:
ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1errata.txt

The proposed text in the errata (as far as I understand it) says that
when using EMSA-PKCS1-V1.5 (which we are using), and any of
id-sha1/256/384/512, the parameters MUST be included and MUST have
type NULL. It is not totally clear (to me, at least) whether the
"MUST accept without parameters" part still applies.

In IEEE 1363a-2003 (EMSA3 encoding method), NULL parameters
must be included.

(But yes, I do agree that TLS 1.2 spec should say something about this.)

Best regards,
Pasi

---

From: [email-masked] (Peter Gutmann)
Date: Thu, 30 Nov 2006 03:08:17 +1300

>2) Clarify that DER encoding is used and:

Which standard do you want to comply with?  From RFC 3274:

  There are two possible encodings for the [algorithm] null parameters field
  which arise from the fact that when the 1988 syntax for AlgorithmIdentifier
  was translated into the 1997 syntax, the OPTIONAL associated with the
  AlgorithmIdentifier parameters got lost.  Later it was recovered via a
  defect report, but by then, everyone thought that algorithm parameters were
  mandatory.  Because of this, some implementations will encode null
  parameters as an ASN.1 NULL element and some will omit them entirely (see
  for example section 12 of CMS [RFC2630]).  Although the correct encoding is
  to omit the parameters field, implementations may encounter encodings which
  use an ASN.1 NULL element for the parameters.

(I've seen this issue come up so often across so many WGs that maybe I should
do some sort of cross-WG RFC on it that can be referred to wherever the
problem comes up.  Comments?).

Peter.

---

From: Mike <[email-masked]>
Date: Wed, 29 Nov 2006 06:19:55 -0800

> I was able to connect successfully
> to https://www.mikestoolbox.net:4433/

Since some of you may be behind a firewall that doesn't permit https
except to port 443, I added a second listener to my server on that
port.

Mike

---

From: [email-masked] (Peter Gutmann)
Date: Thu, 30 Nov 2006 04:36:36 +1300

>understand that CertificateRequest was modified from (RFC 4346):

Can I add a "me too" to this, finding some of the surprises hidden in the 1.2
draft took quite a bit of doing.  A section detailing the changes would be of
considerable benefit to people upgrading existing implementations.

Peter.

---

From: <[email-masked]>
Date: Wed, 29 Nov 2006 18:08:57 +0200

>    acceptance of both omitted and NULL parameters.

Note that PKCS1B requires NULL parameters for MD5 (omitting is not 
acceptable). But unfortunately, even PKCS1B doesn't solve the
problem, since the errata changes the relevant text...

IEEE 1363a-2004 would be unambiguous (DER encoding, NULL parameter
required for SHA-*, omitted parameters not acceptable); this would
also be in line with the errata...

(Note that other specs, such as RFC 3280, may have an identically
named DigestInfo structure, but whether parameters are optional
there or not doesn't really have any direct impact on whether
they're optional in PKCS#1 EMSA-PKCS1-v1_5 encoding.)

Best regards,
Pasi

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 29 Nov 2006 21:41:21 +0100

> problem comes up.  Comments?).

Given the current situation, the pragmatic approach seem to be to
allow implementations to send both variants and require that both MUST
be accepted and have the same meaning.

It doesn't seem necessary to declare that one variant is preferred for
TLS.  I suspect that trying to decide which of the two variants is the
one we should prefer is a rat-hole.

/Simon

---

From: "Kyle Hamilton" <[email-masked]>
Date: Wed, 29 Nov 2006 13:58:31 -0700

As has been noted elsewhere, any time you have a choice of which
option to take, you have at least one bit of information leakage
potential.  One of the rules for Common Criteria validation of higher
assurance levels is the proven removal of covert channels.

I think the ability to precisely specify during negotiation exactly
which behavior you're going to use might be helpful?

-Kyle H

---

From: <[email-masked]>
Date: Thu, 30 Nov 2006 11:52:33 +0200

> be accepted and have the same meaning.

Unnecessary options are a recipe for interoperability (and security)
problems, and in this situation, we don't have to be backwards
compatible with old implementations (since TLS 1.0/1.1 didn't have
this issue).

So IMHO we should specify this in TLS 1.2 spec one way or another.
Given that both IEEE 1363a-2004 and PKCS#1 v2.1 latest errata
seem to agree on the issue (NULL parameter MUST be include),
that would seem the most obvious choice...

Best regards,
Pasi

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 30 Nov 2006 11:34:31 +0100

> compatible with old implementations (since TLS 1.0/1.1 didn't have

Sure.

> So IMHO we should specify this in TLS 1.2 spec one way or another.

Ok.  What about accepting the other alternative?  MUST NOT, to avoid a
covert channel?  MUST, to cater for those implementers with external RSA
libraries that they can't change?  Or MAY or SHOULD?

> that would seem the most obvious choice...

RFC 3447 says the parameters field is omitted, due to NIST
specifications.  It might make sense to ask around what today's
preferences are.

/Simon

---

From: Russ Housley <[email-masked]>
Date: Thu, 30 Nov 2006 10:41:35 -0500

>they're optional in PKCS#1 EMSA-PKCS1-v1_5 encoding.)

I agree.

One word of warning: if the idea of salted hash functions catches on, 
then the hash algorithm parameter will not always be NULL.

I would like to see this documented in a separate document that can 
be referenced by TLS, S/MIME, and any other protocol that needs to 
make use of PKCS#1 v1.5.

Russ

---

From: Dr Stephen Henson <[email-masked]>
Date: Thu, 30 Nov 2006 16:54:32 +0000

My 2c on the subject...

As I think has been mentioned some implementations generate the
DigestInfo structure using a cut+paste operation from a binary blob.
Others perform cut, paste and compare for the verify operation.

This is often done in resouce limited environments or those who have no
wish to implement a full ASN1 library just to produce and parse this one
structure.

Some existing examples, such as smart cards, cannot change the format
they use and would be rendered non compliant if we make their format
illegal.

All the examples I've seen using that technique (and a few specs)
require that a NULL parameter is present and not omitted but I can't
rule out some which may omit parameters.

Steve.
-- 
Dr Stephen N. Henson.
Core developer of the   OpenSSL project: http://www.openssl.org/
Freelance consultant see: http://www.drh-consultancy.co.uk/
Email: [email-masked], PGP key: via homepage.