1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "oauthtestutils.h"
#ifndef QT_NO_SSL
#include <QtNetwork/qsslkey.h>
#include <QtCore/qfile.h>
#endif
#include <QtCore/qdatetime.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qmessageauthenticationcode.h>
QString createSignedJWT(const QVariantMap &header, const QVariantMap &payload)
{
auto base64Encode = [](const QByteArray &input) {
return input.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
};
// Repeating values which can be overridden and augmented by the supplied 'header' and 'payload'
QVariantMap mergedHeader = {{"alg", "HS256"},
{"typ", "JWT"}};
QVariantMap mergedPayload = {{"iss", "https://tst_oauth2.example.com"},
{"sub", "tst_oauth2"},
{"aud", "tst_oauth2_client_id"},
{"exp", QDateTime::currentSecsSinceEpoch() + 300}, // valid 5 mins
{"iat", QDateTime::currentSecsSinceEpoch()}, // issued now
{"name", "No Body"},
{"email", "no.body@example.com"}};
mergedHeader.insert(header);
mergedPayload.insert(payload);
// Signed JWT within OIDC context is: header.payload.signature (separated with dots)
auto header64 =
base64Encode(QJsonDocument::fromVariant(mergedHeader).toJson(QJsonDocument::Compact));
auto payload64 =
base64Encode(QJsonDocument::fromVariant(mergedPayload).toJson(QJsonDocument::Compact));
auto token = header64 + "." + payload64;
auto signature64 =
base64Encode(QMessageAuthenticationCode::hash(token, "secret", QCryptographicHash::Sha256));
token = token + "." + signature64;
return token;
}
#ifndef QT_NO_SSL
QSslConfiguration createSslConfiguration(const QString &keyFileName,
const QString &certificateFileName)
{
QSslConfiguration configuration(QSslConfiguration::defaultConfiguration());
QFile keyFile(keyFileName);
if (keyFile.open(QIODevice::ReadOnly)) {
QSslKey key(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
if (!key.isNull()) {
configuration.setPrivateKey(key);
} else {
qCritical() << "Could not parse key: " << keyFileName;
}
} else {
qCritical() << "Could not find key: " << keyFileName;
}
QList<QSslCertificate> localCert = QSslCertificate::fromPath(certificateFileName);
if (!localCert.isEmpty() && !localCert.first().isNull()) {
configuration.setLocalCertificate(localCert.first());
} else {
qCritical() << "Could not find certificate: " << certificateFileName;
}
configuration.setPeerVerifyMode(QSslSocket::VerifyPeer);
return configuration;
}
#endif // QT_NO_SSL
|