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