6#include "eudgcparser_p.h"
7#include "cborutils_p.h"
8#include "coseparser_p.h"
10#include "zlib/zlib_p.h"
14#include <QCborStreamReader>
17#include <QJsonDocument>
25 visitor(T _f) : func(_f) {}
26 void operator()(std::monostate) {};
27 template <
typename Arg>
28 void operator()(Arg &a) { func(a); }
33EuDgcParser::EuDgcParser() =
default;
34EuDgcParser::~EuDgcParser() =
default;
36void EuDgcParser::init()
38 Q_INIT_RESOURCE(eu_dgc_data);
39 Q_INIT_RESOURCE(eu_dgc_certs);
46 qCWarning(
Log) <<
"no translation table found for" <<
type;
53 if (it != obj.constEnd()) {
54 return it.value().toString();
56 it = obj.constFind(key);
57 if (it != obj.constEnd()) {
58 return it.value().toString();
70 if (decoded.isEmpty()) {
76 if (cose.payload().isEmpty()) {
81 if (!reader.isMap()) {
84 reader.enterContainer();
87 while (reader.hasNext()) {
88 const auto key = CborUtils::readInteger(reader);
91 parseCertificate(reader);
94 qCDebug(
Log) <<
"key issuer:" << CborUtils::readString(reader);
103 qCDebug(
Log) <<
"unhandled header key:" << key;
107 reader.leaveContainer();
108 std::visit(visitor([&issueDt](
auto &cert) { cert.setCertificateIssueDate(issueDt); }), m_cert);
109 std::visit(visitor([&expiryDt](
auto &cert) { cert.setCertificateExpiryDate(expiryDt); }), m_cert);
112 auto sigState = cose.signatureState();
113 if (sigState == CoseParser::ValidSignature && cose.certificate().expiryDate() < issueDt ) {
114 sigState = CoseParser::InvalidSignature;
119 case CoseParser::InvalidSignature:
122 case CoseParser::ValidSignature:
129 std::visit(visitor([&data](
auto &cert) { cert.setRawData(data); }), m_cert);
135 if (!reader.
isMap()) {
139 const auto version = CborUtils::readInteger(reader);
141 qCWarning(
Log) <<
"unknown EU DGC version:" <<
version;
145 parseCertificateV1(reader);
150 if (!reader.
isMap()) {
159 const auto key = CborUtils::readString(reader);
161 parseCertificateArray(reader, &EuDgcParser::parseVaccinationCertificate);
163 parseCertificateArray(reader, &EuDgcParser::parseTestCertificate);
165 parseCertificateArray(reader, &EuDgcParser::parseRecoveryCertificate);
167 name = parseName(reader);
171 qCDebug(
Log) <<
"unhandled element:" << key;
177 std::visit(visitor([&name](
auto &cert) { cert.setName(name); }), m_cert);
178 std::visit(visitor([&dob](
auto &cert) { cert.setDateOfBirth(dob); }), m_cert);
183 if (!reader.
isArray() || !std::holds_alternative<std::monostate>(m_cert)) {
188 (this->*func)(reader);
195 if (!reader.
isMap()) {
201 const auto key = CborUtils::readString(reader);
203 cert.setDisease(translateValue(key, CborUtils::readString(reader)));
205 cert.setVaccineType(translateValue(key, CborUtils::readString(reader)));
209 const auto productId = CborUtils::readString(reader);
210 cert.setVaccine(translateValue(key,productId));
216 cert.setManufacturer(translateValue(key, CborUtils::readString(reader)));
218 cert.setDose(CborUtils::readInteger(reader));
220 cert.setTotalDoses(CborUtils::readInteger(reader));
222 cert.setCountry(CborUtils::readString(reader));
224 cert.setCertificateIssuer(CborUtils::readString(reader));
226 cert.setCertificateId(CborUtils::readString(reader));
228 qCDebug(
Log) <<
"unhandled vaccine key:" << key;
233 m_cert = std::move(cert);
238 if (!reader.
isMap()) {
244 const auto key = CborUtils::readString(reader);
246 cert.setDisease(translateValue(key, CborUtils::readString(reader)));
248 cert.setTestType(translateValue(
QLatin1String(
"tcTt"), CborUtils::readString(reader)));
250 cert.setTestName(CborUtils::readString(reader));
252 const auto productId = CborUtils::readString(reader);
253 cert.setTestName(translateValue(
QLatin1String(
"tcMa"), productId));
254 cert.setTestUrl(
QUrl(
QLatin1String(
"https://covid-19-diagnostics.jrc.ec.europa.eu/devices/detail/") + productId));
258 const auto value = CborUtils::readString(reader);
259 cert.setResultString(translateValue(
QLatin1String(
"tcTr"), value));
260 cert.setResult(value ==
QLatin1String(
"260415000") ? KTestCertificate::Negative : KTestCertificate::Positive);
262 cert.setTestCenter(CborUtils::readString(reader));
264 cert.setCountry(CborUtils::readString(reader));
266 cert.setCertificateIssuer(CborUtils::readString(reader));
268 cert.setCertificateId(CborUtils::readString(reader));
270 qCDebug(
Log) <<
"unhandled test key:" << key;
275 m_cert = std::move(cert);
280 if (!reader.
isMap()) {
286 const auto key = CborUtils::readString(reader);
288 cert.setDisease(translateValue(key, CborUtils::readString(reader)));
296 cert.setCertificateIssuer(CborUtils::readString(reader));
298 cert.setCertificateId(CborUtils::readString(reader));
300 qCDebug(
Log) <<
"unhandled recovery key:" << key;
305 m_cert = std::move(cert);
310 if (!reader.
isMap()) {
316 const auto key = CborUtils::readString(reader);
318 fn = CborUtils::readString(reader);
320 gn = CborUtils::readString(reader);
@ 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 ...
A vaccination certificate.
Type type(const QSqlDatabase &db)
KCODECS_EXPORT QByteArray base45Decode(QByteArrayView in)
KDB_EXPORT KDbVersionInfo version()
QString name(StandardAction id)
QByteArray mid(qsizetype pos, qsizetype len) const const
bool startsWith(QByteArrayView bv) const const
bool hasNext() const const
bool isArray() const const
bool next(int maxRecursion)
QDate fromString(QStringView string, QStringView format, QCalendar cal)
QDateTime fromSecsSinceEpoch(qint64 secs)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonObject object() const const
QString name() const const
QString left(qsizetype n) const const
QStringView mid(qsizetype start, qsizetype length) const const
QVariant fromValue(T &&value)