3

I'm trying to create and XMLDSig using an X509 cert. I run the verbatim example from MS (http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.x509issuerserial.aspx) which generates the XML below. The problem with the XML is that the X509SerialNumber field is too long to be an int, which is what the XSD specifies that it must be. Therefore, when I try to do XSD validation on the signature, it fails.

The error message I get is: The 'http://www.w3.org/2000/09/xmldsig#:X509SerialNumber' element is invalid - The value '72620403068401703770138453672807553309' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:integer' - The string '72620403068401703770138453672807553309' is not a valid Integer value.

How can I get the correct value for X509SerialNumber?

Thanks in advance!

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
  <SignedInfo>
    <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
    <Reference URI="">
      <Transforms>
        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
      </Transforms>
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <DigestValue>zSI5ZAMmQ+8u7R2rP7aAPT6nNQw=</DigestValue>
    </Reference>
  </SignedInfo>
  <SignatureValue>Tx4rqqDae4vdi5sTjARf0AlBiIGWnx2D8ET+ogGD9FtjrX4ZuYlsOG03Zk5KPKDpC/T45XlWaZpZdCtvAWtv0zwL1/jXxlU2BomQFNXm7rb9YoqlTh8nISStiZKizhmMQynW6GRsXGIpkK37Hnip4c8H1U+eSC/taKW4oyUmg40W64+ZyntovpBt2GqIJQu4AFvMfiF2azV9pg/qZ7IYNOgwmrUG6F0t2RhT2hqR9YRePjrfyIebZvYrLwjTQPXGOzzc2utRILAEhzGNSqsvpf5YeVrmuX75E8Zs3JuaicXu4mgDPYxNNVE2membNQMl6ggllfFjxPnvIofbb/KJ4Q==</SignatureValue>
  <KeyInfo>
    <X509Data>
      <X509IssuerSerial>
        <X509IssuerName>CN=XMLDSIG_Test</X509IssuerName>
        <X509SerialNumber>72620403068401703770138453672807553309</X509SerialNumber>
      </X509IssuerSerial>
      <X509Certificate>MIIDIDCCAgygAwIBAgIQNqIuTm7QSrZClm5/JrLZHTAJBgUrDgMCHQUAMCMxITAfBgNVBAMeGABYAE0ATABEAFMASQBHAF8AVABlAHMAdDAeFw0xMDAxMDEwNjAwMDBaFw0yMDAxMDEwNjAwMDBaMCMxITAfBgNVBAMeGABYAE0ATABEAFMASQBHAF8AVABlAHMAdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMl9hSOn53/2W2//EC8HUgwO7Hwpqx0/yTwth0w3amefwZcfu/+7k9rB+mnviCy6G/9uGzb0Mld+L3RVXisAx9zr2l6LVFjzImY1alwZ01z6AiDdllFPqO7BoSJSozMh0k+vdVQYR3lvgLNyKxXmrTayIWhioQeteIo6HuChz8HI/DNdzoO8axGbLuhy34pogG1gAQr3pTn16Pkd4Mu02KoRz90dryt09wuAk1P/jsePYHBeLQeJSLGojWp1sqypxr25FQiqJantyVLXRRmv7IauTTThSSNrREMcTzbpCx7B4tvyocNwGZysYcdJVsyjbxJRLqutQDlID6QykqkL9O8CAwEAAaNYMFYwVAYDVR0BBE0wS4AQ0N2edJbnLN9AE7hLcICPNaElMCMxITAfBgNVBAMeGABYAE0ATABEAFMASQBHAF8AVABlAHMAdIIQNqIuTm7QSrZClm5/JrLZHTAJBgUrDgMCHQUAA4IBAQC5Nf5SGjqIzQqVnwJbP22RqSHrITAPlymGYfP/qST8Q9V5h5aX8idcGMt3lShUbexXAlKcpQLO4ZzUrjjP3H5Jc659sRSDaeqHGXE0ZMTJpvwA871WH/sGZ8tB7/yuHVsP9hPTImwwDCWx9mYDz8LxpvK11beq/tEilZQxLTvMP0MuT5A6YdCcCc4GkeDV0KVFF+VLEO8OkaWDVXUNMe/AJBHrXuHbQPrUb7s67FKH+b/2GVjBBkM6YI9JtL/A96Y2uf6drhOz6C7wfky2XQOe/7v87/YGEshObBawBA1/OB1AVa+A2WVOosisEGi7iJqszQTdF6TLqGB5eDsiZCH2</X509Certificate>
    </X509Data>
  </KeyInfo>
</Signature>

I'm using the XSD from the following URL:

http://www.w3.org/2000/09/xmldsig#

And here's my code to validate the XSD:

    XmlElement xmlDigitalSignature = signedXml.GetXml();

    var xEl = XElement.Parse(xmlDigitalSignature.OuterXml);
    var xDoc = XDocument.Load(xEl.CreateReader());

    XSDValidator.ValidateSignature(xDoc);


