After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 745493 - DSA handled incorrectly
DSA handled incorrectly
Status: RESOLVED FIXED
Product: xmlsec
Classification: Other
Component: xmlsec-openssl
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Aleksey Sanin
Aleksey Sanin
Depends on:
Blocks:
 
 
Reported: 2015-03-03 01:22 UTC by nachman
Modified: 2015-03-06 00:39 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description nachman 2015-03-03 01:22:38 UTC
xmlsec1 1.2.20 (openssl)

The official XML Security specification for DSA is located here: http://www.w3.org/TR/xmldsig-core1/#sec-DSA (and http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf)

The information is long winded and doesn't state plainly the rules. Let me summarize them:

The following DSA signatures combinations are specified for XML Security:
(1024, 160) - DSAwithSHA1 - http://www.w3.org/2000/09/xmldsig#dsa-sha1
(2048, 256) - DSAwithSHA256 - http://www.w3.org/2009/xmldsig11#dsa-sha256
(3072, 256) - DSAwithSHA256 - http://www.w3.org/2009/xmldsig11#dsa-sha256

Among other things, the first variable specifies the amount of bits in the key, the second the size of a DSA signature component, which matches the size of the digest algorithm output.

DSA signatures consist of two components of the same size, r and s, the former being a random value, the latter being an encrypted digest. XML Security wants to see both of them raw, concatenated together, and base64 encoded.


There are two issues here I've noticed with the present implementation:
1) Unspecified combinations are allowed without warnings, for example, 2048 bit DSA keys used with sha1. In some cases, when signing, these combinations go through but with truncated results.
2) 2048 and 3072 bit keys with sha256 cannot be used, as xmlsec1 errors out by saying that 64 > 40.

While technically, there's no reason why all different key sizes (even unspecified ones like 4096 bit) can't be mixed and matched with the two specified digest algorithms, they're not allowed by the specification. At the very least there should be some kind of warning when used in signing or verifying.

Regarding the larger keys with sha256, the XML specification says that: "Integer to octet-stream conversion must be done according to the I2OSP operation defined in the RFC 3447 [PKCS1] specification with a l parameter equal to 20."
This statement in its current form in terms of size is only talking about sha1, and probably left over from an earlier version of the specification prior to sha256 being allowed, as the second value of the (L, N) pair should correspond with the digest algorithm output size.

FIPS 186-3 has this to say on the matter: "It is recommended that the security strength of the (L, N) pair and the security strength of the hash function used for the generation of digital signatures be the same unless an agreement has been made between participating entities to use a stronger hash function. When the length of the output of the hash function is greater than N (i.e., the bit length of q), then the leftmost N bits of the hash function output block shall be used in any calculation using the hash function output during the generation or verification of a digital signature. A hash function that provides a lower security strength than the (L, N) pair ordinarily should not be used, since this would reduce the security strength of the digital signature process to a level no greater than that provided by the hash function."

A hard rule of 20 bytes for sha256, would fall under FIPS 186-3 "should not be used" guideline. Furthermore, if that is the intention of the XML Security specification, it doesn't even define how the data is supposed to be truncated to fit the size! (and more so, restored for verification purposes)

Unless one wants to adhere to an unlikely interpretation of the specification, xmlsec1 should raise the byte size for a DSA signature for sha256 two 64 bytes (32*2 for r and s, up from 20).
Comment 1 nachman 2015-03-03 01:32:37 UTC
Sorry, I just wanted to clarify something in case someone reads this for a purpose other than the one I was aiming for here.

> "DSA signatures consist of two components of the same size, r and s, the former being a random value, the latter being an encrypted digest."

Isn't strictly true. The values are generated in a more complex fashion, and the randomly generated variables end up being a part of the calculation for s not r. However, as a mnemonic, it helps to remember that DSA signatures consist of randomness as well as the digest and encryption data.
Comment 2 Aleksey Sanin 2015-03-05 23:56:54 UTC
Fixed the problem #2 with DSA-SHA256 signatures. Funny there was a very similar issue with ECDSA signatures and similar constant :) 

Now I need to figure out how to handle "unsupported" cases. 


