/*
 * Copyright(C) 2000 Проект ИОК
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто Про.
 */

/*!
 * \file $RCSfile$
 * \version $Revision: 233004 $
 * \date $Date:: 2021-09-27 16:58:59 +0300#$
 * \author $Author: markova $
 * \brief Интерфейс считывателей. Полный, с функциями, требующими восстановления контекста.
 */

#if !defined( _READER_RDR_H )
#define _READER_RDR_H

#include "reader/rdr_indie.h"

/* **** **** Функции, требующие восстановления контекста **** **** */
#if defined( __cplusplus )
extern "C" {
#endif /* defined( __cplusplus ) */

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция захвата носителя/считывателя для работы. 
 *
 * После вызова функции все вызовы функций работы с носителем/считывателем
 * осуществляются в рамках одной сессии носителя/считывателя, с гарантией, что ни другие процессы/нити не получат доступ к этому
 * носителю/считывателю. В то же время, возможны ситуации разрыва соединения, о которых должны соответствующим образом сообщать
 * все функции работы со считывателем/носителем.
 * Данная функция может вызываться произвольное число раз подряд из одной нити, проверяя состояние захвата считывателя/носителя.
 * Захват считывателя/носителя продолжается до вызова первой функции \ref rdr_unlock .
 *
 * \param context [in] Контекст считывателя.
 * \param carrier_ctx [in] Контекст провайдера.
* \return \ref reader_errors
* \sa \ref rdr_lock, \ref rdr_unlock
* 
 */
 DWORD rdr_lock(TSupSysEContext *context, const TProvCallCtx * carrier_ctx);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция прекращения захвата носителя/считывателя.  
 *
 *  Если вызвана после \ref rdr_lock в одной нити криптопровайдера, прекращает захват носителя.
 * Если вызов произошел в нити, в которой захват носителя был снят или не осуществлялся, не выполняет никаких действий.
 *
 * \param context [in] Контекст считывателя.
* \return Ничего
* \sa \ref rdr_lock, \ref rdr_unlock
* 
 */
 void rdr_unlock(TSupSysEContext *context);

#if defined( _WIN32 ) 
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки дескриптора безопасности
*
* \param context [in] Контекст считывателя.
* \param s_info [in]  Информация о безопасности.
* \param p_sec_descr [in] дескриптор безопасности. 
* \param out_error [out] результат 
* \sa \ref rdr_set_sec_descr, \ref rdr_get_sec_descr
* 
 */
 DWORD rdr_set_sec_descr(
     TSupSysEContext *context,
     SECURITY_INFORMATION s_info,
     PSECURITY_DESCRIPTOR p_sec_descr);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки дескриптора безопасности
*
* \param context [in] Контекст считывателя.
* \param s_info [in]  Информация о безопасности.
* \param p_sec_descr [in] дескриптор безопасности.  
* \param sec_descr_len [out] Размер получаемого дескриптора.
* \sa \ref rdr_set_sec_descr, \ref rdr_get_sec_descr
* 
 */
 DWORD rdr_get_sec_descr(
     TSupSysEContext *context,
     SECURITY_INFORMATION request_info,
     PSECURITY_DESCRIPTOR p_sec_descr,
     DWORD * sec_descr_len);
#endif /*_WIN32 */

/* **** Функции работы с носителем. **** */
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция подключения к считывателю/носителю.
 *
 * \param context [in] Контекст считывателя.
 * \param applet_count [out]  Число аплетов (приложений) на носителе. В случае отсутствия понятия "аплет" 
 *  для данного носителя устанавливается равным 0.
* \return \ref reader_errors
* \sa \ref  rdr_disconnect_carrier
* 
*/ 
 DWORD rdr_connect_carrier(
    TSupSysEContext *context, unsigned int * applet_count );

 /*!
* \ingroup Reader_RDR_12
* \brief Функция форматирования считывателя/носителя.
*
* \param context [in] Контекст считывателя.
* \param applet_count [out]  Число аплетов (приложений), созданных на носителе. 
* \return \ref reader_errors
* \sa \ref  rdr_connect_carrier
*
*/
 DWORD rdr_format_carrier(
     TSupSysEContext* context, unsigned int* applet_count);
 
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция выбора аплета(приложения) на носителе.
 *
 * \param context [in] Контекст считывателя.
 * \param app_num [in] Номер аплета, который предстоит выбрать. Аплеты будут перечисляться криптопровайдером, начиная с 0, и нулевой аплет
 * при выборе места записи контейнера пользователем указывается в списке первым, поэтому в качестве нулевого аплета выбирается тот, который 
 * производитель желает видеть наиболее часто употребляемым для данного носителя.
* \return \ref reader_errors
 * \sa \ref #rdr_connect_carrier
 * 
 */
 DWORD rdr_select_applet(TSupSysEContext *context, unsigned app_num);
 
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция возвращает текст описания выбранного апплета.
 *
 * \param context [in] Контекст считывателя.
 * \param text_info_length [in/out] Длина информации об апплете без терминирующего нуля.
 * \param text_info [out] Буфер для информации об апплете. Может быть NULL для получения длины через text_info_length.
* \return \ref reader_errors
* \sa \ref rdr_get_applet_text_info
* 
 */
 DWORD rdr_get_applet_text_info(
     const TSupSysEContext *context, size_t * text_info_length, TCHAR * text_info);


/*!
* \ingroup Reader_RDR_12
* \brief Закрытие соединения с носителем
*
* Функция закрывает соединение с носителем. Если соединие с носителем
*  не было открыто, то функция завершается и не выполняет
*  никаких действий. Если не закрыто текущее \ref rdr_term_application,
*  то предварительно закрывается приложение.
* \param context [in] контекст считывателя
* \return \ref reader_errors
* \sa \ref rdr_connect_carrier
* 
*/
 DWORD rdr_disconnect_carrier( 
    TSupSysEContext *context );

 

/*!
* \ingroup Reader_RDR_12
* \brief Установка local machine.
*
* Функция устанавливает флаг использования системных приложений.
* \param context [in] контекст считывателя
* \param local_machine [in] 1 для установки флага local_machine, 0
*  для снятия.
* \return \ref reader_errors
* \sa \ref rdr_local_machine
* 
*/
 DWORD rdr_local_machine(
    TSupSysEContext *context, int local_machine );


 /*!
  * \ingroup Reader_RDR_12
  * \brief Функция получения разрешений лицензии. Функцию разрешено использовать только привилегированным модулям поддержки.
  *
  * \param context [in] Контекст считывателя.
  * \param permissions [out] Указатель на DWORD, в который запишутся разрешения.
  * \return \ref reader_errors
  * \sa \ref
  *
  */
 DWORD rdr_get_license_permissions(const TSupSysEContext *context, unsigned * permissions);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения уникального номера носителя.
 *
 * \param context [in] Контекст считывателя.
 * \param length [in/out] На вход - длина строки, которую можно записать в буфер unique. То есть, размер передаваемого буфера равен ((length + 1) * sizeof(TCHAR)).
 * На выходе - реальная длина строки записанной строки, если размера буфера достаточно, или длина строки phrase, которую должна вернуть функция, если буфера недостаточно,
 * или если в качестве буфера передан NULL.
 * \param unique [out] Буфер, в который пишется значение уникального номера.
* \return \ref reader_errors
* \sa \ref  
* 
*/
 DWORD rdr_unique_get(
     const TSupSysEContext *context, size_t *length, TCHAR *unique);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения имени носителя, определенного пользователем.
 *
 * \param context [in] Контекст считывателя.
 * \param length [in/out] На вход - длина строки, которую можно записать в буфер name. То есть, размер передаваемого буфера равен ((length + 1) * sizeof(TCHAR)).
 * На выходе - реальная длина строки записанной строки, если размера буфера достаточно, или длина строки phrase, которую должна вернуть функция, если буфера недостаточно,
 * или если в качестве буфера передан NULL.
 * \param name [out] Буфер, в который пишется имя, заданное пользователем
 * \sa \ref
 *
 */
 DWORD rdr_get_user_defined_name(
     const TSupSysEContext *context,
     size_t *length,
     TCHAR *name);

/* **** Функции работы с PIN-кодом(паролем в открытом виде). **** */
 
/*!
* \ingroup Reader_RDR_12
* \brief Функция получения требований типа аутентификации папки
*
* Получает тип аутентификации папки. В случае аутентификации EKE
* возвращает все параметры аутентификации.
*
* \param context [in] контекст считывателя
* \param auth_type [in] место, где производится аутентификация (корень, пук, контейнер)
* \param auth_alg [out] полный тип аутентификации (EKE, SIMPLE, и т.д.)
* \return \ref reader_errors
* \sa rdr_password_type
* _fkc
*/
 DWORD rdr_password_type(
     const TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrLoginInfoType * auth_alg);

/*!  
 * \ingroup Reader_RDR_12
 * \brief Функция ввода символьного пароля.
 *
 * \param context [in] Контекст считывателя.
 * \param passwd [in] PUK в виде TCHAR-строки, заканчивающейся _T('\0').
 * \param retries [out] Число оставшихся попыток ввода. Устанавливается в случае успеха и в случае ошибки. При возврате внутренних ошибок счетчик не должен уменьшаться!
 * \param auth_type [in] AUTH_TYPE_PUK - для ввода PUK; AUTH_TYPE_ROOT - для ввода ПИН на папку; AUTH_TYPE_CONT - для ввода ПИН на контейнер; AUTH_TYPE_USER_PIN1 - для ввода УЭК ПИН1;
 * AUTH_TYPE_USER_PIN2 -для ввода УЭК ПИН2.
* \return \ref reader_errors
* \sa \ref rdr_login_ex
* 
*/
 DWORD rdr_login_ex(
     TSupSysEContext *context, TRdrLoginInfoType auth_type, const char *passwd, int *retries);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция запроса ввода пароля на устройстве.
 *
 * \param context [in] Контекст считывателя.
 * \param auth_type [in] AUTH_TYPE_PUK - для ввода PUK; AUTH_TYPE_ROOT - для ввода ПИН на папку; AUTH_TYPE_CONT - для ввода ПИН на контейнер; AUTH_TYPE_USER_PIN1 - для ввода УЭК ПИН1;
 * AUTH_TYPE_USER_PIN2 -для ввода УЭК ПИН2.
 * \return \ref reader_errors
 * \sa  \ref rdr_logout, \ref rdr_folder_open
 * 
 */
 DWORD rdr_self_login_ex(TSupSysEContext *context, TRdrLoginInfoType auth_type);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция запроса смены пароля на устройстве.
 *
 * \param context [in] Контекст считывателя.
 * \param auth_type [in] AUTH_TYPE_PUK - для ввода PUK; AUTH_TYPE_ROOT - для ввода ПИН на папку; AUTH_TYPE_CONT - для ввода ПИН на контейнер; AUTH_TYPE_USER_PIN1 - для ввода УЭК ПИН1;
 * AUTH_TYPE_USER_PIN2 -для ввода УЭК ПИН2.
 * \return \ref reader_errors
 * \sa \ref rdr_self_change
 * 
 */
 DWORD rdr_self_change(TSupSysEContext *context, TRdrLoginInfoType auth_type);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция восстановления на носителе пароля администратора по умолчанию
 *
 * \param context [in] Контекст считывателя.
 * \return \ref reader_errors
 * \sa \ref rdr_restore_default_login
 */
 DWORD rdr_restore_default_login(TSupSysEContext *context);

/*!
* \ingroup Reader_RDR_12
* \brief Закрытие доступа к приложению.
*
* Функция сбрасывает все открытые аутентификации на \ref rdr_term_application. 
* Если такая функциональность не поддерживается носителем, возвращает
* SCARD_E_UNSUPPORTED_FEATURE.
* \param context [in] контекст считывателя
* \sa \ref rdr_logout
*/
 DWORD rdr_logout(TSupSysEContext *context);
 

/*!
 * \ingroup Reader_RDR_12
 * \brief Cмена пароля с указанием другого пароля.
 *
 * Функция изменяет \ref rdr_term_passwd на \ref rdr_term_application.
 *
 * Если был сохранен пароль по умолчанию, то функция изменяет пароль
 *  по умолчанию.
 * В функции указывается также текущее значение пароля, который необходим для смены аутентификации.
 * Соответственно, функция может установить значение счетчика ошибок.
 * \param context [in] контекст считывателя.
 * \param auth_type [in] тип аутентификации, пароль которой меняется.
 * \param new_passwd [in] новый пароль. Может быть NULL, для очистки
 * \param set_auth_type [in] тип аутентификации, пароль которой предъявляется.
 * \param set_passwd [in] пароль, который предъявляется для смены auth_type.
 * \param retries [out] счетчик ошибок аутентификации set_auth_type.
 *  пароля. Под очисткой понимается установка в значение по умолчанию,
 *  т.е. при передаче пустой строки или при передаче NULL вход в приложение
 *  будет произведен, но это не означает, что будет сброшен пароль
 *  или установлен пароль пустая строка.
 * \return \ref reader_errors
 * \sa \ref  rdr_passwd_default_set,
 *
 */
 DWORD rdr_auth_change(
     TSupSysEContext *context, TRdrLoginInfoType auth_type, const char *new_passwd, TRdrLoginInfoType set_auth_type, const char *set_passwd);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения условной фразы ввода пароля.
 *
 * \param context [in] Контекст считывателя.
 * \param auth_type [in] AUTH_TYPE_PUK - для PUK; AUTH_TYPE_ROOT - для ПИН на папку; AUTH_TYPE_CONT - для ПИН на контейнер; AUTH_TYPE_USER_PIN1 - для УЭК ПИН1;
 * AUTH_TYPE_USER_PIN2 -для УЭК ПИН2.
 * \param length [in/out] На вход - длина строки, которую можно записать в буфер phrase. То есть, размер передаваемого буфера равен ((length + 1) * sizeof(TCHAR)).
 * На выходе - реальная длина строки записанной строки, если размера буфера достаточно, или длина строки phrase, которую должна вернуть функция, если буфера недостаточно,
 * или если в качестве буфера передан NULL.
 * \param phrase [out] Условная строка.
 * \return \ref reader_errors
 * \sa \ref  rdr_folder_open
 * 
*/

 DWORD rdr_passwd_phrase(
     TSupSysEContext *context, TRdrLoginInfoType auth_type, size_t *length, TCHAR *phrase);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция сброса числа попыток ввода пароля пользователя.
 *
 * \param context [in] Контекст считывателя.
 * \param auth_type [in] AUTH_TYPE_PUK - для PUK; AUTH_TYPE_ROOT - для ПИН на папку; AUTH_TYPE_CONT - для ПИН на контейнер; AUTH_TYPE_USER_PIN1 - для УЭК ПИН1;
 * AUTH_TYPE_USER_PIN2 -для УЭК ПИН2.
 * \return \ref reader_errors
 * \sa \ref rdr_clear_tries
 * 
 */
 DWORD rdr_clear_tries(TSupSysEContext *context, TRdrLoginInfoType auth_type);

 /* **** Функции криптоконтейнеров с неизвлекаемыми ключами. **** */

  /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения значений счетчиков ФКН.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] AUTH_TYPE_ROOT - счетчики блока аутентификации возвращаются для пароля на носитель; AUTH_TYPE_CONT - для пароля на контейнер.
 * \param counters [out] Счетчики.
 * \param has_counters [out] Признак существования счетчиков.
 * \return \ref reader_errors
 * \sa \ref rdr_get_sespake_counters
 * 
 */
 DWORD rdr_get_sespake_counters(const TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrFkcSespakeCounters counters, BOOL* has_counters);


 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения состояния аутентификации.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] AUTH_TYPE_ROOT - указывает на аутентификацию, состояние которой надо выяснить.
 * \return \ref reader_errors
 * \sa \ref rdr_get_auth_state
 */
 DWORD rdr_get_auth_state(const TSupSysEContext *context, TRdrLoginInfoType auth_type);

 /*!
* \ingroup Reader_RDR_12
* \brief Функция получения параметров защищенного соединения.
*
* \param context [in] Контекст считывателя/носителя.
* \param type [out] Тип защищенного соединения.
* \param algid [out] Алгоритм шифрования.
* \param cipher_mode [out] Режим шифрования.
* \param imit_key_algid [out] Алгоритм ключа, который будет использоваться для имиты.
* \return \ref reader_errors
* \sa \ref rdr_get_sm_params
*
*/
 DWORD rdr_get_sm_params(const TSupSysEContext* context, TRdrFkcSecureMessagingType* type, unsigned int* algid, DWORD* cipher_mode, unsigned int* imit_key_algid, BOOL* padding);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения уровня безопасности контейнера.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param security_level [out] уровень безопасности.
 * \return \ref reader_errors
 * \sa \ref rdr_get_container_level
 * 
 */
 DWORD rdr_get_container_level(const TSupSysEContext *context, DWORD * security_level);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения блока базовых флагов считывателя.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param flag [in] Имя флага.
 * \param value [out] Значение флага.
 * \return \ref reader_errors
 * \sa \ref rdr_get_support_flag
 * 
 */
 DWORD rdr_get_support_flag(const TSupSysEContext *context, size_t flag, int * value);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Получение возможных параметров ЭК для ключей пользователя
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param algid_array [out] массив для записи идентификатор ЭК
 * \param size_algid_array [in/out] Функция шифрования.
 * \return \ref reader_errors
 * \sa \ref rdr_get_userkey_algids
 * 
 */
 DWORD rdr_get_userkey_algids(TSupSysEContext *context, TRdrFkcEllipticPointParam * algid_array, size_t * size_algid_array);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Получение поддерживаемых OIDов. 
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param oids [out] последовательный набор asciiz-строк, завершающийся дополнительным нуль-терминатором
 * \return \ref reader_errors
 * \sa \ref rdr_get_userkey_algids
 * 
 */
 DWORD rdr_get_oids(TSupSysEContext* context, TSupSysMultiStringAsciiText* oids);
 
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Получение возможных параметров эллиптических кривых для аутентификации
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] аутентификация, для которой получается список алгоритмов
 * \param algid_array [out] массив для записи идентификатор ЭК
 * \param size_algid_array [in/out] Функция шифрования.
 * \return \ref reader_errors
 * \sa \ref rdr_get_sespake_algids
 * 
 */
 DWORD rdr_get_sespake_algids(TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrFkcEllipticPointParam * algid_array, size_t * size_algid_array);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Получение возможных длин для RSA ключей пользователя
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param min_key_bits [out] минимальная модуля RSA в битах
 * \param max_key_bits [out] максимальная модуля RSA в битах
 * \param key_bits_increment [out] шаг от min_key_bits, по которому получаются корректные длины; 0 если поддерживается весь диапазон от min до max
 * \return \ref reader_errors
 * \sa \ref rdr_get_available_rsa_length
 *
 */
 DWORD rdr_get_available_rsa_length(TSupSysEContext *context, DWORD * min_key_bits, DWORD* max_key_bits, DWORD* key_bits_increment);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения параметров аутентификации SESPAKE
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] тип аутентификации, параметры которой надо получить (контейнер, админ, рут)
 * \param auth_id [out] Идентификатор алгоритма ЭК.
 * \param salt [out] случайная величина salt.
 * \param ind [out] случайная величина ind, индекс точки.
 * \param dont_use_mq [out] не использовать m/q в выводе ключа
 * \param prehash [out] хэшировать пароль перед использованием
 * \return \ref reader_errors
 * \sa \ref rdr_get_sespake_full
 * 
 */ 
 DWORD rdr_get_sespake_full(TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrFkcEllipticPointParam * auth_id, TRdrFkcRndm12 salt, BYTE * ind, BOOL* dont_use_mq, BOOL * prehash);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки параметров аутентификации SESPAKE. 
 *
 * Тройка r, salt, ind и значение Qpw могут быть записаны вместе, а могут быть записаны в две команды (Qpw отдельно от остальных).
 * В последнем случае на уровне модуля поддержки необходимо реализовать передачу уникального идентификатора транзакции, причем передавать сначала рандомизаторы, а потом Qpw. Успешное завершение записи Qpw 
 * означает успех записи всех четырех параметров. Неудача первой или второй команды означает невыполненную запись всех четырех параметров. В случае создания нового блока аутентификации (установки аут. информации
 * в неинициализированный ранее блок или в новый контейнер) дополнительно передает идентификатор параметров алгоритма ЭК auth_id. Параметр auth_id игнорируется при переустановке параметров. При передаче двух команд APDU 
 * идентификатор должен передаваться с первой командой (установка рандомизаторов).
 * \param context[in] Контекст считывателя / носителя.
 * \param auth_type [in] тип аутентификации, параметры которой надо установить (контейнер, админ, рут)
 * \param auth_id [int] Идентификатор алгоритма ЭК.
 * \param salt [in] случайная величина salt.
 * \param ind [in] случайная величина ind, индекс точки.
 * \param Qpw [in] точка Qpw, основной секрет.
 * \return \ref reader_errors
 * \sa \ref rdr_set_sespake_full
 * 
 */
 DWORD rdr_set_sespake_full(TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrFkcEllipticPointParam auth_id, TRdrFkcRndm12 salt, BYTE ind, TRdrFkcPoint * Qpw);

   /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция проведения первого шага SESPAKE
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] AUTH_TYPE_ROOT - для пароля на носитель; AUTH_TYPE_CONT - для пароля на контейнер и т.д.
 * \param transaction_id [in] Идентификатор новой транзакции SESPAKE. Если равен предыдущим переданным значениям, то возвращается ошибка.
 * \param u1 [in] Входная точка.
 * \param u2 [out] Выходная точка.
 * \param ukm [out] значение ukm.
 * \return \ref reader_errors
 * \sa \ref rdr_sespake_first_step
 * 
 */
 DWORD rdr_sespake_first_step(TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrFkcTrID transaction_id, TRdrFkcPoint * u1, TRdrFkcPoint *u2);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция проведения второго шага SESPAKE
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] AUTH_TYPE_ROOT - для пароля на носитель; AUTH_TYPE_CONT - для пароля на контейнер и т.д.
 * \param transaction_id [in] Идентификатор транзакции SESPAKE. Должен быть таким же, как у предшествующего первого шага аутентификации, иначе возвращается ошибка.
 * \param hmacA [in] HMAС_A согласно протоколу SESPAKE. Рассчитывается провайдером.
 * \param hmacB [out] Буфер под HMAC_B. Рассчитывается смарт-картой.
 * \return \ref reader_errors
 * \sa \ref rdr_sespake_second_step
 * 
 */
 DWORD rdr_sespake_second_step(TSupSysEContext *context, TRdrLoginInfoType auth_type, TRdrFkcTrID transaction_id, BYTE * hmacA, BYTE * hmacB);

