1 /*!
2 * \copyright Copyright (c) 2017-2021 Governikus GmbH & Co. KG, Germany
3 */
4
5
6 #include "IfdStatus.h"
7
8 #include "AppSettings.h"
9
10 #include <QLoggingCategory>
11
12
13 Q_DECLARE_LOGGING_CATEGORY(remote_device)
14
15
16 using namespace governikus;
17
18
19 namespace
20 {
21 VALUE_NAME(SLOT_NAME, "SlotName")
22 VALUE_NAME(PIN_CAPABILITIES, "PINCapabilities")
23 VALUE_NAME(PIN_CAP_PACE, "PACE")
24 VALUE_NAME(PIN_CAP_EID, "eID")
25 VALUE_NAME(PIN_CAP_ESIGN, "eSign")
26 VALUE_NAME(PIN_CAP_DESTROY, "Destroy")
27 VALUE_NAME(PIN_PAD, "PINPad")
28 VALUE_NAME(MAX_APDU_LENGTH, "MaxAPDULength")
29 VALUE_NAME(CONNECTED_READER, "ConnectedReader")
30 VALUE_NAME(CARD_AVAILABLE, "CardAvailable")
31 VALUE_NAME(EF_ATR, "EFATR")
32 VALUE_NAME(EF_DIR, "EFDIR")
33 } // namespace
34
35
createPaceCapabilities() const36 QJsonValue IfdStatus::createPaceCapabilities() const
37 {
38 QJsonObject result;
39 result[PIN_CAP_PACE()] = mHasPinPad;
40 result[PIN_CAP_EID()] = false;
41 result[PIN_CAP_ESIGN()] = false;
42 result[PIN_CAP_DESTROY()] = false;
43 return result;
44 }
45
46
parsePinPad(const QJsonObject & pMessageObject)47 void IfdStatus::parsePinPad(const QJsonObject& pMessageObject)
48 {
49 const bool v0Supported = IfdVersion(IfdVersion::Version::v0).isSupported();
50
51 bool pinPadFound = false;
52 if (v0Supported && pMessageObject.contains(PIN_CAPABILITIES()))
53 {
54 pinPadFound = true;
55 QJsonValue value = pMessageObject.value(PIN_CAPABILITIES());
56 if (value.isObject())
57 {
58 QJsonObject object = value.toObject();
59 mHasPinPad = getBoolValue(object, PIN_CAP_PACE());
60 Q_UNUSED(getBoolValue(object, PIN_CAP_EID()))
61 Q_UNUSED(getBoolValue(object, PIN_CAP_ESIGN()))
62 Q_UNUSED(getBoolValue(object, PIN_CAP_DESTROY()))
63 }
64 else
65 {
66 invalidType(PIN_CAPABILITIES(), QLatin1String("object"));
67 }
68 }
69
70 if (!v0Supported || pMessageObject.contains(PIN_PAD()))
71 {
72 pinPadFound = true;
73 mHasPinPad = getBoolValue(pMessageObject, PIN_PAD());
74 }
75
76 if (!pinPadFound)
77 {
78 missingValue(PIN_CAPABILITIES());
79 missingValue(PIN_PAD());
80 }
81 }
82
83
IfdStatus(const ReaderInfo & pReaderInfo)84 IfdStatus::IfdStatus(const ReaderInfo& pReaderInfo)
85 : RemoteMessage(RemoteCardMessageType::IFDStatus)
86 , mSlotName(pReaderInfo.getName())
87 , mHasPinPad(pReaderInfo.isBasicReader() ? Env::getSingleton<AppSettings>()->getRemoteServiceSettings().getPinPadMode() : true)
88 , mMaxApduLength(pReaderInfo.getMaxApduLength())
89 , mConnectedReader(pReaderInfo.isConnected())
90 , mCardAvailable(pReaderInfo.hasCard())
91 {
92 }
93
94
IfdStatus(const QJsonObject & pMessageObject)95 IfdStatus::IfdStatus(const QJsonObject& pMessageObject)
96 : RemoteMessage(pMessageObject)
97 , mSlotName()
98 , mHasPinPad(false)
99 , mMaxApduLength(0)
100 , mConnectedReader(false)
101 , mCardAvailable(false)
102 {
103 mSlotName = getStringValue(pMessageObject, SLOT_NAME());
104 parsePinPad(pMessageObject);
105
106 mMaxApduLength = getIntValue(pMessageObject, MAX_APDU_LENGTH(), -1);
107 // Support SaC with AusweisApp2 < 1.22.0
108 if (IfdVersion(IfdVersion::Version::v0).isSupported() && mMaxApduLength == 0)
109 {
110 mMaxApduLength = -1;
111 }
112
113 mConnectedReader = getBoolValue(pMessageObject, CONNECTED_READER());
114 mCardAvailable = getBoolValue(pMessageObject, CARD_AVAILABLE());
115
116 if (getType() != RemoteCardMessageType::IFDStatus)
117 {
118 markIncomplete(QStringLiteral("The value of msg should be IFDStatus"));
119 }
120 }
121
122
getSlotName() const123 const QString& IfdStatus::getSlotName() const
124 {
125 return mSlotName;
126 }
127
128
hasPinPad() const129 bool IfdStatus::hasPinPad() const
130 {
131 return mHasPinPad;
132 }
133
134
getMaxApduLength() const135 int IfdStatus::getMaxApduLength() const
136 {
137 return mMaxApduLength;
138 }
139
140
getConnectedReader() const141 bool IfdStatus::getConnectedReader() const
142 {
143 return mConnectedReader;
144 }
145
146
getCardAvailable() const147 bool IfdStatus::getCardAvailable() const
148 {
149 return mCardAvailable;
150 }
151
152
toByteArray(const IfdVersion & pIfdVersion,const QString & pContextHandle) const153 QByteArray IfdStatus::toByteArray(const IfdVersion& pIfdVersion, const QString& pContextHandle) const
154 {
155 QJsonObject result = createMessageBody(pContextHandle);
156
157 result[SLOT_NAME()] = mSlotName;
158 if (pIfdVersion.getVersion() >= IfdVersion::Version::v2)
159 {
160 result[PIN_PAD()] = mHasPinPad;
161 }
162 else
163 {
164 result[PIN_CAPABILITIES()] = createPaceCapabilities();
165 }
166 result[MAX_APDU_LENGTH()] = mMaxApduLength;
167 result[CONNECTED_READER()] = mConnectedReader;
168 result[CARD_AVAILABLE()] = mCardAvailable;
169 result[EF_ATR()] = QJsonValue();
170 result[EF_DIR()] = QJsonValue();
171
172 return RemoteMessage::toByteArray(result);
173 }
174