Example #1
0
		public EmailHeader SignMessage(Email email)
		{
			// Find the actual headers we're going to sign
			var headers = email.GetHeadersToSign(_headersToSign);

			// Generate the header value
			var value = this.GenerateDkimHeaderValue(email, headers);

			// Add the signature key
			headers.Add(new EmailHeader() { Key = SignatureKey, Value = value});

			// sign email
			value += GenerateSignature(email, headers);

			// Return the new header
			return new EmailHeader() { Key = SignatureKey, Value = value };
		}
Example #2
0
		/*
		 * see http://www.dkim.org/specs/rfc4871-dkimbase.html#dkim-sig-hdr
		 * 
		 * */
		public string GenerateDkimHeaderValue(Email email, List<EmailHeader> headers)
		{
			// 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();

			var start = /*Email.NewLine + */" ";
			var end = ";";
			//nl= string.Empty;

			signatureValue.Append("v=1;");
			
			// algorithm used
			signatureValue.Append(start);
			signatureValue.Append("a=");
			signatureValue.Append(_privateKeySigner.Algorithm);
			signatureValue.Append(end);

			// Canonicalization
			signatureValue.Append(start);
			signatureValue.Append("c=");
			signatureValue.Append(this.HeaderCanonicalization.ToString().ToLower());
			signatureValue.Append('/');
			signatureValue.Append(this.BodyCanonicalization.ToString().ToLower());
			signatureValue.Append(end);

			// signing domain
			signatureValue.Append(start);
			signatureValue.Append("d=");
			signatureValue.Append(_domain);
			signatureValue.Append(end);

			// headers to be signed
			signatureValue.Append(start);
			signatureValue.Append("h=");
			foreach (var header in headers)
			{
				signatureValue.Append(header.Key);
				signatureValue.Append(':');
			}
			signatureValue.Length--;
			signatureValue.Append(end);

			// i=identity
			// not supported

			// l=body length
			//not supported

			// public key location
			signatureValue.Append(start);
			signatureValue.Append("q=dns/txt");
			signatureValue.Append(end);

			// selector
			signatureValue.Append(start);
			signatureValue.Append("s=");
			signatureValue.Append(_selector);
			signatureValue.Append(end);

			// time sent
			signatureValue.Append(start);
			signatureValue.Append("t=");
			signatureValue.Append((int)t.TotalSeconds);
			signatureValue.Append(end);

			// x=expiration
			// not supported

			// hash of body
			signatureValue.Append(start);
			signatureValue.Append("bh=");
			signatureValue.Append(SignBody(email));
			signatureValue.Append(end);

			// x=copied header fields
			// not supported

			signatureValue.Append(start);
			signatureValue.Append("b=");
			
			return signatureValue.ToString();
		}
Example #3
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="email">The email to sign.</param>
		/// <param name="signature"></param>
		/// <returns></returns>
		public string GenerateSignature(Email email, List<EmailHeader> headers)
		{
			var cheaders = DkimCanonicalizer.CanonicalizeHeaders(headers, this.HeaderCanonicalization);
			return Convert.ToBase64String(_privateKeySigner.Sign(email.Encoding.GetBytes(cheaders)));
		}