/* **** Функции работы с папками на носителе. **** */

/*!
* \ingroup Reader_RDR_12
* \brief Открытие контекста перечисления папок
* \param context [in] контекст считывателя
* \param enum_ctx [out] контекст перечисления папок
* \param folder_length [out] размер в символах максимальной по длине имени
*  папки, не включая завершающий 0.
* \param prototype [in] прототип имени папки для перечисления новых папок,
*  при перечислении существующих папок должен быть NULL.
* \param flags Флаги перечисления папок
* \return \ref reader_errors
* \sa \ref   rdr_folder_enum_next,  rdr_folder_enum_close
* 
*/
 DWORD rdr_folder_enum_open(
    const TSupSysEContext *context, 
    TRdrFolderEnumContext **enum_ctx,
    size_t *folder_length,
    const TCHAR *prototype,
    unsigned flags );

/*!
* \ingroup Reader_RDR_12
* \brief Получение следующей папки
* \param enum_ctx [in] контекст перечисления папок
* \param folder [out] имя папки; имя должно быть выделено по длинне + 1
*  возвращенной при открытии контекста перечисления.
* \return \ref reader_errors
* \sa \ref    rdr_folder_enum_open,  rdr_folder_enum_close
* 
*/
 DWORD rdr_folder_enum_next(
    TRdrFolderEnumContext *enum_ctx,
    TCHAR *folder );

