From 223fc15cc47a442de8ba36ae919fe4a1396e1425 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Mon, 18 Jul 2022 12:57:27 -0400 Subject: [PATCH 1/8] This program successfully validates a rimtool-signed swidtag --- tools/tcg_rim_tool/microsoftXmlDsig.cs | 150 +++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 tools/tcg_rim_tool/microsoftXmlDsig.cs diff --git a/tools/tcg_rim_tool/microsoftXmlDsig.cs b/tools/tcg_rim_tool/microsoftXmlDsig.cs new file mode 100644 index 00000000..494dfcd9 --- /dev/null +++ b/tools/tcg_rim_tool/microsoftXmlDsig.cs @@ -0,0 +1,150 @@ + using System; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Security.Cryptography.Xml; +using System.Xml; + +public class VerifyXML +{ + + public static void Main(String[] args) + { + try + { + const string signingAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"; + const string signingCertName = "RimSignCert.pem"; + const string privateKeyFilename = "privateRimKey.pem"; + + //Load public cert from file + X509Certificate2 signingCert = new X509Certificate2(signingCertName); + RSA publicKey = signingCert.GetRSAPublicKey(); + //Load private key from file + string privateKeyText = System.IO.File.ReadAllText(privateKeyFilename); + //System.Console.WriteLine("Using private key: " + privateKeyText); + var privateKey = RSA.Create(); + privateKey.ImportFromPem(privateKeyText); + + // Load an XML file into the XmlDocument object. + XmlDocument unsignedDoc = new XmlDocument(); + unsignedDoc.PreserveWhitespace = true; + unsignedDoc.Load("unsigned.xml"); + SignXml(unsignedDoc, privateKey); + unsignedDoc.Save("signed.xml"); + + // Verify the signature of the signed XML. + XmlDocument signedDoc = new XmlDocument(); + signedDoc.Load("signed.xml"); + bool result = VerifyXml(signedDoc, publicKey); + + // Display the results of the signature verification to + // the console. + if (result) + { + Console.WriteLine("The XML signature is valid."); + } + else + { + Console.WriteLine("The XML signature is not valid."); + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + } + private static void SignXml(XmlDocument xmlDoc, RSA rsaKey) + { + if (xmlDoc == null) + throw new ArgumentException(nameof(xmlDoc)); + if (rsaKey == null) + throw new ArgumentException(nameof(rsaKey)); + + Console.Write("Signing xml..."); + + // Create a SignedXml object. + SignedXml signedXml = new SignedXml(xmlDoc); + + // Add the key to the SignedXml document. + signedXml.SigningKey = rsaKey; + + // Create a reference to be signed. + Reference reference = new Reference(); + reference.Uri = ""; + + // Add an enveloped transformation to the reference. + XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); + reference.AddTransform(env); + + // Add the reference to the SignedXml object. + signedXml.AddReference(reference); + + // Compute the signature. + signedXml.ComputeSignature(); + + // Get the XML representation of the signature and save + // it to an XmlElement object. + XmlElement xmlDigitalSignature = signedXml.GetXml(); + + // Append the element to the XML document. + xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); + Console.WriteLine("Xml signed."); + } + + // Verify the signature of an XML file against an asymmetric + // algorithm and return the result. + public static Boolean VerifyXml(XmlDocument xmlDoc, RSA key) + { + // Check arguments. + if (xmlDoc == null) + throw new ArgumentException("xmlDoc"); + if (key == null) + throw new ArgumentException("key"); + + Console.Write("Verifying signature..."); + // Create a new SignedXml object and pass it + // the XML document class. + SignedXml signedXml = new SignedXml(xmlDoc); + + // Find the "Signature" node and create a new + // XmlNodeList object. + XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature"); + + // Throw an exception if no signature was found. + if (nodeList.Count <= 0) + { + throw new CryptographicException("Verification failed: No Signature was found in the document."); + } + + // This example only supports one signature for + // the entire XML document. Throw an exception + // if more than one signature was found. + if (nodeList.Count >= 2) + { + throw new CryptographicException("Verification failed: More than one signature was found for the document."); + } + + // Load the first node. + signedXml.LoadXml((XmlElement)nodeList[0]); + Boolean isValid = false; + try + { + isValid = signedXml.CheckSignature(key); + } catch (Exception e) + { + Console.WriteLine(e.Message); + } + + // Check the signature and return the result. + return isValid; + } + +} +//6/17/2022 +//Copied RimSignCert.pem, RimCertChain.pem, and generated_user_cert_embed.swidtag to EC2. +//Tried reading RimSignCert and RimCertChain (both certs and each cert by itself) and extracting the PK, validation failed all attempts. +//Verified that swidtag is in fact signed by RimSignCert's private key. +// +//7/11/2022 +//Copied RimSignCert.pem, generated_user_cert_embed.swidtag (less the signature block), and privateRimKey.pem to EC2. +//Tried signing the unsigned RIM with the private key and then validated with the public key from the cert; unsuccessful. + From 6a173fe162b8e6606b120e012aae1cf1695b44f6 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Tue, 19 Jul 2022 18:06:57 -0400 Subject: [PATCH 2/8] This program generates a signature that passes validation by the rimtool. --- tools/tcg_rim_tool/microsoftXmlDsig.cs | 49 ++++++++++++++++---------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/tools/tcg_rim_tool/microsoftXmlDsig.cs b/tools/tcg_rim_tool/microsoftXmlDsig.cs index 494dfcd9..f558d5cb 100644 --- a/tools/tcg_rim_tool/microsoftXmlDsig.cs +++ b/tools/tcg_rim_tool/microsoftXmlDsig.cs @@ -1,9 +1,23 @@ - using System; +using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Xml; +/** + * This program reads in the following files: + * 1. Public certificate, pem format + * 2. Corresponding private key, pem format + * 3. Unsigned xml document + * 4. Signed xml document + * The two functions are SignXml() and VerifyXml() and are called in succession. + * + * XmlDocument.PreserveWhitespace(false) allows the subsequent signed xml document + * to pass validation. + * + * VerifyXml() strictly checks the cryptographic integrity of the Signature block, + * it does not verify the integrity of the certificate chain. + */ public class VerifyXML { @@ -14,6 +28,9 @@ public class VerifyXML const string signingAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"; const string signingCertName = "RimSignCert.pem"; const string privateKeyFilename = "privateRimKey.pem"; + const string unsignedFilename = "unsigned.xml"; + const string signedFilename = "signed.xml"; + const string signedRIM = "signedRIM.swidtag"; //Load public cert from file X509Certificate2 signingCert = new X509Certificate2(signingCertName); @@ -26,21 +43,20 @@ public class VerifyXML // Load an XML file into the XmlDocument object. XmlDocument unsignedDoc = new XmlDocument(); - unsignedDoc.PreserveWhitespace = true; - unsignedDoc.Load("unsigned.xml"); + unsignedDoc.Load(unsignedFilename); SignXml(unsignedDoc, privateKey); - unsignedDoc.Save("signed.xml"); + unsignedDoc.Save(signedFilename); // Verify the signature of the signed XML. XmlDocument signedDoc = new XmlDocument(); - signedDoc.Load("signed.xml"); + signedDoc.Load(signedFilename); bool result = VerifyXml(signedDoc, publicKey); // Display the results of the signature verification to // the console. if (result) { - Console.WriteLine("The XML signature is valid."); + Console.WriteLine("The XML signature is valid!"); } else { @@ -78,6 +94,11 @@ public class VerifyXML // Add the reference to the SignedXml object. signedXml.AddReference(reference); + // Add keyinfo block + KeyInfo keyInfo = new KeyInfo(); + keyInfo.AddClause(new RSAKeyValue((RSA)rsaKey)); + signedXml.KeyInfo = keyInfo; + // Compute the signature. signedXml.ComputeSignature(); @@ -92,7 +113,7 @@ public class VerifyXML // Verify the signature of an XML file against an asymmetric // algorithm and return the result. - public static Boolean VerifyXml(XmlDocument xmlDoc, RSA key) + private static Boolean VerifyXml(XmlDocument xmlDoc, RSA key) { // Check arguments. if (xmlDoc == null) @@ -129,22 +150,14 @@ public class VerifyXML try { isValid = signedXml.CheckSignature(key); - } catch (Exception e) + } + catch (Exception e) { Console.WriteLine(e.Message); } - + // Check the signature and return the result. return isValid; } } -//6/17/2022 -//Copied RimSignCert.pem, RimCertChain.pem, and generated_user_cert_embed.swidtag to EC2. -//Tried reading RimSignCert and RimCertChain (both certs and each cert by itself) and extracting the PK, validation failed all attempts. -//Verified that swidtag is in fact signed by RimSignCert's private key. -// -//7/11/2022 -//Copied RimSignCert.pem, generated_user_cert_embed.swidtag (less the signature block), and privateRimKey.pem to EC2. -//Tried signing the unsigned RIM with the private key and then validated with the public key from the cert; unsuccessful. - From 1836620f9847b1317b457fb75809c13e008c6cba Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Thu, 21 Jul 2022 15:01:57 -0400 Subject: [PATCH 3/8] Moved Microsoft library program to its own directory under HIRS/tools/ --- .../microsoftXmlDsig.cs => tcg_rim_tool_msdotnet/xmlDsig.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/{tcg_rim_tool/microsoftXmlDsig.cs => tcg_rim_tool_msdotnet/xmlDsig.cs} (100%) diff --git a/tools/tcg_rim_tool/microsoftXmlDsig.cs b/tools/tcg_rim_tool_msdotnet/xmlDsig.cs similarity index 100% rename from tools/tcg_rim_tool/microsoftXmlDsig.cs rename to tools/tcg_rim_tool_msdotnet/xmlDsig.cs From de2db0491df9e5fa85ce99a5dd5c2073d5b2e0b4 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Thu, 28 Jul 2022 07:46:54 -0400 Subject: [PATCH 4/8] Read commandline arguments for sign and validate functions. Arguments for either include an xml file and a pem file. --- tools/tcg_rim_tool_msdotnet/xmlDsig.cs | 190 +++++++++++++++---------- 1 file changed, 115 insertions(+), 75 deletions(-) diff --git a/tools/tcg_rim_tool_msdotnet/xmlDsig.cs b/tools/tcg_rim_tool_msdotnet/xmlDsig.cs index f558d5cb..968e5da6 100644 --- a/tools/tcg_rim_tool_msdotnet/xmlDsig.cs +++ b/tools/tcg_rim_tool_msdotnet/xmlDsig.cs @@ -1,87 +1,103 @@ -using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Xml; +using System.CommandLine; /** - * This program reads in the following files: - * 1. Public certificate, pem format - * 2. Corresponding private key, pem format - * 3. Unsigned xml document - * 4. Signed xml document - * The two functions are SignXml() and VerifyXml() and are called in succession. - * - * XmlDocument.PreserveWhitespace(false) allows the subsequent signed xml document - * to pass validation. - * - * VerifyXml() strictly checks the cryptographic integrity of the Signature block, + * This command line program has three commands: + * 1. sign - append a signature calculated from a user-provided private key + * 2. validate - validate a signature with a user-provided certificate + * 3. debug - print out important components of a signed XML document + * + * The validate functioin strictly checks the cryptographic integrity of the signature, * it does not verify the integrity of the certificate chain. */ -public class VerifyXML +class Rimtool { - public static void Main(String[] args) + static async Task Main(String[] args) { - try - { - const string signingAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"; - const string signingCertName = "RimSignCert.pem"; - const string privateKeyFilename = "privateRimKey.pem"; - const string unsignedFilename = "unsigned.xml"; - const string signedFilename = "signed.xml"; - const string signedRIM = "signedRIM.swidtag"; - - //Load public cert from file - X509Certificate2 signingCert = new X509Certificate2(signingCertName); - RSA publicKey = signingCert.GetRSAPublicKey(); - //Load private key from file - string privateKeyText = System.IO.File.ReadAllText(privateKeyFilename); - //System.Console.WriteLine("Using private key: " + privateKeyText); - var privateKey = RSA.Create(); - privateKey.ImportFromPem(privateKeyText); - - // Load an XML file into the XmlDocument object. - XmlDocument unsignedDoc = new XmlDocument(); - unsignedDoc.Load(unsignedFilename); - SignXml(unsignedDoc, privateKey); - unsignedDoc.Save(signedFilename); - - // Verify the signature of the signed XML. - XmlDocument signedDoc = new XmlDocument(); - signedDoc.Load(signedFilename); - bool result = VerifyXml(signedDoc, publicKey); - - // Display the results of the signature verification to - // the console. - if (result) + var fileOption = new Option( + name: "--file", + description: "The filename input for the command.", + parseArgument: result => { - Console.WriteLine("The XML signature is valid!"); - } - else - { - Console.WriteLine("The XML signature is not valid."); - } - } - catch (Exception e) + string? filePath = result.Tokens.Single().Value; + if (!File.Exists(filePath)) + { + result.ErrorMessage = "File " + filePath + " does not exist."; + return null; + } else + { + return filePath; + } + }); + var privateKeyOption = new Option( + name: "--private-key", + description: "The private key with which to sign." + ); + var certificateOption = new Option( + name: "--certificate", + description: "The certificate with which to validate the signature." + ); + + var rootCommand = new RootCommand("A tool for signing, validating, and debugging base RIMs."); + var signCommand = new Command("sign", "Sign the given file with the given key.") { - Console.WriteLine(e.Message); - } + fileOption, + privateKeyOption + }; + var validateCommand = new Command("validate", "Validate the signature in the given base RIM.") + { + fileOption, + certificateOption + }; + var debugCommand = new Command("debug", "Print out the significant portions of a base RIM.") + { + fileOption + }; + + signCommand.SetHandler(async (file, privateKey) => + { + await SignXml(file, privateKey); + }, fileOption, privateKeyOption); + validateCommand.SetHandler(async (file, certificate) => + { + await ValidateXml(file, certificate); + }, fileOption, certificateOption); + debugCommand.SetHandler(async (file) => + { + await DebugRim(file); + }, fileOption); + + rootCommand.AddCommand(signCommand); + rootCommand.AddCommand(validateCommand); + rootCommand.AddCommand(debugCommand); + + return rootCommand.InvokeAsync(args).Result; } - private static void SignXml(XmlDocument xmlDoc, RSA rsaKey) + internal static async Task SignXml(string xmlFilename, string keyFilename) { - if (xmlDoc == null) - throw new ArgumentException(nameof(xmlDoc)); - if (rsaKey == null) - throw new ArgumentException(nameof(rsaKey)); + if (String.IsNullOrWhiteSpace(xmlFilename)) + throw new ArgumentException(nameof(xmlFilename)); + if (String.IsNullOrWhiteSpace(keyFilename)) + throw new ArgumentException(nameof(keyFilename)); Console.Write("Signing xml..."); - // Create a SignedXml object. - SignedXml signedXml = new SignedXml(xmlDoc); + // Load an XML file into a SignedXML object. + XmlDocument unsignedDoc = new XmlDocument(); + unsignedDoc.Load(xmlFilename); + SignedXml signedXml = new SignedXml(unsignedDoc); + + //Load private key from file + string privateKeyText = System.IO.File.ReadAllText(keyFilename); + var privateKey = RSA.Create(); + privateKey.ImportFromPem(privateKeyText); // Add the key to the SignedXml document. - signedXml.SigningKey = rsaKey; + signedXml.SigningKey = privateKey; // Create a reference to be signed. Reference reference = new Reference(); @@ -96,7 +112,7 @@ public class VerifyXML // Add keyinfo block KeyInfo keyInfo = new KeyInfo(); - keyInfo.AddClause(new RSAKeyValue((RSA)rsaKey)); + keyInfo.AddClause(new RSAKeyValue((RSA)privateKey)); signedXml.KeyInfo = keyInfo; // Compute the signature. @@ -107,28 +123,35 @@ public class VerifyXML XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. - xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); + unsignedDoc.DocumentElement.AppendChild(unsignedDoc.ImportNode(xmlDigitalSignature, true)); + // unsignedDoc.Save(signedFilename); Console.WriteLine("Xml signed."); } // Verify the signature of an XML file against an asymmetric // algorithm and return the result. - private static Boolean VerifyXml(XmlDocument xmlDoc, RSA key) + internal static async Task ValidateXml(string signedFilename, string certFilename) { // Check arguments. - if (xmlDoc == null) - throw new ArgumentException("xmlDoc"); - if (key == null) - throw new ArgumentException("key"); + if (String.IsNullOrWhiteSpace(signedFilename)) + throw new ArgumentException(nameof(signedFilename)); + if (certFilename == null) + throw new ArgumentException(nameof(certFilename)); Console.Write("Verifying signature..."); // Create a new SignedXml object and pass it // the XML document class. - SignedXml signedXml = new SignedXml(xmlDoc); + XmlDocument signedDoc = new XmlDocument(); + signedDoc.Load(signedFilename); + SignedXml signedXml = new SignedXml(signedDoc); + + //Load public cert from file + X509Certificate2 signingCert = new X509Certificate2(certFilename); + RSA publicKey = signingCert.GetRSAPublicKey(); // Find the "Signature" node and create a new // XmlNodeList object. - XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature"); + XmlNodeList nodeList = signedDoc.GetElementsByTagName("Signature"); // Throw an exception if no signature was found. if (nodeList.Count <= 0) @@ -149,7 +172,7 @@ public class VerifyXML Boolean isValid = false; try { - isValid = signedXml.CheckSignature(key); + isValid = signedXml.CheckSignature(publicKey); } catch (Exception e) { @@ -157,7 +180,24 @@ public class VerifyXML } // Check the signature and return the result. - return isValid; + if (isValid) + { + Console.WriteLine("Signature is valid!"); + } else + { + Console.WriteLine("Signature is not valid."); + } + } + + internal static async Task DebugRim(string filename) + { + if (String.IsNullOrWhiteSpace(filename)) + { + throw new ArgumentException(nameof(filename)); + } + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.Load(filename); + } } From 5061e6d88c1e0849e4321bf352c91c3b51ad6c88 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Thu, 28 Jul 2022 20:48:29 -0400 Subject: [PATCH 5/8] Sign function writes the signed xml to a new file. Added supporting files for testing convenience. --- tools/tcg_rim_tool_msdotnet/RimSignCert.pem | 23 +++++++++++ .../generated_user_cert.swidtag | 41 +++++++++++++++++++ tools/tcg_rim_tool_msdotnet/privateRimKey.pem | 28 +++++++++++++ tools/tcg_rim_tool_msdotnet/xmlDsig.cs | 14 ++++--- 4 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 tools/tcg_rim_tool_msdotnet/RimSignCert.pem create mode 100644 tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag create mode 100644 tools/tcg_rim_tool_msdotnet/privateRimKey.pem diff --git a/tools/tcg_rim_tool_msdotnet/RimSignCert.pem b/tools/tcg_rim_tool_msdotnet/RimSignCert.pem new file mode 100644 index 00000000..40aa4386 --- /dev/null +++ b/tools/tcg_rim_tool_msdotnet/RimSignCert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID2jCCAsKgAwIBAgIJAP0uwoNdwZDFMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UECgwHRXhhbXBsZTERMA8GA1UECwwI +UENDbGllbnQxEjAQBgNVBAMMCUV4YW1wbGVDQTAeFw0yMDA3MjEyMTQ1MDBaFw0z +MDA1MzAyMTQ1MDBaMFwxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTEQMA4GA1UE +CgwHRXhhbXBsZTERMA8GA1UECwwIUENDbGllbnQxGzAZBgNVBAMMEmV4YW1wbGUu +UklNLnNpZ25lcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKd1lWGk +SRuxAAY2wHag2GVxUk1dZx2PTpfQOflvLeccAVwa8mQhlsRERq+QK8ilj8Xfqs44 +/nBaccZDOjdfIxIUCMfwhGXjxCaqZbgTucNsExDnu4arTGraoAwzHg0cVLiKT/Cx +j9NL4dcMgxRXsPdHfXb0923C7xYd2t2qfW05umgaj7qeQl6c68CFNsGX4JA8rWFQ +ZvvGx5DGlK4KTcjPuQQINs5fxasNKqLY2hq+z82x/rqwr2hmyizD6FpFSyIABPEM +PfB036GEhRwu1WEMkq8yIp2jgRUoFYke9pB3ph9pVow0Hh4mNFSKD4pP41VSKY1n +us83mdkuukPy5o0CAwEAAaOBpzCBpDAdBgNVHQ4EFgQUL96459AwoiCdqgGGGpZP +7ezyvMEwHwYDVR0jBBgwFoAURqG47dumcV/Q0ud6ijxdbprDljgwCQYDVR0TBAIw +ADALBgNVHQ8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwNQYIKwYBBQUHAQEE +KTAnMCUGCCsGAQUFBzAChhlodHRwczovL2V4YW1wbGUuY29tL2NlcnRzMA0GCSqG +SIb3DQEBCwUAA4IBAQDpKx5oQlkS11cg7Qp58BmCvjCzFpof+qYePooJsD3i5SwK +fRTa2CkDMww9qrwBK7G60y7jhe5InKTdqIlVqaji5ZImR0QMKTtk7zt9AJ9EaEzK +xfDiE/qX34KxNe4ZmbvLH8N+BSujQXMMi56zGjW469Y/rbDMG8uU1dq3zqhO5b+d +Ur1ecdkYLgzxu6O+oWy5JpVibmcjvNezJsUtjc+km2FYm24vU3/fCNzZ2z0EHQES +cIEQ5OqfpdFrV3De238RhMH6J4xePSidnFpfBc6FrdyDI1A8eRFz36I4xfVL3ZnJ +P/+j+NE4q6yz5VGvm0npLO394ZihtsI1sRAR8ORJ +-----END CERTIFICATE----- diff --git a/tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag b/tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag new file mode 100644 index 00000000..a86b1edb --- /dev/null +++ b/tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + 97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A= + + + N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV +7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz +FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth +8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4 +TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw== + + + + p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx +xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 +dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q +otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW +jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ== + AQAB + + + + + diff --git a/tools/tcg_rim_tool_msdotnet/privateRimKey.pem b/tools/tcg_rim_tool_msdotnet/privateRimKey.pem new file mode 100644 index 00000000..afe282c4 --- /dev/null +++ b/tools/tcg_rim_tool_msdotnet/privateRimKey.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCndZVhpEkbsQAG +NsB2oNhlcVJNXWcdj06X0Dn5by3nHAFcGvJkIZbEREavkCvIpY/F36rOOP5wWnHG +Qzo3XyMSFAjH8IRl48QmqmW4E7nDbBMQ57uGq0xq2qAMMx4NHFS4ik/wsY/TS+HX +DIMUV7D3R3129Pdtwu8WHdrdqn1tObpoGo+6nkJenOvAhTbBl+CQPK1hUGb7xseQ +xpSuCk3Iz7kECDbOX8WrDSqi2Noavs/Nsf66sK9oZsosw+haRUsiAATxDD3wdN+h +hIUcLtVhDJKvMiKdo4EVKBWJHvaQd6YfaVaMNB4eJjRUig+KT+NVUimNZ7rPN5nZ +LrpD8uaNAgMBAAECggEAcnG8npd9U0x7HMQMcsZoPaPdwHvF/gCzkLNA+8RM1bZh +A4ZzA5WlCQs0V8Wq9pyXjn7Wp8txsG1PdlT5k2AUgsVoXuR0R4IKyvYHQG9StEjH +GvWURmwJdLlnSg8hSYqEJ/52taNUDO6+MI8fgiaQDd8w0ryF4OCpLy9GJdnfkGYZ +Ayemb3USFUdj/S67NVqxnvAfFMM5FqkKGhkoy7wBRgO6eOeJvoTq8LMiPiponwwF +DW409ZStbrk1f1Oszst/UvFUWA9BdDfeoPmFR61y3eB5zlMQG8Mhr2v5hvkj9TPX +FU4Fm4EzZ1h/60cdWoP6XYCP7F2NqZ8N8u4UBQNAIQKBgQDcGIw5GJEvRF+FFTTR +hYatMRn80DGTVjdT32MgajdKx05OWxBmQsFob34fiSnr0wAXPJeDXG4ruMBE2bSk +EC8rCO08G8ihQoH8x0cvuERe1fpVWk3RWNucVGIiJSEXAIwWrlYZLTfYd5GqBkPE +OQxxo4MtOyqeHmVH1mOywk9ABQKBgQDCxt95luzqQZV9Xl78QQvOIbjOdHLjY23Z +yp8sGt9birL/WZ33TCRgmH1e61BdrSqO7Om/ail2Y59XM5UU6kLbDj0IgmOPTsrJ +JmIVf8r3bKltVUaLePgr4yex7dmtHRH8OkLXKnE0RCO0kCi9kJMB12yE3pWxk+Pu +zztQd3a66QKBgBNJd2g9deONe01fOVyu9clRhzR3ThDaOkj4R2h8xlGgO4V0R3Ce +ovIy6vt6epj2yYg/wAs720+rhfXCmijSXj/ILXnZ+W/gMyHimKNe42boG2LFYhJZ +Vg1R+7OAS3EHlD8ckeDs7Hrkp3gdymx0j1mZ+ZHKIIbwpPFxoRT2IBm9AoGBAI0Z +bIK0puP8psKvPrgWluq42xwUl7XKLaX8dtqIjQ3PqGP7E8g2TJP9Y7UDWrDB5Xas +gZi821R8Ts3o/DKukcgGxIgJjP4f4h9dwug4L1yWRxaBFB2tgHqqj/MBjxMtX/4M +Zqdgg6mNQyBm3lyVAynuWRrX9DE0JYa2cQ2VvVkhAoGBAMBv/oT813w00759PmkO +Uxv3LXTJuYBbq0Rmga25jN3ow8LrGQdSVg7F/af3I5KUF7mLiegDy1pkRfauyXH7 ++WhEqnf86vDrzPpytDMxinWOQZusCqeWHb+nuVTuL3Fv+GxEdwVGYI/7lFJ7B//h +P5rU93ZoYY7sWcGVqaaEkMRU +-----END PRIVATE KEY----- diff --git a/tools/tcg_rim_tool_msdotnet/xmlDsig.cs b/tools/tcg_rim_tool_msdotnet/xmlDsig.cs index 968e5da6..256d8bf6 100644 --- a/tools/tcg_rim_tool_msdotnet/xmlDsig.cs +++ b/tools/tcg_rim_tool_msdotnet/xmlDsig.cs @@ -21,14 +21,15 @@ class Rimtool var fileOption = new Option( name: "--file", description: "The filename input for the command.", - parseArgument: result => + parseArgument: result => { string? filePath = result.Tokens.Single().Value; if (!File.Exists(filePath)) { result.ErrorMessage = "File " + filePath + " does not exist."; return null; - } else + } + else { return filePath; } @@ -124,8 +125,9 @@ class Rimtool // Append the element to the XML document. unsignedDoc.DocumentElement.AppendChild(unsignedDoc.ImportNode(xmlDigitalSignature, true)); - // unsignedDoc.Save(signedFilename); - Console.WriteLine("Xml signed."); + string signedFilename = "signed_" + xmlFilename; + unsignedDoc.Save(signedFilename); + Console.WriteLine("Xml signed and written to " + signedFilename); } // Verify the signature of an XML file against an asymmetric @@ -183,7 +185,8 @@ class Rimtool if (isValid) { Console.WriteLine("Signature is valid!"); - } else + } + else { Console.WriteLine("Signature is not valid."); } @@ -201,3 +204,4 @@ class Rimtool } } + From a5a36fda12ab7b766822888fd3d0eab7a2bcd58a Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Mon, 1 Aug 2022 11:52:43 -0400 Subject: [PATCH 6/8] Rename directory tcg_rim_tool_msdotnet to xml_dsig_tool --- .../RimSignCert.pem | 0 .../privateRimKey.pem | 0 .../unsigned.xml} | 30 ------------------- .../xmlDsig.cs | 0 4 files changed, 30 deletions(-) rename tools/{tcg_rim_tool_msdotnet => xml_dsig_tool}/RimSignCert.pem (100%) rename tools/{tcg_rim_tool_msdotnet => xml_dsig_tool}/privateRimKey.pem (100%) rename tools/{tcg_rim_tool_msdotnet/generated_user_cert.swidtag => xml_dsig_tool/unsigned.xml} (52%) rename tools/{tcg_rim_tool_msdotnet => xml_dsig_tool}/xmlDsig.cs (100%) diff --git a/tools/tcg_rim_tool_msdotnet/RimSignCert.pem b/tools/xml_dsig_tool/RimSignCert.pem similarity index 100% rename from tools/tcg_rim_tool_msdotnet/RimSignCert.pem rename to tools/xml_dsig_tool/RimSignCert.pem diff --git a/tools/tcg_rim_tool_msdotnet/privateRimKey.pem b/tools/xml_dsig_tool/privateRimKey.pem similarity index 100% rename from tools/tcg_rim_tool_msdotnet/privateRimKey.pem rename to tools/xml_dsig_tool/privateRimKey.pem diff --git a/tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag b/tools/xml_dsig_tool/unsigned.xml similarity index 52% rename from tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag rename to tools/xml_dsig_tool/unsigned.xml index a86b1edb..1fa11f85 100644 --- a/tools/tcg_rim_tool_msdotnet/generated_user_cert.swidtag +++ b/tools/xml_dsig_tool/unsigned.xml @@ -8,34 +8,4 @@ - - - - - - - - - - 97uWB7zSsO5WaGbrcQrlKd1Bju0aDTjK1/ktUYBje8A= - - - N1YtTeo2Ryuj+CtlXIpICEay+ni7vt8+4J7tAsYpa3efnLwtea69PIqEylPWm9LdA8Eo8XDdpgxV -7h3hi2LTOU+Wxq3bLiLamo99T1EtIwl+ZPcOv8bsfEkmShHdMC0dlfcj6r7x4tc0XkNAhhJgfRNz -FsmPWKJb6FYcsHFbHO/Uw1hSokbAGcWWTshEOqvKHMa8UVkrFMUPnrnMtdyJqZlhDBrZHNi4rWth -8TjlUnQVSCF9s9I04FxJ1cUAdeVMHtXKM8Pvjv68PaJMJK73dW5Yd3SbcgoKLesf/HPWeeZL0rr4 -TNjlqJ/wq61Ons45MFG9bIscVbnd+XxFHx8Skw== - - - - p3WVYaRJG7EABjbAdqDYZXFSTV1nHY9Ol9A5+W8t5xwBXBryZCGWxERGr5AryKWPxd+qzjj+cFpx -xkM6N18jEhQIx/CEZePEJqpluBO5w2wTEOe7hqtMatqgDDMeDRxUuIpP8LGP00vh1wyDFFew90d9 -dvT3bcLvFh3a3ap9bTm6aBqPup5CXpzrwIU2wZfgkDytYVBm+8bHkMaUrgpNyM+5BAg2zl/Fqw0q -otjaGr7PzbH+urCvaGbKLMPoWkVLIgAE8Qw98HTfoYSFHC7VYQySrzIinaOBFSgViR72kHemH2lW -jDQeHiY0VIoPik/jVVIpjWe6zzeZ2S66Q/LmjQ== - AQAB - - - - diff --git a/tools/tcg_rim_tool_msdotnet/xmlDsig.cs b/tools/xml_dsig_tool/xmlDsig.cs similarity index 100% rename from tools/tcg_rim_tool_msdotnet/xmlDsig.cs rename to tools/xml_dsig_tool/xmlDsig.cs From b134ebdeda1b5ab0688b9df9506060b692f0f887 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Thu, 11 Aug 2022 11:59:46 -0400 Subject: [PATCH 7/8] WIP: debug function prints out the xml data to be signed, but the calculated signature value is not decoding properly. --- tools/xml_dsig_tool/xmlDsig.cs | 60 +++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/tools/xml_dsig_tool/xmlDsig.cs b/tools/xml_dsig_tool/xmlDsig.cs index 256d8bf6..8add8088 100644 --- a/tools/xml_dsig_tool/xmlDsig.cs +++ b/tools/xml_dsig_tool/xmlDsig.cs @@ -3,6 +3,7 @@ using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using System.Xml; using System.CommandLine; +using System.Text; /** * This command line program has three commands: @@ -13,7 +14,7 @@ using System.CommandLine; * The validate functioin strictly checks the cryptographic integrity of the signature, * it does not verify the integrity of the certificate chain. */ -class Rimtool +class XmlDsigTool { static async Task Main(String[] args) @@ -54,9 +55,10 @@ class Rimtool fileOption, certificateOption }; - var debugCommand = new Command("debug", "Print out the significant portions of a base RIM.") + var debugCommand = new Command("debug", "Print out the significant portions of a base RIM and the expected signature value.") { - fileOption + fileOption, + privateKeyOption }; signCommand.SetHandler(async (file, privateKey) => @@ -67,10 +69,10 @@ class Rimtool { await ValidateXml(file, certificate); }, fileOption, certificateOption); - debugCommand.SetHandler(async (file) => + debugCommand.SetHandler(async (file, privateKey) => { - await DebugRim(file); - }, fileOption); + await DebugRim(file, privateKey); + }, fileOption, privateKeyOption); rootCommand.AddCommand(signCommand); rootCommand.AddCommand(validateCommand); @@ -93,7 +95,7 @@ class Rimtool SignedXml signedXml = new SignedXml(unsignedDoc); //Load private key from file - string privateKeyText = System.IO.File.ReadAllText(keyFilename); + string privateKeyText = File.ReadAllText(keyFilename); var privateKey = RSA.Create(); privateKey.ImportFromPem(privateKeyText); @@ -192,16 +194,56 @@ class Rimtool } } - internal static async Task DebugRim(string filename) + internal static async Task DebugRim(string filename, string keyFilename) { if (String.IsNullOrWhiteSpace(filename)) { throw new ArgumentException(nameof(filename)); + } else if (String.IsNullOrWhiteSpace(keyFilename)) + { + throw new ArgumentException(nameof(keyFilename)); } + + XmlDocument xmlToBeSigned = new XmlDocument(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(filename); + XmlNodeList nodes = xmlDoc.GetElementsByTagName("SoftwareIdentity"); + XmlNodeList signatureNodes = xmlDoc.GetElementsByTagName("Signature"); + //Assumes there is only one signature; may change in the future for multiple signatures + if (signatureNodes.Count > 0) + { + nodes[0].RemoveChild(signatureNodes[0]); + } + xmlToBeSigned.AppendChild(xmlToBeSigned.ImportNode(nodes[0], true)); + string outFileName = "ToBeSigned_" + filename; + xmlToBeSigned.Save(outFileName); + Console.WriteLine("Xml data to be signed parsed to " + outFileName); + + //Load private key from file + string privateKeyText = File.ReadAllText(keyFilename); + var privateKey = RSA.Create(); + privateKey.ImportFromPem(privateKeyText); + + // Add the key to the SignedXml document. + SignedXml signedXml = new SignedXml(xmlToBeSigned); + signedXml.SigningKey = privateKey; + + // Create a reference to be signed. + Reference reference = new Reference(); + reference.Uri = ""; + + // Add an enveloped transformation to the reference. + XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); + reference.AddTransform(env); + + // Add the reference to the SignedXml object. + signedXml.AddReference(reference); + + signedXml.ComputeSignature(); + Signature signature = signedXml.Signature; + Console.WriteLine("For the data to be signed the expected signature value is " + + Encoding.Default.GetString(signature.SignatureValue)); } } - From fa27277632ead52a6fe93fb2574b8df243c82533 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Thu, 8 Sep 2022 08:23:22 -0400 Subject: [PATCH 8/8] Added README.md --- tools/xml_dsig_tool/README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tools/xml_dsig_tool/README.md diff --git a/tools/xml_dsig_tool/README.md b/tools/xml_dsig_tool/README.md new file mode 100644 index 00000000..21a1de6d --- /dev/null +++ b/tools/xml_dsig_tool/README.md @@ -0,0 +1,30 @@ +The xml_dsig_tool is a Windows command line application that provides the ability to perform basic cryptographic functions per the W3C XML Signature Syntax and Processing Version 1.1. The functions include: + +sign : append an enveloped signature to an unsigned XML document +validate : validate a signed base rim's signature (NOTE: cryptographic validation only, this tool does not validate the RIM structure) + + +# Build and package + - Install Visual Studio + - The recommended project name is "xml_dsig_tool" so that the resulting executable file will be appropriately named xml_dsig_tool.exe. + - Install NuGet packages: + - System.CommandLine.2.0.0-beta4 (check "Include Prerelease" next to search bar) + - System.Security.Cryptography.X509Certificates + - System.Security.Cryptography.Xml + - Publish executable + - https://docs.microsoft.com/en-us/dotnet/core/tutorials/publishing-with-visual-studio?pivots=dotnet-6-0 + - Install support files to .exe directory + - privateRimKey.pem + - RimSignCert.pem + - unsigned.xml + + +# Running xml_dsig_tool +Navigate to the .exe directory and run the following commands + +help + +sign --file unsigned.xml --private-key privateKey.pem + +validate --file signed_unsigned.xml --certificate RimSignCert.pem +