스마트 카드 미니 드라이버 개요
카드별 미니 드라이버는 기본 CSP/KSP에서 가장 낮은 논리 인터페이스 계층입니다. 이 미니드라이버를 사용하면 기본 CSP/KSP 및 애플리케이션이 SCRM을 사용하여 특정 유형의 카드와 직접 상호 작용할 수 있습니다.
카드 미니 드라이버는 이 사양에 정의된 특정 API 집합을 내보내는 DLL입니다. 카드 미니 드라이버에 대한 각 호출에는 컨텍스트 정보를 제공하는 CARD_DATA 구조에 대한 포인터가 포함됩니다. 이 컨텍스트 정보는 상층 계층과 카드 미니 드라이버 간의 통신을 용이하게 하는 데 사용되는 함수 포인터 테이블 외에도 일부 상태 정보를 제공합니다.
이 컨텍스트 구조에 대한 자세한 내용은 CardAcquireContext를 참조하세요.
관련 문서
Cardmod.h C 헤더 파일은 이 사양과 관련된 추가 정보를 제공합니다. 이 파일에는 Microsoft 스마트 카드 미니 드라이버 API에서 지정하는 함수 프로토타입 및 구조가 포함되어 있습니다. 이 API는 Microsoft CPDK(암호화 공급자 개발 키트)를 통해 사용할 수 있습니다.
일반 디자인 지침
카드 미니 드라이버는 DLL로 배포해야 합니다.
각 카드별 작업은 달리 언급된 경우를 제외하고 단일 원자성 트랜잭션을 구현해야 합니다.
표준화된 매크로 수준 연산 집합을 구현해야 합니다.
논리 카드 파일 시스템 개체는 물리적 위치에 매핑되어야 합니다.
이 새 모델을 기반으로 하는 카드는 카드에 저장된 모든 파일을 동적으로 확장할 수 있어야 합니다. 읽기 전용이며 이 지침을 따를 수 없는 카드의 경우 미니 드라이버는 이 사양에 자세히 설명된 읽기 전용 카드에 대한 특정 지침을 따라야 합니다.
미니 드라이버는 CPDK에서 정의를 가져옵니다. 미니 드라이버 헤더 파일(Cardmod.h)에는 이를 위해 Bcrypt.h 가 포함됩니다. 구현은 미니 드라이버 컴파일을 위한 Microsoft Visual Studio 프로젝트 설정을 통해 이러한 종속성을 해결해야 합니다.
플러그 인 또는 드라이버에 대한 보호된 프로세스 요구 사항
LSA 플러그 인 또는 드라이버가 보호된 프로세스로 성공적으로 로드하려면 다음 조건을 충족해야 합니다.
서명 확인
o 보호 모드를 사용하려면 LSA에 로드된 모든 플러그 인을 Microsoft 서명으로 디지털 서명해야 합니다. 따라서 서명되지 않은 플러그 인 또는 타사 서명된 플러그 인은 LSA에서 로드되지 않습니다. 이러한 플러그 인의 예로 스마트 카드 드라이버, 암호화 플러그 인, 암호 필터 등이 있습니다.
o 드라이버(예: 스마트 카드 드라이버)인 LSA 플러그 인은 디지털 서명해야 합니다.
참고Windows 하드웨어 호환성 프로그램은 Windows 드라이버를 디지털 서명하는 유일한 방법을 제공합니다. 따라서 이 정보는 웹 사이트를 참조하는 것이 중요합니다.
Microsoft SDL(보안 개발 수명 주기) 프로세스 지침을 준수합니다.
또한 모든 플러그 인은 Microsoft SDL(보안 개발 수명 주기) – 프로세스 지침 항목의 적용 가능한 부분을 준수해야 합니다. 예를 들어 부록 G의 SDL 프로세스에 설명된 공유 섹션 없음을 참조하세요.
플러그 인이 Microsoft 서명으로 제대로 서명된 경우에도 SDL 프로세스를 준수하지 않으면 플러그 인을 로드하지 못할 수 있습니다.
SDL에 대한 자세한 내용은 Microsoft SDL(보안 개발 수명 주기) – 프로세스 지침을 참조하세요.
개발자를 위한 지침에 대한 논의는 개발자 지침을 참조하세요.
트랜잭션 관리
- 카드 미니 드라이버는 SCRM을 사용하여 카드에 액세스하는 경우 호출자가 트랜잭션을 처리한다고 가정해야 합니다.
- 카드 미니 드라이버는 CardDeleteContext 를 제외한 모든 진입점이 카드 트랜잭션을 보유하여 호출된다고 가정할 수 있습니다. 카드가 제거되었거나 정리 절차의 일부로 호출되고 있기 때문에 CardDeleteContext 에서 이를 가정할 수 없습니다.
- 단일 프로세스에 여러 컨텍스트가 있을 수 있습니다. 한 프로세스에서 CardDeleteContext 를 호출해도 다른 컨텍스트가 작동하지 않습니다.
- 카드의 인증 상태를 처리하는 것은 카드 미니 드라이버가 아니라 호출자의 책임이기도 합니다.
규칙
문자열: UNICODE 및 ANSI
애플리케이션 수준에서 문자열은 일반적으로 직접 또는 간접적으로 사용자 인터페이스의 요소로 발생합니다. 따라서 일반적으로 이해할 수 있도록 지역화(사용자의 언어로 번역)되어야 합니다. 이러한 이유로 대부분의 애플리케이션에서 사용하는 문자열 형식은 서로 다른 문자 집합을 수용하기 위해 더블 바이트(즉, UNICODE)입니다.
그러나 스마트 카드는 최소한의 리소스로 작동하며 디렉터리, 파일, 사용자 등의 이름을 지정하는 옵션은 거의 없습니다. 문자열에 대한 문자 집합은 문자열 데이터의 보다 간결한 표현을 제공하는 싱글 바이트 ANSI입니다.
따라서 카드 미니드라이버와 주고 받는 문자열 버퍼는 싱글 바이트 ANSI여야 하며 필요에 따라 이 문자 형식으로 변환은 카드 미니드라이버 외부에서 수행해야 합니다.
오류 처리
일관된 오류 처리, 실패에 대한 응답 및 카드 미니드라이버에 대한 일관된 동작을 보장하려면 다음 규칙을 따라야 합니다.
- 잘못된 플래그를 포함한 모든 NULL 및 잘못된 매개 변수는 SCARD_E_INVALID_PARAMETER 반환합니다.
- 모든 잘못된 PIN 또는 잘못된 키 반환을 사용한 시도가 SCARD_W_WRONG_CHV.
- 일반 오류가 발생하면 API는 SCARD_E_UNEXPECTED 반환합니다.
또한 다음 섹션에 설명된 함수에서 반환되는 오류는 SCARD_* 범주(winerror.h)에서 반환되어야 합니다. 예를 들어 ERROR_INVALID_PARAMETER(0x00000057) 대신 SCARD_E_INVALID_PARAMETER(0x80100004)를 사용하는 것이 좋습니다.
참고 I/O 오류 또는 카드에 해당 파일의 실제 존재와 관련이 없는 다른 복구할 수 없는 데이터 문제로 인해 카드에서 파일을 읽을 수 없는 경우 SCARD_E_COMM_DATA_LOST 반환하는 것이 좋습니다.
이러한 상황에서 SCARD_E_FILE_NOT_FOUND 우산 오류 코드로 반환하면 잘못된 디버깅 정보가 제공됩니다.
인증 및 권한 부여
버전 6부터 미니 드라이버 인터페이스는 PIN 개념을 기존의 영숫자 문자열 이상으로 확장합니다. 자세한 내용은 이 사양의 뒷부분에 있는 "SECRET_TYPE(열거형)"를 참조하세요.
메모리 할당 처리
메모리 버퍼를 할당하는 이 사양의 모든 API 요소는 PFN_CSP_ALLOC 호출하여 내부적으로 이 작업을 수행합니다. 따라서 이러한 메모리 버퍼는 PFN_CSP_FREE 호출하여 해제되어야 합니다.
카드 미니 드라이버가 수행하는 메모리 할당은 PFN_CSP_ALLOC 또는 PFN_CSP_REALLOC 사용하여 수행해야 합니다.
캐싱
기본 CSP/KSP의 카드 인터페이스 계층은 카드에 쓰거나 카드에서 읽어야 하는 데이터의 양을 최소화하기 위해 데이터 캐시를 구현합니다. 또한 데이터 캐시는 카드 미니 드라이버가 CARD_DATA 구조의 함수 포인터를 통해 사용할 수 있도록 하며, 카드 미니 드라이버는 이러한 포인터를 사용하여 카드에 저장된 내부 데이터 파일을 캐싱하여 성능을 향상시켜야 합니다.
데이터 캐싱을 사용하려면 카드에 대한 캐시 새로 고침 카운터를 유지하기 위해 카드에 대한 쓰기 액세스 권한이 필요합니다. 미니 드라이버는 카드에 데이터를 쓸 수 없는 경우 데이터 캐싱을 제어할 수 있습니다.
데이터 캐싱을 제어하는 방법에 대한 자세한 내용은 이 사양의 뒷부분에 있는 CardGetProperty 의 CP_CARD_CACHE_MODE 속성 정의를 참조하세요.
필수 버전 검사
모든 카드 미니 드라이버는 버전 검사를 구현해야 합니다. CARD_DATA 구조의 버전은 호출자가 지원하려는 버전과 카드 미니 드라이버가 실제로 지원할 수 있는 버전 간의 협상입니다.
CARD_DATA 버전 검사
최소 버전을 지원되는 카드 미니 드라이버 컨텍스트 구조의 최소 버전(즉, CARD_DATA 구조)으로 정의하고, 현재 버전을 이 카드 미니 드라이버가 디자인된 수준과 CardAcquireContext에서 성공적으로 반환할 때 모든 카드 미니 드라이버 집합 구조 항목이 유효하도록 보장하는 수준으로 정의합니다. 현재 버전은 최소 버전보다 크거나 같아야 하며 Cardmod.h에 정의된 CARD_DATA_CURRENT_VERSION 작거나 같아야 합니다.
호출하는 애플리케이션이 CardAcquireContext를 호출할 때 로드하려는 원하는 버전을 지정합니다. 요청된 이 버전은 CARD_DATA 구조체의 dwVersion 멤버에서 설정됩니다.
요청된 버전이 카드 미니 드라이버에서 지원하는 최소 버전보다 작은 경우 CardAcquireContext 는 수정 버전 불일치 오류를 반환해야 합니다(다음 샘플 코드 참조).
요청된 버전이 최소 버전만큼 좋은 경우 카드 미니 드라이버는 dwVersion 멤버를 요청된 버전보다 작거나 같은 버전을 지원할 수 있는 가장 높은 버전으로 설정해야 합니다.
다음 샘플 코드는 버전을 확인할 때 예상되는 카드 미니 드라이버 동작을 보여줍니다. 이는 CardAcquireContext 함수의 본문에 있는 것으로 간주됩니다. pCardData 는 이 호출에 전달된 CARD_DATA 구조체에 대한 포인터입니다.
#define MINIMUM_VERSION_SUPPORTED (4)
#define CURRENT_VERSION_SUPPORTED (7)
// The lowest supported version is 4.
If (pCardData->dwVersion < MINIMUM_VERSION_SUPPORTED)
{
dwError = (DWORD) ERROR_REVISION_MISMATCH;
goto Ret;
}
// Set the version to what we support, but don’t exceed the
// requested version
pCardData->dwVersion =
min(pCardData->dwVersion, CURRENT_VERSION_SUPPORTED);
참고 카드 미니 드라이버가 반환하는 버전이 호출 애플리케이션의 목적에 적합하지 않은 경우 호출 애플리케이션이 이를 적절하게 처리하는 것은 호출 애플리케이션의 책임입니다.
CardAcquireContext에 대한 호출에서 dwVersion을 설정한 후에는 동일한 컨텍스트에 있는 동안 호출자 또는 카드 미니 드라이버가 변경하지 않는다고 가정합니다.
기타 구조 버전 검사
버전이 지정된 다른 구조체 및 기타 카드 미니 드라이버 API 메서드의 경우 버전 처리는 한 가지 예외를 제외하고 CARD_DATA 구조와 동일합니다. 0으로 설정된 dwVersion 멤버를 포함하는 구조체를 사용하여 API 메서드를 호출하는 경우 dwVersion 값 1로 처리해야 합니다.
CardRSADecrypt 및 CardSignData 함수에는 전달되는 데이터 구조에 대한 버전 번호에 대한 특별한 처리가 있습니다.