/*!
* \ingroup Reader_RDR_12
* \brief Закрытие контекста перечисления папок
* \param enum_ctx [out] контекст перечисления папок
* \return \ref reader_errors
* \sa \ref    rdr_folder_enum_open,  rdr_folder_enum_next
* 
*/
 DWORD rdr_folder_enum_close(
    TRdrFolderEnumContext *enum_ctx );
 
/*!
* \ingroup Reader_RDR_12
* \brief Получение имени папки по умолчанию для данного приложения
* \param enum_ctx [out] контекст перечисления папок
* \return \ref reader_errors
* \sa \ref   rdr_folder_enum_open,  rdr_folder_enum_next
* 
*/
 DWORD rdr_get_default_folder(
     TSupSysEContext *context, 
     TCHAR * def_name, 
     size_t max_len );

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки контейнера по умолчанию.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param name [in] Имя контейнера.
 * \return \ref reader_errors
 * \sa \ref rdr_set_default_folder
 * 
 */
 DWORD rdr_set_default_folder(
     TSupSysEContext *context, 
     TCHAR * name);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения свободного места на токене.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param free_space количество свободного места
 * \return \ref reader_errors
 * \sa \ref rdr_get_free_space
 * 
 */
 DWORD rdr_get_free_space(
     TSupSysEContext* context,
     size_t* free_space);
