Example #1
0
        //// todo remove once stable.
        //public IDebug Debug { get; set; }

        #endregion Properties


        public DomainKeySigner([NotNull] IPrivateKeySigner privateKeySigner, [NotNull] string domain, [NotNull] string selector, string[] headersToSign = null)
        {
            if (privateKeySigner == null)
            {
                throw new ArgumentNullException("privateKeySigner");
            }

            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }

            if (domain.Length == 0)
            {
                throw new ArgumentException("Domain cannot be an empty string.");
            }

            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }

            if (selector.Length == 0)
            {
                throw new ArgumentException("Selector cannot be an empty string.");
            }


            _domain           = domain;
            _selector         = selector;
            _headersToSign    = headersToSign;
            _privateKeySigner = privateKeySigner;

            this.Encoding = Encoding.UTF8;
        }
Example #2
0
        private static string GenerateDkimSignature(Email email, Encoding encoding, IPrivateKeySigner privateKeySigner, string[] headersToSign)
        {
            if (email == null)
            {
                throw new ArgumentNullException("email");
            }

            if (email.Headers == null)
            {
                throw new ArgumentException("email headers property is null");
            }

            var headers = DkimCanonicalizer.CanonicalizeHeaders(email.Headers, dkimHeaderCanonicalization, true, headersToSign);

            // assumes signature ends with "b="
            return(Convert.ToBase64String(privateKeySigner.Sign(encoding.GetBytes(headers), dkimSigningAlgorithm)));
        }
Example #3
0
        public static void Sign(ref MailMessage message, Encoding encoding, IPrivateKeySigner privateKeySigner, string domain, string selector, string[] headersToSign)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }

            message.BodyEncoding    = encoding;
            message.SubjectEncoding = encoding;
            message.HeadersEncoding = encoding;

            var email = Parse(message);

            if (!CanSign(email))
            {
                throw new InvalidOperationException("Unable to Domain Key sign the message");
            }

            var signature = GenerateDomainKeySignature(email, encoding, privateKeySigner, domain, selector, headersToSign);

            message.Headers.Prepend(Constant.DomainKeySignatureKey, signature);

            email = Parse(message);

            var value = GenerateDkimHeaderValue(email, encoding, privateKeySigner, domain, selector, headersToSign);

            // signature value get formatted so add dummy signature value then remove it
            message.Headers.Prepend(Constant.DkimSignatureKey, value + new string('0', 70));
            email = Parse(message);
            var formattedSig = email.Headers[Constant.DkimSignatureKey].Value;

            email.Headers[Constant.DkimSignatureKey].Value = formattedSig.Substring(0, formattedSig.Length - 70);

            // sign email
            value += GenerateDkimSignature(email, encoding, privateKeySigner, headersToSign);
            message.Headers.Set(Constant.DkimSignatureKey, value);
        }
Example #4
0
        public DkimSigner([NotNull]IPrivateKeySigner privateKeySigner, [NotNull]string domain, [NotNull]string selector, string[] headersToSign = null)
		{
			if (privateKeySigner == null)
			{
				throw new ArgumentNullException("privateKeySigner");
			}

			if (domain == null)
			{
				throw new ArgumentNullException("domain");
			}

			if (domain.Length == 0)
			{
				throw new ArgumentException("Cannot be empty.", "domain");
			}

			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}

			if(selector.Length == 0)
			{
				throw new ArgumentException("Cannot be empty.", "selector");
			}


			_privateKeySigner = privateKeySigner;
			_domain = domain;
			_selector = selector;
			_headersToSign = headersToSign ?? new string[]{"From"};

            if (_headersToSign.Length ==0)
            {
                _headersToSign = new string[] {"From"};
            }


            this.Encoding = Encoding.UTF8;

		}
Example #5
0
        public DkimSigner([NotNull] IPrivateKeySigner privateKeySigner, [NotNull] string domain, [NotNull] string selector, string[] headersToSign = null)
        {
            if (privateKeySigner == null)
            {
                throw new ArgumentNullException("privateKeySigner");
            }

            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }

            if (domain.Length == 0)
            {
                throw new ArgumentException("Cannot be empty.", "domain");
            }

            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }

            if (selector.Length == 0)
            {
                throw new ArgumentException("Cannot be empty.", "selector");
            }


            _privateKeySigner = privateKeySigner;
            _domain           = domain;
            _selector         = selector;
            _headersToSign    = headersToSign ?? new string[] { "From" };

            if (_headersToSign.Length == 0)
            {
                _headersToSign = new string[] { "From" };
            }


            this.Encoding = Encoding.UTF8;
        }
        public DomainKeySigner(IPrivateKeySigner privateKeySigner, string domain, string selector, string[] headersToSign)
        {
            if (privateKeySigner == null)
            {
                throw new ArgumentNullException("privateKeySigner");
            }

            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }

            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }

            _domain = domain;
            _selector = selector;
            _headersToSign = headersToSign;
            _privateKeySigner = privateKeySigner.EnsureRsaSha1();
        }
Example #7
0
        public DkimSigner(IPrivateKeySigner privateKeySigner, string domain, string selector, string[] headersToSign = null)
        {
            if (privateKeySigner == null)
            {
                throw new ArgumentNullException("privateKeySigner");
            }

            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }

            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }


            _privateKeySigner = privateKeySigner;
            _domain           = domain;
            _selector         = selector;
            _headersToSign    = headersToSign;
        }
