On 09.12.2005 10:40 (+0100), Vinod Panicker wrote: > What are you using as your SASL implementation?
SASL, mechanism DIGEST-MD5, code: my own. I was pointed to the example at the end of the SASL RFC, so I tried to get to the same results, and I didn't. I have attached my code with some comments on how to use it and what results I had. -- Yves Goergen "LonelyPixel" <[EMAIL PROTECTED]> "Does the movement of the trees make the wind blow?" http://newsboard.unclassified.de - Unclassified NewsBoard Forum
using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; // SASL specification: ftp://ietf.org//rfc/rfc2831.txt // // Demo usage of this class: // // XMPP.Sasl sasl = new XMPP.Sasl(); // sasl.Hostname = "elwood.innosoft.com"; // sasl.Mechanism = "DIGEST-MD5"; // sasl.Password = "secret"; // sasl.Username = "chris"; // string challenge = @"realm=""elwood.innosoft.com"",nonce=""OA6MG9tEQGm2hh"",qop=""auth""" + // ",algorithm=md5-sess,charset=utf-8"; // string response = sasl.GetResponse(challenge); namespace XMPP { public class Sasl { public string Hostname = ""; public string Username = ""; public string Password = ""; public string Mechanism = ""; public string GetResponse(string challenge) { Regex r; Match m; string realm = ""; string nonce = ""; string qop = "auth"; string algorithm = ""; r = new Regex(@"realm=""(.*?)(?<!\\)"""); m = r.Match(challenge); if (m.Success) realm = m.Groups[1].Value; r = new Regex(@"nonce=""(.*?)(?<!\\)"""); m = r.Match(challenge); if (!m.Success) throw new System.Security.Authentication.AuthenticationException("Invalid SASL protocol"); nonce = m.Groups[1].Value; r = new Regex(@"qop=""(.*?)(?<!\\)"""); m = r.Match(challenge); if (m.Success) qop = m.Groups[1].Value; if (qop != "auth") throw new System.Security.Authentication.AuthenticationException("Unsupported SASL protocol use"); r = new Regex(@"algorithm=(.*?)(?=,|$)"); m = r.Match(challenge); if (!m.Success) throw new System.Security.Authentication.AuthenticationException("Invalid SASL protocol"); algorithm = m.Groups[1].Value; RandomNumberGenerator rng = RandomNumberGenerator.Create(); byte[] bytes = new byte[32]; rng.GetBytes(bytes); string cnonce = HEX(bytes); cnonce = "OA6MHXh6VqTrRk"; // for testing string nonce_count = "00000001"; string A1 = BytesToString(H(ToUTF8(Username) + ":" + realm + ":" + ToUTF8(Password))) + ":" + nonce + ":" + cnonce; string A2 = "AUTHENTICATE:xmpp/" + Hostname; //A1 = "a2549853149b0536f01f0b850c643c57"; // for testing -> this produces still no correct response A2 = "AUTHENTICATE:imap/" + Hostname; // for testing string response = HEX(KD( HEX(H(A1)), nonce + ":" + nonce_count + ":" + cnonce + ":" + qop + ":" + HEX(H(A2)))); // for testing: string HA1 = HEX(H(A1)); string HA2 = HEX(H(A2)); // my HA1: b797a8d5eeae5f17625ca975f6a8dc2f // my response: db4446e7eedfff854d71882b0266eb80 // correct HA1: a2549853149b0536f01f0b850c643c57 // correct response: d388dad90d4bbd760a152321f2143af7 if (realm != "") realm = @"realm=""" + realm + @""","; string ret = realm + "username=\"" + ToUTF8(Username) + "\",nonce=\"" + nonce + "\",cnonce=\"" + cnonce + "\",nc=00000001,qop=" + qop + ",digest-uri=\"xmpp/" + Hostname + "\",response=" + response + ",charset=utf-8"; return ret; } private byte[] H(string s) { MD5 md5 = new MD5CryptoServiceProvider(); byte[] bytes = Encoding.UTF8.GetBytes(s); bytes = md5.ComputeHash(bytes); return bytes; // TODO: optimise after debugging } private string BytesToString(byte[] bytes) { return Encoding.GetEncoding(28591).GetString(bytes); } private byte[] KD(string k, string s) { return H(k + ":" + s); } private string HEX(byte[] n) { string hex = ""; foreach (byte b in n) hex += b.ToString("x2"); return hex; } private string ToUTF8(string data) { // Codepage 28591 is ISO-8859-1 return Encoding.GetEncoding(28591).GetString(Encoding.UTF8.GetBytes(data)); } } }