/*!
* \ingroup Reader_RDR_12
* \brief Открытие папки
* \param context [in] контекст считывателя
* \param mode [in] метод открытия файла. Допускаются следующие флаги:
*  - <code>"r"</code> открытие существующего
*  - <code>"w"</code> открытие на создание
* \param folder [in] имя папки
* \return \ref reader_errors
* \sa \ref   rdr_folder_close,  rdr_folder_open
* 
*/
 DWORD rdr_folder_open(
    TSupSysEContext *context, 
    BOOL create,
    const TCHAR *folder );

/*!
* \ingroup Reader_RDR_12
* \brief Закрытие папки
*
* Функция закрывает доступ к текущей папке. Если доступ
*  к папке не был открыт, то функция завершается и не выполняет
*  никаких действий. Если не был закрыт доступ к файлу, то предварительно
*  закрывается \ref rdr_term_file.
*  Если переданное имя folder не поддерживается картой, должна вернуться ошибка SCARD_E_CARD_UNSUPPORTED.
* \param context [in] контекст считывателя
* \return \ref reader_errors
* \sa \ref    rdr_folder_open,  rdr_folder_close
* 
*/
 DWORD rdr_folder_close(
    TSupSysEContext *context );


/*!
* \ingroup Reader_RDR_12
* \brief Очистка папки
*
* Удаление папки.
* \param context [in] контекст считывателя
* \return \ref reader_errors
* \sa \ref rdr_folder_clear
* 
*/
 DWORD rdr_folder_clear(
     TSupSysEContext *context);

/* **** Функции работы с файлами. **** */

/*!
* \ingroup Reader_RDR_12
* \brief Открытие файла
*
* Функция открывает файл на носителе или открывает доступ к блоку
*  последовательной записи.
* \param context [in/out] контекст считывателя
* \param mode [in] метод открытия файла. Допускаются следующие флаги:
*  - <code>"r"</code> <code>O_RDONLY</code>
*  - <code>"w"</code> <code>O_CREAT | O_WRONLY | O_TRUNC</code>
*  - <code>"wp"</code> <code>O_PRIVATE | O_CREAT | O_WRONLY | O_TRUNC</code>
*  - <code>"r+"</code> <code>O_RDWR</code>
*  - <code>"w+"</code> <code>O_RDWR | O_CREAT | O_TRUNC</code>
*  - <code>"wp+"</code> <code>O_PRIVATE | O_RDWR | O_CREAT | O_TRUNC</code>
*  .
*  <p>Описание флагов
*  - \c O_RDONLY Открытие только на чтение
*  - \c O_WRONLY Открытие только на запись
*  - \c O_RDWR Открытие на чтение и запись
*  - \c O_IGNORE Пропускать ошибки
*  - \c O_CREATE Создание файла, если не установлен флаг \c O_TRUNC
*   и файл уже существует, или он существует всегда, то будет
*   возвращен \ref reader_errors  (DWORD)NTE_EXISTS.
*   Не гарантируется, что размер файла будет установлен в 0.
*  - \c O_TRUNC Если файл уже существует, то запись в файл
*   будет производиться без предварительного чтения из него. Так же
*   гарантируется, что запись за конец файла приведет к заполнению
*   нулями пространства от текущего конца файла до начала записи, при этом
*   последующее открытие файла без флага \c O_TRUNC не гарантирует этого
*   эффекта.
*  - \c O_PRIVATE Создание файла доступного только при наличии пароля.
*  .
* \param fileno [in] номер открываемого файла. Для открытия носителя
*  поддерживающего файловую систему имя должно быть отлично от
*  \c 0, для носителя не поддерживающего файловую систему
*  имя должно быть \c NULL.
* \return \ref reader_errors
* \sa \ref rdr_file_open
* 
*/
 DWORD rdr_file_open(
    TSupSysEContext *context, const char *mode,  TRdrFileNumber filno );

/*!
* \ingroup Reader_RDR_12
* \brief Закрытие файла.
*
* Функция закрывает файл на носителе. Если файл не был открыт, то функция
*  ничего не далает.
* если пароль предъявлялся
* \param context [in] контекст считывателя
* \return \ref reader_errors
* \sa \ref rdr_file_close,  rdr_file_open
* 
*/
 DWORD rdr_file_close(
    TSupSysEContext *context );

