/*************************************************************************
* Rutoken                                                                *
* Copyright (c) 2003-2017, CJSC Aktiv-Soft. All rights reserved.         *
* Подробная информация:  http://www.rutoken.ru                           *
*------------------------------------------------------------------------*
* Данный пример демонстрирует проверку подписи CMS сообщения с помощью   *
* pkicore. CMS сообщение с данными и сертификатом читается из файла      *
* signed_data. CA сертификат читается из файла ca.pem. Для создания CMS  *
* сообщения можно воспользоваться примером CmsSign.                      *
*************************************************************************/

#include <common.h>

using namespace std;
using namespace rutoken::pkicore;

int main()
{
	try {
		cout << boolalpha;

		/**********************************************************************
		* Инициализируем pkicore, передав путь до директории с библиотекой    *
		* rtPKCS11ECP.                                                        *
		**********************************************************************/
		rutoken::pkicore::initialize(".");
		SCOPE_EXIT() {
			/**********************************************************************
			* Завершаем работу с pkicore при выходе из текущего блока.            *
			**********************************************************************/
			rutoken::pkicore::deinitialize();
		};

		/**********************************************************************
		* Получаем список подключенных устройств и продолжаем работу с первым *
		* доступным устройством.                                              *
		**********************************************************************/
		auto devices = Pkcs11Device::enumerate();
		if (devices.empty()) {
			throw runtime_error("There must be at least one device connected");
		}

		auto device = move(devices.front());

		/**********************************************************************
		* Читаем файл с подписанным сообщением.                               *
		**********************************************************************/
		const auto inputFileName = "signed_data";

		cout << "Reading signed message from " << inputFileName << endl;

		auto signedData = cms::SignedData::parse(readFile(inputFileName));

		/**********************************************************************
		* Читаем файл с CA сертификатом.                                      *
		**********************************************************************/
		const auto caCertFileName = "ca.pem";

		cout << "Reading CA certificate from " << caCertFileName << endl;

		auto caCertBuf = readFile(caCertFileName);
		ExternalCert caCert(string(caCertBuf.begin(), caCertBuf.end()));

		/**********************************************************************
		* Проверяем подпись сообщения.                                        *
		**********************************************************************/
		cms::VerifyParams params(device, cms::VerifyParams::Flag::verifyUserCert);
		params.addCaCert(caCert);

		auto result = signedData.verify(params);
		if (result == cms::VerifyResult::success) {
			cout << "Correct signature" << endl;
		} else {
			cout << "Wrong signature" << endl;
		}
	} catch (const exception& e) {
		cerr << e.what() << endl;
		return 1;
	}

	return 0;
}
