Added Bits Of Binary (XEP-0231) support
[iris.git] / src / xmpp / sasl / digestmd5response.cpp
blobceeb4817118ebbfb86cc6d4e41341441f5c52bfe
1 /*
2 * Copyright (C) 2008 Remko Troncon
3 * See COPYING for license details.
4 */
6 #include "xmpp/sasl/digestmd5response.h"
8 #include <QByteArray>
9 #include <QtCrypto>
10 #include <QtDebug>
12 #include "xmpp/sasl/digestmd5proplist.h"
13 #include "xmpp/base/randomnumbergenerator.h"
14 #include "xmpp/base64/base64.h"
16 namespace XMPP {
18 DIGESTMD5Response::DIGESTMD5Response(const QByteArray& challenge, const QString& service, const QString& host, const QString& arealm, const QString& user, const QString& authz, const QByteArray& password, const RandomNumberGenerator& rand) : isValid_(true)
20 QString realm = arealm;
22 // get props
23 DIGESTMD5PropList in;
24 if(!in.fromString(challenge)) {
25 isValid_ = false;
26 return;
28 //qDebug() << (QString("simplesasl.cpp: IN: %1").arg(QString(in.toString())));
30 // make a cnonce
31 QByteArray a;
32 a.resize(32);
33 for(int n = 0; n < (int)a.size(); ++n) {
34 a[n] = (char) rand.generateNumberBetween(0, 255);
36 QByteArray cnonce = Base64::encode(a).toLatin1();
38 // make other variables
39 if (realm.isEmpty()) {
40 realm = QString::fromUtf8(in.get("realm"));
42 QByteArray nonce = in.get("nonce");
43 QByteArray nc = "00000001";
44 QByteArray uri = service.toUtf8() + '/' + host.toUtf8();
45 QByteArray qop = "auth";
47 // build 'response'
48 QByteArray X = user.toUtf8() + ':' + realm.toUtf8() + ':' + password;
49 QByteArray Y = QCA::Hash("md5").hash(X).toByteArray();
50 QByteArray tmp = ':' + nonce + ':' + cnonce;
51 if (!authz.isEmpty())
52 tmp += ':' + authz.toUtf8();
53 //qDebug() << (QString(tmp));
55 QByteArray A1(Y + tmp);
56 QByteArray A2 = QByteArray("AUTHENTICATE:") + uri;
57 QByteArray HA1 = QCA::Hash("md5").hashToString(A1).toLatin1();
58 QByteArray HA2 = QCA::Hash("md5").hashToString(A2).toLatin1();
59 QByteArray KD = HA1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + HA2;
60 QByteArray Z = QCA::Hash("md5").hashToString(KD).toLatin1();
62 //qDebug() << QString("simplesasl.cpp: A1 = %1").arg(QString(A1));
63 //qDebug() << QString("simplesasl.cpp: A2 = %1").arg(QString(A2));
64 //qDebug() << QString("simplesasl.cpp: KD = %1").arg(QString(KD));
66 // build output
67 DIGESTMD5PropList out;
68 out.set("username", user.toUtf8());
69 if (!realm.isEmpty())
70 out.set("realm", realm.toUtf8());
71 out.set("nonce", nonce);
72 out.set("cnonce", cnonce);
73 out.set("nc", nc);
74 //out.set("serv-type", service.toUtf8());
75 //out.set("host", host.toUtf8());
76 out.set("digest-uri", uri);
77 out.set("qop", qop);
78 out.set("response", Z);
79 out.set("charset", "utf-8");
80 if (!authz.isEmpty())
81 out.set("authzid", authz.toUtf8());
82 value_ = out.toString();