/*!
* \ingroup Reader_RDR_12
* \brief Запись в файл
*
* Функция записывает \a size байт с носителя, заданного контекстом \a context
*  начиная с позиции \a pos из буфера \a buffer.
*
* Если была установлена функция повтора операции, то осуществляется повтор
*  операции.
*
* Функция производит запись информации в файл.
* - Гарантируются, что при записи за пределы файла, при открытии
*  файла с флагом o_trunc предварительного чтения информации при записи
*  за конец файла производиться не будет.
*
* Не гарантируется возможность записи от конца файла, до начала записи.
* \param context [in] контекст считывателя
* \param pos [in] начальная позиция записи
* \param size [in] количество запысываемых байт
* \param buffer [in] записываемая информация
* \param writen [out] количество записанных байт. Может быть NULL,
*  тогда проверяется количество записанных и записываемых байт.
* \return \ref reader_errors
* \sa \ref rdr_file_write
* 
*/
 DWORD rdr_file_write(
    TSupSysEContext *context, size_t pos, size_t size, const void *buffer,
    size_t *writen );

/*!
* \ingroup Reader_RDR_12
* \brief Чтение из файла
*
* Функция читает \a size байт с носителя, заданного контекстом \a context
*  начиная с позиции \a pos в буфер \a buffer.
*
* Если была установлена функция повтора операции, то осуществляется повтор
*  операции.
* \param context [in] контекст считывателя
* \param pos [in] начальная позиция чтения
* \param size [in] количество читаемых байт
* \param buffer [out] прочитанная информация
* \param read [out] количество прочитанных байт. Может быть NULL,
*  тогда проверяется количество читаемых и прочитанных байт.
* \return \ref reader_errors
* \sa \ref rdr_file_read
* 
*/
 DWORD rdr_file_read(
    TSupSysEContext *context, size_t pos, size_t size, void *buffer,
    size_t *rfread );

/*!
* \ingroup Reader_RDR_12
* \brief Размер файла.
*
* Функция получает реальный размер файла, если функция не поддерживается,
*  то возвращается максимальный размер файла.
* \param context [in] контекст считывателя
* \param size [out] размер файла
* \return \ref reader_errors
* \sa \ref rdr_file_length
* 
*/
 DWORD rdr_file_length(
    TSupSysEContext *context, size_t *size );

/*!
* \ingroup Reader_RDR_12
* \brief Изменение размера файла с проверкой максимальной длины
*
* Функция изменяет размер файла. Если увеличение размера файла невозможно,
*  то возвращается \ref reader_errors и возвращается максимальная длина файла.
*  Если размер файла не может быть уменьшен, то действий не производится и
*  возвращается текущая длина файла.
* \param context [in] контекст считывателя
* \param size [in,out] in - требуемый размер файла, out - созданный или
*  максимальный размер файла
* \return \ref reader_errors
* \sa \ref rdr_file_chsize
* 
*/
 DWORD rdr_file_chsize(
    TSupSysEContext *context, size_t *size );

/*!
* \ingroup Reader_RDR_12
* \brief Удаление файла.
*
*
* Если была установлена функция повтора операции, то осуществляется повтор
*  операции.
* \param context [in] контекст считывателя
* \param fileno [in] номер удаляемого файла. Для удаление файла на носителе
*  поддерживающего файловую систему имя должно быть отлично от
*  \c 0, для носителя не поддерживающего файловую систему
*  имя должно быть \c NULL.
* \return \ref reader_errors
* \sa \ref rdr_file_unlink
* 
*/
 DWORD rdr_file_unlink(
    TSupSysEContext *context, TRdrFileNumber rffileno );

 /* **** Функции получения параметров ФКН. **** */

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция проверки существования пароля по умолчанию.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] Тип аутентификации, для которой проверяется наличие пароля по умолчанию.
 * \param exist [out] TRUE, если пароль по умолчанию на носителе задан, FALSE иначе.
 * \return \ref reader_errors
 * \sa \ref rdr_exist_default_password
 * _fkc */
 DWORD rdr_exist_default_password(
     const TSupSysEContext *context, DWORD auth_type, BOOL * exist);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения пароля по умолчанию. 
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param auth_type [in] тип аутентификации
 * \param password [out] Буфер для записи пароля.
 * \param max_length [in] Длина строки, которую можно записать в буфер.
 * \return \ref reader_errors
 * \sa \ref rdr_get_default_password
 * _fkc 
 */
 DWORD rdr_get_default_password(
    const TSupSysEContext *context, DWORD auth_type, char * password, size_t max_length);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения флагов ФКН.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param flags [out] Флаги.
 * \return \ref reader_errors
 * \sa \ref rdr_get_fkc_flags
 * _fkc 
 */
 DWORD rdr_get_fkc_flags(const TSupSysEContext *context, TRdrFkcCarrierFlags * flags);

  /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения флагов папок.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param flags [out] Флаги.
 * \return \ref reader_errors
 * \sa \ref rdr_get_universal_flags
 * _fkc 
 */
 DWORD rdr_get_universal_flags(const TSupSysEContext *context, TRdrUniversalCarrierFlags * flags);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения специфических флагов носителя/считывателя.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param flags [out] Флаги.
 * \return \ref reader_errors
 * _fkc
 */
 DWORD rdr_get_hardware_store_flags(const TSupSysEContext *context, DWORD* hardware_flags);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения термина пароль.
 *
 * \param context [in] Контекст считывателя.
 * \param auth_flags [out] Флаги используемых носителем аутентификаций, булево ИЛИ флагов AUTH_FLAG_TYPE_...
 * \return \ref reader_errors
 * \sa \ref rdr_all_password_flags
 * _fkc 
 */
 DWORD rdr_all_password_flags(const TSupSysEContext *context, DWORD * auth_flags);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки параметра контейнера.
 *
 * \param context [in] Контекст считывателя.
 * \param param_type [in] Тип устанавливаемого параметра
 * \param pbData [in] Значение устанавливаемого параметра 
 * \param dwData [in] Тип значения устанавливаемого параметра
 * \return \ref reader_errors
 * \sa \ref rdr_set_container_param
 * _fkc */
 DWORD rdr_set_container_param(const TSupSysEContext *context, TRdrFkcFolderEnumParam param_type, BYTE * pbData, DWORD dwData);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Установка флагов, специфических для устройства (носителя или считывателя).
 *
 * \param context [in] Контекст считывателя.
 * \param hardware_flags [in] Значение флагов
 * \return \ref reader_errors
 * _fkc */
 DWORD rdr_set_hardware_store_flags(const TSupSysEContext *context, DWORD hardware_flags);
 

