5 #include "credentialpassword_p.h" 6 #include "authenticationrealm.h" 8 #include <QLoggingCategory> 9 #include <QMessageAuthenticationCode> 15 Q_LOGGING_CATEGORY(C_CREDENTIALPASSWORD,
"cutelyst.plugin.credentialpassword", QtWarningMsg)
18 , d_ptr(new CredentialPasswordPrivate)
23 CredentialPassword::~CredentialPassword()
34 if (d->checkPassword(_user, authinfo)) {
37 qCDebug(C_CREDENTIALPASSWORD) <<
"Password didn't match";
40 qCDebug(C_CREDENTIALPASSWORD) <<
"Unable to locate a user matching user info provided in realm";
48 return d->passwordField;
54 d->passwordField = fieldName;
60 return d->passwordType;
66 d->passwordType = type;
72 return d->passwordPreSalt;
84 return d->passwordPostSalt;
97 for(
int i = 0; i < a.
size() && i < b.
size(); i++) {
103 #define HASH_SECTIONS 4 104 #define HASH_ALGORITHM_INDEX 0 105 #define HASH_ITERATION_INDEX 1 106 #define HASH_SALT_INDEX 2 107 #define HASH_PBKDF2_INDEX 3 111 if (params.
size() < HASH_SECTIONS) {
115 int method = CredentialPasswordPrivate::cryptoStrToEnum(params.
at(HASH_ALGORITHM_INDEX));
124 static_cast<QCryptographicHash::Algorithm>(method),
126 params.
at(HASH_SALT_INDEX),
127 params.
at(HASH_ITERATION_INDEX).toInt(),
137 QFile random(QStringLiteral(
"/dev/urandom"));
138 if (random.
open(QIODevice::ReadOnly)) {
139 salt = random.
read(saltByteSize).toBase64();
147 const QByteArray methodStr = CredentialPasswordPrivate::cryptoEnumToStr(method);
160 return createPassword(password, QCryptographicHash::Sha512, 10000, 16, 16);
171 if (rounds <= 0 || keyLength <= 0) {
172 qCCritical(C_CREDENTIALPASSWORD,
"PBKDF2 ERROR: Invalid parameters.");
176 if (salt.
size() == 0 || salt.
size() > std::numeric_limits<int>::max() - 4) {
181 int saltSize = salt.
size();
183 asalt.
resize(saltSize + 4);
189 for (
int count = 1, remainingBytes = keyLength; remainingBytes > 0; ++count) {
190 asalt[saltSize + 0] =
static_cast<char>((count >> 24) & 0xff);
191 asalt[saltSize + 1] =
static_cast<char>((count >> 16) & 0xff);
192 asalt[saltSize + 2] =
static_cast<char>((count >> 8) & 0xff);
193 asalt[saltSize + 3] =
static_cast<char>(count & 0xff);
197 obuf = d1 = code.
result();
199 for (
int i = 1; i < rounds; ++i) {
203 auto it = obuf.
begin();
205 while (d1It != d1.
cend()) {
213 remainingBytes -= obuf.
size();
216 key = key.
mid(0, keyLength);
230 if (Q_LIKELY(passwordType == CredentialPassword::Hashed)) {
231 if (!passwordPreSalt.isEmpty()) {
235 if (!passwordPostSalt.isEmpty()) {
236 password.
append(password);
240 }
else if (passwordType == CredentialPassword::Clear) {
241 return storedPassword == password;
242 }
else if (passwordType == CredentialPassword::None) {
243 qCDebug(C_CREDENTIALPASSWORD) <<
"CredentialPassword is set to ignore password check";
250 QByteArray CredentialPasswordPrivate::cryptoEnumToStr(QCryptographicHash::Algorithm method)
254 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 255 if (method == QCryptographicHash::Md4) {
256 hashmethod = QByteArrayLiteral(
"Md4");
257 }
else if (method == QCryptographicHash::Md5) {
258 hashmethod = QByteArrayLiteral(
"Md5");
261 if (method == QCryptographicHash::Sha1) {
262 hashmethod = QByteArrayLiteral(
"Sha1");
264 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 265 if (method == QCryptographicHash::Sha224) {
266 hashmethod = QByteArrayLiteral(
"Sha224");
267 }
else if (method == QCryptographicHash::Sha256) {
268 hashmethod = QByteArrayLiteral(
"Sha256");
269 }
else if (method == QCryptographicHash::Sha384) {
270 hashmethod = QByteArrayLiteral(
"Sha384");
271 }
else if (method == QCryptographicHash::Sha512) {
272 hashmethod = QByteArrayLiteral(
"Sha512");
273 }
else if (method == QCryptographicHash::Sha3_224) {
274 hashmethod = QByteArrayLiteral(
"Sha3_224");
275 }
else if (method == QCryptographicHash::Sha3_256) {
276 hashmethod = QByteArrayLiteral(
"Sha3_256");
277 }
else if (method == QCryptographicHash::Sha3_384) {
278 hashmethod = QByteArrayLiteral(
"Sha3_384");
279 }
else if (method == QCryptographicHash::Sha3_512) {
280 hashmethod = QByteArrayLiteral(
"Sha3_512");
287 int CredentialPasswordPrivate::cryptoStrToEnum(
const QByteArray &hashMethod)
292 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 293 if (hashmethod ==
"Md4") {
294 method = QCryptographicHash::Md4;
295 }
else if (hashmethod ==
"Md5") {
296 method = QCryptographicHash::Md5;
299 if (hashmethod ==
"Sha1") {
300 method = QCryptographicHash::Sha1;
302 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 303 if (hashmethod ==
"Sha224") {
304 method = QCryptographicHash::Sha224;
305 }
else if (hashmethod ==
"Sha256") {
306 method = QCryptographicHash::Sha256;
307 }
else if (hashmethod ==
"Sha384") {
308 method = QCryptographicHash::Sha384;
309 }
else if (hashmethod ==
"Sha512") {
310 method = QCryptographicHash::Sha512;
311 }
else if (hashmethod ==
"Sha3_224") {
312 method = QCryptographicHash::Sha3_224;
313 }
else if (hashmethod ==
"Sha3_256") {
314 method = QCryptographicHash::Sha3_256;
315 }
else if (hashmethod ==
"Sha3_384") {
316 method = QCryptographicHash::Sha3_384;
317 }
else if (hashmethod ==
"Sha3_512") {
318 method = QCryptographicHash::Sha3_512;
325 #include "moc_credentialpassword.cpp" QByteArray::const_iterator cbegin() const const
QString passwordPostSalt() const
Returns the salt string to be appended to the password.
QString & append(QChar ch)
QList< QByteArray > split(char sep) const const
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userinfo)
Tries to find the user with authinfo returning a non null AuthenticationUser on success.
QByteArray::const_iterator cend() const const
void setPasswordPreSalt(const QString &passwordPreSalt)
Sets the salt string to be prepended to the password.
QString & prepend(QChar ch)
bool isNull() const
Returns true if the object is null.
const T & at(int i) const const
QByteArray fromBase64(const QByteArray &base64, QByteArray::Base64Options options)
static QByteArray hmac(QCryptographicHash::Algorithm method, const QByteArray &key, const QByteArray &message)
Generates the Hash-based message authentication code.
void setPasswordType(PasswordType type)
Sets the type of password this class will be dealing with.
static QByteArray createPassword(const QByteArray &password, QCryptographicHash::Algorithm method, int iterations, int saltByteSize, int hashByteSize)
Creates a password hash string.
QByteArray result() const const
QString passwordField() const
Returns the field to look for when authenticating the user.
void addData(const char *data, int length)
QByteArray number(int n, int base)
QByteArray::iterator begin()
QString passwordPreSalt() const
Returns the salt string to be prepended to the password.
qint64 read(char *data, qint64 maxSize)
The Cutelyst namespace holds all public Cutelyst API.
QByteArray mid(int pos, int len) const const
virtual bool open(QIODevice::OpenMode mode) override
QByteArray & append(char ch)
QByteArray hash(const QByteArray &message, const QByteArray &key, QCryptographicHash::Algorithm method)
void setPasswordField(const QString &fieldName)
Sets the field to look for when authenticating the user.
PasswordType passwordType() const
Returns the type of password this class will be dealing with.
static QByteArray pbkdf2(QCryptographicHash::Algorithm method, const QByteArray &password, const QByteArray &salt, int rounds, int keyLength)
Generates a pbkdf2 string for the given password.
void setPasswordPostSalt(const QString &passwordPostSalt)
Sets the salt string to be appended to the password.
AuthenticationUser authenticate(Context *c, AuthenticationRealm *realm, const ParamsMultiMap &authinfo) final
Tries to authenticate the authinfo using the give realm.
QString toString() const const
QByteArray toRfc4122() const const
QByteArray toBase64(QByteArray::Base64Options options) const const
static bool validatePassword(const QByteArray &password, const QByteArray &correctHash)
Validates the given password against the correct hash.
const T value(const Key &key, const T &defaultValue) const const
QByteArray toUtf8() const const