Exemple #1
0
        /// <summary>
        /// Computes the MD5 checksum of the content.
        /// </summary>
        /// <remarks>
        /// Computes the MD5 checksum of the MIME content in its canonical
        /// format and then base64-encodes the result.
        /// </remarks>
        /// <returns>The md5sum of the content.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// The <see cref="ContentObject"/> is <c>null</c>.
        /// </exception>
        public string ComputeContentMd5()
        {
            if (ContentObject == null)
            {
                throw new InvalidOperationException("Cannot compute Md5 checksum without a ContentObject.");
            }

            using (var stream = ContentObject.Open()) {
                byte[] checksum;

                using (var filtered = new FilteredStream(stream)) {
                    if (ContentType.IsMimeType("text", "*"))
                    {
                        filtered.Add(new Unix2DosFilter());
                    }

                    using (var md5 = MD5.Create())
                        checksum = md5.ComputeHash(filtered);
                }

                var base64 = new Base64Encoder(true);
                var digest = new byte[base64.EstimateOutputLength(checksum.Length)];
                int n      = base64.Flush(checksum, 0, checksum.Length, digest);

                return(Encoding.ASCII.GetString(digest, 0, n));
            }
        }
Exemple #2
0
        static void ComputeNtlmV2Session(string password, byte[] challenge, out byte[] lm, out byte[] ntlm)
        {
            var nonce = new byte[8];

            using (var rng = RandomNumberGenerator.Create())
                rng.GetBytes(nonce);

            var sessionNonce = new byte[challenge.Length + 8];

            challenge.CopyTo(sessionNonce, 0);
            nonce.CopyTo(sessionNonce, challenge.Length);

            lm = new byte[24];
            nonce.CopyTo(lm, 0);

            using (var md5 = MD5.Create()) {
                var hash         = md5.ComputeHash(sessionNonce);
                var newChallenge = new byte[8];

                Array.Copy(hash, newChallenge, 8);

                ntlm = ComputeNtlm(password, newChallenge);

                // clean up
                Array.Clear(newChallenge, 0, newChallenge.Length);
                Array.Clear(hash, 0, hash.Length);
            }

            // clean up
            Array.Clear(sessionNonce, 0, sessionNonce.Length);
            Array.Clear(nonce, 0, nonce.Length);
        }
Exemple #3
0
        static SaslMechanism()
        {
            try {
                using (var md5 = MD5.Create())
                    md5supported = true;
            } catch {
                md5supported = false;
            }

            // Note: It's probably arguable that NTLM is more secure than SCRAM but the odds of a server supporting both is probably low.
            var supported = new List <string> {
                "SCRAM-SHA-512",
                "SCRAM-SHA-256",
                "SCRAM-SHA-1",
                "NTLM"
            };

            if (md5supported)
            {
                supported.Add("DIGEST-MD5");
                supported.Add("CRAM-MD5");
            }
            supported.Add("PLAIN");
            supported.Add("LOGIN");

            RankedAuthenticationMechanisms = supported.ToArray();
        }
Exemple #4
0
 static SaslMechanism()
 {
     try {
         using (var md5 = MD5.Create())
             md5supported = true;
     } catch {
         md5supported = false;
     }
 }
        public string ComputeHash(string password, bool client)
        {
            string text, a1, a2;

            byte[] buf, digest;

            // compute A1
            text = string.Format("{0}:{1}:{2}", UserName, Realm, password);
            buf  = Encoding.UTF8.GetBytes(text);
            using (var md5 = MD5.Create())
                digest = md5.ComputeHash(buf);

            using (var md5 = MD5.Create()) {
                md5.TransformBlock(digest, 0, digest.Length, null, 0);
                text = string.Format(":{0}:{1}", Nonce, CNonce);
                if (!string.IsNullOrEmpty(AuthZid))
                {
                    text += ":" + AuthZid;
                }
                buf = Encoding.ASCII.GetBytes(text);
                md5.TransformFinalBlock(buf, 0, buf.Length);
                a1 = HexEncode(md5.Hash);
            }

            // compute A2
            text  = client ? "AUTHENTICATE:" : ":";
            text += DigestUri;

            if (Qop == "auth-int" || Qop == "auth-conf")
            {
                text += ":00000000000000000000000000000000";
            }

            buf = Encoding.ASCII.GetBytes(text);
            using (var md5 = MD5.Create())
                digest = md5.ComputeHash(buf);
            a2 = HexEncode(digest);

            // compute KD
            text = string.Format("{0}:{1}:{2:x8}:{3}:{4}:{5}", a1, Nonce, Nc, CNonce, Qop, a2);
            buf  = Encoding.ASCII.GetBytes(text);
            using (var md5 = MD5.Create())
                digest = md5.ComputeHash(buf);

            return(HexEncode(digest));
        }
        /// <summary>
        /// Parses the server's challenge token and returns the next challenge response.
        /// </summary>
        /// <remarks>
        /// Parses the server's challenge token and returns the next challenge response.
        /// </remarks>
        /// <returns>The next challenge response.</returns>
        /// <param name="token">The server's challenge token.</param>
        /// <param name="startIndex">The index into the token specifying where the server's challenge begins.</param>
        /// <param name="length">The length of the server's challenge.</param>
        /// <exception cref="System.InvalidOperationException">
        /// The SASL mechanism is already authenticated.
        /// </exception>
        /// <exception cref="System.NotSupportedException">
        /// The SASL mechanism does not support SASL-IR.
        /// </exception>
        /// <exception cref="SaslException">
        /// An error has occurred while parsing the server's challenge token.
        /// </exception>
        protected override byte[] Challenge(byte[] token, int startIndex, int length)
        {
            if (IsAuthenticated)
            {
                throw new InvalidOperationException();
            }

            if (token == null)
            {
                throw new NotSupportedException("CRAM-MD5 does not support SASL-IR.");
            }

            var userName = Encoding.UTF8.GetBytes(Credentials.UserName);
            var password = Encoding.UTF8.GetBytes(Credentials.Password);
            var ipad     = new byte[64];
            var opad     = new byte[64];

            byte[] digest;

            if (password.Length > 64)
            {
                byte[] checksum;

                using (var md5 = MD5.Create())
                    checksum = md5.ComputeHash(password);

                Array.Copy(checksum, ipad, checksum.Length);
                Array.Copy(checksum, opad, checksum.Length);
            }
            else
            {
                Array.Copy(password, ipad, password.Length);
                Array.Copy(password, opad, password.Length);
            }

            Array.Clear(password, 0, password.Length);

            for (int i = 0; i < 64; i++)
            {
                ipad[i] ^= 0x36;
                opad[i] ^= 0x5c;
            }

            using (var md5 = MD5.Create()) {
                md5.TransformBlock(ipad, 0, ipad.Length, null, 0);
                md5.TransformFinalBlock(token, startIndex, length);
                digest = md5.Hash;
            }

            using (var md5 = MD5.Create()) {
                md5.TransformBlock(opad, 0, opad.Length, null, 0);
                md5.TransformFinalBlock(digest, 0, digest.Length);
                digest = md5.Hash;
            }

            var buffer = new byte[userName.Length + 1 + (digest.Length * 2)];
            int offset = 0;

            for (int i = 0; i < userName.Length; i++)
            {
                buffer[offset++] = userName[i];
            }
            buffer[offset++] = 0x20;
            for (int i = 0; i < digest.Length; i++)
            {
                byte c = digest[i];

                buffer[offset++] = HexAlphabet[(c >> 4) & 0x0f];
                buffer[offset++] = HexAlphabet[c & 0x0f];
            }

            IsAuthenticated = true;

            return(buffer);
        }