1 /*!
2 * \copyright Copyright (c) 2017-2021 Governikus GmbH & Co. KG, Germany
3 */
4
5 #include "IfdEstablishPaceChannel.h"
6
7 #include <QJsonObject>
8 #include <QLoggingCategory>
9
10
11 Q_DECLARE_LOGGING_CATEGORY(remote_device)
12
13
14 using namespace governikus;
15
16
17 namespace
18 {
19 VALUE_NAME(SLOT_HANDLE, "SlotHandle")
20 VALUE_NAME(INPUT_DATA, "InputData")
21 VALUE_NAME(PREFERRED_PIN_LENGTH, "PreferredPinLength")
22 } // namespace
23
24
parseInputData(const QJsonObject & pMessageObject)25 void IfdEstablishPaceChannel::parseInputData(const QJsonObject& pMessageObject)
26 {
27 const bool v0Supported = IfdVersion(IfdVersion::Version::v0).isSupported();
28
29 const QString& inputData = getStringValue(pMessageObject, INPUT_DATA());
30 if (isIncomplete())
31 {
32 return;
33 }
34
35 const auto& input = QByteArray::fromHex(inputData.toUtf8());
36 if (v0Supported && EstablishPaceChannel::isCcid(input))
37 {
38 if (!mInputData.fromCcid(input))
39 {
40 markIncomplete(QStringLiteral("The value of InputData should be as defined in TR-03119 section D.3"));
41 }
42
43 return;
44 }
45
46 if (!mInputData.fromInputData(input))
47 {
48 if (v0Supported)
49 {
50 markIncomplete(QStringLiteral("(v0) The value of InputData should be as defined in TR-03119 section D.3"));
51 markIncomplete(QStringLiteral("(v2) The value of InputData should be as defined in PC/SC Part 10 AMD1 section 2.6.16"));
52 }
53 else
54 {
55 markIncomplete(QStringLiteral("The value of InputData should be as defined in PC/SC Part 10 AMD1 section 2.6.16"));
56 }
57 }
58 }
59
60
IfdEstablishPaceChannel(const QString & pSlotHandle,const EstablishPaceChannel & pInputData,int pPreferredPinLength)61 IfdEstablishPaceChannel::IfdEstablishPaceChannel(const QString& pSlotHandle, const EstablishPaceChannel& pInputData, int pPreferredPinLength)
62 : RemoteMessage(RemoteCardMessageType::IFDEstablishPACEChannel)
63 , mSlotHandle(pSlotHandle)
64 , mInputData(pInputData)
65 , mPreferredPinLength(pPreferredPinLength)
66 {
67 }
68
69
IfdEstablishPaceChannel(const QJsonObject & pMessageObject)70 IfdEstablishPaceChannel::IfdEstablishPaceChannel(const QJsonObject& pMessageObject)
71 : RemoteMessage(pMessageObject)
72 , mSlotHandle()
73 , mInputData()
74 , mPreferredPinLength(0)
75 {
76 mSlotHandle = getStringValue(pMessageObject, SLOT_HANDLE());
77
78 parseInputData(pMessageObject);
79
80 if (pMessageObject.contains(PREFERRED_PIN_LENGTH()))
81 {
82 mPreferredPinLength = getIntValue(pMessageObject, PREFERRED_PIN_LENGTH(), 0);
83 }
84
85 if (getType() != RemoteCardMessageType::IFDEstablishPACEChannel)
86 {
87 markIncomplete(QStringLiteral("The value of msg should be IFDEstablishPACEChannel"));
88 }
89 }
90
91
getSlotHandle() const92 const QString& IfdEstablishPaceChannel::getSlotHandle() const
93 {
94 return mSlotHandle;
95 }
96
97
getInputData() const98 const EstablishPaceChannel& IfdEstablishPaceChannel::getInputData() const
99 {
100 return mInputData;
101 }
102
103
getPreferredPinLength() const104 int IfdEstablishPaceChannel::getPreferredPinLength() const
105 {
106 return mPreferredPinLength;
107 }
108
109
toByteArray(const IfdVersion & pIfdVersion,const QString & pContextHandle) const110 QByteArray IfdEstablishPaceChannel::toByteArray(const IfdVersion& pIfdVersion, const QString& pContextHandle) const
111 {
112 QJsonObject result = createMessageBody(pContextHandle);
113
114 result[SLOT_HANDLE()] = mSlotHandle;
115 if (pIfdVersion.getVersion() >= IfdVersion::Version::v2)
116 {
117 result[INPUT_DATA()] = QString::fromLatin1(mInputData.createInputData().toHex());
118 if (mPreferredPinLength > 0)
119 {
120 result[PREFERRED_PIN_LENGTH()] = mPreferredPinLength;
121 }
122 }
123 else
124 {
125 result[INPUT_DATA()] = QString::fromLatin1(mInputData.createCommandDataCcid().toHex());
126 }
127
128 return RemoteMessage::toByteArray(result);
129 }
130