859 lines
30 KiB
C
859 lines
30 KiB
C
/**
|
|
* SmartCard-HSM PKCS#11 Module
|
|
*
|
|
* Copyright (c) 2017, CardContact Systems GmbH, Minden, Germany
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of CardContact Systems GmbH nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL CardContact Systems GmbH BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* @file opensc-minidriver-test.c
|
|
* @author Andreas Schwier
|
|
* @brief Test framework for the CSP minidriver implementation
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <time.h>
|
|
|
|
static int testscompleted = 0;
|
|
static int testsfailed = 0;
|
|
static char *reader = NULL;
|
|
|
|
|
|
#include <windows.h>
|
|
#include <malloc.h>
|
|
#include <cardmod.h>
|
|
|
|
|
|
|
|
char *SystemErrorMsg(DWORD rc)
|
|
{
|
|
char *msg = "UNKNOWN";
|
|
|
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, 0, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0)) {
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle("crypt32.dll"), rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
}
|
|
return msg;
|
|
}
|
|
|
|
|
|
|
|
char *NTSTATUSErrorMsg(NTSTATUS nts)
|
|
{
|
|
char *msg = "UNKNOWN";
|
|
|
|
HMODULE hmod = GetModuleHandle("ntdll.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, nts, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
return msg;
|
|
}
|
|
|
|
|
|
|
|
char *SECURITY_STATUSErrorMsg(SECURITY_STATUS secstat)
|
|
{
|
|
char *msg = "UNKNOWN";
|
|
|
|
HMODULE hmod = GetModuleHandle("crypt32.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, secstat, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
return msg;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
char *ErrorMsg(DWORD rc)
|
|
{
|
|
char *msg = "UNKNOWN";
|
|
HMODULE hmod;
|
|
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, 0, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("bcrypt.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("ncrypt.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("crypt32.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("ntdll.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("kernel32.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("KernelBase.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("msvcrt.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
hmod = GetModuleHandle("cryptbase.dll");
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, hmod, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
|
|
|
return msg;
|
|
}
|
|
*/
|
|
|
|
|
|
static char *verdict(int condition) {
|
|
testscompleted++;
|
|
|
|
if (condition) {
|
|
return "Passed";
|
|
} else {
|
|
testsfailed++;
|
|
return "Failed";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
LPVOID WINAPI CSP_ALLOC(__in SIZE_T Size) {
|
|
return calloc(1, Size);
|
|
}
|
|
|
|
|
|
|
|
LPVOID WINAPI CSP_REALLOC(__in LPVOID Address, __in SIZE_T Size) {
|
|
return realloc(Address, Size);
|
|
}
|
|
|
|
|
|
|
|
void WINAPI CSP_FREE(__in LPVOID Address) {
|
|
free(Address);
|
|
}
|
|
|
|
|
|
|
|
int testSignRSA(NCRYPT_KEY_HANDLE hKey, DWORD padding, LPCWSTR hashAlg )
|
|
{
|
|
BCRYPT_KEY_HANDLE hPubKey;
|
|
SECURITY_STATUS secstat;
|
|
BCRYPT_PKCS1_PADDING_INFO p1padinfo;
|
|
BCRYPT_PSS_PADDING_INFO psspadinfo;
|
|
BCRYPT_ALG_HANDLE hSignAlg;
|
|
void *paddingInfo;
|
|
PCCERT_CONTEXT certctx;
|
|
NTSTATUS ntstat;
|
|
unsigned char cert[4096],hash[64],signature[256],pubkeyblob[1024];
|
|
DWORD dwrc,dwlen,hashlen;
|
|
|
|
printf(" RSA signing with %S and %s padding", hashAlg, (padding == BCRYPT_PAD_PKCS1 ? "V1.5" : "PSS"));
|
|
|
|
memset(hash, 0xA5, sizeof(hash));
|
|
hashlen = sizeof(hash);
|
|
|
|
if (!wcscmp(hashAlg, BCRYPT_SHA1_ALGORITHM)) {
|
|
hashlen = 20;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_SHA256_ALGORITHM)) {
|
|
hashlen = 32;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_SHA384_ALGORITHM)) {
|
|
hashlen = 48;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_SHA512_ALGORITHM)) {
|
|
hashlen = 64;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_MD5_ALGORITHM)) {
|
|
hashlen = 16;
|
|
}
|
|
|
|
if (padding == BCRYPT_PAD_PKCS1) {
|
|
memset(&p1padinfo, 0, sizeof(p1padinfo));
|
|
p1padinfo.pszAlgId = hashAlg;
|
|
paddingInfo = &p1padinfo;
|
|
} else {
|
|
memset(&psspadinfo, 0, sizeof(psspadinfo));
|
|
psspadinfo.pszAlgId = hashAlg;
|
|
psspadinfo.cbSalt = hashlen;
|
|
paddingInfo = &psspadinfo;
|
|
}
|
|
|
|
// Export public key from smart card
|
|
secstat = NCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, 0, pubkeyblob, sizeof(pubkeyblob), &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptExportKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptOpenAlgorithmProvider failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptImportKeyPair(hSignAlg, 0, BCRYPT_RSAPUBLIC_BLOB, &hPubKey, pubkeyblob, dwlen, 0);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptImportKeyPair failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
secstat = NCryptSignHash(hKey, paddingInfo, hash, hashlen, signature, sizeof(signature), &dwlen, padding);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptSignHash failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptVerifySignature(hPubKey, paddingInfo, hash, hashlen, signature, dwlen, padding);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptVerifySignature failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
BCryptDestroyKey(hPubKey);
|
|
|
|
// Verify with certificate
|
|
// Get certificate for key
|
|
secstat = NCryptGetProperty(hKey, NCRYPT_CERTIFICATE_PROPERTY, cert, sizeof(cert), &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptGetProperty failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
certctx = CertCreateCertificateContext(X509_ASN_ENCODING, cert, dwlen);
|
|
|
|
if (certctx == NULL) {
|
|
dwrc = GetLastError();
|
|
printf("\nCertCreateCertificateContext failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc));
|
|
return -1;
|
|
}
|
|
|
|
if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &certctx->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &hPubKey)) {
|
|
dwrc = GetLastError();
|
|
printf("\nCryptImportPublicKeyInfoEx2 failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc));
|
|
return -1;
|
|
}
|
|
|
|
secstat = NCryptSignHash(hKey, paddingInfo, hash, hashlen, signature, sizeof(signature), &dwlen, padding);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptSignHash failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptVerifySignature(hPubKey, paddingInfo, hash, hashlen, signature, dwlen, padding);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptVerifySignature failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
BCryptDestroyKey(hPubKey);
|
|
CertFreeCertificateContext(certctx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int testSignECDSA(NCRYPT_KEY_HANDLE hKey, LPCWSTR hashAlg )
|
|
{
|
|
BCRYPT_KEY_HANDLE hPubKey;
|
|
SECURITY_STATUS secstat;
|
|
PCCERT_CONTEXT certctx;
|
|
// BCRYPT_ALG_HANDLE hSignAlg;
|
|
NTSTATUS ntstat;
|
|
unsigned char cert[4096],hash[64],signature[256]; // ,pubkeyblob[1024];
|
|
DWORD dwrc,dwlen,hashlen;
|
|
|
|
printf(" ECDSA with %S", hashAlg);
|
|
|
|
memset(hash, 0xA5, sizeof(hash));
|
|
hashlen = sizeof(hash);
|
|
|
|
if (!wcscmp(hashAlg, BCRYPT_SHA1_ALGORITHM)) {
|
|
hashlen = 20;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_SHA256_ALGORITHM)) {
|
|
hashlen = 32;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_SHA384_ALGORITHM)) {
|
|
hashlen = 48;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_SHA512_ALGORITHM)) {
|
|
hashlen = 64;
|
|
} else if (!wcscmp(hashAlg, BCRYPT_MD5_ALGORITHM)) {
|
|
hashlen = 16;
|
|
}
|
|
|
|
#if 0
|
|
// Export public key from smart card
|
|
secstat = NCryptExportKey(hKey, 0, BCRYPT_ECCPUBLIC_BLOB, 0, pubkeyblob, sizeof(pubkeyblob), &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptExportKey failed: %08lx %s\n", ntstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptOpenAlgorithmProvider failed: %ld\n", ntstat);
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptImportKeyPair(hSignAlg, 0, BCRYPT_ECCPUBLIC_BLOB, &hPubKey, pubkeyblob, dwlen, 0);
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptImportKeyPair failed: %ld\n", ntstat);
|
|
return -1;
|
|
}
|
|
|
|
secstat = NCryptSignHash(hKey, NULL, hash, hashlen, signature, dwlen, &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptSignHash failed: %08lx %s\n", ntstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptVerifySignature(hPubKey, NULL, hash, hashlen, signature, dwlen, 0);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptVerifySignature failed: %ld\n", ntstat);
|
|
return -1;
|
|
}
|
|
|
|
BCryptDestroyKey(hPubKey);
|
|
#endif
|
|
|
|
// Get certificate for key
|
|
secstat = NCryptGetProperty(hKey, NCRYPT_CERTIFICATE_PROPERTY, cert, sizeof(cert), &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptGetProperty failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
certctx = CertCreateCertificateContext(X509_ASN_ENCODING, cert, dwlen);
|
|
|
|
if (certctx == NULL) {
|
|
dwrc = GetLastError();
|
|
printf("\nCertCreateCertificateContext failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc));
|
|
return -1;
|
|
}
|
|
|
|
if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &certctx->pCertInfo->SubjectPublicKeyInfo, 0, NULL, &hPubKey)) {
|
|
dwrc = GetLastError();
|
|
printf("\nCryptImportPublicKeyInfoEx2 failed: %04x %s\n", dwrc, SystemErrorMsg(dwrc));
|
|
return -1;
|
|
}
|
|
|
|
secstat = NCryptSignHash(hKey, NULL, hash, hashlen, signature, dwlen, &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptSignHash failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptVerifySignature(hPubKey, NULL, hash, hashlen, signature, dwlen, 0);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptVerifySignature failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
BCryptDestroyKey(hPubKey);
|
|
CertFreeCertificateContext(certctx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int testDecryptRSA(NCRYPT_KEY_HANDLE hKey, DWORD padding )
|
|
{
|
|
BCRYPT_KEY_HANDLE hPubKey;
|
|
SECURITY_STATUS secstat;
|
|
BCRYPT_OAEP_PADDING_INFO oaeppadinfo;
|
|
BCRYPT_ALG_HANDLE hSignAlg;
|
|
void *paddingInfo;
|
|
NTSTATUS ntstat;
|
|
unsigned char secret[48],plain[256],cryptogram[256],pubkeyblob[1024];
|
|
DWORD dwlen,secretlen;
|
|
|
|
printf(" RSA decryption with %s padding", (padding == BCRYPT_PAD_PKCS1 ? "V1.5" : "OAEP"));
|
|
|
|
memset(secret, 0xA5, sizeof(secret));
|
|
secret[0] = 0x5A;
|
|
secretlen = sizeof(secret);
|
|
|
|
if (padding == BCRYPT_PAD_PKCS1) {
|
|
paddingInfo = NULL;
|
|
} else {
|
|
memset(&oaeppadinfo, 0, sizeof(oaeppadinfo));
|
|
oaeppadinfo.pszAlgId = BCRYPT_SHA256_ALGORITHM;
|
|
paddingInfo = &oaeppadinfo;
|
|
}
|
|
|
|
// Export public key from smart card
|
|
secstat = NCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, 0, pubkeyblob, sizeof(pubkeyblob), &dwlen, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptExportKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptOpenAlgorithmProvider failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptImportKeyPair(hSignAlg, 0, BCRYPT_RSAPUBLIC_BLOB, &hPubKey, pubkeyblob, dwlen, 0);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptImportKeyPair failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
ntstat = BCryptEncrypt(hPubKey, secret, secretlen, paddingInfo, NULL, 0, cryptogram, sizeof(cryptogram), &dwlen, padding);
|
|
|
|
if (ntstat != ERROR_SUCCESS) {
|
|
printf("\nBCryptEncrypt failed: %08lx %s", ntstat, NTSTATUSErrorMsg(ntstat));
|
|
return -1;
|
|
}
|
|
|
|
secstat = NCryptDecrypt(hKey, cryptogram, dwlen, paddingInfo, plain, sizeof(plain), &dwlen, padding);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("\nNCryptExportKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
BCryptDestroyKey(hPubKey);
|
|
|
|
if ((secretlen != dwlen) || memcmp(plain, secret, secretlen)) {
|
|
printf("\nDecrypted data does not match plain data\n");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int cryptoTests()
|
|
|
|
{
|
|
NCRYPT_PROV_HANDLE hProvider;
|
|
NCRYPT_KEY_HANDLE hKey;
|
|
NCryptKeyName *keyName;
|
|
PVOID enumState = NULL;
|
|
SECURITY_STATUS secstat;
|
|
NCryptAlgorithmName *algos;
|
|
DWORD dwlen, dwi;
|
|
int rc;
|
|
|
|
secstat = NCryptOpenStorageProvider(&hProvider, MS_SMART_CARD_KEY_STORAGE_PROVIDER, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("NCryptOpenStorageProvider failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
secstat = NCryptEnumAlgorithms(hProvider, NCRYPT_CIPHER_OPERATION|NCRYPT_HASH_OPERATION|NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION|NCRYPT_SECRET_AGREEMENT_OPERATION, &dwlen, &algos, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("NCryptEnumAlgorithms failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
for (dwi = 0; dwi < dwlen; dwi++) {
|
|
printf("%S %lx %lx %lx\n", (algos + dwi)->pszName, (algos + dwi)->dwClass, (algos + dwi)->dwAlgOperations, (algos + dwi)->dwFlags);
|
|
}
|
|
|
|
NCryptFreeBuffer(algos);
|
|
|
|
while (TRUE) {
|
|
secstat = NCryptEnumKeys(hProvider, NULL, &keyName, &enumState, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
printf("%S (%S)\n", keyName->pszName, keyName->pszAlgid);
|
|
|
|
secstat = NCryptOpenKey(hProvider, &hKey, keyName->pszName, 0, 0);
|
|
|
|
if (secstat != ERROR_SUCCESS) {
|
|
printf("NCryptOpenKey failed: %08lx %s\n", secstat, SECURITY_STATUSErrorMsg(secstat));
|
|
return -1;
|
|
}
|
|
|
|
if ((keyName->dwLegacyKeySpec == AT_KEYEXCHANGE) || (keyName->dwLegacyKeySpec == AT_SIGNATURE)) {
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA1_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA256_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA384_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_SHA512_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PKCS1, BCRYPT_MD5_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PSS, BCRYPT_SHA1_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignRSA(hKey, BCRYPT_PAD_PSS, BCRYPT_SHA256_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testDecryptRSA(hKey, BCRYPT_PAD_PKCS1 );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testDecryptRSA(hKey, BCRYPT_PAD_OAEP );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
} else {
|
|
rc = testSignECDSA(hKey, BCRYPT_SHA1_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignECDSA(hKey, BCRYPT_SHA256_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignECDSA(hKey, BCRYPT_SHA384_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignECDSA(hKey, BCRYPT_SHA512_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
|
|
rc = testSignECDSA(hKey, BCRYPT_MD5_ALGORITHM );
|
|
printf(" - %s\n", verdict(rc == 0));
|
|
}
|
|
|
|
NCryptFreeObject(hKey);
|
|
}
|
|
|
|
NCryptFreeObject(hProvider);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int listReaders()
|
|
{
|
|
SCARDCONTEXT hSCardCtx;
|
|
DWORD cch = 0;
|
|
LPTSTR readers = NULL;
|
|
|
|
if (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hSCardCtx) != SCARD_S_SUCCESS) {
|
|
printf("SCardEstablishContext() failed\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (SCardListReaders(hSCardCtx, NULL, NULL, &cch) != SCARD_S_SUCCESS) {
|
|
printf("SCardListReaders() failed\n");
|
|
exit(1);
|
|
}
|
|
|
|
readers = malloc(cch);
|
|
reader = readers;
|
|
|
|
if (SCardListReaders(hSCardCtx, NULL, readers, &cch) != SCARD_S_SUCCESS) {
|
|
printf("SCardListReaders() failed\n");
|
|
exit(1);
|
|
}
|
|
|
|
while(*readers) {
|
|
printf("%s\n", readers);
|
|
readers += strlen(readers) + 1;
|
|
}
|
|
|
|
SCardReleaseContext(hSCardCtx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int apiTests(char *reader)
|
|
{
|
|
HMODULE dlhandle;
|
|
PFN_CARD_ACQUIRE_CONTEXT pcac;
|
|
CARD_FREE_SPACE_INFO cardFreeSpaceInfo;
|
|
CARD_CAPABILITIES cardCapabilities;
|
|
CARD_DATA cardData;
|
|
CARD_KEY_SIZES keySizes;
|
|
CARD_FILE_INFO fileInfo;
|
|
CONTAINER_INFO containerInfo;
|
|
PIN_INFO pinInfo;
|
|
LPSTR filenames;
|
|
PBYTE pb;
|
|
DWORD readernamelen, state, protocol, atrlen;
|
|
unsigned char atr[36], cardid[16];
|
|
DWORD dwrc,dwlen,dwparam;
|
|
BOOL flag;
|
|
char *pinEnv = getenv("MINIDRIVER_PIN");
|
|
|
|
if (pinEnv)
|
|
printf("Running tests using PIN=%s/len=%zd\n", pinEnv, strlen(pinEnv));
|
|
else
|
|
printf("Running tests wihtout any PIN\n");
|
|
memset(&cardData, 0, sizeof(cardData));
|
|
cardData.dwVersion = 7;
|
|
cardData.pwszCardName = L"TestCard";
|
|
|
|
cardData.pfnCspAlloc = CSP_ALLOC;
|
|
cardData.pfnCspReAlloc = CSP_REALLOC;
|
|
cardData.pfnCspFree = CSP_FREE;
|
|
|
|
if (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &cardData.hSCardCtx) != SCARD_S_SUCCESS) {
|
|
printf("SCardEstablishContext() failed\n");
|
|
exit(1);
|
|
}
|
|
|
|
dlhandle = LoadLibrary("opensc-minidriver.dll");
|
|
|
|
if (!dlhandle) {
|
|
dwrc = GetLastError();
|
|
printf("LoadLibrary failed %04x %s\n", dwrc, SystemErrorMsg(dwrc));
|
|
exit(1);
|
|
}
|
|
|
|
pcac = (PFN_CARD_ACQUIRE_CONTEXT)GetProcAddress(dlhandle, "CardAcquireContext");
|
|
|
|
readernamelen = 0;
|
|
atrlen = sizeof(atr);
|
|
|
|
if (SCardConnect(cardData.hSCardCtx, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &cardData.hScard, &protocol) != SCARD_S_SUCCESS) {
|
|
printf("SCardStatus() failed\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (SCardStatus(cardData.hScard, NULL, &readernamelen, &state, &protocol, atr, &atrlen) != SCARD_S_SUCCESS) {
|
|
printf("SCardStatus() failed\n");
|
|
exit(1);
|
|
}
|
|
|
|
cardData.pbAtr = atr;
|
|
cardData.cbAtr = atrlen;
|
|
|
|
printf("Calling CardAcquireContext()");
|
|
dwrc = (*pcac)(&cardData, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardQueryFreeSpace()");
|
|
cardFreeSpaceInfo.dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardQueryFreeSpace)(&cardData, 0, &cardFreeSpaceInfo);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_FREE_SPACE)");
|
|
cardFreeSpaceInfo.dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_FREE_SPACE, (PBYTE)&cardFreeSpaceInfo, sizeof(cardFreeSpaceInfo), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardQueryCapabilities()");
|
|
cardCapabilities.dwVersion = CARD_CAPABILITIES_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardQueryCapabilities)(&cardData, &cardCapabilities);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_CAPABILITIES)");
|
|
cardCapabilities.dwVersion = CARD_CAPABILITIES_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_CAPABILITIES, (PBYTE)&cardCapabilities, sizeof(cardCapabilities), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardQueryKeySizes()");
|
|
keySizes.dwVersion = CARD_KEY_SIZES_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardQueryKeySizes)(&cardData, AT_SIGNATURE, 0, &keySizes);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_KEYSIZES)");
|
|
keySizes.dwVersion = CARD_KEY_SIZES_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_KEYSIZES, (PBYTE)&keySizes, sizeof(keySizes), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_READ_ONLY)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_READ_ONLY, (PBYTE)&flag, sizeof(flag), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && flag));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_CACHE_MODE)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_CACHE_MODE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CP_CACHE_MODE_NO_CACHE)));
|
|
|
|
printf("Calling CardGetProperty(CP_SUPPORTS_WIN_X509_ENROLLMENT)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_SUPPORTS_WIN_X509_ENROLLMENT, (PBYTE)&flag, sizeof(flag), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && !flag));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_GUID)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_GUID, (PBYTE)&cardid, sizeof(cardid), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_SERIAL_NO)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_SERIAL_NO, (PBYTE)&cardid, sizeof(cardid), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_PIN_INFO)");
|
|
pinInfo.dwVersion = PIN_INFO_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_PIN_INFO, (PBYTE)&pinInfo, sizeof(pinInfo), &dwlen, ROLE_USER);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_LIST_PINS)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_LIST_PINS, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (IS_PIN_SET(dwparam, ROLE_USER))));
|
|
/* let's continue the tests only for the ROLE_USER */
|
|
dwparam = 0;
|
|
SET_PIN(dwparam, ROLE_USER);
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0)));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_PIN_STRENGTH_VERIFY)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_PIN_STRENGTH_VERIFY, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, ROLE_USER);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == CARD_PIN_STRENGTH_PLAINTEXT)));
|
|
|
|
printf("Calling CardGetProperty(CP_KEY_IMPORT_SUPPORT)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_KEY_IMPORT_SUPPORT, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0)));
|
|
|
|
printf("Calling CardReadFile(cardid)");
|
|
dwrc = (*cardData.pfnCardReadFile)(&cardData, NULL, szCARD_IDENTIFIER_FILE, 0, &pb, &dwlen);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen == 16)));
|
|
|
|
printf("Calling CardReadFile(cardcf)");
|
|
dwrc = (*cardData.pfnCardReadFile)(&cardData, NULL, szCACHE_FILE, 0, &pb, &dwlen);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen == 6)));
|
|
|
|
printf("Calling CardReadFile(cardapps)");
|
|
dwrc = (*cardData.pfnCardReadFile)(&cardData, NULL, "cardapps", 0, &pb, &dwlen);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen == 8)));
|
|
|
|
printf("Calling CardReadFile(mscp/cmapfile)");
|
|
dwrc = (*cardData.pfnCardReadFile)(&cardData, szBASE_CSP_DIR, szCONTAINER_MAP_FILE, 0, &pb, &dwlen);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0)));
|
|
|
|
printf("Calling CardReadFile(mscp/msroots)");
|
|
dwrc = (*cardData.pfnCardReadFile)(&cardData, szBASE_CSP_DIR, szROOT_STORE_FILE, 0, &pb, &dwlen);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0)));
|
|
|
|
printf("Calling CardGetFileInfo(mscp/cmapfile)");
|
|
fileInfo.dwVersion = CARD_FILE_INFO_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardGetFileInfo)(&cardData, szBASE_CSP_DIR, szCONTAINER_MAP_FILE, &fileInfo);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0)));
|
|
|
|
printf("Calling CardReadFile(mscp/kxc00)");
|
|
dwrc = (*cardData.pfnCardReadFile)(&cardData, szBASE_CSP_DIR, szUSER_KEYEXCHANGE_CERT_PREFIX "00", 0, &pb, &dwlen);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0)));
|
|
|
|
printf("Calling CardEnumFiles(root)");
|
|
dwrc = (*cardData.pfnCardEnumFiles)(&cardData, NULL, &filenames, &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwlen > 0)));
|
|
|
|
printf("Calling CardGetContainerInfo(0)");
|
|
containerInfo.dwVersion = CONTAINER_INFO_CURRENT_VERSION;
|
|
dwrc = (*cardData.pfnCardGetContainerInfo)(&cardData, 0, 0, &containerInfo);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardAuthenticatePin(wszCARD_USER_USER)");
|
|
if (pinEnv) {
|
|
dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, pinEnv, (DWORD)strlen(pinEnv), &dwparam);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == -1)));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2)));
|
|
|
|
printf("Calling CardAuthenticatePin(wszCARD_USER_USER) - Wrong PIN");
|
|
dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, "3456", 4, &dwparam);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_W_WRONG_CHV) && (dwparam == 2)));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0)));
|
|
|
|
printf("Calling CardAuthenticatePin(wszCARD_USER_USER)");
|
|
dwrc = (*cardData.pfnCardAuthenticatePin)(&cardData, wszCARD_USER_USER, pinEnv, (DWORD)strlen(pinEnv), &dwparam);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == -1)));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 2)));
|
|
|
|
printf("Calling CardDeAuthenticate(wszCARD_USER_USER)");
|
|
dwrc = (*cardData.pfnCardDeauthenticate)(&cardData, wszCARD_USER_USER, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
printf("Calling CardGetProperty(CP_CARD_AUTHENTICATED_STATE)");
|
|
dwrc = (*cardData.pfnCardGetProperty)(&cardData, CP_CARD_AUTHENTICATED_STATE, (PBYTE)&dwparam, sizeof(dwparam), &dwlen, 0);
|
|
printf(" - %x : %s\n", dwrc, verdict((dwrc == SCARD_S_SUCCESS) && (dwparam == 0)));
|
|
} else {
|
|
printf(" - skip: missing set MINIDRIVER_PIN=abcd\n");
|
|
}
|
|
|
|
printf("Calling CardDeleteContext()");
|
|
dwrc = (*cardData.pfnCardDeleteContext)(&cardData);
|
|
printf(" - %x : %s\n", dwrc, verdict(dwrc == SCARD_S_SUCCESS));
|
|
|
|
SCardReleaseContext(cardData.hSCardCtx);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
if (argc == 1) {
|
|
printf("Usage: opensc-minidriver-test [-l] [-r <name>] [-a] [-c]\n");
|
|
printf(" -l list readers\n");
|
|
printf(" -r <name> define readers\n");
|
|
printf(" -a run API tests\n");
|
|
printf(" -c run crypto tests\n");
|
|
exit(1);
|
|
}
|
|
|
|
argc--;
|
|
argv++;
|
|
|
|
while (argc--) {
|
|
if (!strcmp(*argv, "-l")) {
|
|
listReaders();
|
|
} else if (!strcmp(*argv, "-r")) {
|
|
if (argc == 0) {
|
|
printf("Reader name missing in -r parameter\n");
|
|
exit(1);
|
|
}
|
|
argv++;
|
|
argc--;
|
|
reader = *argv;
|
|
} else if (!strcmp(*argv, "-a")) {
|
|
if (reader == NULL) {
|
|
printf("Need a reader name set with -r or use -l to select first reader\n");
|
|
exit(1);
|
|
}
|
|
apiTests(reader);
|
|
} else if (!strcmp(*argv, "-c")) {
|
|
cryptoTests();
|
|
} else {
|
|
printf("Unknown parameter %s\n", *argv);
|
|
}
|
|
argv++;
|
|
}
|
|
|
|
printf("Unit test finished.\n");
|
|
printf("%d tests performed.\n", testscompleted);
|
|
printf("%d tests failed.\n", testsfailed);
|
|
|
|
exit(testsfailed ? 1 : 0);
|
|
}
|