KHealthCertificate

jwtparser.cpp
1/*
2 * SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 */
5
6#include "jwtparser_p.h"
7#include "jwkloader_p.h"
8#include "logging.h"
9#include "openssl/verify_p.h"
10#include "zlib/zlib_p.h"
11
12#include <QJsonDocument>
13#include <QJsonObject>
14
15JwtParser::JwtParser() = default;
16JwtParser::~JwtParser() = default;
17
18void JwtParser::parse(const QByteArray &data)
19{
20 const auto idx1 = data.indexOf('.');
21 if (idx1 < 0) {
22 return;
23 }
25
26 const auto idx2 = data.indexOf('.', idx1 + 1);
27 auto rawPayload = QByteArray::fromBase64(data.mid(idx1 + 1, idx2 - idx1 - 1), QByteArray::Base64UrlEncoding);
28 if (header.value(QLatin1String("zip")).toString() == QLatin1String("DEF")) {
29 rawPayload = Zlib::decompressDeflate(rawPayload);
30 }
31 m_payload = QJsonDocument::fromJson(rawPayload).object();
32
33 // signature verification
34 const auto signature = QByteArray::fromBase64(data.mid(idx2 + 1), QByteArray::Base64UrlEncoding);
35 const auto kid = header.value(QLatin1String("kid")).toString();
36 const auto evp = JwkLoader::loadPublicKey(QLatin1String(":/org.kde.khealthcertificate/shc/certs/") + kid + QLatin1String(".jwk"));
37 if (!evp) {
38 qCWarning(Log) << "no key found for kid:" << kid;
39 m_signatureState = KHealthCertificate::UnknownSignature;
40 return;
41 }
42 const auto alg = header.value(QLatin1String("alg")).toString();
43 bool valid = false;
44 if (alg == QLatin1String("ES256")) {
45 valid = Verify::verifyECDSA(evp, EVP_sha256(), data.constData(), idx2, signature.constData(), signature.size());
46 } else if (alg == QLatin1String("ES384")) {
47 valid = Verify::verifyECDSA(evp, EVP_sha384(), data.constData(), idx2, signature.constData(), signature.size());
48 } else if (alg == QLatin1String("ES512")) {
49 valid = Verify::verifyECDSA(evp, EVP_sha512(), data.constData(), idx2, signature.constData(), signature.size());
50 } else {
51 qCWarning(Log) << "signature algorithm not supported:" << alg;
52 }
53
55}
56
57QJsonObject JwtParser::payload() const
58{
59 return m_payload;
60}
61
62KHealthCertificate::SignatureValidation JwtParser::signatureState() const
63{
64 return m_signatureState;
65}
SignatureValidation
Result of attempting to verify the cryptographic signature of a certificate.
@ ValidSignature
signature is valid
@ InvalidSignature
signature is invalid
@ UnknownSignature
signature verification was attempted but didn't yield a result, e.g. due to a missing certificate of ...
char * toString(const EngineQuery &query)
const char * constData() const const
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
QByteArray left(qsizetype len) const const
QByteArray mid(qsizetype pos, qsizetype len) const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonObject object() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 10 2024 11:48:34 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.