title: c# Signing XML Document: What is in the x509 certificate
body: <p>I'm incorporating a software license system into a program of mine.
  The client asks for a license, sends me the data I need, then I generate an XML file, being the license file that my program must check at the clients side.</p>
  
  <p>So I generate a x509 certificate on my development computer (win10) and sign the license file.</p>
  
  <pre><code>X509Store store = new X509Store(StoreName, StoreLocation.CurrentUser);
  
  store.Open(OpenFlags.ReadOnly);
  
  X509Certificate2Collection certCollection = store.Certificates;
  X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
  X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, $"CN={CertificateName}", false);
  
  X509Certificate2 cert = signingCert[0]; // has private and public
  store.Close();        
  
  CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
  var exportedKeyMaterial = signingCert[0].PrivateKey.ToXmlString(true);
  
  var key = new RSACryptoServiceProvider(new CspParameters(24));
  key.PersistKeyInCsp = true;
  key.FromXmlString(exportedKeyMaterial);
  
  XmlDocument doc = new XmlDocument();
  doc.PreserveWhitespace = true;
  // LicenseInfo is the info about her computer etc. my client provides, eg. by e-mail
  using (TextReader sr = new StringReader(LicenseInfo))
  {
      doc.Load(sr);
  }
  
  SignedXml signedXml = new SignedXml(doc);
  signedXml.SigningKey = key;
  signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
  
  Reference reference = new Reference();
  reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
  reference.AddTransform(new XmlDsigExcC14NTransform());
  reference.Uri = "";
  reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
  signedXml.AddReference(reference);
  
  KeyInfo keyInfo = new KeyInfo();
  keyInfo.AddClause(new KeyInfoX509Data(cert));
  signedXml.KeyInfo = keyInfo;
  signedXml.ComputeSignature();
  
  XmlElement sig = signedXml.GetXml();
  
  doc.DocumentElement.AppendChild(doc.ImportNode(sig,true));
  if (doc.FirstChild is XmlDeclaration)
  {
      doc.RemoveChild(doc.FirstChild);
  }
  // and here it finally is: the license!
  LicenseText = doc.OuterXml;
  </code></pre>
  
  <p>The signature goes into the license file which will then look like this, after signing:</p>
  
  <pre><code>&lt;License&gt;
    &lt;MailAddress&gt;....&lt;/MailAddress&gt;
    &lt;LicenseNr&gt;8309847560354&lt;/LicenseNr&gt;
    &lt;RequestTimeStamp&gt;8/15/2019 11:28:47 AM&lt;/RequestTimeStamp&gt;
    &lt;ExpirationTimeStamp&gt;8/14/2020 11:28:47 AM&lt;/ExpirationTimeStamp&gt;
    &lt;X5&gt;78-BB-2F-65-4blabla45-A8-B5-4D-82&lt;/X5&gt;
  &lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
  &lt;SignedInfo&gt;
  &lt;CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /&gt;
  &lt;SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /&gt;
  &lt;Reference URI=""&gt;
  &lt;Transforms&gt;
  &lt;Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /&gt;
  &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
  &lt;/Transforms&gt;
  &lt;DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /&gt;
  &lt;DigestValue&gt;Gg9WLq12JSYFh6tatRTCnGbzEzMg8PidcXK4iWwPcXg=&lt;/DigestValue&gt;
  &lt;/Reference&gt;
  &lt;/SignedInfo&gt;
  &lt;SignatureValue&gt;JdC09BIeHcw8...q24JFVseBZWXOo==&lt;/SignatureValue&gt;
  &lt;KeyInfo&gt;
  &lt;X509Data&gt;
  &lt;X509Certificate&gt;MIIC8zCCAd+gAwIBAgIQgwuqv2X..........oP7f5f&lt;/X509Certificate&gt;
  &lt;/X509Data&gt;
  &lt;/KeyInfo&gt;
  &lt;/Signature&gt;
  &lt;/License&gt;
  </code></pre>
  
  <p>What is in that &lt;X509Certificate/> ?
  My public key?
  If so, I do not need to include my public key in the program as an embeded resource because it will be in my clients license file, that must be processed anyway...
  Correct?
  The   will not include my private key, I hope...?</p>
  
  <p>Here is how i (try to) verify the license validity (not including the expiration date, only seeing if the license file was not tampered with)</p>
  
  <pre><code>XmlDocument xmlDocument = new XmlDocument();
  
  xmlDocument.Load(Name); // the license file
  
  SignedXml signedXml = new SignedXml(xmlDocument);
  
  XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
  signedXml.LoadXml((XmlElement)nodeList[0]);
  
  RSACryptoServiceProvider Key = new RSACryptoServiceProvider(new CspParameters(24));
  
  Key.ToXmlString(false);
  
  return signedXml.CheckSignature(Resources.PubKey.FromXmlString()); // ????? or what?
  </code></pre>
  
  <p>So:</p>
  
  <p>1: What is in the X509Certificate in the signature?</p>
  
  <p>2: Verification does not work. Any suggestions?</p>
  
  <p>3: Do I include my public key in the program that checks the license, or is the signature itself the source?</p>
  
  <p>PS:</p>
  
  <p>Please, don't point out that this will not give me 100% security. I know.
  My questions are about X509, not about guarding against theft. That is another, much broader, issue. It's interesting, programming this stuff and learning.</p>