// (c) 2006 Richard Grimes // www.grimes.demon.co.uk using System; using System.IO; using System.Xml; using System.Security.Cryptography; using System.Security.Cryptography.Xml; using System.Security.Cryptography.X509Certificates; class App { // command line to sign: s infile outfile certfile // verify: v infile [certfile] static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("Usage: to sign: sign s infile outfile certfile"); Console.WriteLine(" to verify: v infile [certfile]"); return; } bool bSign = (args[0][0] == 's'); string inFile = args[1]; if (!File.Exists(inFile)) { Console.WriteLine("{0} does not exist", inFile); return; } string outFile = null; string certName = null; if (bSign) { if (args.Length < 4) return; outFile = args[2]; if (File.Exists(outFile)) File.Delete(outFile); certName = args[3]; } else { if (args.Length == 3) certName = args[2]; } if (bSign) { SignDocument(inFile, outFile, certName); } else { if (VerifyDocument(inFile, certName)) { Console.WriteLine("{0} is verified", inFile); } else { Console.WriteLine("{0} is corrupted", inFile); } } } static void SignDocument(string inFile, string outFile, string certName) { X509Certificate2 cert = GetCertificate(StoreName.My, certName); XmlDocument doc = new XmlDocument(); doc.Load(inFile); SignedXml sig = new SignedXml(doc); sig.SigningKey = cert.PrivateKey; Reference reference = new Reference("#item"); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); sig.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); sig.KeyInfo = keyInfo; sig.ComputeSignature(); doc.DocumentElement.AppendChild(sig.GetXml()); doc.Save(outFile); } static bool VerifyDocument(string inFile, string certName) { X509Certificate2 cert = null; if (certName != null) cert = GetCertificate(StoreName.AddressBook, certName); XmlDocument doc = new XmlDocument(); doc.Load(inFile); XmlElement signature = doc.DocumentElement["Signature"]; SignedXml sig = new SignedXml(doc); sig.LoadXml(signature); bool bVerified = false; if (cert == null) bVerified = sig.CheckSignature(); else bVerified = sig.CheckSignature(cert, true); return bVerified; } static X509Certificate2 GetCertificate(StoreName storeName, string certname) { X509Store store = new X509Store(storeName, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, certname, false); store.Close(); if (certs.Count == 0) { return null; } return certs[0]; } }