title: verify digital signed email with attachment "the hash value is not correct"
body: <p>I am trying to verify the signature of a digitally signed email. It know the signature is correct, because outlook verifies it. I am using SignedCms to perform the validation</p>
  
  <p>I have the following message: </p>
  
  <pre><code>Content-Type: multipart/signed; protocol="application/pkcs7-signature";
      micalg=sha1; boundary="boundary1"
  
  --boundary1
  Content-Type: multipart/mixed;
      boundary="boundary2"
  
  --boundary2
  Content-Type: text/plain; charset="iso-8859-1"
  Content-Transfer-Encoding: quoted-printable
  
  some text in the body
  of the message
  
  
  
  --boundary2
  Content-Type: application/something;
      name="somefile.txt"
  Content-Transfer-Encoding: base64
  Content-Disposition: attachment;
      filename="somefile.txt"
  
  FkrMjIwOjE1OCdRVFkrMjIwOjE3NidRVFkrMjIwOjE5MydRVFkrMjIwOjIwNydR
  VFkrMjIwOjIyMidRVFkrMjIwOjIzNCdRVFkrMjIwOjI0NSdRVFkrMjIwOjI1OCdRVFkrMjIwOjI2
  NidRVFkrMjIwOjI3NydRVFkrMjIwOjI4NSdRVFkrMjIwOjI5MSdRVFkrMjIwOjI5OCdRVFkrMjIw
  OjMwMidRVFkrMjIwOjMwNidRVFkrMjIwO
  --boundary2--
  
  --boundary1
  Content-Type: application/pkcs7-signature; name="smime.p7s"
  Content-Transfer-Encoding: base64
  Content-Disposition: attachment; filename="smime.p7s"
  
  MIIIEAYJKoZIhvcNAQcCoIIIATCCB/0CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3
  DQEHAaCCBW4wggVqMIIEUqADAgECAg4YHgABAAIO2xMJhvDULzANBgkqhkiG9w0B
  AQUFADB8MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
  
  
  --boundary1--
  </code></pre>
  
  <p>and I am having huge trouble verifying the signature for it.</p>
  
  <p>This is how I attempt to do it:
  EmailMessage message = results.ElementAt(13) as EmailMessage;
              message.Load();</p>
  
  <pre><code>        var attachments = message.Attachments;
          foreach (var attachment in attachments)
          {
              var fAttachment = attachment as FileAttachment;
              fAttachment.Load();
              string fullMailData = Encoding.UTF8.GetString(fAttachment.Content);
              FileToolbox.WriteStringToFile(@"C:\BeforeDecoding.txt", fullMailData);
              var lines = fullMailData.Split('\n');
              string signature = "";
              string dataPlain = "";
              //These line numbers do not correspond to the example, 
              //because it is altered to hide the real email
              for (int i = 12 - 1; i &lt;= 13 - 1; i++)
              {
                  dataPlain += lines[i];
              }
              //These line numbers do not correspond to the example
              //because it is altered to hide the real email
              for (int i = 56 - 1; i &lt;= 99 - 1; i++)
                  {
                      signature += lines[i];
                  }
  
              var signedCms = new SignedCms(new ContentInfo(Encoding.ASCII.GetBytes(dataPlain)));
              signedCms.Decode(base64_decode(signature));
              signedCms.CheckHash();
              signedCms.CheckSignature(true);
  </code></pre>
  
  <p>So in the above example I only use the body with text/plain to checksignature. I have also attempted the following sections:</p>
  
  <ol>
  <li>Everything from --boundary1 until --boundary1 appears again.</li>
  <li>Only the base64 encrypted body part (which is then base64 decoded)</li>
  <li>A merge of the 2 bodies</li>
  <li>I have attempted keeping the \r and \n values</li>
  <li>I have attempted keeping only the \r values</li>
  </ol>
  
  <p>Every one returns with invalid hash value.</p>
  
  <p>What am I doing wrong? which part of the message should I pass to new SignedCms()?</p>
  
  <p><strong>Extra comment to the solution</strong>
  Since PKCS#7/CMS messages from web methods are always detached signedcms should be instantiated with detached = true according to this <a href="http://www.developmentnow.com/g/46_2009_6_0_0_793061/Dotnet-2-0-PCKS-CheckSignature-Error.htm" rel="nofollow">somewhat acceptable source</a></p>
  
  <pre><code>public SignedCms(
      ContentInfo contentInfo,
      bool detached
  )
  </code></pre>
  
  <p>For my MWE I saved the full file content to a file and then manually removed some lines. I did not do the string split up (yet...). So my MWE ended up like this:</p>
  
  <pre><code>    var fullMessageBytes = File.ReadAllBytes(@"C:\fAttachment_content.txt");
      var isoEncoding = Encoding.GetEncoding("iso-8859-1");
      var fullMessageString = isoEncoding.GetString(fullMessageBytes);
  
      var messageBytes = File.ReadAllBytes(@"C:\message_body.txt");
      var messageBytesString = isoEncoding.GetString(messageBytes);
  
      var signatureStringReadIn = File.ReadAllText(@"C:\certToReadIn.txt");
      var signatureStringReadInBytes = Convert.FromBase64String(signatureStringReadIn);
  
      var signedCms = new SignedCms(new ContentInfo(messageBytes), true);
      signedCms.Decode(signatureStringReadInBytes);
      signedCms.CheckSignature(false);
  </code></pre>