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
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
2017-06-17 17:33:37 +00:00
|
|
|
|
#include <string.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>
|
2018-07-27 13:50:41 +00:00
|
|
|
|
#include <timeapi.h>
|
2017-02-09 12:44:07 +00:00
|
|
|
|
#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"
|
2017-06-13 11:35:32 +00:00
|
|
|
|
#include "ui/notify.h"
|
2017-05-24 10:46:25 +00:00
|
|
|
|
#include "ui/strings.h"
|
2017-06-13 11:35:32 +00:00
|
|
|
|
#include "ui/wchar_from_char_str.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
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
#define MD_ROLE_USER_SIGN (ROLE_ADMIN + 1)
|
|
|
|
|
/*
|
|
|
|
|
* must be higher than MD_ROLE_USER_SIGN and
|
|
|
|
|
* less than or equal MAX_PINS
|
|
|
|
|
*/
|
|
|
|
|
#define MD_MAX_PINS MAX_PINS
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
#define MD_CARDCF_LENGTH (sizeof(CARD_CACHE_FILE_FORMAT))
|
|
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
2018-07-27 13:50:41 +00:00
|
|
|
|
#define SUBKEY_ENABLE_CANCEL "Software\\OpenSC Project\\OpenSC\\md_pinpad_dlg_enable_cancel"
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
BOOL initialized;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
struct sc_pkcs15_object *pin_objs[MD_MAX_PINS];
|
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
|
|
|
|
|
2017-02-10 10:26:49 +00:00
|
|
|
|
CRITICAL_SECTION hScard_lock;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
} VENDOR_SPECIFIC;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
2017-03-14 22:58:03 +00:00
|
|
|
|
static DWORD md_translate_OpenSC_to_Windows_error(int OpenSCerror,
|
|
|
|
|
DWORD dwDefaulCode);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static DWORD associate_card(PCARD_DATA pCardData);
|
|
|
|
|
static void 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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static void md_fs_finalize(PCARD_DATA pCardData);
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
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;
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* Use a simplified 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.
|
2018-04-14 17:38:34 +00:00
|
|
|
|
* flush to get last message before any crash
|
2011-02-09 17:52:00 +00:00
|
|
|
|
* 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
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static DWORD reinit_card(PCARD_DATA pCardData)
|
|
|
|
|
{
|
|
|
|
|
VENDOR_SPECIFIC *vs;
|
|
|
|
|
DWORD r;
|
|
|
|
|
|
|
|
|
|
if (!pCardData)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC *)(pCardData->pvVendorSpecific);
|
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 2, "trying to reinit card\n");
|
|
|
|
|
|
|
|
|
|
if (vs->initialized) {
|
|
|
|
|
disassociate_card(pCardData);
|
|
|
|
|
md_fs_finalize(pCardData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = associate_card(pCardData);
|
|
|
|
|
if (r != SCARD_S_SUCCESS)
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
|
|
r = md_fs_init(pCardData);
|
|
|
|
|
if (r != SCARD_S_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 1,
|
|
|
|
|
"reinit_card md_fs_init failed, r = 0x%lX\n",
|
|
|
|
|
(unsigned long)r);
|
|
|
|
|
disassociate_card(pCardData);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SCARD_S_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
static BOOL lock(PCARD_DATA pCardData)
|
|
|
|
|
{
|
|
|
|
|
if (pCardData) {
|
|
|
|
|
VENDOR_SPECIFIC *vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
|
|
|
|
if (vs) {
|
|
|
|
|
EnterCriticalSection(&vs->hScard_lock);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void unlock(PCARD_DATA pCardData)
|
|
|
|
|
{
|
|
|
|
|
if (pCardData) {
|
|
|
|
|
VENDOR_SPECIFIC *vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
|
|
|
|
if (vs) {
|
|
|
|
|
LeaveCriticalSection(&vs->hScard_lock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static DWORD reinit_card_for(PCARD_DATA pCardData, const char *name)
|
|
|
|
|
{
|
|
|
|
|
DWORD r;
|
|
|
|
|
|
|
|
|
|
r = reinit_card(pCardData);
|
|
|
|
|
if (r != SCARD_S_SUCCESS)
|
|
|
|
|
logprintf(pCardData, 1,
|
|
|
|
|
"%s was called, but unable to initialize card, r = %u\n",
|
|
|
|
|
name, (unsigned int)r);
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DWORD check_card_status(PCARD_DATA pCardData, const char *name)
|
|
|
|
|
{
|
|
|
|
|
VENDOR_SPECIFIC *vs;
|
|
|
|
|
|
|
|
|
|
if (!pCardData)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC *)(pCardData->pvVendorSpecific);
|
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
if (vs->initialized)
|
|
|
|
|
return SCARD_S_SUCCESS;
|
|
|
|
|
|
|
|
|
|
return reinit_card_for(pCardData, name);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-09 17:52:00 +00:00
|
|
|
|
/*
|
2017-06-17 17:33:37 +00:00
|
|
|
|
* check if the card is OK, has been removed, or the
|
2011-02-09 17:52:00 +00:00
|
|
|
|
* caller has changed the handles.
|
2017-06-17 17:33:37 +00:00
|
|
|
|
* if so, then try to reinit card
|
2011-02-09 17:52:00 +00:00
|
|
|
|
*/
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static DWORD
|
|
|
|
|
check_card_reader_status(PCARD_DATA pCardData, const char *name)
|
2012-05-31 14:40:36 +00:00
|
|
|
|
{
|
2011-02-09 17:52:00 +00:00
|
|
|
|
VENDOR_SPECIFIC *vs = NULL;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwRet;
|
|
|
|
|
int r;
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 4, "check_reader_status\n");
|
|
|
|
|
if(!pCardData)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwRet = check_card_status(pCardData, name);
|
|
|
|
|
if (dwRet != SCARD_S_SUCCESS)
|
|
|
|
|
return dwRet;
|
|
|
|
|
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
return reinit_card_for(pCardData, name);
|
|
|
|
|
}
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
/* This should always work, as BaseCSP should be checking for removal too */
|
|
|
|
|
r = sc_detect_card_presence(vs->reader);
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"check_reader_status r=%d flags 0x%08X\n", r,
|
|
|
|
|
(unsigned int)vs->reader->flags);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
return md_translate_OpenSC_to_Windows_error(r,
|
|
|
|
|
SCARD_F_INTERNAL_ERROR);
|
|
|
|
|
|
|
|
|
|
if (!(r & SC_READER_CARD_PRESENT)) {
|
|
|
|
|
/*
|
|
|
|
|
* if there is really no card present it may not make sense to
|
|
|
|
|
* try initializing the card but since it won't hurt let's try
|
|
|
|
|
* it anyway for completeness
|
|
|
|
|
*/
|
|
|
|
|
logprintf(pCardData, 1, "no card present? trying to reinit\n");
|
|
|
|
|
return reinit_card_for(pCardData, name);
|
2011-02-09 17:52:00 +00:00
|
|
|
|
}
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
return SCARD_S_SUCCESS;
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
int rv;
|
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;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
/* please keep me in sync with _get_auth_object_by_name() in pkcs11/framework-pkcs15.c */
|
|
|
|
|
if (role == ROLE_USER) {
|
|
|
|
|
/* 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, ret_obj);
|
|
|
|
|
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, ret_obj);
|
|
|
|
|
}
|
|
|
|
|
else if (role == MD_ROLE_USER_SIGN) {
|
|
|
|
|
int idx = 0;
|
|
|
|
|
|
|
|
|
|
/* Get the 'global' user PIN */
|
|
|
|
|
rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_GLOBAL,
|
|
|
|
|
SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
|
|
|
|
|
if (!rv) {
|
|
|
|
|
/* Global (user) PIN exists, get the local one -- sign PIN */
|
|
|
|
|
rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
|
|
|
|
|
SC_PKCS15_PIN_TYPE_FLAGS_MASK, NULL, ret_obj);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* No global PIN, try to get first local one -- user PIN */
|
|
|
|
|
rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
|
|
|
|
|
SC_PKCS15_PIN_TYPE_FLAGS_MASK, &idx, ret_obj);
|
|
|
|
|
if (!rv) {
|
|
|
|
|
/* User PIN is local, try to get the second local -- sign PIN */
|
|
|
|
|
idx++;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
rv = sc_pkcs15_find_pin_by_flags(vs->p15card, SC_PKCS15_PIN_TYPE_FLAGS_PIN_LOCAL,
|
2017-06-16 12:51:41 +00:00
|
|
|
|
SC_PKCS15_PIN_TYPE_FLAGS_MASK, &idx, ret_obj);
|
|
|
|
|
}
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-16 12:51:41 +00:00
|
|
|
|
else if (role == ROLE_ADMIN) {
|
2012-05-31 14:40:36 +00:00
|
|
|
|
/* Get SO PIN; if no, get the 'global' PUK; if no get the 'local' one */
|
2017-06-16 12:51:41 +00:00
|
|
|
|
rv = sc_pkcs15_find_so_pin(vs->p15card, ret_obj);
|
|
|
|
|
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, ret_obj);
|
|
|
|
|
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, ret_obj);
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2017-06-16 12:51:41 +00:00
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"cannot get PIN object: unsupported role %u\n",
|
|
|
|
|
(unsigned int)role);
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (rv)
|
|
|
|
|
return SCARD_E_UNSUPPORTED_FEATURE;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (*ret_obj)
|
|
|
|
|
logprintf(pCardData, 7, "Returning PIN '%.*s' for role %u\n",
|
|
|
|
|
(int) sizeof (*ret_obj)->label, (*ret_obj)->label,
|
|
|
|
|
(unsigned int)role);
|
|
|
|
|
|
|
|
|
|
return SCARD_S_SUCCESS;
|
|
|
|
|
}
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
static const char *
|
|
|
|
|
md_get_config_str(PCARD_DATA pCardData, enum ui_str id)
|
|
|
|
|
{
|
|
|
|
|
VENDOR_SPECIFIC *vs;
|
|
|
|
|
const char *ret = NULL;
|
|
|
|
|
|
|
|
|
|
if (!pCardData)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
|
|
|
|
if (vs->ctx && vs->reader) {
|
|
|
|
|
const char *preferred_language = NULL;
|
|
|
|
|
struct sc_atr atr;
|
|
|
|
|
atr.len = pCardData->cbAtr;
|
|
|
|
|
memcpy(atr.value, pCardData->pbAtr, atr.len);
|
|
|
|
|
if (vs->p15card && vs->p15card->tokeninfo
|
|
|
|
|
&& vs->p15card->tokeninfo->preferred_language) {
|
|
|
|
|
preferred_language = vs->p15card->tokeninfo->preferred_language;
|
|
|
|
|
}
|
|
|
|
|
ret = ui_get_str(vs->ctx, &atr, vs->p15card, id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static HICON
|
|
|
|
|
md_get_config_icon(PCARD_DATA pCardData, char *flag_name, HICON ret_default)
|
|
|
|
|
{
|
|
|
|
|
VENDOR_SPECIFIC *vs;
|
|
|
|
|
HICON ret = ret_default;
|
|
|
|
|
|
|
|
|
|
if (!pCardData)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 2, "Get '%s' option\n", flag_name);
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
|
|
|
|
if (vs->ctx && vs->reader) {
|
|
|
|
|
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);
|
|
|
|
|
logprintf(pCardData, 2, "Match ATR:\n");
|
|
|
|
|
loghex(pCardData, 3, atr.value, atr.len);
|
|
|
|
|
|
|
|
|
|
if (atrblock) {
|
|
|
|
|
const char *filename = scconf_get_str(atrblock, flag_name, NULL);
|
|
|
|
|
if (filename) {
|
|
|
|
|
ret = (HICON) LoadImage(g_inst, filename, IMAGE_ICON, 0, 0,
|
|
|
|
|
LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_SHARED);
|
|
|
|
|
}
|
|
|
|
|
if (!ret)
|
|
|
|
|
ret = ret_default;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static HICON
|
|
|
|
|
md_get_pinpad_dlg_icon(PCARD_DATA pCardData)
|
|
|
|
|
{
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_icon(pCardData, "md_pinpad_dlg_icon", NULL);
|
2017-05-24 10:46:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
md_get_config_int(PCARD_DATA pCardData, char *flag_name, int ret_default)
|
|
|
|
|
{
|
|
|
|
|
VENDOR_SPECIFIC *vs;
|
|
|
|
|
int ret = ret_default;
|
|
|
|
|
|
|
|
|
|
if (!pCardData)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 2, "Get '%s' option\n", flag_name);
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
|
|
|
|
if (vs->ctx && vs->reader) {
|
|
|
|
|
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);
|
|
|
|
|
logprintf(pCardData, 2, "Match ATR:\n");
|
|
|
|
|
loghex(pCardData, 3, atr.value, atr.len);
|
|
|
|
|
|
|
|
|
|
if (atrblock)
|
|
|
|
|
ret = scconf_get_int(atrblock, flag_name, ret_default);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
md_get_pinpad_dlg_timeout(PCARD_DATA pCardData)
|
|
|
|
|
{
|
|
|
|
|
return md_get_config_int(pCardData, "md_pinpad_dlg_timeout", 30);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
static BOOL
|
2017-11-21 12:20:02 +00:00
|
|
|
|
md_get_config_bool(PCARD_DATA pCardData, char *flag_name, 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;
|
|
|
|
|
|
2015-10-11 08:39:02 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return ret;
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-07-27 13:50:41 +00:00
|
|
|
|
/* 'cancellation' mode can be enabled from the OpenSC configuration file*/
|
2017-05-24 10:46:25 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
md_is_pinpad_dlg_enable_cancel(PCARD_DATA pCardData)
|
|
|
|
|
{
|
2018-07-27 13:50:41 +00:00
|
|
|
|
TCHAR path[MAX_PATH]={0};
|
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
logprintf(pCardData, 2, "Is cancelling the PIN pad dialog enabled?\n");
|
2018-07-27 13:50:41 +00:00
|
|
|
|
|
|
|
|
|
if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) {
|
|
|
|
|
DWORD enable_cancel;
|
|
|
|
|
size_t sz = sizeof enable_cancel;
|
|
|
|
|
|
|
|
|
|
if (SC_SUCCESS == sc_ctx_win32_get_config_value(NULL, path,
|
|
|
|
|
SUBKEY_ENABLE_CANCEL,
|
|
|
|
|
(char *)(&enable_cancel), &sz)) {
|
|
|
|
|
switch (enable_cancel) {
|
|
|
|
|
case 0:
|
|
|
|
|
return FALSE;
|
|
|
|
|
case 1:
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "md_pinpad_dlg_enable_cancel", FALSE);
|
2017-05-24 10:46:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-12-29 11:53:41 +00:00
|
|
|
|
/* 'Write' mode can be enabled from the OpenSC configuration file*/
|
|
|
|
|
static BOOL
|
|
|
|
|
md_is_read_only(PCARD_DATA pCardData)
|
|
|
|
|
{
|
2018-07-16 07:26:32 +00:00
|
|
|
|
BOOL ret = TRUE;
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
logprintf(pCardData, 2, "Is read-only?\n");
|
2018-07-16 07:26:32 +00:00
|
|
|
|
|
|
|
|
|
if (pCardData && pCardData->pvVendorSpecific) {
|
|
|
|
|
VENDOR_SPECIFIC *vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
|
|
|
|
if (vs->p15card && vs->p15card->tokeninfo) {
|
|
|
|
|
if (vs->p15card->tokeninfo->flags & SC_PKCS15_TOKEN_READONLY) {
|
|
|
|
|
ret = TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
ret = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-16 20:19:24 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "read_only", ret);
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "md_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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "md_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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "md_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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "md_supports_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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return md_get_config_bool(pCardData, "md_supports_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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
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';
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* prioritize the use of the key id over the key label as a container name */
|
2015-10-11 13:20:04 +00:00
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2016-04-06 16:20:36 +00:00
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
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);
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static void
|
2015-04-12 11:34:18 +00:00
|
|
|
|
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)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
return;
|
2015-04-12 11:34:18 +00:00
|
|
|
|
|
|
|
|
|
vs = pCardData->pvVendorSpecific;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return;
|
2015-04-12 11:34:18 +00:00
|
|
|
|
|
|
|
|
|
file = vs->root.files;
|
|
|
|
|
while (file != NULL) {
|
|
|
|
|
file_to_rm = file;
|
|
|
|
|
file = file->next;
|
|
|
|
|
md_fs_free_file(pCardData, file_to_rm);
|
|
|
|
|
}
|
2017-06-17 17:33:37 +00:00
|
|
|
|
vs->root.files = NULL;
|
2015-04-12 11:34:18 +00:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2017-06-17 17:33:37 +00:00
|
|
|
|
vs->root.subdirs = NULL;
|
2015-04-12 11:34:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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
|
|
|
|
|
2018-02-23 12:29:54 +00:00
|
|
|
|
if (sn_len > 0) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
memset(cardid_bin, 0, MD_CARDID_SIZE);
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
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));
|
|
|
|
|
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
|
|
|
|
* 2a. Update the non-pkcs#15 attributes of the corresponding internal p15_container;
|
|
|
|
|
* 2b. 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.
|
2018-04-14 17:38:34 +00:00
|
|
|
|
* 3. Initialize the content of the 'soft' 'cmapfile' from the internal p15-containers.
|
2012-05-31 14:40:36 +00:00
|
|
|
|
*/
|
|
|
|
|
static DWORD
|
|
|
|
|
md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
|
|
|
|
|
{
|
2017-06-16 12:51:41 +00:00
|
|
|
|
typedef enum { SCF_NONE,
|
|
|
|
|
SCF_NONDEFAULT_SIGN_PIN,
|
|
|
|
|
SCF_NONDEFAULT_OTHER_PIN,
|
|
|
|
|
SCF_NONDEFAULT_USER_PIN,
|
|
|
|
|
SCF_DEFAULT_SIGN_PIN,
|
|
|
|
|
SCF_DEFAULT_OTHER_PIN,
|
|
|
|
|
SCF_DEFAULT_USER_PIN
|
|
|
|
|
} pin_mode_t;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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];
|
2017-06-16 12:51:41 +00:00
|
|
|
|
pin_mode_t pin_mode = SCF_NONE;
|
|
|
|
|
int pin_cont_idx = -1;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
dwret = md_get_pin_by_role(pCardData, ROLE_USER, &vs->pin_objs[ROLE_USER]);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 2, "Cannot get User PIN object");
|
|
|
|
|
return dwret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dwret = md_get_pin_by_role(pCardData, MD_ROLE_USER_SIGN, &vs->pin_objs[MD_ROLE_USER_SIGN]);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 2, "Cannot get Sign PIN object -- ignored");
|
|
|
|
|
vs->pin_objs[MD_ROLE_USER_SIGN] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dwret = md_get_pin_by_role(pCardData, ROLE_ADMIN, &vs->pin_objs[ROLE_ADMIN]);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 2, "Cannot get Admin PIN object -- ignored");
|
|
|
|
|
vs->pin_objs[ROLE_ADMIN] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7, "Container[%i] is '%.*s' guid=%.*s\n", ii,
|
|
|
|
|
(int) sizeof key_obj->label, key_obj->label,
|
|
|
|
|
(int) sizeof cont->guid, cont->guid);
|
|
|
|
|
|
|
|
|
|
if (cont->flags & CONTAINER_MAP_VALID_CONTAINER &&
|
|
|
|
|
key_obj->auth_id.len > 0) {
|
|
|
|
|
struct sc_pkcs15_object *keypin_obj;
|
|
|
|
|
struct sc_pkcs15_auth_info *userpin_info =
|
|
|
|
|
(struct sc_pkcs15_auth_info *)vs->pin_objs[ROLE_USER]->data;
|
|
|
|
|
struct sc_pkcs15_auth_info *signpin_info =
|
|
|
|
|
vs->pin_objs[MD_ROLE_USER_SIGN] ?
|
|
|
|
|
(struct sc_pkcs15_auth_info *)vs->pin_objs[MD_ROLE_USER_SIGN]->data :
|
|
|
|
|
NULL;
|
|
|
|
|
struct sc_pkcs15_auth_info *adminpin_info =
|
|
|
|
|
vs->pin_objs[ROLE_ADMIN] ?
|
|
|
|
|
(struct sc_pkcs15_auth_info *)vs->pin_objs[ROLE_ADMIN]->data :
|
|
|
|
|
NULL;
|
|
|
|
|
|
|
|
|
|
if (sc_pkcs15_find_pin_by_auth_id(vs->p15card, &key_obj->auth_id, &keypin_obj))
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"Container[%i] has an unknown auth id, might not work properly\n",
|
|
|
|
|
ii);
|
|
|
|
|
else {
|
|
|
|
|
size_t pinidx;
|
|
|
|
|
size_t pinidxempty = MD_MAX_PINS;
|
|
|
|
|
for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
|
|
|
|
|
struct sc_pkcs15_auth_info *pin_info;
|
|
|
|
|
|
|
|
|
|
if (!vs->pin_objs[pinidx]) {
|
|
|
|
|
if (pinidxempty >= MD_MAX_PINS)
|
|
|
|
|
pinidxempty = pinidx;
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pin_info =
|
|
|
|
|
(struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data;
|
|
|
|
|
|
|
|
|
|
if (sc_pkcs15_compare_id(&key_obj->auth_id,
|
|
|
|
|
&pin_info->auth_id))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pinidx >= MD_MAX_PINS) {
|
|
|
|
|
if (pinidxempty >= MD_MAX_PINS)
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"no free slot for container[%i] auth id, might not work properly\n",
|
|
|
|
|
ii);
|
|
|
|
|
else
|
|
|
|
|
vs->pin_objs[pinidxempty] = keypin_obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sc_pkcs15_compare_id(&key_obj->auth_id, &userpin_info->auth_id)) {
|
|
|
|
|
pin_mode_t pin_mode_n =
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
|
|
|
|
|
SCF_DEFAULT_USER_PIN : SCF_NONDEFAULT_USER_PIN;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7,
|
|
|
|
|
"Container[%i]%s is secured by User PIN\n",
|
|
|
|
|
ii,
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
|
|
|
|
|
" (default)" : "");
|
|
|
|
|
|
|
|
|
|
if (pin_mode < pin_mode_n) {
|
|
|
|
|
pin_mode = pin_mode_n;
|
|
|
|
|
pin_cont_idx = ii;
|
|
|
|
|
}
|
|
|
|
|
} else if (signpin_info != NULL &&
|
|
|
|
|
sc_pkcs15_compare_id(&key_obj->auth_id, &signpin_info->auth_id)) {
|
|
|
|
|
pin_mode_t pin_mode_n =
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
|
|
|
|
|
SCF_DEFAULT_SIGN_PIN : SCF_NONDEFAULT_SIGN_PIN;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7,
|
|
|
|
|
"Container[%i]%s is secured by Sign PIN\n",
|
|
|
|
|
ii,
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
|
|
|
|
|
" (default)" : "");
|
|
|
|
|
|
|
|
|
|
if (pin_mode < pin_mode_n) {
|
|
|
|
|
pin_mode = pin_mode_n;
|
|
|
|
|
pin_cont_idx = ii;
|
|
|
|
|
}
|
|
|
|
|
} else if (adminpin_info != NULL &&
|
|
|
|
|
sc_pkcs15_compare_id(&key_obj->auth_id, &adminpin_info->auth_id)) {
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"Container[%i] is secured by Admin PIN, might not work properly\n",
|
|
|
|
|
ii);
|
|
|
|
|
} else {
|
|
|
|
|
pin_mode_t pin_mode_n =
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
|
|
|
|
|
SCF_DEFAULT_OTHER_PIN : SCF_NONDEFAULT_OTHER_PIN;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7,
|
|
|
|
|
"Container[%i]%s is secured by other PIN\n",
|
|
|
|
|
ii,
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER ?
|
|
|
|
|
" (default)" : "");
|
|
|
|
|
|
|
|
|
|
if (pin_mode < pin_mode_n) {
|
|
|
|
|
pin_mode = pin_mode_n;
|
|
|
|
|
pin_cont_idx = ii;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cont->flags & CONTAINER_MAP_VALID_CONTAINER &&
|
|
|
|
|
cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER)
|
2016-04-06 16:20:36 +00:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
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];
|
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* Try to find the friend objects: certificate and public key */
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (strcmp(dinfo->app_label, "CSP"))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!strncmp(dobjs[ii]->label, "Default Key Container", 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
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
/* if no default container was found promote the best one (PIN-wise) to default */
|
|
|
|
|
if (!found_default && (pin_mode == SCF_NONDEFAULT_SIGN_PIN ||
|
|
|
|
|
pin_mode == SCF_NONDEFAULT_OTHER_PIN ||
|
|
|
|
|
pin_mode == SCF_NONDEFAULT_USER_PIN)) {
|
|
|
|
|
struct md_pkcs15_container *cont =
|
|
|
|
|
&vs->p15_containers[pin_cont_idx];
|
|
|
|
|
cont->flags |= CONTAINER_MAP_DEFAULT_CONTAINER;
|
|
|
|
|
|
|
|
|
|
found_default = 1;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7,
|
|
|
|
|
"Container[%i] promoted to default\n",
|
|
|
|
|
pin_cont_idx);
|
|
|
|
|
|
|
|
|
|
if (pin_mode == SCF_NONDEFAULT_SIGN_PIN)
|
|
|
|
|
pin_mode = SCF_DEFAULT_SIGN_PIN;
|
|
|
|
|
else if (pin_mode == SCF_NONDEFAULT_OTHER_PIN)
|
|
|
|
|
pin_mode = SCF_DEFAULT_OTHER_PIN;
|
|
|
|
|
else
|
|
|
|
|
pin_mode = SCF_DEFAULT_USER_PIN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if all containers use non-user PINs we need to make the best container PIN the user (primary) one */
|
|
|
|
|
if (pin_mode == SCF_NONDEFAULT_SIGN_PIN ||
|
|
|
|
|
pin_mode == SCF_DEFAULT_SIGN_PIN ||
|
|
|
|
|
pin_mode == SCF_NONDEFAULT_OTHER_PIN ||
|
|
|
|
|
pin_mode == SCF_DEFAULT_OTHER_PIN) {
|
|
|
|
|
struct sc_pkcs15_object *user_pin_old =
|
|
|
|
|
vs->pin_objs[ROLE_USER];
|
|
|
|
|
struct sc_pkcs15_object *user_pin_new =
|
|
|
|
|
NULL;
|
|
|
|
|
|
|
|
|
|
if (pin_mode == SCF_NONDEFAULT_SIGN_PIN ||
|
|
|
|
|
pin_mode == SCF_DEFAULT_SIGN_PIN) {
|
|
|
|
|
user_pin_new = vs->pin_objs[MD_ROLE_USER_SIGN];
|
|
|
|
|
vs->pin_objs[MD_ROLE_USER_SIGN] = NULL;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7,
|
|
|
|
|
"Sign PIN%s promoted to user one\n",
|
|
|
|
|
pin_mode == SCF_DEFAULT_SIGN_PIN ?
|
|
|
|
|
" (from default container)" : "");
|
|
|
|
|
} else {
|
|
|
|
|
struct sc_pkcs15_object *key_obj =
|
|
|
|
|
vs->p15_containers[pin_cont_idx].prkey_obj;
|
|
|
|
|
struct sc_pkcs15_object *keypin_obj;
|
|
|
|
|
|
|
|
|
|
if (sc_pkcs15_find_pin_by_auth_id(vs->p15card, &key_obj->auth_id, &keypin_obj))
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"Cannot find container[%i] auth id again, might not work properly\n",
|
|
|
|
|
pin_cont_idx);
|
|
|
|
|
else {
|
|
|
|
|
size_t pinidx;
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 7,
|
|
|
|
|
"Container[%i]%s PIN will be made the user one\n",
|
|
|
|
|
pin_cont_idx,
|
|
|
|
|
pin_mode == SCF_DEFAULT_OTHER_PIN ?
|
|
|
|
|
" (default)" : "");
|
|
|
|
|
|
|
|
|
|
for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
|
|
|
|
|
struct sc_pkcs15_auth_info *pin_info;
|
|
|
|
|
|
|
|
|
|
if (!vs->pin_objs[pinidx])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
pin_info =
|
|
|
|
|
(struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data;
|
|
|
|
|
|
|
|
|
|
if (sc_pkcs15_compare_id(&key_obj->auth_id,
|
|
|
|
|
&pin_info->auth_id)) {
|
|
|
|
|
vs->pin_objs[pinidx] = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
user_pin_new = keypin_obj;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (user_pin_new) {
|
|
|
|
|
size_t pinidx;
|
|
|
|
|
|
|
|
|
|
vs->pin_objs[ROLE_USER] = user_pin_new;
|
|
|
|
|
|
|
|
|
|
for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
|
|
|
|
|
if (vs->pin_objs[pinidx])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
vs->pin_objs[pinidx] = user_pin_old;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pinidx >= MD_MAX_PINS) {
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"no free slot for previous User PIN, replacing last one\n");
|
|
|
|
|
|
|
|
|
|
vs->pin_objs[MD_MAX_PINS - 1] = user_pin_old;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
dwret = md_fs_add_file(pCardData, &(vs->root.files), "cardcf", EveryoneReadUserWriteAc, NULL, 0, &cardcf);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
dwret = md_set_cardcf(pCardData, cardcf);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
dwret = md_fs_add_file(pCardData, &(vs->root.files), "cardapps", EveryoneReadAdminWriteAc, NULL, 0, &cardapps);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
dwret = md_set_cardapps(pCardData, cardapps);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
dwret = md_fs_add_directory(pCardData, &(vs->root.subdirs), "mscp", UserCreateDeleteDirAc, &mscp);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
dwret = md_fs_add_file(pCardData, &(mscp->files), "cmapfile", EveryoneReadUserWriteAc, NULL, 0, &cmapfile);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
dwret = md_set_cmapfile(pCardData, cmapfile);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-06-17 17:33:37 +00:00
|
|
|
|
goto ret_cleanup;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
|
|
|
|
ret_cleanup:
|
|
|
|
|
md_fs_finalize(pCardData);
|
|
|
|
|
return dwret;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
/* 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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
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
|
2017-06-16 12:51:41 +00:00
|
|
|
|
md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD key_size, PIN_ID PinId)
|
2012-05-31 14:40:36 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
DWORD 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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId])
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
pin_obj = vs->pin_objs[PinId];
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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
|
2017-06-16 12:51:41 +00:00
|
|
|
|
md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob, DWORD blob_size, PIN_ID PinId)
|
2012-05-31 14:40:36 +00:00
|
|
|
|
{
|
|
|
|
|
#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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
DWORD 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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
if (PinId >= MD_MAX_PINS || !vs->pin_objs[PinId])
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
pin_obj = vs->pin_objs[PinId];
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2015-09-25 20:22:29 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* dwKeySpec=0 is a special value when the key size is queried without specifying the algorithm.
|
2015-09-25 20:22:29 +00:00
|
|
|
|
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-05-24 10:46:25 +00:00
|
|
|
|
static const char *md_get_ui_str(PCARD_DATA pCardData, enum ui_str id)
|
|
|
|
|
{
|
|
|
|
|
const char *str = md_get_config_str(pCardData, id);
|
|
|
|
|
|
|
|
|
|
if (str && *str == '\0') {
|
|
|
|
|
/* if the user used an empty string, remove the field by setting it to NULL */
|
|
|
|
|
str = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-02 21:12:58 +00:00
|
|
|
|
static HRESULT CALLBACK md_dialog_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData)
|
2015-04-19 17:51:22 +00:00
|
|
|
|
{
|
2017-03-01 20:15:11 +00:00
|
|
|
|
LONG_PTR param;
|
|
|
|
|
|
2017-02-09 12:44:07 +00:00
|
|
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
|
|
|
switch (message) {
|
|
|
|
|
case TDN_CREATED:
|
2017-05-24 10:46:25 +00:00
|
|
|
|
{
|
|
|
|
|
PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)dwRefData)[7];
|
2018-07-27 13:50:41 +00:00
|
|
|
|
DWORD now = timeGetTime();
|
|
|
|
|
|
2017-05-24 10:46:25 +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);
|
2018-07-27 13:50:41 +00:00
|
|
|
|
|
|
|
|
|
/* store parameter like pCardData for further use if needed */
|
|
|
|
|
((LONG_PTR*)dwRefData)[11] = (LONG_PTR) now;
|
|
|
|
|
SetWindowLongPtr(hWnd, GWLP_USERDATA, dwRefData);
|
|
|
|
|
((LONG_PTR*)dwRefData)[10] = (LONG_PTR) hWnd;
|
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
if (!md_is_pinpad_dlg_enable_cancel(pCardData)) {
|
2018-07-27 13:50:41 +00:00
|
|
|
|
int timeout = md_get_pinpad_dlg_timeout(pCardData);
|
|
|
|
|
if (timeout > 0) {
|
|
|
|
|
SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, timeout*1000));
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
/* disable "Close" */
|
|
|
|
|
SendMessage(hWnd, TDM_ENABLE_BUTTON, IDCLOSE, 0);
|
2018-07-27 13:50:41 +00:00
|
|
|
|
|
|
|
|
|
/* launch the function in another thread context store the thread handle */
|
|
|
|
|
((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL);
|
|
|
|
|
} else {
|
|
|
|
|
int timeout = md_get_pinpad_dlg_timeout(pCardData);
|
|
|
|
|
if (timeout > 0) {
|
|
|
|
|
SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, 0);
|
|
|
|
|
SendMessage(hWnd, TDM_SET_PROGRESS_BAR_STATE, PBST_PAUSED, 0);
|
|
|
|
|
}
|
2017-05-24 10:46:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-01 20:15:11 +00:00
|
|
|
|
return S_OK;
|
|
|
|
|
|
2017-02-09 12:44:07 +00:00
|
|
|
|
case TDN_TIMER:
|
2018-07-27 13:50:41 +00:00
|
|
|
|
SendMessage(hWnd, TDM_SET_PROGRESS_BAR_POS, wParam, 0L);
|
2017-02-09 12:44:07 +00:00
|
|
|
|
return S_OK;
|
2017-03-01 20:15:11 +00:00
|
|
|
|
|
2017-02-09 12:44:07 +00:00
|
|
|
|
case TDN_BUTTON_CLICKED:
|
2018-07-27 13:50:41 +00:00
|
|
|
|
switch(LOWORD(wParam)) {
|
|
|
|
|
case IDCANCEL:
|
|
|
|
|
DestroyWindow(hWnd);
|
|
|
|
|
break;
|
2017-02-24 16:00:25 +00:00
|
|
|
|
|
2018-07-27 13:50:41 +00:00
|
|
|
|
case IDOK:
|
|
|
|
|
param = GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
|
|
|
if (param) {
|
|
|
|
|
PCARD_DATA pCardData = (PCARD_DATA)((LONG_PTR*)param)[7];
|
|
|
|
|
VENDOR_SPECIFIC* vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
|
|
|
|
|
|
|
|
|
int timeout = md_get_pinpad_dlg_timeout(pCardData);
|
|
|
|
|
if (timeout > 0) {
|
|
|
|
|
DWORD start = (DWORD)((LONG_PTR*)dwRefData)[11];
|
|
|
|
|
DWORD delta = timeGetTime() - start;
|
|
|
|
|
SendMessage(hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(delta, delta + timeout*1000));
|
|
|
|
|
SendMessage(hWnd, TDM_SET_PROGRESS_BAR_STATE, PBST_NORMAL, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* disable "OK" and "Cancel" */
|
|
|
|
|
SendMessage(hWnd, TDM_ENABLE_BUTTON, IDOK, 0);
|
|
|
|
|
SendMessage(hWnd, TDM_ENABLE_BUTTON, IDCANCEL, 0);
|
|
|
|
|
|
|
|
|
|
/* disable "x" */
|
|
|
|
|
HMENU menu = GetSystemMenu(hWnd, FALSE);
|
|
|
|
|
if (menu) {
|
|
|
|
|
EnableMenuItem(menu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* launch the function in another thread context store the thread handle */
|
|
|
|
|
((LONG_PTR*)dwRefData)[9] = (LONG_PTR) CreateThread(NULL, 0, md_dialog_perform_pin_operation_thread, (LPVOID) dwRefData, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-05-24 10:46:25 +00:00
|
|
|
|
|
2018-07-27 13:50:41 +00:00
|
|
|
|
default:
|
|
|
|
|
return S_FALSE;
|
2017-01-13 18:40:03 +00:00
|
|
|
|
}
|
2017-02-24 16:00:25 +00:00
|
|
|
|
break;
|
2017-03-01 20:15:11 +00:00
|
|
|
|
|
2017-02-09 12:44:07 +00:00
|
|
|
|
case TDN_DESTROYED:
|
2017-03-01 20:15:11 +00:00
|
|
|
|
/* clean resources used */
|
|
|
|
|
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
|
|
|
|
{
|
2018-07-27 13:50:41 +00:00
|
|
|
|
LONG_PTR parameter[12];
|
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;
|
2018-07-27 13:50:41 +00:00
|
|
|
|
BOOL checked, user_checked;
|
2015-04-19 17:51:22 +00:00
|
|
|
|
VENDOR_SPECIFIC* pv = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-02-09 12:44:07 +00:00
|
|
|
|
|
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 */
|
2018-07-27 13:50:41 +00:00
|
|
|
|
parameter[11] = 0; /* place holder for end of timer */
|
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;
|
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
tc.pszWindowTitle = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_TITLE));
|
|
|
|
|
tc.pszMainInstruction = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_MAIN));
|
|
|
|
|
tc.pszExpandedControlText = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_CONTROL_EXPANDED));
|
|
|
|
|
tc.pszCollapsedControlText = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_CONTROL_COLLAPSED));
|
|
|
|
|
tc.pszExpandedInformation = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_EXPANDED));
|
2018-07-27 13:50:41 +00:00
|
|
|
|
tc.pszVerificationText = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_VERIFICATION));
|
2017-05-24 10:46:25 +00:00
|
|
|
|
switch (role) {
|
|
|
|
|
case ROLE_ADMIN:
|
|
|
|
|
tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_CONTENT_ADMIN));
|
|
|
|
|
break;
|
2017-10-17 07:38:19 +00:00
|
|
|
|
case MD_ROLE_USER_SIGN:
|
|
|
|
|
tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_CONTENT_USER_SIGN));
|
|
|
|
|
break;
|
2017-05-24 10:46:25 +00:00
|
|
|
|
case ROLE_USER:
|
|
|
|
|
default:
|
|
|
|
|
tc.pszContent = wchar_from_char_str(md_get_ui_str(pCardData,
|
|
|
|
|
MD_PINPAD_DLG_CONTENT_USER));
|
|
|
|
|
break;
|
2017-02-09 12:44:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-16 11:16:13 +00:00
|
|
|
|
if (pv->wszPinContext) {
|
2017-05-24 10:46:25 +00:00
|
|
|
|
/* overwrite the main instruction with the application's information if
|
|
|
|
|
* possible */
|
2017-02-09 12:44:07 +00:00
|
|
|
|
tc.pszMainInstruction = pv->wszPinContext;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
tc.dwFlags = TDF_POSITION_RELATIVE_TO_WINDOW;
|
|
|
|
|
if (tc.pszExpandedInformation != NULL) {
|
|
|
|
|
tc.dwFlags |= TDF_EXPAND_FOOTER_AREA;
|
|
|
|
|
}
|
|
|
|
|
if (md_get_pinpad_dlg_timeout(pCardData) > 0) {
|
|
|
|
|
tc.dwFlags |= TDF_SHOW_PROGRESS_BAR | TDF_CALLBACK_TIMER;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-27 13:50:41 +00:00
|
|
|
|
checked = !md_is_pinpad_dlg_enable_cancel(pCardData);
|
|
|
|
|
if (checked) {
|
|
|
|
|
tc.dwFlags |= TDF_VERIFICATION_FLAG_CHECKED;
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* can't use TDCBF_CANCEL_BUTTON since this would implicitly set TDF_ALLOW_DIALOG_CANCELLATION */
|
2017-05-24 10:46:25 +00:00
|
|
|
|
tc.dwCommonButtons = TDCBF_CLOSE_BUTTON;
|
2018-07-27 13:50:41 +00:00
|
|
|
|
} else {
|
|
|
|
|
tc.dwFlags |= TDF_ALLOW_DIALOG_CANCELLATION;
|
|
|
|
|
tc.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_OK_BUTTON;
|
2017-02-16 11:16:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
tc.hMainIcon = md_get_pinpad_dlg_icon(pCardData);
|
|
|
|
|
if (tc.hMainIcon) {
|
|
|
|
|
tc.dwFlags |= TDF_USE_HICON_MAIN;
|
|
|
|
|
} else {
|
|
|
|
|
tc.pszMainIcon = MAKEINTRESOURCEW(IDI_SMARTCARD);
|
|
|
|
|
}
|
2017-02-09 12:44:07 +00:00
|
|
|
|
tc.pfCallback = md_dialog_proc;
|
|
|
|
|
tc.lpCallbackData = (LONG_PTR)parameter;
|
|
|
|
|
tc.cbSize = sizeof(tc);
|
|
|
|
|
|
2018-07-27 13:50:41 +00:00
|
|
|
|
result = TaskDialogIndirect(&tc, NULL, NULL, &user_checked);
|
|
|
|
|
|
|
|
|
|
if (user_checked != checked) {
|
|
|
|
|
TCHAR path[MAX_PATH]={0};
|
|
|
|
|
if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) {
|
|
|
|
|
HKEY hKey;
|
|
|
|
|
LSTATUS lstatus = RegOpenKeyExA(HKEY_CURRENT_USER,
|
|
|
|
|
SUBKEY_ENABLE_CANCEL, 0, KEY_WRITE, &hKey);
|
|
|
|
|
if (ERROR_SUCCESS != lstatus) {
|
|
|
|
|
lstatus = RegCreateKeyExA(HKEY_CURRENT_USER,
|
|
|
|
|
SUBKEY_ENABLE_CANCEL, 0, NULL, REG_OPTION_NON_VOLATILE,
|
|
|
|
|
KEY_WRITE, NULL, &hKey, NULL);
|
|
|
|
|
}
|
|
|
|
|
if (ERROR_SUCCESS == lstatus) {
|
|
|
|
|
DWORD enable_cancel = 0;
|
|
|
|
|
if (user_checked == FALSE) {
|
|
|
|
|
enable_cancel = 1;
|
|
|
|
|
}
|
|
|
|
|
lstatus = RegSetValueEx(hKey, path, 0, REG_DWORD,
|
|
|
|
|
(const BYTE*)&enable_cancel, sizeof(enable_cancel));
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-09 12:44:07 +00:00
|
|
|
|
|
2017-05-24 10:46:25 +00:00
|
|
|
|
LocalFree((WCHAR *) tc.pszWindowTitle);
|
|
|
|
|
LocalFree((WCHAR *) tc.pszMainInstruction);
|
|
|
|
|
LocalFree((WCHAR *) tc.pszExpandedControlText);
|
|
|
|
|
LocalFree((WCHAR *) tc.pszCollapsedControlText);
|
|
|
|
|
LocalFree((WCHAR *) tc.pszExpandedInformation);
|
|
|
|
|
LocalFree((WCHAR *) tc.pszContent);
|
|
|
|
|
|
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;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
CRITICAL_SECTION hScard_lock;
|
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,
|
|
|
|
|
"\nP:%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;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
hScard_lock = vs->hScard_lock;
|
|
|
|
|
EnterCriticalSection(&hScard_lock);
|
|
|
|
|
|
|
|
|
|
disassociate_card(pCardData);
|
|
|
|
|
md_fs_finalize(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);
|
|
|
|
|
vs->ctx = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
logprintf(pCardData, 1, "**********************************************************************\n");
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
|
|
|
|
pCardData->pfnCspFree(pCardData->pvVendorSpecific);
|
|
|
|
|
pCardData->pvVendorSpecific = NULL;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
LeaveCriticalSection(&hScard_lock);
|
|
|
|
|
DeleteCriticalSection(&hScard_lock);
|
|
|
|
|
|
2010-02-05 13:05:25 +00:00
|
|
|
|
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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || !pCardCapabilities || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_status(pCardData, "CardQueryCapabilities");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = md_card_capabilities(pCardData, pCardCapabilities);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
|
|
|
|
return dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || !lock(pCardData))
|
2015-09-30 20:52:37 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardDeleteContainer");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-09-30 20:52:37 +00:00
|
|
|
|
|
|
|
|
|
if (!md_is_supports_container_key_gen(pCardData)) {
|
|
|
|
|
logprintf(pCardData, 1, "Denied 'deletion' mechanism to delete container.\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
2015-09-30 20:52:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-09-30 20:52:37 +00:00
|
|
|
|
|
|
|
|
|
cont = &(vs->p15_containers[bContainerIndex]);
|
|
|
|
|
|
|
|
|
|
dwret = md_pkcs15_delete_object(pCardData, cont->prkey_obj);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
2015-09-30 20:52:37 +00:00
|
|
|
|
logprintf(pCardData, 1, "private key deletion failed\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2015-09-30 20:52:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dwret = md_pkcs15_delete_object(pCardData, cont->pubkey_obj);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 1, "public key deletion failed\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2015-09-30 20:52:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ZeroMemory(cont, sizeof(struct md_pkcs15_container));
|
|
|
|
|
|
|
|
|
|
logprintf(pCardData, 1, "key deleted\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
|
|
|
|
return dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
/** 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)
|
2010-02-05 13:05:25 +00:00
|
|
|
|
{
|
2012-05-31 14:40:36 +00:00
|
|
|
|
DWORD dwret;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (PinId == ROLE_ADMIN) {
|
|
|
|
|
dwret = SCARD_W_SECURITY_VIOLATION;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardCreateContainerEx");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
|
|
|
|
|
(unsigned long)GetCurrentProcessId(),
|
|
|
|
|
(unsigned long)GetCurrentThreadId(), pCardData);
|
|
|
|
|
logprintf(pCardData, 1,
|
2017-06-16 12:51:41 +00:00
|
|
|
|
"CardCreateContainerEx(idx:%u,flags:%lX,type:%lX,size:%lu,data:%p,pin:%u)\n",
|
2017-03-14 21:56:39 +00:00
|
|
|
|
(unsigned int)bContainerIndex, (unsigned long)dwFlags,
|
2017-06-16 12:51:41 +00:00
|
|
|
|
(unsigned long)dwKeySpec, (unsigned long)dwKeySize, pbKeyData,
|
|
|
|
|
(unsigned int)PinId);
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
2013-12-29 11:53:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
if (dwFlags & CARD_CREATE_CONTAINER_KEY_GEN) {
|
2017-06-16 12:51:41 +00:00
|
|
|
|
dwret = md_pkcs15_generate_key(pCardData, bContainerIndex, dwKeySpec, dwKeySize, PinId);
|
2012-05-31 14:40:36 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
2013-12-29 11:54:36 +00:00
|
|
|
|
logprintf(pCardData, 1, "key generation failed\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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)) {
|
2017-06-16 12:51:41 +00:00
|
|
|
|
dwret = md_pkcs15_store_key(pCardData, bContainerIndex, dwKeySpec, pbKeyData, dwKeySize, PinId);
|
2012-05-31 14:40:36 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
2013-12-29 11:54:36 +00:00
|
|
|
|
logprintf(pCardData, 1, "key store failed\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
|
|
|
|
return dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
|
|
|
|
|
__in BYTE bContainerIndex,
|
|
|
|
|
__in DWORD dwFlags,
|
|
|
|
|
__in DWORD dwKeySpec,
|
|
|
|
|
__in DWORD dwKeySize,
|
|
|
|
|
__in PBYTE pbKeyData)
|
|
|
|
|
{
|
|
|
|
|
return CardCreateContainerEx(pCardData, bContainerIndex, dwFlags,
|
|
|
|
|
dwKeySpec, dwKeySize, pbKeyData,
|
|
|
|
|
ROLE_USER);
|
|
|
|
|
}
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD ret;
|
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;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
pubkey_der.value = NULL;
|
|
|
|
|
pubkey_der.len = 0;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
if(!pCardData)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pContainerInfo || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
ret = check_card_reader_status(pCardData, "CardGetContainerInfo");
|
|
|
|
|
if (ret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dwFlags) {
|
|
|
|
|
ret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
if (bContainerIndex >= MD_MAX_KEY_CONTAINERS) {
|
|
|
|
|
ret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
if (pContainerInfo->dwVersion > CONTAINER_INFO_CURRENT_VERSION) {
|
|
|
|
|
ret = ERROR_REVISION_MISMATCH;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
pContainerInfo->dwVersion = CONTAINER_INFO_CURRENT_VERSION;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
ret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
ret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
ret = SCARD_F_UNKNOWN_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
|
|
|
|
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
ret = SCARD_F_INTERNAL_ERROR;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!publicKey) {
|
|
|
|
|
ret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!publicKey) {
|
|
|
|
|
ret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
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);
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
ret = SCARD_F_INTERNAL_ERROR;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
2015-10-15 20:40:36 +00:00
|
|
|
|
publicKey = (BCRYPT_ECCKEY_BLOB *)pCardData->pfnCspAlloc(sz);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!publicKey) {
|
|
|
|
|
ret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
ret = SCARD_F_INTERNAL_ERROR;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2015-10-15 20:40:36 +00:00
|
|
|
|
publicKey = (BCRYPT_ECCKEY_BLOB *)pCardData->pfnCspAlloc(sz);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!publicKey) {
|
|
|
|
|
ret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-09-25 20:22:29 +00:00
|
|
|
|
|
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-11-21 12:20:02 +00:00
|
|
|
|
logprintf(pCardData, 7, "returns container(idx:%u) info",
|
|
|
|
|
(unsigned int)bContainerIndex);
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
2017-11-14 15:10:28 +00:00
|
|
|
|
free(pubkey_der.value);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
unlock(pCardData);
|
2017-11-14 15:10:28 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return ret;
|
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, "\nP:%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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2013-12-19 08:34:52 +00:00
|
|
|
|
int rv;
|
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!ppbChallengeData || !pcbChallengeData || !lock(pCardData))
|
2013-12-19 08:34:52 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardGetChallenge");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS) {
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2013-12-19 08:34:52 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2013-12-19 08:34:52 +00:00
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!*ppbChallengeData) {
|
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2013-12-19 08:34:52 +00:00
|
|
|
|
|
2015-04-17 19:39:41 +00:00
|
|
|
|
rv = sc_get_challenge(vs->p15card->card, *ppbChallengeData, 8);
|
2018-01-23 12:53:23 +00:00
|
|
|
|
if (rv < 0) {
|
2013-12-19 08:34:52 +00:00
|
|
|
|
logprintf(pCardData, 1, "Get challenge failed: %s\n", sc_strerror(rv));
|
2015-04-17 19:39:41 +00:00
|
|
|
|
pCardData->pfnCspFree(*ppbChallengeData);
|
|
|
|
|
*ppbChallengeData = NULL;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_UNEXPECTED;
|
|
|
|
|
goto err;
|
2013-12-19 08:34:52 +00:00
|
|
|
|
}
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_S_SUCCESS;
|
2013-12-19 08:34:52 +00:00
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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, "\nP:%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)
|
|
|
|
|
{
|
2017-11-21 12:20:02 +00:00
|
|
|
|
DWORD r = SCARD_S_SUCCESS;
|
|
|
|
|
|
|
|
|
|
if(!pCardData || !lock(pCardData))
|
2013-12-19 12:08:03 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
r = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
r = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2016-08-25 20:41:58 +00:00
|
|
|
|
}
|
|
|
|
|
if (wcscmp(wszCARD_USER_ADMIN, pwszUserId) == 0) {
|
|
|
|
|
logprintf(pCardData, 1, "unlocking admin not supported\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
r = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
2016-08-25 20:41:58 +00:00
|
|
|
|
}
|
|
|
|
|
if (dwFlags & CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE) {
|
|
|
|
|
logprintf(pCardData, 1,
|
2017-11-21 12:20:02 +00:00
|
|
|
|
"challenge / response not supported, we'll treat response as a PUK\n");
|
2016-08-25 20:41:58 +00:00
|
|
|
|
logprintf(pCardData, 1,
|
2017-11-21 12:20:02 +00:00
|
|
|
|
"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");
|
2016-08-25 20:41:58 +00:00
|
|
|
|
dwFlags &= ~CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE;
|
|
|
|
|
}
|
|
|
|
|
if (dwFlags) {
|
|
|
|
|
logprintf(pCardData, 1, "flags of %x not supported\n",
|
2017-11-21 12:20:02 +00:00
|
|
|
|
(unsigned int)dwFlags);
|
|
|
|
|
r = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
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,
|
2017-11-21 12:20:02 +00:00
|
|
|
|
"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);
|
|
|
|
|
|
|
|
|
|
r = CardChangeAuthenticatorEx(pCardData,
|
|
|
|
|
PIN_CHANGE_FLAG_UNBLOCK |
|
|
|
|
|
CARD_PIN_SILENT_CONTEXT,
|
|
|
|
|
ROLE_ADMIN, pbAuthenticationData,
|
|
|
|
|
cbAuthenticationData, ROLE_USER,
|
|
|
|
|
pbNewPinData, cbNewPinData,
|
|
|
|
|
cRetryCount, NULL);
|
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
2017-03-14 21:56:39 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
return r;
|
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)
|
|
|
|
|
{
|
2017-11-21 12:20:02 +00:00
|
|
|
|
DWORD r = SCARD_S_SUCCESS;
|
2015-04-18 17:09:45 +00:00
|
|
|
|
PIN_ID pinid;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
if(!pCardData || !lock(pCardData))
|
2013-12-22 17:05:32 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%lu T:%lu pCardData:%p ",
|
2017-11-21 12:20:02 +00:00
|
|
|
|
(unsigned long)GetCurrentProcessId(),
|
|
|
|
|
(unsigned long)GetCurrentThreadId(), pCardData);
|
2013-12-22 17:05:32 +00:00
|
|
|
|
logprintf(pCardData, 1, "CardChangeAuthenticator\n");
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (pwszUserId == NULL) {
|
|
|
|
|
r = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2013-12-22 17:05:32 +00:00
|
|
|
|
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
r = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
2013-12-22 17:05:32 +00:00
|
|
|
|
}
|
2015-04-18 17:09:45 +00:00
|
|
|
|
else if (dwFlags != CARD_AUTHENTICATE_PIN_PIN){
|
2017-11-21 12:20:02 +00:00
|
|
|
|
r = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2015-04-18 17:09:45 +00:00
|
|
|
|
}
|
2013-12-22 17:05:32 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (wcscmp(wszCARD_USER_USER, pwszUserId) != 0 && wcscmp(wszCARD_USER_ADMIN, pwszUserId) != 0) {
|
|
|
|
|
r = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2013-12-22 17:05:32 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1,
|
2017-11-21 12:20:02 +00:00
|
|
|
|
"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-11-21 12:20:02 +00:00
|
|
|
|
r = CardChangeAuthenticatorEx(pCardData, PIN_CHANGE_FLAG_CHANGEPIN |
|
|
|
|
|
CARD_PIN_SILENT_CONTEXT, pinid,
|
|
|
|
|
pbCurrentAuthenticator,
|
|
|
|
|
cbCurrentAuthenticator, pinid,
|
|
|
|
|
pbNewAuthenticator, cbNewAuthenticator,
|
|
|
|
|
cRetryCount, pcAttemptsRemaining);
|
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return r;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
/* Note: the PIN freshness 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)
|
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2015-12-09 20:41:37 +00:00
|
|
|
|
VENDOR_SPECIFIC* vs = NULL;
|
|
|
|
|
int rv;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!pCardData || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardDeauthenticate");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2015-12-09 20:41:37 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-12-09 20:41:37 +00:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (rv != SC_SUCCESS) {
|
|
|
|
|
/* force a reset of a card - SCARD_S_SUCCESS do not lead to the reset
|
|
|
|
|
* of the card and leave it still authenticated */
|
|
|
|
|
dwret = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dwret = SCARD_S_SUCCESS;
|
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
|
|
|
|
return dwret;
|
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, "\nP:%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, "\nP:%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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!lock(pCardData))
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_status(pCardData, "CardCreateFile");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dwret = md_fs_add_file(pCardData, &dir->files, pszFileName, AccessCondition, NULL, cbInitialCreationSize, NULL);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
|
|
|
|
return dwret;
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!pCardData || !lock(pCardData))
|
2012-05-31 14:40:36 +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,
|
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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pszFileName || !strlen(pszFileName) || dwFlags) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardReadFile");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_FILE_NOT_FOUND;
|
|
|
|
|
goto err;
|
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) {
|
|
|
|
|
dwret = md_fs_read_content(pCardData, pszDirectoryName, file);
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-03-14 22:58:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ppbData) {
|
|
|
|
|
*ppbData = pCardData->pfnCspAlloc(file->size);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!*ppbData) {
|
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2017-03-14 22:58:03 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
|
|
|
|
return dwret;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!pCardData || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardWriteFile");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_FILE_NOT_FOUND;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
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 (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)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!pCardData || !lock(pCardData))
|
2010-02-05 13:05:25 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardDeleteFile");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || !pmszFileNames || !pdwcbFileName || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_status(pCardData, "CardEnumFiles");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2012-05-31 14:40:36 +00:00
|
|
|
|
|
|
|
|
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_FILE_NOT_FOUND;
|
|
|
|
|
goto err;
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (*pmszFileNames == NULL) {
|
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
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;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
struct md_file *file = NULL;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if(!pCardData || !lock(pCardData))
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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);
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_status(pCardData, "CardGetFileInfo");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_FILE_NOT_FOUND;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || !lock(pCardData))
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_status(pCardData, "CardQueryFreeSpace");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
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, "CardQueryFreeSpace() md free space error");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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, "\nP:%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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || dwFlags != 0 || dwKeySpec == 0 || !lock(pCardData))
|
2015-09-25 20:22:29 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_status(pCardData, "CardQueryKeySizes");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +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)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
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));
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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 CardRSADecrypt(__in PCARD_DATA pCardData,
|
|
|
|
|
__inout PCARD_RSA_DECRYPT_INFO pInfo)
|
|
|
|
|
|
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
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, "\nP:%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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pCardData || !pInfo || pInfo->pbData == NULL)
|
2015-04-11 09:08:52 +00:00
|
|
|
|
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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!lock(pCardData))
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardRSADecrypt");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2011-02-09 17:52:00 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
2015-04-11 09:08:52 +00:00
|
|
|
|
/* check if the container exists */
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) {
|
|
|
|
|
dwret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-04-11 09:08:52 +00:00
|
|
|
|
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pbuf) {
|
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_F_INTERNAL_ERROR;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* filter bogus input: the data to decrypt is shorter than the RSA key ? */
|
2015-04-11 09:08:52 +00:00
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_INSUFFICIENT_BUFFER;
|
|
|
|
|
goto err;
|
2015-04-11 09:08:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_F_INTERNAL_ERROR;
|
|
|
|
|
goto err;
|
2015-04-11 09:08:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_F_INTERNAL_ERROR;
|
|
|
|
|
goto err;
|
2013-05-22 10:11:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE);
|
|
|
|
|
goto err;
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
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
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
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];
|
2018-10-04 13:59:11 +00:00
|
|
|
|
int opt_crypt_flags;
|
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, "\nP:%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-11-21 12:20:02 +00:00
|
|
|
|
if (!lock(pCardData))
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardSignData");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (pInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) {
|
|
|
|
|
dwret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
pkey = vs->p15_containers[pInfo->bContainerIndex].prkey_obj;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pkey) {
|
|
|
|
|
dwret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2012-05-31 14:40:36 +00:00
|
|
|
|
prkey_info = (struct sc_pkcs15_prkey_info *)(pkey->data);
|
2011-02-09 17:52:00 +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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (dataToSignLen < pInfo->cbData) {
|
|
|
|
|
dwret = SCARD_E_INSUFFICIENT_BUFFER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2011-03-23 18:37:46 +00:00
|
|
|
|
memcpy(dataToSign, pInfo->pbData, pInfo->cbData);
|
|
|
|
|
dataToSignLen = pInfo->cbData;
|
|
|
|
|
|
2018-10-04 13:59:11 +00:00
|
|
|
|
if (0 == (CARD_PADDING_INFO_PRESENT & pInfo->dwSigningFlags)) {
|
|
|
|
|
/* When CARD_PADDING_INFO_PRESENT is not set in dwSigningFlags, this is
|
|
|
|
|
* the basic version of the signing structure. (If this is not the
|
|
|
|
|
* basic verison of the signing structure, the minidriver should return
|
|
|
|
|
* ERROR_REVISION_MISMATCH.) The minidriver should only do PKCS1
|
|
|
|
|
* padding and use the value in aiHashAlg. */
|
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
|
|
|
|
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
if (hashAlg == CALG_MD5)
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
else if (hashAlg == CALG_SHA1)
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
2011-03-23 18:37:46 +00:00
|
|
|
|
else if (hashAlg == CALG_SSL3_SHAMD5)
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
else if (hashAlg == CALG_SHA_256)
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
|
2015-04-11 12:17:20 +00:00
|
|
|
|
else if (hashAlg == CALG_SHA_384)
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
|
2015-04-11 12:17:20 +00:00
|
|
|
|
else if (hashAlg == CALG_SHA_512)
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
|
2015-04-11 12:17:20 +00:00
|
|
|
|
else if (hashAlg == (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_RIPEMD160))
|
2018-10-04 13:59:11 +00:00
|
|
|
|
opt_crypt_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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
2018-10-04 13:59:11 +00:00
|
|
|
|
} else {
|
|
|
|
|
switch (pInfo->dwPaddingType) {
|
|
|
|
|
case CARD_PADDING_NONE:
|
|
|
|
|
opt_crypt_flags = SC_ALGORITHM_RSA_PAD_NONE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CARD_PADDING_PKCS1:
|
|
|
|
|
opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1;
|
2018-10-15 13:14:14 +00:00
|
|
|
|
BCRYPT_PKCS1_PADDING_INFO *pkcs1_pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo;
|
2018-10-04 13:59:11 +00:00
|
|
|
|
|
2018-10-15 13:14:14 +00:00
|
|
|
|
if (!pkcs1_pinf->pszAlgId || wcscmp(pkcs1_pinf->pszAlgId, L"SHAMD5") == 0) {
|
2018-10-04 13:59:11 +00:00
|
|
|
|
/* hashAlg = CALG_SSL3_SHAMD5; */
|
|
|
|
|
logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n");
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1;
|
2018-10-15 13:14:14 +00:00
|
|
|
|
} else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_MD5_ALGORITHM) == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5;
|
|
|
|
|
else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA1_ALGORITHM) == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
|
|
|
|
else if (wcscmp(pkcs1_pinf->pszAlgId, L"SHA224") == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224;
|
|
|
|
|
else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA256_ALGORITHM) == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
|
|
|
|
|
else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA384_ALGORITHM) == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
|
|
|
|
|
else if (wcscmp(pkcs1_pinf->pszAlgId, BCRYPT_SHA512_ALGORITHM) == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
|
|
|
|
|
else if (wcscmp(pkcs1_pinf->pszAlgId, L"RIPEMD160") == 0)
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160;
|
|
|
|
|
else {
|
|
|
|
|
logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pkcs1_pinf->pszAlgId));
|
|
|
|
|
dwret = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CARD_PADDING_PSS:
|
|
|
|
|
opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PSS;
|
|
|
|
|
BCRYPT_PSS_PADDING_INFO *pss_pinf = (BCRYPT_PSS_PADDING_INFO *)pInfo->pPaddingInfo;
|
|
|
|
|
ULONG expected_salt_len;
|
|
|
|
|
|
|
|
|
|
if (!pss_pinf->pszAlgId || wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA1_ALGORITHM) == 0) {
|
|
|
|
|
/* hashAlg = CALG_SHA1; */
|
|
|
|
|
logprintf(pCardData, 3, "Using CALG_SHA1 hashAlg\n");
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
|
|
|
|
expected_salt_len = 160;
|
|
|
|
|
} else if (wcscmp(pss_pinf->pszAlgId, L"SHA224") == 0) {
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224;
|
|
|
|
|
expected_salt_len = 224;
|
|
|
|
|
} else if (wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA256_ALGORITHM) == 0) {
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
|
|
|
|
|
expected_salt_len = 256;
|
|
|
|
|
} else if (wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA384_ALGORITHM) == 0) {
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
|
|
|
|
|
expected_salt_len = 384;
|
|
|
|
|
} else if (wcscmp(pss_pinf->pszAlgId, BCRYPT_SHA512_ALGORITHM) == 0) {
|
|
|
|
|
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
|
|
|
|
|
expected_salt_len = 512;
|
2018-10-04 13:59:11 +00:00
|
|
|
|
} else {
|
2018-10-15 13:14:14 +00:00
|
|
|
|
logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pss_pinf->pszAlgId));
|
|
|
|
|
dwret = SCARD_E_UNSUPPORTED_FEATURE;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
/* We're strict, and only do PSS signatures with a salt length that
|
|
|
|
|
* matches the digest length (any shorter is rubbish, any longer
|
|
|
|
|
* is useless). */
|
|
|
|
|
if (pss_pinf->cbSalt != expected_salt_len / 8) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2018-10-04 13:59:11 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
logprintf(pCardData, 0, "unsupported paddingtype\n");
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
2011-03-23 18:37:46 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-10-04 13:59:11 +00:00
|
|
|
|
|
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;
|
|
|
|
|
} else if ( prkey_info->field_length > 0) {
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_INVALID_VALUE;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
logprintf(pCardData, 0, "invalid private key\n");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_INVALID_VALUE;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!pbuf) {
|
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_F_INTERNAL_ERROR);
|
|
|
|
|
goto err;
|
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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
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, "\nP:%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;
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!lock(pCardData))
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardConstructDHAgreement");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
2017-11-21 12:20:02 +00:00
|
|
|
|
goto err;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
2015-09-25 20:22:29 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
dwret = SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-09-25 20:22:29 +00:00
|
|
|
|
|
|
|
|
|
/* check if the container exists */
|
2017-11-21 12:20:02 +00:00
|
|
|
|
if (pAgreementInfo->bContainerIndex >= MD_MAX_KEY_CONTAINERS) {
|
|
|
|
|
dwret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
2015-09-25 20:22:29 +00:00
|
|
|
|
|
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");
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_NO_KEY_CONTAINER;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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) {
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = ERROR_OUTOFMEMORY;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE);
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out = pCardData->pfnCspAlloc(outlen);
|
|
|
|
|
|
|
|
|
|
if (!out) {
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = ERROR_OUTOFMEMORY;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = md_translate_OpenSC_to_Windows_error(r, SCARD_E_INVALID_VALUE);
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_S_SUCCESS;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* 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);
|
2017-11-21 12:20:02 +00:00
|
|
|
|
dwret = SCARD_E_NO_MEMORY;
|
|
|
|
|
goto err;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
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++;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
unlock(pCardData);
|
|
|
|
|
return dwret;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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, "\nP:%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;
|
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* according to the documentation, CARD_DERIVE_KEY_CURRENT_VERSION should be equal to 2.
|
|
|
|
|
In practice it is not 2 but 1
|
2015-09-25 20:22:29 +00:00
|
|
|
|
|
|
|
|
|
if ( pAgreementInfo->dwVersion < CARD_DERIVE_KEY_CURRENT_VERSION
|
|
|
|
|
&& pCardData->dwVersion == CARD_DATA_CURRENT_VERSION)
|
|
|
|
|
return ERROR_REVISION_MISMATCH;*/
|
|
|
|
|
|
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* check the values with the KDF chosen */
|
2015-09-25 20:22:29 +00:00
|
|
|
|
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, "\nP:%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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2015-09-25 20:22:29 +00:00
|
|
|
|
|
|
|
|
|
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, "\nP:%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)
|
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
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, "\nP:%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-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardAuthenticateEx");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
return dwret;
|
|
|
|
|
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (PinId >= MD_MAX_PINS)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2015-05-08 13:49:30 +00:00
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
pin_obj = vs->pin_objs[PinId];
|
|
|
|
|
if (!pin_obj)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
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;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN &&
|
|
|
|
|
(ppbSessionPin == NULL || pcbSessionPin == NULL))
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
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 */
|
2017-06-16 12:51:41 +00:00
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"use real session pin with %lu bytes",
|
|
|
|
|
(unsigned long)cbPinData);
|
2017-03-01 16:53:44 +00:00
|
|
|
|
auth_info->auth_method = SC_AC_SESSION;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set the session pin according to the minidriver specification */
|
|
|
|
|
if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN) {
|
2017-06-16 12:51:41 +00:00
|
|
|
|
size_t session_pin_len = SC_MAX_PIN_SIZE;
|
|
|
|
|
|
2017-03-01 16:53:44 +00:00
|
|
|
|
logprintf(pCardData, 2, "generating session pin");
|
2017-06-16 12:51:41 +00:00
|
|
|
|
*ppbSessionPin = pCardData->pfnCspAlloc(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,
|
|
|
|
|
*ppbSessionPin,
|
|
|
|
|
*ppbSessionPin != NULL ?
|
|
|
|
|
&session_pin_len : NULL,
|
2017-10-16 13:16:34 +00:00
|
|
|
|
DisplayPinpadUI, PinId);
|
2017-03-01 16:53:44 +00:00
|
|
|
|
if (r) {
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (*ppbSessionPin != NULL) {
|
2017-03-01 16:53:44 +00:00
|
|
|
|
pCardData->pfnCspFree(*ppbSessionPin);
|
|
|
|
|
*ppbSessionPin = NULL;
|
|
|
|
|
}
|
2017-06-16 12:51:41 +00:00
|
|
|
|
*pcbSessionPin = 0;
|
2017-03-01 16:53:44 +00:00
|
|
|
|
logprintf(pCardData, 2, "generating session pin failed");
|
|
|
|
|
} else {
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (*ppbSessionPin != NULL && session_pin_len > 0) {
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"generated session pin with %"SC_FORMAT_LEN_SIZE_T"u bytes",
|
|
|
|
|
session_pin_len);
|
|
|
|
|
|
|
|
|
|
*pcbSessionPin = session_pin_len;
|
2017-03-01 16:53:44 +00:00
|
|
|
|
} else {
|
|
|
|
|
logprintf(pCardData, 2, "session pin not supported");
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (*ppbSessionPin != NULL) {
|
2017-03-01 16:53:44 +00:00
|
|
|
|
pCardData->pfnCspFree(*ppbSessionPin);
|
|
|
|
|
*ppbSessionPin = NULL;
|
|
|
|
|
}
|
2017-06-16 12:51:41 +00:00
|
|
|
|
*pcbSessionPin = 0;
|
2017-03-01 16:53:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} 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-06-16 12:51:41 +00:00
|
|
|
|
if (dwFlags & CARD_AUTHENTICATE_GENERATE_SESSION_PIN
|
|
|
|
|
&& *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 */
|
2017-06-16 12:51:41 +00:00
|
|
|
|
*ppbSessionPin = pCardData->pfnCspAlloc(sizeof(MAGIC_SESSION_PIN));
|
|
|
|
|
if (*ppbSessionPin != NULL) {
|
|
|
|
|
memcpy(*ppbSessionPin, MAGIC_SESSION_PIN, sizeof(MAGIC_SESSION_PIN));
|
|
|
|
|
*pcbSessionPin = sizeof(MAGIC_SESSION_PIN);
|
2015-04-20 21:25:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
2015-04-18 17:09:45 +00:00
|
|
|
|
VENDOR_SPECIFIC *vs = NULL;
|
|
|
|
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
size_t target_len = cbTargetData;
|
2015-04-06 17:38:15 +00:00
|
|
|
|
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardChangeAuthenticatorEx");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
return dwret;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (dwAuthenticatingPinId >= MD_MAX_PINS || dwTargetPinId >= MD_MAX_PINS)
|
2015-04-06 17:38:15 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (!vs->pin_objs[dwAuthenticatingPinId] || !vs->pin_objs[dwTargetPinId])
|
2015-04-06 17:38:15 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +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
|
|
|
|
|
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
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
pin_obj = vs->pin_objs[dwTargetPinId];
|
2015-04-18 17:09:45 +00:00
|
|
|
|
|
|
|
|
|
if(pcAttemptsRemaining)
|
|
|
|
|
(*pcAttemptsRemaining) = (DWORD) -1;
|
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
/* FIXME: this does not enforce dwAuthenticatingPinId */
|
|
|
|
|
rv = md_dialog_perform_pin_operation(pCardData,
|
|
|
|
|
(dwFlags & PIN_CHANGE_FLAG_UNBLOCK ?
|
|
|
|
|
SC_PIN_CMD_UNBLOCK :
|
|
|
|
|
SC_PIN_CMD_CHANGE),
|
|
|
|
|
vs->p15card, pin_obj,
|
|
|
|
|
(const u8 *) pbAuthenticatingPinData,
|
|
|
|
|
cbAuthenticatingPinData,
|
|
|
|
|
pbTargetData, &target_len,
|
2017-10-16 13:16:34 +00:00
|
|
|
|
DisplayPinpadUI, dwTargetPinId);
|
2017-06-16 12:51:41 +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, "\nP:%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)
|
|
|
|
|
{
|
2017-06-17 17:33:37 +00:00
|
|
|
|
DWORD dwret;
|
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, "\nP:%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
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!pCardData)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
dwret = check_card_status(pCardData, "CardGetContainerProperty");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
return dwret;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
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;
|
|
|
|
|
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* the test for the existence of containers is redundant with the one made in CardGetContainerInfo but CCP_PIN_IDENTIFIER does not do it */
|
2015-04-12 12:06:36 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
2015-04-12 12:06: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);
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
if (cont->prkey_obj->auth_id.len == 0)
|
|
|
|
|
*p = ROLE_EVERYONE;
|
|
|
|
|
else {
|
|
|
|
|
size_t pinidx;
|
|
|
|
|
for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
|
|
|
|
|
struct sc_pkcs15_auth_info *pin_info;
|
|
|
|
|
|
|
|
|
|
if (!vs->pin_objs[pinidx])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
pin_info =
|
|
|
|
|
(struct sc_pkcs15_auth_info *)vs->pin_objs[pinidx]->data;
|
|
|
|
|
|
|
|
|
|
if (sc_pkcs15_compare_id(&cont->prkey_obj->auth_id,
|
|
|
|
|
&pin_info->auth_id))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pinidx >= MD_MAX_PINS) {
|
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"Could not find container %i PIN, returning no PIN needed, might not work properly\n",
|
|
|
|
|
bContainerIndex);
|
|
|
|
|
*p = ROLE_EVERYONE;
|
|
|
|
|
} else
|
|
|
|
|
*p = (PIN_ID)pinidx;
|
|
|
|
|
}
|
|
|
|
|
|
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, "\nP:%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, "\nP:%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
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
dwret = check_card_reader_status(pCardData, "CardGetProperty");
|
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
return dwret;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2011-02-09 17:52:00 +00:00
|
|
|
|
|
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-06-16 12:51:41 +00:00
|
|
|
|
if (dwFlags >= MD_MAX_PINS)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
if (!vs->pin_objs[dwFlags])
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
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) {
|
|
|
|
|
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-06-16 12:51:41 +00:00
|
|
|
|
logprintf(pCardData, 2,
|
|
|
|
|
"returning info on normal PIN [%lu]\n",
|
2017-03-14 21:56:39 +00:00
|
|
|
|
(unsigned long)dwFlags);
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
if (dwFlags == ROLE_USER)
|
|
|
|
|
p->PinPurpose = PrimaryCardPin;
|
|
|
|
|
else if (dwFlags == MD_ROLE_USER_SIGN)
|
|
|
|
|
p->PinPurpose = DigitalSignaturePin;
|
|
|
|
|
else
|
|
|
|
|
p->PinPurpose = AuthenticationPin;
|
|
|
|
|
|
|
|
|
|
p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
|
|
|
|
|
p->PinCachePolicy.dwPinCachePolicyInfo = 0;
|
|
|
|
|
p->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
|
|
|
|
|
p->dwChangePermission = CREATE_PIN_SET(dwFlags);
|
|
|
|
|
p->dwUnblockPermission = CREATE_PIN_SET(ROLE_ADMIN);
|
|
|
|
|
break;
|
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;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
size_t pinidx;
|
2012-05-31 14:40:36 +00:00
|
|
|
|
if (pdwDataLen)
|
|
|
|
|
*pdwDataLen = sizeof(*p);
|
|
|
|
|
if (cbData < sizeof(*p))
|
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
|
|
|
|
memset(p, 0, sizeof(*p));
|
|
|
|
|
for (pinidx = 0; pinidx < MD_MAX_PINS; pinidx++) {
|
|
|
|
|
if (!vs->pin_objs[pinidx])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
SET_PIN(*p, (PIN_ID)pinidx);
|
|
|
|
|
}
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
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
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
if (dwFlags >= MD_MAX_PINS)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
|
|
if (!vs->pin_objs[dwFlags])
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-16 12:51:41 +00:00
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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, "\nP:%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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
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, "\nP:%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, "\nP:%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, "\nP:%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, "\nP:%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, "\nP:%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, "\nP:%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, "\nP:%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, "\nP:%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, "\nP:%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;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
CRITICAL_SECTION hScard_lock;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
|
|
|
|
if (!pCardData)
|
2010-02-05 13:05:25 +00:00
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (dwFlags & ~CARD_SECURE_KEY_INJECTION_NO_CARD_MODE)
|
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) {
|
2018-04-14 17:38:34 +00:00
|
|
|
|
logprintf(pCardData, 0, "Invalid handle.\n");
|
2015-04-06 17:38:15 +00:00
|
|
|
|
return SCARD_E_INVALID_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
if( pCardData->hScard == 0) {
|
2018-04-14 17:38:34 +00:00
|
|
|
|
logprintf(pCardData, 0, "Invalid handle.\n");
|
2015-04-06 17:38:15 +00:00
|
|
|
|
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;
|
2018-04-14 17:38:34 +00:00
|
|
|
|
/* <2 length or >=0x22 are not ISO compliant */
|
2015-04-06 17:38:15 +00:00
|
|
|
|
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));
|
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
InitializeCriticalSection(&vs->hScard_lock);
|
|
|
|
|
lock(pCardData);
|
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
logprintf(pCardData, 1, "==================================================================\n");
|
2017-03-14 21:56:39 +00:00
|
|
|
|
logprintf(pCardData, 1, "\nP:%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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
goto ret_free;
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
goto ret_release;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
dwret = md_fs_init(pCardData);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (dwret != SCARD_S_SUCCESS)
|
|
|
|
|
goto ret_disassoc;
|
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
|
|
|
|
|
2017-11-21 12:20:02 +00:00
|
|
|
|
unlock(pCardData);
|
|
|
|
|
|
2011-02-09 17:52:00 +00:00
|
|
|
|
return SCARD_S_SUCCESS;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
|
|
|
|
|
ret_disassoc:
|
|
|
|
|
disassociate_card(pCardData);
|
|
|
|
|
|
|
|
|
|
ret_release:
|
|
|
|
|
sc_release_context(vs->ctx);
|
|
|
|
|
|
|
|
|
|
ret_free:
|
2017-11-21 12:20:02 +00:00
|
|
|
|
hScard_lock = vs->hScard_lock;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
pCardData->pfnCspFree(pCardData->pvVendorSpecific);
|
|
|
|
|
pCardData->pvVendorSpecific = NULL;
|
2017-11-21 12:20:02 +00:00
|
|
|
|
LeaveCriticalSection(&hScard_lock);
|
|
|
|
|
DeleteCriticalSection(&hScard_lock);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
return dwret;
|
2011-02-09 17:52:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static DWORD associate_card(PCARD_DATA pCardData)
|
2011-02-09 17:52:00 +00:00
|
|
|
|
{
|
2012-05-31 14:40:36 +00:00
|
|
|
|
VENDOR_SPECIFIC *vs;
|
2011-02-09 17:52:00 +00:00
|
|
|
|
int r;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
struct sc_app_info *app_generic;
|
|
|
|
|
struct sc_aid *aid;
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs)
|
|
|
|
|
return SCARD_E_INVALID_PARAMETER;
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
/* set the provided reader and card handles into ctx */
|
2017-06-17 17:33:37 +00:00
|
|
|
|
r = sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard);
|
|
|
|
|
if (r != SC_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 0, "sc_ctx_use_reader() failed with %d\n", r);
|
|
|
|
|
return SCARD_E_COMM_DATA_LOST;
|
|
|
|
|
}
|
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);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs->reader)
|
|
|
|
|
return SCARD_E_COMM_DATA_LOST;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
r = sc_connect_card(vs->reader, &(vs->card));
|
|
|
|
|
if (r != SC_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 0, "Cannot connect card in reader '%s'\n", NULLSTR(vs->reader->name));
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_UNKNOWN_CARD;
|
2011-02-09 17:52:00 +00:00
|
|
|
|
}
|
2017-06-17 17:33:37 +00:00
|
|
|
|
logprintf(pCardData, 3, "Connected card in '%s'\n", NULLSTR(vs->reader->name));
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +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;
|
|
|
|
|
|
|
|
|
|
r = sc_pkcs15_bind(vs->card, aid, &(vs->p15card));
|
|
|
|
|
logprintf(pCardData, 2, "PKCS#15 initialization result: %d, %s\n", r, sc_strerror(r));
|
|
|
|
|
if (r != SC_SUCCESS) {
|
|
|
|
|
logprintf(pCardData, 0, "PKCS#15 init failed.\n");
|
|
|
|
|
sc_disconnect_card(vs->card);
|
2012-05-31 14:40:36 +00:00
|
|
|
|
return SCARD_E_UNKNOWN_CARD;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
vs->initialized = TRUE;
|
2011-03-23 18:37:46 +00:00
|
|
|
|
|
2011-02-09 17:52:00 +00:00
|
|
|
|
return SCARD_S_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
static void disassociate_card(PCARD_DATA pCardData)
|
2011-02-09 17:52:00 +00:00
|
|
|
|
{
|
2012-05-31 14:40:36 +00:00
|
|
|
|
VENDOR_SPECIFIC *vs;
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!pCardData) {
|
|
|
|
|
logprintf(pCardData, 1,
|
|
|
|
|
"disassociate_card called without card data\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-09 17:52:00 +00:00
|
|
|
|
logprintf(pCardData, 1, "disassociate_card\n");
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2012-05-31 14:40:36 +00:00
|
|
|
|
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
|
2017-06-17 17:33:37 +00:00
|
|
|
|
if (!vs) {
|
|
|
|
|
logprintf(pCardData, 1,
|
|
|
|
|
"disassociate_card called without vendor specific data\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2011-04-12 07:40:12 +00:00
|
|
|
|
|
2017-06-16 12:51:41 +00:00
|
|
|
|
memset(vs->pin_objs, 0, sizeof(vs->pin_objs));
|
|
|
|
|
memset(vs->p15_containers, 0, sizeof(vs->p15_containers));
|
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;
|
2017-06-17 17:33:37 +00:00
|
|
|
|
vs->initialized = FALSE;
|
2010-02-05 13:05:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
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;
|
2017-06-13 11:35:32 +00:00
|
|
|
|
sc_notify_instance = hinstDLL;
|
|
|
|
|
sc_notify_init();
|
2012-05-31 14:40:36 +00:00
|
|
|
|
break;
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
2017-06-13 11:35:32 +00:00
|
|
|
|
sc_notify_close();
|
2018-11-05 10:16:04 +00:00
|
|
|
|
#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE)
|
|
|
|
|
CRYPTO_secure_malloc_done();
|
|
|
|
|
#endif
|
2012-05-31 14:40:36 +00:00
|
|
|
|
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
|