Skip to content

Commit

Permalink
feat(cryptopro-cades): Добавлена функция получения доступных считыват…
Browse files Browse the repository at this point in the history
…елей (#41)

* feat(cryptopro-cades): Добавлена функция получения доступных считывателей

* Update packages/cryptopro-cades/README.md

---------

Co-authored-by: Andrey Potyomkin <[email protected]>
  • Loading branch information
aiekseu and AndTem authored Feb 27, 2024
1 parent 49b5a97 commit 2ca07d1
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/cryptopro-cades/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ npm install @astral/cryptopro-cades
- getCryptoProviders - получение списка криптопровайдеров установленных на компьютере пользователя. Название, тип, версия.
- getSystemInfo - получение информации о системе пользователя - версия КриптоПро ЭЦП Browser plug-in, версия CSP (VipNet или CryptoPro)
- pluginConfig - возможность включить вывод отладочной информации, подписываться на все создаваемые исключения, отключать проверку корректности системы, ограничивать тип криптопровайдера которым можно пользоваться, его версии.
- getReaders - получение списка доступных считывателей (в т.ч. вставленных токенов) с помощью CryptoPro CSP.
80 changes: 80 additions & 0 deletions packages/cryptopro-cades/src/api/getReaders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { CRYPTO_OBJECTS, DEFAULT_CRYPTO_PROVIDER } from '../constants';
import { CryptoError } from '../errors';
import {
type CCspInformation,
type CReaderMode,
type CReaderModes,
} from '../types';
import { outputDebug } from '../utils';

import { createObject } from './createObject';
import { getSystemInfo } from './getSystemInfo';
import { afterPluginLoaded } from './internal/afterPluginLoaded';
import { unwrap } from './internal/unwrap';

/**
* Кэш из доступных считывателей.
*/
let readersCache: CReaderMode[] | null;

/**
* Получить список доступных считывателей (в т.ч. вставленных токенов) с помощью CryptoPro CSP.
* @throws {CryptoError} в случае ошибки.
* @returns {Promise<CReaderMode[]>} Информация о доступных считывателях.
*/
export function getReaders(
resetCache: boolean = false,
): Promise<CReaderMode[]> {
if (readersCache && !resetCache) {
return Promise.resolve(readersCache);
}

return afterPluginLoaded(async () => {
if (readersCache && !resetCache) {
return Promise.resolve(readersCache);
}

// Получить список считывателей можно только с помощью КриптоПро CSP
const systemInfo = await getSystemInfo();

if (!systemInfo.cryptoProInstalled) {
throw CryptoError.create(
'CBP-12',
'Ошибка получения списка доступных считывателей',
null,
);
}

const logData = [];
const readers: CReaderMode[] = [];

try {
const cspInformation: CCspInformation = await createObject(
CRYPTO_OBJECTS.cspInformation,
);

await cspInformation.InitializeFromName(
DEFAULT_CRYPTO_PROVIDER.Default.ProviderName,
);

const readerModes: CReaderModes = await unwrap(
cspInformation.GetReaderModes(),
);
const readersCount = await unwrap(readerModes.Count);

for (let i = 0; i < readersCount; i++) {
const reader = await unwrap(readerModes.ItemByIndex(i));

readers.push(reader);
}

return (readersCache = readers);
} catch (error) {
logData.push({ error });
throw error;
} finally {
logData.push({ readers });
outputDebug('getReaders >>', logData);
}
})();
}
2 changes: 2 additions & 0 deletions packages/cryptopro-cades/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ export { findCertificateByThumbprint } from './findCertificateByThumbprint';
export { findCertificateBySkid } from './findCertificateBySkid';

export { checkPlugin } from './checkPlugin';

export { getReaders } from './getReaders';
6 changes: 6 additions & 0 deletions packages/cryptopro-cades/src/constants/cades.ts
Original file line number Diff line number Diff line change
Expand Up @@ -960,4 +960,10 @@ export const enum CRYPTO_OBJECTS {
* @see https://docs.cryptopro.ru/cades/plugin/certenroll/ccspinformations?id=ccspinformations
*/
cspInformations = 'X509Enrollment.CCspInformations',

/**
* Объект CCspInformation позволяет получить информацию о криптопровайдере.
* @see https://docs.cryptopro.ru/cades/plugin/certenroll/ccspinformation
*/
cspInformation = 'X509Enrollment.CCspInformation',
}
1 change: 1 addition & 0 deletions packages/cryptopro-cades/src/errors/errorCodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export const PLUGIN_ERRORS = Object.freeze({
'CBP-9': 'Неизвестный алгоритм ключа.',
'CBP-10': 'Не удалось прочитать данные сертификата.',
'CBP-11': 'Потеряно соединение с КриптоПро ЭЦП Browser plug-in.',
'CBP-12': 'Для получения списка считывателей необходим КриптоПро CSP',
});

/**
Expand Down
23 changes: 23 additions & 0 deletions packages/cryptopro-cades/src/types/cadesplugin/CCspInformation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { WithOptionalPromise } from '../WithOptionalPromise';

import { CReaderModes } from './CReaderModes';

/**
* Объект CCspInformation позволяет получить информацию о криптопровайдере.
* @see https://docs.cryptopro.ru/cades/plugin/certenroll/ccspinformation
*/
export interface CCspInformation {
/**
* Инициализирует объект по имени криптопровайдера
* @param {string} cryptoProviderName –
*/
InitializeFromName(cryptoProviderName: string): WithOptionalPromise<void>;

/**
* Возвращает коллекцию доступных считывателей
*/
GetReaderModes(): WithOptionalPromise<CReaderModes>;

// есть еще другие методы и свойства (см. по ссылке выше),
// но для получения информации о вставленных токенах нужны только эти
}
36 changes: 36 additions & 0 deletions packages/cryptopro-cades/src/types/cadesplugin/CReaderMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { WithOptionalPromise } from '../WithOptionalPromise';

/**
* Объект, содержащий информацию о режимах работы доступного считывателя.
* @see https://docs.cryptopro.ru/cades/reference/cadescom/cadescom_class/creadermode
*/
export type CReaderMode = {
/**
* Возвращает имя для данного режима работы считывателя, с порядковым номером
* @example HDIMAGE
* @example Aktiv Rutoken lite
* @example Aktiv Rutoken lite 01 – если вставлен еще один токен
*/
Name: WithOptionalPromise<string>;

/**
* Возвращает никнейм для данного режима работы считывателя, не уникальное значение
* @example HDD key storage
* @example Rutoken lite
* @example Rutoken ECP
*/
NickName: WithOptionalPromise<string>;

/**
* Возвращает медиа для данного режима работы считывателя, уникальное значение для токенов
* @example NO_UNIQUE, NO_MEDIA – для диска или облака
* @example pkcs11_rutoken_ecp_435461fa
* @example rutoken_lt_40a6544f
*/
Media: WithOptionalPromise<string>;

/**
* Возвращает результат побитового сложения флагов для данного режима работы считывателя
*/
CarrierFlags: WithOptionalPromise<number>;
};
20 changes: 20 additions & 0 deletions packages/cryptopro-cades/src/types/cadesplugin/CReaderModes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { WithOptionalPromise } from '../WithOptionalPromise';

import { CReaderMode } from './CReaderMode';

/**
* Объект, содержащий информацию о режимах работы доступного считывателя.
* @see https://docs.cryptopro.ru/cades/reference/cadescom/cadescom_interface/icpreadermodes
*/
export type CReaderModes = {
/**
* Возвращает считыватель с заданным индексом из коллекции.
* @param index Порядковый номер
*/
ItemByIndex(index: number): WithOptionalPromise<CReaderMode>;

/**
* Возвращает количество считывателей.
*/
Count: WithOptionalPromise<number>;
};
6 changes: 6 additions & 0 deletions packages/cryptopro-cades/src/types/cadesplugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ export type { ISignedXml } from './ISignedXml';
export type { IStore } from './IStore';

export type { IVersion } from './IVersion';

export type { CCspInformation } from './CCspInformation';

export type { CReaderMode } from './CReaderMode';

export type { CReaderModes } from './CReaderModes';

0 comments on commit 2ca07d1

Please sign in to comment.