1 /*
2  * Copyright (C) 2010  Tobias Markmann
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  */
19 
20 #include "xmpp/sasl/scramsha1message.h"
21 
22 #include <QString>
23 #include <QTextStream>
24 #include <QtCrypto>
25 #include <QDebug>
26 
27 #include "xmpp/base/randomnumbergenerator.h"
28 #include "xmpp/jid/jid.h"
29 
30 namespace XMPP {
31 
Normalize(const QString & username_in,QString & username_out)32 bool Normalize(const QString &username_in, QString &username_out ) {
33 	// SASLprep
34 	if (StringPrepCache::saslprep(username_in, 1024, username_out)) {
35 		// '=' -> '=3D'	 and ',' -> '=2C'
36 		username_out.replace("=", "=3D");
37 		username_out.replace(",", "=2C");
38 		return true;
39 	} else {
40 		return false;
41 	}
42 }
43 
SCRAMSHA1Message(const QString & authzid,const QString & authcid,const QByteArray & cnonce,const RandomNumberGenerator & rand)44 SCRAMSHA1Message::SCRAMSHA1Message(const QString& authzid, const QString& authcid, const QByteArray& cnonce, const RandomNumberGenerator& rand) : isValid_(true)
45 {
46 	QString result;
47 	QByteArray clientnonce;
48 	QString username;
49 
50 	if (!Normalize(authcid, username)) {
51 		isValid_ = false;
52 		return;
53 	}
54 
55 	if (cnonce.size() == 0) {
56 		// make a cnonce
57 		QByteArray a;
58 		a.resize(32);
59 		for(int n = 0; n < (int)a.size(); ++n) {
60 			a[n] = (char) rand.generateNumberBetween(0, 255);
61 		}
62 		clientnonce = a.toBase64();
63 	} else clientnonce = cnonce;
64 
65 	QTextStream(&result) << "n,";
66 	if (authzid.size() > 0) {
67 		QTextStream(&result) << authzid.toUtf8();
68 	}
69 	QTextStream(&result) << ",n=" << username << ",r=" << clientnonce;
70 	value_ = result.toUtf8();
71 }
72 
73 }
74