4

In PKCS1 there's DigestInfo:

  DigestInfo ::= SEQUENCE {
      digestAlgorithm AlgorithmIdentifier,
      digest OCTET STRING
  }

AlgorithmIdentifier is defined in RFC5280:

   AlgorithmIdentifier  ::=  SEQUENCE  {
        algorithm               OBJECT IDENTIFIER,
        parameters              ANY DEFINED BY algorithm OPTIONAL  }

PKCS1 provides DER encodings of DigestInfo for various hashing algorithms on page 43:

   1. For the six hash functions mentioned in Appendix B.1, the DER
      encoding T of the DigestInfo value is equal to the following:

      MD2:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04
                   10 || H.
      MD5:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04
                   10 || H.
      SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
      SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00
                   04 20 || H.
      SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00
                   04 30 || H.
      SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00
                      04 40 || H.

If I create do asn1parse on one of those DER encodings (sha512) I get the following:

    0:d=0  hl=2 l=  81 cons: SEQUENCE
    2:d=1  hl=2 l=  13 cons:  SEQUENCE
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha512
   15:d=2  hl=2 l=   0 prim:   NULL
   17:d=1  hl=2 l=  64 prim:  OCTET STRING

algorithm is denoted by OBJECT and parameters is denoted by NULL. My question is...

If parameters is optional why is NULL present at all? Why do the strings provided in PKCS1 correspond to the above DER encoding instead of, say, this one (without the NULL)?:

    0:d=0  hl=2 l=  79 cons: SEQUENCE
    2:d=1  hl=2 l=  11 cons:  SEQUENCE
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha512
   15:d=1  hl=2 l=  64 prim:  OCTET STRING
neubert
  • 1,605
  • 3
  • 18
  • 36

1 Answers1

2

The information in the two cited RFC's seems slightly contradictory regarding the NULL after algorithm.

The overall definition of the structure claims the parameters attribute is optional, however in the appendix regarding the rsaEncryption algorithm specifically there is this:

-- When rsaEncryption is used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.

And similarly specific hashing algorithms:

-- When the following OIDs are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
--
md2WithRSAEncryption       OBJECT IDENTIFIER ::= { pkcs-1 2 }
md5WithRSAEncryption       OBJECT IDENTIFIER ::= { pkcs-1 4 }
sha1WithRSAEncryption      OBJECT IDENTIFIER ::= { pkcs-1 5 }
sha256WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 11 }
sha384WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 12 }
sha512WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 13 }

It seems a little silly to define a field as optional but later mandate its presence and value. Perhaps there are other algorithms where the field may be omitted, but these algorithms specifically require it?

The standard does seem to get confusing in the EMSA-PKCS1-v1_5 section where it talks about optional parameters with some algorithms:

-- When id-md2 and id-md5 are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.

-- When id-sha1, id-sha256, id-sha384 and id-sha512 are used in an
-- AlgorithmIdentifier the parameters (which are optional) SHOULD
-- be omitted. However, an implementation MUST also accept
-- AlgorithmIdentifier values where the parameters are NULL.

But the example immediately following this text includes the null:

sha1    HashAlgorithm ::= {
    algorithm   id-sha1,
    parameters  SHA1Parameters : NULL  -- included for compatibility
                                       -- with existing implementations
}

All the ASN.1 examples I looked at in the documentation appear to include the mandatory optional null. Based on the behavior of both openssl (creation) and Mozilla PKIX (validation: https://hg.mozilla.org/mozilla-central/rev/08032b8280c6) the nulls-after-algorithm appears to be the generally accepted interpretation of the documentation, even though its required presence could be argued based on the original structure definition and the null does not appear to add value.

Update: I came across a posting on the OpenSSL mailing list https://mta.openssl.org/pipermail/openssl-dev/2015-January/000441.html that actually discusses this same issue, and the interpretation logic seems to be summed up (with some history) as follows:

... declaring that in this particular case (optional parameters of
AlgorithmIdentifier) NULL is equivalent to (the same as) absent. In fact,
RFC 5754 (page 4) states that the correct encoding is omitting the empty
list altogether, but some uses defined their encoding as NULL, and it’s OK. 
It reveals some history of this duality:

The two alternatives arise from the loss of the OPTIONAL associated with the
algorithm identifier parameters when the 1988 syntax for
AlgorithmIdentifier was translated into the 1997 syntax.  Later, the
OPTIONAL was recovered via a defect report, but by then many people
thought that algorithm parameters were mandatory.  Because of this
history, some implementations encode parameters as a NULL element
while others omit them entirely.
MC3
  • 36
  • 3