2015-04-25 21:29:03 +00:00
/*
2011-04-12 07:40:12 +00:00
* minidriver . c : OpenSC minidriver
2010-02-05 13:05:25 +00:00
*
2011-04-12 07:40:12 +00:00
* Copyright ( C ) 2009 , 2010 francois . leblanc @ cev - sa . com
2015-04-26 17:54:09 +00:00
* Copyright ( C ) 2015 vincent . letoux @ mysmartlogon . com
2010-02-05 13:05:25 +00:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/*
2011-04-12 07:40:12 +00:00
* This module requires " cardmod.h " from CNG SDK or platform SDK to build .
2010-02-05 13:05:25 +00:00
*/
2011-04-12 07:40:12 +00:00
# include "config.h"
# ifdef ENABLE_MINIDRIVER
2010-02-05 13:05:25 +00:00
# ifdef _MANAGED
# pragma managed(push, off)
# endif
2017-02-09 12:44:07 +00:00
2010-02-05 13:05:25 +00:00
# include <stdio.h>
# include <stdlib.h>
2012-05-31 14:40:36 +00:00
# include <time.h>
2010-02-05 13:05:25 +00:00
2010-03-04 08:14:36 +00:00
# include <windows.h>
2017-02-09 12:44:07 +00:00
# include <Commctrl.h>
# include "cardmod.h"
2010-03-04 08:14:36 +00:00
2017-03-14 19:39:29 +00:00
# include "common/compat_strlcpy.h"
2012-05-31 14:40:36 +00:00
# include "libopensc/asn1.h"
2011-03-25 18:19:28 +00:00
# include "libopensc/cardctl.h"
2010-03-04 08:14:36 +00:00
# include "libopensc/opensc.h"
# include "libopensc/pkcs15.h"
2010-03-09 07:41:28 +00:00
# include "libopensc/log.h"
2011-04-07 16:58:01 +00:00
# include "libopensc/internal.h"
2016-04-06 16:20:36 +00:00
# include "libopensc/aux-data.h"
2012-05-31 14:40:36 +00:00
# include "pkcs15init/pkcs15-init.h"
# ifdef ENABLE_OPENSSL
# include <openssl/opensslv.h>
# if OPENSSL_VERSION_NUMBER >= 0x10000000L
# include <openssl/pem.h>
# endif
# endif
2010-03-04 08:14:36 +00:00
2011-02-09 17:52:00 +00:00
# if defined(__MINGW32__)
# include "cardmod-mingw-compat.h"
# endif
2017-01-25 22:01:18 +00:00
# include "cardmod.h"
2015-04-19 17:51:22 +00:00
/* store the instance given at DllMain when attached to access internal resources */
HINSTANCE g_inst ;
2012-05-31 14:40:36 +00:00
# define MD_MINIMUM_VERSION_SUPPORTED 4
# define MD_CURRENT_VERSION_SUPPORTED 7
2010-02-05 13:05:25 +00:00
# define NULLSTR(a) (a == NULL ? "<NULL>" : a)
# define NULLWSTR(a) (a == NULL ? L"<NULL>" : a)
2012-05-31 14:40:36 +00:00
# define MD_MAX_KEY_CONTAINERS 12
# define MD_CARDID_SIZE 16
# define MD_UTC_TIME_LENGTH_MAX 16
# define MD_CARDCF_LENGTH (sizeof(CARD_CACHE_FILE_FORMAT))
# define MD_DATA_APPLICAITON_NAME "CSP"
# define MD_DATA_DEFAULT_CONT_LABEL "Default Key Container"
# define MD_KEY_USAGE_KEYEXCHANGE \
SC_PKCS15INIT_X509_KEY_ENCIPHERMENT | \
SC_PKCS15INIT_X509_DATA_ENCIPHERMENT | \
SC_PKCS15INIT_X509_DIGITAL_SIGNATURE
2015-09-25 20:22:29 +00:00
# define MD_KEY_USAGE_KEYEXCHANGE_ECC \
SC_PKCS15INIT_X509_KEY_AGREEMENT | \
SC_PKCS15INIT_X509_DIGITAL_SIGNATURE
2012-05-31 14:40:36 +00:00
# define MD_KEY_USAGE_SIGNATURE \
SC_PKCS15INIT_X509_DIGITAL_SIGNATURE | \
SC_PKCS15INIT_X509_KEY_CERT_SIGN | \
SC_PKCS15INIT_X509_CRL_SIGN
# define MD_KEY_ACCESS \
SC_PKCS15_PRKEY_ACCESS_SENSITIVE | \
SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE | \
SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE | \
SC_PKCS15_PRKEY_ACCESS_LOCAL
/* copied from pkcs15-cardos.c */
# define USAGE_ANY_SIGN (SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
# define USAGE_ANY_DECIPHER (SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP)
2015-09-25 20:22:29 +00:00
# define USAGE_ANY_AGREEMENT (SC_PKCS15_PRKEY_USAGE_DERIVE)
2012-05-31 14:40:36 +00:00
2010-02-17 07:51:52 +00:00
/* if use of internal-winscard.h */
# ifndef SCARD_E_INVALID_PARAMETER
2012-05-31 14:40:36 +00:00
# define SCARD_E_INVALID_PARAMETER 0x80100004L
# define SCARD_E_UNSUPPORTED_FEATURE 0x80100022L
# define SCARD_E_NO_MEMORY 0x80100006L
# define SCARD_W_WRONG_CHV 0x8010006BL
# define SCARD_E_FILE_NOT_FOUND 0x80100024L
# define SCARD_E_UNKNOWN_CARD 0x8010000DL
# define SCARD_F_UNKNOWN_ERROR 0x80100014L
2010-02-17 07:51:52 +00:00
# endif
2015-04-19 17:51:22 +00:00
/* defined twice: in versioninfo-minidriver.rc.in and in minidriver.c */
2017-02-09 12:44:07 +00:00
# define IDI_SMARTCARD 102
2015-04-19 17:51:22 +00:00
2015-04-20 21:25:57 +00:00
/* magic to determine previous pinpad authentication */
# define MAGIC_SESSION_PIN "opensc-minidriver"
2015-04-19 17:51:22 +00:00
2015-10-14 20:48:41 +00:00
# define TLS1_0_PROTOCOL_VERSION 0x0301
# define TLS1_1_PROTOCOL_VERSION 0x0302
# define TLS1_2_PROTOCOL_VERSION 0x0303
# define TLS_DERIVE_KEY_SIZE 48
2012-05-31 14:40:36 +00:00
struct md_directory {
unsigned char name [ 9 ] ;
CARD_DIRECTORY_ACCESS_CONDITION acl ;
struct md_file * files ;
struct md_directory * subdirs ;
struct md_directory * next ;
} ;
struct md_file {
unsigned char name [ 9 ] ;
CARD_FILE_ACCESS_CONDITION acl ;
unsigned char * blob ;
size_t size ;
struct md_file * next ;
} ;
struct md_pkcs15_container {
int index ;
struct sc_pkcs15_id id ;
char guid [ MAX_CONTAINER_NAME_LEN + 1 ] ;
2016-04-06 16:20:36 +00:00
unsigned char flags ;
2015-04-25 21:29:03 +00:00
size_t size_key_exchange , size_sign ;
2012-05-31 14:40:36 +00:00
struct sc_pkcs15_object * cert_obj , * prkey_obj , * pubkey_obj ;
2016-04-06 16:20:36 +00:00
// BOOL guid_overwrite;
2012-05-31 14:40:36 +00:00
} ;
2015-09-25 20:22:29 +00:00
struct md_dh_agreement {
DWORD dwSize ;
PBYTE pbAgreement ;
} ;
2015-10-11 13:20:04 +00:00
struct md_guid_conversion {
CHAR szOpenSCGuid [ MAX_CONTAINER_NAME_LEN + 1 ] ;
CHAR szWindowsGuid [ MAX_CONTAINER_NAME_LEN + 1 ] ;
} ;
# define MD_MAX_CONVERSIONS 50
struct md_guid_conversion md_static_conversions [ MD_MAX_CONVERSIONS ] = { 0 } ;
2010-02-05 13:05:25 +00:00
typedef struct _VENDOR_SPECIFIC
{
2012-05-31 14:40:36 +00:00
struct sc_pkcs15_object * obj_user_pin , * obj_sopin ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
struct sc_context * ctx ;
struct sc_reader * reader ;
struct sc_card * card ;
struct sc_pkcs15_card * p15card ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
struct md_pkcs15_container p15_containers [ MD_MAX_KEY_CONTAINERS ] ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
struct md_directory root ;
2010-02-05 13:05:25 +00:00
2011-02-09 17:52:00 +00:00
SCARDCONTEXT hSCardCtx ;
SCARDHANDLE hScard ;
2013-09-24 16:07:03 +00:00
/* These will be used in CardAuthenticateEx to display a dialog box when doing
* external PIN verification .
*/
HWND hwndParent ;
LPWSTR wszPinContext ;
2015-09-25 20:22:29 +00:00
/* these will be used to store intermediate dh agreements results */
struct md_dh_agreement * dh_agreements ;
BYTE allocatedAgreements ;
2010-02-05 13:05:25 +00:00
} VENDOR_SPECIFIC ;
2012-05-31 14:40:36 +00:00
/*
2016-05-12 11:15:31 +00:00
* Windows ( ex . Vista ) may access the card from more than one thread .
* The following data type and static data is an attempt to resolve
2012-05-31 14:40:36 +00:00
* some of the encountered multi - thread issues of OpenSC
* on the minidriver side .
*
* TODO : resolve multi - thread issues on the OpenSC side
*/
2013-12-29 11:54:36 +00:00
# define MD_STATIC_FLAG_READ_ONLY 1
# define MD_STATIC_FLAG_SUPPORTS_X509_ENROLLMENT 2
# define MD_STATIC_FLAG_CONTEXT_DELETED 4
# define MD_STATIC_FLAG_GUID_AS_ID 8
# define MD_STATIC_FLAG_GUID_AS_LABEL 16
# define MD_STATIC_FLAG_CREATE_CONTAINER_KEY_IMPORT 32
# define MD_STATIC_FLAG_CREATE_CONTAINER_KEY_GEN 64
2013-12-25 22:18:29 +00:00
# define MD_STATIC_FLAG_IGNORE_PIN_LENGTH 128
2013-12-29 11:46:51 +00:00
2012-05-31 14:40:36 +00:00
# define MD_STATIC_PROCESS_ATTACHED 0xA11AC4EDL
struct md_opensc_static_data {
unsigned flags , flags_checked ;
unsigned long attach_check ;
} ;
static struct md_opensc_static_data md_static_data ;
# define C_ASN1_MD_CONTAINER_ATTRS_SIZE 7
static const struct sc_asn1_entry c_asn1_md_container_attrs [ C_ASN1_MD_CONTAINER_ATTRS_SIZE ] = {
{ " index " , SC_ASN1_INTEGER , SC_ASN1_TAG_INTEGER , 0 , NULL , NULL } ,
{ " id " , SC_ASN1_PKCS15_ID , SC_ASN1_TAG_OCTET_STRING , SC_ASN1_EMPTY_ALLOWED , NULL , NULL } ,
{ " guid " , SC_ASN1_UTF8STRING , SC_ASN1_TAG_UTF8STRING , SC_ASN1_EMPTY_ALLOWED , NULL , NULL } ,
{ " flags " , SC_ASN1_BIT_FIELD , SC_ASN1_TAG_BIT_STRING , 0 , NULL , NULL } ,
{ " sizeKeyExchange " , SC_ASN1_INTEGER , SC_ASN1_TAG_INTEGER , 0 , NULL , NULL } ,
{ " sizeSign " , SC_ASN1_INTEGER , SC_ASN1_TAG_INTEGER , 0 , NULL , NULL } ,
{ NULL , 0 , 0 , 0 , NULL , NULL }
} ;
# define C_ASN1_MD_CONTAINER_SIZE 2
static const struct sc_asn1_entry c_asn1_md_container [ C_ASN1_MD_CONTAINER_SIZE ] = {
{ " mdContainer " , SC_ASN1_STRUCT , SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS , 0 , NULL , NULL } ,
{ NULL , 0 , 0 , 0 , NULL , NULL }
} ;
2017-03-14 22:58:03 +00:00
static DWORD md_translate_OpenSC_to_Windows_error ( int OpenSCerror ,
DWORD dwDefaulCode ) ;
2011-02-09 17:52:00 +00:00
static int associate_card ( PCARD_DATA pCardData ) ;
static int disassociate_card ( PCARD_DATA pCardData ) ;
2012-05-31 14:40:36 +00:00
static DWORD md_pkcs15_delete_object ( PCARD_DATA pCardData , struct sc_pkcs15_object * obj ) ;
static DWORD md_fs_init ( PCARD_DATA pCardData ) ;
2011-02-09 17:52:00 +00:00
2017-03-14 19:39:29 +00:00
# if defined(_MSC_VER) && _MSC_VER < 1900
# define snprintf _snprintf
# endif
2016-09-30 21:05:17 +00:00
# if defined(__GNUC__)
static void logprintf ( PCARD_DATA pCardData , int level , const char * format , . . . )
__attribute__ ( ( format ( SC_PRINTF_FORMAT , 3 , 4 ) ) ) ;
# endif
2015-04-17 19:39:41 +00:00
static void logprintf ( PCARD_DATA pCardData , int level , _Printf_format_string_ const char * format , . . . )
2010-02-05 13:05:25 +00:00
{
va_list arg ;
2010-02-17 07:51:52 +00:00
VENDOR_SPECIFIC * vs ;
2011-04-12 07:40:12 +00:00
/* Use a simplied log to get all messages including messages
2011-02-09 17:52:00 +00:00
* before opensc is loaded . The file must be modifiable by all
2011-04-12 07:40:12 +00:00
* users as we maybe called under lsa or user . Note data from
2011-02-09 17:52:00 +00:00
* multiple process and threads may get intermingled .
* flush to get last message before ann crash
* close so as the file is not left open during any wait .
*/
2016-04-13 12:28:06 +00:00
DWORD md_debug = 0 ;
2016-06-05 01:04:20 +00:00
size_t sz = sizeof ( md_debug ) ;
2016-04-13 12:28:06 +00:00
int rv ;
2011-02-09 17:52:00 +00:00
2016-04-13 12:28:06 +00:00
rv = sc_ctx_win32_get_config_value ( " CARDMOD_LOW_LEVEL_DEBUG " ,
" MiniDriverDebug " , " Software \\ OpenSC Project \\ OpenSC " ,
( char * ) ( & md_debug ) , & sz ) ;
if ( rv = = SC_SUCCESS & & md_debug ! = 0 ) {
FILE * lldebugfp = fopen ( " C: \\ tmp \\ md.log " , " a+ " ) ;
2012-05-31 14:40:36 +00:00
if ( lldebugfp ) {
2011-02-09 17:52:00 +00:00
va_start ( arg , format ) ;
vfprintf ( lldebugfp , format , arg ) ;
va_end ( arg ) ;
fflush ( lldebugfp ) ;
fclose ( lldebugfp ) ;
}
}
2010-02-17 07:51:52 +00:00
va_start ( arg , format ) ;
2012-05-31 14:40:36 +00:00
if ( pCardData ! = NULL ) {
2010-02-17 07:51:52 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2016-08-23 16:56:45 +00:00
if ( vs ! = NULL & & vs - > ctx ! = NULL )
2011-05-08 08:07:03 +00:00
sc_do_log_noframe ( vs - > ctx , level , format , arg ) ;
2010-02-05 13:05:25 +00:00
}
2010-02-17 07:51:52 +00:00
va_end ( arg ) ;
2011-04-12 07:40:12 +00:00
}
2010-02-05 13:05:25 +00:00
2015-04-25 21:29:03 +00:00
static void loghex ( PCARD_DATA pCardData , int level , PBYTE data , size_t len )
2011-02-09 17:52:00 +00:00
{
char line [ 74 ] ;
char * c ;
2015-10-10 17:01:14 +00:00
unsigned int i , a ;
2011-02-09 17:52:00 +00:00
unsigned char * p ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , level , " --- %p:% " SC_FORMAT_LEN_SIZE_T " u \n " ,
data , len ) ;
2011-02-09 17:52:00 +00:00
if ( data = = NULL | | len < = 0 ) return ;
p = data ;
c = line ;
i = 0 ;
a = 0 ;
memset ( line , 0 , sizeof ( line ) ) ;
while ( i < len ) {
2017-03-14 19:39:29 +00:00
snprintf ( c , sizeof ( line ) - ( size_t ) ( c - line ) , " %02X " , * p ) ;
line [ sizeof ( line ) - 1 ] = 0 ;
2011-02-09 17:52:00 +00:00
p + + ;
c + = 2 ;
i + + ;
if ( i % 32 = = 0 ) {
logprintf ( pCardData , level , " %04X %s \n " , a , line ) ;
a + = 32 ;
memset ( line , 0 , sizeof ( line ) ) ;
c = line ;
} else {
if ( i % 4 = = 0 ) * ( c + + ) = ' ' ;
if ( i % 16 = = 0 ) * ( c + + ) = ' ' ;
}
}
if ( i % 32 ! = 0 )
logprintf ( pCardData , level , " %04X %s \n " , a , line ) ;
2011-04-12 07:40:12 +00:00
}
2011-02-09 17:52:00 +00:00
/*
2011-04-12 07:40:12 +00:00
* check if the card has been removed , or the
2011-02-09 17:52:00 +00:00
* caller has changed the handles .
* if so , then free up all previous card info
* and reestablish
*/
2012-05-31 14:40:36 +00:00
static int
check_reader_status ( PCARD_DATA pCardData )
{
2015-05-08 13:49:30 +00:00
int r = SCARD_S_SUCCESS ;
2011-02-09 17:52:00 +00:00
VENDOR_SPECIFIC * vs = NULL ;
logprintf ( pCardData , 4 , " check_reader_status \n " ) ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
if ( ! vs )
return SCARD_E_INVALID_PARAMETER ;
logprintf ( pCardData , 7 , " pCardData->hSCardCtx:0x%08X hScard:0x%08X \n " ,
2017-03-14 21:56:39 +00:00
( unsigned int ) pCardData - > hSCardCtx ,
( unsigned int ) pCardData - > hScard ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( pCardData - > hSCardCtx ! = vs - > hSCardCtx | | pCardData - > hScard ! = vs - > hScard ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " HANDLES CHANGED from 0x%08X 0x%08X \n " ,
( unsigned int ) vs - > hSCardCtx ,
( unsigned int ) vs - > hScard ) ;
2011-02-09 17:52:00 +00:00
2015-03-28 12:04:41 +00:00
/* Basically a mini AcquireContext */
2012-05-31 14:40:36 +00:00
r = disassociate_card ( pCardData ) ;
logprintf ( pCardData , 1 , " disassociate_card r = 0x%08X \n " , r ) ;
r = associate_card ( pCardData ) ; /* need to check return codes */
2015-05-08 13:49:30 +00:00
if ( r ! = SCARD_S_SUCCESS )
return r ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " associate_card r = 0x%08X \n " , r ) ;
2015-03-28 12:04:41 +00:00
/* Rebuild 'soft' fs - in case changed */
2012-05-31 14:40:36 +00:00
r = md_fs_init ( pCardData ) ;
logprintf ( pCardData , 1 , " md_fs_init r = 0x%08X \n " , r ) ;
}
else if ( vs - > reader ) {
/* This should always work, as BaseCSP should be checking for removal too */
2011-02-09 17:52:00 +00:00
r = sc_detect_card_presence ( vs - > reader ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" check_reader_status r=%d flags 0x%08X \n " , r ,
( unsigned int ) vs - > reader - > flags ) ;
2011-02-09 17:52:00 +00:00
}
2012-05-31 14:40:36 +00:00
2015-05-08 13:49:30 +00:00
return r ;
2011-02-09 17:52:00 +00:00
}
2012-05-31 14:40:36 +00:00
static DWORD
md_get_pin_by_role ( PCARD_DATA pCardData , PIN_ID role , struct sc_pkcs15_object * * ret_obj )
{
VENDOR_SPECIFIC * vs ;
int rv = SC_SUCCESS ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
if ( ! ret_obj )
return SCARD_E_INVALID_PARAMETER ;
* ret_obj = NULL ;
if ( role = = ROLE_USER ) {
if ( ! vs - > obj_user_pin ) {
/* Get 'global' User PIN; if no, get the 'local' one */
rv = sc_pkcs15_find_pin_by_flags ( vs - > p15card , SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL ,
SC_PKCS15_PIN_TYPE_FLAGS_MASK , NULL , & vs - > obj_user_pin ) ;
if ( rv )
rv = sc_pkcs15_find_pin_by_flags ( vs - > p15card , SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL ,
SC_PKCS15_PIN_TYPE_FLAGS_MASK , NULL , & vs - > obj_user_pin ) ;
}
* ret_obj = vs - > obj_user_pin ;
}
else if ( role = = ROLE_ADMIN ) {
/* Get SO PIN; if no, get the 'global' PUK; if no get the 'local' one */
if ( ! vs - > obj_sopin ) {
rv = sc_pkcs15_find_pin_by_flags ( vs - > p15card , SC_PKCS15_PIN_TYPE_FLAGS_SOPIN ,
SC_PKCS15_PIN_TYPE_FLAGS_SOPIN , NULL , & vs - > obj_sopin ) ;
if ( rv )
rv = sc_pkcs15_find_pin_by_flags ( vs - > p15card , SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL ,
SC_PKCS15_PIN_TYPE_FLAGS_MASK , NULL , & vs - > obj_sopin ) ;
if ( rv )
rv = sc_pkcs15_find_pin_by_flags ( vs - > p15card , SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL ,
SC_PKCS15_PIN_TYPE_FLAGS_MASK , NULL , & vs - > obj_sopin ) ;
}
* ret_obj = vs - > obj_sopin ;
}
else {
logprintf ( pCardData , 2 , " cannot get PIN object: unsupported role \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
return ( rv = = SC_SUCCESS ) ? SCARD_S_SUCCESS : SCARD_E_UNSUPPORTED_FEATURE ;
}
static BOOL
2013-12-29 11:53:41 +00:00
md_get_config_bool ( PCARD_DATA pCardData , char * flag_name , unsigned flag , BOOL ret_default )
2012-05-31 14:40:36 +00:00
{
VENDOR_SPECIFIC * vs ;
2013-12-29 11:53:41 +00:00
BOOL ret = ret_default ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
2013-12-29 11:53:41 +00:00
return ret ;
logprintf ( pCardData , 2 , " Get '%s' option \n " , flag_name ) ;
if ( md_static_data . flags_checked & flag ) {
ret = ( md_static_data . flags & flag ) ? TRUE : FALSE ;
logprintf ( pCardData , 2 , " Returns checked flag: %s \n " , ret ? " TRUE " : " FALSE " ) ;
return ret ;
}
2015-10-11 08:39:02 +00:00
vs = ( VENDOR_SPECIFIC * ) pCardData - > pvVendorSpecific ;
2013-12-29 11:53:41 +00:00
if ( vs - > ctx & & vs - > reader ) {
2015-10-11 08:39:02 +00:00
struct sc_atr atr ;
scconf_block * atrblock ;
atr . len = pCardData - > cbAtr ;
memcpy ( atr . value , pCardData - > pbAtr , atr . len ) ;
atrblock = _sc_match_atr_block ( vs - > ctx , NULL , & atr ) ;
2013-12-29 11:53:41 +00:00
logprintf ( pCardData , 2 , " Match ATR: \n " ) ;
2015-10-11 08:39:02 +00:00
loghex ( pCardData , 3 , atr . value , atr . len ) ;
2013-12-29 11:53:41 +00:00
if ( atrblock )
ret = scconf_get_bool ( atrblock , flag_name , ret_default ) ? TRUE : FALSE ;
}
md_static_data . flags_checked | = flag ;
if ( ret = = TRUE )
md_static_data . flags | = flag ;
else
md_static_data . flags & = ~ flag ;
logprintf ( pCardData , 2 , " Returns '%s' flag '%s', static flags/checked %X/%X \n " ,
flag_name , ret ? " TRUE " : " FALSE " ,
md_static_data . flags , md_static_data . flags_checked ) ;
return ret ;
}
/* 'Write' mode can be enabled from the OpenSC configuration file*/
static BOOL
md_is_read_only ( PCARD_DATA pCardData )
{
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 2 , " Is read-only? \n " ) ;
2013-12-29 11:54:36 +00:00
return md_get_config_bool ( pCardData , " md_read_only " , MD_STATIC_FLAG_READ_ONLY , TRUE ) ;
2012-05-31 14:40:36 +00:00
}
2013-12-29 11:53:41 +00:00
2012-05-31 14:40:36 +00:00
/* 'Write' mode can be enabled from the OpenSC configuration file*/
static BOOL
md_is_supports_X509_enrollment ( PCARD_DATA pCardData )
2010-02-05 13:05:25 +00:00
{
2015-10-11 08:39:02 +00:00
BOOL defaultvalue = ! md_is_read_only ( pCardData ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 2 , " Is supports X509 enrollment? \n " ) ;
2015-10-11 08:39:02 +00:00
return md_get_config_bool ( pCardData , " md_supports_X509_enrollment " , MD_STATIC_FLAG_SUPPORTS_X509_ENROLLMENT , defaultvalue ) ;
2010-02-05 13:05:25 +00:00
}
2013-12-29 11:46:51 +00:00
/* Get know if the GUID has to used as ID of crypto objects */
2013-12-29 11:41:36 +00:00
static BOOL
2013-12-29 11:46:51 +00:00
md_is_guid_as_id ( PCARD_DATA pCardData )
2013-12-29 11:41:36 +00:00
{
logprintf ( pCardData , 2 , " Is GUID has to be used as ID of crypto objects? \n " ) ;
2013-12-29 11:54:36 +00:00
return md_get_config_bool ( pCardData , " md_guid_as_id " , MD_STATIC_FLAG_GUID_AS_ID , FALSE ) ;
2013-12-29 11:41:36 +00:00
}
2013-12-29 11:46:51 +00:00
/* Get know if the GUID has to used as label of crypto objects */
static BOOL
md_is_guid_as_label ( PCARD_DATA pCardData )
{
logprintf ( pCardData , 2 , " Is GUID has to be used as label of crypto objects? \n " ) ;
2013-12-29 11:54:36 +00:00
return md_get_config_bool ( pCardData , " md_guid_as_label " , MD_STATIC_FLAG_GUID_AS_LABEL , FALSE ) ;
2013-12-29 11:46:51 +00:00
}
2013-12-29 11:53:41 +00:00
/* Get know if disabled CARD_CREATE_CONTAINER_KEY_GEN mechanism */
static BOOL
md_is_supports_container_key_gen ( PCARD_DATA pCardData )
{
logprintf ( pCardData , 2 , " Is supports 'key generation' create_container mechanism? \n " ) ;
2013-12-29 11:54:36 +00:00
return md_get_config_bool ( pCardData , " md_supports_container_key_gen " , MD_STATIC_FLAG_CREATE_CONTAINER_KEY_GEN , TRUE ) ;
2013-12-29 11:53:41 +00:00
}
/* Get know if disabled CARD_CREATE_CONTAINER_KEY_IMPORT mechanism */
static BOOL
md_is_supports_container_key_import ( PCARD_DATA pCardData )
{
logprintf ( pCardData , 2 , " Is supports 'key import' create container mechanism? \n " ) ;
2013-12-29 11:54:36 +00:00
return md_get_config_bool ( pCardData , " md_supports_container_key_import " , MD_STATIC_FLAG_CREATE_CONTAINER_KEY_IMPORT , TRUE ) ;
2013-12-29 11:53:41 +00:00
}
2015-10-10 13:39:27 +00:00
/* generate unique key label (GUID)*/
static VOID md_generate_guid ( __in_ecount ( MAX_CONTAINER_NAME_LEN + 1 ) PSTR szGuid ) {
RPC_CSTR szRPCGuid = NULL ;
GUID Label = { 0 } ;
UuidCreate ( & Label ) ;
2017-03-14 19:39:29 +00:00
if ( UuidToStringA ( & Label , & szRPCGuid ) = = RPC_S_OK & & szRPCGuid ) {
strlcpy ( szGuid , ( PSTR ) szRPCGuid , MAX_CONTAINER_NAME_LEN + 1 ) ;
RpcStringFreeA ( & szRPCGuid ) ;
} else
szGuid [ 0 ] = 0 ;
2015-10-10 13:39:27 +00:00
}
2016-04-06 16:20:36 +00:00
static DWORD
2015-10-11 13:20:04 +00:00
md_contguid_get_guid_from_card ( PCARD_DATA pCardData , struct sc_pkcs15_object * prkey , __in_ecount ( MAX_CONTAINER_NAME_LEN + 1 ) PSTR szGuid )
{
int rv ;
VENDOR_SPECIFIC * vs ;
size_t guid_len = MAX_CONTAINER_NAME_LEN + 1 ;
2016-04-06 16:20:36 +00:00
2015-10-11 13:20:04 +00:00
vs = ( VENDOR_SPECIFIC * ) pCardData - > pvVendorSpecific ;
2016-04-08 07:53:10 +00:00
rv = sc_pkcs15_get_object_guid ( vs - > p15card , prkey , 1 , ( unsigned char * ) szGuid , & guid_len ) ;
2015-10-11 13:20:04 +00:00
if ( rv ) {
logprintf ( pCardData , 2 , " md_contguid_get_guid_from_card(): error %d \n " , rv ) ;
2016-04-06 16:20:36 +00:00
return SCARD_F_INTERNAL_ERROR ;
2015-10-11 13:20:04 +00:00
}
2016-04-06 16:20:36 +00:00
return SCARD_S_SUCCESS ;
2015-10-11 13:20:04 +00:00
}
/* add a new entry in the guid conversion table */
2016-04-06 16:20:36 +00:00
static DWORD
md_contguid_add_conversion ( PCARD_DATA pCardData , struct sc_pkcs15_object * prkey ,
__in_ecount ( MAX_CONTAINER_NAME_LEN + 1 ) PSTR szWindowsGuid )
2015-10-11 13:20:04 +00:00
{
2016-04-06 16:20:36 +00:00
DWORD ret ;
2015-10-11 13:20:04 +00:00
int i ;
CHAR szOpenSCGuid [ MAX_CONTAINER_NAME_LEN + 1 ] = " " ;
2016-04-06 16:20:36 +00:00
ret = md_contguid_get_guid_from_card ( pCardData , prkey , szOpenSCGuid ) ;
if ( ret ! = SCARD_S_SUCCESS )
return ret ;
if ( strcmp ( szOpenSCGuid , szWindowsGuid ) = = 0 )
return ret ;
2015-10-11 13:20:04 +00:00
for ( i = 0 ; i < MD_MAX_CONVERSIONS ; i + + ) {
if ( md_static_conversions [ i ] . szWindowsGuid [ 0 ] = = 0 ) {
2017-03-14 19:39:29 +00:00
strlcpy ( md_static_conversions [ i ] . szWindowsGuid ,
szWindowsGuid , MAX_CONTAINER_NAME_LEN + 1 ) ;
strlcpy ( md_static_conversions [ i ] . szOpenSCGuid ,
szOpenSCGuid , MAX_CONTAINER_NAME_LEN + 1 ) ;
2015-10-11 13:20:04 +00:00
logprintf ( pCardData , 0 , " md_contguid_add_conversion(): Registering conversion '%s' '%s' \n " , szWindowsGuid , szOpenSCGuid ) ;
2016-04-06 16:20:36 +00:00
return SCARD_S_SUCCESS ; ;
2015-10-11 13:20:04 +00:00
}
}
2016-04-06 16:20:36 +00:00
logprintf ( pCardData , 0 , " md_contguid_add_conversion(): Unable to add a new conversion with guid %s. \n " , szWindowsGuid ) ;
return SCARD_F_INTERNAL_ERROR ; ;
2015-10-11 13:20:04 +00:00
}
/* remove an entry in the guid conversion table*/
static VOID
md_contguid_delete_conversion ( PCARD_DATA pCardData , __in_ecount ( MAX_CONTAINER_NAME_LEN + 1 ) PSTR szWindowsGuid )
{
int i ;
for ( i = 0 ; i < MD_MAX_CONVERSIONS ; i + + ) {
if ( strcmp ( md_static_conversions [ i ] . szWindowsGuid , szWindowsGuid ) = = 0 ) {
memset ( md_static_conversions + i , 0 , sizeof ( struct md_guid_conversion ) ) ;
}
}
}
2015-10-10 13:39:27 +00:00
/* build key args from the minidriver guid */
static VOID
md_contguid_build_key_args_from_cont_guid ( PCARD_DATA pCardData , __in_ecount ( MAX_CONTAINER_NAME_LEN + 1 ) PSTR szGuid ,
2016-04-06 16:20:36 +00:00
struct sc_pkcs15init_prkeyargs * prkey_args )
2015-10-10 13:39:27 +00:00
{
/* strlen(szGuid) <= MAX_CONTAINER_NAME */
logprintf ( pCardData , 3 , " Using the guid '%s' \n " , szGuid ) ;
if ( szGuid [ 0 ] ! = 0 ) {
prkey_args - > guid = ( unsigned char * ) szGuid ;
prkey_args - > guid_len = strlen ( szGuid ) ;
}
if ( md_is_guid_as_id ( pCardData ) ) {
memcpy ( prkey_args - > id . value , szGuid , strlen ( szGuid ) ) ;
prkey_args - > id . len = strlen ( szGuid ) ;
}
if ( md_is_guid_as_label ( pCardData ) ) {
prkey_args - > label = szGuid ;
}
}
/* build minidriver guid from the key */
2016-04-06 16:20:36 +00:00
static DWORD
2015-10-10 13:39:27 +00:00
md_contguid_build_cont_guid_from_key ( PCARD_DATA pCardData , struct sc_pkcs15_object * key_obj , __in_ecount ( MAX_CONTAINER_NAME_LEN + 1 ) PSTR szGuid )
{
struct sc_pkcs15_prkey_info * prkey_info = ( struct sc_pkcs15_prkey_info * ) key_obj - > data ;
2016-04-06 16:20:36 +00:00
DWORD dwret = SCARD_S_SUCCESS ;
2015-10-10 13:39:27 +00:00
szGuid [ 0 ] = ' \0 ' ;
2015-10-11 13:20:04 +00:00
/* priorize the use of the key id over the key label as a container name */
if ( md_is_guid_as_id ( pCardData ) & & prkey_info - > id . len > 0 & & prkey_info - > id . len < = MAX_CONTAINER_NAME_LEN ) {
memcpy ( szGuid , prkey_info - > id . value , prkey_info - > id . len ) ;
szGuid [ prkey_info - > id . len ] = 0 ;
} else if ( md_is_guid_as_label ( pCardData ) & & key_obj - > label [ 0 ] ! = 0 ) {
2017-03-14 19:39:29 +00:00
strlcpy ( szGuid , key_obj - > label , MAX_CONTAINER_NAME_LEN + 1 ) ;
2015-10-10 13:39:27 +00:00
} else {
2016-04-06 16:20:36 +00:00
dwret = md_contguid_get_guid_from_card ( pCardData , key_obj , szGuid ) ;
2015-10-10 13:39:27 +00:00
}
2016-04-06 16:20:36 +00:00
return dwret ;
2015-10-10 13:39:27 +00:00
}
2016-04-06 16:20:36 +00:00
static DWORD
md_cont_flags_from_key ( PCARD_DATA pCardData , struct sc_pkcs15_object * key_obj , unsigned char * cont_flags )
{
struct sc_pkcs15_prkey_info * prkey_info = NULL ;
VENDOR_SPECIFIC * vs ;
int rv ;
vs = ( VENDOR_SPECIFIC * ) pCardData - > pvVendorSpecific ;
prkey_info = ( struct sc_pkcs15_prkey_info * ) key_obj - > data ;
* cont_flags = CONTAINER_MAP_VALID_CONTAINER ;
if ( prkey_info - > aux_data ) {
rv = sc_aux_data_get_md_flags ( vs - > ctx , prkey_info - > aux_data , cont_flags ) ;
if ( rv ! = SC_ERROR_NOT_SUPPORTED & & rv ! = SC_SUCCESS )
return SCARD_F_INTERNAL_ERROR ;
}
return SCARD_S_SUCCESS ;
}
2012-05-31 14:40:36 +00:00
/* Search directory by name and optionally by name of it's parent */
static DWORD
md_fs_find_directory ( PCARD_DATA pCardData , struct md_directory * parent , char * name , struct md_directory * * out )
2011-03-23 18:37:46 +00:00
{
VENDOR_SPECIFIC * vs ;
2012-05-31 14:40:36 +00:00
struct md_directory * dir = NULL ;
if ( out )
* out = NULL ;
2011-03-23 18:37:46 +00:00
2011-04-12 07:40:12 +00:00
if ( ! pCardData )
2011-03-23 18:37:46 +00:00
return SCARD_E_INVALID_PARAMETER ;
2012-05-31 14:40:36 +00:00
vs = pCardData - > pvVendorSpecific ;
if ( ! parent )
parent = & vs - > root ;
2011-03-23 18:37:46 +00:00
2012-05-31 14:40:36 +00:00
if ( ! name ) {
dir = parent ;
}
else {
dir = parent - > subdirs ;
while ( dir ) {
2015-10-06 20:47:50 +00:00
if ( strlen ( name ) > sizeof dir - > name
2017-01-25 22:27:27 +00:00
| | ! strncmp ( ( char * ) dir - > name , name , sizeof dir - > name ) )
2012-05-31 14:40:36 +00:00
break ;
dir = dir - > next ;
}
2011-03-23 18:37:46 +00:00
}
2012-05-31 14:40:36 +00:00
if ( ! dir )
return SCARD_E_DIR_NOT_FOUND ;
if ( out )
* out = dir ;
logprintf ( pCardData , 3 , " MD virtual file system: found '%s' directory \n " , name ) ;
return SCARD_S_SUCCESS ;
}
static DWORD
md_fs_add_directory ( PCARD_DATA pCardData , struct md_directory * * head , char * name ,
CARD_FILE_ACCESS_CONDITION acl ,
struct md_directory * * out )
{
struct md_directory * new_dir = NULL ;
if ( ! pCardData | | ! head | | ! name )
2011-03-23 18:37:46 +00:00
return SCARD_E_INVALID_PARAMETER ;
2012-05-31 14:40:36 +00:00
new_dir = pCardData - > pfnCspAlloc ( sizeof ( struct md_directory ) ) ;
if ( ! new_dir )
return SCARD_E_NO_MEMORY ;
memset ( new_dir , 0 , sizeof ( struct md_directory ) ) ;
2011-03-23 18:37:46 +00:00
2017-03-14 19:39:29 +00:00
strlcpy ( ( char * ) new_dir - > name , name , sizeof ( new_dir - > name ) ) ;
2012-05-31 14:40:36 +00:00
new_dir - > acl = acl ;
if ( * head = = NULL ) {
* head = new_dir ;
}
else {
2015-10-16 07:58:01 +00:00
struct md_directory * last = * head ;
while ( last - > next )
last = last - > next ;
last - > next = new_dir ;
2012-05-31 14:40:36 +00:00
}
if ( out )
* out = new_dir ;
logprintf ( pCardData , 3 , " MD virtual file system: directory '%s' added \n " , name ) ;
return SCARD_S_SUCCESS ;
}
static DWORD
md_fs_find_file ( PCARD_DATA pCardData , char * parent , char * name , struct md_file * * out )
{
struct md_file * file = NULL ;
struct md_directory * dir = NULL ;
DWORD dwret ;
if ( out )
* out = NULL ;
if ( ! pCardData | | ! name )
return SCARD_E_INVALID_PARAMETER ;
dwret = md_fs_find_directory ( pCardData , NULL , parent , & dir ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " find directory '%s' error: %lX \n " ,
parent ? parent : " <null> " , ( unsigned long ) dwret ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
}
else if ( ! dir ) {
logprintf ( pCardData , 2 , " directory '%s' not found \n " , parent ? parent : " <null> " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
for ( file = dir - > files ; file ! = NULL ; ) {
2015-10-06 20:47:50 +00:00
if ( sizeof file - > name < strlen ( name )
2017-01-25 22:27:27 +00:00
| | ! strncmp ( ( char * ) file - > name , name , sizeof file - > name ) )
2012-05-31 14:40:36 +00:00
break ;
file = file - > next ;
}
if ( ! file )
return SCARD_E_FILE_NOT_FOUND ;
if ( out )
* out = file ;
logprintf ( pCardData , 3 , " MD virtual file system: found '%s' file \n " , name ) ;
return SCARD_S_SUCCESS ;
}
static DWORD
md_fs_add_file ( PCARD_DATA pCardData , struct md_file * * head , char * name , CARD_FILE_ACCESS_CONDITION acl ,
unsigned char * blob , size_t size , struct md_file * * out )
{
struct md_file * new_file = NULL ;
if ( ! pCardData | | ! head | | ! name )
return SCARD_E_INVALID_PARAMETER ;
new_file = pCardData - > pfnCspAlloc ( sizeof ( struct md_file ) ) ;
if ( ! new_file )
return SCARD_E_NO_MEMORY ;
memset ( new_file , 0 , sizeof ( struct md_file ) ) ;
2017-03-14 19:39:29 +00:00
strlcpy ( ( char * ) new_file - > name , name , sizeof ( new_file - > name ) ) ;
2012-05-31 14:40:36 +00:00
new_file - > size = size ;
new_file - > acl = acl ;
if ( size ) {
new_file - > blob = pCardData - > pfnCspAlloc ( size ) ;
if ( ! new_file - > blob ) {
pCardData - > pfnCspFree ( new_file ) ;
return SCARD_E_NO_MEMORY ;
2011-03-23 18:37:46 +00:00
}
2012-05-31 14:40:36 +00:00
if ( blob )
CopyMemory ( new_file - > blob , blob , size ) ;
else
memset ( new_file - > blob , 0 , size ) ;
}
if ( * head = = NULL ) {
* head = new_file ;
}
else {
2015-10-16 07:58:01 +00:00
struct md_file * last = * head ;
while ( last - > next )
last = last - > next ;
last - > next = new_file ;
2012-05-31 14:40:36 +00:00
}
if ( out )
* out = new_file ;
logprintf ( pCardData , 3 , " MD virtual file system: file '%s' added \n " , name ) ;
return SCARD_S_SUCCESS ;
}
static void
md_fs_free_file ( PCARD_DATA pCardData , struct md_file * file )
{
if ( ! file )
return ;
if ( file - > blob )
pCardData - > pfnCspFree ( file - > blob ) ;
file - > blob = NULL ;
file - > size = 0 ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( file ) ;
2012-05-31 14:40:36 +00:00
}
static DWORD
md_fs_delete_file ( PCARD_DATA pCardData , char * parent , char * name )
{
VENDOR_SPECIFIC * vs ;
struct md_file * file = NULL , * file_to_rm = NULL ;
struct md_directory * dir = NULL ;
int deleted = 0 ;
DWORD dwret ;
if ( ! pCardData | | ! name )
return SCARD_E_INVALID_PARAMETER ;
vs = pCardData - > pvVendorSpecific ;
dwret = md_fs_find_directory ( pCardData , NULL , parent , & dir ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " find directory '%s' error: %lX \n " ,
parent ? parent : " <null> " , ( unsigned long ) dwret ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
}
else if ( ! dir ) {
logprintf ( pCardData , 2 , " directory '%s' not found \n " , parent ? parent : " <null> " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
else if ( ! dir - > files ) {
logprintf ( pCardData , 2 , " no files in '%s' directory \n " , parent ? parent : " <null> " ) ;
return SCARD_E_FILE_NOT_FOUND ;
}
2015-10-06 20:47:50 +00:00
if ( sizeof dir - > files - > name < strlen ( name )
2017-01-25 22:27:27 +00:00
| | ! strncmp ( ( char * ) dir - > files - > name , name , sizeof dir - > files - > name ) ) {
2012-05-31 14:40:36 +00:00
file_to_rm = dir - > files ;
dir - > files = dir - > files - > next ;
md_fs_free_file ( pCardData , file_to_rm ) ;
dwret = SCARD_S_SUCCESS ;
}
else {
for ( file = dir - > files ; file ! = NULL ; file = file - > next ) {
if ( ! file - > next )
break ;
2015-10-06 20:47:50 +00:00
if ( sizeof file - > next - > name < strlen ( name )
2017-01-25 22:27:27 +00:00
| | ! strncmp ( ( char * ) file - > next - > name , name , sizeof file - > next - > name ) ) {
2012-05-31 14:40:36 +00:00
file_to_rm = file - > next ;
file - > next = file - > next - > next ;
md_fs_free_file ( pCardData , file_to_rm ) ;
deleted = 1 ;
2011-03-23 18:37:46 +00:00
break ;
}
}
2012-05-31 14:40:36 +00:00
dwret = deleted ? SCARD_S_SUCCESS : SCARD_E_FILE_NOT_FOUND ;
}
if ( ! strcmp ( parent , " mscp " ) ) {
int idx = - 1 ;
2017-03-14 19:39:29 +00:00
if ( sscanf ( name , " ksc%d " , & idx ) > 0 ) {
2012-05-31 14:40:36 +00:00
}
2017-03-14 19:39:29 +00:00
else if ( sscanf ( name , " kxc%d " , & idx ) > 0 ) {
2012-05-31 14:40:36 +00:00
}
if ( idx > = 0 & & idx < MD_MAX_KEY_CONTAINERS ) {
dwret = md_pkcs15_delete_object ( pCardData , vs - > p15_containers [ idx ] . cert_obj ) ;
vs - > p15_containers [ idx ] . cert_obj = NULL ;
if ( dwret ! = SCARD_S_SUCCESS )
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" Cannot delete certificate PKCS#15 object #%i: dwret 0x%lX \n " ,
idx , ( unsigned long ) dwret ) ;
2012-05-31 14:40:36 +00:00
}
}
return dwret ;
}
2015-04-12 11:34:18 +00:00
static DWORD
md_fs_finalize ( PCARD_DATA pCardData )
{
VENDOR_SPECIFIC * vs ;
struct md_file * file = NULL , * file_to_rm ;
struct md_directory * dir = NULL , * dir_to_rm ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
vs = pCardData - > pvVendorSpecific ;
file = vs - > root . files ;
while ( file ! = NULL ) {
file_to_rm = file ;
file = file - > next ;
md_fs_free_file ( pCardData , file_to_rm ) ;
}
dir = vs - > root . subdirs ;
while ( dir ) {
file = dir - > files ;
while ( file ! = NULL ) {
file_to_rm = file ;
file = file - > next ;
md_fs_free_file ( pCardData , file_to_rm ) ;
}
dir_to_rm = dir ;
dir = dir - > next ;
pCardData - > pfnCspFree ( dir_to_rm ) ;
}
return 0 ;
}
2012-05-31 14:40:36 +00:00
/*
* Update ' soft ' containers .
* Called each time when ' WriteFile ' is called for ' cmapfile ' .
*/
static DWORD
md_pkcs15_update_containers ( PCARD_DATA pCardData , unsigned char * blob , size_t size )
{
VENDOR_SPECIFIC * vs ;
CONTAINER_MAP_RECORD * pp ;
int nn_records , idx ;
if ( ! pCardData | | ! blob | | size < sizeof ( CONTAINER_MAP_RECORD ) )
return SCARD_E_INVALID_PARAMETER ;
vs = pCardData - > pvVendorSpecific ;
2015-04-25 21:29:03 +00:00
nn_records = ( int ) size / sizeof ( CONTAINER_MAP_RECORD ) ;
2012-05-31 14:40:36 +00:00
if ( nn_records > MD_MAX_KEY_CONTAINERS )
nn_records = MD_MAX_KEY_CONTAINERS ;
for ( idx = 0 , pp = ( CONTAINER_MAP_RECORD * ) blob ; idx < nn_records ; idx + + , pp + + ) {
struct md_pkcs15_container * cont = & ( vs - > p15_containers [ idx ] ) ;
size_t count ;
2015-10-11 13:20:04 +00:00
CHAR szGuid [ MAX_CONTAINER_NAME_LEN + 1 ] = " " ;
2012-05-31 14:40:36 +00:00
2015-10-11 13:20:04 +00:00
count = wcstombs ( szGuid , pp - > wszGuid , sizeof ( cont - > guid ) ) ;
2012-05-31 14:40:36 +00:00
if ( ! count ) {
2015-10-11 13:20:04 +00:00
if ( cont - > guid [ 0 ] ! = 0 ) {
md_contguid_delete_conversion ( pCardData , cont - > guid ) ;
}
2012-05-31 14:40:36 +00:00
memset ( cont , 0 , sizeof ( CONTAINER_MAP_RECORD ) ) ;
}
2011-03-23 18:37:46 +00:00
else {
2017-03-14 19:39:29 +00:00
strlcpy ( cont - > guid , szGuid , MAX_CONTAINER_NAME_LEN + 1 ) ;
2012-05-31 14:40:36 +00:00
cont - > index = idx ;
cont - > flags = pp - > bFlags ;
cont - > size_sign = pp - > wSigKeySizeBits ;
cont - > size_key_exchange = pp - > wKeyExchangeKeySizeBits ;
2015-10-06 06:21:20 +00:00
logprintf ( pCardData , 3 , " update P15 containers: touch container (idx:%i,id:%s,guid:%.*s,flags:%X) \n " ,
2016-04-06 16:20:36 +00:00
idx , sc_pkcs15_print_id ( & cont - > id ) ,
( int ) sizeof cont - > guid , cont - > guid , cont - > flags ) ;
2012-05-31 14:40:36 +00:00
}
}
return SCARD_S_SUCCESS ;
}
static DWORD
md_pkcs15_delete_object ( PCARD_DATA pCardData , struct sc_pkcs15_object * obj )
{
VENDOR_SPECIFIC * vs ;
struct sc_profile * profile = NULL ;
struct sc_card * card = NULL ;
struct sc_app_info * app_info = NULL ;
DWORD dwret = SCARD_F_INTERNAL_ERROR ;
int rv ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
vs = pCardData - > pvVendorSpecific ;
card = vs - > p15card - > card ;
if ( ! obj )
return SCARD_S_SUCCESS ;
2015-10-04 15:33:14 +00:00
logprintf ( pCardData , 3 , " MdDeleteObject('%.*s',type:0x%X) called \n " , ( int ) sizeof obj - > label , obj - > label , obj - > type ) ;
2012-05-31 14:40:36 +00:00
rv = sc_lock ( card ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdDeleteObject(): cannot lock card \n " ) ;
return SCARD_F_INTERNAL_ERROR ;
}
app_info = vs - > p15card - > app ;
2015-09-30 20:47:16 +00:00
rv = sc_pkcs15init_bind ( card , " pkcs15 " , NULL , NULL , & profile ) ;
2012-05-31 14:40:36 +00:00
if ( rv ) {
logprintf ( pCardData , 3 , " MdDeleteObject(): PKCS#15 bind failed \n " ) ;
sc_unlock ( card ) ;
return SCARD_F_INTERNAL_ERROR ;
}
rv = sc_pkcs15init_finalize_profile ( card , profile , app_info ? & app_info - > aid : NULL ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdDeleteObject(): cannot finalize profile \n " ) ;
goto done ;
}
sc_pkcs15init_set_p15card ( profile , vs - > p15card ) ;
rv = sc_pkcs15init_delete_object ( vs - > p15card , profile , obj ) ;
if ( rv ) {
logprintf ( pCardData , 2 , " MdDeleteObject(): pkcs15init delete object failed %d \n " , rv ) ;
goto done ;
}
dwret = SCARD_S_SUCCESS ;
logprintf ( pCardData , 3 , " MdDeleteObject() returns OK \n " ) ;
done :
sc_pkcs15init_unbind ( profile ) ;
sc_unlock ( card ) ;
return dwret ;
}
/* Set 'soft' file contents,
* and update data associated to ' cardcf ' and ' cmapfile ' .
*/
static DWORD
md_fs_set_content ( PCARD_DATA pCardData , struct md_file * file , unsigned char * blob , size_t size )
{
if ( ! pCardData | | ! file )
return SCARD_E_INVALID_PARAMETER ;
if ( file - > blob )
pCardData - > pfnCspFree ( file - > blob ) ;
file - > blob = pCardData - > pfnCspAlloc ( size ) ;
if ( ! file - > blob )
return SCARD_E_NO_MEMORY ;
CopyMemory ( file - > blob , blob , size ) ;
file - > size = size ;
2017-01-25 22:27:27 +00:00
if ( ! strcmp ( ( char * ) file - > name , " cmapfile " ) )
2012-05-31 14:40:36 +00:00
return md_pkcs15_update_containers ( pCardData , blob , size ) ;
return SCARD_S_SUCCESS ;
}
/*
* Set ' cardid ' from the ' serialNumber ' attribute of the ' tokenInfo '
*/
static DWORD
md_set_cardid ( PCARD_DATA pCardData , struct md_file * file )
{
VENDOR_SPECIFIC * vs ;
DWORD dwret ;
if ( ! pCardData | | ! file )
return SCARD_E_INVALID_PARAMETER ;
vs = pCardData - > pvVendorSpecific ;
if ( vs - > p15card - > tokeninfo & & vs - > p15card - > tokeninfo - > serial_number ) {
unsigned char sn_bin [ SC_MAX_SERIALNR ] ;
unsigned char cardid_bin [ MD_CARDID_SIZE ] ;
size_t offs , wr , sn_len = sizeof ( sn_bin ) ;
int rv ;
rv = sc_hex_to_bin ( vs - > p15card - > tokeninfo - > serial_number , sn_bin , & sn_len ) ;
2012-08-22 10:45:03 +00:00
if ( rv ) {
sn_len = strlen ( vs - > p15card - > tokeninfo - > serial_number ) ;
if ( sn_len > SC_MAX_SERIALNR ) {
sn_len = SC_MAX_SERIALNR ;
}
memcpy ( sn_bin , vs - > p15card - > tokeninfo - > serial_number , sn_len ) ;
}
2013-12-29 18:46:30 +00:00
2012-05-31 14:40:36 +00:00
for ( offs = 0 ; offs < MD_CARDID_SIZE ; ) {
wr = MD_CARDID_SIZE - offs ;
if ( wr > sn_len )
wr = sn_len ;
memcpy ( cardid_bin + offs , sn_bin , wr ) ;
offs + = wr ;
}
dwret = md_fs_set_content ( pCardData , file , cardid_bin , MD_CARDID_SIZE ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
}
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " cardid(% " SC_FORMAT_LEN_SIZE_T " u) \n " ,
file - > size ) ;
2012-05-31 14:40:36 +00:00
loghex ( pCardData , 3 , file - > blob , file - > size ) ;
return SCARD_S_SUCCESS ;
}
2017-03-09 06:19:51 +00:00
/* fill the msroots file from root certificates */
2017-03-14 22:58:03 +00:00
static DWORD
md_fs_read_msroots_file ( PCARD_DATA pCardData , struct md_file * file )
2015-04-18 19:43:13 +00:00
{
CERT_BLOB dbStore = { 0 } ;
2017-03-14 22:58:03 +00:00
HCERTSTORE hCertStore ;
2015-04-18 19:43:13 +00:00
VENDOR_SPECIFIC * vs ;
int rv , ii , cert_num ;
struct sc_pkcs15_object * prkey_objs [ MD_MAX_KEY_CONTAINERS ] ;
2017-03-14 22:58:03 +00:00
DWORD dwret = SCARD_F_INTERNAL_ERROR ;
2015-04-18 19:43:13 +00:00
2017-03-14 22:58:03 +00:00
if ( ! pCardData | | ! file )
return SCARD_E_INVALID_PARAMETER ;
2015-04-18 19:43:13 +00:00
vs = ( VENDOR_SPECIFIC * ) pCardData - > pvVendorSpecific ;
2017-03-14 22:58:03 +00:00
if ( ! vs )
return SCARD_E_INVALID_PARAMETER ;
hCertStore = CertOpenStore ( CERT_STORE_PROV_MEMORY , X509_ASN_ENCODING , ( HCRYPTPROV_LEGACY ) NULL , 0 , NULL ) ;
if ( ! hCertStore )
goto Ret ;
2015-04-18 19:43:13 +00:00
rv = sc_pkcs15_get_objects ( vs - > p15card , SC_PKCS15_TYPE_CERT_X509 , prkey_objs , MD_MAX_KEY_CONTAINERS ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 0 , " certificate enumeration failed: %s \n " , sc_strerror ( rv ) ) ;
2017-03-14 22:58:03 +00:00
dwret = md_translate_OpenSC_to_Windows_error ( rv , dwret ) ;
2015-04-18 19:43:13 +00:00
goto Ret ;
}
cert_num = rv ;
for ( ii = 0 ; ii < cert_num ; ii + + ) {
struct sc_pkcs15_cert_info * cert_info = ( struct sc_pkcs15_cert_info * ) prkey_objs [ ii ] - > data ;
struct sc_pkcs15_cert * cert = NULL ;
PCCERT_CONTEXT wincert = NULL ;
if ( cert_info - > authority ) {
rv = sc_pkcs15_read_certificate ( vs - > p15card , cert_info , & cert ) ;
if ( rv ) {
logprintf ( pCardData , 2 , " Cannot read certificate idx:%i: sc-error %d \n " , ii , rv ) ;
continue ;
}
2015-04-25 21:29:03 +00:00
wincert = CertCreateCertificateContext ( X509_ASN_ENCODING , cert - > data . value , ( DWORD ) cert - > data . len ) ;
2015-04-18 19:43:13 +00:00
if ( wincert ) {
CertAddCertificateContextToStore ( hCertStore , wincert , CERT_STORE_ADD_REPLACE_EXISTING , NULL ) ;
CertFreeCertificateContext ( wincert ) ;
}
else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" unable to load the certificate from Windows 0x%08X \n " ,
( unsigned int ) GetLastError ( ) ) ;
2015-04-18 19:43:13 +00:00
}
sc_pkcs15_free_certificate ( cert ) ;
}
}
if ( FALSE = = CertSaveStore ( hCertStore ,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING ,
CERT_STORE_SAVE_AS_PKCS7 ,
CERT_STORE_SAVE_TO_MEMORY ,
& dbStore ,
0 ) ) {
goto Ret ;
}
dbStore . pbData = ( PBYTE ) pCardData - > pfnCspAlloc ( dbStore . cbData ) ;
if ( NULL = = dbStore . pbData ) {
2017-03-14 22:58:03 +00:00
dwret = SCARD_E_NO_MEMORY ;
2015-04-18 19:43:13 +00:00
goto Ret ;
}
if ( FALSE = = CertSaveStore ( hCertStore ,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING ,
CERT_STORE_SAVE_AS_PKCS7 ,
CERT_STORE_SAVE_TO_MEMORY ,
& dbStore ,
0 ) )
{
goto Ret ;
}
file - > size = dbStore . cbData ;
file - > blob = dbStore . pbData ;
dbStore . pbData = NULL ;
2017-03-14 22:58:03 +00:00
dwret = SCARD_S_SUCCESS ;
2015-04-18 19:43:13 +00:00
Ret :
if ( dbStore . pbData )
pCardData - > pfnCspFree ( dbStore . pbData ) ;
if ( hCertStore )
CertCloseStore ( hCertStore , CERT_CLOSE_STORE_FORCE_FLAG ) ;
2017-03-14 22:58:03 +00:00
return dwret ;
2015-04-18 19:43:13 +00:00
}
2012-05-31 14:40:36 +00:00
/*
* Return content of the ' soft ' file .
*/
2017-03-14 22:58:03 +00:00
static DWORD
2012-05-31 14:40:36 +00:00
md_fs_read_content ( PCARD_DATA pCardData , char * parent , struct md_file * file )
{
VENDOR_SPECIFIC * vs ;
struct md_directory * dir = NULL ;
DWORD dwret ;
if ( ! pCardData | | ! file )
2017-03-14 22:58:03 +00:00
return SCARD_E_INVALID_PARAMETER ;
2012-05-31 14:40:36 +00:00
vs = pCardData - > pvVendorSpecific ;
2017-03-14 22:58:03 +00:00
if ( ! vs | | ! vs - > p15card )
return SCARD_E_INVALID_PARAMETER ;
2012-05-31 14:40:36 +00:00
dwret = md_fs_find_directory ( pCardData , NULL , parent , & dir ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " find directory '%s' error: %lX \n " ,
parent ? parent : " <null> " , ( unsigned long ) dwret ) ;
2017-03-14 22:58:03 +00:00
return dwret ;
2012-05-31 14:40:36 +00:00
}
else if ( ! dir ) {
logprintf ( pCardData , 2 , " directory '%s' not found \n " , parent ? parent : " <null> " ) ;
2017-03-14 22:58:03 +00:00
return SCARD_E_DIR_NOT_FOUND ;
2015-05-08 13:49:30 +00:00
}
2012-05-31 14:40:36 +00:00
2017-01-25 22:27:27 +00:00
if ( ! strcmp ( ( char * ) dir - > name , " mscp " ) ) {
2012-05-31 14:40:36 +00:00
int idx , rv ;
2017-03-14 19:39:29 +00:00
if ( sscanf ( ( char * ) file - > name , " ksc%d " , & idx ) > 0 ) {
2012-05-31 14:40:36 +00:00
}
2017-03-14 19:39:29 +00:00
else if ( sscanf ( ( char * ) file - > name , " kxc%d " , & idx ) > 0 ) {
2012-05-31 14:40:36 +00:00
}
else {
idx = - 1 ;
}
if ( idx > = 0 & & idx < MD_MAX_KEY_CONTAINERS & & vs - > p15_containers [ idx ] . cert_obj ) {
struct sc_pkcs15_cert * cert = NULL ;
struct sc_pkcs15_object * cert_obj = vs - > p15_containers [ idx ] . cert_obj ;
struct sc_pkcs15_cert_info * cert_info = ( struct sc_pkcs15_cert_info * ) cert_obj - > data ;
rv = sc_pkcs15_read_certificate ( vs - > p15card , cert_info , & cert ) ;
if ( rv ) {
logprintf ( pCardData , 2 , " Cannot read certificate idx:%i: sc-error %d \n " , idx , rv ) ;
logprintf ( pCardData , 2 , " set cardcf from 'DATA' pkcs#15 object \n " ) ;
2017-03-14 22:58:03 +00:00
return md_translate_OpenSC_to_Windows_error ( rv ,
SCARD_F_INTERNAL_ERROR ) ;
2012-05-31 14:40:36 +00:00
}
2012-09-30 20:38:27 +00:00
file - > blob = pCardData - > pfnCspAlloc ( cert - > data . len ) ;
2017-03-14 22:58:03 +00:00
if ( file - > blob ) {
CopyMemory ( file - > blob , cert - > data . value , cert - > data . len ) ;
file - > size = cert - > data . len ;
dwret = SCARD_S_SUCCESS ;
} else
dwret = SCARD_E_NO_MEMORY ;
2012-05-31 14:40:36 +00:00
sc_pkcs15_free_certificate ( cert ) ;
2017-03-14 22:58:03 +00:00
return dwret ;
} else if ( ! strcmp ( ( char * ) file - > name , " msroots " ) )
return md_fs_read_msroots_file ( pCardData , file ) ;
2012-05-31 14:40:36 +00:00
}
2017-03-14 22:58:03 +00:00
return SCARD_E_FILE_NOT_FOUND ;
2012-05-31 14:40:36 +00:00
}
/*
* Set content of ' cardcf ' ,
* for that look for the possible source in the following order :
* - data from the dedicated PKCS # 15 ' DATA ' object ;
* - ' lastUpdate ' attribute of tokenInfo ;
* - random data .
*/
static DWORD
md_set_cardcf ( PCARD_DATA pCardData , struct md_file * file )
{
2015-10-11 13:20:04 +00:00
CARD_CACHE_FILE_FORMAT empty = { 0 } ;
2012-05-31 14:40:36 +00:00
DWORD dwret ;
if ( ! pCardData | | ! file )
return SCARD_E_INVALID_PARAMETER ;
dwret = md_fs_set_content ( pCardData , file , ( unsigned char * ) ( & empty ) , MD_CARDCF_LENGTH ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " 'cardcf' content(% " SC_FORMAT_LEN_SIZE_T " u) \n " ,
file - > size ) ;
2012-05-31 14:40:36 +00:00
loghex ( pCardData , 3 , file - > blob , file - > size ) ;
return SCARD_S_SUCCESS ;
}
static DWORD
md_set_cardapps ( PCARD_DATA pCardData , struct md_file * file )
{
DWORD dwret ;
unsigned char mscp [ 8 ] = { ' m ' , ' s ' , ' c ' , ' p ' , 0 , 0 , 0 , 0 } ;
if ( ! pCardData | | ! file )
return SCARD_E_INVALID_PARAMETER ;
dwret = md_fs_set_content ( pCardData , file , mscp , sizeof ( mscp ) ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " mscp(% " SC_FORMAT_LEN_SIZE_T " u) \n " , file - > size ) ;
2012-05-31 14:40:36 +00:00
loghex ( pCardData , 3 , file - > blob , file - > size ) ;
return SCARD_S_SUCCESS ;
}
2017-03-09 06:19:51 +00:00
/* check if the card has root certificates. If yes, notify the base csp by creating the msroots file */
2015-04-18 19:43:13 +00:00
static DWORD
2017-03-09 06:19:51 +00:00
md_fs_add_msroots ( PCARD_DATA pCardData , struct md_file * * head )
2015-04-18 19:43:13 +00:00
{
VENDOR_SPECIFIC * vs ;
int rv , ii , cert_num ;
DWORD dwret ;
struct sc_pkcs15_object * prkey_objs [ MD_MAX_KEY_CONTAINERS ] ;
if ( ! pCardData | | ! head )
return SCARD_E_INVALID_PARAMETER ;
vs = ( VENDOR_SPECIFIC * ) pCardData - > pvVendorSpecific ;
rv = sc_pkcs15_get_objects ( vs - > p15card , SC_PKCS15_TYPE_CERT_X509 , prkey_objs , MD_MAX_KEY_CONTAINERS ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 0 , " certificate enumeration failed: %s \n " , sc_strerror ( rv ) ) ;
return SCARD_S_SUCCESS ;
}
cert_num = rv ;
for ( ii = 0 ; ii < cert_num ; ii + + ) {
struct sc_pkcs15_cert_info * cert_info = ( struct sc_pkcs15_cert_info * ) prkey_objs [ ii ] - > data ;
if ( cert_info - > authority ) {
2017-03-09 06:19:51 +00:00
dwret = md_fs_add_file ( pCardData , head , " msroots " , EveryoneReadUserWriteAc , NULL , 0 , NULL ) ;
2015-04-18 19:43:13 +00:00
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
return SCARD_S_SUCCESS ;
}
}
return SCARD_S_SUCCESS ;
}
2012-05-31 14:40:36 +00:00
/*
* Set the content of the ' soft ' ' cmapfile ' :
* 1. Initialize internal p15_contaniers with the existing private keys PKCS # 15 objects ;
* 2. Try to read the content of the PKCS # 15 ' DATA ' object ' CSP ' : ' cmapfile ' ,
2016-04-06 16:20:36 +00:00
* If some record from the ' DATA ' object references an existing key :
2012-05-31 14:40:36 +00:00
* 2 a . Update the non - pkcs # 15 attributes of the corresponding internal p15_container ;
* 2 b . Change the index of internal p15_container according to the index from ' DATA ' file .
2016-04-06 16:20:36 +00:00
* Records from ' DATA ' file are ignored is they do not have
* the corresponding PKCS # 15 private key object .
2012-05-31 14:40:36 +00:00
* 3. Initalize the content of the ' soft ' ' cmapfile ' from the inernal p15 - containers .
*/
static DWORD
md_set_cmapfile ( PCARD_DATA pCardData , struct md_file * file )
{
VENDOR_SPECIFIC * vs ;
PCONTAINER_MAP_RECORD p ;
unsigned char * cmap_buf = NULL ;
size_t cmap_len ;
DWORD dwret ;
int ii , rv , conts_num , found_default = 0 ;
/* struct sc_pkcs15_data *data_object; */
struct sc_pkcs15_object * prkey_objs [ MD_MAX_KEY_CONTAINERS ] ;
if ( ! pCardData | | ! file )
return SCARD_E_INVALID_PARAMETER ;
2015-10-11 16:51:36 +00:00
logprintf ( pCardData , 2 , " set 'cmapfile' \n " ) ;
2012-05-31 14:40:36 +00:00
vs = pCardData - > pvVendorSpecific ;
cmap_len = MD_MAX_KEY_CONTAINERS * sizeof ( CONTAINER_MAP_RECORD ) ;
cmap_buf = pCardData - > pfnCspAlloc ( cmap_len ) ;
if ( ! cmap_buf )
return SCARD_E_NO_MEMORY ;
memset ( cmap_buf , 0 , cmap_len ) ;
2015-09-25 20:22:29 +00:00
rv = sc_pkcs15_get_objects ( vs - > p15card , SC_PKCS15_TYPE_PRKEY , prkey_objs , MD_MAX_KEY_CONTAINERS ) ;
2012-05-31 14:40:36 +00:00
if ( rv < 0 ) {
logprintf ( pCardData , 0 , " Private key enumeration failed: %s \n " , sc_strerror ( rv ) ) ;
return SCARD_F_UNKNOWN_ERROR ;
}
conts_num = rv ;
logprintf ( pCardData , 2 , " Found %d private key(s) in the card. \n " , conts_num ) ;
/* Initialize the P15 container array with the existing keys */
for ( ii = 0 ; ii < conts_num ; ii + + ) {
2017-01-25 22:27:27 +00:00
struct sc_pkcs15_object * key_obj = prkey_objs [ ii ] ;
2012-05-31 14:40:36 +00:00
struct sc_pkcs15_prkey_info * prkey_info = ( struct sc_pkcs15_prkey_info * ) key_obj - > data ;
struct md_pkcs15_container * cont = & vs - > p15_containers [ ii ] ;
2015-09-25 20:22:29 +00:00
if ( key_obj - > type ! = SC_PKCS15_TYPE_PRKEY_RSA & & key_obj - > type ! = SC_PKCS15_TYPE_PRKEY_EC ) {
logprintf ( pCardData , 7 , " Non 'RSA' 'EC' key (type:%X) are ignored \n " , key_obj - > type ) ;
2012-05-31 14:40:36 +00:00
continue ;
}
2016-04-06 16:20:36 +00:00
dwret = md_contguid_build_cont_guid_from_key ( pCardData , key_obj , cont - > guid ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2013-12-25 19:57:42 +00:00
2015-10-11 13:20:04 +00:00
/* replace the OpenSC guid by a Windows Guid if needed
Typically used in the certificate enrollment process .
Windows create a new container with a Windows guid , close the context , then create a new context and look for the previous container .
If we return our guid , it fails because the Windows guid can ' t be found .
The overwrite is present to avoid this conversion been replaced by md_pkcs15_update_container_from_do */
2016-04-06 16:20:36 +00:00
// cont->guid_overwrite = md_contguid_find_conversion(pCardData, cont->guid);
2015-10-11 13:20:04 +00:00
2016-04-06 16:20:36 +00:00
// cont->flags = CONTAINER_MAP_VALID_CONTAINER;
dwret = md_cont_flags_from_key ( pCardData , key_obj , & cont - > flags ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
if ( cont - > flags & CONTAINER_MAP_DEFAULT_CONTAINER )
found_default = 1 ;
2015-10-11 13:20:04 +00:00
/* AT_KEYEXCHANGE is more general key usage,
2016-04-06 16:20:36 +00:00
* it allows ' decryption ' as well as ' signature ' key usage .
* AT_SIGNATURE allows only ' signature ' usage .
*/
2015-10-11 13:20:04 +00:00
cont - > size_key_exchange = cont - > size_sign = 0 ;
if ( key_obj - > type = = SC_PKCS15_TYPE_PRKEY_RSA ) {
if ( prkey_info - > usage & USAGE_ANY_DECIPHER )
cont - > size_key_exchange = prkey_info - > modulus_length ;
else if ( prkey_info - > usage & USAGE_ANY_SIGN )
cont - > size_sign = prkey_info - > modulus_length ;
else
cont - > size_key_exchange = prkey_info - > modulus_length ;
} else if ( key_obj - > type = = SC_PKCS15_TYPE_PRKEY_EC ) {
if ( prkey_info - > usage & USAGE_ANY_AGREEMENT )
cont - > size_key_exchange = prkey_info - > field_length ;
else if ( prkey_info - > usage & USAGE_ANY_SIGN )
cont - > size_sign = prkey_info - > field_length ;
else
cont - > size_key_exchange = prkey_info - > field_length ;
2012-05-31 14:40:36 +00:00
}
2015-10-06 06:21:20 +00:00
logprintf ( pCardData , 7 , " Container[%i]'s guid=%.*s \n " , ii , ( int ) sizeof cont - > guid , cont - > guid ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 ,
" Container[%i]'s key-exchange:% " SC_FORMAT_LEN_SIZE_T " u, sign:% " SC_FORMAT_LEN_SIZE_T " u \n " ,
ii , cont - > size_key_exchange , cont - > size_sign ) ;
2012-05-31 14:40:36 +00:00
cont - > id = prkey_info - > id ;
cont - > prkey_obj = prkey_objs [ ii ] ;
/* Try to find the friend objects: certficate and public key */
if ( ! sc_pkcs15_find_cert_by_id ( vs - > p15card , & cont - > id , & cont - > cert_obj ) )
2015-10-04 15:33:14 +00:00
logprintf ( pCardData , 2 , " found certificate friend '%.*s' \n " , ( int ) sizeof cont - > cert_obj - > label , cont - > cert_obj - > label ) ;
2012-05-31 14:40:36 +00:00
if ( ! sc_pkcs15_find_pubkey_by_id ( vs - > p15card , & cont - > id , & cont - > pubkey_obj ) )
2015-10-04 15:33:14 +00:00
logprintf ( pCardData , 2 , " found public key friend '%.*s' \n " , ( int ) sizeof cont - > pubkey_obj - > label , cont - > pubkey_obj - > label ) ;
2012-05-31 14:40:36 +00:00
}
if ( conts_num ) {
2013-12-25 19:57:42 +00:00
/* Read 'CMAPFILE' (Gemalto style) and update the attributes of P15 containers */
2016-04-06 16:20:36 +00:00
#if 0
2012-05-31 14:40:36 +00:00
struct sc_pkcs15_object * dobjs [ MD_MAX_KEY_CONTAINERS + 1 ] , * default_cont = NULL ;
int num_dobjs = MD_MAX_KEY_CONTAINERS + 1 ;
rv = sc_pkcs15_get_objects ( vs - > p15card , SC_PKCS15_TYPE_DATA_OBJECT , dobjs , num_dobjs ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 0 , " 'DATA' object enumeration failed: %s \n " , sc_strerror ( rv ) ) ;
return SCARD_F_UNKNOWN_ERROR ;
}
num_dobjs = rv ;
logprintf ( pCardData , 2 , " Found %d 'DATA' objects. \n " , num_dobjs ) ;
for ( ii = 0 ; ii < num_dobjs ; ii + + ) {
struct sc_pkcs15_data_info * dinfo = ( struct sc_pkcs15_data_info * ) dobjs [ ii ] - > data ;
if ( strcmp ( dinfo - > app_label , MD_DATA_APPLICAITON_NAME ) )
continue ;
2015-10-04 15:33:14 +00:00
logprintf ( pCardData , 2 , " Found 'DATA' object '%.*s' \n " , ( int ) sizeof dobjs [ ii ] - > label , dobjs [ ii ] - > label ) ;
if ( ! strncmp ( dobjs [ ii ] - > label , MD_DATA_DEFAULT_CONT_LABEL , sizeof dobjs [ ii ] - > label ) ) {
2012-05-31 14:40:36 +00:00
default_cont = dobjs [ ii ] ;
continue ;
}
dwret = md_pkcs15_update_container_from_do ( pCardData , dobjs [ ii ] ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 2 , " Cannot update container from DO: %li " , dwret ) ;
return dwret ;
}
}
if ( default_cont ) {
dwret = md_pkcs15_default_container_from_do ( pCardData , default_cont ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 2 , " Cannot set default container from DO: %li " , dwret ) ;
return dwret ;
}
}
2016-04-06 16:20:36 +00:00
# endif
2012-05-31 14:40:36 +00:00
/* Initialize 'CMAPFILE' content from the P15 containers */
p = ( PCONTAINER_MAP_RECORD ) cmap_buf ;
for ( ii = 0 ; ii < MD_MAX_KEY_CONTAINERS ; ii + + ) {
if ( ! ( vs - > p15_containers [ ii ] . flags & CONTAINER_MAP_VALID_CONTAINER ) )
continue ;
if ( ! found_default ) {
vs - > p15_containers [ ii ] . flags | = CONTAINER_MAP_DEFAULT_CONTAINER ;
found_default = 1 ;
}
mbstowcs ( ( p + ii ) - > wszGuid , vs - > p15_containers [ ii ] . guid , MAX_CONTAINER_NAME_LEN + 1 ) ;
( p + ii ) - > bFlags = vs - > p15_containers [ ii ] . flags ;
2015-04-25 21:29:03 +00:00
( p + ii ) - > wSigKeySizeBits = ( WORD ) vs - > p15_containers [ ii ] . size_sign ;
( p + ii ) - > wKeyExchangeKeySizeBits = ( WORD ) vs - > p15_containers [ ii ] . size_key_exchange ;
2012-05-31 14:40:36 +00:00
if ( vs - > p15_containers [ ii ] . cert_obj ) {
char k_name [ 6 ] ;
if ( vs - > p15_containers [ ii ] . size_key_exchange ) {
2017-03-14 19:39:29 +00:00
snprintf ( k_name , sizeof ( k_name ) , " kxc%02i " , ii ) ;
k_name [ sizeof ( k_name ) - 1 ] = 0 ;
2012-05-31 14:40:36 +00:00
dwret = md_fs_add_file ( pCardData , & ( file - > next ) , k_name , file - > acl , NULL , 0 , NULL ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
}
if ( vs - > p15_containers [ ii ] . size_sign ) {
2017-03-14 19:39:29 +00:00
snprintf ( k_name , sizeof ( k_name ) , " ksc%02i " , ii ) ;
k_name [ sizeof ( k_name ) - 1 ] = 0 ;
2012-05-31 14:40:36 +00:00
dwret = md_fs_add_file ( pCardData , & ( file - > next ) , k_name , file - > acl , NULL , 0 , NULL ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
}
}
logprintf ( pCardData , 7 , " cmapfile entry(%d) '%s' " , ii , vs - > p15_containers [ ii ] . guid ) ;
loghex ( pCardData , 7 , ( PBYTE ) ( p + ii ) , sizeof ( CONTAINER_MAP_RECORD ) ) ;
}
}
2016-04-06 16:20:36 +00:00
2017-03-09 06:19:51 +00:00
dwret = md_fs_add_msroots ( pCardData , & ( file - > next ) ) ;
2015-04-18 19:43:13 +00:00
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2012-05-31 14:40:36 +00:00
dwret = md_fs_set_content ( pCardData , file , cmap_buf , cmap_len ) ;
pCardData - > pfnCspFree ( cmap_buf ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " cmap(% " SC_FORMAT_LEN_SIZE_T " u) \n " , file - > size ) ;
2012-05-31 14:40:36 +00:00
loghex ( pCardData , 3 , file - > blob , file - > size ) ;
return SCARD_S_SUCCESS ;
}
/*
* Initialize internal ' soft ' file system
*/
static DWORD
md_fs_init ( PCARD_DATA pCardData )
{
VENDOR_SPECIFIC * vs ;
DWORD dwret ;
struct md_file * cardid , * cardcf , * cardapps , * cmapfile ;
struct md_directory * mscp ;
if ( ! pCardData | | ! pCardData - > pvVendorSpecific )
return SCARD_E_INVALID_PARAMETER ;
vs = pCardData - > pvVendorSpecific ;
dwret = md_fs_add_file ( pCardData , & ( vs - > root . files ) , " cardid " , EveryoneReadAdminWriteAc , NULL , 0 , & cardid ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_set_cardid ( pCardData , cardid ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_fs_add_file ( pCardData , & ( vs - > root . files ) , " cardcf " , EveryoneReadUserWriteAc , NULL , 0 , & cardcf ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_set_cardcf ( pCardData , cardcf ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_fs_add_file ( pCardData , & ( vs - > root . files ) , " cardapps " , EveryoneReadAdminWriteAc , NULL , 0 , & cardapps ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_set_cardapps ( pCardData , cardapps ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_fs_add_directory ( pCardData , & ( vs - > root . subdirs ) , " mscp " , UserCreateDeleteDirAc , & mscp ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_fs_add_file ( pCardData , & ( mscp - > files ) , " cmapfile " , EveryoneReadUserWriteAc , NULL , 0 , & cmapfile ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
dwret = md_set_cmapfile ( pCardData , cmapfile ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2015-03-28 12:04:41 +00:00
# ifdef OPENSSL_VERSION_NUMBER
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" MD virtual file system initialized; OPENSSL_VERSION_NUMBER 0x%lX \n " ,
OPENSSL_VERSION_NUMBER ) ;
2015-03-28 12:04:41 +00:00
# else
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" MD virtual file system initialized; Without OPENSSL \n " ) ;
2015-03-28 12:04:41 +00:00
# endif
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
}
/* Create SC context */
static DWORD
md_create_context ( PCARD_DATA pCardData , VENDOR_SPECIFIC * vs )
{
sc_context_param_t ctx_param ;
int r ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
logprintf ( pCardData , 3 , " create sc ccontext \n " ) ;
vs - > ctx = NULL ;
memset ( & ctx_param , 0 , sizeof ( ctx_param ) ) ;
ctx_param . ver = 1 ;
ctx_param . app_name = " cardmod " ;
r = sc_context_create ( & ( vs - > ctx ) , & ctx_param ) ;
if ( r ) {
logprintf ( pCardData , 0 , " Failed to establish context: %s \n " , sc_strerror ( r ) ) ;
return SCARD_F_UNKNOWN_ERROR ;
}
logprintf ( pCardData , 3 , " sc context created \n " ) ;
return SCARD_S_SUCCESS ;
}
static DWORD
2015-04-17 19:39:41 +00:00
md_card_capabilities ( PCARD_DATA pCardData , PCARD_CAPABILITIES pCardCapabilities )
2012-05-31 14:40:36 +00:00
{
if ( ! pCardCapabilities )
return SCARD_E_INVALID_PARAMETER ;
if ( pCardCapabilities - > dwVersion ! = CARD_CAPABILITIES_CURRENT_VERSION & & pCardCapabilities - > dwVersion ! = 0 )
return ERROR_REVISION_MISMATCH ;
pCardCapabilities - > dwVersion = CARD_CAPABILITIES_CURRENT_VERSION ;
pCardCapabilities - > fCertificateCompression = TRUE ;
2015-04-17 16:04:05 +00:00
/* a read only card cannot generate new keys */
pCardCapabilities - > fKeyGen = ! md_is_read_only ( pCardData ) ;
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
}
static DWORD
md_free_space ( PCARD_DATA pCardData , PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo )
{
VENDOR_SPECIFIC * vs ;
int count , idx ;
if ( ! pCardData | | ! pCardFreeSpaceInfo )
return SCARD_E_INVALID_PARAMETER ;
if ( pCardFreeSpaceInfo - > dwVersion > CARD_FREE_SPACE_INFO_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
/* Count free containers */
for ( idx = 0 , count = 0 ; idx < MD_MAX_KEY_CONTAINERS ; idx + + )
if ( ! vs - > p15_containers [ idx ] . prkey_obj )
count + + ;
pCardFreeSpaceInfo - > dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION ;
pCardFreeSpaceInfo - > dwBytesAvailable = CARD_DATA_VALUE_UNKNOWN ;
pCardFreeSpaceInfo - > dwKeyContainersAvailable = count ;
pCardFreeSpaceInfo - > dwMaxKeyContainers = MD_MAX_KEY_CONTAINERS ;
return SCARD_S_SUCCESS ;
}
/* Check the new key to be created for the compatibility with card:
* - for the key to be generated the card needs to support the mechanism and size ;
* - for the key to be imported checked also the validity of supplied key blob .
*/
static DWORD
md_check_key_compatibility ( PCARD_DATA pCardData , DWORD flags , DWORD key_type ,
DWORD key_size , BYTE * pbKeyData )
{
VENDOR_SPECIFIC * vs ;
struct sc_algorithm_info * algo_info ;
unsigned int count , key_algo ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2015-09-25 20:22:29 +00:00
switch ( key_type ) {
case AT_SIGNATURE :
case AT_KEYEXCHANGE :
key_algo = SC_ALGORITHM_RSA ;
break ;
case AT_ECDHE_P256 :
case AT_ECDHE_P384 :
case AT_ECDHE_P521 :
case AT_ECDSA_P256 :
case AT_ECDSA_P384 :
case AT_ECDSA_P521 :
key_algo = SC_ALGORITHM_EC ;
break ;
default :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " Unsupported key type: 0x%lX \n " ,
( unsigned long ) key_type ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
2012-05-31 14:40:36 +00:00
}
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
if ( flags & CARD_CREATE_CONTAINER_KEY_IMPORT ) {
2015-09-25 20:22:29 +00:00
if ( key_algo = = SC_ALGORITHM_RSA ) {
PUBLICKEYSTRUC * pub_struc = ( PUBLICKEYSTRUC * ) pbKeyData ;
RSAPUBKEY * pub_rsa = ( RSAPUBKEY * ) ( pbKeyData + sizeof ( PUBLICKEYSTRUC ) ) ;
2012-05-31 14:40:36 +00:00
2015-09-25 20:22:29 +00:00
if ( ! pub_struc ) {
logprintf ( pCardData , 3 , " No data for the key import operation \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
else if ( pub_struc - > bType ! = PRIVATEKEYBLOB ) {
logprintf ( pCardData , 3 , " Invalid blob data for the key import operation \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
else if ( ( key_type = = AT_KEYEXCHANGE ) & & ( pub_struc - > aiKeyAlg ! = CALG_RSA_KEYX ) ) {
logprintf ( pCardData , 3 , " Expected KEYEXCHANGE type of blob \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
else if ( ( key_type = = AT_SIGNATURE ) & & ( pub_struc - > aiKeyAlg ! = CALG_RSA_SIGN ) ) {
logprintf ( pCardData , 3 , " Expected KEYSIGN type of blob \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
2012-05-31 14:40:36 +00:00
2015-10-14 20:48:41 +00:00
if ( pub_rsa - > magic = = BCRYPT_RSAPUBLIC_MAGIC | | pub_rsa - > magic = = BCRYPT_RSAPRIVATE_MAGIC ) {
2015-09-25 20:22:29 +00:00
key_size = pub_rsa - > bitlen ;
}
else {
logprintf ( pCardData , 3 , " 'Magic' control failed \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
2012-05-31 14:40:36 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " Set key size to %lu \n " ,
( unsigned long ) key_size ) ;
2015-09-25 20:22:29 +00:00
} else if ( key_algo = = SC_ALGORITHM_EC ) {
BCRYPT_ECCKEY_BLOB * pub_ecc = ( BCRYPT_ECCKEY_BLOB * ) pbKeyData ;
switch ( key_type ) {
case AT_ECDSA_P256 :
if ( pub_ecc - > dwMagic ! = BCRYPT_ECDSA_PRIVATE_P256_MAGIC ) {
logprintf ( pCardData , 3 , " Expected AT_ECDSA_P256 magic \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
key_size = 256 ;
break ;
case AT_ECDSA_P384 :
if ( pub_ecc - > dwMagic ! = BCRYPT_ECDSA_PRIVATE_P384_MAGIC ) {
logprintf ( pCardData , 3 , " Expected AT_ECDSA_P384 magic \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
key_size = 384 ;
break ;
case AT_ECDSA_P521 :
if ( pub_ecc - > dwMagic ! = BCRYPT_ECDSA_PRIVATE_P521_MAGIC ) {
logprintf ( pCardData , 3 , " Expected AT_ECDSA_P521 magic \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
key_size = 521 ;
break ;
case AT_ECDHE_P256 :
if ( pub_ecc - > dwMagic ! = BCRYPT_ECDH_PRIVATE_P256_MAGIC ) {
logprintf ( pCardData , 3 , " Expected AT_ECDHE_P256 magic \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
key_size = 256 ;
break ;
case AT_ECDHE_P384 :
if ( pub_ecc - > dwMagic ! = BCRYPT_ECDH_PRIVATE_P384_MAGIC ) {
logprintf ( pCardData , 3 , " Expected AT_ECDHE_P384 magic \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
key_size = 384 ;
break ;
case AT_ECDHE_P521 :
if ( pub_ecc - > dwMagic ! = BCRYPT_ECDH_PRIVATE_P521_MAGIC ) {
logprintf ( pCardData , 3 , " Expected AT_ECDHE_P521 magic \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
key_size = 521 ;
break ;
}
}
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " Set key size to %lu \n " ,
( unsigned long ) key_size ) ;
2012-05-31 14:40:36 +00:00
}
count = vs - > p15card - > card - > algorithm_count ;
for ( algo_info = vs - > p15card - > card - > algorithms ; count - - ; algo_info + + ) {
if ( algo_info - > algorithm ! = key_algo | | algo_info - > key_length ! = key_size )
continue ;
logprintf ( pCardData , 3 , " Key compatible with the card capabilities \n " ) ;
return SCARD_S_SUCCESS ;
}
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" No card support for key(type:0x%lX,size:0x%lX) \n " ,
( unsigned long ) key_type , ( unsigned long ) key_size ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
static DWORD
md_pkcs15_generate_key ( PCARD_DATA pCardData , DWORD idx , DWORD key_type , DWORD key_size )
{
VENDOR_SPECIFIC * vs ;
struct sc_card * card = NULL ;
struct sc_profile * profile = NULL ;
struct sc_pkcs15_object * pin_obj = NULL ;
struct sc_pkcs15_auth_info * auth_info = NULL ;
struct sc_app_info * app_info = NULL ;
struct sc_pkcs15init_keygen_args keygen_args ;
struct sc_pkcs15init_pubkeyargs pub_args ;
struct md_pkcs15_container * cont = NULL ;
int rv ;
DWORD dw , dwret = SCARD_F_INTERNAL_ERROR ;
2015-10-10 13:39:27 +00:00
CHAR szGuid [ MAX_CONTAINER_NAME_LEN + 1 ] = " Default key label " ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
card = vs - > p15card - > card ;
memset ( & pub_args , 0 , sizeof ( pub_args ) ) ;
memset ( & keygen_args , 0 , sizeof ( keygen_args ) ) ;
2015-10-10 13:39:27 +00:00
keygen_args . prkey_args . label = szGuid ;
keygen_args . pubkey_label = szGuid ;
2012-05-31 14:40:36 +00:00
if ( key_type = = AT_SIGNATURE ) {
keygen_args . prkey_args . key . algorithm = SC_ALGORITHM_RSA ;
pub_args . key . algorithm = SC_ALGORITHM_RSA ;
keygen_args . prkey_args . x509_usage = MD_KEY_USAGE_SIGNATURE ;
}
else if ( key_type = = AT_KEYEXCHANGE ) {
keygen_args . prkey_args . key . algorithm = SC_ALGORITHM_RSA ;
pub_args . key . algorithm = SC_ALGORITHM_RSA ;
keygen_args . prkey_args . x509_usage = MD_KEY_USAGE_KEYEXCHANGE ;
}
2015-09-25 20:22:29 +00:00
else if ( ( key_type = = AT_ECDSA_P256 ) | | ( key_type = = AT_ECDSA_P384 ) | | ( key_type = = AT_ECDSA_P521 ) ) {
keygen_args . prkey_args . key . algorithm = SC_ALGORITHM_EC ;
pub_args . key . algorithm = SC_ALGORITHM_EC ;
keygen_args . prkey_args . x509_usage = MD_KEY_USAGE_SIGNATURE ;
}
else if ( ( key_type = = AT_ECDHE_P256 ) | | ( key_type = = AT_ECDHE_P384 ) | | ( key_type = = AT_ECDHE_P521 ) ) {
keygen_args . prkey_args . key . algorithm = SC_ALGORITHM_EC ;
pub_args . key . algorithm = SC_ALGORITHM_EC ;
keygen_args . prkey_args . x509_usage = MD_KEY_USAGE_KEYEXCHANGE_ECC ;
}
2012-05-31 14:40:36 +00:00
else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" MdGenerateKey(): unsupported key type: 0x%lX \n " ,
( unsigned long ) key_type ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
if ( pub_args . key . algorithm = = SC_ALGORITHM_EC ) {
keygen_args . prkey_args . key . u . ec . params . field_length = key_size ;
if ( ( key_type = = AT_ECDSA_P256 ) | | ( key_type = = AT_ECDHE_P256 ) ) {
keygen_args . prkey_args . key . u . ec . params . named_curve = " secp256r1 " ;
keygen_args . prkey_args . key . u . ec . params . der . len = 10 ;
2017-01-25 22:27:27 +00:00
keygen_args . prkey_args . key . u . ec . params . der . value = ( unsigned char * ) " \x06 \x08 \x2A \x86 \x48 \xCE \x3D \x03 \x01 \x07 " ;
2015-09-25 20:22:29 +00:00
} else if ( ( key_type = = AT_ECDSA_P384 ) | | ( key_type = = AT_ECDHE_P384 ) ) {
keygen_args . prkey_args . key . u . ec . params . named_curve = " secp384r1 " ;
keygen_args . prkey_args . key . u . ec . params . der . len = 7 ;
2017-01-25 22:27:27 +00:00
keygen_args . prkey_args . key . u . ec . params . der . value = ( unsigned char * ) " \x06 \x05 \x2B \x81 \x04 \x00 \x22 " ;
2015-09-25 20:22:29 +00:00
} else if ( ( key_type = = AT_ECDSA_P521 ) | | ( key_type = = AT_ECDHE_P521 ) ) {
keygen_args . prkey_args . key . u . ec . params . named_curve = " secp521r1 " ;
keygen_args . prkey_args . key . u . ec . params . der . len = 7 ;
2017-01-25 22:27:27 +00:00
keygen_args . prkey_args . key . u . ec . params . der . value = ( unsigned char * ) " \x06 \x05 \x2B \x81 \x04 \x00 \x23 " ;
2015-09-25 20:22:29 +00:00
}
2012-05-31 14:40:36 +00:00
}
keygen_args . prkey_args . access_flags = MD_KEY_ACCESS ;
dw = md_get_pin_by_role ( pCardData , ROLE_USER , & pin_obj ) ;
if ( dw ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 2 , " MdGenerateKey(): cannot get User PIN object " ) ;
return dw ;
}
auth_info = ( struct sc_pkcs15_auth_info * ) pin_obj - > data ;
keygen_args . prkey_args . auth_id = pub_args . auth_id = auth_info - > auth_id ;
rv = sc_lock ( card ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdGenerateKey(): cannot lock card \n " ) ;
return SCARD_F_INTERNAL_ERROR ;
}
app_info = vs - > p15card - > app ;
2015-09-30 20:47:16 +00:00
rv = sc_pkcs15init_bind ( card , " pkcs15 " , NULL , NULL , & profile ) ;
2012-05-31 14:40:36 +00:00
if ( rv ) {
logprintf ( pCardData , 3 , " MdGenerateKey(): PKCS#15 bind failed \n " ) ;
sc_unlock ( card ) ;
return SCARD_F_INTERNAL_ERROR ;
}
rv = sc_pkcs15init_finalize_profile ( card , profile , app_info ? & app_info - > aid : NULL ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdGenerateKey(): cannot finalize profile \n " ) ;
goto done ;
}
sc_pkcs15init_set_p15card ( profile , vs - > p15card ) ;
cont = & ( vs - > p15_containers [ idx ] ) ;
2013-12-29 11:41:36 +00:00
2015-10-10 13:39:27 +00:00
/* use the Windows Guid as input to determine some characteristics of the key such as the label or the id */
md_contguid_build_key_args_from_cont_guid ( pCardData , cont - > guid , & ( keygen_args . prkey_args ) ) ;
2016-04-06 16:20:36 +00:00
2015-10-10 13:39:27 +00:00
if ( keygen_args . prkey_args . label = = NULL ) {
md_generate_guid ( szGuid ) ;
keygen_args . prkey_args . label = szGuid ;
2013-12-29 11:46:51 +00:00
}
2015-10-10 13:39:27 +00:00
keygen_args . pubkey_label = keygen_args . prkey_args . label ;
2013-12-29 11:46:51 +00:00
2012-05-31 14:40:36 +00:00
rv = sc_pkcs15init_generate_key ( vs - > p15card , profile , & keygen_args , key_size , & cont - > prkey_obj ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 3 , " MdGenerateKey(): key generation failed: sc-error %i \n " , rv ) ;
goto done ;
}
2016-04-06 16:20:36 +00:00
dwret = md_contguid_add_conversion ( pCardData , cont - > prkey_obj , cont - > guid ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2015-10-11 13:20:04 +00:00
2012-05-31 14:40:36 +00:00
cont - > id = ( ( struct sc_pkcs15_prkey_info * ) cont - > prkey_obj - > data ) - > id ;
cont - > index = idx ;
cont - > flags = CONTAINER_MAP_VALID_CONTAINER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" MdGenerateKey(): generated key(idx:%lu,id:%s,guid:%.*s) \n " ,
( unsigned long ) idx , sc_pkcs15_print_id ( & cont - > id ) ,
( int ) sizeof cont - > guid , cont - > guid ) ;
2012-05-31 14:40:36 +00:00
done :
sc_pkcs15init_unbind ( profile ) ;
sc_unlock ( card ) ;
return dwret ;
}
static DWORD
md_pkcs15_store_key ( PCARD_DATA pCardData , DWORD idx , DWORD key_type , BYTE * blob , DWORD blob_size )
{
# if OPENSSL_VERSION_NUMBER >= 0x10000000L
VENDOR_SPECIFIC * vs ;
struct sc_card * card = NULL ;
struct sc_profile * profile = NULL ;
struct sc_pkcs15_object * pin_obj = NULL ;
struct sc_app_info * app_info = NULL ;
struct md_pkcs15_container * cont = NULL ;
struct sc_pkcs15init_prkeyargs prkey_args ;
struct sc_pkcs15init_pubkeyargs pubkey_args ;
BYTE * ptr = blob ;
EVP_PKEY * pkey = NULL ;
int rv ;
DWORD dw , dwret = SCARD_F_INTERNAL_ERROR ;
2015-10-10 13:39:27 +00:00
CHAR szGuid [ MAX_CONTAINER_NAME_LEN + 1 ] = " Default key label " ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
card = vs - > p15card - > card ;
2017-01-25 22:27:27 +00:00
pkey = b2i_PrivateKey ( ( const unsigned char * * ) & ptr , blob_size ) ;
2012-05-31 14:40:36 +00:00
if ( ! pkey ) {
logprintf ( pCardData , 1 , " MdStoreKey() MSBLOB key parse error " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
memset ( & prkey_args , 0 , sizeof ( prkey_args ) ) ;
rv = sc_pkcs15_convert_prkey ( & prkey_args . key , pkey ) ;
if ( rv ) {
logprintf ( pCardData , 1 , " MdStoreKey() cannot convert private key " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
memset ( & pubkey_args , 0 , sizeof ( pubkey_args ) ) ;
rv = sc_pkcs15_convert_pubkey ( & pubkey_args . key , pkey ) ;
if ( rv ) {
logprintf ( pCardData , 1 , " MdStoreKey() cannot convert public key " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( key_type = = AT_SIGNATURE ) {
prkey_args . x509_usage = MD_KEY_USAGE_SIGNATURE ;
pubkey_args . x509_usage = MD_KEY_USAGE_SIGNATURE ;
}
else if ( key_type = = AT_KEYEXCHANGE ) {
prkey_args . x509_usage = MD_KEY_USAGE_KEYEXCHANGE ;
pubkey_args . x509_usage = MD_KEY_USAGE_KEYEXCHANGE ;
}
else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" MdStoreKey(): unsupported key type: 0x%lX \n " ,
( unsigned long ) key_type ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
prkey_args . access_flags = MD_KEY_ACCESS ;
dw = md_get_pin_by_role ( pCardData , ROLE_USER , & pin_obj ) ;
if ( dw ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 2 , " MdStoreKey(): cannot get User PIN object " ) ;
return dw ;
}
prkey_args . auth_id = ( ( struct sc_pkcs15_auth_info * ) pin_obj - > data ) - > auth_id ;
rv = sc_lock ( card ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdStoreKey(): cannot lock card \n " ) ;
return SCARD_F_INTERNAL_ERROR ;
}
app_info = vs - > p15card - > app ;
2015-09-30 20:47:16 +00:00
rv = sc_pkcs15init_bind ( card , " pkcs15 " , NULL , NULL , & profile ) ;
2012-05-31 14:40:36 +00:00
if ( rv ) {
logprintf ( pCardData , 3 , " MdStoreKey(): PKCS#15 bind failed \n " ) ;
sc_unlock ( card ) ;
return SCARD_F_INTERNAL_ERROR ;
}
rv = sc_pkcs15init_finalize_profile ( card , profile , app_info ? & app_info - > aid : NULL ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdStoreKey(): cannot finalize profile \n " ) ;
goto done ;
}
sc_pkcs15init_set_p15card ( profile , vs - > p15card ) ;
cont = & ( vs - > p15_containers [ idx ] ) ;
2016-04-06 16:20:36 +00:00
2015-10-10 13:39:27 +00:00
prkey_args . label = szGuid ;
/* use the Windows Guid as input to determine some characteristics of the key such as the label or the id */
md_contguid_build_key_args_from_cont_guid ( pCardData , cont - > guid , & prkey_args ) ;
2016-04-06 16:20:36 +00:00
2015-10-10 13:39:27 +00:00
memcpy ( pubkey_args . id . value , prkey_args . id . value , prkey_args . id . len ) ;
pubkey_args . id . len = prkey_args . id . len ;
pubkey_args . label = prkey_args . label ;
2013-12-29 11:41:36 +00:00
2015-10-10 13:39:27 +00:00
if ( prkey_args . label = = szGuid ) {
md_generate_guid ( szGuid ) ;
2013-12-29 11:46:51 +00:00
}
2015-10-10 13:39:27 +00:00
pubkey_args . label = prkey_args . label ;
2013-12-29 11:46:51 +00:00
2012-05-31 14:40:36 +00:00
rv = sc_pkcs15init_store_private_key ( vs - > p15card , profile , & prkey_args , & cont - > prkey_obj ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 3 , " MdStoreKey(): private key store failed: sc-error %i \n " , rv ) ;
goto done ;
}
rv = sc_pkcs15init_store_public_key ( vs - > p15card , profile , & pubkey_args , & cont - > pubkey_obj ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 3 , " MdStoreKey(): public key store failed: sc-error %i \n " , rv ) ;
goto done ;
2011-03-23 18:37:46 +00:00
}
2016-04-06 16:20:36 +00:00
dwret = md_contguid_add_conversion ( pCardData , cont - > prkey_obj , cont - > guid ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2015-10-11 13:20:04 +00:00
2012-05-31 14:40:36 +00:00
cont - > id = ( ( struct sc_pkcs15_prkey_info * ) cont - > prkey_obj - > data ) - > id ;
cont - > index = idx ;
cont - > flags | = CONTAINER_MAP_VALID_CONTAINER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" MdStoreKey(): stored key(idx:%lu,id:%s,guid:%.*s) \n " ,
( unsigned long ) idx , sc_pkcs15_print_id ( & cont - > id ) ,
( int ) sizeof cont - > guid , cont - > guid ) ;
2012-05-31 14:40:36 +00:00
done :
sc_pkcs15init_unbind ( profile ) ;
sc_unlock ( card ) ;
return dwret ;
# else
logprintf ( pCardData , 1 , " MD store key not supported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
# endif
2011-03-23 18:37:46 +00:00
}
2012-05-31 14:40:36 +00:00
static DWORD
md_pkcs15_store_certificate ( PCARD_DATA pCardData , char * file_name , unsigned char * blob , size_t len )
2011-03-23 18:37:46 +00:00
{
VENDOR_SPECIFIC * vs ;
2013-12-29 11:41:36 +00:00
struct md_pkcs15_container * cont = NULL ;
2012-05-31 14:40:36 +00:00
struct sc_card * card = NULL ;
struct sc_profile * profile = NULL ;
struct sc_app_info * app_info = NULL ;
struct sc_pkcs15_object * cert_obj ;
struct sc_pkcs15init_certargs args ;
2013-12-29 11:41:36 +00:00
int rv , idx ;
2012-05-31 14:40:36 +00:00
DWORD dwret = SCARD_F_INTERNAL_ERROR ;
2011-03-23 18:37:46 +00:00
if ( ! pCardData )
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
2011-03-23 18:37:46 +00:00
2013-12-29 11:41:36 +00:00
logprintf ( pCardData , 1 , " MdStoreCert(): store certificate '%s' \n " , file_name ) ;
2011-03-23 18:37:46 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2012-05-31 14:40:36 +00:00
card = vs - > p15card - > card ;
2011-03-23 18:37:46 +00:00
2012-05-31 14:40:36 +00:00
memset ( & args , 0 , sizeof ( args ) ) ;
args . der_encoded . value = blob ;
args . der_encoded . len = len ;
2015-05-10 09:48:45 +00:00
args . update = 1 ;
2012-05-31 14:40:36 +00:00
2013-12-29 11:41:36 +00:00
/* use container's ID as ID of certificate to store */
idx = - 1 ;
2017-03-14 19:39:29 +00:00
if ( sscanf ( file_name , " ksc%d " , & idx ) > 0 ) {
} else if ( sscanf ( file_name , " kxc%d " , & idx ) > 0 ) {
2017-01-25 22:27:27 +00:00
}
2013-12-29 11:41:36 +00:00
if ( idx > = 0 & & idx < MD_MAX_KEY_CONTAINERS ) {
cont = & ( vs - > p15_containers [ idx ] ) ;
args . id = cont - > id ;
logprintf ( pCardData , 3 , " MdStoreCert(): store certificate(idx:%i,id:%s) \n " , idx , sc_pkcs15_print_id ( & cont - > id ) ) ;
}
2012-05-31 14:40:36 +00:00
rv = sc_lock ( card ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdStoreCert(): cannot lock card \n " ) ;
return SCARD_F_INTERNAL_ERROR ;
2011-03-23 18:37:46 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
app_info = vs - > p15card - > app ;
2015-09-30 20:47:16 +00:00
rv = sc_pkcs15init_bind ( card , " pkcs15 " , NULL , NULL , & profile ) ;
2012-05-31 14:40:36 +00:00
if ( rv ) {
logprintf ( pCardData , 3 , " MdStoreCert(): PKCS#15 bind failed \n " ) ;
sc_unlock ( card ) ;
return SCARD_F_INTERNAL_ERROR ;
2011-03-23 18:37:46 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
rv = sc_pkcs15init_finalize_profile ( card , profile , app_info ? & app_info - > aid : NULL ) ;
if ( rv ) {
logprintf ( pCardData , 3 , " MdStoreCert(): cannot finalize profile \n " ) ;
goto done ;
}
sc_pkcs15init_set_p15card ( profile , vs - > p15card ) ;
rv = sc_pkcs15init_store_certificate ( vs - > p15card , profile , & args , & cert_obj ) ;
if ( rv < 0 ) {
logprintf ( pCardData , 3 , " MdStoreCert(): cannot store certificate: sc-error %i \n " , rv ) ;
goto done ;
2011-03-23 18:37:46 +00:00
}
2012-05-31 14:40:36 +00:00
dwret = SCARD_S_SUCCESS ;
done :
sc_pkcs15init_unbind ( profile ) ;
sc_unlock ( card ) ;
return dwret ;
2011-03-23 18:37:46 +00:00
}
2012-05-31 14:40:36 +00:00
static DWORD
2015-09-25 20:22:29 +00:00
md_query_key_sizes ( PCARD_DATA pCardData , DWORD dwKeySpec , CARD_KEY_SIZES * pKeySizes )
2012-05-31 14:40:36 +00:00
{
2015-09-25 20:22:29 +00:00
VENDOR_SPECIFIC * vs = NULL ;
struct sc_algorithm_info * algo_info ;
2017-01-25 22:27:27 +00:00
int count = 0 , i , keysize = 0 , flag ;
2012-05-31 14:40:36 +00:00
if ( ! pKeySizes )
return SCARD_E_INVALID_PARAMETER ;
if ( pKeySizes - > dwVersion ! = CARD_KEY_SIZES_CURRENT_VERSION & & pKeySizes - > dwVersion ! = 0 )
return ERROR_REVISION_MISMATCH ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " md_query_key_sizes: store dwKeySpec '%lu' \n " ,
( unsigned long ) dwKeySpec ) ;
2015-09-25 20:22:29 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
count = vs - > p15card - > card - > algorithm_count ;
2012-05-31 14:40:36 +00:00
2015-09-25 20:22:29 +00:00
pKeySizes - > dwVersion = CARD_KEY_SIZES_CURRENT_VERSION ;
pKeySizes - > dwMinimumBitlen = 0 ;
pKeySizes - > dwDefaultBitlen = 0 ;
pKeySizes - > dwMaximumBitlen = 0 ;
pKeySizes - > dwIncrementalBitlen = 0 ;
/* dwKeySpec=0 is a special value when the key size is queried without specifing the algorithm.
Used on old minidriver version . In this case , it is RSA */
if ( ( dwKeySpec = = 0 ) | | ( dwKeySpec = = AT_KEYEXCHANGE ) | | ( dwKeySpec = = AT_SIGNATURE ) ) {
for ( i = 0 ; i < count ; i + + ) {
algo_info = vs - > p15card - > card - > algorithms + i ;
if ( algo_info - > algorithm = = SC_ALGORITHM_RSA ) {
if ( pKeySizes - > dwMinimumBitlen = = 0 | | pKeySizes - > dwMinimumBitlen > algo_info - > key_length ) {
pKeySizes - > dwMinimumBitlen = algo_info - > key_length ;
}
if ( pKeySizes - > dwMaximumBitlen = = 0 | | pKeySizes - > dwMaximumBitlen < algo_info - > key_length ) {
pKeySizes - > dwMaximumBitlen = algo_info - > key_length ;
}
if ( algo_info - > key_length = = 2048 ) {
pKeySizes - > dwDefaultBitlen = algo_info - > key_length ;
}
if ( algo_info - > key_length = = 1536 ) {
pKeySizes - > dwIncrementalBitlen = 512 ;
}
}
}
if ( pKeySizes - > dwMinimumBitlen = = 0 ) {
logprintf ( pCardData , 0 , " No RSA key found \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( pKeySizes - > dwDefaultBitlen = = 0 ) {
logprintf ( pCardData , 3 , " No 2048 key found \n " ) ;
pKeySizes - > dwDefaultBitlen = pKeySizes - > dwMaximumBitlen ;
}
if ( pKeySizes - > dwIncrementalBitlen = = 0 ) {
pKeySizes - > dwIncrementalBitlen = 1024 ;
}
} else {
keysize = 0 ;
for ( i = 0 ; i < count ; i + + ) {
algo_info = vs - > p15card - > card - > algorithms + i ;
if ( algo_info - > algorithm = = SC_ALGORITHM_EC ) {
flag = SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_EXT_EC_NAMEDCURVE ;
/* ECDHE */
if ( ( dwKeySpec = = AT_ECDHE_P256 ) & & ( algo_info - > key_length = = 256 ) & & ( algo_info - > flags & flag ) ) {
keysize = 256 ;
break ;
}
if ( ( dwKeySpec = = AT_ECDHE_P384 ) & & ( algo_info - > key_length = = 384 ) & & ( algo_info - > flags & flag ) ) {
keysize = 384 ;
break ;
}
if ( ( dwKeySpec = = AT_ECDHE_P521 ) & & ( algo_info - > key_length = = 521 ) & & ( algo_info - > flags & flag ) ) {
keysize = 521 ;
break ;
}
/* ECDSA */
flag = SC_ALGORITHM_ECDSA_HASH_NONE |
SC_ALGORITHM_ECDSA_HASH_SHA1 |
SC_ALGORITHM_ECDSA_HASH_SHA224 |
SC_ALGORITHM_ECDSA_HASH_SHA256 |
SC_ALGORITHM_EXT_EC_NAMEDCURVE ;
if ( ( dwKeySpec = = AT_ECDSA_P256 ) & & ( algo_info - > key_length = = 256 ) & & ( algo_info - > flags & flag ) ) {
keysize = 256 ;
break ;
}
if ( ( dwKeySpec = = AT_ECDSA_P384 ) & & ( algo_info - > key_length = = 384 ) & & ( algo_info - > flags & flag ) ) {
keysize = 384 ;
break ;
}
if ( ( dwKeySpec = = AT_ECDSA_P521 ) & & ( algo_info - > key_length = = 521 ) & & ( algo_info - > flags & flag ) ) {
keysize = 521 ;
break ;
}
}
if ( keysize ) {
pKeySizes - > dwMinimumBitlen = keysize ;
pKeySizes - > dwDefaultBitlen = keysize ;
pKeySizes - > dwMaximumBitlen = keysize ;
pKeySizes - > dwIncrementalBitlen = 1 ;
} else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" No ECC key found (keyspec=%lu) \n " ,
( unsigned long ) dwKeySpec ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
}
}
2017-03-14 21:56:39 +00:00
2015-09-25 20:22:29 +00:00
logprintf ( pCardData , 3 , " Key compatible with the card capabilities \n " ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " dwMinimumBitlen: %lu \n " ,
( unsigned long ) pKeySizes - > dwMinimumBitlen ) ;
logprintf ( pCardData , 3 , " dwDefaultBitlen: %lu \n " ,
( unsigned long ) pKeySizes - > dwDefaultBitlen ) ;
logprintf ( pCardData , 3 , " dwMaximumBitlen: %lu \n " ,
( unsigned long ) pKeySizes - > dwMaximumBitlen ) ;
logprintf ( pCardData , 3 , " dwIncrementalBitlen: %lu \n " ,
( unsigned long ) pKeySizes - > dwIncrementalBitlen ) ;
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
}
2011-03-23 18:37:46 +00:00
2015-04-19 17:51:22 +00:00
static DWORD WINAPI
md_dialog_perform_pin_operation_thread ( PVOID lpParameter )
{
/* unstack the parameters */
LONG_PTR * parameter = ( LONG_PTR * ) lpParameter ;
2015-04-25 21:29:03 +00:00
int operation = ( int ) parameter [ 0 ] ;
2015-04-19 17:51:22 +00:00
struct sc_pkcs15_card * p15card = ( struct sc_pkcs15_card * ) parameter [ 1 ] ;
struct sc_pkcs15_object * pin_obj = ( struct sc_pkcs15_object * ) parameter [ 2 ] ;
const u8 * pin1 = ( const u8 * ) parameter [ 3 ] ;
size_t pin1len = parameter [ 4 ] ;
const u8 * pin2 = ( const u8 * ) parameter [ 5 ] ;
2017-03-01 16:53:44 +00:00
size_t * pin2len = ( size_t * ) parameter [ 6 ] ;
2015-04-19 17:51:22 +00:00
int rv = 0 ;
switch ( operation )
{
case SC_PIN_CMD_VERIFY :
rv = sc_pkcs15_verify_pin ( p15card , pin_obj , pin1 , pin1len ) ;
break ;
2017-03-01 16:53:44 +00:00
case SC_PIN_CMD_GET_SESSION_PIN :
rv = sc_pkcs15_verify_pin_with_session_pin ( p15card , pin_obj , pin1 , pin1len , pin2 , pin2len ) ;
break ;
2015-04-19 17:51:22 +00:00
case SC_PIN_CMD_CHANGE :
2017-03-01 16:53:44 +00:00
rv = sc_pkcs15_change_pin ( p15card , pin_obj , pin1 , pin1len , pin2 , pin2len ? * pin2len : 0 ) ;
2015-04-19 17:51:22 +00:00
break ;
case SC_PIN_CMD_UNBLOCK :
2017-03-01 16:53:44 +00:00
rv = sc_pkcs15_unblock_pin ( p15card , pin_obj , pin1 , pin1len , pin2 , pin2len ? * pin2len : 0 ) ;
2015-04-19 17:51:22 +00:00
break ;
default :
rv = ( DWORD ) ERROR_INVALID_PARAMETER ;
break ;
}
2017-01-13 18:40:03 +00:00
if ( parameter [ 10 ] ! = 0 ) {
EndDialog ( ( HWND ) parameter [ 10 ] , rv ) ;
2015-04-19 17:51:22 +00:00
}
return ( DWORD ) rv ;
}
2017-02-09 12:44:07 +00:00
static INT_PTR CALLBACK md_dialog_proc ( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam , LONG_PTR dwRefData )
2015-04-19 17:51:22 +00:00
{
2017-02-09 12:44:07 +00:00
UNREFERENCED_PARAMETER ( lParam ) ;
switch ( message ) {
case TDN_CREATED :
2015-05-02 21:44:05 +00:00
{
2017-02-09 12:44:07 +00:00
/* remove the icon from the window title */
SendMessage ( hWnd , WM_SETICON , ( LPARAM ) ICON_BIG , ( LONG_PTR ) NULL ) ;
SendMessage ( hWnd , WM_SETICON , ( LPARAM ) ICON_SMALL , ( LONG_PTR ) NULL ) ;
/* store parameter like pCardData for further use if needed */
SetWindowLongPtr ( hWnd , GWLP_USERDATA , dwRefData ) ;
/* launch the function in another thread context store the thread handle */
( ( LONG_PTR * ) dwRefData ) [ 10 ] = ( LONG_PTR ) hWnd ;
( ( LONG_PTR * ) dwRefData ) [ 9 ] = ( LONG_PTR ) CreateThread ( NULL , 0 , md_dialog_perform_pin_operation_thread , ( LPVOID ) dwRefData , 0 , NULL ) ;
2015-05-02 21:44:05 +00:00
}
2017-02-09 12:44:07 +00:00
case TDN_TIMER :
// progress bar 30 seconds.
SendMessage ( hWnd , TDM_SET_PROGRESS_BAR_POS , wParam / 300 , 0L ) ;
/* continue the tickcount */
return S_OK ;
case TDN_BUTTON_CLICKED :
{
/* We ignore anything else than the Cancel button */
if ( LOWORD ( wParam ) ! = IDCANCEL )
return S_FALSE ;
LONG_PTR param = GetWindowLongPtr ( hWnd , GWLP_USERDATA ) ;
if ( param ) {
PCARD_DATA pCardData = ( PCARD_DATA ) ( ( LONG_PTR * ) param ) [ 7 ] ;
VENDOR_SPECIFIC * vs = ( VENDOR_SPECIFIC * ) pCardData - > pvVendorSpecific ;
sc_cancel ( vs - > ctx ) ;
2017-01-13 18:40:03 +00:00
}
}
2017-02-09 12:44:07 +00:00
/* Some readers don't support SCardCancel, though they're
* reporting SCARD_S_SUCCESS . We force closing of the dialog so
* that at least the application can continue . */
return S_OK ;
case TDN_DESTROYED :
{
/* clean resources used */
LONG_PTR param = GetWindowLongPtr ( hWnd , GWLP_USERDATA ) ;
if ( param ) {
HANDLE hThread = ( HANDLE ) ( ( LONG_PTR * ) param ) [ 9 ] ;
CloseHandle ( hThread ) ;
}
2015-04-19 17:51:22 +00:00
}
2017-02-09 12:44:07 +00:00
break ;
2015-04-19 17:51:22 +00:00
}
2017-02-09 12:44:07 +00:00
/* don't close the Task Dialog */
return S_FALSE ;
2015-04-19 17:51:22 +00:00
}
static int
md_dialog_perform_pin_operation ( PCARD_DATA pCardData , int operation , struct sc_pkcs15_card * p15card ,
2015-10-16 07:58:01 +00:00
struct sc_pkcs15_object * pin_obj ,
const u8 * pin1 , size_t pin1len ,
2017-01-13 18:40:03 +00:00
const u8 * pin2 , size_t * pin2len , BOOL displayUI , DWORD role )
2015-04-19 17:51:22 +00:00
{
2017-01-13 18:40:03 +00:00
LONG_PTR parameter [ 11 ] ;
2015-04-19 17:51:22 +00:00
INT_PTR result = 0 ;
2017-02-09 12:44:07 +00:00
HWND hWndDlg = 0 ;
TASKDIALOGCONFIG tc = { 0 } ;
2015-04-19 17:51:22 +00:00
int rv = 0 ;
VENDOR_SPECIFIC * pv = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2017-02-09 12:44:07 +00:00
LANGID lang = GetUserDefaultUILanguage ( ) ;
2015-04-19 17:51:22 +00:00
/* stack the parameters */
parameter [ 0 ] = ( LONG_PTR ) operation ;
parameter [ 1 ] = ( LONG_PTR ) p15card ;
parameter [ 2 ] = ( LONG_PTR ) pin_obj ;
parameter [ 3 ] = ( LONG_PTR ) pin1 ;
parameter [ 4 ] = ( LONG_PTR ) pin1len ;
parameter [ 5 ] = ( LONG_PTR ) pin2 ;
parameter [ 6 ] = ( LONG_PTR ) pin2len ;
parameter [ 7 ] = ( LONG_PTR ) pCardData ;
2017-01-13 18:40:03 +00:00
parameter [ 8 ] = ( LONG_PTR ) role ;
parameter [ 9 ] = 0 ; /* place holder for thread handle */
parameter [ 10 ] = 0 ; /* place holder for window handle */
2017-02-09 12:44:07 +00:00
2015-04-19 17:51:22 +00:00
/* launch the function to perform in the same thread context */
if ( ! displayUI ) {
rv = md_dialog_perform_pin_operation_thread ( parameter ) ;
SecureZeroMemory ( parameter , sizeof ( parameter ) ) ;
return rv ;
}
2017-02-09 12:44:07 +00:00
2015-04-19 17:51:22 +00:00
/* launch the UI in the same thread context than the parent and the function to perform in another thread context
this is the only way to display a modal dialog attached to a parent ( hwndParent ! = 0 ) */
2017-02-09 12:44:07 +00:00
tc . hwndParent = pv - > hwndParent ;
tc . hInstance = g_inst ;
tc . dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER | TDF_EXPAND_FOOTER_AREA | TDF_POSITION_RELATIVE_TO_WINDOW | TDF_USE_HICON_FOOTER ;
tc . dwCommonButtons = TDCBF_CANCEL_BUTTON ;
if ( p15card - > tokeninfo - > preferred_language ) {
/* choose the token's preferred language over the system's language */
if ( strncmp ( p15card - > tokeninfo - > preferred_language , " de " , 2 ) )
lang = LANG_GERMAN | SUBLANG_GERMAN ;
}
if ( lang & LANG_GERMAN ) {
tc . pszWindowTitle = L " Windows-Sicherheit " ;
tc . pszMainInstruction = L " OpenSC Smartcard-Anbieter " ;
switch ( role ) {
case ROLE_ADMIN :
tc . pszContent = L " Bitte geben Sie Ihre PIN zum Entsperren der Nutzer-PIN auf dem PINPAD ein. " ;
break ;
case ROLE_USER :
/* fall through */
default :
tc . pszContent = L " Bitte geben Sie Ihre PIN für die digitale Signatur auf dem PINPAD ein. " ;
break ;
}
tc . pszExpandedInformation = L " Dieses Fenster wird automatisch geschlossen, wenn die PIN am PINPAD eingegeben wurde (Timeout typischerweise nach 30 Sekunden). " ;
tc . pszExpandedControlText = L " Weitere Informationen " ;
tc . pszCollapsedControlText = L " Weitere Informationen " ;
} else {
tc . pszWindowTitle = L " Windows Security " ;
tc . pszMainInstruction = L " OpenSC Smart Card Provider " ;
switch ( role ) {
case ROLE_ADMIN :
tc . pszContent = L " Please enter your PIN to unblock the user PIN on the PINPAD. " ;
break ;
case ROLE_USER :
/* fall through */
default :
tc . pszContent = L " Please enter your digital signature PIN on the PINPAD. " ;
break ;
}
tc . pszExpandedInformation = L " This window will be closed automatically after the PIN has been submitted on the PINPAD (timeout typically after 30 seconds). " ;
tc . pszExpandedControlText = L " Click here for more information " ;
tc . pszCollapsedControlText = L " Click here for more information " ;
}
if ( pv - > wszPinContext ) {
tc . pszMainInstruction = pv - > wszPinContext ;
}
tc . pszMainIcon = MAKEINTRESOURCE ( IDI_SMARTCARD ) ;
tc . cButtons = 0 ;
tc . pButtons = NULL ;
tc . cRadioButtons = 0 ;
tc . pRadioButtons = NULL ;
tc . pfCallback = md_dialog_proc ;
tc . lpCallbackData = ( LONG_PTR ) parameter ;
tc . cbSize = sizeof ( tc ) ;
result = TaskDialogIndirect ( & tc , NULL , NULL , NULL ) ;
2015-04-19 17:51:22 +00:00
SecureZeroMemory ( parameter , sizeof ( parameter ) ) ;
2017-02-09 12:44:07 +00:00
2015-04-25 21:29:03 +00:00
return ( int ) result ;
2015-04-19 17:51:22 +00:00
}
2017-03-14 22:58:03 +00:00
static DWORD md_translate_OpenSC_to_Windows_error ( int OpenSCerror ,
DWORD dwDefaulCode )
2015-04-19 17:51:22 +00:00
{
switch ( OpenSCerror )
{
/* Errors related to reader operation */
case SC_ERROR_READER :
return SCARD_E_PROTO_MISMATCH ;
case SC_ERROR_NO_READERS_FOUND :
return SCARD_E_NO_READERS_AVAILABLE ;
case SC_ERROR_CARD_NOT_PRESENT :
return SCARD_E_NO_SMARTCARD ;
case SC_ERROR_TRANSMIT_FAILED :
return SCARD_E_NOT_TRANSACTED ;
case SC_ERROR_CARD_REMOVED :
return SCARD_W_REMOVED_CARD ;
case SC_ERROR_CARD_RESET :
return SCARD_W_RESET_CARD ;
case SC_ERROR_KEYPAD_CANCELLED :
return SCARD_W_CANCELLED_BY_USER ;
case SC_ERROR_KEYPAD_MSG_TOO_LONG :
return SCARD_W_CARD_NOT_AUTHENTICATED ;
case SC_ERROR_KEYPAD_PIN_MISMATCH :
return SCARD_E_INVALID_CHV ;
case SC_ERROR_KEYPAD_TIMEOUT :
return ERROR_TIMEOUT ;
case SC_ERROR_EVENT_TIMEOUT :
return SCARD_E_TIMEOUT ;
case SC_ERROR_CARD_UNRESPONSIVE :
return SCARD_W_UNRESPONSIVE_CARD ;
case SC_ERROR_READER_LOCKED :
return SCARD_E_SHARING_VIOLATION ;
/* Resulting from a card command or related to the card*/
case SC_ERROR_INCORRECT_PARAMETERS :
return SCARD_E_INVALID_PARAMETER ;
case SC_ERROR_MEMORY_FAILURE :
case SC_ERROR_NOT_ENOUGH_MEMORY :
return SCARD_E_NO_MEMORY ;
case SC_ERROR_NOT_ALLOWED :
return SCARD_W_SECURITY_VIOLATION ;
case SC_ERROR_AUTH_METHOD_BLOCKED :
return SCARD_W_CHV_BLOCKED ;
case SC_ERROR_PIN_CODE_INCORRECT :
return SCARD_W_WRONG_CHV ;
2017-03-14 22:58:03 +00:00
2015-04-19 17:51:22 +00:00
/* Returned by OpenSC library when called with invalid arguments */
2015-04-20 21:25:57 +00:00
case SC_ERROR_INVALID_ARGUMENTS :
return ERROR_INVALID_PARAMETER ;
2015-04-19 17:51:22 +00:00
case SC_ERROR_BUFFER_TOO_SMALL :
return NTE_BUFFER_TOO_SMALL ;
/* Resulting from OpenSC internal operation */
case SC_ERROR_INTERNAL :
return ERROR_INTERNAL_ERROR ;
case SC_ERROR_NOT_SUPPORTED :
return SCARD_E_UNSUPPORTED_FEATURE ;
case SC_ERROR_NOT_IMPLEMENTED :
return ERROR_CALL_NOT_IMPLEMENTED ;
default :
return dwDefaulCode ;
}
}
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardDeleteContext ( __inout PCARD_DATA pCardData )
{
VENDOR_SPECIFIC * vs = NULL ;
2012-05-31 14:40:36 +00:00
if ( md_static_data . attach_check ! = MD_STATIC_PROCESS_ATTACHED )
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 ,
" \n P:%lu T:%lu pCardData:%p hScard=0x%08X hSCardCtx=0x%08X CardDeleteContext \n " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ,
( unsigned int ) pCardData - > hScard ,
( unsigned int ) pCardData - > hSCardCtx ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2010-02-05 13:05:25 +00:00
if ( ! vs )
return SCARD_E_INVALID_PARAMETER ;
2011-02-09 17:52:00 +00:00
disassociate_card ( pCardData ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( vs - > ctx ) {
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 6 , " release context \n " ) ;
2010-02-05 13:05:25 +00:00
sc_release_context ( vs - > ctx ) ;
2012-05-31 14:40:36 +00:00
md_static_data . flags | = MD_STATIC_FLAG_CONTEXT_DELETED ;
2010-02-05 13:05:25 +00:00
vs - > ctx = NULL ;
}
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " ********************************************************************** \n " ) ;
2010-02-05 13:05:25 +00:00
2015-04-12 11:34:18 +00:00
md_fs_finalize ( pCardData ) ;
2010-02-05 13:05:25 +00:00
pCardData - > pfnCspFree ( pCardData - > pvVendorSpecific ) ;
pCardData - > pvVendorSpecific = NULL ;
return SCARD_S_SUCCESS ;
}
2011-04-12 07:40:12 +00:00
DWORD WINAPI CardQueryCapabilities ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__inout PCARD_CAPABILITIES pCardCapabilities )
2010-02-05 13:05:25 +00:00
{
2012-05-31 14:40:36 +00:00
DWORD dwret ;
2011-02-09 17:52:00 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-17 19:39:41 +00:00
logprintf ( pCardData , 1 , " pCardCapabilities=%p \n " , pCardCapabilities ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData | | ! pCardCapabilities )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2015-04-17 16:04:05 +00:00
dwret = md_card_capabilities ( pCardData , pCardCapabilities ) ;
2012-05-31 14:40:36 +00:00
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2010-02-05 13:05:25 +00:00
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
DWORD WINAPI CardDeleteContainer ( __in PCARD_DATA pCardData ,
__in BYTE bContainerIndex ,
__in DWORD dwReserved )
{
2015-09-30 20:52:37 +00:00
VENDOR_SPECIFIC * vs = NULL ;
DWORD dwret ;
struct md_pkcs15_container * cont ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 , " CardDeleteContainer(idx:%u) \n " ,
( unsigned int ) bContainerIndex ) ;
2012-05-31 14:40:36 +00:00
2015-09-30 20:52:37 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( bContainerIndex > = MD_MAX_KEY_CONTAINERS )
return SCARD_E_INVALID_PARAMETER ;
if ( ! md_is_supports_container_key_gen ( pCardData ) ) {
logprintf ( pCardData , 1 , " Denied 'deletion' mechanism to delete container. \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
if ( ! vs )
return SCARD_E_INVALID_PARAMETER ;
cont = & ( vs - > p15_containers [ bContainerIndex ] ) ;
dwret = md_pkcs15_delete_object ( pCardData , cont - > prkey_obj ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 1 , " private key deletion failed \n " ) ;
return dwret ;
}
dwret = md_pkcs15_delete_object ( pCardData , cont - > pubkey_obj ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 1 , " public key deletion failed \n " ) ;
return dwret ;
}
ZeroMemory ( cont , sizeof ( struct md_pkcs15_container ) ) ;
logprintf ( pCardData , 1 , " key deleted \n " ) ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardCreateContainer ( __in PCARD_DATA pCardData ,
__in BYTE bContainerIndex ,
__in DWORD dwFlags ,
__in DWORD dwKeySpec ,
__in DWORD dwKeySize ,
__in PBYTE pbKeyData )
{
2012-05-31 14:40:36 +00:00
DWORD dwret ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardCreateContainerEx(idx:%u,flags:%lX,type:%lX,size:%lu,data:%p) \n " ,
( unsigned int ) bContainerIndex , ( unsigned long ) dwFlags ,
( unsigned long ) dwKeySpec , ( unsigned long ) dwKeySize , pbKeyData ) ;
2012-05-31 14:40:36 +00:00
if ( pbKeyData ) {
logprintf ( pCardData , 7 , " Key data \n " ) ;
loghex ( pCardData , 7 , pbKeyData , dwKeySize ) ;
}
dwret = md_check_key_compatibility ( pCardData , dwFlags , dwKeySpec , dwKeySize , pbKeyData ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " check key compatibility failed \n " ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
}
2013-12-29 11:53:41 +00:00
if ( ! md_is_supports_container_key_gen ( pCardData ) ) {
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " Denied 'generate key' mechanism to create container. \n " ) ;
2013-12-29 11:53:41 +00:00
dwFlags & = ~ CARD_CREATE_CONTAINER_KEY_GEN ;
}
if ( ! md_is_supports_container_key_import ( pCardData ) ) {
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " Denied 'import key' mechanism to create container. \n " ) ;
2013-12-29 11:53:41 +00:00
dwFlags & = ~ CARD_CREATE_CONTAINER_KEY_IMPORT ;
}
if ( ! dwFlags ) {
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " Unsupported create container mechanism. \n " ) ;
2013-12-29 11:53:41 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
2012-05-31 14:40:36 +00:00
if ( dwFlags & CARD_CREATE_CONTAINER_KEY_GEN ) {
dwret = md_pkcs15_generate_key ( pCardData , bContainerIndex , dwKeySpec , dwKeySize ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " key generation failed \n " ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
}
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " key generated \n " ) ;
2012-05-31 14:40:36 +00:00
}
else if ( ( dwFlags & CARD_CREATE_CONTAINER_KEY_IMPORT ) & & ( pbKeyData ! = NULL ) ) {
dwret = md_pkcs15_store_key ( pCardData , bContainerIndex , dwKeySpec , pbKeyData , dwKeySize ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " key store failed \n " ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
}
2013-12-29 11:54:36 +00:00
logprintf ( pCardData , 1 , " key imported \n " ) ;
2012-05-31 14:40:36 +00:00
}
else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " Invalid dwFlags value: 0x%lX \n " ,
( unsigned long ) dwFlags ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
typedef struct {
PUBLICKEYSTRUC publickeystruc ;
RSAPUBKEY rsapubkey ;
2015-09-25 20:22:29 +00:00
} PUBRSAKEYSTRUCT_BASE ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
DWORD WINAPI CardGetContainerInfo ( __in PCARD_DATA pCardData , __in BYTE bContainerIndex , __in DWORD dwFlags ,
2015-04-17 19:39:41 +00:00
__inout PCONTAINER_INFO pContainerInfo )
2010-02-05 13:05:25 +00:00
{
VENDOR_SPECIFIC * vs = NULL ;
2013-09-25 19:36:33 +00:00
DWORD sz = 0 ;
DWORD ret = SCARD_F_UNKNOWN_ERROR ;
2012-05-31 14:40:36 +00:00
struct md_pkcs15_container * cont = NULL ;
struct sc_pkcs15_der pubkey_der ;
2015-09-25 20:22:29 +00:00
struct sc_pkcs15_prkey_info * prkey_info = NULL ;
2012-05-31 14:40:36 +00:00
int rv ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pContainerInfo )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardGetContainerInfo bContainerIndex=%u, dwFlags=0x%08X, dwVersion=%lu, cbSigPublicKey=%lu, cbKeyExPublicKey=%lu \n " ,
( unsigned int ) bContainerIndex , ( unsigned int ) dwFlags ,
( unsigned long ) pContainerInfo - > dwVersion ,
( unsigned long ) pContainerInfo - > cbSigPublicKey ,
( unsigned long ) pContainerInfo - > cbKeyExPublicKey ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( dwFlags )
return SCARD_E_INVALID_PARAMETER ;
if ( bContainerIndex > = MD_MAX_KEY_CONTAINERS )
return SCARD_E_NO_KEY_CONTAINER ;
2017-01-25 22:27:27 +00:00
if ( pContainerInfo - > dwVersion > CONTAINER_INFO_CURRENT_VERSION )
2012-05-31 14:40:36 +00:00
return ERROR_REVISION_MISMATCH ;
pContainerInfo - > dwVersion = CONTAINER_INFO_CURRENT_VERSION ;
2010-02-05 13:05:25 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2012-05-31 14:40:36 +00:00
cont = & vs - > p15_containers [ bContainerIndex ] ;
if ( ! cont - > prkey_obj ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 , " Container %u is empty \n " ,
( unsigned int ) bContainerIndex ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_NO_KEY_CONTAINER ;
}
2011-04-12 07:40:12 +00:00
2015-10-15 20:40:36 +00:00
if ( vs - > p15card = = NULL ) {
return SCARD_F_INTERNAL_ERROR ;
}
2015-09-25 20:22:29 +00:00
prkey_info = ( struct sc_pkcs15_prkey_info * ) cont - > prkey_obj - > data ;
2015-05-08 13:49:30 +00:00
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2012-05-31 14:40:36 +00:00
pubkey_der . value = NULL ;
pubkey_der . len = 0 ;
2011-02-09 17:52:00 +00:00
2013-09-25 19:36:33 +00:00
if ( ( cont - > prkey_obj - > content . value ! = NULL ) & & ( cont - > prkey_obj - > content . len > 0 ) ) {
2012-05-31 14:40:36 +00:00
sc_der_copy ( & pubkey_der , & cont - > prkey_obj - > content ) ;
2013-09-25 19:36:33 +00:00
ret = SCARD_S_SUCCESS ;
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pubkey_der . value & & cont - > pubkey_obj ) {
struct sc_pkcs15_pubkey * pubkey = NULL ;
2015-10-04 15:33:14 +00:00
logprintf ( pCardData , 1 , " now read public key '%.*s' \n " , ( int ) sizeof cont - > pubkey_obj - > label , cont - > pubkey_obj - > label ) ;
2012-05-31 14:40:36 +00:00
rv = sc_pkcs15_read_pubkey ( vs - > p15card , cont - > pubkey_obj , & pubkey ) ;
if ( ! rv ) {
2014-02-02 21:16:00 +00:00
rv = sc_pkcs15_encode_pubkey ( vs - > ctx , pubkey , & pubkey_der . value , & pubkey_der . len ) ;
if ( rv ) {
logprintf ( pCardData , 1 , " encode public key error %d \n " , rv ) ;
ret = SCARD_F_INTERNAL_ERROR ;
2013-09-25 19:36:33 +00:00
}
2014-05-13 12:57:01 +00:00
else {
logprintf ( pCardData , 1 , " public key encoded \n " ) ;
ret = SCARD_S_SUCCESS ;
}
2012-05-31 14:40:36 +00:00
sc_pkcs15_free_pubkey ( pubkey ) ;
}
else {
logprintf ( pCardData , 1 , " public key read error %d \n " , rv ) ;
ret = SCARD_E_FILE_NOT_FOUND ;
}
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
if ( ! pubkey_der . value & & cont - > cert_obj ) {
struct sc_pkcs15_cert * cert = NULL ;
2015-10-04 15:33:14 +00:00
logprintf ( pCardData , 1 , " now read certificate '%.*s' \n " , ( int ) sizeof cont - > cert_obj - > label , cont - > cert_obj - > label ) ;
2012-05-31 14:40:36 +00:00
rv = sc_pkcs15_read_certificate ( vs - > p15card , ( struct sc_pkcs15_cert_info * ) ( cont - > cert_obj - > data ) , & cert ) ;
if ( ! rv ) {
2014-02-02 21:16:00 +00:00
rv = sc_pkcs15_encode_pubkey ( vs - > ctx , cert - > key , & pubkey_der . value , & pubkey_der . len ) ;
if ( rv ) {
logprintf ( pCardData , 1 , " encode certificate public key error %d \n " , rv ) ;
ret = SCARD_F_INTERNAL_ERROR ;
2013-09-25 19:36:33 +00:00
}
2014-05-13 12:57:01 +00:00
else {
logprintf ( pCardData , 1 , " certificate public key encoded \n " ) ;
ret = SCARD_S_SUCCESS ;
}
2014-02-02 21:16:00 +00:00
2012-05-31 14:40:36 +00:00
sc_pkcs15_free_certificate ( cert ) ;
}
else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 ,
" certificate '%u' read error %d \n " ,
( unsigned int ) bContainerIndex , rv ) ;
2012-05-31 14:40:36 +00:00
ret = SCARD_E_FILE_NOT_FOUND ;
}
}
if ( ! pubkey_der . value & & ( cont - > size_sign | | cont - > size_key_exchange ) ) {
logprintf ( pCardData , 2 , " cannot find public key \n " ) ;
return SCARD_F_INTERNAL_ERROR ;
}
if ( ret ! = SCARD_S_SUCCESS ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 ,
" GetContainerInfo(idx:%u) failed; error %lX " ,
( unsigned int ) bContainerIndex , ( unsigned long ) ret ) ;
2012-05-31 14:40:36 +00:00
return ret ;
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " SubjectPublicKeyInfo: \n " ) ;
loghex ( pCardData , 7 , pubkey_der . value , pubkey_der . len ) ;
2011-02-09 17:52:00 +00:00
2015-09-25 20:22:29 +00:00
if ( prkey_info - > modulus_length > 0 ) {
logprintf ( pCardData , 7 , " Encoding RSA public key " ) ;
if ( pubkey_der . len & & pubkey_der . value ) {
sz = 0 ; /* get size */
CryptDecodeObject ( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , RSA_CSP_PUBLICKEYBLOB ,
pubkey_der . value , ( DWORD ) pubkey_der . len , 0 , NULL , & sz ) ;
2012-05-31 14:40:36 +00:00
2015-09-25 20:22:29 +00:00
if ( cont - > size_sign ) {
2015-10-15 20:40:36 +00:00
PUBRSAKEYSTRUCT_BASE * publicKey = ( PUBRSAKEYSTRUCT_BASE * ) pCardData - > pfnCspAlloc ( sz ) ;
if ( ! publicKey )
2015-09-25 20:22:29 +00:00
return SCARD_E_NO_MEMORY ;
2012-05-31 14:40:36 +00:00
2015-09-25 20:22:29 +00:00
CryptDecodeObject ( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , RSA_CSP_PUBLICKEYBLOB ,
2015-10-15 20:40:36 +00:00
pubkey_der . value , ( DWORD ) pubkey_der . len , 0 , publicKey , & sz ) ;
2011-04-12 07:40:12 +00:00
2015-10-15 20:40:36 +00:00
publicKey - > publickeystruc . aiKeyAlg = CALG_RSA_SIGN ;
2015-09-25 20:22:29 +00:00
pContainerInfo - > cbSigPublicKey = sz ;
2015-10-15 20:40:36 +00:00
pContainerInfo - > pbSigPublicKey = ( PBYTE ) publicKey ;
2011-02-09 17:52:00 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" return info on SIGN_CONTAINER_INDEX %u \n " ,
( unsigned int ) bContainerIndex ) ;
2015-09-25 20:22:29 +00:00
}
if ( cont - > size_key_exchange ) {
2015-10-15 20:40:36 +00:00
PUBRSAKEYSTRUCT_BASE * publicKey = ( PUBRSAKEYSTRUCT_BASE * ) pCardData - > pfnCspAlloc ( sz ) ;
if ( ! publicKey )
2015-09-25 20:22:29 +00:00
return SCARD_E_NO_MEMORY ;
CryptDecodeObject ( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , RSA_CSP_PUBLICKEYBLOB ,
2015-10-15 20:40:36 +00:00
pubkey_der . value , ( DWORD ) pubkey_der . len , 0 , publicKey , & sz ) ;
2015-09-25 20:22:29 +00:00
2015-10-15 20:40:36 +00:00
publicKey - > publickeystruc . aiKeyAlg = CALG_RSA_KEYX ;
2015-09-25 20:22:29 +00:00
pContainerInfo - > cbKeyExPublicKey = sz ;
2015-10-15 20:40:36 +00:00
pContainerInfo - > pbKeyExPublicKey = ( PBYTE ) publicKey ;
2015-09-25 20:22:29 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" return info on KEYX_CONTAINER_INDEX %u \n " ,
( unsigned int ) bContainerIndex ) ;
2015-09-25 20:22:29 +00:00
}
2012-05-31 14:40:36 +00:00
}
2015-09-25 20:22:29 +00:00
} else if ( prkey_info - > field_length > 0 ) {
logprintf ( pCardData , 7 , " Encoding ECC public key " ) ;
if ( pubkey_der . len > 2 & & pubkey_der . value & & pubkey_der . value [ 0 ] = = 4 & & pubkey_der . value [ 1 ] = = pubkey_der . len - 2 ) {
2015-10-15 20:40:36 +00:00
BCRYPT_ECCKEY_BLOB * publicKey = NULL ;
2015-09-25 20:22:29 +00:00
DWORD dwMagic = 0 ;
if ( cont - > size_sign ) {
sz = ( DWORD ) ( sizeof ( BCRYPT_ECCKEY_BLOB ) + pubkey_der . len - 3 ) ;
switch ( cont - > size_sign )
{
case 256 :
dwMagic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC ;
break ;
case 384 :
dwMagic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC ;
break ;
case 521 :
dwMagic = BCRYPT_ECDSA_PUBLIC_P521_MAGIC ;
break ;
default :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" Unable to match the ECC public size to one of Microsoft algorithm % " SC_FORMAT_LEN_SIZE_T " u \n " ,
cont - > size_sign ) ;
2015-09-25 20:22:29 +00:00
return SCARD_F_INTERNAL_ERROR ;
}
2011-02-09 17:52:00 +00:00
2015-10-15 20:40:36 +00:00
publicKey = ( BCRYPT_ECCKEY_BLOB * ) pCardData - > pfnCspAlloc ( sz ) ;
if ( ! publicKey )
2015-09-25 20:22:29 +00:00
return SCARD_E_NO_MEMORY ;
2011-02-09 17:52:00 +00:00
2015-10-15 20:40:36 +00:00
publicKey - > cbKey = ( DWORD ) ( pubkey_der . len - 3 ) / 2 ;
publicKey - > dwMagic = dwMagic ;
2010-02-05 13:05:25 +00:00
2015-09-25 20:22:29 +00:00
pContainerInfo - > cbSigPublicKey = sz ;
2015-10-15 20:40:36 +00:00
pContainerInfo - > pbSigPublicKey = ( PBYTE ) publicKey ;
memcpy ( ( ( PBYTE ) publicKey ) + sizeof ( BCRYPT_ECCKEY_BLOB ) , pubkey_der . value + 3 , pubkey_der . len - 3 ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" return info on ECC SIGN_CONTAINER_INDEX %u \n " ,
( unsigned int ) bContainerIndex ) ;
2015-09-25 20:22:29 +00:00
}
if ( cont - > size_key_exchange ) {
sz = ( DWORD ) ( sizeof ( BCRYPT_ECCKEY_BLOB ) + pubkey_der . len - 3 ) ;
switch ( cont - > size_key_exchange )
{
case 256 :
dwMagic = BCRYPT_ECDH_PUBLIC_P256_MAGIC ;
break ;
case 384 :
dwMagic = BCRYPT_ECDH_PUBLIC_P384_MAGIC ;
break ;
case 521 :
dwMagic = BCRYPT_ECDH_PUBLIC_P521_MAGIC ;
break ;
default :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" Unable to match the ECC public size to one of Microsoft algorithm % " SC_FORMAT_LEN_SIZE_T " u \n " ,
cont - > size_key_exchange ) ;
2015-09-25 20:22:29 +00:00
return SCARD_F_INTERNAL_ERROR ;
}
2010-02-05 13:05:25 +00:00
2015-10-15 20:40:36 +00:00
publicKey = ( BCRYPT_ECCKEY_BLOB * ) pCardData - > pfnCspAlloc ( sz ) ;
if ( ! publicKey )
2015-09-25 20:22:29 +00:00
return SCARD_E_NO_MEMORY ;
2015-10-15 20:40:36 +00:00
publicKey - > cbKey = ( DWORD ) ( pubkey_der . len - 3 ) / 2 ;
publicKey - > dwMagic = dwMagic ;
2015-09-25 20:22:29 +00:00
pContainerInfo - > cbKeyExPublicKey = sz ;
2015-10-15 20:40:36 +00:00
pContainerInfo - > pbKeyExPublicKey = ( PBYTE ) publicKey ;
memcpy ( ( ( PBYTE ) publicKey ) + sizeof ( BCRYPT_ECCKEY_BLOB ) , pubkey_der . value + 3 , pubkey_der . len - 3 ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" return info on ECC KEYX_CONTAINER_INDEX %u \n " ,
( unsigned int ) bContainerIndex ) ;
2015-09-25 20:22:29 +00:00
}
2012-05-31 14:40:36 +00:00
}
2010-02-05 13:05:25 +00:00
}
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 , " returns container(idx:%u) info " ,
( unsigned int ) bContainerIndex ) ;
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardAuthenticatePin ( __in PCARD_DATA pCardData ,
__in LPWSTR pwszUserId ,
2015-04-17 19:39:41 +00:00
__in_bcount ( cbPin ) PBYTE pbPin ,
2010-02-05 13:05:25 +00:00
__in DWORD cbPin ,
__out_opt PDWORD pcAttemptsRemaining )
{
2015-04-17 19:39:41 +00:00
PIN_ID PinId = 0 ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 , " CardAuthenticatePin '%S':%lu \n " ,
NULLWSTR ( pwszUserId ) , ( unsigned long ) cbPin ) ;
2011-02-09 17:52:00 +00:00
2015-04-17 19:39:41 +00:00
if ( wcscmp ( pwszUserId , wszCARD_USER_USER ) = = 0 ) {
PinId = ROLE_USER ;
2011-05-11 16:52:13 +00:00
}
2015-04-17 19:39:41 +00:00
else if ( wcscmp ( pwszUserId , wszCARD_USER_ADMIN ) = = 0 ) {
PinId = ROLE_ADMIN ;
2010-02-05 13:05:25 +00:00
}
2015-04-17 19:39:41 +00:00
else {
return SCARD_E_INVALID_PARAMETER ;
}
if ( pbPin = = NULL )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2015-04-19 17:51:22 +00:00
return CardAuthenticateEx ( pCardData , PinId , CARD_PIN_SILENT_CONTEXT , pbPin , cbPin , NULL , NULL , pcAttemptsRemaining ) ;
2010-02-05 13:05:25 +00:00
}
2013-12-19 08:34:52 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardGetChallenge ( __in PCARD_DATA pCardData ,
__deref_out_bcount ( * pcbChallengeData ) PBYTE * ppbChallengeData ,
__out PDWORD pcbChallengeData )
{
2013-12-19 08:34:52 +00:00
VENDOR_SPECIFIC * vs ;
int rv ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2013-12-19 08:34:52 +00:00
logprintf ( pCardData , 1 , " CardGetChallenge \n " ) ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( ! ppbChallengeData | | ! pcbChallengeData )
return SCARD_E_INVALID_PARAMETER ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
check_reader_status ( pCardData ) ;
2015-04-17 19:39:41 +00:00
* pcbChallengeData = 8 ;
2013-12-19 08:34:52 +00:00
2015-04-17 19:39:41 +00:00
* ppbChallengeData = ( PBYTE ) pCardData - > pfnCspAlloc ( 8 ) ;
if ( ! * ppbChallengeData )
2013-12-19 08:34:52 +00:00
return SCARD_E_NO_MEMORY ;
2015-04-17 19:39:41 +00:00
rv = sc_get_challenge ( vs - > p15card - > card , * ppbChallengeData , 8 ) ;
2013-12-19 08:34:52 +00:00
if ( rv ) {
logprintf ( pCardData , 1 , " Get challenge failed: %s \n " , sc_strerror ( rv ) ) ;
2015-04-17 19:39:41 +00:00
pCardData - > pfnCspFree ( * ppbChallengeData ) ;
* ppbChallengeData = NULL ;
2013-12-19 08:34:52 +00:00
return SCARD_E_UNEXPECTED ;
}
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 , " returns %lu bytes: \n " ,
( unsigned long ) * pcbChallengeData ) ;
2013-12-19 08:34:52 +00:00
loghex ( pCardData , 7 , * ppbChallengeData , * pcbChallengeData ) ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2013-12-19 08:34:52 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardAuthenticateChallenge ( __in PCARD_DATA pCardData ,
__in_bcount ( cbResponseData ) PBYTE pbResponseData ,
__in DWORD cbResponseData ,
__out_opt PDWORD pcAttemptsRemaining )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 1 , " CardAuthenticateChallenge - unsupported \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
2013-12-19 08:34:52 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardUnblockPin ( __in PCARD_DATA pCardData ,
__in LPWSTR pwszUserId ,
__in_bcount ( cbAuthenticationData ) PBYTE pbAuthenticationData ,
__in DWORD cbAuthenticationData ,
__in_bcount ( cbNewPinData ) PBYTE pbNewPinData ,
__in DWORD cbNewPinData ,
__in DWORD cRetryCount ,
__in DWORD dwFlags )
{
2013-12-19 12:08:03 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2013-12-19 12:08:03 +00:00
logprintf ( pCardData , 1 , " CardUnblockPin \n " ) ;
2016-08-25 20:41:58 +00:00
if ( pwszUserId = = NULL ) {
logprintf ( pCardData , 1 , " no user ID \n " ) ;
2013-12-19 12:08:03 +00:00
return SCARD_E_INVALID_PARAMETER ;
2016-08-25 20:41:58 +00:00
}
if ( wcscmp ( wszCARD_USER_USER , pwszUserId ) ! = 0 & & wcscmp ( wszCARD_USER_ADMIN , pwszUserId ) ! = 0 ) {
logprintf ( pCardData , 1 , " unknown user ID %S \n " , pwszUserId ) ;
2013-12-19 12:08:03 +00:00
return SCARD_E_INVALID_PARAMETER ;
2016-08-25 20:41:58 +00:00
}
if ( wcscmp ( wszCARD_USER_ADMIN , pwszUserId ) = = 0 ) {
logprintf ( pCardData , 1 , " unlocking admin not supported \n " ) ;
2015-04-18 17:09:45 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
2016-08-25 20:41:58 +00:00
}
if ( dwFlags & CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE ) {
logprintf ( pCardData , 1 ,
" challenge / response not supported, we'll treat response as a PUK \n " ) ;
logprintf ( pCardData , 1 ,
" note that you'll need to type PUK in hex (replace every PUK digit X with '3X') in Win CAD unblock dialog response field \n " ) ;
dwFlags & = ~ CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE ;
}
if ( dwFlags ) {
logprintf ( pCardData , 1 , " flags of %x not supported \n " ,
( unsigned int ) dwFlags ) ;
2015-04-18 17:09:45 +00:00
return SCARD_E_INVALID_PARAMETER ;
2016-08-25 20:41:58 +00:00
}
2013-12-19 12:08:03 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 ,
" UserID('%S'), AuthData(%p, %lu), NewPIN(%p, %lu), Retry(%lu), dwFlags(0x%lX) \n " ,
pwszUserId , pbAuthenticationData ,
( unsigned long ) cbAuthenticationData , pbNewPinData ,
( unsigned long ) cbNewPinData , ( unsigned long ) cRetryCount ,
( unsigned long ) dwFlags ) ;
return CardChangeAuthenticatorEx ( pCardData ,
PIN_CHANGE_FLAG_UNBLOCK |
CARD_PIN_SILENT_CONTEXT ,
ROLE_ADMIN , pbAuthenticationData ,
cbAuthenticationData , ROLE_USER ,
pbNewPinData , cbNewPinData ,
cRetryCount , NULL ) ;
2010-02-05 13:05:25 +00:00
}
2013-12-19 12:08:03 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardChangeAuthenticator ( __in PCARD_DATA pCardData ,
__in LPWSTR pwszUserId ,
__in_bcount ( cbCurrentAuthenticator ) PBYTE pbCurrentAuthenticator ,
__in DWORD cbCurrentAuthenticator ,
__in_bcount ( cbNewAuthenticator ) PBYTE pbNewAuthenticator ,
__in DWORD cbNewAuthenticator ,
__in DWORD cRetryCount ,
__in DWORD dwFlags ,
__out_opt PDWORD pcAttemptsRemaining )
{
2015-04-18 17:09:45 +00:00
PIN_ID pinid ;
2013-12-22 17:05:32 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2013-12-22 17:05:32 +00:00
logprintf ( pCardData , 1 , " CardChangeAuthenticator \n " ) ;
if ( pwszUserId = = NULL )
return SCARD_E_INVALID_PARAMETER ;
2015-04-18 17:09:45 +00:00
if ( dwFlags = = CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE ) {
2013-12-22 17:05:32 +00:00
logprintf ( pCardData , 1 , " Other then 'authentication' the PIN are not supported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
2015-04-18 17:09:45 +00:00
else if ( dwFlags ! = CARD_AUTHENTICATE_PIN_PIN ) {
return SCARD_E_INVALID_PARAMETER ;
}
2013-12-22 17:05:32 +00:00
if ( wcscmp ( wszCARD_USER_USER , pwszUserId ) ! = 0 & & wcscmp ( wszCARD_USER_ADMIN , pwszUserId ) ! = 0 )
return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 ,
" UserID('%S'), CurrentPIN(%p, %lu), NewPIN(%p, %lu), Retry(%lu), dwFlags(0x%lX) \n " ,
pwszUserId , pbCurrentAuthenticator ,
( unsigned long ) cbCurrentAuthenticator , pbNewAuthenticator ,
( unsigned long ) cbNewAuthenticator , ( unsigned long ) cRetryCount ,
( unsigned long ) dwFlags ) ;
2013-12-22 17:05:32 +00:00
if ( wcscmp ( wszCARD_USER_USER , pwszUserId ) = = 0 )
2015-04-18 17:09:45 +00:00
pinid = ROLE_USER ;
2013-12-22 17:05:32 +00:00
else
2015-04-18 17:09:45 +00:00
pinid = ROLE_ADMIN ;
2013-12-22 17:05:32 +00:00
2017-03-14 21:56:39 +00:00
return CardChangeAuthenticatorEx ( pCardData , PIN_CHANGE_FLAG_CHANGEPIN |
CARD_PIN_SILENT_CONTEXT , pinid ,
pbCurrentAuthenticator ,
cbCurrentAuthenticator , pinid ,
pbNewAuthenticator , cbNewAuthenticator ,
cRetryCount , pcAttemptsRemaining ) ;
2010-02-05 13:05:25 +00:00
}
2015-04-09 20:29:50 +00:00
/* this function is not called on purpose.
If a deauthentication is not possible , it should be set to NULL in CardAcquireContext .
Because this function do nothing - it is not called .
Note : the PIN freshnesh will be managed by the Base CSP */
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardDeauthenticate ( __in PCARD_DATA pCardData ,
__in LPWSTR pwszUserId ,
__in DWORD dwFlags )
{
2015-12-09 20:41:37 +00:00
VENDOR_SPECIFIC * vs = NULL ;
int rv ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%ld T:%ld pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 , " CardDeauthenticate(%S) %lu \n " ,
NULLWSTR ( pwszUserId ) , ( unsigned long ) dwFlags ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2015-12-09 20:41:37 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
sc_pkcs15_pincache_clear ( vs - > p15card ) ;
2015-04-09 20:29:50 +00:00
2015-12-09 20:41:37 +00:00
rv = sc_logout ( vs - > p15card - > card ) ;
if ( rv ! = SC_SUCCESS )
return SCARD_E_UNSUPPORTED_FEATURE ;
2015-04-09 20:29:50 +00:00
/* force a reset of a card - SCARD_S_SUCCESS do not lead to the reset of the card and leave it still authenticated */
2015-12-09 20:41:37 +00:00
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardCreateDirectory ( __in PCARD_DATA pCardData ,
__in LPSTR pszDirectoryName ,
__in CARD_DIRECTORY_ACCESS_CONDITION AccessCondition )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 1 , " CardCreateDirectory - unsupported \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
DWORD WINAPI CardDeleteDirectory ( __in PCARD_DATA pCardData ,
__in LPSTR pszDirectoryName )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " CardDeleteDirectory(%s) - unsupported \n " , NULLSTR ( pszDirectoryName ) ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
DWORD WINAPI CardCreateFile ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__in_opt LPSTR pszDirectoryName ,
2010-02-05 13:05:25 +00:00
__in LPSTR pszFileName ,
__in DWORD cbInitialCreationSize ,
__in CARD_FILE_ACCESS_CONDITION AccessCondition )
{
2012-05-31 14:40:36 +00:00
struct md_directory * dir = NULL ;
DWORD dwret ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardCreateFile(%s::%s, size %lu, acl:0x%X) called \n " ,
NULLSTR ( pszDirectoryName ) , NULLSTR ( pszFileName ) ,
( unsigned long ) cbInitialCreationSize , AccessCondition ) ;
2012-05-31 14:40:36 +00:00
dwret = md_fs_find_directory ( pCardData , NULL , pszDirectoryName , & dir ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 1 , " CardCreateFile() cannot find parent directory '%s' " , NULLSTR ( pszDirectoryName ) ) ;
return dwret ;
}
dwret = md_fs_add_file ( pCardData , & dir - > files , pszFileName , AccessCondition , NULL , cbInitialCreationSize , NULL ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardReadFile ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__in_opt LPSTR pszDirectoryName ,
2010-02-05 13:05:25 +00:00
__in LPSTR pszFileName ,
__in DWORD dwFlags ,
2015-04-17 19:39:41 +00:00
__deref_out_bcount_opt ( * pcbData ) PBYTE * ppbData ,
2010-02-05 13:05:25 +00:00
__out PDWORD pcbData )
{
2012-05-31 14:40:36 +00:00
struct md_file * file = NULL ;
2010-02-05 13:05:25 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 1 , " CardReadFile \n " ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
2017-03-14 22:58:03 +00:00
" pszDirectoryName = %s, pszFileName = %s, dwFlags = %lX, pcbData=%p, ppbData=%p \n " ,
2017-03-14 21:56:39 +00:00
NULLSTR ( pszDirectoryName ) , NULLSTR ( pszFileName ) ,
2017-03-14 22:58:03 +00:00
( unsigned long ) dwFlags , pcbData , ppbData ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pszFileName | | ! strlen ( pszFileName ) )
return SCARD_E_INVALID_PARAMETER ;
if ( dwFlags )
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2012-05-31 14:40:36 +00:00
md_fs_find_file ( pCardData , pszDirectoryName , pszFileName , & file ) ;
if ( ! file ) {
logprintf ( pCardData , 2 , " CardReadFile(): file '%s' not found in '%s' \n " , NULLSTR ( pszFileName ) , NULLSTR ( pszDirectoryName ) ) ;
return SCARD_E_FILE_NOT_FOUND ;
2010-02-05 13:05:25 +00:00
}
2011-04-12 07:40:12 +00:00
2017-03-14 22:58:03 +00:00
if ( ! file - > blob ) {
DWORD dwret ;
2011-04-12 07:40:12 +00:00
2017-03-14 22:58:03 +00:00
dwret = md_fs_read_content ( pCardData , pszDirectoryName , file ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
}
if ( ppbData ) {
* ppbData = pCardData - > pfnCspAlloc ( file - > size ) ;
if ( ! * ppbData )
return SCARD_E_NO_MEMORY ;
memcpy ( * ppbData , file - > blob , file - > size ) ;
}
if ( pcbData )
* pcbData = ( DWORD ) file - > size ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " returns '%s' content: \n " , NULLSTR ( pszFileName ) ) ;
2017-03-14 22:58:03 +00:00
loghex ( pCardData , 7 , file - > blob , file - > size ) ;
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
}
2010-02-05 13:05:25 +00:00
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
DWORD WINAPI CardWriteFile ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__in_opt LPSTR pszDirectoryName ,
2012-05-31 14:40:36 +00:00
__in LPSTR pszFileName ,
__in DWORD dwFlags ,
__in_bcount ( cbData ) PBYTE pbData ,
__in DWORD cbData )
{
struct md_file * file = NULL ;
DWORD dwret ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " CardWriteFile() dirName:'%s', fileName:'%s' \n " , NULLSTR ( pszDirectoryName ) , NULLSTR ( pszFileName ) ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
check_reader_status ( pCardData ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( pbData & & cbData ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " CardWriteFile try to write (%lu): \n " ,
( unsigned long ) cbData ) ;
2012-05-31 14:40:36 +00:00
loghex ( pCardData , 2 , pbData , cbData ) ;
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
md_fs_find_file ( pCardData , pszDirectoryName , pszFileName , & file ) ;
if ( ! file ) {
logprintf ( pCardData , 2 , " CardWriteFile(): file '%s' not found in '%s' \n " , NULLSTR ( pszFileName ) , NULLSTR ( pszDirectoryName ) ) ;
return SCARD_E_FILE_NOT_FOUND ;
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " set content of '%s' to: \n " , NULLSTR ( pszFileName ) ) ;
loghex ( pCardData , 7 , pbData , cbData ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
dwret = md_fs_set_content ( pCardData , file , pbData , cbData ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " cannot set file content: %lu \n " ,
( unsigned long ) dwret ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
}
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( pszDirectoryName & & ! strcmp ( pszDirectoryName , " mscp " ) ) {
2013-12-29 11:41:36 +00:00
if ( ( strstr ( pszFileName , " kxc " ) = = pszFileName ) | | ( strstr ( pszFileName , " ksc " ) = = pszFileName ) ) {
2012-05-31 14:40:36 +00:00
dwret = md_pkcs15_store_certificate ( pCardData , pszFileName , pbData , cbData ) ;
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
logprintf ( pCardData , 2 , " md_pkcs15_store_certificate() OK \n " ) ;
2010-02-05 13:05:25 +00:00
}
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 2 , " write '%s' ok. \n " , NULLSTR ( pszFileName ) ) ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
DWORD WINAPI CardDeleteFile ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__in_opt LPSTR pszDirectoryName ,
2010-02-05 13:05:25 +00:00
__in LPSTR pszFileName ,
2012-05-31 14:40:36 +00:00
__in DWORD dwFlags )
2010-02-05 13:05:25 +00:00
{
2012-05-31 14:40:36 +00:00
DWORD dwret ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " CardDeleteFile(%s, %s) called \n " , NULLSTR ( pszDirectoryName ) , NULLSTR ( pszFileName ) ) ;
2010-02-05 13:05:25 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
check_reader_status ( pCardData ) ;
dwret = md_fs_delete_file ( pCardData , pszDirectoryName , pszFileName ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardDeleteFile(): delete file error: %lX \n " ,
( unsigned long ) dwret ) ;
2012-05-31 14:40:36 +00:00
return dwret ;
2010-02-05 13:05:25 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardEnumFiles ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__in_opt LPSTR pszDirectoryName ,
__deref_out_ecount ( * pdwcbFileName ) LPSTR * pmszFileNames ,
2010-02-05 13:05:25 +00:00
__out LPDWORD pdwcbFileName ,
__in DWORD dwFlags )
{
2012-05-31 14:40:36 +00:00
VENDOR_SPECIFIC * vs = NULL ;
char mstr [ 0x100 ] ;
struct md_directory * dir = NULL ;
struct md_file * file = NULL ;
size_t offs ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " CardEnumFiles() directory '%s' \n " , NULLSTR ( pszDirectoryName ) ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pmszFileNames | | ! pdwcbFileName )
return SCARD_E_INVALID_PARAMETER ;
if ( dwFlags ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 ,
" CardEnumFiles() dwFlags not 'zero' -- %lX \n " ,
( unsigned long ) dwFlags ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
memset ( mstr , 0 , sizeof ( mstr ) ) ;
2010-02-05 13:05:25 +00:00
2011-04-12 07:40:12 +00:00
if ( ! pszDirectoryName | | ! strlen ( pszDirectoryName ) )
2012-05-31 14:40:36 +00:00
dir = & vs - > root ;
else
md_fs_find_directory ( pCardData , NULL , pszDirectoryName , & dir ) ;
if ( ! dir ) {
logprintf ( pCardData , 2 , " enum files() failed: directory '%s' not found \n " , NULLSTR ( pszDirectoryName ) ) ;
return SCARD_E_FILE_NOT_FOUND ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
file = dir - > files ;
for ( offs = 0 ; file ! = NULL & & offs < sizeof ( mstr ) - 10 ; ) {
logprintf ( pCardData , 2 , " enum files(): file name '%s' \n " , file - > name ) ;
2017-03-14 19:39:29 +00:00
strlcpy ( mstr + offs , ( char * ) file - > name , sizeof ( mstr ) - offs ) ;
2017-01-25 22:27:27 +00:00
offs + = strlen ( ( char * ) file - > name ) + 1 ;
2012-05-31 14:40:36 +00:00
file = file - > next ;
2010-02-05 13:05:25 +00:00
}
2015-10-10 20:07:49 +00:00
mstr [ offs ] = 0 ;
2012-05-31 14:40:36 +00:00
offs + = 1 ;
* pmszFileNames = ( LPSTR ) ( * pCardData - > pfnCspAlloc ) ( offs ) ;
if ( * pmszFileNames = = NULL )
return SCARD_E_NO_MEMORY ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
CopyMemory ( * pmszFileNames , mstr , offs ) ;
2015-04-25 21:29:03 +00:00
* pdwcbFileName = ( DWORD ) offs ;
2012-05-31 14:40:36 +00:00
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardGetFileInfo ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__in_opt LPSTR pszDirectoryName ,
2010-02-05 13:05:25 +00:00
__in LPSTR pszFileName ,
2015-04-17 19:39:41 +00:00
__inout PCARD_FILE_INFO pCardFileInfo )
2010-02-05 13:05:25 +00:00
{
2012-05-31 14:40:36 +00:00
struct md_file * file = NULL ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " CardGetFileInfo(dirName:'%s',fileName:'%s', out %p) \n " , NULLSTR ( pszDirectoryName ) , NULLSTR ( pszFileName ) , pCardFileInfo ) ;
md_fs_find_file ( pCardData , pszDirectoryName , pszFileName , & file ) ;
if ( ! file ) {
logprintf ( pCardData , 2 , " CardWriteFile(): file '%s' not found in '%s' \n " , NULLSTR ( pszFileName ) , NULLSTR ( pszDirectoryName ) ) ;
return SCARD_E_FILE_NOT_FOUND ;
}
pCardFileInfo - > dwVersion = CARD_FILE_INFO_CURRENT_VERSION ;
2015-04-25 21:29:03 +00:00
pCardFileInfo - > cbFileSize = ( DWORD ) file - > size ;
2012-05-31 14:40:36 +00:00
pCardFileInfo - > AccessCondition = file - > acl ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
DWORD WINAPI CardQueryFreeSpace ( __in PCARD_DATA pCardData , __in DWORD dwFlags ,
2015-04-17 19:39:41 +00:00
__inout PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo )
2010-02-05 13:05:25 +00:00
{
2012-05-31 14:40:36 +00:00
DWORD dwret ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardQueryFreeSpace %p, dwFlags=%lX, version=%lX \n " ,
pCardFreeSpaceInfo , ( unsigned long ) dwFlags ,
( unsigned long ) pCardFreeSpaceInfo - > dwVersion ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2012-05-31 14:40:36 +00:00
dwret = md_free_space ( pCardData , pCardFreeSpaceInfo ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 1 , " CardQueryFreeSpace() md free space error " ) ;
return dwret ;
}
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " FreeSpace: \n " ) ;
loghex ( pCardData , 7 , ( BYTE * ) pCardFreeSpaceInfo , sizeof ( * pCardFreeSpaceInfo ) ) ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
DWORD WINAPI CardQueryKeySizes ( __in PCARD_DATA pCardData ,
__in DWORD dwKeySpec ,
__in DWORD dwFlags ,
2015-04-17 19:39:41 +00:00
__inout PCARD_KEY_SIZES pKeySizes )
2010-02-05 13:05:25 +00:00
{
2012-05-31 14:40:36 +00:00
DWORD dwret ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardQueryKeySizes dwKeySpec=%lX, dwFlags=%lX, version=%lX \n " ,
( unsigned long ) dwKeySpec , ( unsigned long ) dwFlags ,
pKeySizes ? ( unsigned long ) pKeySizes - > dwVersion : 0 ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2015-04-12 12:06:36 +00:00
if ( dwFlags ! = 0 )
return SCARD_E_INVALID_PARAMETER ;
2015-09-25 20:22:29 +00:00
if ( dwKeySpec = = 0 )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2015-09-25 20:22:29 +00:00
dwret = md_query_key_sizes ( pCardData , dwKeySpec , pKeySizes ) ;
2012-05-31 14:40:36 +00:00
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " pKeySizes: \n " ) ;
loghex ( pCardData , 7 , ( BYTE * ) pKeySizes , sizeof ( * pKeySizes ) ) ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardRSADecrypt ( __in PCARD_DATA pCardData ,
__inout PCARD_RSA_DECRYPT_INFO pInfo )
{
2012-05-31 14:40:36 +00:00
int r , opt_crypt_flags = 0 ;
2011-04-07 16:55:07 +00:00
unsigned ui ;
2011-02-09 17:52:00 +00:00
VENDOR_SPECIFIC * vs ;
2012-05-31 14:40:36 +00:00
struct sc_pkcs15_prkey_info * prkey_info ;
2011-02-09 17:52:00 +00:00
BYTE * pbuf = NULL , * pbuf2 = NULL ;
2012-05-31 14:40:36 +00:00
struct sc_pkcs15_object * pkey = NULL ;
struct sc_algorithm_info * alg_info = NULL ;
2011-02-09 17:52:00 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 1 , " CardRSADecrypt \n " ) ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pInfo )
return SCARD_E_INVALID_PARAMETER ;
2015-04-11 09:08:52 +00:00
if ( pInfo - > pbData = = NULL )
return SCARD_E_INVALID_PARAMETER ;
if ( pInfo - > dwVersion > CARD_RSA_KEY_DECRYPT_INFO_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ;
if ( pInfo - > dwVersion < CARD_RSA_KEY_DECRYPT_INFO_CURRENT_VERSION
& & pCardData - > dwVersion = = CARD_DATA_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ;
if ( pInfo - > dwKeySpec ! = AT_KEYEXCHANGE )
return SCARD_E_INVALID_PARAMETER ;
2011-02-09 17:52:00 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2015-04-11 09:08:52 +00:00
/* check if the container exists */
if ( pInfo - > bContainerIndex > = MD_MAX_KEY_CONTAINERS )
return SCARD_E_NO_KEY_CONTAINER ;
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardRSADecrypt dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu pbData=%p, cbData=%lu \n " ,
( unsigned long ) pInfo - > dwVersion ,
( unsigned int ) pInfo - > bContainerIndex ,
( unsigned long ) pInfo - > dwKeySpec , pInfo - > pbData ,
( unsigned long ) pInfo - > cbData ) ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
if ( pInfo - > dwVersion > = CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO )
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" pPaddingInfo=%p dwPaddingType=0x%08X \n " ,
pInfo - > pPaddingInfo ,
( unsigned int ) pInfo - > dwPaddingType ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
pkey = vs - > p15_containers [ pInfo - > bContainerIndex ] . prkey_obj ;
if ( ! pkey ) {
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 2 , " CardRSADecrypt prkey not found \n " ) ;
2015-04-11 09:08:52 +00:00
return SCARD_E_NO_KEY_CONTAINER ;
2012-05-31 14:40:36 +00:00
}
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
/* input and output buffers are always the same size */
pbuf = pCardData - > pfnCspAlloc ( pInfo - > cbData ) ;
2012-05-31 14:40:36 +00:00
if ( ! pbuf )
2011-02-09 17:52:00 +00:00
return SCARD_E_NO_MEMORY ;
2012-05-31 14:40:36 +00:00
2011-02-09 17:52:00 +00:00
pbuf2 = pCardData - > pfnCspAlloc ( pInfo - > cbData ) ;
2015-04-12 11:34:18 +00:00
if ( ! pbuf2 ) {
pCardData - > pfnCspFree ( pbuf ) ;
2011-02-09 17:52:00 +00:00
return SCARD_E_NO_MEMORY ;
2015-04-12 11:34:18 +00:00
}
2011-02-09 17:52:00 +00:00
/*inversion donnees*/
2012-05-31 14:40:36 +00:00
for ( ui = 0 ; ui < pInfo - > cbData ; ui + + )
pbuf [ ui ] = pInfo - > pbData [ pInfo - > cbData - ui - 1 ] ;
logprintf ( pCardData , 2 , " Data to be decrypted (inverted): \n " ) ;
loghex ( pCardData , 7 , pbuf , pInfo - > cbData ) ;
prkey_info = ( struct sc_pkcs15_prkey_info * ) ( pkey - > data ) ;
2015-04-25 21:29:03 +00:00
alg_info = sc_card_find_rsa_alg ( vs - > p15card - > card , ( unsigned int ) prkey_info - > modulus_length ) ;
2012-05-31 14:40:36 +00:00
if ( ! alg_info ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" Cannot get appropriate RSA card algorithm for key size % " SC_FORMAT_LEN_SIZE_T " u \n " ,
prkey_info - > modulus_length ) ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
2012-05-31 14:40:36 +00:00
return SCARD_F_INTERNAL_ERROR ;
}
2015-04-11 09:08:52 +00:00
/* filter boggus input: the data to decrypt is shorter than the RSA key ? */
if ( pInfo - > cbData < prkey_info - > modulus_length / 8 )
{
/* according to the minidriver specs, this is the error code to return
( instead of invalid parameter when the call is forwarded to the card implementation ) */
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
2015-04-11 09:08:52 +00:00
return SCARD_E_INSUFFICIENT_BUFFER ;
}
2012-05-31 14:40:36 +00:00
if ( alg_info - > flags & SC_ALGORITHM_RSA_RAW ) {
2013-05-22 10:11:51 +00:00
logprintf ( pCardData , 2 , " sc_pkcs15_decipher: using RSA-RAW mechanism \n " ) ;
2012-05-31 14:40:36 +00:00
r = sc_pkcs15_decipher ( vs - > p15card , pkey , opt_crypt_flags , pbuf , pInfo - > cbData , pbuf2 , pInfo - > cbData ) ;
logprintf ( pCardData , 2 , " sc_pkcs15_decipher returned %d \n " , r ) ;
2013-05-22 10:11:51 +00:00
2015-04-11 09:08:52 +00:00
if ( r > 0 ) {
/* Need to handle padding */
if ( pInfo - > dwVersion > = CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" sc_pkcs15_decipher: DECRYPT-INFO dwVersion=%lu \n " ,
( unsigned long ) pInfo - > dwVersion ) ;
2015-04-11 09:08:52 +00:00
if ( pInfo - > dwPaddingType = = CARD_PADDING_PKCS1 ) {
2015-04-25 21:29:03 +00:00
size_t temp = pInfo - > cbData ;
2015-04-11 09:08:52 +00:00
logprintf ( pCardData , 2 , " sc_pkcs15_decipher: stripping PKCS1 padding \n " ) ;
2015-04-25 21:29:03 +00:00
r = sc_pkcs1_strip_02_padding ( vs - > ctx , pbuf2 , pInfo - > cbData , pbuf2 , & temp ) ;
pInfo - > cbData = ( DWORD ) temp ;
2015-04-11 09:08:52 +00:00
if ( r < 0 ) {
logprintf ( pCardData , 2 , " Cannot strip PKCS1 padding: %i \n " , r ) ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
2015-04-11 09:08:52 +00:00
return SCARD_F_INTERNAL_ERROR ;
}
}
else if ( pInfo - > dwPaddingType = = CARD_PADDING_OAEP ) {
/* TODO: Handle OAEP padding if present - can call PFN_CSP_UNPAD_DATA */
logprintf ( pCardData , 2 , " OAEP padding not implemented \n " ) ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
2013-05-22 10:11:51 +00:00
return SCARD_F_INTERNAL_ERROR ;
}
}
2012-05-31 14:40:36 +00:00
}
}
else if ( alg_info - > flags & SC_ALGORITHM_RSA_PAD_PKCS1 ) {
2013-05-22 10:11:51 +00:00
logprintf ( pCardData , 2 , " sc_pkcs15_decipher: using RSA_PAD_PKCS1 mechanism \n " ) ;
2012-05-31 14:40:36 +00:00
r = sc_pkcs15_decipher ( vs - > p15card , pkey , opt_crypt_flags | SC_ALGORITHM_RSA_PAD_PKCS1 ,
pbuf , pInfo - > cbData , pbuf2 , pInfo - > cbData ) ;
logprintf ( pCardData , 2 , " sc_pkcs15_decipher returned %d \n " , r ) ;
if ( r > 0 ) {
2015-03-28 12:04:41 +00:00
/* No padding info, or padding info none */
2012-05-31 14:40:36 +00:00
if ( ( pInfo - > dwVersion < CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO ) | |
2015-10-16 07:58:01 +00:00
( ( pInfo - > dwVersion > = CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO ) & & ( pInfo - > dwPaddingType = = CARD_PADDING_NONE ) ) ) {
2012-05-31 14:40:36 +00:00
if ( ( unsigned ) r < = pInfo - > cbData - 9 ) {
/* add pkcs1 02 padding */
logprintf ( pCardData , 2 , " Add '%s' to the output data " , " PKCS#1 BT02 padding " ) ;
memset ( pbuf , 0x30 , pInfo - > cbData ) ;
* ( pbuf + 0 ) = 0 ;
* ( pbuf + 1 ) = 2 ;
memcpy ( pbuf + pInfo - > cbData - r , pbuf2 , r ) ;
* ( pbuf + pInfo - > cbData - r - 1 ) = 0 ;
memcpy ( pbuf2 , pbuf , pInfo - > cbData ) ;
}
}
else if ( pInfo - > dwPaddingType = = CARD_PADDING_PKCS1 ) {
2015-03-28 12:04:41 +00:00
/* PKCS1 padding is already handled by the card... */
2012-05-31 14:40:36 +00:00
pInfo - > cbData = r ;
}
/* TODO: Handle OAEP padding if present - can call PFN_CSP_UNPAD_DATA */
}
}
else {
logprintf ( pCardData , 2 , " CardRSADecrypt: no usable RSA algorithm \n " ) ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
if ( r < 0 ) {
2013-05-22 10:11:51 +00:00
logprintf ( pCardData , 2 , " sc_pkcs15_decipher error(%i): %s \n " , r , sc_strerror ( r ) ) ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
2015-04-19 17:51:22 +00:00
return md_translate_OpenSC_to_Windows_error ( r , SCARD_E_INVALID_VALUE ) ;
2011-02-09 17:52:00 +00:00
}
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " decrypted data(%lu): \n " ,
( unsigned long ) pInfo - > cbData ) ;
2012-05-31 14:40:36 +00:00
loghex ( pCardData , 7 , pbuf2 , pInfo - > cbData ) ;
2011-02-09 17:52:00 +00:00
/*inversion donnees */
2012-05-31 14:40:36 +00:00
for ( ui = 0 ; ui < pInfo - > cbData ; ui + + )
pInfo - > pbData [ ui ] = pbuf2 [ pInfo - > cbData - ui - 1 ] ;
2011-02-09 17:52:00 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
pCardData - > pfnCspFree ( pbuf2 ) ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
2015-04-17 19:39:41 +00:00
DWORD WINAPI CardSignData ( __in PCARD_DATA pCardData , __inout PCARD_SIGNING_INFO pInfo )
2010-02-05 13:05:25 +00:00
{
VENDOR_SPECIFIC * vs ;
2011-03-23 18:37:46 +00:00
ALG_ID hashAlg ;
2010-02-05 13:05:25 +00:00
sc_pkcs15_prkey_info_t * prkey_info ;
2011-03-23 18:37:46 +00:00
BYTE dataToSign [ 0x200 ] ;
2011-04-07 16:55:07 +00:00
int r , opt_crypt_flags = 0 , opt_hash_flags = 0 ;
2011-03-23 18:37:46 +00:00
size_t dataToSignLen = sizeof ( dataToSign ) ;
2012-05-31 14:40:36 +00:00
sc_pkcs15_object_t * pkey ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 1 , " CardSignData \n " ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData | | ! pInfo )
return SCARD_E_INVALID_PARAMETER ;
2015-04-09 20:02:10 +00:00
if ( ( pInfo - > dwVersion ! = CARD_SIGNING_INFO_BASIC_VERSION ) & &
( pInfo - > dwVersion ! = CARD_SIGNING_INFO_CURRENT_VERSION ) )
return ERROR_REVISION_MISMATCH ;
if ( pInfo - > pbData = = NULL )
return SCARD_E_INVALID_PARAMETER ;
2015-09-25 20:22:29 +00:00
switch ( pInfo - > dwKeySpec )
{
case AT_SIGNATURE :
case AT_KEYEXCHANGE :
case AT_ECDSA_P256 :
case AT_ECDSA_P384 :
case AT_ECDSA_P521 :
case AT_ECDHE_P256 :
case AT_ECDHE_P384 :
case AT_ECDHE_P521 :
break ;
default :
2015-04-09 20:02:10 +00:00
return SCARD_E_INVALID_PARAMETER ;
2015-09-25 20:22:29 +00:00
}
2015-04-18 13:23:18 +00:00
if ( pInfo - > dwSigningFlags & ~ ( CARD_PADDING_INFO_PRESENT | CARD_PADDING_NONE | CARD_BUFFER_SIZE_ONLY | CARD_PADDING_PKCS1 | CARD_PADDING_PSS | CARD_PADDING_OAEP ) )
2015-04-09 20:02:10 +00:00
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardSignData dwVersion=%lu, bContainerIndex=%u, dwKeySpec=%lu, dwSigningFlags=0x%08X, aiHashAlg=0x%08X \n " ,
( unsigned long ) pInfo - > dwVersion ,
( unsigned int ) pInfo - > bContainerIndex ,
( unsigned long ) pInfo - > dwKeySpec ,
( unsigned int ) pInfo - > dwSigningFlags ,
( unsigned int ) pInfo - > aiHashAlg ) ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 , " pInfo->pbData(%lu) " ,
( unsigned long ) pInfo - > cbData ) ;
2011-03-23 18:37:46 +00:00
loghex ( pCardData , 7 , pInfo - > pbData , pInfo - > cbData ) ;
hashAlg = pInfo - > aiHashAlg ;
2010-02-05 13:05:25 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2012-05-31 14:40:36 +00:00
if ( pInfo - > bContainerIndex > = MD_MAX_KEY_CONTAINERS )
return SCARD_E_NO_KEY_CONTAINER ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
pkey = vs - > p15_containers [ pInfo - > bContainerIndex ] . prkey_obj ;
if ( ! pkey )
return SCARD_E_NO_KEY_CONTAINER ;
prkey_info = ( struct sc_pkcs15_prkey_info * ) ( pkey - > data ) ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
check_reader_status ( pCardData ) ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " pInfo->dwVersion = %lu \n " ,
( unsigned long ) pInfo - > dwVersion ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( dataToSignLen < pInfo - > cbData )
return SCARD_E_INSUFFICIENT_BUFFER ;
2011-03-23 18:37:46 +00:00
memcpy ( dataToSign , pInfo - > pbData , pInfo - > cbData ) ;
dataToSignLen = pInfo - > cbData ;
2012-05-31 14:40:36 +00:00
if ( CARD_PADDING_INFO_PRESENT & pInfo - > dwSigningFlags ) {
2010-02-05 13:05:25 +00:00
BCRYPT_PKCS1_PADDING_INFO * pinf = ( BCRYPT_PKCS1_PADDING_INFO * ) pInfo - > pPaddingInfo ;
2015-04-09 20:02:10 +00:00
if ( CARD_PADDING_PSS = = pInfo - > dwPaddingType ) {
logprintf ( pCardData , 0 , " unsupported paddingtype CARD_PADDING_PSS \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
2015-04-09 20:02:10 +00:00
else if ( CARD_PADDING_PKCS1 ! = pInfo - > dwPaddingType ) {
logprintf ( pCardData , 0 , " unsupported paddingtype \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
2012-05-31 14:40:36 +00:00
if ( ! pinf - > pszAlgId ) {
2010-06-11 07:35:45 +00:00
/* hashAlg = CALG_SSL3_SHAMD5; */
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 3 , " Using CALG_SSL3_SHAMD5 hashAlg \n " ) ;
2011-03-23 18:37:46 +00:00
opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1 ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else {
if ( wcscmp ( pinf - > pszAlgId , L " MD5 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5 ;
else if ( wcscmp ( pinf - > pszAlgId , L " SHA1 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1 ;
else if ( wcscmp ( pinf - > pszAlgId , L " SHAMD5 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1 ;
2015-04-11 12:17:20 +00:00
else if ( wcscmp ( pinf - > pszAlgId , L " SHA224 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA224 ;
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( pinf - > pszAlgId , L " SHA256 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA256 ;
2015-04-11 12:17:20 +00:00
else if ( wcscmp ( pinf - > pszAlgId , L " SHA384 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA384 ;
else if ( wcscmp ( pinf - > pszAlgId , L " SHA512 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512 ;
else if ( wcscmp ( pinf - > pszAlgId , L " RIPEMD160 " ) = = 0 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160 ;
2011-04-12 07:40:12 +00:00
else
2012-05-31 14:40:36 +00:00
{
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 0 , " unknown AlgId %S \n " , NULLWSTR ( pinf - > pszAlgId ) ) ;
2012-05-31 14:40:36 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
2010-02-05 13:05:25 +00:00
}
}
2012-05-31 14:40:36 +00:00
else {
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 3 , " CARD_PADDING_INFO_PRESENT not set \n " ) ;
2011-04-12 07:40:12 +00:00
if ( hashAlg = = CALG_MD5 )
2011-03-23 18:37:46 +00:00
opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5 ;
2011-04-12 07:40:12 +00:00
else if ( hashAlg = = CALG_SHA1 )
2011-03-23 18:37:46 +00:00
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1 ;
else if ( hashAlg = = CALG_SSL3_SHAMD5 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1 ;
2012-05-31 14:40:36 +00:00
else if ( hashAlg = = CALG_SHA_256 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA256 ;
2015-04-11 12:17:20 +00:00
else if ( hashAlg = = CALG_SHA_384 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA384 ;
else if ( hashAlg = = CALG_SHA_512 )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512 ;
else if ( hashAlg = = ( ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_RIPEMD160 ) )
opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160 ;
2015-09-25 20:22:29 +00:00
else if ( hashAlg ! = 0 ) {
logprintf ( pCardData , 0 , " bogus aiHashAlg %i \n " , hashAlg ) ;
2011-03-23 18:37:46 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
2015-09-25 20:22:29 +00:00
}
2010-02-05 13:05:25 +00:00
}
2015-04-11 06:52:22 +00:00
if ( pInfo - > dwSigningFlags & CARD_PADDING_NONE )
{
/* do not add the digest info when called from CryptSignHash(CRYPT_NOHASHOID)
Note : SC_ALGORITHM_RSA_HASH_MD5_SHA1 aka CALG_SSL3_SHAMD5 do not have a digest info to be added
CryptSignHash ( CALG_SSL3_SHAMD5 , CRYPT_NOHASHOID ) is the same than CryptSignHash ( CALG_SSL3_SHAMD5 )
*/
opt_hash_flags = 0 ;
}
2011-03-23 18:37:46 +00:00
/* From sc-minidriver_specs_v7.docx pp.76:
2011-04-12 07:40:12 +00:00
* ' The Base CSP / KSP performs the hashing operation on the data before passing it
2012-05-31 14:40:36 +00:00
* to CardSignData for signature . '
* So , the SC_ALGORITHM_RSA_HASH_ * flags should not be passed to pkcs15 library
* when calculating the signature .
2011-03-23 18:37:46 +00:00
*
* From sc - minidriver_specs_v7 . docx pp .76 :
2011-04-12 07:40:12 +00:00
* ' If the aiHashAlg member is nonzero , it specifies the hash algorithm ’ s object identifier ( OID )
2011-03-23 18:37:46 +00:00
* that is encoded in the PKCS padding . '
* So , the digest info has be included into the data to be signed .
* */
if ( opt_hash_flags ) {
logprintf ( pCardData , 2 , " include digest info of the algorithm 0x%08X \n " , opt_hash_flags ) ;
dataToSignLen = sizeof ( dataToSign ) ;
2012-05-31 14:40:36 +00:00
r = sc_pkcs1_encode ( vs - > ctx , opt_hash_flags , pInfo - > pbData , pInfo - > cbData , dataToSign , & dataToSignLen , 0 ) ;
2011-03-23 18:37:46 +00:00
if ( r ) {
logprintf ( pCardData , 2 , " PKCS#1 encode error %s \n " , sc_strerror ( r ) ) ;
return SCARD_E_INVALID_VALUE ;
}
}
2011-04-12 07:40:12 +00:00
2015-09-25 20:22:29 +00:00
/* Compute output size */
if ( prkey_info - > modulus_length > 0 ) {
/* RSA */
pInfo - > cbSignedData = ( DWORD ) prkey_info - > modulus_length / 8 ;
opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE ;
} else if ( prkey_info - > field_length > 0 ) {
opt_crypt_flags = SC_ALGORITHM_ECDSA_HASH_NONE ;
switch ( prkey_info - > field_length ) {
case 256 :
/* ECDSA_P256 */
pInfo - > cbSignedData = 256 / 8 * 2 ;
break ;
case 384 :
/* ECDSA_P384 */
pInfo - > cbSignedData = 384 / 8 * 2 ;
break ;
case 512 :
/* ECDSA_P512 : special case !!!*/
pInfo - > cbSignedData = 132 ;
break ;
default :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" unknown ECC key size % " SC_FORMAT_LEN_SIZE_T " u \n " ,
prkey_info - > field_length ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_INVALID_VALUE ;
}
} else {
logprintf ( pCardData , 0 , " invalid private key \n " ) ;
return SCARD_E_INVALID_VALUE ;
}
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " pInfo->cbSignedData = %lu \n " ,
( unsigned long ) pInfo - > cbSignedData ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! ( pInfo - > dwSigningFlags & CARD_BUFFER_SIZE_ONLY ) ) {
2010-02-05 13:05:25 +00:00
int r , i ;
2011-03-23 18:37:46 +00:00
BYTE * pbuf = NULL ;
DWORD lg ;
2011-04-12 07:40:12 +00:00
2010-02-05 13:05:25 +00:00
lg = pInfo - > cbSignedData ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 , " lg = %lu \n " , ( unsigned long ) lg ) ;
2010-02-05 13:05:25 +00:00
pbuf = pCardData - > pfnCspAlloc ( lg ) ;
2011-04-12 07:40:12 +00:00
if ( ! pbuf )
2010-02-05 13:05:25 +00:00
return SCARD_E_NO_MEMORY ;
2011-04-12 07:40:12 +00:00
2011-03-23 18:37:46 +00:00
logprintf ( pCardData , 7 , " Data to sign: " ) ;
loghex ( pCardData , 7 , dataToSign , dataToSignLen ) ;
2010-02-05 13:05:25 +00:00
2015-09-25 20:22:29 +00:00
pInfo - > pbSignedData = ( PBYTE ) pCardData - > pfnCspAlloc ( pInfo - > cbSignedData ) ;
2012-05-31 14:40:36 +00:00
if ( ! pInfo - > pbSignedData ) {
2010-02-05 13:05:25 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
return SCARD_E_NO_MEMORY ;
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
r = sc_pkcs15_compute_signature ( vs - > p15card , pkey , opt_crypt_flags , dataToSign , dataToSignLen , pbuf , lg ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 2 , " sc_pkcs15_compute_signature return %d \n " , r ) ;
2012-05-31 14:40:36 +00:00
if ( r < 0 ) {
2016-05-12 11:15:31 +00:00
logprintf ( pCardData , 2 , " sc_pkcs15_compute_signature error %s \n " , sc_strerror ( r ) ) ;
2015-04-12 11:34:18 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
2015-04-19 17:51:22 +00:00
return md_translate_OpenSC_to_Windows_error ( r , SCARD_F_INTERNAL_ERROR ) ;
2010-02-05 13:05:25 +00:00
}
pInfo - > cbSignedData = r ;
2011-04-12 07:40:12 +00:00
2015-09-25 20:22:29 +00:00
/*revert data only for RSA (Microsoft uses the big endian version while everyone is using little endian*/
if ( prkey_info - > modulus_length > 0 ) {
for ( i = 0 ; i < r ; i + + )
pInfo - > pbSignedData [ i ] = pbuf [ r - i - 1 ] ;
} else {
for ( i = 0 ; i < r ; i + + )
pInfo - > pbSignedData [ i ] = pbuf [ i ] ;
}
2010-02-05 13:05:25 +00:00
pCardData - > pfnCspFree ( pbuf ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " Signature (inverted): " ) ;
2011-02-09 17:52:00 +00:00
loghex ( pCardData , 7 , pInfo - > pbSignedData , pInfo - > cbSignedData ) ;
2010-02-05 13:05:25 +00:00
}
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 3 ,
" CardSignData, dwVersion=%lu, name=%S, hScard=0x%08X, hSCardCtx=0x%08X \n " ,
( unsigned long ) pCardData - > dwVersion ,
NULLWSTR ( pCardData - > pwszCardName ) ,
( unsigned int ) pCardData - > hScard ,
( unsigned int ) pCardData - > hSCardCtx ) ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
DWORD WINAPI CardConstructDHAgreement ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__inout PCARD_DH_AGREEMENT_INFO pAgreementInfo )
2010-02-05 13:05:25 +00:00
{
2015-09-25 20:22:29 +00:00
VENDOR_SPECIFIC * vs ;
struct sc_pkcs15_object * pkey = NULL ;
int r , opt_derive_flags = 0 ;
u8 * out = 0 ;
unsigned long outlen = 0 ;
PBYTE pbPublicKey = NULL ;
DWORD dwPublicKeySize = 0 ;
struct md_dh_agreement * dh_agreement = NULL ;
struct md_dh_agreement * temp = NULL ;
BYTE i ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-09-25 20:22:29 +00:00
logprintf ( pCardData , 1 , " CardConstructDHAgreement \n " ) ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pAgreementInfo )
return SCARD_E_INVALID_PARAMETER ;
if ( pAgreementInfo - > pbPublicKey = = NULL )
return SCARD_E_INVALID_PARAMETER ;
if ( pAgreementInfo - > dwVersion > CARD_DH_AGREEMENT_INFO_VERSION )
return ERROR_REVISION_MISMATCH ;
if ( pAgreementInfo - > dwVersion < CARD_DH_AGREEMENT_INFO_VERSION
& & pCardData - > dwVersion = = CARD_DATA_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
/* check if the container exists */
if ( pAgreementInfo - > bContainerIndex > = MD_MAX_KEY_CONTAINERS )
return SCARD_E_NO_KEY_CONTAINER ;
check_reader_status ( pCardData ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " CardConstructDHAgreement dwVersion=%lu, dwKeySpec=%u pbData=%p, cbData=%lu \n " ,
( unsigned long ) pAgreementInfo - > dwVersion ,
( unsigned int ) pAgreementInfo - > bContainerIndex ,
pAgreementInfo - > pbPublicKey ,
( unsigned long ) pAgreementInfo - > dwPublicKey ) ;
2015-09-25 20:22:29 +00:00
pkey = vs - > p15_containers [ pAgreementInfo - > bContainerIndex ] . prkey_obj ;
if ( ! pkey ) {
logprintf ( pCardData , 2 , " CardConstructDHAgreement prkey not found \n " ) ;
return SCARD_E_NO_KEY_CONTAINER ;
}
/* convert the Windows public key into an OpenSC public key */
dwPublicKeySize = pAgreementInfo - > dwPublicKey - sizeof ( BCRYPT_ECCKEY_BLOB ) + 1 ;
pbPublicKey = ( PBYTE ) pCardData - > pfnCspAlloc ( dwPublicKeySize ) ;
if ( ! pbPublicKey ) {
return ERROR_OUTOFMEMORY ;
}
pbPublicKey [ 0 ] = 4 ;
memcpy ( pbPublicKey + 1 , pAgreementInfo - > pbPublicKey + sizeof ( BCRYPT_ECCKEY_BLOB ) , dwPublicKeySize - 1 ) ;
/* derive the key using the OpenSC functions */
r = sc_pkcs15_derive ( vs - > p15card , pkey , opt_derive_flags , pbPublicKey , dwPublicKeySize , out , & outlen ) ;
logprintf ( pCardData , 2 , " sc_pkcs15_derive returned %d \n " , r ) ;
if ( r < 0 ) {
logprintf ( pCardData , 2 , " sc_pkcs15_derive error(%i): %s \n " , r , sc_strerror ( r ) ) ;
pCardData - > pfnCspFree ( pbPublicKey ) ;
return md_translate_OpenSC_to_Windows_error ( r , SCARD_E_INVALID_VALUE ) ;
}
out = pCardData - > pfnCspAlloc ( outlen ) ;
if ( ! out ) {
return ERROR_OUTOFMEMORY ;
}
r = sc_pkcs15_derive ( vs - > p15card , pkey , opt_derive_flags , pbPublicKey , dwPublicKeySize , out , & outlen ) ;
logprintf ( pCardData , 2 , " sc_pkcs15_derive returned %d \n " , r ) ;
pCardData - > pfnCspFree ( pbPublicKey ) ;
if ( r < 0 ) {
logprintf ( pCardData , 2 , " sc_pkcs15_derive error(%i): %s \n " , r , sc_strerror ( r ) ) ;
pCardData - > pfnCspFree ( out ) ;
return md_translate_OpenSC_to_Windows_error ( r , SCARD_E_INVALID_VALUE ) ;
}
/* save the dh agreement for later use */
/* try to find an empty index */
for ( i = 0 ; i < vs - > allocatedAgreements ; i + + ) {
dh_agreement = vs - > dh_agreements + i ;
if ( dh_agreement - > pbAgreement = = NULL ) {
pAgreementInfo - > bSecretAgreementIndex = i ;
dh_agreement - > pbAgreement = out ;
dh_agreement - > dwSize = outlen ;
return SCARD_S_SUCCESS ;
}
}
/* no empty space => need to allocate memory */
temp = ( struct md_dh_agreement * ) pCardData - > pfnCspAlloc ( ( vs - > allocatedAgreements + 1 ) * sizeof ( struct md_dh_agreement ) ) ;
if ( ! temp ) {
pCardData - > pfnCspFree ( out ) ;
return SCARD_E_NO_MEMORY ;
}
if ( ( vs - > allocatedAgreements ) > 0 ) {
memcpy ( temp , vs - > dh_agreements , sizeof ( struct md_dh_agreement ) * ( vs - > allocatedAgreements ) ) ;
pCardData - > pfnCspFree ( vs - > dh_agreements ) ;
}
vs - > dh_agreements = temp ;
dh_agreement = vs - > dh_agreements + ( vs - > allocatedAgreements ) ;
pAgreementInfo - > bSecretAgreementIndex = ( vs - > allocatedAgreements ) ;
dh_agreement - > pbAgreement = out ;
dh_agreement - > dwSize = outlen ;
vs - > allocatedAgreements + + ;
return SCARD_S_SUCCESS ;
}
DWORD WINAPI CardDeriveHashOrHMAC ( __in PCARD_DATA pCardData ,
__inout PCARD_DERIVE_KEY pAgreementInfo ,
__in struct md_dh_agreement * agreement ,
__in PWSTR szAlgorithm ,
__in PBYTE pbHmacKey , __in DWORD dwHmacKeySize
)
{
DWORD dwReturn = 0 ;
/* CNG variables */
BCRYPT_ALG_HANDLE hAlgorithm = NULL ;
BCRYPT_HASH_HANDLE hHash = NULL ;
DWORD dwSize , dwHashSize ;
PBYTE pbBuffer = NULL ;
DWORD dwBufferSize = 0 ;
ULONG i ;
NCryptBufferDesc * parameters = NULL ;
dwReturn = BCryptOpenAlgorithmProvider ( & hAlgorithm , szAlgorithm , NULL , ( pbHmacKey ? BCRYPT_ALG_HANDLE_HMAC_FLAG : 0 ) ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to find a provider for the algorithm %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
dwSize = sizeof ( DWORD ) ;
dwReturn = BCryptGetProperty ( hAlgorithm , BCRYPT_HASH_LENGTH , ( PUCHAR ) & dwHashSize , dwSize , & dwSize , 0 ) ;
if ( dwReturn ) {
logprintf ( pCardData , 0 , " CardDeriveKey: unable to get the hash length \n " ) ;
goto cleanup ;
}
pAgreementInfo - > cbDerivedKey = dwHashSize ;
if ( pAgreementInfo - > dwFlags & CARD_BUFFER_SIZE_ONLY ) {
dwReturn = SCARD_S_SUCCESS ;
goto cleanup ;
}
pAgreementInfo - > pbDerivedKey = ( PBYTE ) pCardData - > pfnCspAlloc ( dwHashSize ) ;
if ( pAgreementInfo - > pbDerivedKey = = NULL ) {
dwReturn = SCARD_E_NO_MEMORY ;
goto cleanup ;
}
dwSize = sizeof ( DWORD ) ;
dwReturn = BCryptGetProperty ( hAlgorithm , BCRYPT_OBJECT_LENGTH , ( PUCHAR ) & dwBufferSize , dwSize , & dwSize , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to get the buffer length 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
pbBuffer = ( PBYTE ) LocalAlloc ( 0 , dwBufferSize ) ;
if ( pbBuffer = = NULL ) {
dwReturn = SCARD_E_NO_MEMORY ;
goto cleanup ;
}
if ( wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_HMAC ) = = 0 ) {
dwReturn = BCryptCreateHash ( hAlgorithm , & hHash , pbBuffer , dwBufferSize , pbHmacKey , dwHmacKeySize , 0 ) ;
}
else {
dwReturn = BCryptCreateHash ( hAlgorithm , & hHash , pbBuffer , dwBufferSize , NULL , 0 , 0 ) ;
}
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to create the alg object 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
parameters = ( NCryptBufferDesc * ) pAgreementInfo - > pParameterList ;
if ( parameters ) {
for ( i = 0 ; i < parameters - > cBuffers ; i + + ) {
NCryptBuffer * buffer = parameters - > pBuffers + i ;
if ( buffer - > BufferType = = KDF_SECRET_PREPEND ) {
dwReturn = BCryptHashData ( hHash , ( PUCHAR ) buffer - > pvBuffer , buffer - > cbBuffer , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash data 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
}
}
}
dwReturn = BCryptHashData ( hHash , ( PUCHAR ) agreement - > pbAgreement , agreement - > dwSize , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash data 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
if ( parameters ) {
for ( i = 0 ; i < parameters - > cBuffers ; i + + ) {
NCryptBuffer * buffer = parameters - > pBuffers + i ;
if ( buffer - > BufferType = = KDF_SECRET_APPEND ) {
dwReturn = BCryptHashData ( hHash , ( PUCHAR ) buffer - > pvBuffer , buffer - > cbBuffer , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash data 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
}
}
}
dwReturn = BCryptFinishHash ( hHash , pAgreementInfo - > pbDerivedKey , pAgreementInfo - > cbDerivedKey , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to finish hash 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
cleanup :
if ( hHash )
BCryptDestroyHash ( hHash ) ;
if ( pbBuffer )
LocalFree ( pbBuffer ) ;
if ( hAlgorithm )
BCryptCloseAlgorithmProvider ( hAlgorithm , 0 ) ;
return dwReturn ;
}
2015-09-25 20:56:26 +00:00
/* Generic function to perform hash. Could have been OpenSSL but used BCrypt* functions.
BCrypt is loaded as a delay load library . The dll can be loaded into Windows XP until this code is called .
Hopefully , ECC is not available in Windows XP and BCrypt functions are not called */
2015-10-14 20:48:41 +00:00
DWORD HashDataWithBCrypt ( __in PCARD_DATA pCardData , BCRYPT_ALG_HANDLE hAlgorithm ,
2015-10-16 07:58:01 +00:00
PBYTE pbOuput , DWORD dwOutputSize , PBYTE pbSecret , DWORD dwSecretSize ,
PBYTE pbData1 , DWORD dwDataSize1 ,
PBYTE pbData2 , DWORD dwDataSize2 ,
PBYTE pbData3 , DWORD dwDataSize3 )
2015-09-25 20:22:29 +00:00
{
DWORD dwReturn , dwSize , dwBufferSize ;
BCRYPT_HASH_HANDLE hHash = NULL ;
PBYTE pbBuffer = NULL ;
2017-03-14 21:56:39 +00:00
2015-09-25 20:22:29 +00:00
dwSize = sizeof ( DWORD ) ;
dwReturn = BCryptGetProperty ( hAlgorithm , BCRYPT_OBJECT_LENGTH , ( PUCHAR ) & dwBufferSize , dwSize , & dwSize , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to get the buffer length 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
pbBuffer = ( PBYTE ) LocalAlloc ( 0 , dwBufferSize ) ;
if ( pbBuffer = = NULL ) {
dwReturn = SCARD_E_NO_MEMORY ;
goto cleanup ;
}
dwReturn = BCryptCreateHash ( hAlgorithm , & hHash , pbBuffer , dwBufferSize , pbSecret , dwSecretSize , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to create the alg object 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
if ( pbData1 ) {
dwReturn = BCryptHashData ( hHash , pbData1 , dwDataSize1 , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash data 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
}
if ( pbData2 ) {
dwReturn = BCryptHashData ( hHash , pbData2 , dwDataSize2 , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash data 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
}
if ( pbData3 ) {
dwReturn = BCryptHashData ( hHash , pbData3 , dwDataSize3 , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash data 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
}
dwReturn = BCryptFinishHash ( hHash , pbOuput , dwOutputSize , 0 ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to finish hash 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
cleanup :
if ( hHash )
BCryptDestroyHash ( hHash ) ;
if ( pbBuffer )
LocalFree ( pbBuffer ) ;
return dwReturn ;
}
2015-09-25 20:56:26 +00:00
/* Generic function for TLS PRF. Compute the P_HASH function */
2015-09-25 20:22:29 +00:00
DWORD WINAPI DoTlsPrf ( __in PCARD_DATA pCardData ,
2015-10-16 07:58:01 +00:00
__in PBYTE pbOutput ,
2015-09-25 20:22:29 +00:00
__in PBYTE pbSecret ,
__in DWORD dwSecretSize ,
__in PWSTR szAlgorithm ,
__in PBYTE pbLabel , __in DWORD dwLabelSize ,
__in PBYTE pbSeed
)
{
DWORD dwReturn = 0 , i ;
/* CNG variables */
BCRYPT_ALG_HANDLE hAlgorithm = NULL ;
DWORD dwSize , dwHashSize , dwNumberOfRounds , dwLastRoundSize ;
PBYTE pbBuffer = NULL ;
/* TLS intermediate results */
PBYTE pbAx = NULL ;
2017-03-14 21:56:39 +00:00
2015-09-25 20:22:29 +00:00
dwReturn = BCryptOpenAlgorithmProvider ( & hAlgorithm , szAlgorithm , NULL , BCRYPT_ALG_HANDLE_HMAC_FLAG ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to find a provider for the algorithm %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
dwSize = sizeof ( DWORD ) ;
dwReturn = BCryptGetProperty ( hAlgorithm , BCRYPT_HASH_LENGTH , ( PUCHAR ) & dwHashSize , dwSize , & dwSize , 0 ) ;
if ( dwReturn ) {
logprintf ( pCardData , 0 , " CardDeriveKey: unable to get the hash length \n " ) ;
goto cleanup ;
}
2017-03-14 21:56:39 +00:00
2015-09-25 20:22:29 +00:00
/* size is always 48 */
2015-10-14 20:48:41 +00:00
dwLastRoundSize = TLS_DERIVE_KEY_SIZE % dwHashSize ;
2015-09-25 20:22:29 +00:00
if ( dwLastRoundSize = = 0 ) dwLastRoundSize = dwHashSize ;
2015-10-14 20:48:41 +00:00
dwNumberOfRounds = ( DWORD ) ( TLS_DERIVE_KEY_SIZE / dwHashSize ) + ( dwLastRoundSize = = dwHashSize ? 0 : 1 ) ;
2015-09-25 20:22:29 +00:00
/* store TLS A1, A2 intermediate operations */
pbAx = ( PBYTE ) LocalAlloc ( 0 , dwNumberOfRounds * dwHashSize ) ;
if ( pbAx = = NULL ) {
dwReturn = SCARD_E_NO_MEMORY ;
goto cleanup ;
}
pbBuffer = ( PBYTE ) LocalAlloc ( 0 , dwHashSize ) ;
if ( pbBuffer = = NULL ) {
dwReturn = SCARD_E_NO_MEMORY ;
goto cleanup ;
}
for ( i = 0 ; i < dwNumberOfRounds ; i + + ) {
/* A1, A2, ... */
if ( i = = 0 ) {
/* A(1) = HMAC_hash(secret, label + seed)*/
2015-10-14 20:48:41 +00:00
dwReturn = HashDataWithBCrypt ( pCardData , hAlgorithm ,
2015-10-16 07:58:01 +00:00
pbAx , dwHashSize , pbSecret , dwSecretSize ,
pbLabel , dwLabelSize ,
pbSeed , 64 ,
NULL , 0 ) ;
2015-09-25 20:22:29 +00:00
} else {
/* A(i) = HMAC_hash(secret, A(i-1))*/
2015-10-14 20:48:41 +00:00
dwReturn = HashDataWithBCrypt ( pCardData , hAlgorithm ,
2015-10-16 07:58:01 +00:00
pbAx + i * dwHashSize , dwHashSize , pbSecret , dwSecretSize ,
pbAx + ( i - 1 ) * dwHashSize , dwHashSize ,
NULL , 0 ,
NULL , 0 ) ;
2015-09-25 20:22:29 +00:00
}
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
if ( dwNumberOfRounds - 1 = = i ) {
/* last round */
2015-10-14 20:48:41 +00:00
dwReturn = HashDataWithBCrypt ( pCardData , hAlgorithm ,
2015-10-16 07:58:01 +00:00
pbBuffer , dwHashSize , pbSecret , dwSecretSize ,
pbAx + i * dwHashSize , dwHashSize ,
pbLabel , dwLabelSize ,
pbSeed , 64 ) ;
2015-09-25 20:22:29 +00:00
memcpy ( pbOutput + i * dwHashSize , pbBuffer , dwLastRoundSize ) ;
} else {
2015-10-14 20:48:41 +00:00
dwReturn = HashDataWithBCrypt ( pCardData , hAlgorithm ,
2015-10-16 07:58:01 +00:00
pbOutput + i * dwHashSize , dwHashSize , pbSecret , dwSecretSize ,
pbAx + i * dwHashSize , dwHashSize ,
pbLabel , dwLabelSize ,
pbSeed , 64 ) ;
2015-09-25 20:22:29 +00:00
}
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unable to hash %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
goto cleanup ;
}
}
cleanup :
if ( pbBuffer )
LocalFree ( pbBuffer ) ;
if ( pbAx )
LocalFree ( pbAx ) ;
if ( hAlgorithm )
BCryptCloseAlgorithmProvider ( hAlgorithm , 0 ) ;
return dwReturn ;
}
2015-09-25 20:56:26 +00:00
/* Implement TLS 1.0, 1.1 and 1.2 PRF */
2015-09-25 20:22:29 +00:00
DWORD WINAPI CardDeriveTlsPrf ( __in PCARD_DATA pCardData ,
__inout PCARD_DERIVE_KEY pAgreementInfo ,
__in struct md_dh_agreement * agreement ,
__in DWORD dwProtocol ,
__in PWSTR szAlgorithm ,
__in PBYTE pbLabel , __in DWORD dwLabelSize ,
__in PBYTE pbSeed
)
{
DWORD dwReturn = 0 ;
PBYTE pbBuffer = NULL ;
DWORD i ;
if ( dwProtocol = = 0 ) {
2015-10-14 20:48:41 +00:00
dwProtocol = TLS1_0_PROTOCOL_VERSION ;
} else if ( dwProtocol = = TLS1_0_PROTOCOL_VERSION | | dwProtocol = = TLS1_1_PROTOCOL_VERSION ) {
2015-09-25 20:22:29 +00:00
/* TLS 1.0 & 1.1 */
2015-10-14 20:48:41 +00:00
} else if ( dwProtocol = = TLS1_2_PROTOCOL_VERSION ) {
2015-09-25 20:22:29 +00:00
/* TLS 1.2 */
if ( szAlgorithm & & wcscmp ( szAlgorithm , BCRYPT_SHA256_ALGORITHM ) ! = 0 & & wcscmp ( szAlgorithm , BCRYPT_SHA384_ALGORITHM ) ! = 0 ) {
logprintf ( pCardData , 0 , " CardDeriveKey: The algorithm for TLS_PRF is invalid %S \n " , szAlgorithm ) ;
return SCARD_E_INVALID_PARAMETER ;
}
} else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveTlsPrf: TLS protocol unknown 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
/* size is always 48 according to msdn */
2015-10-14 20:48:41 +00:00
pAgreementInfo - > cbDerivedKey = TLS_DERIVE_KEY_SIZE ;
2015-09-25 20:22:29 +00:00
if ( pAgreementInfo - > dwFlags & CARD_BUFFER_SIZE_ONLY ) {
return SCARD_S_SUCCESS ;
}
2015-10-14 20:48:41 +00:00
pAgreementInfo - > pbDerivedKey = ( PBYTE ) pCardData - > pfnCspAlloc ( TLS_DERIVE_KEY_SIZE ) ;
2015-09-25 20:22:29 +00:00
if ( pAgreementInfo - > pbDerivedKey = = NULL ) {
return SCARD_E_NO_MEMORY ;
}
2015-10-14 20:48:41 +00:00
if ( dwProtocol = = TLS1_0_PROTOCOL_VERSION | | dwProtocol = = TLS1_1_PROTOCOL_VERSION ) {
2015-09-25 20:22:29 +00:00
/* TLS 1.0 & 1.1 */
DWORD dwNewSecretLength = ( ( ( agreement - > dwSize ) + ( 2 ) - 1 ) / ( 2 ) ) ;
dwReturn = DoTlsPrf ( pCardData ,
2015-10-16 07:58:01 +00:00
pAgreementInfo - > pbDerivedKey ,
2015-09-25 20:22:29 +00:00
agreement - > pbAgreement ,
dwNewSecretLength ,
BCRYPT_MD5_ALGORITHM ,
pbLabel , dwLabelSize ,
pbSeed ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveTlsPrf: unable to DoTlsPrf with %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
pCardData - > pfnCspFree ( pAgreementInfo - > pbDerivedKey ) ;
pAgreementInfo - > pbDerivedKey = NULL ;
return dwReturn ;
}
2015-10-14 20:48:41 +00:00
pbBuffer = ( PBYTE ) LocalAlloc ( 0 , TLS_DERIVE_KEY_SIZE ) ;
2015-09-25 20:22:29 +00:00
if ( ! pbBuffer ) {
pCardData - > pfnCspFree ( pAgreementInfo - > pbDerivedKey ) ;
pAgreementInfo - > pbDerivedKey = NULL ;
return SCARD_E_NO_MEMORY ;
}
dwReturn = DoTlsPrf ( pCardData ,
2015-10-16 07:58:01 +00:00
pbBuffer ,
2015-09-25 20:22:29 +00:00
agreement - > pbAgreement + dwNewSecretLength ,
dwNewSecretLength ,
BCRYPT_SHA1_ALGORITHM ,
pbLabel , dwLabelSize ,
pbSeed ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveTlsPrf: unable to DoTlsPrf with %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
LocalFree ( pbBuffer ) ;
pCardData - > pfnCspFree ( pAgreementInfo - > pbDerivedKey ) ;
pAgreementInfo - > pbDerivedKey = NULL ;
return dwReturn ;
}
2015-10-14 20:48:41 +00:00
for ( i = 0 ; i < TLS_DERIVE_KEY_SIZE ; i + + ) {
2015-09-25 20:22:29 +00:00
pAgreementInfo - > pbDerivedKey [ i ] = pAgreementInfo - > pbDerivedKey [ i ] ^ pbBuffer [ i ] ;
}
LocalFree ( pbBuffer ) ;
2015-10-14 20:48:41 +00:00
} else if ( dwProtocol = = TLS1_2_PROTOCOL_VERSION ) {
2015-09-25 20:22:29 +00:00
dwReturn = DoTlsPrf ( pCardData ,
2015-10-16 07:58:01 +00:00
pAgreementInfo - > pbDerivedKey ,
2015-09-25 20:22:29 +00:00
agreement - > pbAgreement ,
agreement - > dwSize ,
szAlgorithm ,
pbLabel , dwLabelSize ,
pbSeed ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveTlsPrf: unable to DoTlsPrf with %S 0x%08X \n " ,
szAlgorithm , ( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
pCardData - > pfnCspFree ( pAgreementInfo - > pbDerivedKey ) ;
pAgreementInfo - > pbDerivedKey = NULL ;
return dwReturn ;
}
}
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardDeriveKey ( __in PCARD_DATA pCardData ,
2015-04-17 19:39:41 +00:00
__inout PCARD_DERIVE_KEY pAgreementInfo )
2010-02-05 13:05:25 +00:00
{
2015-09-25 20:22:29 +00:00
VENDOR_SPECIFIC * vs ;
struct md_dh_agreement * agreement = NULL ;
NCryptBufferDesc * parameters = NULL ;
ULONG i ;
DWORD dwReturn = 0 ;
/* store parameter references */
PWSTR szAlgorithm = NULL ;
PBYTE pbHmacKey = NULL ;
DWORD dwHmacKeySize = 0 ;
PBYTE pbLabel = NULL ;
DWORD dwLabelSize = 0 ;
PBYTE pbSeed = NULL ;
DWORD dwProtocol = 0 ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-09-25 20:22:29 +00:00
logprintf ( pCardData , 1 , " CardDeriveKey \n " ) ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pAgreementInfo )
return SCARD_E_INVALID_PARAMETER ;
2015-09-30 20:49:41 +00:00
if ( ! pAgreementInfo - > dwVersion )
return ERROR_REVISION_MISMATCH ;
2015-09-25 20:22:29 +00:00
if ( pAgreementInfo - > dwVersion > CARD_DERIVE_KEY_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ;
2015-09-30 20:49:41 +00:00
if ( pAgreementInfo - > pwszKDF = = NULL )
return SCARD_E_INVALID_PARAMETER ;
if ( pAgreementInfo - > dwFlags & ~ ( KDF_USE_SECRET_AS_HMAC_KEY_FLAG | CARD_RETURN_KEY_HANDLE | CARD_BUFFER_SIZE_ONLY ) )
return SCARD_E_INVALID_PARAMETER ;
2015-09-25 20:22:29 +00:00
/* according to the documenation, CARD_DERIVE_KEY_CURRENT_VERSION should be equal to 2.
In pratice it is not 2 but 1
if ( pAgreementInfo - > dwVersion < CARD_DERIVE_KEY_CURRENT_VERSION
& & pCardData - > dwVersion = = CARD_DATA_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ; */
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
/* check if the agreement index is ok */
if ( pAgreementInfo - > bSecretAgreementIndex > = vs - > allocatedAgreements ) {
return SCARD_E_INVALID_PARAMETER ;
}
agreement = vs - > dh_agreements + pAgreementInfo - > bSecretAgreementIndex ;
if ( agreement - > pbAgreement = = NULL ) {
return SCARD_E_INVALID_PARAMETER ;
}
if ( pAgreementInfo - > dwFlags & CARD_RETURN_KEY_HANDLE ) {
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/* find the algorithm, checks parameters */
parameters = ( NCryptBufferDesc * ) pAgreementInfo - > pParameterList ;
if ( parameters ) {
for ( i = 0 ; i < parameters - > cBuffers ; i + + ) {
NCryptBuffer * buffer = parameters - > pBuffers + i ;
switch ( buffer - > BufferType ) {
case KDF_HASH_ALGORITHM :
if ( szAlgorithm ! = NULL ) {
logprintf ( pCardData , 0 , " CardDeriveKey: got more than one algorithm \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( wcscmp ( ( PWSTR ) buffer - > pvBuffer , BCRYPT_SHA1_ALGORITHM ) = = 0 ) {
szAlgorithm = BCRYPT_SHA1_ALGORITHM ;
} else if ( wcscmp ( ( PWSTR ) buffer - > pvBuffer , BCRYPT_SHA256_ALGORITHM ) = = 0 ) {
szAlgorithm = BCRYPT_SHA256_ALGORITHM ;
} else if ( wcscmp ( ( PWSTR ) buffer - > pvBuffer , BCRYPT_SHA384_ALGORITHM ) = = 0 ) {
2015-09-30 20:49:41 +00:00
szAlgorithm = BCRYPT_SHA384_ALGORITHM ;
2015-09-25 20:22:29 +00:00
} else if ( wcscmp ( ( PWSTR ) buffer - > pvBuffer , BCRYPT_SHA512_ALGORITHM ) = = 0 ) {
2015-09-30 20:49:41 +00:00
szAlgorithm = BCRYPT_SHA512_ALGORITHM ;
2015-09-25 20:22:29 +00:00
} else if ( wcscmp ( ( PWSTR ) buffer - > pvBuffer , BCRYPT_MD5_ALGORITHM ) = = 0 ) {
szAlgorithm = BCRYPT_MD5_ALGORITHM ;
} else {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unsupported algorithm %S \n " ,
( PWSTR ) buffer - > pvBuffer ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
break ;
case KDF_HMAC_KEY :
if ( pbHmacKey ! = NULL ) {
logprintf ( pCardData , 0 , " CardDeriveKey: got more than one hhmac key \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
pbHmacKey = ( PBYTE ) buffer - > pvBuffer ;
dwHmacKeySize = buffer - > cbBuffer ;
break ;
case KDF_SECRET_APPEND :
case KDF_SECRET_PREPEND :
/* do not throw an error for invalid arg*/
break ;
case KDF_TLS_PRF_LABEL :
if ( pbLabel ! = NULL ) {
logprintf ( pCardData , 0 , " CardDeriveKey: got more than one Label \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
pbLabel = ( PBYTE ) buffer - > pvBuffer ;
dwLabelSize = buffer - > cbBuffer ;
break ;
case KDF_TLS_PRF_SEED :
if ( pbSeed ! = NULL ) {
logprintf ( pCardData , 0 , " CardDeriveKey: got more than one Seed \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( buffer - > cbBuffer ! = 64 )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: invalid seed size %lu \n " ,
buffer - > cbBuffer ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
pbSeed = ( PBYTE ) buffer - > pvBuffer ;
break ;
case KDF_TLS_PRF_PROTOCOL :
dwProtocol = * ( ( PDWORD ) buffer - > pvBuffer ) ;
break ;
/*case KDF_ALGORITHMID:
case KDF_PARTYUINFO :
case KDF_PARTYVINFO :
case KDF_SUPPPUBINFO :
case KDF_SUPPPRIVINFO :
break ; */
default :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: unknown buffer type %lu \n " ,
( parameters - > pBuffers + i ) - > BufferType ) ;
2015-09-25 20:22:29 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
}
}
/* default parameters */
if ( szAlgorithm = = NULL & & wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_TLS_PRF ) ! = 0 ) {
szAlgorithm = BCRYPT_SHA1_ALGORITHM ;
}
2017-03-14 21:56:39 +00:00
2015-09-25 20:22:29 +00:00
/* check the values with the KDF choosen */
if ( wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_HASH ) = = 0 ) {
}
else if ( wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_HMAC ) = = 0 ) {
if ( pbHmacKey = = NULL ) {
logprintf ( pCardData , 0 , " CardDeriveKey: no hhmac key for hmac KDF \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
}
else if ( wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_TLS_PRF ) = = 0 ) {
if ( ! pbSeed ) {
logprintf ( pCardData , 0 , " CardDeriveKey: No seed was provided \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( ! pbLabel ) {
logprintf ( pCardData , 0 , " CardDeriveKey: No label was provided \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
} else {
logprintf ( pCardData , 0 , " CardDeriveKey: unsupported KDF %S \n " , pAgreementInfo - > pwszKDF ) ;
return SCARD_E_INVALID_PARAMETER ;
}
/* do the job for the KDF Hash & Hmac */
if ( wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_HASH ) = = 0 | |
wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_HMAC ) = = 0 ) {
2017-03-14 21:56:39 +00:00
2015-09-25 20:22:29 +00:00
dwReturn = CardDeriveHashOrHMAC ( pCardData , pAgreementInfo , agreement , szAlgorithm , pbHmacKey , dwHmacKeySize ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: got an error while deriving the Key (hash or HMAC) 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
return dwReturn ;
}
} else if ( wcscmp ( pAgreementInfo - > pwszKDF , BCRYPT_KDF_TLS_PRF ) = = 0 ) {
dwReturn = CardDeriveTlsPrf ( pCardData , pAgreementInfo , agreement , dwProtocol , szAlgorithm , pbLabel , dwLabelSize , pbSeed ) ;
if ( dwReturn ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" CardDeriveKey: got an error while deriving the Key (TlsPrf) 0x%08X \n " ,
( unsigned int ) dwReturn ) ;
2015-09-25 20:22:29 +00:00
return dwReturn ;
}
}
/*else if (wcscmp(pAgreementInfo->pwszKDF, BCRYPT_KDF_SP80056A_CONCAT ) == 0) {
} */
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardDestroyDHAgreement (
__in PCARD_DATA pCardData ,
__in BYTE bSecretAgreementIndex ,
__in DWORD dwFlags )
{
2015-09-25 20:22:29 +00:00
VENDOR_SPECIFIC * vs ;
struct md_dh_agreement * agreement = NULL ;
2010-02-05 13:05:25 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-09-25 20:22:29 +00:00
logprintf ( pCardData , 1 , " CardDestroyDHAgreement \n " ) ;
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
if ( dwFlags )
return SCARD_E_INVALID_PARAMETER ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
if ( bSecretAgreementIndex > = vs - > allocatedAgreements ) {
return SCARD_E_INVALID_PARAMETER ;
}
agreement = vs - > dh_agreements + bSecretAgreementIndex ;
if ( agreement - > pbAgreement = = NULL ) {
return SCARD_E_INVALID_PARAMETER ;
}
SecureZeroMemory ( agreement - > pbAgreement , agreement - > dwSize ) ;
pCardData - > pfnCspFree ( agreement - > pbAgreement ) ;
agreement - > pbAgreement = 0 ;
agreement - > dwSize = 0 ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardGetChallengeEx ( __in PCARD_DATA pCardData ,
__in PIN_ID PinId ,
__deref_out_bcount ( * pcbChallengeData ) PBYTE * ppbChallengeData ,
__out PDWORD pcbChallengeData ,
__in DWORD dwFlags )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 1 , " CardGetChallengeEx - unsupported \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
DWORD WINAPI CardAuthenticateEx ( __in PCARD_DATA pCardData ,
__in PIN_ID PinId ,
__in DWORD dwFlags ,
2015-04-17 19:39:41 +00:00
__in_bcount ( cbPinData ) PBYTE pbPinData ,
2010-02-05 13:05:25 +00:00
__in DWORD cbPinData ,
2015-04-17 19:39:41 +00:00
__deref_opt_out_bcount ( * pcbSessionPin ) PBYTE * ppbSessionPin ,
2010-02-05 13:05:25 +00:00
__out_opt PDWORD pcbSessionPin ,
__out_opt PDWORD pcAttemptsRemaining )
{
VENDOR_SPECIFIC * vs ;
2013-12-18 13:15:02 +00:00
struct sc_pkcs15_object * pin_obj = NULL ;
struct sc_pkcs15_auth_info * auth_info = NULL ;
2017-03-01 16:53:44 +00:00
unsigned int auth_method ;
2014-01-19 17:42:25 +00:00
int r ;
2015-04-19 17:51:22 +00:00
BOOL DisplayPinpadUI = FALSE ;
2010-02-05 13:05:25 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 1 , " CardAuthenticateEx \n " ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardAuthenticateEx: PinId=%u, dwFlags=0x%08X, cbPinData=%lu, Attempts %s \n " ,
( unsigned int ) PinId , ( unsigned int ) dwFlags ,
( unsigned long ) cbPinData , pcAttemptsRemaining ? " YES " : " NO " ) ;
2010-02-05 13:05:25 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2015-05-08 13:49:30 +00:00
r = check_reader_status ( pCardData ) ;
if ( ( vs - > p15card ) = = NULL )
return SCARD_F_INTERNAL_ERROR ;
2011-02-09 17:52:00 +00:00
2017-03-01 16:53:44 +00:00
#if 0
/* TODO do we need to return SCARD_E_UNSUPPORTED_FEATURE if the card
* doesn ' t support it or if the minidriver doesn ' t support it in general ?
* */
2013-09-24 16:07:03 +00:00
if ( dwFlags = = CARD_AUTHENTICATE_GENERATE_SESSION_PIN | | dwFlags = = CARD_AUTHENTICATE_SESSION_PIN ) {
2017-03-23 15:45:31 +00:00
if ( ! ( vs - > reader - > capabilities & SC_READER_CAP_PIN_PAD
| | vs - > p15card - > card - > caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH ) )
2013-09-24 16:07:03 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
2013-12-18 13:15:02 +00:00
}
2017-03-01 16:53:44 +00:00
# endif
2012-05-31 14:40:36 +00:00
2015-04-17 19:39:41 +00:00
if ( dwFlags & ~ ( CARD_AUTHENTICATE_GENERATE_SESSION_PIN | CARD_AUTHENTICATE_SESSION_PIN | CARD_PIN_SILENT_CONTEXT ) )
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
2015-04-17 19:39:41 +00:00
/* using a pin pad */
if ( NULL = = pbPinData ) {
2017-03-23 15:45:31 +00:00
if ( ! ( vs - > reader - > capabilities & SC_READER_CAP_PIN_PAD
| | vs - > p15card - > card - > caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH ) )
2015-04-17 19:39:41 +00:00
return SCARD_E_INVALID_PARAMETER ;
2016-12-09 11:54:06 +00:00
if ( ! ( dwFlags & CARD_PIN_SILENT_CONTEXT )
& & ! ( vs - > ctx - > flags & SC_CTX_FLAG_DISABLE_POPUPS ) ) {
2015-04-19 17:51:22 +00:00
DisplayPinpadUI = TRUE ;
2015-04-17 19:39:41 +00:00
}
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( PinId ! = ROLE_USER )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2013-12-18 13:15:02 +00:00
if ( pcAttemptsRemaining )
2015-04-17 14:39:48 +00:00
( * pcAttemptsRemaining ) = ( DWORD ) - 1 ;
2013-12-18 13:15:02 +00:00
2012-05-31 14:40:36 +00:00
r = md_get_pin_by_role ( pCardData , PinId , & pin_obj ) ;
if ( r ! = SCARD_S_SUCCESS ) {
2011-03-23 18:37:46 +00:00
logprintf ( pCardData , 2 , " Cannot get User PIN object " ) ;
return r ;
}
2013-12-18 13:15:02 +00:00
if ( ! pin_obj )
return SCARD_F_INTERNAL_ERROR ;
auth_info = ( struct sc_pkcs15_auth_info * ) pin_obj - > data ;
2017-03-01 16:53:44 +00:00
/* save the pin type */
auth_method = auth_info - > auth_method ;
2013-12-18 13:15:02 +00:00
2013-09-24 16:07:03 +00:00
/* Do we need to display a prompt to enter PIN on pin pad? */
2015-04-17 19:39:41 +00:00
logprintf ( pCardData , 7 , " PIN pad=%s, pbPinData=%p, hwndParent=%p \n " ,
2017-03-23 15:45:31 +00:00
vs - > reader - > capabilities & SC_READER_CAP_PIN_PAD
| | vs - > p15card - > card - > caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH
? " yes " : " no " , pbPinData , vs - > hwndParent ) ;
2013-12-25 22:18:29 +00:00
2017-03-01 16:53:44 +00:00
if ( dwFlags & CARD_AUTHENTICATE_SESSION_PIN ) {
/* check if the pin is the session pin generated by a previous authentication with a pinpad */
if ( pbPinData ! = NULL & & cbPinData = = sizeof ( MAGIC_SESSION_PIN ) & & memcmp ( MAGIC_SESSION_PIN , pbPinData , sizeof ( MAGIC_SESSION_PIN ) ) = = 0 ) {
logprintf ( pCardData , 2 , " use magic session pin " ) ;
pbPinData = NULL ;
cbPinData = 0 ;
} else {
/* seems we have a real session pin, set the pin type accordingly */
logprintf ( pCardData , 2 , " use real session pin with %d bytes " , cbPinData ) ;
auth_info - > auth_method = SC_AC_SESSION ;
}
}
/* set the session pin according to the minidriver specification */
if ( dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN ) {
logprintf ( pCardData , 2 , " generating session pin " ) ;
if ( ppbSessionPin ) * ppbSessionPin = pCardData - > pfnCspAlloc ( SC_MAX_PIN_SIZE ) ;
if ( ppbSessionPin ) * pcbSessionPin = SC_MAX_PIN_SIZE ;
r = md_dialog_perform_pin_operation ( pCardData , SC_PIN_CMD_GET_SESSION_PIN , vs - > p15card , pin_obj , ( const u8 * ) pbPinData , cbPinData ,
2017-01-13 18:40:03 +00:00
ppbSessionPin & & * ppbSessionPin ? * ppbSessionPin : NULL , pcbSessionPin , DisplayPinpadUI , PinId ) ;
2017-03-01 16:53:44 +00:00
if ( r ) {
if ( ppbSessionPin ) {
pCardData - > pfnCspFree ( * ppbSessionPin ) ;
* ppbSessionPin = NULL ;
}
if ( pcbSessionPin ) * pcbSessionPin = 0 ;
logprintf ( pCardData , 2 , " generating session pin failed " ) ;
} else {
if ( pcbSessionPin & & * pcbSessionPin ) {
logprintf ( pCardData , 2 , " generated session pin with %d bytes " , * pcbSessionPin ) ;
} else {
logprintf ( pCardData , 2 , " session pin not supported " ) ;
if ( ppbSessionPin ) {
pCardData - > pfnCspFree ( * ppbSessionPin ) ;
* ppbSessionPin = NULL ;
}
}
}
} else {
if ( pcbSessionPin ) * pcbSessionPin = 0 ;
if ( ppbSessionPin ) * ppbSessionPin = NULL ;
logprintf ( pCardData , 2 , " standard pin verification " ) ;
2017-01-13 18:40:03 +00:00
r = md_dialog_perform_pin_operation ( pCardData , SC_PIN_CMD_VERIFY , vs - > p15card , pin_obj , ( const u8 * ) pbPinData , cbPinData , NULL , NULL , DisplayPinpadUI , PinId ) ;
2015-04-20 21:25:57 +00:00
}
2017-03-01 16:53:44 +00:00
/* restore the pin type */
auth_info - > auth_method = auth_method ;
2015-04-19 17:51:22 +00:00
2012-05-31 14:40:36 +00:00
if ( r ) {
2013-12-18 13:15:02 +00:00
logprintf ( pCardData , 1 , " PIN code verification failed: %s; tries left %i \n " , sc_strerror ( r ) , auth_info - > tries_left ) ;
2015-04-17 21:04:39 +00:00
if ( r = = SC_ERROR_AUTH_METHOD_BLOCKED ) {
2015-04-18 13:26:42 +00:00
if ( pcAttemptsRemaining )
( * pcAttemptsRemaining ) = 0 ;
2012-05-31 14:40:36 +00:00
return SCARD_W_CHV_BLOCKED ;
2015-04-17 21:04:39 +00:00
}
2013-12-18 13:15:02 +00:00
2011-04-12 07:40:12 +00:00
if ( pcAttemptsRemaining )
2013-12-18 13:15:02 +00:00
( * pcAttemptsRemaining ) = auth_info - > tries_left ;
2015-04-19 17:51:22 +00:00
return md_translate_OpenSC_to_Windows_error ( r , SCARD_W_WRONG_CHV ) ;
2010-02-05 13:05:25 +00:00
}
2011-04-12 07:40:12 +00:00
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 2 , " Pin code correct. \n " ) ;
2011-04-12 07:40:12 +00:00
2015-04-20 21:25:57 +00:00
/* set the session pin according to the minidriver specification */
2017-03-23 15:45:31 +00:00
if ( dwFlags = = CARD_AUTHENTICATE_GENERATE_SESSION_PIN
2017-03-01 16:53:44 +00:00
& & pcbSessionPin & & * pcbSessionPin = = 0
2017-03-23 15:45:31 +00:00
& & ( vs - > reader - > capabilities & SC_READER_CAP_PIN_PAD
| | vs - > p15card - > card - > caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH ) ) {
2017-03-01 16:53:44 +00:00
/* If we could not generate a real session PIN, set it to a special
* value for pinpad authentication to force a new pinpad authentication */
* pcbSessionPin = sizeof ( MAGIC_SESSION_PIN ) ;
2015-04-20 21:25:57 +00:00
if ( ppbSessionPin ) {
* ppbSessionPin = pCardData - > pfnCspAlloc ( sizeof ( MAGIC_SESSION_PIN ) ) ;
if ( ppbSessionPin ) memcpy ( * ppbSessionPin , MAGIC_SESSION_PIN , sizeof ( MAGIC_SESSION_PIN ) ) ;
}
}
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardChangeAuthenticatorEx ( __in PCARD_DATA pCardData ,
__in DWORD dwFlags ,
__in PIN_ID dwAuthenticatingPinId ,
__in_bcount ( cbAuthenticatingPinData ) PBYTE pbAuthenticatingPinData ,
__in DWORD cbAuthenticatingPinData ,
__in PIN_ID dwTargetPinId ,
__in_bcount ( cbTargetData ) PBYTE pbTargetData ,
__in DWORD cbTargetData ,
__in DWORD cRetryCount ,
__out_opt PDWORD pcAttemptsRemaining )
{
2015-04-18 17:09:45 +00:00
VENDOR_SPECIFIC * vs = NULL ;
DWORD dw_rv ;
struct sc_pkcs15_object * pin_obj = NULL ;
int rv ;
struct sc_pkcs15_auth_info * auth_info ;
2015-04-19 17:51:22 +00:00
BOOL DisplayPinpadUI = FALSE ;
2015-04-06 17:38:15 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-18 17:09:45 +00:00
logprintf ( pCardData , 1 , " CardChangeAuthenticatorEx \n " ) ;
2015-04-06 17:38:15 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2015-04-18 17:09:45 +00:00
if ( ! ( dwFlags & PIN_CHANGE_FLAG_UNBLOCK ) & & ! ( dwFlags & PIN_CHANGE_FLAG_CHANGEPIN ) ) {
logprintf ( pCardData , 1 , " Unknown flag \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( ( dwFlags & PIN_CHANGE_FLAG_UNBLOCK ) & & ( dwFlags & PIN_CHANGE_FLAG_CHANGEPIN ) )
2015-04-06 17:38:15 +00:00
return SCARD_E_INVALID_PARAMETER ;
2015-04-18 17:09:45 +00:00
if ( dwFlags & PIN_CHANGE_FLAG_UNBLOCK & & dwAuthenticatingPinId = = dwTargetPinId )
2015-04-06 17:38:15 +00:00
return SCARD_E_INVALID_PARAMETER ;
if ( dwAuthenticatingPinId ! = ROLE_USER & & dwAuthenticatingPinId ! = ROLE_ADMIN )
return SCARD_E_INVALID_PARAMETER ;
2015-04-18 17:09:45 +00:00
if ( dwTargetPinId ! = ROLE_USER & & dwTargetPinId ! = ROLE_ADMIN ) {
logprintf ( pCardData , 1 , " Only ROLE_USER or ROLE_ADMIN is supported \n " ) ;
2015-04-06 17:38:15 +00:00
return SCARD_E_INVALID_PARAMETER ;
2015-04-18 17:09:45 +00:00
}
2015-04-06 17:38:15 +00:00
/* according to the spec: cRetryCount MUST be zero */
if ( cRetryCount )
return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardChangeAuthenticatorEx: AuthenticatingPinId=%u, dwFlags=0x%08X, cbAuthenticatingPinData=%lu, TargetPinId=%u, cbTargetData=%lu, Attempts %s \n " ,
( unsigned int ) dwAuthenticatingPinId , ( unsigned int ) dwFlags ,
( unsigned long ) cbAuthenticatingPinData ,
( unsigned int ) dwTargetPinId , ( unsigned long ) cbTargetData ,
pcAttemptsRemaining ? " YES " : " NO " ) ;
2015-04-06 17:38:15 +00:00
2015-04-18 17:09:45 +00:00
check_reader_status ( pCardData ) ;
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2017-03-23 15:45:31 +00:00
if ( ! ( vs - > reader - > capabilities & SC_READER_CAP_PIN_PAD
| | vs - > p15card - > card - > caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH ) ) {
2015-04-18 17:09:45 +00:00
if ( pbAuthenticatingPinData = = NULL | | cbAuthenticatingPinData = = 0 ) {
logprintf ( pCardData , 1 , " Invalid current PIN data \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
if ( pbTargetData = = NULL | | cbTargetData = = 0 ) {
logprintf ( pCardData , 1 , " Invalid new PIN data \n " ) ;
return SCARD_E_INVALID_PARAMETER ;
}
2015-04-06 17:38:15 +00:00
}
2015-04-18 17:09:45 +00:00
/* using a pin pad */
if ( NULL = = pbAuthenticatingPinData ) {
2016-12-09 11:54:06 +00:00
if ( ! ( dwFlags & CARD_PIN_SILENT_CONTEXT )
& & ! ( vs - > ctx - > flags & SC_CTX_FLAG_DISABLE_POPUPS ) ) {
2015-04-19 17:51:22 +00:00
DisplayPinpadUI = TRUE ;
2015-04-18 17:09:45 +00:00
}
2015-04-06 17:38:15 +00:00
}
2015-04-18 17:09:45 +00:00
dw_rv = md_get_pin_by_role ( pCardData , dwTargetPinId , & pin_obj ) ;
if ( dw_rv ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 2 , " Cannot get User PIN object %s " , ( dwTargetPinId = = ROLE_ADMIN ? " admin " : " user " ) ) ;
return dw_rv ;
}
if ( ! pin_obj )
return SCARD_F_INTERNAL_ERROR ;
if ( pcAttemptsRemaining )
( * pcAttemptsRemaining ) = ( DWORD ) - 1 ;
2015-04-19 17:51:22 +00:00
rv = md_dialog_perform_pin_operation ( pCardData , ( dwFlags & PIN_CHANGE_FLAG_UNBLOCK ? SC_PIN_CMD_UNBLOCK : SC_PIN_CMD_CHANGE ) ,
2017-01-13 18:40:03 +00:00
vs - > p15card , pin_obj , ( const u8 * ) pbAuthenticatingPinData , cbAuthenticatingPinData , pbTargetData , & cbTargetData , DisplayPinpadUI , dwTargetPinId ) ;
2015-04-19 17:51:22 +00:00
2015-04-18 17:09:45 +00:00
if ( rv ) {
logprintf ( pCardData , 2 , " Failed to %s %s PIN: '%s' (%i) \n " ,
( dwFlags & PIN_CHANGE_FLAG_CHANGEPIN ? " change " : " unblock " ) ,
( dwTargetPinId = = ROLE_ADMIN ? " admin " : " user " ) , sc_strerror ( rv ) , rv ) ;
auth_info = ( struct sc_pkcs15_auth_info * ) pin_obj - > data ;
if ( rv = = SC_ERROR_AUTH_METHOD_BLOCKED ) {
if ( pcAttemptsRemaining )
( * pcAttemptsRemaining ) = 0 ;
return SCARD_W_CHV_BLOCKED ;
}
if ( pcAttemptsRemaining )
( * pcAttemptsRemaining ) = auth_info - > tries_left ;
2015-04-19 17:51:22 +00:00
return md_translate_OpenSC_to_Windows_error ( rv , SCARD_W_WRONG_CHV ) ;
2015-04-18 17:09:45 +00:00
}
logprintf ( pCardData , 7 , " returns success \n " ) ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardDeauthenticateEx ( __in PCARD_DATA pCardData ,
__in PIN_SET PinId ,
__in DWORD dwFlags )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardDeauthenticateEx PinId=%u dwFlags=0x%08X \n " ,
( unsigned int ) PinId , ( unsigned int ) dwFlags ) ;
2011-04-12 07:40:12 +00:00
2015-12-09 20:41:37 +00:00
return CardDeauthenticate ( pCardData , wszCARD_USER_USER , 0 ) ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardGetContainerProperty ( __in PCARD_DATA pCardData ,
__in BYTE bContainerIndex ,
__in LPCWSTR wszProperty ,
__out_bcount_part_opt ( cbData , * pdwDataLen ) PBYTE pbData ,
__in DWORD cbData ,
__out PDWORD pdwDataLen ,
__in DWORD dwFlags )
{
2015-04-12 12:06:36 +00:00
VENDOR_SPECIFIC * vs = NULL ;
struct md_pkcs15_container * cont = NULL ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 1 , " CardGetContainerProperty \n " ) ;
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2011-04-12 07:40:12 +00:00
2010-02-05 13:05:25 +00:00
if ( ! pCardData ) return SCARD_E_INVALID_PARAMETER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardGetContainerProperty bContainerIndex=%u, wszProperty=%S, cbData=%lu, dwFlags=0x%08X \n " ,
( unsigned int ) bContainerIndex , NULLWSTR ( wszProperty ) ,
( unsigned long ) cbData , ( unsigned int ) dwFlags ) ;
2012-05-31 14:40:36 +00:00
if ( ! wszProperty )
return SCARD_E_INVALID_PARAMETER ;
if ( dwFlags )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pbData | | ! pdwDataLen )
return SCARD_E_INVALID_PARAMETER ;
2015-04-12 12:06:36 +00:00
if ( bContainerIndex > = MD_MAX_KEY_CONTAINERS )
return SCARD_E_NO_KEY_CONTAINER ;
/* the test for the existence of containers is redondant with the one made in CardGetContainerInfo but CCP_PIN_IDENTIFIER does not do it */
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
cont = & vs - > p15_containers [ bContainerIndex ] ;
if ( ! cont - > prkey_obj ) {
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 7 , " Container %u is empty \n " ,
( unsigned int ) bContainerIndex ) ;
2015-04-12 12:06:36 +00:00
return SCARD_E_NO_KEY_CONTAINER ;
}
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( wcscmp ( CCP_CONTAINER_INFO , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PCONTAINER_INFO p = ( PCONTAINER_INFO ) pbData ;
if ( pdwDataLen ) * pdwDataLen = sizeof ( * p ) ;
if ( cbData > = sizeof ( DWORD ) )
2012-05-31 14:40:36 +00:00
if ( p - > dwVersion ! = CONTAINER_INFO_CURRENT_VERSION & & p - > dwVersion ! = 0 )
return ERROR_REVISION_MISMATCH ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
2010-02-05 13:05:25 +00:00
return CardGetContainerInfo ( pCardData , bContainerIndex , 0 , p ) ;
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( wcscmp ( CCP_PIN_IDENTIFIER , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PPIN_ID p = ( PPIN_ID ) pbData ;
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
2010-02-05 13:05:25 +00:00
* p = ROLE_USER ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " Return Pin id %u \n " ,
( unsigned int ) * p ) ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
2011-04-12 07:40:12 +00:00
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
DWORD WINAPI CardSetContainerProperty ( __in PCARD_DATA pCardData ,
__in BYTE bContainerIndex ,
__in LPCWSTR wszProperty ,
__in_bcount ( cbDataLen ) PBYTE pbData ,
__in DWORD cbDataLen ,
__in DWORD dwFlags )
{
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 1 , " CardSetContainerProperty - unsupported \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_UNSUPPORTED_FEATURE ;
}
2012-05-31 14:40:36 +00:00
2010-02-05 13:05:25 +00:00
DWORD WINAPI CardGetProperty ( __in PCARD_DATA pCardData ,
__in LPCWSTR wszProperty ,
__out_bcount_part_opt ( cbData , * pdwDataLen ) PBYTE pbData ,
__in DWORD cbData ,
__out PDWORD pdwDataLen ,
__in DWORD dwFlags )
{
VENDOR_SPECIFIC * vs ;
2012-05-31 14:40:36 +00:00
DWORD dwret ;
2010-02-05 13:05:25 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 2 ,
" CardGetProperty('%S',cbData=%lu,dwFlags=%lu) called \n " ,
NULLWSTR ( wszProperty ) , ( unsigned long ) cbData ,
( unsigned long ) dwFlags ) ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData | | ! wszProperty )
return SCARD_E_INVALID_PARAMETER ;
if ( ! pbData | | ! pdwDataLen )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2010-02-05 13:05:25 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2011-02-09 17:52:00 +00:00
check_reader_status ( pCardData ) ;
2012-05-31 14:40:36 +00:00
if ( wcscmp ( CP_CARD_FREE_SPACE , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo = ( PCARD_FREE_SPACE_INFO ) pbData ;
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * pCardFreeSpaceInfo ) ;
if ( cbData < sizeof ( * pCardFreeSpaceInfo ) )
return SCARD_E_NO_MEMORY ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
dwret = md_free_space ( pCardData , pCardFreeSpaceInfo ) ;
if ( dwret ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 1 , " Get free space error " ) ;
return dwret ;
}
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_CAPABILITIES , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PCARD_CAPABILITIES pCardCapabilities = ( PCARD_CAPABILITIES ) pbData ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * pCardCapabilities ) ;
if ( cbData < sizeof ( * pCardCapabilities ) )
return ERROR_INSUFFICIENT_BUFFER ;
2015-04-17 16:04:05 +00:00
dwret = md_card_capabilities ( pCardData , pCardCapabilities ) ;
2012-05-31 14:40:36 +00:00
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_KEYSIZES , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PCARD_KEY_SIZES pKeySizes = ( PCARD_KEY_SIZES ) pbData ;
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * pKeySizes ) ;
if ( cbData < sizeof ( * pKeySizes ) )
return ERROR_INSUFFICIENT_BUFFER ;
2011-04-12 07:40:12 +00:00
2015-09-25 20:22:29 +00:00
dwret = md_query_key_sizes ( pCardData , 0 , pKeySizes ) ;
2012-05-31 14:40:36 +00:00
if ( dwret ! = SCARD_S_SUCCESS )
return dwret ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_READ_ONLY , wszProperty ) = = 0 ) {
BOOL * p = ( BOOL * ) pbData ;
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
* p = md_is_read_only ( pCardData ) ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_CACHE_MODE , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
DWORD * p = ( DWORD * ) pbData ;
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
2010-02-05 13:05:25 +00:00
* p = CP_CACHE_MODE_NO_CACHE ;
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_SUPPORTS_WIN_X509_ENROLLMENT , wszProperty ) = = 0 ) {
BOOL * p = ( BOOL * ) pbData ;
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
* p = md_is_supports_X509_enrollment ( pCardData ) ;
}
else if ( wcscmp ( CP_CARD_GUID , wszProperty ) = = 0 ) {
struct md_file * cardid = NULL ;
md_fs_find_file ( pCardData , NULL , " cardid " , & cardid ) ;
if ( ! cardid ) {
logprintf ( pCardData , 2 , " file 'cardid' not found \n " ) ;
return SCARD_E_FILE_NOT_FOUND ;
}
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
2015-04-25 21:29:03 +00:00
* pdwDataLen = ( DWORD ) cardid - > size ;
2012-05-31 14:40:36 +00:00
if ( cbData < cardid - > size )
return ERROR_INSUFFICIENT_BUFFER ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
CopyMemory ( pbData , cardid - > blob , cardid - > size ) ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_SERIAL_NO , wszProperty ) = = 0 ) {
unsigned char buf [ 64 ] ;
size_t buf_len = sizeof ( buf ) ;
if ( sc_hex_to_bin ( vs - > p15card - > tokeninfo - > serial_number , buf , & buf_len ) ) {
2012-08-22 10:45:03 +00:00
buf_len = strlen ( vs - > p15card - > tokeninfo - > serial_number ) ;
if ( buf_len > SC_MAX_SERIALNR ) {
buf_len = SC_MAX_SERIALNR ;
}
memcpy ( buf , vs - > p15card - > tokeninfo - > serial_number , buf_len ) ;
2012-05-31 14:40:36 +00:00
}
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
2015-04-25 21:29:03 +00:00
* pdwDataLen = ( DWORD ) buf_len ;
2012-05-31 14:40:36 +00:00
if ( cbData < buf_len )
return ERROR_INSUFFICIENT_BUFFER ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
CopyMemory ( pbData , buf , buf_len ) ;
2010-02-05 13:05:25 +00:00
}
2013-12-18 13:15:02 +00:00
else if ( wcscmp ( CP_CARD_PIN_INFO , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PPIN_INFO p = ( PPIN_INFO ) pbData ;
2013-12-18 13:15:02 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
if ( p - > dwVersion ! = PIN_INFO_CURRENT_VERSION )
return ERROR_REVISION_MISMATCH ;
2017-03-23 15:45:31 +00:00
p - > PinType = vs - > reader - > capabilities & SC_READER_CAP_PIN_PAD
| | vs - > p15card - > card - > caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH
? ExternalPinType : AlphaNumericPinType ;
2010-02-05 13:05:25 +00:00
p - > dwFlags = 0 ;
2012-05-31 14:40:36 +00:00
switch ( dwFlags ) {
2010-02-05 13:05:25 +00:00
case ROLE_USER :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" returning info on PIN ROLE_USER ( Auth ) [%lu] \n " ,
( unsigned long ) dwFlags ) ;
2010-02-05 13:05:25 +00:00
p - > PinPurpose = DigitalSignaturePin ;
p - > PinCachePolicy . dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION ;
p - > PinCachePolicy . dwPinCachePolicyInfo = 0 ;
p - > PinCachePolicy . PinCachePolicyType = PinCacheNormal ;
2012-05-31 14:40:36 +00:00
p - > dwChangePermission = CREATE_PIN_SET ( ROLE_USER ) ;
p - > dwUnblockPermission = CREATE_PIN_SET ( ROLE_ADMIN ) ;
break ;
case ROLE_ADMIN :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" returning info on PIN ROLE_ADMIN ( Unblock ) [%lu] \n " ,
( unsigned long ) dwFlags ) ;
2012-05-31 14:40:36 +00:00
p - > PinPurpose = UnblockOnlyPin ;
p - > PinCachePolicy . dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION ;
p - > PinCachePolicy . dwPinCachePolicyInfo = 0 ;
p - > PinCachePolicy . PinCachePolicyType = PinCacheNormal ;
p - > dwChangePermission = CREATE_PIN_SET ( ROLE_ADMIN ) ;
2011-04-12 07:40:12 +00:00
p - > dwUnblockPermission = 0 ;
2010-02-05 13:05:25 +00:00
break ;
default :
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 0 ,
" Invalid Pin number %lu requested \n " ,
( unsigned long ) dwFlags ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
2012-05-31 14:40:36 +00:00
}
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_LIST_PINS , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PPIN_SET p = ( PPIN_SET ) pbData ;
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
2010-02-05 13:05:25 +00:00
SET_PIN ( * p , ROLE_USER ) ;
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_AUTHENTICATED_STATE , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
PPIN_SET p = ( PPIN_SET ) pbData ;
2012-05-31 14:40:36 +00:00
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 7 , " CARD_AUTHENTICATED_STATE invalid \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
2012-05-31 14:40:36 +00:00
else if ( wcscmp ( CP_CARD_PIN_STRENGTH_VERIFY , wszProperty ) = = 0 ) {
2010-02-05 13:05:25 +00:00
DWORD * p = ( DWORD * ) pbData ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
if ( dwFlags ! = ROLE_USER )
return SCARD_E_INVALID_PARAMETER ;
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
* p = CARD_PIN_STRENGTH_PLAINTEXT ;
2017-03-01 16:53:44 +00:00
if ( vs - > p15card - > card - > caps & SC_CARD_CAP_SESSION_PIN ) {
* p | = CARD_PIN_STRENGTH_SESSION_PIN ;
}
2010-02-05 13:05:25 +00:00
}
2015-04-07 20:50:39 +00:00
else if ( wcscmp ( CP_KEY_IMPORT_SUPPORT , wszProperty ) = = 0 ) {
DWORD * p = ( DWORD * ) pbData ;
if ( pdwDataLen )
* pdwDataLen = sizeof ( * p ) ;
if ( cbData < sizeof ( * p ) )
return ERROR_INSUFFICIENT_BUFFER ;
* p = 0 ;
}
2015-09-25 20:22:29 +00:00
else if ( wcscmp ( CP_ENUM_ALGORITHMS , wszProperty ) = = 0 ) {
logprintf ( pCardData , 3 , " Unsupported property '%S' \n " , wszProperty ) ;
//TODO
return SCARD_E_INVALID_PARAMETER ;
}
else if ( wcscmp ( CP_PADDING_SCHEMES , wszProperty ) = = 0 ) {
logprintf ( pCardData , 3 , " Unsupported property '%S' \n " , wszProperty ) ;
//TODO
return SCARD_E_INVALID_PARAMETER ;
}
else if ( wcscmp ( CP_CHAINING_MODES , wszProperty ) = = 0 ) {
logprintf ( pCardData , 3 , " Unsupported property '%S' \n " , wszProperty ) ;
//TODO
return SCARD_E_INVALID_PARAMETER ;
}
2012-05-31 14:40:36 +00:00
else {
logprintf ( pCardData , 3 , " Unsupported property '%S' \n " , wszProperty ) ;
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
}
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 7 , " returns '%S' " , wszProperty ) ;
loghex ( pCardData , 7 , pbData , * pdwDataLen ) ;
return SCARD_S_SUCCESS ;
2010-02-05 13:05:25 +00:00
}
DWORD WINAPI CardSetProperty ( __in PCARD_DATA pCardData ,
__in LPCWSTR wszProperty ,
__in_bcount ( cbDataLen ) PBYTE pbData ,
__in DWORD cbDataLen ,
__in DWORD dwFlags )
{
2013-09-24 16:07:03 +00:00
VENDOR_SPECIFIC * vs ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2010-02-17 07:51:52 +00:00
logprintf ( pCardData , 1 , " CardSetProperty \n " ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 ,
" CardSetProperty wszProperty=%S, pbData=%p, cbDataLen=%lu, dwFlags=%lu " ,
NULLWSTR ( wszProperty ) , pbData , ( unsigned long ) cbDataLen ,
( unsigned long ) dwFlags ) ;
2013-09-24 16:07:03 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
if ( ! wszProperty )
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2015-04-07 20:50:39 +00:00
if ( dwFlags )
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2015-04-11 14:30:17 +00:00
if ( ! cbDataLen )
2012-05-31 14:40:36 +00:00
return SCARD_E_INVALID_PARAMETER ;
2010-02-05 13:05:25 +00:00
2015-04-07 20:50:39 +00:00
/* the following properties cannot be set according to the minidriver specifications */
if ( wcscmp ( wszProperty , CP_CARD_FREE_SPACE ) = = 0 | |
wcscmp ( wszProperty , CP_CARD_CAPABILITIES ) = = 0 | |
wcscmp ( wszProperty , CP_CARD_KEYSIZES ) = = 0 | |
wcscmp ( wszProperty , CP_CARD_LIST_PINS ) = = 0 | |
wcscmp ( wszProperty , CP_CARD_AUTHENTICATED_STATE ) = = 0 | |
wcscmp ( wszProperty , CP_KEY_IMPORT_SUPPORT ) = = 0 | |
wcscmp ( wszProperty , CP_ENUM_ALGORITHMS ) = = 0 | |
wcscmp ( wszProperty , CP_PADDING_SCHEMES ) = = 0 | |
wcscmp ( wszProperty , CP_CHAINING_MODES ) = = 0 | |
wcscmp ( wszProperty , CP_SUPPORTS_WIN_X509_ENROLLMENT ) = = 0 | |
wcscmp ( wszProperty , CP_CARD_CACHE_MODE ) = = 0 | |
wcscmp ( wszProperty , CP_CARD_SERIAL_NO ) = = 0
) {
return SCARD_E_UNSUPPORTED_FEATURE ;
2013-09-24 16:07:03 +00:00
}
2010-02-05 13:05:25 +00:00
2015-04-07 20:50:39 +00:00
/* the following properties can be set, but are not implemented by the minidriver */
if ( wcscmp ( CP_CARD_PIN_STRENGTH_VERIFY , wszProperty ) = = 0 | |
wcscmp ( CP_CARD_PIN_INFO , wszProperty ) = = 0 | |
wcscmp ( CP_CARD_GUID , wszProperty ) = = 0 ) {
return SCARD_E_UNSUPPORTED_FEATURE ;
2010-02-05 13:05:25 +00:00
}
2013-09-24 16:07:03 +00:00
/* This property and CP_PIN_CONTEXT_STRING are set just prior to a call to
* CardAuthenticateEx if the PIN required is declared of type ExternalPinType .
*/
2010-02-05 13:05:25 +00:00
if ( wcscmp ( CP_PARENT_WINDOW , wszProperty ) = = 0 ) {
2015-04-11 14:30:17 +00:00
if ( cbDataLen ! = sizeof ( HWND ) | | ! pbData ) {
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
2012-05-31 14:40:36 +00:00
}
else {
2010-02-05 13:05:25 +00:00
HWND cp = * ( ( HWND * ) pbData ) ;
2012-05-31 14:40:36 +00:00
if ( cp ! = 0 & & ! IsWindow ( cp ) )
return SCARD_E_INVALID_PARAMETER ;
2013-09-24 16:07:03 +00:00
vs - > hwndParent = cp ;
2010-02-05 13:05:25 +00:00
}
2015-04-17 19:39:41 +00:00
logprintf ( pCardData , 3 , " Saved parent window (%p) \n " , vs - > hwndParent ) ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
2015-04-07 20:50:39 +00:00
if ( wcscmp ( CP_PIN_CONTEXT_STRING , wszProperty ) = = 0 ) {
2015-04-17 19:39:41 +00:00
vs - > wszPinContext = ( PWSTR ) pbData ;
logprintf ( pCardData , 3 , " Saved PIN context string: %S \n " , ( PWSTR ) pbData ) ;
2015-04-07 20:50:39 +00:00
return SCARD_S_SUCCESS ;
}
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 3 , " INVALID PARAMETER \n " ) ;
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
}
2015-04-06 17:38:15 +00:00
// 4.8 Secure key injection
/** The CardImportSessionKey function imports a temporary session key to the card.
The session key is encrypted with a key exchange key , and the function returns a
handle of the imported session key to the caller . */
DWORD WINAPI CardImportSessionKey (
__in PCARD_DATA pCardData ,
__in BYTE bContainerIndex ,
__in VOID * pPaddingInfo ,
__in LPCWSTR pwszBlobType ,
__in LPCWSTR pwszAlgId ,
__out CARD_KEY_HANDLE * phKey ,
__in_bcount ( cbInput ) PBYTE pbInput ,
__in DWORD cbInput ,
__in DWORD dwFlags
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( bContainerIndex ) ;
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( pPaddingInfo ) ;
UNREFERENCED_PARAMETER ( pwszBlobType ) ;
UNREFERENCED_PARAMETER ( pwszAlgId ) ;
UNREFERENCED_PARAMETER ( phKey ) ;
UNREFERENCED_PARAMETER ( pbInput ) ;
UNREFERENCED_PARAMETER ( cbInput ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardImportSessionKey - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** The MDImportSessionKey function imports a temporary session key to the card minidriver
and returns a key handle to the caller . */
DWORD WINAPI MDImportSessionKey (
__in PCARD_DATA pCardData ,
__in LPCWSTR pwszBlobType ,
__in LPCWSTR pwszAlgId ,
__out PCARD_KEY_HANDLE phKey ,
__in_bcount ( cbInput ) PBYTE pbInput ,
__in DWORD cbInput
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( pwszBlobType ) ;
UNREFERENCED_PARAMETER ( pwszAlgId ) ;
UNREFERENCED_PARAMETER ( phKey ) ;
UNREFERENCED_PARAMETER ( pbInput ) ;
UNREFERENCED_PARAMETER ( cbInput ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " MDImportSessionKey - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** The MDEncryptData function uses a key handle to encrypt data with a symmetric key.
The data is encrypted in a format that the smart card supports . */
DWORD WINAPI MDEncryptData (
__in PCARD_DATA pCardData ,
__in CARD_KEY_HANDLE hKey ,
__in LPCWSTR pwszSecureFunction ,
__in_bcount ( cbInput ) PBYTE pbInput ,
__in DWORD cbInput ,
__in DWORD dwFlags ,
__deref_out_ecount ( * pcEncryptedData )
PCARD_ENCRYPTED_DATA * ppEncryptedData ,
__out PDWORD pcEncryptedData
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( hKey ) ;
UNREFERENCED_PARAMETER ( pwszSecureFunction ) ;
UNREFERENCED_PARAMETER ( pbInput ) ;
UNREFERENCED_PARAMETER ( cbInput ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
UNREFERENCED_PARAMETER ( ppEncryptedData ) ;
UNREFERENCED_PARAMETER ( pcEncryptedData ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " MDEncryptData - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** The CardGetSharedKeyHandle function returns a session key handle to the caller.
Note : The manner in which this session key has been established is outside the
scope of this specification . For example , the session key could be established
by either a permanent shared key or a key derivation algorithm that has occurred
before the call to CardGetSharedKeyHandle . */
DWORD WINAPI CardGetSharedKeyHandle (
__in PCARD_DATA pCardData ,
__in_bcount ( cbInput ) PBYTE pbInput ,
__in DWORD cbInput ,
__deref_opt_out_bcount ( * pcbOutput )
PBYTE * ppbOutput ,
__out_opt PDWORD pcbOutput ,
__out PCARD_KEY_HANDLE phKey
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( pbInput ) ;
UNREFERENCED_PARAMETER ( cbInput ) ;
UNREFERENCED_PARAMETER ( ppbOutput ) ;
UNREFERENCED_PARAMETER ( pcbOutput ) ;
UNREFERENCED_PARAMETER ( phKey ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardGetSharedKeyHandle - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** The CardDestroyKey function releases a temporary key on the card. The card
should delete all of the key material that is associated with that key handle . */
DWORD WINAPI CardDestroyKey (
__in PCARD_DATA pCardData ,
__in CARD_KEY_HANDLE hKey
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( hKey ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardDestroyKey - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** This function can be used to get properties for a cryptographic algorithm.*/
DWORD WINAPI CardGetAlgorithmProperty (
__in PCARD_DATA pCardData ,
__in LPCWSTR pwszAlgId ,
__in LPCWSTR pwszProperty ,
__out_bcount_part_opt ( cbData , * pdwDataLen )
PBYTE pbData ,
__in DWORD cbData ,
__out PDWORD pdwDataLen ,
__in DWORD dwFlags
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( pwszAlgId ) ;
UNREFERENCED_PARAMETER ( pwszProperty ) ;
UNREFERENCED_PARAMETER ( pbData ) ;
UNREFERENCED_PARAMETER ( cbData ) ;
UNREFERENCED_PARAMETER ( pdwDataLen ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardGetAlgorithmProperty - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** This function is used to get the properties of a key.*/
DWORD WINAPI CardGetKeyProperty (
__in PCARD_DATA pCardData ,
__in CARD_KEY_HANDLE hKey ,
__in LPCWSTR pwszProperty ,
__out_bcount_part_opt ( cbData , * pdwDataLen ) PBYTE pbData ,
__in DWORD cbData ,
__out PDWORD pdwDataLen ,
__in DWORD dwFlags
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( hKey ) ;
UNREFERENCED_PARAMETER ( pwszProperty ) ;
UNREFERENCED_PARAMETER ( pbData ) ;
UNREFERENCED_PARAMETER ( cbData ) ;
UNREFERENCED_PARAMETER ( pdwDataLen ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardGetKeyProperty - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** This function is used to set the properties of a key.*/
DWORD WINAPI CardSetKeyProperty (
__in PCARD_DATA pCardData ,
__in CARD_KEY_HANDLE hKey ,
__in LPCWSTR pwszProperty ,
__in_bcount ( cbInput ) PBYTE pbInput ,
__in DWORD cbInput ,
__in DWORD dwFlags
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
UNREFERENCED_PARAMETER ( hKey ) ;
UNREFERENCED_PARAMETER ( pwszProperty ) ;
UNREFERENCED_PARAMETER ( pbInput ) ;
UNREFERENCED_PARAMETER ( cbInput ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardSetKeyProperty - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** CardProcessEncryptedData processes a set of encrypted data BLOBs by
sending them to the card where the data BLOBs are decrypted . */
DWORD WINAPI CardProcessEncryptedData (
__in PCARD_DATA pCardData ,
__in CARD_KEY_HANDLE hKey ,
__in LPCWSTR pwszSecureFunction ,
__in_ecount ( cEncryptedData )
PCARD_ENCRYPTED_DATA pEncryptedData ,
__in DWORD cEncryptedData ,
__out_bcount_part_opt ( cbOutput , * pdwOutputLen )
PBYTE pbOutput ,
__in DWORD cbOutput ,
__out_opt PDWORD pdwOutputLen ,
__in DWORD dwFlags
)
{
UNREFERENCED_PARAMETER ( pCardData ) ;
UNREFERENCED_PARAMETER ( hKey ) ;
UNREFERENCED_PARAMETER ( pwszSecureFunction ) ;
UNREFERENCED_PARAMETER ( pEncryptedData ) ;
UNREFERENCED_PARAMETER ( cEncryptedData ) ;
UNREFERENCED_PARAMETER ( pbOutput ) ;
UNREFERENCED_PARAMETER ( cbOutput ) ;
UNREFERENCED_PARAMETER ( pdwOutputLen ) ;
UNREFERENCED_PARAMETER ( dwFlags ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
2015-04-06 17:38:15 +00:00
logprintf ( pCardData , 1 , " CardProcessEncryptedData - unsupported \n " ) ;
return SCARD_E_UNSUPPORTED_FEATURE ;
}
/** The CardCreateContainerEx function creates a new key container that the
container index identifies and the bContainerIndex parameter specifies . The function
associates the key container with the PIN that the PinId parameter specified .
This function is useful if the card - edge does not allow for changing the key attributes
after the key container is created . This function replaces the need to call
CardSetContainerProperty to set the CCP_PIN_IDENTIFIER property CardCreateContainer
is called .
The caller of this function can provide the key material that the card imports .
This is useful in those situations in which the card either does not support internal
key generation or the caller requests that the key be archived in the card . */
DWORD WINAPI CardCreateContainerEx (
__in PCARD_DATA pCardData ,
__in BYTE bContainerIndex ,
__in DWORD dwFlags ,
__in DWORD dwKeySpec ,
__in DWORD dwKeySize ,
__in PBYTE pbKeyData ,
__in PIN_ID PinId
)
{
if ( PinId = = ROLE_ADMIN )
return SCARD_W_SECURITY_VIOLATION ;
if ( PinId ! = ROLE_USER )
return SCARD_E_INVALID_PARAMETER ;
/* basically CardCreateContainerEx is CardCreateContainer + the PinId */
return CardCreateContainer ( pCardData , bContainerIndex , dwFlags , dwKeySpec , dwKeySize , pbKeyData ) ;
}
2015-04-17 19:39:41 +00:00
DWORD WINAPI CardAcquireContext ( __inout PCARD_DATA pCardData , __in DWORD dwFlags )
2010-02-05 13:05:25 +00:00
{
VENDOR_SPECIFIC * vs ;
2012-05-31 14:40:36 +00:00
DWORD dwret , suppliedVersion = 0 ;
2011-04-12 07:40:12 +00:00
if ( ! pCardData )
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
if ( dwFlags )
2010-02-05 13:05:25 +00:00
return SCARD_E_INVALID_PARAMETER ;
2015-04-06 17:38:15 +00:00
if ( ! ( dwFlags & CARD_SECURE_KEY_INJECTION_NO_CARD_MODE ) ) {
if ( pCardData - > hSCardCtx = = 0 ) {
logprintf ( pCardData , 0 , " Invalide handle. \n " ) ;
return SCARD_E_INVALID_HANDLE ;
}
if ( pCardData - > hScard = = 0 ) {
logprintf ( pCardData , 0 , " Invalide handle. \n " ) ;
return SCARD_E_INVALID_HANDLE ;
}
}
else
{
/* secure key injection not supported */
return SCARD_E_UNSUPPORTED_FEATURE ;
}
if ( pCardData - > pbAtr = = NULL )
return SCARD_E_INVALID_PARAMETER ;
if ( pCardData - > pwszCardName = = NULL )
return SCARD_E_INVALID_PARAMETER ;
/* <2 lenght or >=0x22 are not ISO compliant */
if ( pCardData - > cbAtr > = 0x22 | | pCardData - > cbAtr < = 0x2 )
return SCARD_E_INVALID_PARAMETER ;
/* ATR beginning by 0x00 or 0xFF are not ISO compliant */
if ( pCardData - > pbAtr [ 0 ] = = 0xFF | | pCardData - > pbAtr [ 0 ] = = 0x00 )
return SCARD_E_UNKNOWN_CARD ;
/* Memory management functions */
if ( ( pCardData - > pfnCspAlloc = = NULL ) | |
( pCardData - > pfnCspReAlloc = = NULL ) | |
( pCardData - > pfnCspFree = = NULL ) )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2015-04-06 17:38:15 +00:00
/* The lowest supported version is 4 - maximum is 7. */
if ( pCardData - > dwVersion < MD_MINIMUM_VERSION_SUPPORTED )
return ( DWORD ) ERROR_REVISION_MISMATCH ;
2010-02-05 13:05:25 +00:00
2015-04-06 17:38:15 +00:00
suppliedVersion = pCardData - > dwVersion ;
2017-03-14 21:56:39 +00:00
2010-06-11 07:35:45 +00:00
/* VENDOR SPECIFIC */
2012-05-31 14:40:36 +00:00
vs = pCardData - > pvVendorSpecific = pCardData - > pfnCspAlloc ( sizeof ( VENDOR_SPECIFIC ) ) ;
2017-04-20 19:08:49 +00:00
if ( ! vs )
return SCARD_E_NO_MEMORY ;
2010-02-05 13:05:25 +00:00
memset ( vs , 0 , sizeof ( VENDOR_SPECIFIC ) ) ;
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " ================================================================== \n " ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " \n P:%lu T:%lu pCardData:%p " ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) , pCardData ) ;
logprintf ( pCardData , 1 ,
" CardAcquireContext, dwVersion=%lu, name=%S,hScard=0x%08X, hSCardCtx=0x%08X \n " ,
( unsigned long ) pCardData - > dwVersion ,
NULLWSTR ( pCardData - > pwszCardName ) ,
( unsigned int ) pCardData - > hScard ,
( unsigned int ) pCardData - > hSCardCtx ) ;
2011-02-09 17:52:00 +00:00
vs - > hScard = pCardData - > hScard ;
vs - > hSCardCtx = pCardData - > hSCardCtx ;
2011-04-12 07:40:12 +00:00
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " request version pCardData->dwVersion = %lu \n " ,
( unsigned long ) pCardData - > dwVersion ) ;
2012-05-31 14:40:36 +00:00
pCardData - > dwVersion = min ( pCardData - > dwVersion , MD_CURRENT_VERSION_SUPPORTED ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 2 , " pCardData->dwVersion = %lu \n " ,
( unsigned long ) pCardData - > dwVersion ) ;
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
dwret = md_create_context ( pCardData , vs ) ;
2015-04-06 17:38:15 +00:00
if ( dwret ! = SCARD_S_SUCCESS ) {
pCardData - > pfnCspFree ( pCardData - > pvVendorSpecific ) ;
pCardData - > pvVendorSpecific = NULL ;
2012-05-31 14:40:36 +00:00
return dwret ;
2015-04-06 17:38:15 +00:00
}
2012-05-31 14:40:36 +00:00
md_static_data . flags & = ~ MD_STATIC_FLAG_CONTEXT_DELETED ;
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
pCardData - > pfnCardDeleteContext = CardDeleteContext ;
pCardData - > pfnCardQueryCapabilities = CardQueryCapabilities ;
pCardData - > pfnCardDeleteContainer = CardDeleteContainer ;
pCardData - > pfnCardCreateContainer = CardCreateContainer ;
pCardData - > pfnCardGetContainerInfo = CardGetContainerInfo ;
pCardData - > pfnCardAuthenticatePin = CardAuthenticatePin ;
pCardData - > pfnCardGetChallenge = CardGetChallenge ;
pCardData - > pfnCardAuthenticateChallenge = CardAuthenticateChallenge ;
pCardData - > pfnCardUnblockPin = CardUnblockPin ;
pCardData - > pfnCardChangeAuthenticator = CardChangeAuthenticator ;
2015-12-09 20:41:37 +00:00
pCardData - > pfnCardDeauthenticate = CardDeauthenticate ;
2011-02-09 17:52:00 +00:00
pCardData - > pfnCardCreateDirectory = CardCreateDirectory ;
pCardData - > pfnCardDeleteDirectory = CardDeleteDirectory ;
pCardData - > pvUnused3 = NULL ;
pCardData - > pvUnused4 = NULL ;
pCardData - > pfnCardCreateFile = CardCreateFile ;
pCardData - > pfnCardReadFile = CardReadFile ;
pCardData - > pfnCardWriteFile = CardWriteFile ;
pCardData - > pfnCardDeleteFile = CardDeleteFile ;
pCardData - > pfnCardEnumFiles = CardEnumFiles ;
pCardData - > pfnCardGetFileInfo = CardGetFileInfo ;
pCardData - > pfnCardQueryFreeSpace = CardQueryFreeSpace ;
pCardData - > pfnCardQueryKeySizes = CardQueryKeySizes ;
pCardData - > pfnCardSignData = CardSignData ;
pCardData - > pfnCardRSADecrypt = CardRSADecrypt ;
pCardData - > pfnCardConstructDHAgreement = CardConstructDHAgreement ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
dwret = associate_card ( pCardData ) ;
2015-04-06 17:38:15 +00:00
if ( dwret ! = SCARD_S_SUCCESS ) {
pCardData - > pfnCspFree ( pCardData - > pvVendorSpecific ) ;
pCardData - > pvVendorSpecific = NULL ;
2012-05-31 14:40:36 +00:00
return dwret ;
2015-04-06 17:38:15 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
dwret = md_fs_init ( pCardData ) ;
2015-04-06 17:38:15 +00:00
if ( dwret ! = SCARD_S_SUCCESS ) {
pCardData - > pfnCspFree ( pCardData - > pvVendorSpecific ) ;
pCardData - > pvVendorSpecific = NULL ;
2012-05-31 14:40:36 +00:00
return dwret ;
2015-04-06 17:38:15 +00:00
}
2010-02-05 13:05:25 +00:00
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 1 , " OpenSC init done. \n " ) ;
2017-03-14 21:56:39 +00:00
logprintf ( pCardData , 1 , " Supplied version %lu - version used %lu. \n " ,
( unsigned long ) suppliedVersion ,
( unsigned long ) pCardData - > dwVersion ) ;
2011-04-12 07:40:12 +00:00
2015-04-06 17:38:15 +00:00
if ( pCardData - > dwVersion > = CARD_DATA_VERSION_FIVE ) {
2011-04-12 07:40:12 +00:00
pCardData - > pfnCardDeriveKey = CardDeriveKey ;
pCardData - > pfnCardDestroyDHAgreement = CardDestroyDHAgreement ;
2015-04-06 17:38:15 +00:00
if ( pCardData - > dwVersion > = CARD_DATA_VERSION_SIX ) {
2013-12-19 08:34:52 +00:00
2011-02-09 17:52:00 +00:00
pCardData - > pfnCardGetChallengeEx = CardGetChallengeEx ;
pCardData - > pfnCardAuthenticateEx = CardAuthenticateEx ;
pCardData - > pfnCardChangeAuthenticatorEx = CardChangeAuthenticatorEx ;
pCardData - > pfnCardDeauthenticateEx = CardDeauthenticateEx ;
pCardData - > pfnCardGetContainerProperty = CardGetContainerProperty ;
pCardData - > pfnCardSetContainerProperty = CardSetContainerProperty ;
pCardData - > pfnCardGetProperty = CardGetProperty ;
pCardData - > pfnCardSetProperty = CardSetProperty ;
2015-04-06 17:38:15 +00:00
if ( pCardData - > dwVersion > = CARD_DATA_VERSION_SEVEN ) {
pCardData - > pfnMDImportSessionKey = MDImportSessionKey ;
pCardData - > pfnMDEncryptData = MDEncryptData ;
pCardData - > pfnCardImportSessionKey = CardImportSessionKey ;
pCardData - > pfnCardGetSharedKeyHandle = CardGetSharedKeyHandle ;
pCardData - > pfnCardGetAlgorithmProperty = CardGetAlgorithmProperty ;
pCardData - > pfnCardGetKeyProperty = CardGetKeyProperty ;
pCardData - > pfnCardSetKeyProperty = CardSetKeyProperty ;
pCardData - > pfnCardProcessEncryptedData = CardProcessEncryptedData ;
pCardData - > pfnCardDestroyKey = CardDestroyKey ;
pCardData - > pfnCardCreateContainerEx = CardCreateContainerEx ;
}
2010-02-05 13:05:25 +00:00
}
2011-02-09 17:52:00 +00:00
}
2010-02-05 13:05:25 +00:00
2011-02-09 17:52:00 +00:00
return SCARD_S_SUCCESS ;
}
static int associate_card ( PCARD_DATA pCardData )
{
2012-05-31 14:40:36 +00:00
VENDOR_SPECIFIC * vs ;
DWORD dw ;
2011-02-09 17:52:00 +00:00
int r ;
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 1 , " associate_card \n " ) ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2011-02-09 17:52:00 +00:00
/*
* set the addresses of the reader and card handles
2016-11-15 21:48:48 +00:00
* Our pcsc code will use these when we call sc_ctx_use_reader
2011-02-09 17:52:00 +00:00
* We use the address of the handles as provided in the pCardData
*/
vs - > hSCardCtx = pCardData - > hSCardCtx ;
vs - > hScard = pCardData - > hScard ;
2012-05-31 14:40:36 +00:00
/**
* Check if a linked context has been deleted - if so , repair shared data .
* Multithreaded issue - TODO : proper multithreaded handling
*/
if ( md_static_data . flags & MD_STATIC_FLAG_CONTEXT_DELETED )
{
r = sc_context_repair ( & ( vs - > ctx ) ) ;
logprintf ( pCardData , 2 , " sc_context_repair called - result = %d, %s \n " , r , sc_strerror ( r ) ) ;
md_static_data . flags & = ~ MD_STATIC_FLAG_CONTEXT_DELETED ;
}
2011-02-09 17:52:00 +00:00
/* set the provided reader and card handles into ctx */
2016-11-15 21:48:48 +00:00
logprintf ( pCardData , 5 , " sc_ctx_use_reader %d \n " , sc_ctx_use_reader ( vs - > ctx , & vs - > hSCardCtx , & vs - > hScard ) ) ;
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
/* should be only one reader */
2012-05-31 14:40:36 +00:00
logprintf ( pCardData , 5 , " sc_ctx_get_reader_count(ctx): %d \n " , sc_ctx_get_reader_count ( vs - > ctx ) ) ;
2011-02-09 17:52:00 +00:00
vs - > reader = sc_ctx_get_reader ( vs - > ctx , 0 ) ;
2012-05-31 14:40:36 +00:00
if ( vs - > reader ) {
struct sc_app_info * app_generic = NULL ;
struct sc_aid * aid = NULL ;
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
r = sc_connect_card ( vs - > reader , & ( vs - > card ) ) ;
2012-05-31 14:40:36 +00:00
if ( r ) {
logprintf ( pCardData , 0 , " Cannot connect card in reader '%s' \n " , NULLSTR ( vs - > reader - > name ) ) ;
return SCARD_E_UNKNOWN_CARD ;
}
logprintf ( pCardData , 3 , " Connected card in '%s' \n " , NULLSTR ( vs - > reader - > name ) ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
app_generic = sc_pkcs15_get_application_by_type ( vs - > card , " generic " ) ;
if ( app_generic )
logprintf ( pCardData , 3 , " Use generic application '%s' \n " , app_generic - > label ) ;
aid = app_generic ? & app_generic - > aid : NULL ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
r = sc_pkcs15_bind ( vs - > card , aid , & ( vs - > p15card ) ) ;
logprintf ( pCardData , 2 , " PKCS#15 initialization result: %d, %s \n " , r , sc_strerror ( r ) ) ;
2011-02-09 17:52:00 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
if ( vs - > card = = NULL | | vs - > p15card = = NULL ) {
logprintf ( pCardData , 0 , " Card unknown. \n " ) ;
return SCARD_E_UNKNOWN_CARD ;
2011-02-09 17:52:00 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
dw = md_get_pin_by_role ( pCardData , ROLE_USER , & vs - > obj_user_pin ) ;
if ( dw ! = SCARD_S_SUCCESS ) {
logprintf ( pCardData , 2 , " Cannot get User PIN object " ) ;
return dw ;
2010-02-05 13:05:25 +00:00
}
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
dw = md_get_pin_by_role ( pCardData , ROLE_USER , & vs - > obj_sopin ) ;
if ( dw ! = SCARD_S_SUCCESS )
logprintf ( pCardData , 2 , " Cannot get ADMIN PIN object -- ignored " ) ;
2011-03-23 18:37:46 +00:00
2011-02-09 17:52:00 +00:00
return SCARD_S_SUCCESS ;
}
static int disassociate_card ( PCARD_DATA pCardData )
{
2012-05-31 14:40:36 +00:00
VENDOR_SPECIFIC * vs ;
2011-04-12 07:40:12 +00:00
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 1 , " disassociate_card \n " ) ;
2012-05-31 14:40:36 +00:00
if ( ! pCardData )
return SCARD_E_INVALID_PARAMETER ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
vs = ( VENDOR_SPECIFIC * ) ( pCardData - > pvVendorSpecific ) ;
2011-04-12 07:40:12 +00:00
2012-05-31 14:40:36 +00:00
vs - > obj_user_pin = NULL ;
vs - > obj_sopin = NULL ;
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
if ( vs - > p15card ) {
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 6 , " sc_pkcs15_unbind \n " ) ;
sc_pkcs15_unbind ( vs - > p15card ) ;
vs - > p15card = NULL ;
2010-02-05 13:05:25 +00:00
}
2011-02-09 17:52:00 +00:00
2012-05-31 14:40:36 +00:00
if ( vs - > card ) {
2011-02-09 17:52:00 +00:00
logprintf ( pCardData , 6 , " sc_disconnect_card \n " ) ;
sc_disconnect_card ( vs - > card ) ;
vs - > card = NULL ;
2010-02-05 13:05:25 +00:00
}
2011-02-09 17:52:00 +00:00
vs - > reader = NULL ;
vs - > hSCardCtx = - 1 ;
vs - > hScard = - 1 ;
2010-02-05 13:05:25 +00:00
return SCARD_S_SUCCESS ;
}
2011-02-09 17:52:00 +00:00
2015-04-19 17:51:22 +00:00
BOOL APIENTRY DllMain ( HINSTANCE hinstDLL ,
2010-02-05 13:05:25 +00:00
DWORD ul_reason_for_call ,
LPVOID lpReserved
)
{
2012-05-31 14:40:36 +00:00
CHAR name [ MAX_PATH + 1 ] = " \0 " ;
char * reason = " " ;
2015-03-28 12:04:41 +00:00
GetModuleFileNameA ( GetModuleHandle ( NULL ) , name , MAX_PATH ) ;
2012-05-31 14:40:36 +00:00
switch ( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH :
reason = " Attach Process " ;
break ;
case DLL_THREAD_ATTACH :
reason = " Attach Thread " ;
break ;
case DLL_THREAD_DETACH :
reason = " Detach Thread " ;
break ;
case DLL_PROCESS_DETACH :
reason = " Detach Process " ;
break ;
}
2017-03-14 21:56:39 +00:00
logprintf ( NULL , 8 ,
" \n ********** DllMain Module(handle:0x%p) '%s'; reason='%s'; Reserved=%p; P:%lu; T:%lu \n " ,
hinstDLL , name , reason , lpReserved ,
( unsigned long ) GetCurrentProcessId ( ) ,
( unsigned long ) GetCurrentThreadId ( ) ) ;
2011-04-12 07:40:12 +00:00
switch ( ul_reason_for_call )
2010-02-05 13:05:25 +00:00
{
2012-05-31 14:40:36 +00:00
case DLL_PROCESS_ATTACH :
2015-04-19 17:51:22 +00:00
g_inst = hinstDLL ;
2012-05-31 14:40:36 +00:00
md_static_data . attach_check = MD_STATIC_PROCESS_ATTACHED ;
break ;
case DLL_PROCESS_DETACH :
md_static_data . attach_check = 0 ;
break ;
2010-02-05 13:05:25 +00:00
}
return TRUE ;
}
# ifdef _MANAGED
# pragma managed(pop)
# endif
2011-05-08 08:07:03 +00:00
# endif