diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-07-20 16:55:16 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-07-20 16:55:16 +0200 |
| commit | eea1abd543afecab18ff1ef7f83459902f989c87 (patch) | |
| tree | 9cf83efe197ce2edee69edfc22d50ca72ebf24ac /src/base | |
| parent | 4f78eb1f8207e4d151146a6fb11e28d38cd40d7a (diff) | |
| download | qxmpp-eea1abd543afecab18ff1ef7f83459902f989c87.tar.gz | |
hide some SASL internals
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/QXmppSaslAuth.cpp | 105 | ||||
| -rw-r--r-- | src/base/QXmppSaslAuth.h | 20 | ||||
| -rw-r--r-- | src/base/QXmppSaslAuth_p.h | 10 |
3 files changed, 40 insertions, 95 deletions
diff --git a/src/base/QXmppSaslAuth.cpp b/src/base/QXmppSaslAuth.cpp index 533792c8..6c9c85fc 100644 --- a/src/base/QXmppSaslAuth.cpp +++ b/src/base/QXmppSaslAuth.cpp @@ -35,6 +35,19 @@ const char *ns_xmpp_sasl = "urn:ietf:params:xml:ns:xmpp-sasl"; +// Calculate digest response for use with XMPP/SASL. + +static QByteArray calculateDigest(const QByteArray &method, const QByteArray &digestUri, const QByteArray &secret, const QByteArray &nonce, const QByteArray &cnonce, const QByteArray &nc) +{ + const QByteArray A1 = secret + ':' + nonce + ':' + cnonce; + const QByteArray A2 = method + ':' + digestUri; + + QByteArray HA1 = QCryptographicHash::hash(A1, QCryptographicHash::Md5).toHex(); + QByteArray HA2 = QCryptographicHash::hash(A2, QCryptographicHash::Md5).toHex(); + const QByteArray KD = HA1 + ':' + nonce + ':' + nc + ':' + cnonce + ":auth:" + HA2; + return QCryptographicHash::hash(KD, QCryptographicHash::Md5).toHex(); +} + static QByteArray generateNonce() { QByteArray nonce = QXmppUtils::generateRandomBytes(32); @@ -281,8 +294,10 @@ bool QXmppSaslClientAnonymous::respond(const QByteArray &challenge, QByteArray & QXmppSaslClientDigestMd5::QXmppSaslClientDigestMd5(QObject *parent) : QXmppSaslClient(parent) + , m_nc("00000001") , m_step(0) { + m_cnonce = generateNonce(); } QString QXmppSaslClientDigestMd5::mechanism() const @@ -317,24 +332,22 @@ bool QXmppSaslClientDigestMd5::respond(const QByteArray &challenge, QByteArray & return false; } - m_saslDigest.setCnonce(generateNonce()); - m_saslDigest.setNc("00000001"); - m_saslDigest.setNonce(input.value("nonce")); - m_saslDigest.setSecret(QCryptographicHash::hash( + m_nonce = input.value("nonce"); + m_secret = QCryptographicHash::hash( username().toUtf8() + ":" + realm + ":" + password().toUtf8(), - QCryptographicHash::Md5)); + QCryptographicHash::Md5); // Build response QMap<QByteArray, QByteArray> output; output["username"] = username().toUtf8(); if (!realm.isEmpty()) output["realm"] = realm; - output["nonce"] = m_saslDigest.nonce(); + output["nonce"] = m_nonce; output["qop"] = "auth"; - output["cnonce"] = m_saslDigest.cnonce(); - output["nc"] = m_saslDigest.nc(); + output["cnonce"] = m_cnonce; + output["nc"] = m_nc; output["digest-uri"] = digestUri; - output["response"] = m_saslDigest.calculateDigest("AUTHENTICATE", digestUri); + output["response"] = calculateDigest("AUTHENTICATE", digestUri, m_secret, m_nonce, m_cnonce, m_nc); output["charset"] = "utf-8"; response = QXmppSaslDigestMd5::serializeMessage(output); @@ -344,7 +357,7 @@ bool QXmppSaslClientDigestMd5::respond(const QByteArray &challenge, QByteArray & const QMap<QByteArray, QByteArray> input = QXmppSaslDigestMd5::parseMessage(challenge); // check new challenge - if (input.value("rspauth") != m_saslDigest.calculateDigest(QByteArray(), digestUri)) { + if (input.value("rspauth") != calculateDigest(QByteArray(), digestUri, m_secret, m_nonce, m_cnonce, m_nc)) { warning("QXmppSaslClientDigestMd5 : Invalid challenge on step 2"); return false; } @@ -546,6 +559,7 @@ QXmppSaslServerDigestMd5::QXmppSaslServerDigestMd5(QObject *parent) : QXmppSaslServer(parent) , m_step(0) { + m_nonce = generateNonce(); } QString QXmppSaslServerDigestMd5::mechanism() const @@ -556,12 +570,8 @@ QString QXmppSaslServerDigestMd5::mechanism() const QXmppSaslServer::Response QXmppSaslServerDigestMd5::respond(const QByteArray &request, QByteArray &response) { if (m_step == 0) { - // generate nonce - m_saslDigest.setNonce(generateNonce()); - //m_saslDigest.setQop("auth"); - QMap<QByteArray, QByteArray> output; - output["nonce"] = m_saslDigest.nonce(); + output["nonce"] = m_nonce; if (!realm().isEmpty()) output["realm"] = realm().toUtf8(); output["qop"] = "auth"; @@ -585,21 +595,21 @@ QXmppSaslServer::Response QXmppSaslServerDigestMd5::respond(const QByteArray &re if (password().isEmpty() && passwordDigest().isEmpty()) return InputNeeded; - m_saslDigest.setNc(input.value("nc")); - m_saslDigest.setCnonce(input.value("cnonce")); + m_nc = input.value("nc"); + m_cnonce = input.value("cnonce"); if (!password().isEmpty()) { - m_saslDigest.setSecret(QCryptographicHash::hash( + m_secret = QCryptographicHash::hash( username().toUtf8() + ":" + realm + ":" + password().toUtf8(), - QCryptographicHash::Md5)); + QCryptographicHash::Md5); } else { - m_saslDigest.setSecret(passwordDigest()); + m_secret = passwordDigest(); } - if (input.value("response") != m_saslDigest.calculateDigest("AUTHENTICATE", digestUri)) + if (input.value("response") != calculateDigest("AUTHENTICATE", digestUri, m_secret, m_nonce, m_cnonce, m_nc)) return Failed; QMap<QByteArray, QByteArray> output; - output["rspauth"] = m_saslDigest.calculateDigest(QByteArray(), digestUri); + output["rspauth"] = calculateDigest(QByteArray(), digestUri, m_secret, m_nonce, m_cnonce, m_nc); m_step++; response = QXmppSaslDigestMd5::serializeMessage(output); @@ -645,57 +655,6 @@ QXmppSaslServer::Response QXmppSaslServerPlain::respond(const QByteArray &reques } } -QByteArray QXmppSaslDigestMd5::cnonce() const -{ - return m_cnonce; -} - -void QXmppSaslDigestMd5::setCnonce(const QByteArray &cnonce) -{ - m_cnonce = cnonce; -} - -QByteArray QXmppSaslDigestMd5::nc() const -{ - return m_nc; -} - -void QXmppSaslDigestMd5::setNc(const QByteArray &nc) -{ - m_nc = nc; -} - -QByteArray QXmppSaslDigestMd5::nonce() const -{ - return m_nonce; -} - -void QXmppSaslDigestMd5::setNonce(const QByteArray &nonce) -{ - m_nonce = nonce; -} - -void QXmppSaslDigestMd5::setSecret(const QByteArray &secret) -{ - m_secret = secret; -} - -/// Calculate digest response for use with XMPP/SASL. -/// -/// \param A2 -/// - -QByteArray QXmppSaslDigestMd5::calculateDigest(const QByteArray &method, const QByteArray &digestUri) const -{ - const QByteArray A1 = m_secret + ':' + m_nonce + ':' + m_cnonce; - const QByteArray A2 = method + ':' + digestUri; - - QByteArray HA1 = QCryptographicHash::hash(A1, QCryptographicHash::Md5).toHex(); - QByteArray HA2 = QCryptographicHash::hash(A2, QCryptographicHash::Md5).toHex(); - const QByteArray KD = HA1 + ':' + m_nonce + ':' + m_nc + ':' + m_cnonce + ":auth:" + HA2; - return QCryptographicHash::hash(KD, QCryptographicHash::Md5).toHex(); -} - QMap<QByteArray, QByteArray> QXmppSaslDigestMd5::parseMessage(const QByteArray &ba) { QMap<QByteArray, QByteArray> map; diff --git a/src/base/QXmppSaslAuth.h b/src/base/QXmppSaslAuth.h index 4173d74c..713095f8 100644 --- a/src/base/QXmppSaslAuth.h +++ b/src/base/QXmppSaslAuth.h @@ -37,29 +37,9 @@ class QXmppSaslServerPrivate; class QXMPP_EXPORT QXmppSaslDigestMd5 { public: - QByteArray cnonce() const; - void setCnonce(const QByteArray &cnonce); - - QByteArray nc() const; - void setNc(const QByteArray &nc); - - QByteArray nonce() const; - void setNonce(const QByteArray &nonce); - - void setSecret(const QByteArray &secret); - - QByteArray calculateDigest(const QByteArray &method, const QByteArray &digestUri) const; - // message parsing and serialization static QMap<QByteArray, QByteArray> parseMessage(const QByteArray &ba); static QByteArray serializeMessage(const QMap<QByteArray, QByteArray> &map); - -private: - QByteArray m_cnonce; - QByteArray m_nc; - QByteArray m_nonce; - QByteArray m_qop; - QByteArray m_secret; }; /// The QXmppSaslClient class is the base class for all SASL client diff --git a/src/base/QXmppSaslAuth_p.h b/src/base/QXmppSaslAuth_p.h index 67480ddb..178b7c09 100644 --- a/src/base/QXmppSaslAuth_p.h +++ b/src/base/QXmppSaslAuth_p.h @@ -130,7 +130,10 @@ public: bool respond(const QByteArray &challenge, QByteArray &response); private: - QXmppSaslDigestMd5 m_saslDigest; + QByteArray m_cnonce; + QByteArray m_nc; + QByteArray m_nonce; + QByteArray m_secret; int m_step; }; @@ -177,7 +180,10 @@ public: Response respond(const QByteArray &challenge, QByteArray &response); private: - QXmppSaslDigestMd5 m_saslDigest; + QByteArray m_cnonce; + QByteArray m_nc; + QByteArray m_nonce; + QByteArray m_secret; int m_step; }; |
