Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qapduutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
5#include "qapduutils_p.h"
6#include <QtCore/QtEndian>
7
9
10/*
11 Utilities for handling smart card application protocol data units (APDU).
12
13 The structure of APDUs is defined by ISO/IEC 7816-4 Organization, security
14 and commands for interchange. The summary can be found on Wikipedia:
15
16 https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit
17*/
18
19/*
20 Parses a response APDU from the raw data.
21
22 If the data is too short to contain SW bytes, the returned responses SW
23 is set to QResponseApdu::Empty.
24*/
25QResponseApdu::QResponseApdu(const QByteArray &response)
26{
27 const auto view = qToByteArrayViewIgnoringNull(response);
28 if (view.size() < 2) {
29 m_status = Empty;
30 m_data = response;
31 } else {
32 const auto dataSize = view.size() - 2;
33 m_status = qFromBigEndian(qFromUnaligned<uint16_t>(view.data() + dataSize));
34 m_data = response.left(dataSize);
35 }
36}
37
38/*
39 Builds a command APDU from components according to ISO/IEC 7816.
40*/
41QByteArray QCommandApdu::build(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2,
42 QByteArrayView data, uint16_t ne)
43{
44 Q_ASSERT(data.size() <= 0xFFFF);
45
46 QByteArray apdu;
47 apdu.append(static_cast<char>(cla));
48 apdu.append(static_cast<char>(ins));
49 apdu.append(static_cast<char>(p1));
50 apdu.append(static_cast<char>(p2));
51
52 bool extendedLc = false;
53 uint16_t nc = data.size();
54
55 if (nc > 0) {
56 if (nc < 256) {
57 apdu.append(static_cast<char>(nc));
58 } else {
59 extendedLc = true;
60 apdu.append('\0');
61 apdu.append(static_cast<char>(nc >> 8));
62 apdu.append(static_cast<char>(nc & 0xFF));
63 }
64 apdu.append(data);
65 }
66
67 if (ne) {
68 if (ne < 256) {
69 apdu.append(static_cast<char>(ne));
70 } else if (ne == 256) {
71 apdu.append(static_cast<char>('\0'));
72 } else {
73 if (!extendedLc)
74 apdu.append('\0');
75 apdu.append(static_cast<char>(ne >> 8));
76 apdu.append(static_cast<char>(ne & 0xFF));
77 }
78 }
79
80 return apdu;
81}
82
83QT_END_NAMESPACE
QByteArray build(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, QByteArrayView data, uint16_t ne=0)