[jdev] SASL debugging

Norman Rasmussen norman at rasmussen.co.za
Fri Dec 9 08:23:08 CST 2005


this is breaking stuff:

foreach (byte b in n)
    hex += b.ToString("x2");

try:

foreach (byte b in n)
    hex += b.ToString("x02");

On 12/9/05, Yves Goergen <nospam.list at unclassified.de> wrote:
> 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" <nospam.list at unclassified.de>
> "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));
>                 }
>         }
> }
>
>
>


--
- Norman Rasmussen
 - Email: norman at rasmussen.co.za
 - Home page: http://norman.rasmussen.co.za/



More information about the JDev mailing list