public class XSDValidator
{
    public static void ValidateSignature(XDocument document)
    {
        var schemaSet = new XmlSchemaSet();
        var assm = Assembly.GetExecutingAssembly();
        using (var stream = assm.GetManifestResourceStream("JayTest1.XMLSignature.xsd"))
        {
            schemaSet.Add(XmlSchema.Read(stream, null));
        }
        var isValid = true;
        string errorMessage = null;

        document.Validate(schemaSet, (o, e) =>
        {
            errorMessage = e.Message;
            isValid = false;
        });
        if (!isValid)
        {
            Console.WriteLine("XSD is not valid: " + errorMessage);
        }
        else
        {
            Console.WriteLine("GOOD!");
        }
    }
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
jhilden
  • 12,207
  • 5
  • 53
  • 76

2 Answers2

2

According to RFC 5280 serial numbers can be expected to contain long integers:

Certificate users MUST be able to handle serialNumber values up to 20 octets. Conforming CAs MUST NOT use serialNumber values longer than 20 octets.

(section 4.1.2.2 on Serial Number)

Your serial number 7262040306 8401703770 1384536728 07553309 has merely 38 digits which even if they were hexadecimal digits form a number easily fitting into a 20 bytes long integer.

In XML Signature Syntax and Processing (Second Edition) (and the schema file) the element X509SerialNumber is defined as

<element name="X509SerialNumber" type="integer"/>

Which by the definition of integer does allow arbitrary integer values:

integer is derived from decimal by fixing the value of fractionDigits to be 0. This results in the standard mathematical concept of the integer numbers. The value space of integer is the infinite set {...,-2,-1,0,1,2,...}. The base type of integer is decimal.

(section 3.3.13 of XML Schema Part 2: Datatypes)

Thus, you might want to check your schema file or your XSD validator.

EDIT

While your code is based upon XML-Signature Syntax and Processing instead of XML Signature Syntax and Processing (Second Edition) as my answer is, this does make no difference because in both cases X509SerialNumber is defined as an integer without further restriction.

Thus, this is an issue of your validator. Whether it'a a bug or merely some configuration or customization matter, I do not know.

mkl
  • 90,588
  • 15
  • 125
  • 265
  • mkl, thank you for the reply. I've updated the question with the XSD file I'm using and the code I'm using to validate the XSD. Am I perhaps doing something wrong in the XSD check? – jhilden Mar 06 '13 at 21:05
  • @jhilden Your XMLdsig version also defines `X509SerialNumber` as `integer.` Thus, this is an issue of your validator. Whether it'a a bug or merely some configuration or customization matter, I do not know. – mkl Mar 07 '13 at 14:20
  • Hi, did you ever resolve this? I have had the same problem today. I struggle to believe that the .NET System.Xml libraries are at fault.... also, I got the same validation error with the XML Plugin for Notepad++ - so that's 2 validators that are allegedly buggy now... – Simon Green Apr 29 '15 at 19:48
  • sorry Simon but I don't think I ever resolved this issue. Perhaps manually updating the XSD is the key. – jhilden Apr 29 '15 at 19:50
  • 1
    Hmm, don't like doing that but it seems the only option available to me. Can't believe .NET xsd validator has been misbehaving for 2 years and not been fixed though! I'll change the xsd to say string and to a numeric check myself after parsing – Simon Green Apr 29 '15 at 19:56
  • Hi @SimonGreen. I have same issue with .NET. I have also applied a workaround and I'm also interested in an elegant solution. If someone push one, please, mention me to be aware. By de way, mkl's answer is right ( http://www.w3.org/2001/XMLSchema.xsd ) – dani herrera Jul 01 '15 at 13:08
1

The .NET XSD validator for xs:integer tries to validate the value by parsing it as a C# decimal (https://referencesource.microsoft.com/#System.Xml/System/Xml/Schema/DataTypeImplementation.cs,2874, https://referencesource.microsoft.com/#System.Xml/System/Xml/XmlConvert.cs,3e8716fb1936c48d).

Decimal has a range of positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335 (https://learn.microsoft.com/en-us/dotnet/api/system.decimal?view=netframework-4.7), or 28.79 digits.

This limit does exceed the minimum by http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#decimal:

NOTE: All ·minimally conforming· processors ·must· support decimal numbers with a minimum of 18 decimal digits (i.e., with a ·totalDigits· of 18). However, ·minimally conforming· processors ·may· set an application-defined limit on the maximum number of decimal digits they are prepared to support ...

If you feel that this is inhibiting valid usages of these types (not just test scenarios, though those are important, too) https://github.com/dotnet/corefx/issues/ would be the place to search for an issue to upvote (or finding none, create a new one).

bartonjs
  • 30,352
  • 2
  • 71
  • 111