I'm using .NET framework 1.1 + WSE10SP1.exe.
I'm not able to merge transforms: enveloped signature and exclusive
canonical
to get something like that:
<Transforms>
<Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
inside my xml signed document.
If I uncomment the lines with the comment "Buggy!!!!!!!!! ", I get a
validation error: "unknown transform".
----------------------------------------------------------------------------
---------------------------------------------------------
Unknown tranform has been encountered.
at Microsoft.Web.Services.Security.Reference.LoadXml(XmlElement value)
at Microsoft.Web.Services.Security.SignedInfo.LoadXml(XmlElement value)
at Microsoft.Web.Services.Security.SignedXmlSignature.LoadXml(XmlElement
value)
at Microsoft.Web.Services.Security.SignedXml.LoadXml(XmlElement value)
at FirmaProject.WSFindCertnet.ExclusiveCanonicalVerify(XmlDocument doc,
XmlElement signedOutput, RSA rsa) in
----------------------------------------------------------------------------
----------------------------------------------------------
Rigth now, I'm just able to sign exclusive canonical without enveloped.
I hope somebody could help me!.
Any help would be appreciated and thanks in advance,
Joan.
ps: Here is my code:
public static string Sign(string filter, string xml)
{
// Certificate search.
Certificate foundcert = findCertificate(storeName, filter);
if (!foundcert.HasPrivateKey())
{
return "ERROR";
}
// Retrieve X509 certificate from a store Certificate.
Microsoft.Web.Services.Security.X509.X509Certificate x509 =
Certificate2X509Certificate(foundcert);
Console.WriteLine("Private key: \t{0}", x509.Key.ToString());
// Retrieve private key with WSDL library.
System.Security.Cryptography.RSA privateCertKey = x509.Key;
try
{
// Load document to sign.
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.LoadXml(xml);
Console.WriteLine("\n Signing from <{1}>: \t{0}", xml, filter);
// Sign.
XmlElement xmlDigitalSignature = SignExclusive(doc, privateCertKey,
x509, "#ID", false);
Console.WriteLine("\nFirma\t{0}", xmlDigitalSignature.OuterXml);
// Verify.
if (ExclusiveCanonicalVerify(doc, xmlDigitalSignature, x509.PublicKey))
{
Console.WriteLine("OK!");
}
else
{
Console.WriteLine("SNIFF, SNIFF, SNIFF!");
}
// Compose the signed XML into the result string.
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature,
true)); // insert the signature into the document
if (doc.FirstChild is XmlDeclaration)
doc.RemoveChild(doc.FirstChild);
return doc.OuterXml;
}
catch(System.Security.Cryptography.CryptographicException ex)
{
Console.WriteLine("Crypto exception:");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
return "ERROR";
}
catch(Exception ex)
{
Console.WriteLine("Generic exception:");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.Message);
return "ERROR";
}
}
public static bool ExclusiveCanonicalVerify(XmlDocument doc,
XmlElement signedOutput,
System.Security.Cryptography.RSA rsa)
{
// Exclusive transform c14n.
Microsoft.Web.Services.Security.SignedXml xmlSign =
new Microsoft.Web.Services.Security.SignedXml(doc);
// XML document retrieving.
xmlSign.LoadXml(signedOutput);
System.Security.Cryptography.Xml.KeyInfo keyInfo =
new System.Security.Cryptography.Xml.KeyInfo();
keyInfo.AddClause(new System.Security.Cryptography.Xml.RSAKeyValue(rsa));
xmlSign.KeyInfo = keyInfo;
// Check the signature.
return xmlSign.CheckSignature();
}
public static XmlElement SignExclusive(
XmlDocument doc,
System.Security.Cryptography.RSA key,
Microsoft.Web.Services.Security.X509.X509Certificate MSCert,
string uri, bool comments)
{
// Create a new KeyInfo object.
System.Security.Cryptography.Xml.KeyInfo keyInfo =
new System.Security.Cryptography.Xml.KeyInfo();
// Load the certificate into a KeyInfoX509Data object
// and add it to the KeyInfo object.
keyInfo.AddClause(new
System.Security.Cryptography.Xml.KeyInfoX509Data(MSCert));
// Create a WebServices SignedXml object.
Microsoft.Web.Services.Security.SignedXml signedXml =
new Microsoft.Web.Services.Security.SignedXml(doc);
// Assign the key to the SignedXml object.
signedXml.SigningKey = key;
// Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyInfo;
// Create a reference to be signed.
Microsoft.Web.Services.Security.Reference reference =
new Microsoft.Web.Services.Security.Reference();
reference.Uri = uri;
// Enveloped transform.
// Buggy!!!!!!!!!. EnvelopedSignature does not work with "Exclusive C14N"
!!!!!!!!!
// Buggy!!!!!!!!! reference.AddTransform(new
System.Security.Cryptography.Xml.XmlDsigEnvelopedSignatureTransform());
// Buggy!!!!!!!!!. EnvelopedSignature does not work with "Exclusive C14N"
!!!!!!!!!
// Exclusive C14D transform.
Microsoft.Web.Services.Security.XmlDsigExcC14NTransform transC14 =
new Microsoft.Web.Services.Security.XmlDsigExcC14NTransform(comments);
reference.AddTransform(transC14);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// add key info if neccessary
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
// (insert the signature into the doc)
return signedXml.GetXml();
}
ps2: Sample document to sign.
<PeticionVolante>
<PeticionVolanteDatosFirmados Id='ID' Version='V1.0' xmlns=''>
<CodigoMunicipio>666</CodigoMunicipio>
<CodigoProvincia>999</CodigoProvincia>
<NumeroExpediente>expediente</NumeroExpediente>
<TipoDocumentacion>tipoDocumentacion</TipoDocumentacion>
<Documentacion>documentacion</Documentacion>
</PeticionVolanteDatosFirmados>
</PeticionVolante
DPai - 09 Sep 2004 18:06 GMT
I believe you need to register the class you're using for the
transform (in your case, provided by WSE) with the framework.
Try adding this section as the last entry before the
</configuration> tag in your machine.config
(under %windir%\Microsoft.NET\Framework\v1.1.4322\CONFIG).
You'll need to reboot for it to take effect.
<!-- Other configuration settings. -->
<!-- This is required by the exclusive C14N transform. -->
<mscorlib>
<cryptographySettings>
<cryptoNameMapping>
<cryptoClasses>
<cryptoClass
exc14n="Microsoft.Web.Services.Security.XmlDsigExcC14NTransform,
Microsoft.Web.Services.Security" />
<cryptoClass
exc14n.comments="Microsoft.Web.Services.Security.XmlDsigExcC14NWithCommentsTransform,
Microsoft.Web.Services.Security" />
</cryptoClasses>
<nameEntry name="http://www.w3.org/2001/10/xml-exc-c14n#"
class="exc14n" />
<nameEntry
name="http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
class="exc14n.comments" />
</cryptoNameMapping>
</cryptographySettings>
</mscorlib
Curt Smith - 17 Sep 2004 16:18 GMT
> I believe you need to register the class you're using for the
> transform (in your case, provided by WSE) with the framework.
[quoted text clipped - 26 lines]
> </cryptographySettings>
> </mscorlib>
I did this and I'm still getting the following exception. Any other
possibilities?
OBTW, I can sign a doc, but when I feed that same Document to
signedXml.LoadXml(Document) it throws this exception:
Exception Details: System.Security.Cryptography.CryptographicException:
Unknown tranform has been encountered.
Source Error:
Line 203:
Line 204: XmlNodeList nodeList =
signedDoc.GetElementsByTagName("Signature",
SignedXml.XmlDsigNamespaceUrl);
Line 205: sx.LoadXml((XmlElement)nodeList[0]);
Line 206:
Line 207: bool isValid = sx.CheckSignature(key);
Source File: c:\inetpub\wwwroot\browserpost\samlutils.cs Line: 205
Stack Trace:
[CryptographicException: Unknown tranform has been encountered.]
Microsoft.Web.Services.Security.Reference.LoadXml(XmlElement value)
Microsoft.Web.Services.Security.SignedInfo.LoadXml(XmlElement
value)
Microsoft.Web.Services.Security.SignedXmlSignature.LoadXml(XmlElement
value)
Microsoft.Web.Services.Security.SignedXml.LoadXml(XmlElement value)
BrowserPost.SAMLUtils.ValidateDocument(XmlDocument signedDoc,
String keyName) in c:\inetpub\wwwroot\browserpost\samlutils.cs:205
BrowserPost.TestScenarios.Page_Load(Object sender, EventArgs e) in
c:\inetpub\wwwroot\browserpost\testscenarios.aspx.cs:84
System.Web.UI.Control.OnLoad(EventArgs e)
System.Web.UI.Control.LoadRecursive()
System.Web.UI.Page.ProcessRequestMain()
Thanks, curt