/*
* Интерфейс использования, специфичный для ФКН
*/

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки первоначального значения ключа в контейнере (шаг 1).
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param masked_key [in] Значение ключа подписи, закрытого аддитивной маской по модулю 2^32.
 * \param key_length [in] Длина ключевого материала.
 * \param public_key [in] Значение ключа проверки подписи.
 * \param uiIDg [in] Набор параметров кривой ключа.
 * \param oid [in] OID набора параметров кривой ключа.
 * \param alg_type [in] Алгоритм, для которого создаётся ключ.
 * \param is_able_dh [in] Признак разрешения ДХ.
 * \param permissions [in] Разрешения ключа.
 * \param index [in] Номер ключа в контейнере.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_simple_key_set_step1
 * _fkc 
 */
 DWORD rdr_crypt_simple_key_set_step1(
     TSupSysEContext *context, 
     TRdrFkcOrder masked_key,
     DWORD key_length,
     TRdrFkcPoint* public_key,
     TRdrFkcEllipticPointParam uiIDg,
     char * oid,
     TKeyAlgType alg_type,
     DWORD key_type, 
     BOOL is_able_dh,
     unsigned int alg_id,
     DWORD permissions, 
     int index
 );
 
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция установки первоначального значения ключа в контейнере (шаг 2).
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param mask [in] Значение аддитивной маски.
 * \param key_length [in] Длина ключевого материала.
 * \param public_key [in] Значение ключа проверки подписи.
 * \param uiIDg [in] Набор параметров кривой ключа.
 * \param oid [in] OID набора параметров кривой ключа.
 * \param alg_type [in] Алгоритм, для которого создаётся ключ.
 * \param is_able_dh [in] Признак разрешения ДХ.
 * \param permissions [in] Разрешения ключа.
  * \param index [in/out] Номер ключа в контейнере. Возможны значения 0 - для первого созданного ключа в контейнере, 1 - для второго. В контейнере
 * можно создать как минимум один ключ. Впоследствии по этому номеру ключи будут адресоваться в контейнере.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_simple_key_set_step2
 * _fkc
 */
 DWORD rdr_crypt_simple_key_set_step2(
     TSupSysEContext *context, 
     TRdrFkcOrder mask, DWORD key_length, 
     TRdrFkcPoint* public_key, 
     TRdrFkcEllipticPointParam uiIDg, 
     char * oid,
     TKeyAlgType alg_type, 
     DWORD key_type, 
     BOOL is_able_dh,
     unsigned int alg_id, 
     DWORD permissions,
     int* index
 );

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения идентификатора алгоритма ключа
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param alg_id [out] идентификатор алгоритма ключа
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key, \ref rdr_crypt_get_public_key_oid \ref rdr_crypt_get_key_permissions
 * _fkc
 */
 DWORD rdr_crypt_get_key_algid(TSupSysEContext *context, DWORD key_type, unsigned int *alg_id);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения открытого ключа RSA
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param public_key [out] параметры ключа RSA
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key_param, \ref rdr_crypt_get_public_key_oid
 * _fkc
 */
 DWORD rdr_crypt_get_rsa_public_key(TSupSysEContext *context, DWORD key_type, TRdrFkcRsaKey *public_key);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения открытого ключа
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param public_key [out] Значение ключа
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key_param, \ref rdr_crypt_get_public_key_oid
 * _fkc
 */
 DWORD rdr_crypt_get_public_key(TSupSysEContext *context, DWORD key_type, TRdrFkcPoint* public_key);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция установки признака ключа 2001 года.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \return \ref reader_errors
 * _fkc
 */
 DWORD rdr_crypt_set_gost_2001(TSupSysEContext *context);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция получения параметров ключа
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param alg_id [out] идентификатор алгоритма ключа
 * \param idG [out] идентификатор параметров ключа
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key, \ref rdr_crypt_get_public_key_oid \ref rdr_crypt_get_key_permissions
 * _fkc
 */
 DWORD rdr_crypt_get_public_key_param(TSupSysEContext *context, DWORD key_type, unsigned int * alg_id, TRdrFkcEllipticPointParam * idG);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения разрешения ключа на операцию DH.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param is_able_dh [out] Разрешение ключа
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key, \ref rdr_crypt_get_public_key_oid, \ref rdr_crypt_get_public_key_param \ref rdr_crypt_get_key_permissions
 * _fkc
 */
 DWORD rdr_crypt_get_able_dh(TSupSysEContext *context, DWORD key_type, BOOL * is_able_dh);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения OIDa ключа
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param oid [out] OID параметров ключа. В функцию передается массив, в который модулем поддержки пишется CSTR.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key_param, \ref rdr_crypt_get_public_key \ref rdr_crypt_get_key_permissions
 * _fkc
 */
 DWORD rdr_crypt_get_public_key_oid(TSupSysEContext *context, DWORD key_type, char * oid);

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения разрешений ключа
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param key_type [in] AT_KEYEXCHANGE/AT_SIGNATURE
 * \param permissions [out] Разрешения ключа.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_get_public_key_param, \ref rdr_crypt_get_public_key \ref rdr_crypt_get_public_key_oid
 * _fkc
 */
 DWORD rdr_crypt_get_key_permissions(TSupSysEContext *context, DWORD key_type, DWORD * permissions);

/*!  
 * \ingroup Reader_RDR_12
 * \brief Функция генерации ключа в контейнере.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param uiIDg [in] Набор параметров кривой ключа.
 * \param oid [in] OID набора параметров кривой ключа.
 * \param alg_type [in] Алгоритм, для которого создаётся ключ.
 * \param add_random_data [in] Дополнительные данные для инициализации ДСЧ.
 * \param random_length [in] Длина данных для ДСЧ.
 * \param index [in/out] Номер ключа в контейнере. Возможны значения 0 - для первого созданного ключа в контейнере, 1 - для второго. В контейнере
 * можно создать как минимум один ключ. Впоследствии по этому номеру ключи будут адресоваться в контейнере.
 * \param pubKey [out] Значение открытого ключа.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_simple_key_gen 
 * _fkc
 */
 DWORD rdr_crypt_simple_key_gen(
     TSupSysEContext *context, 
     TRdrFkcEllipticPointParam uiIDg, 
     char * oid,
     TKeyAlgType alg_type, 
     DWORD key_type, 
     BOOL is_able_dh,
     unsigned int alg_id, 
     const BYTE * add_random_data, DWORD random_length, DWORD permissions, 
     int* index,
     TRdrFkcPoint * pubKey
 );

 /*!
 * \ingroup Reader_RDR_12
 * \brief Функция генерации RSA ключа в контейнере.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param rsa_len [in] Длина модуля ключа RSA в байтах.
 * \param alg_type [in] Алгоритм, для которого создаётся ключ.
 * \param add_random_data [in] Дополнительные данные для инициализации ДСЧ.
 * \param random_length [in] Длина данных для ДСЧ.
 * \param index [in/out] Номер ключа в контейнере. Возможны значения 0 - для первого созданного ключа в контейнере, 1 - для второго. В контейнере
 * можно создать как минимум один ключ. Впоследствии по этому номеру ключи будут адресоваться в контейнере.
 * \param pubKey [out] Значение открытого ключа RSA.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_simple_key_gen
 * _fkc
 */
 DWORD rdr_crypt_simple_rsa_key_gen(TSupSysEContext *context, DWORD rsa_len, long public_exp, DWORD key_type,
     BOOL is_able_dh, unsigned int alg_id, const BYTE *add_random_data, DWORD random_length,
     DWORD permissions, int *index, TRdrFkcRsaKey *pubKey);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция выработки ключа обмена.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param index [in] Номер ключа пользователя в контейнере.
 * \param point_Qalpha [in] Входное значение, открытый ключ.
 * \param coord_length [in] Длина координаты открытого ключа.
 * \param ukm [in] Входное значение, ukm.
 * \param ukm_length [in] Длина UKM.
 * \param mask [in] Входное значение, маска ключа обмена.
 * \param mask_length [in] Длина маски.
 * \param key [out] Ключ обмена.
 * \param key_length [in/out] размер буфера под ключ / длина ключа
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_agreement
 * _fkc
 */
 DWORD rdr_crypt_agreement(
TSupSysEContext *context,
 int index,
 DWORD key_type, 
const TRdrFkcPoint *point_Qalpha,
 size_t coord_length, 
const TRdrFkcUKM ukm, 
size_t ukm_length, 
TRdrFkcOrder mask, 
size_t mask_length,
 TRdrFkcOrder key, 
size_t * key_length);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция подписи.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param index [in] Номер ключа пользователя в контейнере.
 * \param hash_ctx [in] Контекст хэширования данных. Если присутствует, то подпись вычисляет на его основе.
 * \param hash [in] Значение хэша, в big-endian
 * \param r, s [out] Подпись, в big-endian каждая компонента.
 * \param r_length, s_length [out] Длина компонента подписи в байтах.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_signature
 * 
 */
 DWORD rdr_crypt_signature(TSupSysEContext *context, int index, DWORD key_type, TRdrHashContext * hash_ctx, TRdrFkcOrder hash, size_t hash_length, TRdrFkcOrder r, size_t * r_length, TRdrFkcOrder s, size_t * s_length);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция возведения в степень по модулю RSA.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param index [in] Номер ключа пользователя в контейнере.
 * \param key_type [in] Тип ключа (AT_KEYEXCHANGE/AT_SIGNATURE).
 * \param hash_ctx [in] Контекст хэширования данных. Если присутствует, то подпись вычисляется на его основе.
 * \param hash_length [in] Длина хэша в байтах. В случае расшифрования должна быть равна 0.
 * \param in_data [in] Входные данные (закодированный хэш/зашифрованные данные), в big-endian.
 * \param out_data [out] Выходные данные (подпись RSA/расшифрованные данные), в big-endian.
 * \param data_length [in/out] Длина входных/выходных данных в байтах (длина модуля RSA).
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_rsa_exptmod
 * 
 */
 DWORD rdr_crypt_rsa_exptmod(TSupSysEContext* context, int index, DWORD key_type, TRdrHashContext* hash_ctx,
     size_t hash_length, DWORD hash_alg, const BYTE* in_data, BYTE* out_data, size_t data_length);