[master 78f720b] fix DSA-SHA256 signatures + test cases (bug #745493)
 30 files changed, 1045 insertions(+), 315 deletions(-)
 rewrite docs/xmlsec-man.html (100%)
 create mode 100644 tests/aleksey-xmldsig-01/enveloping-sha256-dsa2048-sha256.tmpl
 create mode 100644 tests/aleksey-xmldsig-01/enveloping-sha256-dsa2048-sha256.xml
 create mode 100644 tests/aleksey-xmldsig-01/enveloping-sha256-dsa3072-sha256.tmpl
 create mode 100644 tests/aleksey-xmldsig-01/enveloping-sha256-dsa3072-sha256.xml
 create mode 100644 tests/keys/demoCA/newcerts/AFA28BB933ADDAB2.pem
 create mode 100644 tests/keys/demoCA/newcerts/AFA28BB933ADDAB3.pem
 create mode 100644 tests/keys/dsa2048cert.der
 create mode 100644 tests/keys/dsa2048cert.pem
 create mode 100644 tests/keys/dsa2048key.der
 create mode 100644 tests/keys/dsa2048key.p12
 create mode 100644 tests/keys/dsa2048key.p8-der
 create mode 100644 tests/keys/dsa2048key.p8-pem
 create mode 100644 tests/keys/dsa2048key.pem
 create mode 100644 tests/keys/dsa3072cert.der
 create mode 100644 tests/keys/dsa3072cert.pem
 create mode 100644 tests/keys/dsa3072key.der
 create mode 100644 tests/keys/dsa3072key.p12
 create mode 100644 tests/keys/dsa3072key.p8-der
 create mode 100644 tests/keys/dsa3072key.p8-pem
 create mode 100644 tests/keys/dsa3072key.pem
Comment 3 Aleksey Sanin 2015-03-06 00:15:15 UTC
Actually, #1 is also fixed with this change. There is no truncation anymore and the signature value will simply be longer. This is not exactly "by the spec" but it is reasonable extension :)

Thanks again for reporting the problem!
Comment 4 nachman 2015-03-06 00:33:49 UTC
> Funny there was a very similar issue with ECDSA signatures and similar constant

Well, I see the issue as natural for the situation at hand. The XML Security group decided for (EC)DSA to not use an ASN.1 signature, and used fix length per DSA settings, to add additional work to handling for XML Signatures. Therefore, signatures could no longer be used directly, but need to be parsed and handled specifically for each size. Thanks to constant advancement in the field, these "fixed" sizes will keep growing.

> Now I need to figure out how to handle "unsupported" cases.

Regarding unsupported cases, here's what we're doing to handle them:

After loading the key, use EVP_PKEY_bits() to get amount of bits.

if dsa
  switch bits
    case 1024:
     dsa component size = 20
    case 2048:
    case 3072:
     dsa component size = 32
else if ecdsa
  dsa component size = (bits + 7) / 8
-----

if dsa
  if algo is sha1
    if dsa component size doesn't equal 20
      throw error
  else if algo is sha256
    if dsa component size doesn't equal 32
      throw error
  else
    throw error
-----

Another thing we're doing, which may or not be required depending on the ASN.1 parser and component to byte functions being used, is sanitizing the components from the signature.

loop
  if output component size > dsa component size and leading zero
    remove leading zero from output component

loop
  if output component size < dsa component size
    add leading zero to output component

if output component size doesn't equal dsa component size
  throw error

-----

This above pseudo code should handle all the current cases. However, it will need to be updated each time the DSA specification is expanded further, which is annoying. Although due to the way XML Security requires explicit strings for each signature and hash algorithm combination to be added, I don't see any alternative. Just need to keep such additions in sync with the new bit pairs supported.

The recently published FIPS 186-4 doesn't add on any new pairs, so at least it's unlikely for XML Security to make changes here any time soon.
Comment 5 nachman 2015-03-06 00:39:14 UTC
I might add another inconsistency with XML Security spec is not just having two subtags in the XML of <r></r> and <s></s> of any size, which would avoid the issue entirely. Although as Peter Gutmann said, the specification for XML Security, was designed to be difficult, just so they can be seen as working really hard on this.

Thanks for the fixes.