Example #8
0
        private static string GenerateDomainKeySignature(Email email, Encoding encoding, IPrivateKeySigner privateKeySigner, string domain, string selector, string[] headersToSign)
        {
            var signatureValue = new StringBuilder();

            const string start = /*Email.NewLine +*/ " ";
            const string end   = ";";

            // algorithm used
            //signatureValue.Append(" ");
            signatureValue.Append("a=");
            signatureValue.Append("rsa-sha1");// only rsa-sha1 suprted
            signatureValue.Append(end);


            // Canonicalization
            signatureValue.Append(start);
            signatureValue.Append("c=");
            signatureValue.Append(domainKeyCanonicalization.ToString().ToLower());
            signatureValue.Append(end);


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


            // headers to be signed
            if (headersToSign != null && headersToSign.Length > 0)
            {
                signatureValue.Append(start);
                signatureValue.Append("h=");
                foreach (var header in headersToSign)
                {
                    signatureValue.Append(header);
                    signatureValue.Append(':');
                }
                signatureValue.Length--;
                signatureValue.Append(end);
            }


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

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


            // signature data
            signatureValue.Append(start);
            signatureValue.Append("b=");

            signatureValue.Append(DomainKeySignSignature(email, encoding, privateKeySigner, headersToSign));
            signatureValue.Append(end);

            return(signatureValue.ToString());
        }
Example #9
0
        private static string DkimSignBody(string body, Encoding encoding, IPrivateKeySigner privateKeySigner)
        {
            var cb = DkimCanonicalizer.CanonicalizeBody(body, dkimBodyCanonicalization);

            return(Convert.ToBase64String(privateKeySigner.Hash(encoding.GetBytes(cb), dkimSigningAlgorithm)));
        }
Example #10
0
        //see http://www.dkim.org/specs/rfc4871-dkimbase.html#dkim-sig-hdr
        private static string GenerateDkimHeaderValue(Email email, Encoding encoding, IPrivateKeySigner privateKeySigner, string domain, string selector, string[] headersToSign)
        {
            // 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();

            const string start = /*Email.NewLine +*/ " ";
            const string end   = ";";

            signatureValue.Append("v=1;");

            // algorithm used
            signatureValue.Append(start);
            signatureValue.Append("a=");
            signatureValue.Append(GetAlgorithmName());
            signatureValue.Append(end);

            // Canonicalization
            signatureValue.Append(start);
            signatureValue.Append("c=");
            signatureValue.Append(dkimHeaderCanonicalization.ToString().ToLower());
            signatureValue.Append('/');
            signatureValue.Append(dkimBodyCanonicalization.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 headersToSign)
            {
                signatureValue.Append(header);
                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(DkimSignBody(email.Body, encoding, privateKeySigner));
            signatureValue.Append(end);

            // x=copied header fields
            // not supported

            signatureValue.Append(start);
            signatureValue.Append("b=");

            return(signatureValue.ToString());
        }
Example #11
0
        private static string DomainKeySignSignature(Email email, Encoding encoding, IPrivateKeySigner privateKeySigner, string[] headersToSign)
        {
            var text = DomainKeyCanonicalizer.Canonicalize(email, domainKeyCanonicalization, headersToSign);

            return(Convert.ToBase64String(privateKeySigner.Sign(encoding.GetBytes(text), SigningAlgorithm.RSASha1)));
        }
Example #12
0
        //// todo remove once stable.
        //public IDebug Debug { get; set; }

        #endregion Properties


        public DomainKeySigner([NotNull]IPrivateKeySigner privateKeySigner, [NotNull]string domain, [NotNull]string selector, string[] headersToSign = null)
		{
			if (privateKeySigner == null)
			{
				throw new ArgumentNullException("privateKeySigner");
			}

			if (domain == null)
			{
				throw new ArgumentNullException("domain");
			}

            if(domain.Length == 0)
            {
                throw new ArgumentException("Domain cannot be an empty string.");
            }

			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}

            if (selector.Length == 0)
            {
                throw new ArgumentException("Selector cannot be an empty string.");
            }


			_domain = domain;
			_selector = selector;
			_headersToSign = headersToSign;
			_privateKeySigner = privateKeySigner;

            this.Encoding = Encoding.UTF8;
		}
Example #13
0
        public FullEmailSigner(
            [NotNull] IPrivateKeySigner privateKey,
            [NotNull] Encoding encoding,
            [NotNull] string domain,
            [NotNull] string dkimSelector,
            [NotNull] string domainKeySelector,
            [NotNull] string[] headers)
        {
            if (privateKey == null)
            {
                throw new ArgumentNullException("privateKey");
            }
            if (encoding == null)
            {
                throw new ArgumentNullException("encoding");
            }
            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }
            if (dkimSelector == null)
            {
                throw new ArgumentNullException("dkimSelector");
            }
            if (domainKeySelector == null)
            {
                throw new ArgumentNullException("domainKeySelector");
            }
            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }


            var dkim = new DkimSigner(
                privateKey,
                domain,
                dkimSelector,
                headers
                );



            //var debugger = new ConsoleDebug();

            //dkim.Debug = debugger;

            dkim.Encoding             = encoding;
            dkim.BodyCanonicalization = DkimCanonicalizationAlgorithm.Simple;

            _dkimSigner = dkim;


            var domainKeySigner = new DomainKeySigner(
                privateKey,
                domain,
                domainKeySelector,
                headers
                );

            domainKeySigner.Encoding         = encoding;
            domainKeySigner.Canonicalization = DomainKeyCanonicalizationAlgorithm.Nofws;

            _domainKeySigner = domainKeySigner;
        }