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