public static Email ParseEmail(string data) { var email = new Email(); bool isHeader = true; using (var reader = new StringReader(data)) { string line; while ((line = reader.ReadLine()) != null) { if (isHeader) { if (line == string.Empty) { isHeader = false; continue; } email.HeaderLines.Add(line); } else { email.BodyLines.Add(line); } } } email.Body = string.Join(Environment.NewLine, email.BodyLines); email.Headers = string.Join(Environment.NewLine, email.HeaderLines) + Environment.NewLine; return email; }
string GenerateSignature(Email email, params string[] signHeaders) { // timestamp - seconds since 00:00:00 on January 1, 1970 UTC TimeSpan t = DateTime.Now.ToUniversalTime() - DateTime.SpecifyKind(DateTime.Parse("00:00:00 January 1, 1970"), DateTimeKind.Utc); var signatureValue = new StringBuilder(); signatureValue.Append("v=1; "); signatureValue.Append("a=rsa-sha256; "); // Canonicalization signatureValue.Append("c="); signatureValue.Append(this.HeaderCanonicalization.ToString().ToLower()); signatureValue.Append('/'); signatureValue.Append(this.BodyCanonicalization.ToString().ToLower()); signatureValue.Append("; "); signatureValue.Append("q=dns/txt; "); // signing domain signatureValue.Append("d="); signatureValue.Append(this.Domain); signatureValue.Append("; "); // selector signatureValue.Append("s="); signatureValue.Append(this.Selector); signatureValue.Append("; "); // time sent signatureValue.Append("t="); signatureValue.Append((int)t.TotalSeconds); signatureValue.Append("; "); // hash of body signatureValue.Append("bh="); signatureValue.Append(SignBody(Canonicalization.CanonicalizationBody(email.Body, this.BodyCanonicalization))); signatureValue.Append("; "); // headers to be signed signatureValue.Append("h="); //sb.Append(string.Join(":", headers)); foreach (var header in signHeaders) { signatureValue.Append(header); signatureValue.Append(':'); } signatureValue.Length--; signatureValue.Append("; "); signatureValue.Append("b="); Console.WriteLine(); Console.WriteLine("---- start sig ----"); Console.WriteLine(signatureValue); Console.WriteLine("---- start sig ----"); var catHeaders = new StringBuilder(); catHeaders.Append(Canonicalization.CanonicalizationHeaders(email.Headers, this.HeaderCanonicalization)); //foreach (var header in signHeaders) //{ // catHeaders.Append(header.ToLower()); // catHeaders.Append(':'); // catHeaders.AppendLine(headers[header]); //} catHeaders.Append("dkim-signature:"); catHeaders.Append(signatureValue); Console.WriteLine("---- can sig ----"); Console.WriteLine(catHeaders); Console.WriteLine("---- can end ----"); using (TextReader reader = new StringReader(this.PrivateKey)) { var r = new PemReader(reader); var o = (AsymmetricCipherKeyPair)r.ReadObject(); byte[] plaintext = this.Encoding.GetBytes(catHeaders.ToString()); ISigner sig = SignerUtilities.GetSigner("SHA256WithRSAEncryption"); sig.Init(true, o.Private); sig.BlockUpdate(plaintext, 0, plaintext.Length); byte[] signature = sig.GenerateSignature(); signatureValue.Append(Convert.ToBase64String(signature)); } return signatureValue.ToString(); }