From 2ad673c6112b86f79520483fb1c9a9d771b1eb22 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Sun, 2 Feb 2014 00:17:38 +0100 Subject: [PATCH] engines/e_capi.c: TCHAR support (cumilative update from master). --- engines/e_capi.c | 138 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 30 deletions(-) diff --git a/engines/e_capi.c b/engines/e_capi.c index c1085b56cd..a3456a330c 100644 --- a/engines/e_capi.c +++ b/engines/e_capi.c @@ -54,22 +54,27 @@ #include #include +#include + #include -#include -#include #ifdef OPENSSL_SYS_WIN32 #ifndef OPENSSL_NO_CAPIENG +#include +#include #include -#include - #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif +#include #include +#include +#ifndef alloca +# define alloca _alloca +#endif /* * This module uses several "new" interfaces, among which is @@ -858,7 +863,7 @@ int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, /* Finally sign it */ slen = RSA_size(rsa); - if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) + if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) { CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); capi_addlasterror(); @@ -996,7 +1001,7 @@ static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, /* Finally sign it */ slen = sizeof(csigbuf); - if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) + if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) { CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); capi_addlasterror(); @@ -1068,7 +1073,7 @@ static void capi_adderror(DWORD err) ERR_add_error_data(2, "Error code= 0x", errstr); } -static char *wide_to_asc(LPWSTR wstr) +static char *wide_to_asc(LPCWSTR wstr) { char *str; int len_0,sz; @@ -1099,10 +1104,10 @@ static char *wide_to_asc(LPWSTR wstr) static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx) { - LPSTR name; DWORD len, err; + LPTSTR name; CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx); - if (!CryptEnumProvidersA(idx, NULL, 0, ptype, NULL, &len)) + if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len)) { err = GetLastError(); if (err == ERROR_NO_MORE_ITEMS) @@ -1111,8 +1116,11 @@ static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD id capi_adderror(err); return 0; } - name = OPENSSL_malloc(len); - if (!CryptEnumProvidersA(idx, NULL, 0, ptype, name, &len)) + if (sizeof(TCHAR) != sizeof(char)) + name = alloca(len); + else + name = OPENSSL_malloc(len); + if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) { err = GetLastError(); if (err == ERROR_NO_MORE_ITEMS) @@ -1121,8 +1129,11 @@ static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD id capi_adderror(err); return 0; } - *pname = name; - CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name, *ptype); + if (sizeof(TCHAR) != sizeof(char)) + *pname = wide_to_asc((WCHAR *)name); + else + *pname = (char *)name; + CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname, *ptype); return 1; } @@ -1153,8 +1164,26 @@ static int capi_list_containers(CAPI_CTX *ctx, BIO *out) HCRYPTPROV hprov; DWORD err, idx, flags, buflen = 0, clen; LPSTR cname; + LPTSTR cspname = NULL; + CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype); - if (!CryptAcquireContextA(&hprov, NULL, ctx->cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) + if (ctx->cspname && sizeof(TCHAR)!=sizeof(char)) + { + if ((clen=MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,NULL,0))) + { + cspname = alloca(clen*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,(WCHAR *)cspname,clen); + } + if (!cspname) + { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); + capi_addlasterror(); + return 0; + } + } + else + cspname = (TCHAR *)ctx->cspname; + if (!CryptAcquireContext(&hprov, NULL, cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) { CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); capi_addlasterror(); @@ -1186,7 +1215,7 @@ static int capi_list_containers(CAPI_CTX *ctx, BIO *out) flags = CRYPT_FIRST; else flags = 0; - if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, cname, &clen, flags)) + if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, (BYTE *)cname, &clen, flags)) { err = GetLastError(); if (err == ERROR_NO_MORE_ITEMS) @@ -1382,7 +1411,6 @@ int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id) { for(idx = 0;;idx++) { - LPWSTR fname = NULL; cert = CertEnumCertificatesInStore(hstore, cert); if (!cert) break; @@ -1429,16 +1457,28 @@ static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE h } } -static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec) +static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const TCHAR *contname, TCHAR *provname, DWORD ptype, DWORD keyspec) { CAPI_KEY *key; - DWORD dwFlags = 0; + DWORD dwFlags = 0; key = OPENSSL_malloc(sizeof(CAPI_KEY)); - CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", + if (sizeof(TCHAR)==sizeof(char)) + CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", contname, provname, ptype); - if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) - dwFlags = CRYPT_MACHINE_KEYSET; - if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, dwFlags)) + else if (ctx && ctx->debug_level>=CAPI_DBG_TRACE && ctx->debug_file) + { + /* above 'if' is optimization to minimize malloc-ations */ + char *_contname = wide_to_asc((WCHAR *)contname); + char *_provname = wide_to_asc((WCHAR *)provname); + + CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", + _contname, _provname, ptype); + if (_provname) OPENSSL_free(_provname); + if (_contname) OPENSSL_free(_contname); + } + if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) + dwFlags = CRYPT_MACHINE_KEYSET; + if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) { CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); capi_addlasterror(); @@ -1468,12 +1508,19 @@ static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert) pinfo = capi_get_prov_info(ctx, cert); if (!pinfo) goto err; - provname = wide_to_asc(pinfo->pwszProvName); - contname = wide_to_asc(pinfo->pwszContainerName); - if (!provname || !contname) - goto err; - key = capi_get_key(ctx, contname, provname, + if (sizeof(TCHAR) != sizeof(char)) + key = capi_get_key(ctx, (TCHAR *)pinfo->pwszContainerName, + (TCHAR *)pinfo->pwszProvName, pinfo->dwProvType, pinfo->dwKeySpec); + else + { + provname = wide_to_asc(pinfo->pwszProvName); + contname = wide_to_asc(pinfo->pwszContainerName); + if (!provname || !contname) + goto err; + key = capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, + pinfo->dwProvType, pinfo->dwKeySpec); + } err: if (pinfo) @@ -1507,8 +1554,25 @@ CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id) break; case CAPI_LU_CONTNAME: - key = capi_get_key(ctx, id, ctx->cspname, ctx->csptype, - ctx->keytype); + if (sizeof(TCHAR)!=sizeof(char)) + { + WCHAR *contname, *provname; + DWORD len; + + if ((len=MultiByteToWideChar(CP_ACP,0,id,-1,NULL,0)) && + (contname=alloca(len*sizeof(WCHAR)), + MultiByteToWideChar(CP_ACP,0,id,-1,contname,len)) && + (len=MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,NULL,0)) && + (provname=alloca(len*sizeof(WCHAR)), + MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,provname,len))) + key = capi_get_key(ctx,(TCHAR *)contname, + (TCHAR *)provname, + ctx->csptype,ctx->keytype); + } + else + key = capi_get_key(ctx, (TCHAR *)id, + (TCHAR *)ctx->cspname, + ctx->csptype,ctx->keytype); break; } @@ -1576,7 +1640,21 @@ static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int che if (check) { HCRYPTPROV hprov; - if (!CryptAcquireContextA(&hprov, NULL, pname, type, + LPTSTR name=NULL; + + if (sizeof(TCHAR)!=sizeof(char)) + { + DWORD len; + if ((len=MultiByteToWideChar(CP_ACP,0,pname,-1,NULL,0))) + { + name = alloca(len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP,0,pname,-1,(WCHAR *)name,len); + } + } + else + name = (TCHAR *)pname; + + if (!name || !CryptAcquireContext(&hprov, NULL, name, type, CRYPT_VERIFYCONTEXT)) { CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); -- 2.25.1