/*!
 * \ingroup Reader_RDR_12
 * \brief Первая функция подписи для слабодоверенных носителей.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param transaction_id [in] Идентификатор сессии подписи.
 * \param index [in] Номер ключа пользователя в контейнере.
 * \param hash_ctx [in] Контекст хэширования данных. Если присутствует, то подпись вычисляет на его основе.
 * \param hash [in] Значение хэша, в big-endian
 * \param r, s [out] Подпись, в big-endian каждая компонента.
 * \param r_length, s_length [out] Длина компонента подписи в байтах.
 * \param w [out] Контрольное значение w
 * \param w_length [out] Длина контрольного значения w
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_signature, \ref rdr_crypt_weak_signature_2
 *
 */
 DWORD rdr_crypt_weak_signature_1(TSupSysEContext *context, TRdrFkcTrID transaction_id, int index, DWORD key_type, TRdrHashContext * hash_ctx, TRdrFkcOrder hash, size_t hash_length, TRdrFkcOrder r, size_t * r_length, TRdrFkcOrder s, size_t * s_length, TRdrFkcOrder w, size_t * w_length);
 
 /*!
 * \ingroup Reader_RDR_12
 * \brief Вторая функция подписи для слабодоверенных носителей.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param transaction_id [in] Идентификатор сессии подписи.
 * \param l [in] Случайная величина, передаваемая носителю
 * \param l_length [in] Длина случайной величины l в байтах.
 * \param index [in] Индекс ключа в контейнере.
 * \param v [out] Контрольное значение v
 * \param v_length [out] Длина контрольного значения v
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_signature, \ref rdr_crypt_weak_signature_1
 *
 */
 DWORD rdr_crypt_weak_signature_2(TSupSysEContext *context, TRdrFkcTrID transaction_id, TRdrFkcOrder l, size_t l_length, int index, TRdrFkcOrder v, size_t * v_length);


 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция инициализации контекста хэширования.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param hash_algid [in] Алгоритм хэша.
 * \param hash_ctx [out] Указатель на созданный контекст.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_hash_init
 * 
 */
 DWORD rdr_crypt_hash_init(TSupSysEContext *context, unsigned int hash_algid, TRdrHashContext ** hash_ctx);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция хэширования данных.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param hash_ctx [in] Контекст хэширования.
 * \param data [in] Данные для хэширования.
 * \param data_len [in] Количество данных для хэширования.
 * \param hashed_data_len [out] Количество прохэшированных данных.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_hash_data
 * 
 */
 DWORD rdr_crypt_hash_data(TSupSysEContext *context, TRdrHashContext * hash_ctx, const void * data, size_t data_len, size_t * hashed_data_len);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция хэширования данных.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param hash_ctx [in] Контекст хэширования.
 * \param buffer [out] Буфер для результата хэширования.
 * \param buffer_len [in/out] Размер буфера на входе, размер хэша на выходе.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_hash_getval
 * 
 */
 DWORD rdr_crypt_hash_getval(TSupSysEContext *context, TRdrHashContext * hash_ctx, void * buffer, size_t * buffer_len);

 
 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция удаления контекста хэширования.
 *
 * \param context [in] Контекст считывателя/носителя.
 * \param hash_ctx [in] Удаляемый контекст хэширования.
 * \return \ref reader_errors
 * \sa \ref rdr_crypt_hash_destroy
 * 
 */
 DWORD rdr_crypt_hash_destroy(TSupSysEContext *context, TRdrHashContext * hash_ctx);

/*!
* \ingroup Reader_RDR_12
* \brief Функция получает случайные значения.
*
* Функция получает набор случайных значения от носителя.
* \param context [in] контекст считывателя
* \param length [in/out] in - запрашиваемая длина случайной последовательности в байтах;
out - реальная длина полученной с карты случайной последовательности
* \param out [out] случайная последовательность или NULL для получения максимальной длины последовательности
* \return \ref reader_errors
* \sa \ref rdr_get_random
* 
*/
 DWORD rdr_get_random(TSupSysEContext *context, size_t *length, BYTE *out);

 /*!  
 * \ingroup Reader_RDR_12
 * \brief Функция для сообщения модулю поддержки состояния SM-контекста провайдера
 *
 * \param context [in] контекст считывателя
 * \param isSM [in] признак наличия защищенного соединения
 * \param auth_typs [in] тип установленной аутентификации
* \sa \ref rdr_set_sm_state
* 
*/
 DWORD rdr_set_sm_state(TSupSysEContext *context, BOOL isSM, TRdrLoginInfoType auth_type);

/*!
* \ingroup  Reader_RDR_12
* \brief Начало регистрации списка считывателей.
*
* Функция инициализирует список зарегистрированных считывателей.
* \param list [out] Инициализированный (пустой) список считывателей.
* \return \ref reader_errors
* \sa \ref rdr_register_start
* 
*/
DWORD rdr_register_start(TSupSysEList **list);

/*!
* \ingroup  Reader_RDR_12
* \brief Функция регистрации одного считывателя.
*
* Функция регистрирует указанный считыватель в списке.
* \param list [in/out] Заполненный список считывателей.
* \param reader [in] Имя считывателя.
* \return \ref reader_errors
* \sa \ref rdr_register_start
*
*/
DWORD rdr_register_one(TSupSysEList *list, const TCHAR *reader);

/*!
* \ingroup  Reader_RDR_12
* \brief Функция регистрации считывателей.
*
* Функция регистрирует все считыватели в списке.
* \param list [in/out] Заполненный список считывателей.
* \return \ref reader_errors
* \sa \ref rdr_register_start
*
*/
DWORD rdr_register_all(TSupSysEList *list);