Example #4
0
		public string SignBody(Email email)
		{
			var cb = DkimCanonicalizer.CanonicalizeBody(email.Body, this.BodyCanonicalization);
			return Convert.ToBase64String(_privateKeySigner.Hash(email.Encoding.GetBytes(cb)));
		}
        public static string Canonicalize(Email email, DomainKeyCanonicalizationAlgorithm algorithm, List<EmailHeader> headersToSign)
        {
            Func<String, string> process;
            switch (algorithm)
            {
                case DomainKeyCanonicalizationAlgorithm.Simple:
                    {
                        process = x => x;
                        break;
                    }
                case DomainKeyCanonicalizationAlgorithm.Nofws:
                    {
                        process = x => x.RemoveWhitespace();
                        break;
                    }
                default:
                    {
                        throw new ArgumentException("Invalid canonicalization type.");
                    }
            }

            var headers = new StringBuilder();
            foreach (var h in headersToSign)
            {
                headers.Append(process(h.Key));
                headers.Append(':');
                headers.Append(process(" " + h.Value));
                headers.Append(Email.NewLine);
            }

            var body = new StringBuilder();
            using (var reader = new StringReader(email.Body))
            {
                string line;
                int emptyLines = 0;

                // if only empty lines don't write until these is text after them
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Length == 0)
                    {
                        emptyLines++;
                    }
                    else
                    {
                        while (emptyLines > 0)
                        {
                            body.Append(Email.NewLine);
                            emptyLines--;
                        }

                        body.Append(process(line));
                        body.Append(Email.NewLine);

                    }

                }
            }

            // If the body consists entirely of empty lines, then the header/body
            // line is similarly ignored.
            if (body.Length == 0)
            {
                return headers.ToString();
            }

            headers.Append(Email.NewLine);// header/body seperator line
            headers.Append(body);
            return headers.ToString();
        }
        public EmailHeader SignMessage(Email email)
        {
            var signatureValue = new StringBuilder();

            // algorithm used
            signatureValue.Append("a=");
            signatureValue.Append(_privateKeySigner.Algorithm);
            signatureValue.Append("; ");

            // Canonicalization
            signatureValue.Append("c=");
            signatureValue.Append(this.Canonicalization.ToString().ToLower());
            signatureValue.Append("; ");

            // signing domain
            signatureValue.Append("d=");
            signatureValue.Append(_domain);
            signatureValue.Append("; ");

            // headers to be signed
            var headers = email.GetHeadersToSign(_headersToSign);
            if (headers.Count>0)
            {
                signatureValue.Append("h=");
                foreach (var header in headers)
                {
                    signatureValue.Append(header.Key);
                    signatureValue.Append(':');
                }
                signatureValue.Length--;
                signatureValue.Append("; ");
            }

            // public key location
            signatureValue.Append("q=dns; ");

            // selector
            signatureValue.Append("s=");
            signatureValue.Append(_selector);
            signatureValue.Append("; ");

            // signature data
            signatureValue.Append("b=");
            signatureValue.Append(SignSignature(email, headers));
            signatureValue.Append(";");

            return new EmailHeader() { Key = SignatureKey, Value = signatureValue.ToString() };
        }
 public string SignSignature(Email email, List<EmailHeader> headers)
 {
     var text = DomainKeyCanonicalizer.Canonicalize(email, this.Canonicalization, headers);
     return Convert.ToBase64String(_privateKeySigner.Sign(email.Encoding.GetBytes(text)));
 }
Example #8
0
		void FinishCollecting()
		{
			if (m_CollectMode == CollectMode.None)
				return;

			var e = new Email() 
			{ 
				Headers = m_collectedHeaders, 
				Body = m_collectedContent.ToString(),
				Encoding = writer.Encoding
			};

			// Generate Dkim signature
			if (DkimSigner != null)
			{
				m_collectedHeaders.Insert(0, DkimSigner.SignMessage(e));
			}

			// Generate domain keys signature
			if (DomainKeysSigner != null)
			{
				m_collectedHeaders.Insert(0, DomainKeysSigner.SignMessage(e));
			}

			m_CollectMode = CollectMode.None;

			// Write all headers
			foreach (var h in m_collectedHeaders)
			{
				SendHeader(h.Key, h.Value);
			}

			// Write the separator
			SendData(string.Empty);

			// Write the content
			SendData(e.Body);
		}
Example #9
0
        public string SignSignature(Email email, List <EmailHeader> headers)
        {
            var text = DomainKeyCanonicalizer.Canonicalize(email, this.Canonicalization, headers);

            return(Convert.ToBase64String(_privateKeySigner.Sign(email.Encoding.GetBytes(text))));
        }