Reputation: 12449
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!");
}
}
}
Upvotes: 3
Views: 2849
Reputation: 33266
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).
Upvotes: 1
Reputation: 96039
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.
Upvotes: 2