1 /*!
2 * \copyright Copyright (c) 2014-2021 Governikus GmbH & Co. KG, Germany
3 */
4
5 #include "AuthContext.h"
6
7 #include "asn1/Chat.h"
8 #include "AppSettings.h"
9 #include "GeneralSettings.h"
10 #include "paos/retrieve/DidAuthenticateEac1Parser.h"
11 #include "SecureStorage.h"
12
13 #include <QSignalBlocker>
14
15 using namespace governikus;
16
AuthContext(const QSharedPointer<ActivationContext> & pActivationContext)17 AuthContext::AuthContext(const QSharedPointer<ActivationContext>& pActivationContext)
18 : WorkflowContext()
19 , mProgressValue(0)
20 , mProgressMessage()
21 , mTcTokenNotFound(true)
22 , mErrorReportedToServer(false)
23 , mSkipRedirect(false)
24 , mActivationContext(pActivationContext)
25 , mTcTokenUrl()
26 , mTcToken()
27 , mRefreshUrl()
28 , mReceivedMessageId()
29 , mStartPaos()
30 , mInitializeFramework()
31 , mInitializeFrameworkResponse()
32 , mDIDList()
33 , mDIDListResponse()
34 , mDIDAuthenticateEAC1()
35 , mDIDAuthenticateResponseEAC1()
36 , mDIDAuthenticateEAC2()
37 , mDIDAuthenticateResponseEACAdditionalInputType()
38 , mDIDAuthenticateEACAdditionalInputType()
39 , mDIDAuthenticateResponseEAC2()
40 , mTransmits()
41 , mTransmitResponses()
42 , mDisconnectResponse()
43 , mStartPaosResponse()
44 , mAccessRightManager()
45 , mCertificates()
46 , mDvCvc()
47 , mCvcChainBuilderProd()
48 , mCvcChainBuilderTest()
49 , mSslSession()
50 {
51 const auto& generalSettings = Env::getSingleton<AppSettings>()->getGeneralSettings();
52 connect(&generalSettings, &GeneralSettings::fireLanguageChanged, this, &AuthContext::fireProgressChanged);
53 }
54
55
setProgress(int pValue,const QString & pMessage)56 void AuthContext::setProgress(int pValue, const QString& pMessage)
57 {
58 if (pValue != mProgressValue || pMessage != mProgressMessage)
59 {
60 mProgressValue = pValue;
61 mProgressMessage = pMessage;
62
63 const auto& connection = getCardConnection();
64 if (connection)
65 {
66 // Card interaction makes up about 80 % of the entire workflow's duration,
67 // "correct" the relative progress value accordingly.
68 connection->setProgressMessage(pMessage, static_cast<int>(1.25 * pValue));
69 }
70
71 Q_EMIT fireProgressChanged();
72 }
73 }
74
75
initAccessRightManager(const QSharedPointer<const CVCertificate> & pTerminalCvc)76 void AuthContext::initAccessRightManager(const QSharedPointer<const CVCertificate>& pTerminalCvc)
77 {
78 mAccessRightManager.reset(new AccessRightManager(mDIDAuthenticateEAC1, pTerminalCvc));
79 connect(mAccessRightManager.data(), &AccessRightManager::fireEffectiveAccessRightsChanged, this, &AuthContext::fireCanAllowedModeChanged);
80 Q_EMIT fireAccessRightManagerCreated(mAccessRightManager);
81 Q_EMIT fireCanAllowedModeChanged();
82 }
83
84
isCanAllowedMode() const85 bool AuthContext::isCanAllowedMode() const
86 {
87 return mAccessRightManager && mAccessRightManager->getEffectiveAccessRights().contains(AccessRight::CAN_ALLOWED);
88 }
89
90
getSslSession() const91 const QByteArray& AuthContext::getSslSession() const
92 {
93 return mSslSession;
94 }
95
96
setSslSession(const QByteArray & pSession)97 void AuthContext::setSslSession(const QByteArray& pSession)
98 {
99 mSslSession = pSession;
100 }
101
102
encodeEffectiveChat()103 QByteArray AuthContext::encodeEffectiveChat()
104 {
105 if (!mAccessRightManager)
106 {
107 return QByteArray();
108 }
109
110 return *mAccessRightManager;
111 }
112
113
getChainStartingWith(const QSharedPointer<const CVCertificate> & pChainRoot) const114 CVCertificateChain AuthContext::getChainStartingWith(const QSharedPointer<const CVCertificate>& pChainRoot) const
115 {
116 const auto& productionChain = mCvcChainBuilderProd.getChainStartingWith(pChainRoot);
117 if (productionChain.isValid())
118 {
119 qDebug() << "Found chain within productive PKI.";
120 return productionChain;
121 }
122
123 const auto& testChain = mCvcChainBuilderTest.getChainStartingWith(pChainRoot);
124 if (testChain.isValid())
125 {
126 qDebug() << "Found chain within test PKI.";
127 return testChain;
128 }
129
130 return CVCertificateChain();
131 }
132
133
hasChainForCertificationAuthority(const EstablishPaceChannelOutput & pPaceOutput) const134 bool AuthContext::hasChainForCertificationAuthority(const EstablishPaceChannelOutput& pPaceOutput) const
135 {
136 return getChainForCertificationAuthority(pPaceOutput).isValid();
137 }
138
139
getChainForCertificationAuthority(const EstablishPaceChannelOutput & pPaceOutput) const140 CVCertificateChain AuthContext::getChainForCertificationAuthority(const EstablishPaceChannelOutput& pPaceOutput) const
141 {
142 const auto& productionChain = mCvcChainBuilderProd.getChainForCertificationAuthority(pPaceOutput);
143 if (productionChain.isValid())
144 {
145 return productionChain;
146 }
147
148 return mCvcChainBuilderTest.getChainForCertificationAuthority(pPaceOutput);
149 }
150
151
initCvcChainBuilder(const QVector<QSharedPointer<const CVCertificate>> & pAdditionalCertificates)152 void AuthContext::initCvcChainBuilder(const QVector<QSharedPointer<const CVCertificate> >& pAdditionalCertificates)
153 {
154 Q_ASSERT(mDIDAuthenticateEAC1);
155
156 QVector<QSharedPointer<const CVCertificate> > cvcs;
157 cvcs += CVCertificate::fromHex(Env::getSingleton<AppSettings>()->getPreVerificationSettings().getLinkCertificates());
158 cvcs += getDidAuthenticateEac1()->getCvCertificates();
159 cvcs += pAdditionalCertificates;
160
161 const auto* secureStorage = Env::getSingleton<SecureStorage>();
162 mCvcChainBuilderProd = CVCertificateChainBuilder(cvcs + CVCertificate::fromHex(secureStorage->getCVRootCertificates(true)), true);
163 mCvcChainBuilderTest = CVCertificateChainBuilder(cvcs + CVCertificate::fromHex(secureStorage->getCVRootCertificates(false)), false);
164 }
165