/*!
* \ingroup  Reader_RDR_12
* \brief Функция регистрации считывателей в зависимости от флагов.
*
* Функция регистрирует считыватели в списке.
* \param list [in/out] Заполненный список считывателей.
* \param flags [in] Флаги, указывающие, какие элементы добавлять в список.
* \return \ref reader_errors
* \sa \ref rdr_register_start
*
*/
DWORD rdr_register_all_ext(TSupSysEList *list, unsigned flags);

/*!
* \ingroup Reader_RDR_12
* \brief Начало регистрации списка носителей.
*
* Функция инициализирует список зарегистрированных носителей.
* \param list [out] Инициализированный (пустой) список носителей.
* \return \ref reader_errors
* \sa \ref rdr_media_register_start
* 
*/
DWORD rdr_media_register_start(TSupSysEList **list);

/*!
* \ingroup Reader_RDR_12
* \brief Получение контекста считывателя по умолчанию.
*
* Функция получает \ref rdr_term_conext по умолчанию в следующей
*  последовательности:
*  - из локального реестра
*  - из глобального реестра
*  - первый найденный считыватель из списка.
*  .
* \param list [in] список считывателей
* \param context [out] контекст считывателя по умолчению
* \return \ref reader_errors
* \sa \ref rdr_context_default_set
* 
*/
DWORD rdr_context_default_get(const TSupSysEList *list, TSupSysEContext **context);

/*!
* \ingroup Reader_RDR_12
* \brief Установка контекста считывателя по умолчанию.
*
* Функция устанавливает \ref rdr_term_conext по умолчанию
*  в локальный реестр.
* \param context [in] контекст считывателя по умолчению
* \return \ref reader_errors
* \sa \ref rdr_context_default_get
* 
*/
DWORD rdr_context_default_set(const TSupSysEContext *context);

/*!
* \ingroup Reader_RDR_12
* \brief Прозвище поддерживаемго типа носителей.
* \param context [in] контекст считывателя.
* \param carrier_type [in] прозвище типа носитеелей.
* \return \ref reader_errors
* \sa rdr_info_carrier_type
* 
*/
DWORD rdr_info_carrier_type(const TSupSysEContext *context, TSupSysNickname carrier_type);

/*!
* \ingroup Reader_RDR_12
* \brief Получение текущего имени соединения.
*
* \param context [in] контекст считывателя.
* \param length [in/out] длина строки имени.
* \param name [out] имя соединения.
* \return \ref reader_errors
* \sa rdr_connect_current
*
*/
DWORD rdr_connect_current(const TSupSysEContext *context, size_t *length, TCHAR *name);

/*!
 * \ingroup Reader_RDR_12
 * \brief Функция получения имени внутреннего зарегистрированного элемента
 *   по умолчанию
 * \param context [in] контекст элемента
 * \param length [in/out] in - максимальное количество символов, которые
 *  могут быть записаны; out - требуемое количество символов для записи
 *  имени. Длина указывается в символах не включая последний нулевой символ
 * \param name [out] имя или NULL для получения только длины имени
 * \param connect [in] имя соединения, может быть NULL.
 */
DWORD rdr_default_internal_register_name(const TSupSysEContext *context, size_t *length, TCHAR *name, const TCHAR *ssconnect);


/* **** Функции работы с паролем. **** */

/*!
* \ingroup Reader_RDR_12
* \brief Функция получения параметров парольной аутентификации.
*
* \param context [in] Контекст считывателя.
* \param auth_type [in] Тип аутентификации, для которой запрашиваются свойства (ROOT или CONT).
* \param min_password_length [out] Минимальная длина пароля.
* \param max_password_length [out] Максимальная длина пароля.
* \param retries [out] Предельное число попыток неверного ввода пароля.
* \return \ref reader_errors
* \sa rdr_get_password_info
* 
*/
DWORD rdr_get_password_info(const TSupSysEContext *context, DWORD auth_type, size_t * min_password_length, size_t * max_password_length, size_t * retries, BOOL * isUtf8);


/*!
* \ingroup Reader_RDR_12
* \brief Функция получения термина пароль.
*
* \param context [in] Контекст считывателя.
* \param auth_type [in] AUTH_TYPE_PUK - для PUK; AUTH_TYPE_ROOT - для ПИН на папку; AUTH_TYPE_CONT - для ПИН на контейнер; AUTH_TYPE_USER_PIN1 - для УЭК ПИН1;
* AUTH_TYPE_USER_PIN2 -для УЭК ПИН2.
* \param length [in/out] Длина буфера.
* \param min_length [out] Наименование пароля. "Пин-код", "PUK" и т.д.
* \return \ref reader_errors
* \sa \ref rdr_folder_open
* 
*/
DWORD rdr_passwd_term(const TSupSysEContext *context, TRdrLoginInfoType auth_type, size_t *length, TCHAR *term);

/*!
* \ingroup Reader_RDR_12
* \brief Получение пароля по умолчанию (запомненного пароля)
*
* \param context [in] контекст считывателя
* \param passwd_length [in,out]
*  in - максимальное количество символов, которые
*  могут быть возвращены; out - требуемое количество символов для возврата.
*  Длина указывается в символах не включая последний нулевой символ.
* \param passwd [out] Пароль
* \return \ref reader_errors
* \sa \ref rdr_passwd_default_clear,
*  #rdr_passwd_default_set, #rdr_connect_carrier
* 
*/
DWORD rdr_passwd_default_get(const TSupSysEContext *context, BOOL is_local_machine, TCHAR * carrier_type, TCHAR * unique, TCHAR * folder, size_t *passwd_length, TCHAR *passwd);


/*!
* \ingroup Reader_RDR_12
* \brief Установка пароля по умолчанию (запомненный пароль)
*
* Функция получает \ref rdr_term_passwd установленный по умолчанию.
*
* \param context [in] контекст считывателя.
* \param passwd [in] пароль, для установки пустого пароля "", для
*  не установки пароля NULL.
* \return \ref reader_errors
* \sa \ref  #rdr_passwd_default_clear, #rdr_passwd_default_get,
*  #rdr_connect_carrier
* 
*/
DWORD rdr_passwd_default_set(const TSupSysEContext *context, BOOL is_local_machine, TCHAR * carrier_type, TCHAR * unique, TCHAR * folder, const TCHAR *passwd);

/*!
* \ingroup Reader_RDR_12
* \brief Удаление пароля по умолчанию (запомненного пароля)
*
* \param context [in] контекст считывателя.
* \return \ref reader_errors
* \sa \ref  #rdr_passwd_default_get, #rdr_passwd_default_set
* 
*/
DWORD rdr_passwd_default_clear(const TSupSysEContext *context, BOOL is_local_machine, TCHAR * carrier_type, TCHAR * unique, TCHAR * folder);

/* Функция удаления всех паролей установленный по умолчанию. */
DWORD rdr_passwd_default_clear_all(int machine);

/*!
* \ingroup Reader_RDR_12
* \brief Передача дополнительной информации о провайдере.
*
* \param context [in] Контекст считывателя/носителя.
* \param car_ctx [in] Контекст кэриера, передаваемый в колбеки
* \param callbacks [in] Функции обратного вызова.
* \return \ref reader_errors
*/
DWORD rdr_set_provider_callbacks(const TSupSysEContext *context, TProvCallCtx car_ctx, const TCarrierCallbacks * callbacks);

#if defined( __cplusplus )
}
#endif /* defined( __cplusplus ) */

#endif /* !defined( _READER_RDR_H ) */
/* end of file:Id: rdr.h,v 1.40 2001/01/22 09:42:09 cav Exp  */
