1db522d3aSSimon L. B. Nielsen /* engines/e_capi.c */ 26f9291ceSJung-uk Kim /* 36f9291ceSJung-uk Kim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4db522d3aSSimon L. B. Nielsen * project. 5db522d3aSSimon L. B. Nielsen */ 6db522d3aSSimon L. B. Nielsen /* ==================================================================== 7db522d3aSSimon L. B. Nielsen * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 8db522d3aSSimon L. B. Nielsen * 9db522d3aSSimon L. B. Nielsen * Redistribution and use in source and binary forms, with or without 10db522d3aSSimon L. B. Nielsen * modification, are permitted provided that the following conditions 11db522d3aSSimon L. B. Nielsen * are met: 12db522d3aSSimon L. B. Nielsen * 13db522d3aSSimon L. B. Nielsen * 1. Redistributions of source code must retain the above copyright 14db522d3aSSimon L. B. Nielsen * notice, this list of conditions and the following disclaimer. 15db522d3aSSimon L. B. Nielsen * 16db522d3aSSimon L. B. Nielsen * 2. Redistributions in binary form must reproduce the above copyright 17db522d3aSSimon L. B. Nielsen * notice, this list of conditions and the following disclaimer in 18db522d3aSSimon L. B. Nielsen * the documentation and/or other materials provided with the 19db522d3aSSimon L. B. Nielsen * distribution. 20db522d3aSSimon L. B. Nielsen * 21db522d3aSSimon L. B. Nielsen * 3. All advertising materials mentioning features or use of this 22db522d3aSSimon L. B. Nielsen * software must display the following acknowledgment: 23db522d3aSSimon L. B. Nielsen * "This product includes software developed by the OpenSSL Project 24db522d3aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25db522d3aSSimon L. B. Nielsen * 26db522d3aSSimon L. B. Nielsen * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27db522d3aSSimon L. B. Nielsen * endorse or promote products derived from this software without 28db522d3aSSimon L. B. Nielsen * prior written permission. For written permission, please contact 29db522d3aSSimon L. B. Nielsen * licensing@OpenSSL.org. 30db522d3aSSimon L. B. Nielsen * 31db522d3aSSimon L. B. Nielsen * 5. Products derived from this software may not be called "OpenSSL" 32db522d3aSSimon L. B. Nielsen * nor may "OpenSSL" appear in their names without prior written 33db522d3aSSimon L. B. Nielsen * permission of the OpenSSL Project. 34db522d3aSSimon L. B. Nielsen * 35db522d3aSSimon L. B. Nielsen * 6. Redistributions of any form whatsoever must retain the following 36db522d3aSSimon L. B. Nielsen * acknowledgment: 37db522d3aSSimon L. B. Nielsen * "This product includes software developed by the OpenSSL Project 38db522d3aSSimon L. B. Nielsen * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39db522d3aSSimon L. B. Nielsen * 40db522d3aSSimon L. B. Nielsen * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41db522d3aSSimon L. B. Nielsen * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42db522d3aSSimon L. B. Nielsen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43db522d3aSSimon L. B. Nielsen * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44db522d3aSSimon L. B. Nielsen * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45db522d3aSSimon L. B. Nielsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46db522d3aSSimon L. B. Nielsen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47db522d3aSSimon L. B. Nielsen * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48db522d3aSSimon L. B. Nielsen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49db522d3aSSimon L. B. Nielsen * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50db522d3aSSimon L. B. Nielsen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51db522d3aSSimon L. B. Nielsen * OF THE POSSIBILITY OF SUCH DAMAGE. 52db522d3aSSimon L. B. Nielsen * ==================================================================== 53db522d3aSSimon L. B. Nielsen */ 54db522d3aSSimon L. B. Nielsen 55db522d3aSSimon L. B. Nielsen #include <stdio.h> 56db522d3aSSimon L. B. Nielsen #include <string.h> 577bded2dbSJung-uk Kim #include <stdlib.h> 587bded2dbSJung-uk Kim 59db522d3aSSimon L. B. Nielsen #include <openssl/crypto.h> 60db522d3aSSimon L. B. Nielsen 61db522d3aSSimon L. B. Nielsen #ifdef OPENSSL_SYS_WIN32 62db522d3aSSimon L. B. Nielsen # ifndef OPENSSL_NO_CAPIENG 63db522d3aSSimon L. B. Nielsen 647bded2dbSJung-uk Kim # include <openssl/buffer.h> 657bded2dbSJung-uk Kim # include <openssl/bn.h> 666a599222SSimon L. B. Nielsen # include <openssl/rsa.h> 67db522d3aSSimon L. B. Nielsen 68db522d3aSSimon L. B. Nielsen # ifndef _WIN32_WINNT 69db522d3aSSimon L. B. Nielsen # define _WIN32_WINNT 0x0400 70db522d3aSSimon L. B. Nielsen # endif 71db522d3aSSimon L. B. Nielsen 727bded2dbSJung-uk Kim # include <windows.h> 73db522d3aSSimon L. B. Nielsen # include <wincrypt.h> 747bded2dbSJung-uk Kim # include <malloc.h> 757bded2dbSJung-uk Kim # ifndef alloca 767bded2dbSJung-uk Kim # define alloca _alloca 777bded2dbSJung-uk Kim # endif 78db522d3aSSimon L. B. Nielsen 791f13597dSJung-uk Kim /* 801f13597dSJung-uk Kim * This module uses several "new" interfaces, among which is 811f13597dSJung-uk Kim * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is 821f13597dSJung-uk Kim * one of possible values you can pass to function in question. By 831f13597dSJung-uk Kim * checking if it's defined we can see if wincrypt.h and accompanying 841f13597dSJung-uk Kim * crypt32.lib are in shape. The native MingW32 headers up to and 851f13597dSJung-uk Kim * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the 861f13597dSJung-uk Kim * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG, 871f13597dSJung-uk Kim * so we check for these too and avoid compiling. 881f13597dSJung-uk Kim * Yes, it's rather "weak" test and if compilation fails, 891f13597dSJung-uk Kim * then re-configure with -DOPENSSL_NO_CAPIENG. 901f13597dSJung-uk Kim */ 911f13597dSJung-uk Kim # if defined(CERT_KEY_PROV_INFO_PROP_ID) && \ 921f13597dSJung-uk Kim defined(CERT_STORE_PROV_SYSTEM_A) && \ 931f13597dSJung-uk Kim defined(CERT_STORE_READONLY_FLAG) 941f13597dSJung-uk Kim # define __COMPILE_CAPIENG 951f13597dSJung-uk Kim # endif /* CERT_KEY_PROV_INFO_PROP_ID */ 961f13597dSJung-uk Kim # endif /* OPENSSL_NO_CAPIENG */ 971f13597dSJung-uk Kim #endif /* OPENSSL_SYS_WIN32 */ 981f13597dSJung-uk Kim 991f13597dSJung-uk Kim #ifdef __COMPILE_CAPIENG 1001f13597dSJung-uk Kim 101db522d3aSSimon L. B. Nielsen # undef X509_EXTENSIONS 102db522d3aSSimon L. B. Nielsen # undef X509_CERT_PAIR 103db522d3aSSimon L. B. Nielsen 104db522d3aSSimon L. B. Nielsen /* Definitions which may be missing from earlier version of headers */ 105db522d3aSSimon L. B. Nielsen # ifndef CERT_STORE_OPEN_EXISTING_FLAG 106db522d3aSSimon L. B. Nielsen # define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 107db522d3aSSimon L. B. Nielsen # endif 108db522d3aSSimon L. B. Nielsen 109db522d3aSSimon L. B. Nielsen # ifndef CERT_STORE_CREATE_NEW_FLAG 110db522d3aSSimon L. B. Nielsen # define CERT_STORE_CREATE_NEW_FLAG 0x00002000 111db522d3aSSimon L. B. Nielsen # endif 112db522d3aSSimon L. B. Nielsen 113ab8565e2SSimon L. B. Nielsen # ifndef CERT_SYSTEM_STORE_CURRENT_USER 114ab8565e2SSimon L. B. Nielsen # define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000 115ab8565e2SSimon L. B. Nielsen # endif 116ab8565e2SSimon L. B. Nielsen 117*4c6a0400SJung-uk Kim # ifndef ALG_SID_SHA_256 118*4c6a0400SJung-uk Kim # define ALG_SID_SHA_256 12 119*4c6a0400SJung-uk Kim # endif 120*4c6a0400SJung-uk Kim # ifndef ALG_SID_SHA_384 121*4c6a0400SJung-uk Kim # define ALG_SID_SHA_384 13 122*4c6a0400SJung-uk Kim # endif 123*4c6a0400SJung-uk Kim # ifndef ALG_SID_SHA_512 124*4c6a0400SJung-uk Kim # define ALG_SID_SHA_512 14 125*4c6a0400SJung-uk Kim # endif 126*4c6a0400SJung-uk Kim 127*4c6a0400SJung-uk Kim # ifndef CALG_SHA_256 128*4c6a0400SJung-uk Kim # define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256) 129*4c6a0400SJung-uk Kim # endif 130*4c6a0400SJung-uk Kim # ifndef CALG_SHA_384 131*4c6a0400SJung-uk Kim # define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384) 132*4c6a0400SJung-uk Kim # endif 133*4c6a0400SJung-uk Kim # ifndef CALG_SHA_512 134*4c6a0400SJung-uk Kim # define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512) 135*4c6a0400SJung-uk Kim # endif 136*4c6a0400SJung-uk Kim 137db522d3aSSimon L. B. Nielsen # include <openssl/engine.h> 138db522d3aSSimon L. B. Nielsen # include <openssl/pem.h> 139db522d3aSSimon L. B. Nielsen # include <openssl/x509v3.h> 140db522d3aSSimon L. B. Nielsen 141db522d3aSSimon L. B. Nielsen # include "e_capi_err.h" 142db522d3aSSimon L. B. Nielsen # include "e_capi_err.c" 143db522d3aSSimon L. B. Nielsen 144db522d3aSSimon L. B. Nielsen static const char *engine_capi_id = "capi"; 145db522d3aSSimon L. B. Nielsen static const char *engine_capi_name = "CryptoAPI ENGINE"; 146db522d3aSSimon L. B. Nielsen 147db522d3aSSimon L. B. Nielsen typedef struct CAPI_CTX_st CAPI_CTX; 148db522d3aSSimon L. B. Nielsen typedef struct CAPI_KEY_st CAPI_KEY; 149db522d3aSSimon L. B. Nielsen 150db522d3aSSimon L. B. Nielsen static void capi_addlasterror(void); 151db522d3aSSimon L. B. Nielsen static void capi_adderror(DWORD err); 152db522d3aSSimon L. B. Nielsen 153db522d3aSSimon L. B. Nielsen static void CAPI_trace(CAPI_CTX * ctx, char *format, ...); 154db522d3aSSimon L. B. Nielsen 155db522d3aSSimon L. B. Nielsen static int capi_list_providers(CAPI_CTX * ctx, BIO *out); 156db522d3aSSimon L. B. Nielsen static int capi_list_containers(CAPI_CTX * ctx, BIO *out); 157db522d3aSSimon L. B. Nielsen int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *storename); 158db522d3aSSimon L. B. Nielsen void capi_free_key(CAPI_KEY * key); 159db522d3aSSimon L. B. Nielsen 1606f9291ceSJung-uk Kim static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id, 1616f9291ceSJung-uk Kim HCERTSTORE hstore); 162db522d3aSSimon L. B. Nielsen 163db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id); 164db522d3aSSimon L. B. Nielsen 165db522d3aSSimon L. B. Nielsen static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, 166db522d3aSSimon L. B. Nielsen UI_METHOD *ui_method, void *callback_data); 1676f9291ceSJung-uk Kim static int capi_rsa_sign(int dtype, const unsigned char *m, 1686f9291ceSJung-uk Kim unsigned int m_len, unsigned char *sigret, 1696f9291ceSJung-uk Kim unsigned int *siglen, const RSA *rsa); 170db522d3aSSimon L. B. Nielsen static int capi_rsa_priv_enc(int flen, const unsigned char *from, 171db522d3aSSimon L. B. Nielsen unsigned char *to, RSA *rsa, int padding); 172db522d3aSSimon L. B. Nielsen static int capi_rsa_priv_dec(int flen, const unsigned char *from, 173db522d3aSSimon L. B. Nielsen unsigned char *to, RSA *rsa, int padding); 174db522d3aSSimon L. B. Nielsen static int capi_rsa_free(RSA *rsa); 175db522d3aSSimon L. B. Nielsen 176db522d3aSSimon L. B. Nielsen static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, 177db522d3aSSimon L. B. Nielsen DSA *dsa); 178db522d3aSSimon L. B. Nielsen static int capi_dsa_free(DSA *dsa); 179db522d3aSSimon L. B. Nielsen 180db522d3aSSimon L. B. Nielsen static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, 1816f9291ceSJung-uk Kim STACK_OF(X509_NAME) *ca_dn, X509 **pcert, 1826f9291ceSJung-uk Kim EVP_PKEY **pkey, STACK_OF(X509) **pother, 1836f9291ceSJung-uk Kim UI_METHOD *ui_method, 1846f9291ceSJung-uk Kim void *callback_data); 185db522d3aSSimon L. B. Nielsen 186db522d3aSSimon L. B. Nielsen static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); 187db522d3aSSimon L. B. Nielsen # ifdef OPENSSL_CAPIENG_DIALOG 188db522d3aSSimon L. B. Nielsen static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); 189db522d3aSSimon L. B. Nielsen # endif 190db522d3aSSimon L. B. Nielsen 191db522d3aSSimon L. B. Nielsen typedef PCCERT_CONTEXT(WINAPI *CERTDLG) (HCERTSTORE, HWND, LPCWSTR, 1926f9291ceSJung-uk Kim LPCWSTR, DWORD, DWORD, void *); 193db522d3aSSimon L. B. Nielsen typedef HWND(WINAPI *GETCONSWIN) (void); 194db522d3aSSimon L. B. Nielsen 1956f9291ceSJung-uk Kim /* 1966f9291ceSJung-uk Kim * This structure contains CAPI ENGINE specific data: it contains various 1976f9291ceSJung-uk Kim * global options and affects how other functions behave. 198db522d3aSSimon L. B. Nielsen */ 199db522d3aSSimon L. B. Nielsen 200db522d3aSSimon L. B. Nielsen # define CAPI_DBG_TRACE 2 201db522d3aSSimon L. B. Nielsen # define CAPI_DBG_ERROR 1 202db522d3aSSimon L. B. Nielsen 203db522d3aSSimon L. B. Nielsen struct CAPI_CTX_st { 204db522d3aSSimon L. B. Nielsen int debug_level; 205db522d3aSSimon L. B. Nielsen char *debug_file; 206db522d3aSSimon L. B. Nielsen /* Parameters to use for container lookup */ 207db522d3aSSimon L. B. Nielsen DWORD keytype; 2086a599222SSimon L. B. Nielsen LPSTR cspname; 209db522d3aSSimon L. B. Nielsen DWORD csptype; 210db522d3aSSimon L. B. Nielsen /* Certificate store name to use */ 2116a599222SSimon L. B. Nielsen LPSTR storename; 2126a599222SSimon L. B. Nielsen LPSTR ssl_client_store; 213db522d3aSSimon L. B. Nielsen /* System store flags */ 214db522d3aSSimon L. B. Nielsen DWORD store_flags; 215db522d3aSSimon L. B. Nielsen /* Lookup string meanings in load_private_key */ 216db522d3aSSimon L. B. Nielsen /* Substring of subject: uses "storename" */ 2176a599222SSimon L. B. Nielsen # define CAPI_LU_SUBSTR 1 218db522d3aSSimon L. B. Nielsen /* Friendly name: uses storename */ 2196a599222SSimon L. B. Nielsen # define CAPI_LU_FNAME 2 220db522d3aSSimon L. B. Nielsen /* Container name: uses cspname, keytype */ 2216a599222SSimon L. B. Nielsen # define CAPI_LU_CONTNAME 3 222db522d3aSSimon L. B. Nielsen int lookup_method; 223db522d3aSSimon L. B. Nielsen /* Info to dump with dumpcerts option */ 224db522d3aSSimon L. B. Nielsen /* Issuer and serial name strings */ 225db522d3aSSimon L. B. Nielsen # define CAPI_DMP_SUMMARY 0x1 226db522d3aSSimon L. B. Nielsen /* Friendly name */ 227db522d3aSSimon L. B. Nielsen # define CAPI_DMP_FNAME 0x2 228db522d3aSSimon L. B. Nielsen /* Full X509_print dump */ 229db522d3aSSimon L. B. Nielsen # define CAPI_DMP_FULL 0x4 230db522d3aSSimon L. B. Nielsen /* Dump PEM format certificate */ 231db522d3aSSimon L. B. Nielsen # define CAPI_DMP_PEM 0x8 232db522d3aSSimon L. B. Nielsen /* Dump pseudo key (if possible) */ 233db522d3aSSimon L. B. Nielsen # define CAPI_DMP_PSKEY 0x10 234db522d3aSSimon L. B. Nielsen /* Dump key info (if possible) */ 235db522d3aSSimon L. B. Nielsen # define CAPI_DMP_PKEYINFO 0x20 236db522d3aSSimon L. B. Nielsen DWORD dump_flags; 237db522d3aSSimon L. B. Nielsen int (*client_cert_select) (ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); 238db522d3aSSimon L. B. Nielsen CERTDLG certselectdlg; 239db522d3aSSimon L. B. Nielsen GETCONSWIN getconswindow; 240db522d3aSSimon L. B. Nielsen }; 241db522d3aSSimon L. B. Nielsen 242db522d3aSSimon L. B. Nielsen static CAPI_CTX *capi_ctx_new(); 243db522d3aSSimon L. B. Nielsen static void capi_ctx_free(CAPI_CTX * ctx); 2446f9291ceSJung-uk Kim static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type, 2456f9291ceSJung-uk Kim int check); 246db522d3aSSimon L. B. Nielsen static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx); 247db522d3aSSimon L. B. Nielsen 248db522d3aSSimon L. B. Nielsen # define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE 249db522d3aSSimon L. B. Nielsen # define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1) 250db522d3aSSimon L. B. Nielsen # define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2) 251db522d3aSSimon L. B. Nielsen # define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3) 252db522d3aSSimon L. B. Nielsen # define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4) 253db522d3aSSimon L. B. Nielsen # define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5) 254db522d3aSSimon L. B. Nielsen # define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6) 255db522d3aSSimon L. B. Nielsen # define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7) 256db522d3aSSimon L. B. Nielsen # define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8) 257db522d3aSSimon L. B. Nielsen # define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9) 258db522d3aSSimon L. B. Nielsen # define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10) 259db522d3aSSimon L. B. Nielsen # define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11) 260db522d3aSSimon L. B. Nielsen # define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12) 261db522d3aSSimon L. B. Nielsen # define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13) 262db522d3aSSimon L. B. Nielsen 263db522d3aSSimon L. B. Nielsen static const ENGINE_CMD_DEFN capi_cmd_defns[] = { 264db522d3aSSimon L. B. Nielsen {CAPI_CMD_LIST_CERTS, 265db522d3aSSimon L. B. Nielsen "list_certs", 266db522d3aSSimon L. B. Nielsen "List all certificates in store", 267db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NO_INPUT}, 268db522d3aSSimon L. B. Nielsen {CAPI_CMD_LOOKUP_CERT, 269db522d3aSSimon L. B. Nielsen "lookup_cert", 270db522d3aSSimon L. B. Nielsen "Lookup and output certificates", 271db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_STRING}, 272db522d3aSSimon L. B. Nielsen {CAPI_CMD_DEBUG_LEVEL, 273db522d3aSSimon L. B. Nielsen "debug_level", 274db522d3aSSimon L. B. Nielsen "debug level (1=errors, 2=trace)", 275db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 276db522d3aSSimon L. B. Nielsen {CAPI_CMD_DEBUG_FILE, 277db522d3aSSimon L. B. Nielsen "debug_file", 278db522d3aSSimon L. B. Nielsen "debugging filename)", 279db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_STRING}, 280db522d3aSSimon L. B. Nielsen {CAPI_CMD_KEYTYPE, 281db522d3aSSimon L. B. Nielsen "key_type", 282db522d3aSSimon L. B. Nielsen "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE", 283db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 284db522d3aSSimon L. B. Nielsen {CAPI_CMD_LIST_CSPS, 285db522d3aSSimon L. B. Nielsen "list_csps", 286db522d3aSSimon L. B. Nielsen "List all CSPs", 287db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NO_INPUT}, 288db522d3aSSimon L. B. Nielsen {CAPI_CMD_SET_CSP_IDX, 289db522d3aSSimon L. B. Nielsen "csp_idx", 290db522d3aSSimon L. B. Nielsen "Set CSP by index", 291db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 292db522d3aSSimon L. B. Nielsen {CAPI_CMD_SET_CSP_NAME, 293db522d3aSSimon L. B. Nielsen "csp_name", 294db522d3aSSimon L. B. Nielsen "Set CSP name, (default CSP used if not specified)", 295db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_STRING}, 296db522d3aSSimon L. B. Nielsen {CAPI_CMD_SET_CSP_TYPE, 297db522d3aSSimon L. B. Nielsen "csp_type", 298db522d3aSSimon L. B. Nielsen "Set CSP type, (default RSA_PROV_FULL)", 299db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 300db522d3aSSimon L. B. Nielsen {CAPI_CMD_LIST_CONTAINERS, 301db522d3aSSimon L. B. Nielsen "list_containers", 302db522d3aSSimon L. B. Nielsen "list container names", 303db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NO_INPUT}, 304db522d3aSSimon L. B. Nielsen {CAPI_CMD_LIST_OPTIONS, 305db522d3aSSimon L. B. Nielsen "list_options", 306db522d3aSSimon L. B. Nielsen "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, " 307db522d3aSSimon L. B. Nielsen "32=private key info)", 308db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 309db522d3aSSimon L. B. Nielsen {CAPI_CMD_LOOKUP_METHOD, 310db522d3aSSimon L. B. Nielsen "lookup_method", 311db522d3aSSimon L. B. Nielsen "Set key lookup method (1=substring, 2=friendlyname, 3=container name)", 312db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 313db522d3aSSimon L. B. Nielsen {CAPI_CMD_STORE_NAME, 314db522d3aSSimon L. B. Nielsen "store_name", 315db522d3aSSimon L. B. Nielsen "certificate store name, default \"MY\"", 316db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_STRING}, 317db522d3aSSimon L. B. Nielsen {CAPI_CMD_STORE_FLAGS, 318db522d3aSSimon L. B. Nielsen "store_flags", 319db522d3aSSimon L. B. Nielsen "Certificate store flags: 1 = system store", 320db522d3aSSimon L. B. Nielsen ENGINE_CMD_FLAG_NUMERIC}, 321db522d3aSSimon L. B. Nielsen 322db522d3aSSimon L. B. Nielsen {0, NULL, NULL, 0} 323db522d3aSSimon L. B. Nielsen }; 324db522d3aSSimon L. B. Nielsen 325db522d3aSSimon L. B. Nielsen static int capi_idx = -1; 326db522d3aSSimon L. B. Nielsen static int rsa_capi_idx = -1; 327db522d3aSSimon L. B. Nielsen static int dsa_capi_idx = -1; 328db522d3aSSimon L. B. Nielsen static int cert_capi_idx = -1; 329db522d3aSSimon L. B. Nielsen 330db522d3aSSimon L. B. Nielsen static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 331db522d3aSSimon L. B. Nielsen { 332db522d3aSSimon L. B. Nielsen int ret = 1; 333db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 334db522d3aSSimon L. B. Nielsen BIO *out; 3356f9291ceSJung-uk Kim if (capi_idx == -1) { 336db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED); 337db522d3aSSimon L. B. Nielsen return 0; 338db522d3aSSimon L. B. Nielsen } 339db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(e, capi_idx); 340db522d3aSSimon L. B. Nielsen out = BIO_new_fp(stdout, BIO_NOCLOSE); 3416f9291ceSJung-uk Kim switch (cmd) { 342db522d3aSSimon L. B. Nielsen case CAPI_CMD_LIST_CSPS: 343db522d3aSSimon L. B. Nielsen ret = capi_list_providers(ctx, out); 344db522d3aSSimon L. B. Nielsen break; 345db522d3aSSimon L. B. Nielsen 346db522d3aSSimon L. B. Nielsen case CAPI_CMD_LIST_CERTS: 347db522d3aSSimon L. B. Nielsen ret = capi_list_certs(ctx, out, NULL); 348db522d3aSSimon L. B. Nielsen break; 349db522d3aSSimon L. B. Nielsen 350db522d3aSSimon L. B. Nielsen case CAPI_CMD_LOOKUP_CERT: 351db522d3aSSimon L. B. Nielsen ret = capi_list_certs(ctx, out, p); 352db522d3aSSimon L. B. Nielsen break; 353db522d3aSSimon L. B. Nielsen 354db522d3aSSimon L. B. Nielsen case CAPI_CMD_LIST_CONTAINERS: 355db522d3aSSimon L. B. Nielsen ret = capi_list_containers(ctx, out); 356db522d3aSSimon L. B. Nielsen break; 357db522d3aSSimon L. B. Nielsen 358db522d3aSSimon L. B. Nielsen case CAPI_CMD_STORE_NAME: 359db522d3aSSimon L. B. Nielsen if (ctx->storename) 360db522d3aSSimon L. B. Nielsen OPENSSL_free(ctx->storename); 361db522d3aSSimon L. B. Nielsen ctx->storename = BUF_strdup(p); 362db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Setting store name to %s\n", p); 363db522d3aSSimon L. B. Nielsen break; 364db522d3aSSimon L. B. Nielsen 365db522d3aSSimon L. B. Nielsen case CAPI_CMD_STORE_FLAGS: 3666f9291ceSJung-uk Kim if (i & 1) { 367db522d3aSSimon L. B. Nielsen ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; 368db522d3aSSimon L. B. Nielsen ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER; 3696f9291ceSJung-uk Kim } else { 370db522d3aSSimon L. B. Nielsen ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER; 371db522d3aSSimon L. B. Nielsen ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE; 372db522d3aSSimon L. B. Nielsen } 373db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Setting flags to %d\n", i); 374db522d3aSSimon L. B. Nielsen break; 375db522d3aSSimon L. B. Nielsen 376db522d3aSSimon L. B. Nielsen case CAPI_CMD_DEBUG_LEVEL: 377db522d3aSSimon L. B. Nielsen ctx->debug_level = (int)i; 378db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level); 379db522d3aSSimon L. B. Nielsen break; 380db522d3aSSimon L. B. Nielsen 381db522d3aSSimon L. B. Nielsen case CAPI_CMD_DEBUG_FILE: 382db522d3aSSimon L. B. Nielsen ctx->debug_file = BUF_strdup(p); 383db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file); 384db522d3aSSimon L. B. Nielsen break; 385db522d3aSSimon L. B. Nielsen 386db522d3aSSimon L. B. Nielsen case CAPI_CMD_KEYTYPE: 387db522d3aSSimon L. B. Nielsen ctx->keytype = i; 388db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype); 389db522d3aSSimon L. B. Nielsen break; 390db522d3aSSimon L. B. Nielsen 391db522d3aSSimon L. B. Nielsen case CAPI_CMD_SET_CSP_IDX: 392db522d3aSSimon L. B. Nielsen ret = capi_ctx_set_provname_idx(ctx, i); 393db522d3aSSimon L. B. Nielsen break; 394db522d3aSSimon L. B. Nielsen 395db522d3aSSimon L. B. Nielsen case CAPI_CMD_LIST_OPTIONS: 396db522d3aSSimon L. B. Nielsen ctx->dump_flags = i; 397db522d3aSSimon L. B. Nielsen break; 398db522d3aSSimon L. B. Nielsen 399db522d3aSSimon L. B. Nielsen case CAPI_CMD_LOOKUP_METHOD: 4006f9291ceSJung-uk Kim if (i < 1 || i > 3) { 401db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD); 402db522d3aSSimon L. B. Nielsen return 0; 403db522d3aSSimon L. B. Nielsen } 404db522d3aSSimon L. B. Nielsen ctx->lookup_method = i; 405db522d3aSSimon L. B. Nielsen break; 406db522d3aSSimon L. B. Nielsen 407db522d3aSSimon L. B. Nielsen case CAPI_CMD_SET_CSP_NAME: 408db522d3aSSimon L. B. Nielsen ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1); 409db522d3aSSimon L. B. Nielsen break; 410db522d3aSSimon L. B. Nielsen 411db522d3aSSimon L. B. Nielsen case CAPI_CMD_SET_CSP_TYPE: 412db522d3aSSimon L. B. Nielsen ctx->csptype = i; 413db522d3aSSimon L. B. Nielsen break; 414db522d3aSSimon L. B. Nielsen 415db522d3aSSimon L. B. Nielsen default: 416db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND); 417db522d3aSSimon L. B. Nielsen ret = 0; 418db522d3aSSimon L. B. Nielsen } 419db522d3aSSimon L. B. Nielsen 420db522d3aSSimon L. B. Nielsen BIO_free(out); 421db522d3aSSimon L. B. Nielsen return ret; 422db522d3aSSimon L. B. Nielsen 423db522d3aSSimon L. B. Nielsen } 424db522d3aSSimon L. B. Nielsen 4256f9291ceSJung-uk Kim static RSA_METHOD capi_rsa_method = { 426db522d3aSSimon L. B. Nielsen "CryptoAPI RSA method", 427db522d3aSSimon L. B. Nielsen 0, /* pub_enc */ 428db522d3aSSimon L. B. Nielsen 0, /* pub_dec */ 429db522d3aSSimon L. B. Nielsen capi_rsa_priv_enc, /* priv_enc */ 430db522d3aSSimon L. B. Nielsen capi_rsa_priv_dec, /* priv_dec */ 431db522d3aSSimon L. B. Nielsen 0, /* rsa_mod_exp */ 432db522d3aSSimon L. B. Nielsen 0, /* bn_mod_exp */ 433db522d3aSSimon L. B. Nielsen 0, /* init */ 434db522d3aSSimon L. B. Nielsen capi_rsa_free, /* finish */ 435db522d3aSSimon L. B. Nielsen RSA_FLAG_SIGN_VER, /* flags */ 436db522d3aSSimon L. B. Nielsen NULL, /* app_data */ 437db522d3aSSimon L. B. Nielsen capi_rsa_sign, /* rsa_sign */ 438db522d3aSSimon L. B. Nielsen 0 /* rsa_verify */ 439db522d3aSSimon L. B. Nielsen }; 440db522d3aSSimon L. B. Nielsen 4416f9291ceSJung-uk Kim static DSA_METHOD capi_dsa_method = { 442db522d3aSSimon L. B. Nielsen "CryptoAPI DSA method", 443db522d3aSSimon L. B. Nielsen capi_dsa_do_sign, /* dsa_do_sign */ 444db522d3aSSimon L. B. Nielsen 0, /* dsa_sign_setup */ 445db522d3aSSimon L. B. Nielsen 0, /* dsa_do_verify */ 446db522d3aSSimon L. B. Nielsen 0, /* dsa_mod_exp */ 447db522d3aSSimon L. B. Nielsen 0, /* bn_mod_exp */ 448db522d3aSSimon L. B. Nielsen 0, /* init */ 449db522d3aSSimon L. B. Nielsen capi_dsa_free, /* finish */ 450db522d3aSSimon L. B. Nielsen 0, /* flags */ 451db522d3aSSimon L. B. Nielsen NULL, /* app_data */ 452db522d3aSSimon L. B. Nielsen 0, /* dsa_paramgen */ 453db522d3aSSimon L. B. Nielsen 0 /* dsa_keygen */ 454db522d3aSSimon L. B. Nielsen }; 455db522d3aSSimon L. B. Nielsen 456db522d3aSSimon L. B. Nielsen static int capi_init(ENGINE *e) 457db522d3aSSimon L. B. Nielsen { 458db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 459db522d3aSSimon L. B. Nielsen const RSA_METHOD *ossl_rsa_meth; 460db522d3aSSimon L. B. Nielsen const DSA_METHOD *ossl_dsa_meth; 461db522d3aSSimon L. B. Nielsen 4626f9291ceSJung-uk Kim if (capi_idx < 0) { 46312de4ed2SJung-uk Kim capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); 46412de4ed2SJung-uk Kim if (capi_idx < 0) 465db522d3aSSimon L. B. Nielsen goto memerr; 466db522d3aSSimon L. B. Nielsen 46712de4ed2SJung-uk Kim cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); 46812de4ed2SJung-uk Kim 469db522d3aSSimon L. B. Nielsen /* Setup RSA_METHOD */ 470db522d3aSSimon L. B. Nielsen rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); 471db522d3aSSimon L. B. Nielsen ossl_rsa_meth = RSA_PKCS1_SSLeay(); 472db522d3aSSimon L. B. Nielsen capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc; 473db522d3aSSimon L. B. Nielsen capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec; 474db522d3aSSimon L. B. Nielsen capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp; 475db522d3aSSimon L. B. Nielsen capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp; 476db522d3aSSimon L. B. Nielsen 477db522d3aSSimon L. B. Nielsen /* Setup DSA Method */ 478db522d3aSSimon L. B. Nielsen dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); 479db522d3aSSimon L. B. Nielsen ossl_dsa_meth = DSA_OpenSSL(); 480db522d3aSSimon L. B. Nielsen capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify; 481db522d3aSSimon L. B. Nielsen capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp; 482db522d3aSSimon L. B. Nielsen capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp; 48312de4ed2SJung-uk Kim } 48412de4ed2SJung-uk Kim 48512de4ed2SJung-uk Kim ctx = capi_ctx_new(); 48612de4ed2SJung-uk Kim if (!ctx) 48712de4ed2SJung-uk Kim goto memerr; 48812de4ed2SJung-uk Kim 48912de4ed2SJung-uk Kim ENGINE_set_ex_data(e, capi_idx, ctx); 490db522d3aSSimon L. B. Nielsen 491db522d3aSSimon L. B. Nielsen # ifdef OPENSSL_CAPIENG_DIALOG 492db522d3aSSimon L. B. Nielsen { 493db522d3aSSimon L. B. Nielsen HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL")); 4946a599222SSimon L. B. Nielsen HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL")); 495db522d3aSSimon L. B. Nielsen if (cryptui) 4966f9291ceSJung-uk Kim ctx->certselectdlg = 4976f9291ceSJung-uk Kim (CERTDLG) GetProcAddress(cryptui, 4986f9291ceSJung-uk Kim "CryptUIDlgSelectCertificateFromStore"); 499db522d3aSSimon L. B. Nielsen if (kernel) 5006f9291ceSJung-uk Kim ctx->getconswindow = 5016f9291ceSJung-uk Kim (GETCONSWIN) GetProcAddress(kernel, "GetConsoleWindow"); 502db522d3aSSimon L. B. Nielsen if (cryptui && !OPENSSL_isservice()) 503db522d3aSSimon L. B. Nielsen ctx->client_cert_select = cert_select_dialog; 504db522d3aSSimon L. B. Nielsen } 505db522d3aSSimon L. B. Nielsen # endif 506db522d3aSSimon L. B. Nielsen 507db522d3aSSimon L. B. Nielsen return 1; 508db522d3aSSimon L. B. Nielsen 509db522d3aSSimon L. B. Nielsen memerr: 510db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE); 511db522d3aSSimon L. B. Nielsen return 0; 512db522d3aSSimon L. B. Nielsen 513db522d3aSSimon L. B. Nielsen return 1; 514db522d3aSSimon L. B. Nielsen } 515db522d3aSSimon L. B. Nielsen 516db522d3aSSimon L. B. Nielsen static int capi_destroy(ENGINE *e) 517db522d3aSSimon L. B. Nielsen { 518db522d3aSSimon L. B. Nielsen ERR_unload_CAPI_strings(); 519db522d3aSSimon L. B. Nielsen return 1; 520db522d3aSSimon L. B. Nielsen } 521db522d3aSSimon L. B. Nielsen 522db522d3aSSimon L. B. Nielsen static int capi_finish(ENGINE *e) 523db522d3aSSimon L. B. Nielsen { 524db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 525db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(e, capi_idx); 526db522d3aSSimon L. B. Nielsen capi_ctx_free(ctx); 527db522d3aSSimon L. B. Nielsen ENGINE_set_ex_data(e, capi_idx, NULL); 528db522d3aSSimon L. B. Nielsen return 1; 529db522d3aSSimon L. B. Nielsen } 530db522d3aSSimon L. B. Nielsen 5316f9291ceSJung-uk Kim /* 5326f9291ceSJung-uk Kim * CryptoAPI key application data. This contains a handle to the private key 5336f9291ceSJung-uk Kim * container (for sign operations) and a handle to the key (for decrypt 5346f9291ceSJung-uk Kim * operations). 535db522d3aSSimon L. B. Nielsen */ 536db522d3aSSimon L. B. Nielsen 5376f9291ceSJung-uk Kim struct CAPI_KEY_st { 538db522d3aSSimon L. B. Nielsen /* Associated certificate context (if any) */ 539db522d3aSSimon L. B. Nielsen PCCERT_CONTEXT pcert; 540db522d3aSSimon L. B. Nielsen HCRYPTPROV hprov; 541db522d3aSSimon L. B. Nielsen HCRYPTKEY key; 542db522d3aSSimon L. B. Nielsen DWORD keyspec; 543db522d3aSSimon L. B. Nielsen }; 544db522d3aSSimon L. B. Nielsen 545db522d3aSSimon L. B. Nielsen static int bind_capi(ENGINE *e) 546db522d3aSSimon L. B. Nielsen { 547db522d3aSSimon L. B. Nielsen if (!ENGINE_set_id(e, engine_capi_id) 548db522d3aSSimon L. B. Nielsen || !ENGINE_set_name(e, engine_capi_name) 5491f13597dSJung-uk Kim || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) 550db522d3aSSimon L. B. Nielsen || !ENGINE_set_init_function(e, capi_init) 551db522d3aSSimon L. B. Nielsen || !ENGINE_set_finish_function(e, capi_finish) 552db522d3aSSimon L. B. Nielsen || !ENGINE_set_destroy_function(e, capi_destroy) 553db522d3aSSimon L. B. Nielsen || !ENGINE_set_RSA(e, &capi_rsa_method) 554db522d3aSSimon L. B. Nielsen || !ENGINE_set_DSA(e, &capi_dsa_method) 555db522d3aSSimon L. B. Nielsen || !ENGINE_set_load_privkey_function(e, capi_load_privkey) 556db522d3aSSimon L. B. Nielsen || !ENGINE_set_load_ssl_client_cert_function(e, 557db522d3aSSimon L. B. Nielsen capi_load_ssl_client_cert) 558db522d3aSSimon L. B. Nielsen || !ENGINE_set_cmd_defns(e, capi_cmd_defns) 559db522d3aSSimon L. B. Nielsen || !ENGINE_set_ctrl_function(e, capi_ctrl)) 560db522d3aSSimon L. B. Nielsen return 0; 561db522d3aSSimon L. B. Nielsen ERR_load_CAPI_strings(); 562db522d3aSSimon L. B. Nielsen 563db522d3aSSimon L. B. Nielsen return 1; 564db522d3aSSimon L. B. Nielsen 565db522d3aSSimon L. B. Nielsen } 566db522d3aSSimon L. B. Nielsen 567db522d3aSSimon L. B. Nielsen # ifndef OPENSSL_NO_DYNAMIC_ENGINE 568db522d3aSSimon L. B. Nielsen static int bind_helper(ENGINE *e, const char *id) 569db522d3aSSimon L. B. Nielsen { 570db522d3aSSimon L. B. Nielsen if (id && (strcmp(id, engine_capi_id) != 0)) 571db522d3aSSimon L. B. Nielsen return 0; 572db522d3aSSimon L. B. Nielsen if (!bind_capi(e)) 573db522d3aSSimon L. B. Nielsen return 0; 574db522d3aSSimon L. B. Nielsen return 1; 575db522d3aSSimon L. B. Nielsen } 5766f9291ceSJung-uk Kim 577db522d3aSSimon L. B. Nielsen IMPLEMENT_DYNAMIC_CHECK_FN() 578db522d3aSSimon L. B. Nielsen IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) 579db522d3aSSimon L. B. Nielsen # else 580db522d3aSSimon L. B. Nielsen static ENGINE *engine_capi(void) 581db522d3aSSimon L. B. Nielsen { 582db522d3aSSimon L. B. Nielsen ENGINE *ret = ENGINE_new(); 583db522d3aSSimon L. B. Nielsen if (!ret) 584db522d3aSSimon L. B. Nielsen return NULL; 5856f9291ceSJung-uk Kim if (!bind_capi(ret)) { 586db522d3aSSimon L. B. Nielsen ENGINE_free(ret); 587db522d3aSSimon L. B. Nielsen return NULL; 588db522d3aSSimon L. B. Nielsen } 589db522d3aSSimon L. B. Nielsen return ret; 590db522d3aSSimon L. B. Nielsen } 591db522d3aSSimon L. B. Nielsen 592db522d3aSSimon L. B. Nielsen void ENGINE_load_capi(void) 593db522d3aSSimon L. B. Nielsen { 594db522d3aSSimon L. B. Nielsen /* Copied from eng_[openssl|dyn].c */ 595db522d3aSSimon L. B. Nielsen ENGINE *toadd = engine_capi(); 5966f9291ceSJung-uk Kim if (!toadd) 5976f9291ceSJung-uk Kim return; 598db522d3aSSimon L. B. Nielsen ENGINE_add(toadd); 599db522d3aSSimon L. B. Nielsen ENGINE_free(toadd); 600db522d3aSSimon L. B. Nielsen ERR_clear_error(); 601db522d3aSSimon L. B. Nielsen } 602db522d3aSSimon L. B. Nielsen # endif 603db522d3aSSimon L. B. Nielsen 604db522d3aSSimon L. B. Nielsen static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) 605db522d3aSSimon L. B. Nielsen { 606db522d3aSSimon L. B. Nielsen int i; 6076f9291ceSJung-uk Kim /* 6086f9291ceSJung-uk Kim * Reverse buffer in place: since this is a keyblob structure that will 6096f9291ceSJung-uk Kim * be freed up after conversion anyway it doesn't matter if we change 6106f9291ceSJung-uk Kim * it. 611db522d3aSSimon L. B. Nielsen */ 6126f9291ceSJung-uk Kim for (i = 0; i < binlen / 2; i++) { 613db522d3aSSimon L. B. Nielsen unsigned char c; 614db522d3aSSimon L. B. Nielsen c = bin[i]; 615db522d3aSSimon L. B. Nielsen bin[i] = bin[binlen - i - 1]; 616db522d3aSSimon L. B. Nielsen bin[binlen - i - 1] = c; 617db522d3aSSimon L. B. Nielsen } 618db522d3aSSimon L. B. Nielsen 619db522d3aSSimon L. B. Nielsen if (!BN_bin2bn(bin, binlen, bn)) 620db522d3aSSimon L. B. Nielsen return 0; 621db522d3aSSimon L. B. Nielsen return 1; 622db522d3aSSimon L. B. Nielsen } 623db522d3aSSimon L. B. Nielsen 624db522d3aSSimon L. B. Nielsen /* Given a CAPI_KEY get an EVP_PKEY structure */ 625db522d3aSSimon L. B. Nielsen 626db522d3aSSimon L. B. Nielsen static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY * key) 627db522d3aSSimon L. B. Nielsen { 628db522d3aSSimon L. B. Nielsen unsigned char *pubkey = NULL; 629db522d3aSSimon L. B. Nielsen DWORD len; 630db522d3aSSimon L. B. Nielsen BLOBHEADER *bh; 631db522d3aSSimon L. B. Nielsen RSA *rkey = NULL; 632db522d3aSSimon L. B. Nielsen DSA *dkey = NULL; 633db522d3aSSimon L. B. Nielsen EVP_PKEY *ret = NULL; 6346f9291ceSJung-uk Kim if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { 635db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); 636db522d3aSSimon L. B. Nielsen capi_addlasterror(); 637db522d3aSSimon L. B. Nielsen return NULL; 638db522d3aSSimon L. B. Nielsen } 639db522d3aSSimon L. B. Nielsen 640db522d3aSSimon L. B. Nielsen pubkey = OPENSSL_malloc(len); 641db522d3aSSimon L. B. Nielsen 642db522d3aSSimon L. B. Nielsen if (!pubkey) 643db522d3aSSimon L. B. Nielsen goto memerr; 644db522d3aSSimon L. B. Nielsen 6456f9291ceSJung-uk Kim if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { 646db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); 647db522d3aSSimon L. B. Nielsen capi_addlasterror(); 648db522d3aSSimon L. B. Nielsen goto err; 649db522d3aSSimon L. B. Nielsen } 650db522d3aSSimon L. B. Nielsen 651db522d3aSSimon L. B. Nielsen bh = (BLOBHEADER *) pubkey; 6526f9291ceSJung-uk Kim if (bh->bType != PUBLICKEYBLOB) { 653db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); 654db522d3aSSimon L. B. Nielsen goto err; 655db522d3aSSimon L. B. Nielsen } 6566f9291ceSJung-uk Kim if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) { 657db522d3aSSimon L. B. Nielsen RSAPUBKEY *rp; 658db522d3aSSimon L. B. Nielsen DWORD rsa_modlen; 659db522d3aSSimon L. B. Nielsen unsigned char *rsa_modulus; 660db522d3aSSimon L. B. Nielsen rp = (RSAPUBKEY *) (bh + 1); 6616f9291ceSJung-uk Kim if (rp->magic != 0x31415352) { 662db522d3aSSimon L. B. Nielsen char magstr[10]; 663db522d3aSSimon L. B. Nielsen BIO_snprintf(magstr, 10, "%lx", rp->magic); 6646f9291ceSJung-uk Kim CAPIerr(CAPI_F_CAPI_GET_PKEY, 6656f9291ceSJung-uk Kim CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); 666db522d3aSSimon L. B. Nielsen ERR_add_error_data(2, "magic=0x", magstr); 667db522d3aSSimon L. B. Nielsen goto err; 668db522d3aSSimon L. B. Nielsen } 669db522d3aSSimon L. B. Nielsen rsa_modulus = (unsigned char *)(rp + 1); 670db522d3aSSimon L. B. Nielsen rkey = RSA_new_method(eng); 671db522d3aSSimon L. B. Nielsen if (!rkey) 672db522d3aSSimon L. B. Nielsen goto memerr; 673db522d3aSSimon L. B. Nielsen 674db522d3aSSimon L. B. Nielsen rkey->e = BN_new(); 675db522d3aSSimon L. B. Nielsen rkey->n = BN_new(); 676db522d3aSSimon L. B. Nielsen 677db522d3aSSimon L. B. Nielsen if (!rkey->e || !rkey->n) 678db522d3aSSimon L. B. Nielsen goto memerr; 679db522d3aSSimon L. B. Nielsen 680db522d3aSSimon L. B. Nielsen if (!BN_set_word(rkey->e, rp->pubexp)) 681db522d3aSSimon L. B. Nielsen goto memerr; 682db522d3aSSimon L. B. Nielsen 683db522d3aSSimon L. B. Nielsen rsa_modlen = rp->bitlen / 8; 684db522d3aSSimon L. B. Nielsen if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen)) 685db522d3aSSimon L. B. Nielsen goto memerr; 686db522d3aSSimon L. B. Nielsen 687db522d3aSSimon L. B. Nielsen RSA_set_ex_data(rkey, rsa_capi_idx, key); 688db522d3aSSimon L. B. Nielsen 689db522d3aSSimon L. B. Nielsen if (!(ret = EVP_PKEY_new())) 690db522d3aSSimon L. B. Nielsen goto memerr; 691db522d3aSSimon L. B. Nielsen 692db522d3aSSimon L. B. Nielsen EVP_PKEY_assign_RSA(ret, rkey); 693db522d3aSSimon L. B. Nielsen rkey = NULL; 694db522d3aSSimon L. B. Nielsen 6956f9291ceSJung-uk Kim } else if (bh->aiKeyAlg == CALG_DSS_SIGN) { 696db522d3aSSimon L. B. Nielsen DSSPUBKEY *dp; 697db522d3aSSimon L. B. Nielsen DWORD dsa_plen; 698db522d3aSSimon L. B. Nielsen unsigned char *btmp; 699db522d3aSSimon L. B. Nielsen dp = (DSSPUBKEY *) (bh + 1); 7006f9291ceSJung-uk Kim if (dp->magic != 0x31535344) { 701db522d3aSSimon L. B. Nielsen char magstr[10]; 702db522d3aSSimon L. B. Nielsen BIO_snprintf(magstr, 10, "%lx", dp->magic); 7036f9291ceSJung-uk Kim CAPIerr(CAPI_F_CAPI_GET_PKEY, 7046f9291ceSJung-uk Kim CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); 705db522d3aSSimon L. B. Nielsen ERR_add_error_data(2, "magic=0x", magstr); 706db522d3aSSimon L. B. Nielsen goto err; 707db522d3aSSimon L. B. Nielsen } 708db522d3aSSimon L. B. Nielsen dsa_plen = dp->bitlen / 8; 709db522d3aSSimon L. B. Nielsen btmp = (unsigned char *)(dp + 1); 710db522d3aSSimon L. B. Nielsen dkey = DSA_new_method(eng); 711db522d3aSSimon L. B. Nielsen if (!dkey) 712db522d3aSSimon L. B. Nielsen goto memerr; 713db522d3aSSimon L. B. Nielsen dkey->p = BN_new(); 714db522d3aSSimon L. B. Nielsen dkey->q = BN_new(); 715db522d3aSSimon L. B. Nielsen dkey->g = BN_new(); 716db522d3aSSimon L. B. Nielsen dkey->pub_key = BN_new(); 717db522d3aSSimon L. B. Nielsen if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key) 718db522d3aSSimon L. B. Nielsen goto memerr; 719db522d3aSSimon L. B. Nielsen if (!lend_tobn(dkey->p, btmp, dsa_plen)) 720db522d3aSSimon L. B. Nielsen goto memerr; 721db522d3aSSimon L. B. Nielsen btmp += dsa_plen; 722db522d3aSSimon L. B. Nielsen if (!lend_tobn(dkey->q, btmp, 20)) 723db522d3aSSimon L. B. Nielsen goto memerr; 724db522d3aSSimon L. B. Nielsen btmp += 20; 725db522d3aSSimon L. B. Nielsen if (!lend_tobn(dkey->g, btmp, dsa_plen)) 726db522d3aSSimon L. B. Nielsen goto memerr; 727db522d3aSSimon L. B. Nielsen btmp += dsa_plen; 728db522d3aSSimon L. B. Nielsen if (!lend_tobn(dkey->pub_key, btmp, dsa_plen)) 729db522d3aSSimon L. B. Nielsen goto memerr; 730db522d3aSSimon L. B. Nielsen btmp += dsa_plen; 731db522d3aSSimon L. B. Nielsen 732db522d3aSSimon L. B. Nielsen DSA_set_ex_data(dkey, dsa_capi_idx, key); 733db522d3aSSimon L. B. Nielsen 734db522d3aSSimon L. B. Nielsen if (!(ret = EVP_PKEY_new())) 735db522d3aSSimon L. B. Nielsen goto memerr; 736db522d3aSSimon L. B. Nielsen 737db522d3aSSimon L. B. Nielsen EVP_PKEY_assign_DSA(ret, dkey); 738db522d3aSSimon L. B. Nielsen dkey = NULL; 7396f9291ceSJung-uk Kim } else { 740db522d3aSSimon L. B. Nielsen char algstr[10]; 741db522d3aSSimon L. B. Nielsen BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); 7426f9291ceSJung-uk Kim CAPIerr(CAPI_F_CAPI_GET_PKEY, 7436f9291ceSJung-uk Kim CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); 744db522d3aSSimon L. B. Nielsen ERR_add_error_data(2, "aiKeyAlg=0x", algstr); 745db522d3aSSimon L. B. Nielsen goto err; 746db522d3aSSimon L. B. Nielsen } 747db522d3aSSimon L. B. Nielsen 748db522d3aSSimon L. B. Nielsen err: 749db522d3aSSimon L. B. Nielsen if (pubkey) 750db522d3aSSimon L. B. Nielsen OPENSSL_free(pubkey); 7516f9291ceSJung-uk Kim if (!ret) { 752db522d3aSSimon L. B. Nielsen if (rkey) 753db522d3aSSimon L. B. Nielsen RSA_free(rkey); 754db522d3aSSimon L. B. Nielsen if (dkey) 755db522d3aSSimon L. B. Nielsen DSA_free(dkey); 756db522d3aSSimon L. B. Nielsen } 757db522d3aSSimon L. B. Nielsen 758db522d3aSSimon L. B. Nielsen return ret; 759db522d3aSSimon L. B. Nielsen 760db522d3aSSimon L. B. Nielsen memerr: 761db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE); 762db522d3aSSimon L. B. Nielsen goto err; 763db522d3aSSimon L. B. Nielsen 764db522d3aSSimon L. B. Nielsen } 765db522d3aSSimon L. B. Nielsen 766db522d3aSSimon L. B. Nielsen static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, 767db522d3aSSimon L. B. Nielsen UI_METHOD *ui_method, void *callback_data) 768db522d3aSSimon L. B. Nielsen { 769db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 770db522d3aSSimon L. B. Nielsen CAPI_KEY *key; 771db522d3aSSimon L. B. Nielsen EVP_PKEY *ret; 772db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(eng, capi_idx); 773db522d3aSSimon L. B. Nielsen 7746f9291ceSJung-uk Kim if (!ctx) { 775db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); 776db522d3aSSimon L. B. Nielsen return NULL; 777db522d3aSSimon L. B. Nielsen } 778db522d3aSSimon L. B. Nielsen 779db522d3aSSimon L. B. Nielsen key = capi_find_key(ctx, key_id); 780db522d3aSSimon L. B. Nielsen 781db522d3aSSimon L. B. Nielsen if (!key) 782db522d3aSSimon L. B. Nielsen return NULL; 783db522d3aSSimon L. B. Nielsen 784db522d3aSSimon L. B. Nielsen ret = capi_get_pkey(eng, key); 785db522d3aSSimon L. B. Nielsen 786db522d3aSSimon L. B. Nielsen if (!ret) 787db522d3aSSimon L. B. Nielsen capi_free_key(key); 788db522d3aSSimon L. B. Nielsen return ret; 789db522d3aSSimon L. B. Nielsen 790db522d3aSSimon L. B. Nielsen } 791db522d3aSSimon L. B. Nielsen 792db522d3aSSimon L. B. Nielsen /* CryptoAPI RSA operations */ 793db522d3aSSimon L. B. Nielsen 794db522d3aSSimon L. B. Nielsen int capi_rsa_priv_enc(int flen, const unsigned char *from, 795db522d3aSSimon L. B. Nielsen unsigned char *to, RSA *rsa, int padding) 796db522d3aSSimon L. B. Nielsen { 797db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED); 798db522d3aSSimon L. B. Nielsen return -1; 799db522d3aSSimon L. B. Nielsen } 800db522d3aSSimon L. B. Nielsen 801db522d3aSSimon L. B. Nielsen int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, 802db522d3aSSimon L. B. Nielsen unsigned char *sigret, unsigned int *siglen, const RSA *rsa) 803db522d3aSSimon L. B. Nielsen { 804db522d3aSSimon L. B. Nielsen ALG_ID alg; 805db522d3aSSimon L. B. Nielsen HCRYPTHASH hash; 806db522d3aSSimon L. B. Nielsen DWORD slen; 807db522d3aSSimon L. B. Nielsen unsigned int i; 808db522d3aSSimon L. B. Nielsen int ret = -1; 809db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_key; 810db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 811db522d3aSSimon L. B. Nielsen 812db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); 813db522d3aSSimon L. B. Nielsen 814db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Called CAPI_rsa_sign()\n"); 815db522d3aSSimon L. B. Nielsen 816db522d3aSSimon L. B. Nielsen capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); 8176f9291ceSJung-uk Kim if (!capi_key) { 818db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY); 819db522d3aSSimon L. B. Nielsen return -1; 820db522d3aSSimon L. B. Nielsen } 821db522d3aSSimon L. B. Nielsen /* Convert the signature type to a CryptoAPI algorithm ID */ 8226f9291ceSJung-uk Kim switch (dtype) { 823*4c6a0400SJung-uk Kim case NID_sha256: 824*4c6a0400SJung-uk Kim alg = CALG_SHA_256; 825*4c6a0400SJung-uk Kim break; 826*4c6a0400SJung-uk Kim 827*4c6a0400SJung-uk Kim case NID_sha384: 828*4c6a0400SJung-uk Kim alg = CALG_SHA_384; 829*4c6a0400SJung-uk Kim break; 830*4c6a0400SJung-uk Kim 831*4c6a0400SJung-uk Kim case NID_sha512: 832*4c6a0400SJung-uk Kim alg = CALG_SHA_512; 833*4c6a0400SJung-uk Kim break; 834*4c6a0400SJung-uk Kim 835db522d3aSSimon L. B. Nielsen case NID_sha1: 836db522d3aSSimon L. B. Nielsen alg = CALG_SHA1; 837db522d3aSSimon L. B. Nielsen break; 838db522d3aSSimon L. B. Nielsen 839db522d3aSSimon L. B. Nielsen case NID_md5: 840db522d3aSSimon L. B. Nielsen alg = CALG_MD5; 841db522d3aSSimon L. B. Nielsen break; 842db522d3aSSimon L. B. Nielsen 843db522d3aSSimon L. B. Nielsen case NID_md5_sha1: 844db522d3aSSimon L. B. Nielsen alg = CALG_SSL3_SHAMD5; 845db522d3aSSimon L. B. Nielsen break; 846db522d3aSSimon L. B. Nielsen default: 847db522d3aSSimon L. B. Nielsen { 848db522d3aSSimon L. B. Nielsen char algstr[10]; 849db522d3aSSimon L. B. Nielsen BIO_snprintf(algstr, 10, "%lx", dtype); 850db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID); 851db522d3aSSimon L. B. Nielsen ERR_add_error_data(2, "NID=0x", algstr); 852db522d3aSSimon L. B. Nielsen return -1; 853db522d3aSSimon L. B. Nielsen } 854db522d3aSSimon L. B. Nielsen } 855db522d3aSSimon L. B. Nielsen 856db522d3aSSimon L. B. Nielsen /* Create the hash object */ 8576f9291ceSJung-uk Kim if (!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) { 858db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); 859db522d3aSSimon L. B. Nielsen capi_addlasterror(); 860db522d3aSSimon L. B. Nielsen return -1; 861db522d3aSSimon L. B. Nielsen } 862db522d3aSSimon L. B. Nielsen /* Set the hash value to the value passed */ 863db522d3aSSimon L. B. Nielsen 8646f9291ceSJung-uk Kim if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) { 865db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE); 866db522d3aSSimon L. B. Nielsen capi_addlasterror(); 867db522d3aSSimon L. B. Nielsen goto err; 868db522d3aSSimon L. B. Nielsen } 869db522d3aSSimon L. B. Nielsen 870db522d3aSSimon L. B. Nielsen /* Finally sign it */ 871db522d3aSSimon L. B. Nielsen slen = RSA_size(rsa); 8727bded2dbSJung-uk Kim if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) { 873db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); 874db522d3aSSimon L. B. Nielsen capi_addlasterror(); 875db522d3aSSimon L. B. Nielsen goto err; 8766f9291ceSJung-uk Kim } else { 877db522d3aSSimon L. B. Nielsen ret = 1; 878db522d3aSSimon L. B. Nielsen /* Inplace byte reversal of signature */ 8796f9291ceSJung-uk Kim for (i = 0; i < slen / 2; i++) { 880db522d3aSSimon L. B. Nielsen unsigned char c; 881db522d3aSSimon L. B. Nielsen c = sigret[i]; 882db522d3aSSimon L. B. Nielsen sigret[i] = sigret[slen - i - 1]; 883db522d3aSSimon L. B. Nielsen sigret[slen - i - 1] = c; 884db522d3aSSimon L. B. Nielsen } 885db522d3aSSimon L. B. Nielsen *siglen = slen; 886db522d3aSSimon L. B. Nielsen } 887db522d3aSSimon L. B. Nielsen 888db522d3aSSimon L. B. Nielsen /* Now cleanup */ 889db522d3aSSimon L. B. Nielsen 890db522d3aSSimon L. B. Nielsen err: 891db522d3aSSimon L. B. Nielsen CryptDestroyHash(hash); 892db522d3aSSimon L. B. Nielsen 893db522d3aSSimon L. B. Nielsen return ret; 894db522d3aSSimon L. B. Nielsen } 895db522d3aSSimon L. B. Nielsen 896db522d3aSSimon L. B. Nielsen int capi_rsa_priv_dec(int flen, const unsigned char *from, 897db522d3aSSimon L. B. Nielsen unsigned char *to, RSA *rsa, int padding) 898db522d3aSSimon L. B. Nielsen { 899db522d3aSSimon L. B. Nielsen int i; 900db522d3aSSimon L. B. Nielsen unsigned char *tmpbuf; 901db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_key; 902db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 903db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); 904db522d3aSSimon L. B. Nielsen 905db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); 906db522d3aSSimon L. B. Nielsen 907db522d3aSSimon L. B. Nielsen capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); 9086f9291ceSJung-uk Kim if (!capi_key) { 909db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY); 910db522d3aSSimon L. B. Nielsen return -1; 911db522d3aSSimon L. B. Nielsen } 912db522d3aSSimon L. B. Nielsen 9136f9291ceSJung-uk Kim if (padding != RSA_PKCS1_PADDING) { 914db522d3aSSimon L. B. Nielsen char errstr[10]; 915db522d3aSSimon L. B. Nielsen BIO_snprintf(errstr, 10, "%d", padding); 916db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); 917db522d3aSSimon L. B. Nielsen ERR_add_error_data(2, "padding=", errstr); 918db522d3aSSimon L. B. Nielsen return -1; 919db522d3aSSimon L. B. Nielsen } 920db522d3aSSimon L. B. Nielsen 921db522d3aSSimon L. B. Nielsen /* Create temp reverse order version of input */ 9226f9291ceSJung-uk Kim if (!(tmpbuf = OPENSSL_malloc(flen))) { 923db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE); 924db522d3aSSimon L. B. Nielsen return -1; 925db522d3aSSimon L. B. Nielsen } 926db522d3aSSimon L. B. Nielsen for (i = 0; i < flen; i++) 927db522d3aSSimon L. B. Nielsen tmpbuf[flen - i - 1] = from[i]; 928db522d3aSSimon L. B. Nielsen 929db522d3aSSimon L. B. Nielsen /* Finally decrypt it */ 9306f9291ceSJung-uk Kim if (!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen)) { 931db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); 932db522d3aSSimon L. B. Nielsen capi_addlasterror(); 933db522d3aSSimon L. B. Nielsen OPENSSL_free(tmpbuf); 934db522d3aSSimon L. B. Nielsen return -1; 9356f9291ceSJung-uk Kim } else 9366f9291ceSJung-uk Kim memcpy(to, tmpbuf, flen); 937db522d3aSSimon L. B. Nielsen 938db522d3aSSimon L. B. Nielsen OPENSSL_free(tmpbuf); 939db522d3aSSimon L. B. Nielsen 940db522d3aSSimon L. B. Nielsen return flen; 941db522d3aSSimon L. B. Nielsen } 942db522d3aSSimon L. B. Nielsen 943db522d3aSSimon L. B. Nielsen static int capi_rsa_free(RSA *rsa) 944db522d3aSSimon L. B. Nielsen { 945db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_key; 946db522d3aSSimon L. B. Nielsen capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); 947db522d3aSSimon L. B. Nielsen capi_free_key(capi_key); 948db522d3aSSimon L. B. Nielsen RSA_set_ex_data(rsa, rsa_capi_idx, 0); 949db522d3aSSimon L. B. Nielsen return 1; 950db522d3aSSimon L. B. Nielsen } 951db522d3aSSimon L. B. Nielsen 952db522d3aSSimon L. B. Nielsen /* CryptoAPI DSA operations */ 953db522d3aSSimon L. B. Nielsen 954db522d3aSSimon L. B. Nielsen static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, 955db522d3aSSimon L. B. Nielsen DSA *dsa) 956db522d3aSSimon L. B. Nielsen { 957db522d3aSSimon L. B. Nielsen HCRYPTHASH hash; 958db522d3aSSimon L. B. Nielsen DWORD slen; 959db522d3aSSimon L. B. Nielsen DSA_SIG *ret = NULL; 960db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_key; 961db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 962db522d3aSSimon L. B. Nielsen unsigned char csigbuf[40]; 963db522d3aSSimon L. B. Nielsen 964db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(dsa->engine, capi_idx); 965db522d3aSSimon L. B. Nielsen 966db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n"); 967db522d3aSSimon L. B. Nielsen 968db522d3aSSimon L. B. Nielsen capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); 969db522d3aSSimon L. B. Nielsen 9706f9291ceSJung-uk Kim if (!capi_key) { 971db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY); 972db522d3aSSimon L. B. Nielsen return NULL; 973db522d3aSSimon L. B. Nielsen } 974db522d3aSSimon L. B. Nielsen 9756f9291ceSJung-uk Kim if (dlen != 20) { 976db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH); 977db522d3aSSimon L. B. Nielsen return NULL; 978db522d3aSSimon L. B. Nielsen } 979db522d3aSSimon L. B. Nielsen 980db522d3aSSimon L. B. Nielsen /* Create the hash object */ 9816f9291ceSJung-uk Kim if (!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) { 982db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); 983db522d3aSSimon L. B. Nielsen capi_addlasterror(); 984db522d3aSSimon L. B. Nielsen return NULL; 985db522d3aSSimon L. B. Nielsen } 986db522d3aSSimon L. B. Nielsen 987db522d3aSSimon L. B. Nielsen /* Set the hash value to the value passed */ 9886f9291ceSJung-uk Kim if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) { 989db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE); 990db522d3aSSimon L. B. Nielsen capi_addlasterror(); 991db522d3aSSimon L. B. Nielsen goto err; 992db522d3aSSimon L. B. Nielsen } 993db522d3aSSimon L. B. Nielsen 994db522d3aSSimon L. B. Nielsen /* Finally sign it */ 995db522d3aSSimon L. B. Nielsen slen = sizeof(csigbuf); 9967bded2dbSJung-uk Kim if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) { 997db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); 998db522d3aSSimon L. B. Nielsen capi_addlasterror(); 999db522d3aSSimon L. B. Nielsen goto err; 10006f9291ceSJung-uk Kim } else { 1001db522d3aSSimon L. B. Nielsen ret = DSA_SIG_new(); 1002db522d3aSSimon L. B. Nielsen if (!ret) 1003db522d3aSSimon L. B. Nielsen goto err; 1004db522d3aSSimon L. B. Nielsen ret->r = BN_new(); 1005db522d3aSSimon L. B. Nielsen ret->s = BN_new(); 1006db522d3aSSimon L. B. Nielsen if (!ret->r || !ret->s) 1007db522d3aSSimon L. B. Nielsen goto err; 1008db522d3aSSimon L. B. Nielsen if (!lend_tobn(ret->r, csigbuf, 20) 10096f9291ceSJung-uk Kim || !lend_tobn(ret->s, csigbuf + 20, 20)) { 1010db522d3aSSimon L. B. Nielsen DSA_SIG_free(ret); 1011db522d3aSSimon L. B. Nielsen ret = NULL; 1012db522d3aSSimon L. B. Nielsen goto err; 1013db522d3aSSimon L. B. Nielsen } 1014db522d3aSSimon L. B. Nielsen } 1015db522d3aSSimon L. B. Nielsen 1016db522d3aSSimon L. B. Nielsen /* Now cleanup */ 1017db522d3aSSimon L. B. Nielsen 1018db522d3aSSimon L. B. Nielsen err: 1019db522d3aSSimon L. B. Nielsen OPENSSL_cleanse(csigbuf, 40); 1020db522d3aSSimon L. B. Nielsen CryptDestroyHash(hash); 1021db522d3aSSimon L. B. Nielsen return ret; 1022db522d3aSSimon L. B. Nielsen } 1023db522d3aSSimon L. B. Nielsen 1024db522d3aSSimon L. B. Nielsen static int capi_dsa_free(DSA *dsa) 1025db522d3aSSimon L. B. Nielsen { 1026db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_key; 1027db522d3aSSimon L. B. Nielsen capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); 1028db522d3aSSimon L. B. Nielsen capi_free_key(capi_key); 1029db522d3aSSimon L. B. Nielsen DSA_set_ex_data(dsa, dsa_capi_idx, 0); 1030db522d3aSSimon L. B. Nielsen return 1; 1031db522d3aSSimon L. B. Nielsen } 1032db522d3aSSimon L. B. Nielsen 10336f9291ceSJung-uk Kim static void capi_vtrace(CAPI_CTX * ctx, int level, char *format, 10346f9291ceSJung-uk Kim va_list argptr) 1035db522d3aSSimon L. B. Nielsen { 1036db522d3aSSimon L. B. Nielsen BIO *out; 1037db522d3aSSimon L. B. Nielsen 1038db522d3aSSimon L. B. Nielsen if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file)) 1039db522d3aSSimon L. B. Nielsen return; 1040db522d3aSSimon L. B. Nielsen out = BIO_new_file(ctx->debug_file, "a+"); 1041db522d3aSSimon L. B. Nielsen BIO_vprintf(out, format, argptr); 1042db522d3aSSimon L. B. Nielsen BIO_free(out); 1043db522d3aSSimon L. B. Nielsen } 1044db522d3aSSimon L. B. Nielsen 1045db522d3aSSimon L. B. Nielsen static void CAPI_trace(CAPI_CTX * ctx, char *format, ...) 1046db522d3aSSimon L. B. Nielsen { 1047db522d3aSSimon L. B. Nielsen va_list args; 1048db522d3aSSimon L. B. Nielsen va_start(args, format); 1049db522d3aSSimon L. B. Nielsen capi_vtrace(ctx, CAPI_DBG_TRACE, format, args); 1050db522d3aSSimon L. B. Nielsen va_end(args); 1051db522d3aSSimon L. B. Nielsen } 1052db522d3aSSimon L. B. Nielsen 1053db522d3aSSimon L. B. Nielsen static void capi_addlasterror(void) 1054db522d3aSSimon L. B. Nielsen { 1055db522d3aSSimon L. B. Nielsen capi_adderror(GetLastError()); 1056db522d3aSSimon L. B. Nielsen } 1057db522d3aSSimon L. B. Nielsen 1058db522d3aSSimon L. B. Nielsen static void capi_adderror(DWORD err) 1059db522d3aSSimon L. B. Nielsen { 1060db522d3aSSimon L. B. Nielsen char errstr[10]; 1061db522d3aSSimon L. B. Nielsen BIO_snprintf(errstr, 10, "%lX", err); 1062db522d3aSSimon L. B. Nielsen ERR_add_error_data(2, "Error code= 0x", errstr); 1063db522d3aSSimon L. B. Nielsen } 1064db522d3aSSimon L. B. Nielsen 10657bded2dbSJung-uk Kim static char *wide_to_asc(LPCWSTR wstr) 1066db522d3aSSimon L. B. Nielsen { 1067db522d3aSSimon L. B. Nielsen char *str; 10686a599222SSimon L. B. Nielsen int len_0, sz; 10696a599222SSimon L. B. Nielsen 1070db522d3aSSimon L. B. Nielsen if (!wstr) 1071db522d3aSSimon L. B. Nielsen return NULL; 10726a599222SSimon L. B. Nielsen len_0 = (int)wcslen(wstr) + 1; /* WideCharToMultiByte expects int */ 10736a599222SSimon L. B. Nielsen sz = WideCharToMultiByte(CP_ACP, 0, wstr, len_0, NULL, 0, NULL, NULL); 10746f9291ceSJung-uk Kim if (!sz) { 10756a599222SSimon L. B. Nielsen CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); 10766a599222SSimon L. B. Nielsen return NULL; 10776a599222SSimon L. B. Nielsen } 10786a599222SSimon L. B. Nielsen str = OPENSSL_malloc(sz); 10796f9291ceSJung-uk Kim if (!str) { 1080db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE); 1081db522d3aSSimon L. B. Nielsen return NULL; 1082db522d3aSSimon L. B. Nielsen } 10836f9291ceSJung-uk Kim if (!WideCharToMultiByte(CP_ACP, 0, wstr, len_0, str, sz, NULL, NULL)) { 10846a599222SSimon L. B. Nielsen OPENSSL_free(str); 10856a599222SSimon L. B. Nielsen CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); 10866a599222SSimon L. B. Nielsen return NULL; 10876a599222SSimon L. B. Nielsen } 1088db522d3aSSimon L. B. Nielsen return str; 1089db522d3aSSimon L. B. Nielsen } 1090db522d3aSSimon L. B. Nielsen 10916f9291ceSJung-uk Kim static int capi_get_provname(CAPI_CTX * ctx, LPSTR * pname, DWORD * ptype, 10926f9291ceSJung-uk Kim DWORD idx) 1093db522d3aSSimon L. B. Nielsen { 1094db522d3aSSimon L. B. Nielsen DWORD len, err; 10957bded2dbSJung-uk Kim LPTSTR name; 1096db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx); 10977bded2dbSJung-uk Kim if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len)) { 1098db522d3aSSimon L. B. Nielsen err = GetLastError(); 1099db522d3aSSimon L. B. Nielsen if (err == ERROR_NO_MORE_ITEMS) 1100db522d3aSSimon L. B. Nielsen return 2; 1101db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); 1102db522d3aSSimon L. B. Nielsen capi_adderror(err); 1103db522d3aSSimon L. B. Nielsen return 0; 1104db522d3aSSimon L. B. Nielsen } 11057bded2dbSJung-uk Kim if (sizeof(TCHAR) != sizeof(char)) 11067bded2dbSJung-uk Kim name = alloca(len); 11077bded2dbSJung-uk Kim else 1108db522d3aSSimon L. B. Nielsen name = OPENSSL_malloc(len); 11097bded2dbSJung-uk Kim if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) { 1110db522d3aSSimon L. B. Nielsen err = GetLastError(); 1111db522d3aSSimon L. B. Nielsen if (err == ERROR_NO_MORE_ITEMS) 1112db522d3aSSimon L. B. Nielsen return 2; 1113db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); 1114db522d3aSSimon L. B. Nielsen capi_adderror(err); 1115db522d3aSSimon L. B. Nielsen return 0; 1116db522d3aSSimon L. B. Nielsen } 11177bded2dbSJung-uk Kim if (sizeof(TCHAR) != sizeof(char)) 11187bded2dbSJung-uk Kim *pname = wide_to_asc((WCHAR *)name); 11197bded2dbSJung-uk Kim else 11207bded2dbSJung-uk Kim *pname = (char *)name; 11217bded2dbSJung-uk Kim CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname, 11226f9291ceSJung-uk Kim *ptype); 1123db522d3aSSimon L. B. Nielsen 1124db522d3aSSimon L. B. Nielsen return 1; 1125db522d3aSSimon L. B. Nielsen } 1126db522d3aSSimon L. B. Nielsen 1127db522d3aSSimon L. B. Nielsen static int capi_list_providers(CAPI_CTX * ctx, BIO *out) 1128db522d3aSSimon L. B. Nielsen { 1129db522d3aSSimon L. B. Nielsen DWORD idx, ptype; 1130db522d3aSSimon L. B. Nielsen int ret; 11316a599222SSimon L. B. Nielsen LPSTR provname = NULL; 1132db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "capi_list_providers\n"); 1133db522d3aSSimon L. B. Nielsen BIO_printf(out, "Available CSPs:\n"); 11346f9291ceSJung-uk Kim for (idx = 0;; idx++) { 1135db522d3aSSimon L. B. Nielsen ret = capi_get_provname(ctx, &provname, &ptype, idx); 1136db522d3aSSimon L. B. Nielsen if (ret == 2) 1137db522d3aSSimon L. B. Nielsen break; 1138db522d3aSSimon L. B. Nielsen if (ret == 0) 1139db522d3aSSimon L. B. Nielsen break; 1140db522d3aSSimon L. B. Nielsen BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype); 1141db522d3aSSimon L. B. Nielsen OPENSSL_free(provname); 1142db522d3aSSimon L. B. Nielsen } 1143db522d3aSSimon L. B. Nielsen return 1; 1144db522d3aSSimon L. B. Nielsen } 1145db522d3aSSimon L. B. Nielsen 1146db522d3aSSimon L. B. Nielsen static int capi_list_containers(CAPI_CTX * ctx, BIO *out) 1147db522d3aSSimon L. B. Nielsen { 1148db522d3aSSimon L. B. Nielsen int ret = 1; 1149db522d3aSSimon L. B. Nielsen HCRYPTPROV hprov; 1150db522d3aSSimon L. B. Nielsen DWORD err, idx, flags, buflen = 0, clen; 1151db522d3aSSimon L. B. Nielsen LPSTR cname; 11527bded2dbSJung-uk Kim LPTSTR cspname = NULL; 11537bded2dbSJung-uk Kim 11546f9291ceSJung-uk Kim CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, 11556f9291ceSJung-uk Kim ctx->csptype); 11567bded2dbSJung-uk Kim if (ctx->cspname && sizeof(TCHAR) != sizeof(char)) { 11577bded2dbSJung-uk Kim if ((clen = 11587bded2dbSJung-uk Kim MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0))) { 11597bded2dbSJung-uk Kim cspname = alloca(clen * sizeof(WCHAR)); 11607bded2dbSJung-uk Kim MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, (WCHAR *)cspname, 11617bded2dbSJung-uk Kim clen); 11627bded2dbSJung-uk Kim } 11637bded2dbSJung-uk Kim if (!cspname) { 11647bded2dbSJung-uk Kim CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); 11657bded2dbSJung-uk Kim capi_addlasterror(); 11667bded2dbSJung-uk Kim return 0; 11677bded2dbSJung-uk Kim } 11687bded2dbSJung-uk Kim } else 11697bded2dbSJung-uk Kim cspname = (TCHAR *)ctx->cspname; 11707bded2dbSJung-uk Kim if (!CryptAcquireContext 11717bded2dbSJung-uk Kim (&hprov, NULL, cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) { 11726f9291ceSJung-uk Kim CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, 11736f9291ceSJung-uk Kim CAPI_R_CRYPTACQUIRECONTEXT_ERROR); 1174db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1175db522d3aSSimon L. B. Nielsen return 0; 1176db522d3aSSimon L. B. Nielsen } 11776f9291ceSJung-uk Kim if (!CryptGetProvParam 11786f9291ceSJung-uk Kim (hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST)) { 1179db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); 1180db522d3aSSimon L. B. Nielsen capi_addlasterror(); 118112de4ed2SJung-uk Kim CryptReleaseContext(hprov, 0); 1182db522d3aSSimon L. B. Nielsen return 0; 1183db522d3aSSimon L. B. Nielsen } 1184db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Got max container len %d\n", buflen); 1185db522d3aSSimon L. B. Nielsen if (buflen == 0) 1186db522d3aSSimon L. B. Nielsen buflen = 1024; 1187db522d3aSSimon L. B. Nielsen cname = OPENSSL_malloc(buflen); 11886f9291ceSJung-uk Kim if (!cname) { 1189db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); 1190db522d3aSSimon L. B. Nielsen goto err; 1191db522d3aSSimon L. B. Nielsen } 1192db522d3aSSimon L. B. Nielsen 11936f9291ceSJung-uk Kim for (idx = 0;; idx++) { 1194db522d3aSSimon L. B. Nielsen clen = buflen; 1195db522d3aSSimon L. B. Nielsen cname[0] = 0; 1196db522d3aSSimon L. B. Nielsen 1197db522d3aSSimon L. B. Nielsen if (idx == 0) 1198db522d3aSSimon L. B. Nielsen flags = CRYPT_FIRST; 1199db522d3aSSimon L. B. Nielsen else 1200db522d3aSSimon L. B. Nielsen flags = 0; 12017bded2dbSJung-uk Kim if (!CryptGetProvParam 12027bded2dbSJung-uk Kim (hprov, PP_ENUMCONTAINERS, (BYTE *) cname, &clen, flags)) { 1203db522d3aSSimon L. B. Nielsen err = GetLastError(); 1204db522d3aSSimon L. B. Nielsen if (err == ERROR_NO_MORE_ITEMS) 1205db522d3aSSimon L. B. Nielsen goto done; 1206db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); 1207db522d3aSSimon L. B. Nielsen capi_adderror(err); 1208db522d3aSSimon L. B. Nielsen goto err; 1209db522d3aSSimon L. B. Nielsen } 12106f9291ceSJung-uk Kim CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", 12116f9291ceSJung-uk Kim cname, clen, idx, flags); 12126f9291ceSJung-uk Kim if (!cname[0] && (clen == buflen)) { 1213db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Enumerate bug: using workaround\n"); 1214db522d3aSSimon L. B. Nielsen goto done; 1215db522d3aSSimon L. B. Nielsen } 1216db522d3aSSimon L. B. Nielsen BIO_printf(out, "%d. %s\n", idx, cname); 1217db522d3aSSimon L. B. Nielsen } 1218db522d3aSSimon L. B. Nielsen err: 1219db522d3aSSimon L. B. Nielsen 1220db522d3aSSimon L. B. Nielsen ret = 0; 1221db522d3aSSimon L. B. Nielsen 1222db522d3aSSimon L. B. Nielsen done: 1223db522d3aSSimon L. B. Nielsen if (cname) 1224db522d3aSSimon L. B. Nielsen OPENSSL_free(cname); 1225db522d3aSSimon L. B. Nielsen CryptReleaseContext(hprov, 0); 1226db522d3aSSimon L. B. Nielsen 1227db522d3aSSimon L. B. Nielsen return ret; 1228db522d3aSSimon L. B. Nielsen } 1229db522d3aSSimon L. B. Nielsen 1230db522d3aSSimon L. B. Nielsen CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX * ctx, PCCERT_CONTEXT cert) 1231db522d3aSSimon L. B. Nielsen { 1232db522d3aSSimon L. B. Nielsen DWORD len; 1233db522d3aSSimon L. B. Nielsen CRYPT_KEY_PROV_INFO *pinfo; 1234db522d3aSSimon L. B. Nielsen 12356f9291ceSJung-uk Kim if (!CertGetCertificateContextProperty 12366f9291ceSJung-uk Kim (cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) 1237db522d3aSSimon L. B. Nielsen return NULL; 1238db522d3aSSimon L. B. Nielsen pinfo = OPENSSL_malloc(len); 12396f9291ceSJung-uk Kim if (!pinfo) { 1240db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE); 1241db522d3aSSimon L. B. Nielsen return NULL; 1242db522d3aSSimon L. B. Nielsen } 12436f9291ceSJung-uk Kim if (!CertGetCertificateContextProperty 12446f9291ceSJung-uk Kim (cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { 12456f9291ceSJung-uk Kim CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, 12466f9291ceSJung-uk Kim CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO); 1247db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1248db522d3aSSimon L. B. Nielsen OPENSSL_free(pinfo); 1249db522d3aSSimon L. B. Nielsen return NULL; 1250db522d3aSSimon L. B. Nielsen } 1251db522d3aSSimon L. B. Nielsen return pinfo; 1252db522d3aSSimon L. B. Nielsen } 1253db522d3aSSimon L. B. Nielsen 12546f9291ceSJung-uk Kim static void capi_dump_prov_info(CAPI_CTX * ctx, BIO *out, 12556f9291ceSJung-uk Kim CRYPT_KEY_PROV_INFO * pinfo) 1256db522d3aSSimon L. B. Nielsen { 1257db522d3aSSimon L. B. Nielsen char *provname = NULL, *contname = NULL; 12586f9291ceSJung-uk Kim if (!pinfo) { 1259db522d3aSSimon L. B. Nielsen BIO_printf(out, " No Private Key\n"); 1260db522d3aSSimon L. B. Nielsen return; 1261db522d3aSSimon L. B. Nielsen } 1262db522d3aSSimon L. B. Nielsen provname = wide_to_asc(pinfo->pwszProvName); 1263db522d3aSSimon L. B. Nielsen contname = wide_to_asc(pinfo->pwszContainerName); 1264db522d3aSSimon L. B. Nielsen if (!provname || !contname) 1265db522d3aSSimon L. B. Nielsen goto err; 1266db522d3aSSimon L. B. Nielsen 1267db522d3aSSimon L. B. Nielsen BIO_printf(out, " Private Key Info:\n"); 12686f9291ceSJung-uk Kim BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, 12696f9291ceSJung-uk Kim pinfo->dwProvType); 12706f9291ceSJung-uk Kim BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, 12716f9291ceSJung-uk Kim pinfo->dwKeySpec); 1272db522d3aSSimon L. B. Nielsen err: 1273db522d3aSSimon L. B. Nielsen if (provname) 1274db522d3aSSimon L. B. Nielsen OPENSSL_free(provname); 1275db522d3aSSimon L. B. Nielsen if (contname) 1276db522d3aSSimon L. B. Nielsen OPENSSL_free(contname); 1277db522d3aSSimon L. B. Nielsen } 1278db522d3aSSimon L. B. Nielsen 1279db522d3aSSimon L. B. Nielsen char *capi_cert_get_fname(CAPI_CTX * ctx, PCCERT_CONTEXT cert) 1280db522d3aSSimon L. B. Nielsen { 1281db522d3aSSimon L. B. Nielsen LPWSTR wfname; 1282db522d3aSSimon L. B. Nielsen DWORD dlen; 1283db522d3aSSimon L. B. Nielsen 1284db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "capi_cert_get_fname\n"); 12856f9291ceSJung-uk Kim if (!CertGetCertificateContextProperty 12866f9291ceSJung-uk Kim (cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen)) 1287db522d3aSSimon L. B. Nielsen return NULL; 1288db522d3aSSimon L. B. Nielsen wfname = OPENSSL_malloc(dlen); 12896f9291ceSJung-uk Kim if (CertGetCertificateContextProperty 12906f9291ceSJung-uk Kim (cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) { 1291db522d3aSSimon L. B. Nielsen char *fname = wide_to_asc(wfname); 1292db522d3aSSimon L. B. Nielsen OPENSSL_free(wfname); 1293db522d3aSSimon L. B. Nielsen return fname; 1294db522d3aSSimon L. B. Nielsen } 1295db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME); 1296db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1297db522d3aSSimon L. B. Nielsen 1298db522d3aSSimon L. B. Nielsen OPENSSL_free(wfname); 1299db522d3aSSimon L. B. Nielsen return NULL; 1300db522d3aSSimon L. B. Nielsen } 1301db522d3aSSimon L. B. Nielsen 1302db522d3aSSimon L. B. Nielsen void capi_dump_cert(CAPI_CTX * ctx, BIO *out, PCCERT_CONTEXT cert) 1303db522d3aSSimon L. B. Nielsen { 1304db522d3aSSimon L. B. Nielsen X509 *x; 1305db522d3aSSimon L. B. Nielsen unsigned char *p; 1306db522d3aSSimon L. B. Nielsen unsigned long flags = ctx->dump_flags; 13076f9291ceSJung-uk Kim if (flags & CAPI_DMP_FNAME) { 1308db522d3aSSimon L. B. Nielsen char *fname; 1309db522d3aSSimon L. B. Nielsen fname = capi_cert_get_fname(ctx, cert); 13106f9291ceSJung-uk Kim if (fname) { 1311db522d3aSSimon L. B. Nielsen BIO_printf(out, " Friendly Name \"%s\"\n", fname); 1312db522d3aSSimon L. B. Nielsen OPENSSL_free(fname); 13136f9291ceSJung-uk Kim } else 1314db522d3aSSimon L. B. Nielsen BIO_printf(out, " <No Friendly Name>\n"); 1315db522d3aSSimon L. B. Nielsen } 1316db522d3aSSimon L. B. Nielsen 1317db522d3aSSimon L. B. Nielsen p = cert->pbCertEncoded; 1318db522d3aSSimon L. B. Nielsen x = d2i_X509(NULL, &p, cert->cbCertEncoded); 1319db522d3aSSimon L. B. Nielsen if (!x) 1320db522d3aSSimon L. B. Nielsen BIO_printf(out, " <Can't parse certificate>\n"); 13216f9291ceSJung-uk Kim if (flags & CAPI_DMP_SUMMARY) { 1322db522d3aSSimon L. B. Nielsen BIO_printf(out, " Subject: "); 1323db522d3aSSimon L. B. Nielsen X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); 1324db522d3aSSimon L. B. Nielsen BIO_printf(out, "\n Issuer: "); 1325db522d3aSSimon L. B. Nielsen X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); 1326db522d3aSSimon L. B. Nielsen BIO_printf(out, "\n"); 1327db522d3aSSimon L. B. Nielsen } 1328db522d3aSSimon L. B. Nielsen if (flags & CAPI_DMP_FULL) 1329db522d3aSSimon L. B. Nielsen X509_print_ex(out, x, XN_FLAG_ONELINE, 0); 1330db522d3aSSimon L. B. Nielsen 13316f9291ceSJung-uk Kim if (flags & CAPI_DMP_PKEYINFO) { 1332db522d3aSSimon L. B. Nielsen CRYPT_KEY_PROV_INFO *pinfo; 1333db522d3aSSimon L. B. Nielsen pinfo = capi_get_prov_info(ctx, cert); 1334db522d3aSSimon L. B. Nielsen capi_dump_prov_info(ctx, out, pinfo); 1335db522d3aSSimon L. B. Nielsen if (pinfo) 1336db522d3aSSimon L. B. Nielsen OPENSSL_free(pinfo); 1337db522d3aSSimon L. B. Nielsen } 1338db522d3aSSimon L. B. Nielsen 1339db522d3aSSimon L. B. Nielsen if (flags & CAPI_DMP_PEM) 1340db522d3aSSimon L. B. Nielsen PEM_write_bio_X509(out, x); 1341db522d3aSSimon L. B. Nielsen X509_free(x); 1342db522d3aSSimon L. B. Nielsen } 1343db522d3aSSimon L. B. Nielsen 1344db522d3aSSimon L. B. Nielsen HCERTSTORE capi_open_store(CAPI_CTX * ctx, char *storename) 1345db522d3aSSimon L. B. Nielsen { 1346db522d3aSSimon L. B. Nielsen HCERTSTORE hstore; 1347db522d3aSSimon L. B. Nielsen 1348db522d3aSSimon L. B. Nielsen if (!storename) 1349db522d3aSSimon L. B. Nielsen storename = ctx->storename; 1350db522d3aSSimon L. B. Nielsen if (!storename) 1351db522d3aSSimon L. B. Nielsen storename = "MY"; 1352db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Opening certificate store %s\n", storename); 1353db522d3aSSimon L. B. Nielsen 1354db522d3aSSimon L. B. Nielsen hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, 1355db522d3aSSimon L. B. Nielsen ctx->store_flags, storename); 13566f9291ceSJung-uk Kim if (!hstore) { 1357db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE); 1358db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1359db522d3aSSimon L. B. Nielsen } 1360db522d3aSSimon L. B. Nielsen return hstore; 1361db522d3aSSimon L. B. Nielsen } 1362db522d3aSSimon L. B. Nielsen 1363db522d3aSSimon L. B. Nielsen int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *id) 1364db522d3aSSimon L. B. Nielsen { 1365db522d3aSSimon L. B. Nielsen char *storename; 1366db522d3aSSimon L. B. Nielsen int idx; 1367db522d3aSSimon L. B. Nielsen int ret = 1; 1368db522d3aSSimon L. B. Nielsen HCERTSTORE hstore; 1369db522d3aSSimon L. B. Nielsen PCCERT_CONTEXT cert = NULL; 1370db522d3aSSimon L. B. Nielsen 1371db522d3aSSimon L. B. Nielsen storename = ctx->storename; 1372db522d3aSSimon L. B. Nielsen if (!storename) 1373db522d3aSSimon L. B. Nielsen storename = "MY"; 1374db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Listing certs for store %s\n", storename); 1375db522d3aSSimon L. B. Nielsen 1376db522d3aSSimon L. B. Nielsen hstore = capi_open_store(ctx, storename); 1377db522d3aSSimon L. B. Nielsen if (!hstore) 1378db522d3aSSimon L. B. Nielsen return 0; 13796f9291ceSJung-uk Kim if (id) { 1380db522d3aSSimon L. B. Nielsen cert = capi_find_cert(ctx, id, hstore); 13816f9291ceSJung-uk Kim if (!cert) { 1382db522d3aSSimon L. B. Nielsen ret = 0; 1383db522d3aSSimon L. B. Nielsen goto err; 1384db522d3aSSimon L. B. Nielsen } 1385db522d3aSSimon L. B. Nielsen capi_dump_cert(ctx, out, cert); 1386db522d3aSSimon L. B. Nielsen CertFreeCertificateContext(cert); 13876f9291ceSJung-uk Kim } else { 13886f9291ceSJung-uk Kim for (idx = 0;; idx++) { 1389db522d3aSSimon L. B. Nielsen cert = CertEnumCertificatesInStore(hstore, cert); 1390db522d3aSSimon L. B. Nielsen if (!cert) 1391db522d3aSSimon L. B. Nielsen break; 1392db522d3aSSimon L. B. Nielsen BIO_printf(out, "Certificate %d\n", idx); 1393db522d3aSSimon L. B. Nielsen capi_dump_cert(ctx, out, cert); 1394db522d3aSSimon L. B. Nielsen } 1395db522d3aSSimon L. B. Nielsen } 1396db522d3aSSimon L. B. Nielsen err: 1397db522d3aSSimon L. B. Nielsen CertCloseStore(hstore, 0); 1398db522d3aSSimon L. B. Nielsen return ret; 1399db522d3aSSimon L. B. Nielsen } 1400db522d3aSSimon L. B. Nielsen 14016f9291ceSJung-uk Kim static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id, 14026f9291ceSJung-uk Kim HCERTSTORE hstore) 1403db522d3aSSimon L. B. Nielsen { 1404db522d3aSSimon L. B. Nielsen PCCERT_CONTEXT cert = NULL; 1405db522d3aSSimon L. B. Nielsen char *fname = NULL; 1406db522d3aSSimon L. B. Nielsen int match; 14076f9291ceSJung-uk Kim switch (ctx->lookup_method) { 1408db522d3aSSimon L. B. Nielsen case CAPI_LU_SUBSTR: 1409db522d3aSSimon L. B. Nielsen return CertFindCertificateInStore(hstore, 1410db522d3aSSimon L. B. Nielsen X509_ASN_ENCODING, 0, 1411db522d3aSSimon L. B. Nielsen CERT_FIND_SUBJECT_STR_A, id, NULL); 1412db522d3aSSimon L. B. Nielsen case CAPI_LU_FNAME: 14136f9291ceSJung-uk Kim for (;;) { 1414db522d3aSSimon L. B. Nielsen cert = CertEnumCertificatesInStore(hstore, cert); 1415db522d3aSSimon L. B. Nielsen if (!cert) 1416db522d3aSSimon L. B. Nielsen return NULL; 1417db522d3aSSimon L. B. Nielsen fname = capi_cert_get_fname(ctx, cert); 14186f9291ceSJung-uk Kim if (fname) { 1419db522d3aSSimon L. B. Nielsen if (strcmp(fname, id)) 1420db522d3aSSimon L. B. Nielsen match = 0; 1421db522d3aSSimon L. B. Nielsen else 1422db522d3aSSimon L. B. Nielsen match = 1; 1423db522d3aSSimon L. B. Nielsen OPENSSL_free(fname); 1424db522d3aSSimon L. B. Nielsen if (match) 1425db522d3aSSimon L. B. Nielsen return cert; 1426db522d3aSSimon L. B. Nielsen } 1427db522d3aSSimon L. B. Nielsen } 1428db522d3aSSimon L. B. Nielsen default: 1429db522d3aSSimon L. B. Nielsen return NULL; 1430db522d3aSSimon L. B. Nielsen } 1431db522d3aSSimon L. B. Nielsen } 1432db522d3aSSimon L. B. Nielsen 14337bded2dbSJung-uk Kim static CAPI_KEY *capi_get_key(CAPI_CTX * ctx, const TCHAR *contname, 14347bded2dbSJung-uk Kim TCHAR *provname, DWORD ptype, DWORD keyspec) 1435db522d3aSSimon L. B. Nielsen { 1436db522d3aSSimon L. B. Nielsen CAPI_KEY *key; 143709286989SJung-uk Kim DWORD dwFlags = 0; 1438db522d3aSSimon L. B. Nielsen key = OPENSSL_malloc(sizeof(CAPI_KEY)); 14397bded2dbSJung-uk Kim if (sizeof(TCHAR) == sizeof(char)) 1440db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 1441db522d3aSSimon L. B. Nielsen contname, provname, ptype); 14427bded2dbSJung-uk Kim else if (ctx && ctx->debug_level >= CAPI_DBG_TRACE && ctx->debug_file) { 14437bded2dbSJung-uk Kim /* above 'if' is optimization to minimize malloc-ations */ 14447bded2dbSJung-uk Kim char *_contname = wide_to_asc((WCHAR *)contname); 14457bded2dbSJung-uk Kim char *_provname = wide_to_asc((WCHAR *)provname); 14467bded2dbSJung-uk Kim 14477bded2dbSJung-uk Kim CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 14487bded2dbSJung-uk Kim _contname, _provname, ptype); 14497bded2dbSJung-uk Kim if (_provname) 14507bded2dbSJung-uk Kim OPENSSL_free(_provname); 14517bded2dbSJung-uk Kim if (_contname) 14527bded2dbSJung-uk Kim OPENSSL_free(_contname); 14537bded2dbSJung-uk Kim } 145409286989SJung-uk Kim if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) 145509286989SJung-uk Kim dwFlags = CRYPT_MACHINE_KEYSET; 14567bded2dbSJung-uk Kim if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) { 1457db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); 1458db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1459db522d3aSSimon L. B. Nielsen goto err; 1460db522d3aSSimon L. B. Nielsen } 14616f9291ceSJung-uk Kim if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) { 1462db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR); 1463db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1464db522d3aSSimon L. B. Nielsen CryptReleaseContext(key->hprov, 0); 1465db522d3aSSimon L. B. Nielsen goto err; 1466db522d3aSSimon L. B. Nielsen } 1467db522d3aSSimon L. B. Nielsen key->keyspec = keyspec; 1468db522d3aSSimon L. B. Nielsen key->pcert = NULL; 1469db522d3aSSimon L. B. Nielsen return key; 1470db522d3aSSimon L. B. Nielsen 1471db522d3aSSimon L. B. Nielsen err: 1472db522d3aSSimon L. B. Nielsen OPENSSL_free(key); 1473db522d3aSSimon L. B. Nielsen return NULL; 1474db522d3aSSimon L. B. Nielsen } 1475db522d3aSSimon L. B. Nielsen 1476db522d3aSSimon L. B. Nielsen static CAPI_KEY *capi_get_cert_key(CAPI_CTX * ctx, PCCERT_CONTEXT cert) 1477db522d3aSSimon L. B. Nielsen { 1478db522d3aSSimon L. B. Nielsen CAPI_KEY *key = NULL; 1479db522d3aSSimon L. B. Nielsen CRYPT_KEY_PROV_INFO *pinfo = NULL; 1480db522d3aSSimon L. B. Nielsen char *provname = NULL, *contname = NULL; 1481db522d3aSSimon L. B. Nielsen pinfo = capi_get_prov_info(ctx, cert); 1482db522d3aSSimon L. B. Nielsen if (!pinfo) 1483db522d3aSSimon L. B. Nielsen goto err; 14847bded2dbSJung-uk Kim if (sizeof(TCHAR) != sizeof(char)) 14857bded2dbSJung-uk Kim key = capi_get_key(ctx, (TCHAR *)pinfo->pwszContainerName, 14867bded2dbSJung-uk Kim (TCHAR *)pinfo->pwszProvName, 14877bded2dbSJung-uk Kim pinfo->dwProvType, pinfo->dwKeySpec); 14887bded2dbSJung-uk Kim else { 1489db522d3aSSimon L. B. Nielsen provname = wide_to_asc(pinfo->pwszProvName); 1490db522d3aSSimon L. B. Nielsen contname = wide_to_asc(pinfo->pwszContainerName); 1491db522d3aSSimon L. B. Nielsen if (!provname || !contname) 1492db522d3aSSimon L. B. Nielsen goto err; 14937bded2dbSJung-uk Kim key = capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, 1494db522d3aSSimon L. B. Nielsen pinfo->dwProvType, pinfo->dwKeySpec); 14957bded2dbSJung-uk Kim } 1496db522d3aSSimon L. B. Nielsen 1497db522d3aSSimon L. B. Nielsen err: 1498db522d3aSSimon L. B. Nielsen if (pinfo) 1499db522d3aSSimon L. B. Nielsen OPENSSL_free(pinfo); 1500db522d3aSSimon L. B. Nielsen if (provname) 1501db522d3aSSimon L. B. Nielsen OPENSSL_free(provname); 1502db522d3aSSimon L. B. Nielsen if (contname) 1503db522d3aSSimon L. B. Nielsen OPENSSL_free(contname); 1504db522d3aSSimon L. B. Nielsen return key; 1505db522d3aSSimon L. B. Nielsen } 1506db522d3aSSimon L. B. Nielsen 1507db522d3aSSimon L. B. Nielsen CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id) 1508db522d3aSSimon L. B. Nielsen { 1509db522d3aSSimon L. B. Nielsen PCCERT_CONTEXT cert; 1510db522d3aSSimon L. B. Nielsen HCERTSTORE hstore; 1511db522d3aSSimon L. B. Nielsen CAPI_KEY *key = NULL; 15126f9291ceSJung-uk Kim switch (ctx->lookup_method) { 1513db522d3aSSimon L. B. Nielsen case CAPI_LU_SUBSTR: 1514db522d3aSSimon L. B. Nielsen case CAPI_LU_FNAME: 1515db522d3aSSimon L. B. Nielsen hstore = capi_open_store(ctx, NULL); 1516db522d3aSSimon L. B. Nielsen if (!hstore) 1517db522d3aSSimon L. B. Nielsen return NULL; 1518db522d3aSSimon L. B. Nielsen cert = capi_find_cert(ctx, id, hstore); 15196f9291ceSJung-uk Kim if (cert) { 1520db522d3aSSimon L. B. Nielsen key = capi_get_cert_key(ctx, cert); 1521db522d3aSSimon L. B. Nielsen CertFreeCertificateContext(cert); 1522db522d3aSSimon L. B. Nielsen } 1523db522d3aSSimon L. B. Nielsen CertCloseStore(hstore, 0); 1524db522d3aSSimon L. B. Nielsen break; 1525db522d3aSSimon L. B. Nielsen 1526db522d3aSSimon L. B. Nielsen case CAPI_LU_CONTNAME: 15277bded2dbSJung-uk Kim if (sizeof(TCHAR) != sizeof(char)) { 15287bded2dbSJung-uk Kim WCHAR *contname, *provname; 15297bded2dbSJung-uk Kim DWORD len; 15307bded2dbSJung-uk Kim 15317bded2dbSJung-uk Kim if ((len = MultiByteToWideChar(CP_ACP, 0, id, -1, NULL, 0)) && 15327bded2dbSJung-uk Kim (contname = alloca(len * sizeof(WCHAR)), 15337bded2dbSJung-uk Kim MultiByteToWideChar(CP_ACP, 0, id, -1, contname, len)) && 15347bded2dbSJung-uk Kim (len = 15357bded2dbSJung-uk Kim MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0)) 15367bded2dbSJung-uk Kim && (provname = 15377bded2dbSJung-uk Kim alloca(len * sizeof(WCHAR)), MultiByteToWideChar(CP_ACP, 15387bded2dbSJung-uk Kim 0, 15397bded2dbSJung-uk Kim ctx->cspname, 15407bded2dbSJung-uk Kim -1, 15417bded2dbSJung-uk Kim provname, 15427bded2dbSJung-uk Kim len))) 15437bded2dbSJung-uk Kim key = 15447bded2dbSJung-uk Kim capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, 15457bded2dbSJung-uk Kim ctx->csptype, ctx->keytype); 15467bded2dbSJung-uk Kim } else 15477bded2dbSJung-uk Kim key = capi_get_key(ctx, (TCHAR *)id, 15487bded2dbSJung-uk Kim (TCHAR *)ctx->cspname, 15497bded2dbSJung-uk Kim ctx->csptype, ctx->keytype); 1550db522d3aSSimon L. B. Nielsen break; 1551db522d3aSSimon L. B. Nielsen } 1552db522d3aSSimon L. B. Nielsen 1553db522d3aSSimon L. B. Nielsen return key; 1554db522d3aSSimon L. B. Nielsen } 1555db522d3aSSimon L. B. Nielsen 1556db522d3aSSimon L. B. Nielsen void capi_free_key(CAPI_KEY * key) 1557db522d3aSSimon L. B. Nielsen { 1558db522d3aSSimon L. B. Nielsen if (!key) 1559db522d3aSSimon L. B. Nielsen return; 1560db522d3aSSimon L. B. Nielsen CryptDestroyKey(key->key); 1561db522d3aSSimon L. B. Nielsen CryptReleaseContext(key->hprov, 0); 1562db522d3aSSimon L. B. Nielsen if (key->pcert) 1563db522d3aSSimon L. B. Nielsen CertFreeCertificateContext(key->pcert); 1564db522d3aSSimon L. B. Nielsen OPENSSL_free(key); 1565db522d3aSSimon L. B. Nielsen } 1566db522d3aSSimon L. B. Nielsen 1567db522d3aSSimon L. B. Nielsen /* Initialize a CAPI_CTX structure */ 1568db522d3aSSimon L. B. Nielsen 1569db522d3aSSimon L. B. Nielsen static CAPI_CTX *capi_ctx_new() 1570db522d3aSSimon L. B. Nielsen { 1571db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 1572db522d3aSSimon L. B. Nielsen ctx = OPENSSL_malloc(sizeof(CAPI_CTX)); 15736f9291ceSJung-uk Kim if (!ctx) { 1574db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE); 1575db522d3aSSimon L. B. Nielsen return NULL; 1576db522d3aSSimon L. B. Nielsen } 1577db522d3aSSimon L. B. Nielsen ctx->cspname = NULL; 1578db522d3aSSimon L. B. Nielsen ctx->csptype = PROV_RSA_FULL; 1579db522d3aSSimon L. B. Nielsen ctx->dump_flags = CAPI_DMP_SUMMARY | CAPI_DMP_FNAME; 1580db522d3aSSimon L. B. Nielsen ctx->keytype = AT_KEYEXCHANGE; 1581db522d3aSSimon L. B. Nielsen ctx->storename = NULL; 1582db522d3aSSimon L. B. Nielsen ctx->ssl_client_store = NULL; 1583db522d3aSSimon L. B. Nielsen ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG | 15846f9291ceSJung-uk Kim CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER; 1585db522d3aSSimon L. B. Nielsen ctx->lookup_method = CAPI_LU_SUBSTR; 1586db522d3aSSimon L. B. Nielsen ctx->debug_level = 0; 1587db522d3aSSimon L. B. Nielsen ctx->debug_file = NULL; 1588db522d3aSSimon L. B. Nielsen ctx->client_cert_select = cert_select_simple; 1589db522d3aSSimon L. B. Nielsen return ctx; 1590db522d3aSSimon L. B. Nielsen } 1591db522d3aSSimon L. B. Nielsen 1592db522d3aSSimon L. B. Nielsen static void capi_ctx_free(CAPI_CTX * ctx) 1593db522d3aSSimon L. B. Nielsen { 1594db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx); 1595db522d3aSSimon L. B. Nielsen if (!ctx) 1596db522d3aSSimon L. B. Nielsen return; 1597db522d3aSSimon L. B. Nielsen if (ctx->cspname) 1598db522d3aSSimon L. B. Nielsen OPENSSL_free(ctx->cspname); 1599db522d3aSSimon L. B. Nielsen if (ctx->debug_file) 1600db522d3aSSimon L. B. Nielsen OPENSSL_free(ctx->debug_file); 1601db522d3aSSimon L. B. Nielsen if (ctx->storename) 1602db522d3aSSimon L. B. Nielsen OPENSSL_free(ctx->storename); 1603db522d3aSSimon L. B. Nielsen if (ctx->ssl_client_store) 1604db522d3aSSimon L. B. Nielsen OPENSSL_free(ctx->ssl_client_store); 1605db522d3aSSimon L. B. Nielsen OPENSSL_free(ctx); 1606db522d3aSSimon L. B. Nielsen } 1607db522d3aSSimon L. B. Nielsen 16086f9291ceSJung-uk Kim static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type, 16096f9291ceSJung-uk Kim int check) 1610db522d3aSSimon L. B. Nielsen { 1611db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type); 16126f9291ceSJung-uk Kim if (check) { 1613db522d3aSSimon L. B. Nielsen HCRYPTPROV hprov; 16147bded2dbSJung-uk Kim LPTSTR name = NULL; 16157bded2dbSJung-uk Kim 16167bded2dbSJung-uk Kim if (sizeof(TCHAR) != sizeof(char)) { 16177bded2dbSJung-uk Kim DWORD len; 16187bded2dbSJung-uk Kim if ((len = MultiByteToWideChar(CP_ACP, 0, pname, -1, NULL, 0))) { 16197bded2dbSJung-uk Kim name = alloca(len * sizeof(WCHAR)); 16207bded2dbSJung-uk Kim MultiByteToWideChar(CP_ACP, 0, pname, -1, (WCHAR *)name, len); 16217bded2dbSJung-uk Kim } 16227bded2dbSJung-uk Kim } else 16237bded2dbSJung-uk Kim name = (TCHAR *)pname; 16247bded2dbSJung-uk Kim 16257bded2dbSJung-uk Kim if (!name || !CryptAcquireContext(&hprov, NULL, name, type, 16266f9291ceSJung-uk Kim CRYPT_VERIFYCONTEXT)) { 16276f9291ceSJung-uk Kim CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, 16286f9291ceSJung-uk Kim CAPI_R_CRYPTACQUIRECONTEXT_ERROR); 1629db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1630db522d3aSSimon L. B. Nielsen return 0; 1631db522d3aSSimon L. B. Nielsen } 1632db522d3aSSimon L. B. Nielsen CryptReleaseContext(hprov, 0); 1633db522d3aSSimon L. B. Nielsen } 163412de4ed2SJung-uk Kim if (ctx->cspname) 163512de4ed2SJung-uk Kim OPENSSL_free(ctx->cspname); 1636db522d3aSSimon L. B. Nielsen ctx->cspname = BUF_strdup(pname); 1637db522d3aSSimon L. B. Nielsen ctx->csptype = type; 1638db522d3aSSimon L. B. Nielsen return 1; 1639db522d3aSSimon L. B. Nielsen } 1640db522d3aSSimon L. B. Nielsen 1641db522d3aSSimon L. B. Nielsen static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx) 1642db522d3aSSimon L. B. Nielsen { 1643db522d3aSSimon L. B. Nielsen LPSTR pname; 1644db522d3aSSimon L. B. Nielsen DWORD type; 164512de4ed2SJung-uk Kim int res; 1646db522d3aSSimon L. B. Nielsen if (capi_get_provname(ctx, &pname, &type, idx) != 1) 1647db522d3aSSimon L. B. Nielsen return 0; 164812de4ed2SJung-uk Kim res = capi_ctx_set_provname(ctx, pname, type, 0); 164912de4ed2SJung-uk Kim OPENSSL_free(pname); 165012de4ed2SJung-uk Kim return res; 1651db522d3aSSimon L. B. Nielsen } 1652db522d3aSSimon L. B. Nielsen 1653db522d3aSSimon L. B. Nielsen static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) 1654db522d3aSSimon L. B. Nielsen { 1655db522d3aSSimon L. B. Nielsen int i; 1656db522d3aSSimon L. B. Nielsen X509_NAME *nm; 1657db522d3aSSimon L. B. Nielsen /* Special case: empty list: match anything */ 1658db522d3aSSimon L. B. Nielsen if (sk_X509_NAME_num(ca_dn) <= 0) 1659db522d3aSSimon L. B. Nielsen return 1; 16606f9291ceSJung-uk Kim for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) { 1661db522d3aSSimon L. B. Nielsen nm = sk_X509_NAME_value(ca_dn, i); 1662db522d3aSSimon L. B. Nielsen if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) 1663db522d3aSSimon L. B. Nielsen return 1; 1664db522d3aSSimon L. B. Nielsen } 1665db522d3aSSimon L. B. Nielsen return 0; 1666db522d3aSSimon L. B. Nielsen } 1667db522d3aSSimon L. B. Nielsen 1668db522d3aSSimon L. B. Nielsen static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, 16696f9291ceSJung-uk Kim STACK_OF(X509_NAME) *ca_dn, X509 **pcert, 16706f9291ceSJung-uk Kim EVP_PKEY **pkey, STACK_OF(X509) **pother, 16716f9291ceSJung-uk Kim UI_METHOD *ui_method, 16726f9291ceSJung-uk Kim void *callback_data) 1673db522d3aSSimon L. B. Nielsen { 1674db522d3aSSimon L. B. Nielsen STACK_OF(X509) *certs = NULL; 1675db522d3aSSimon L. B. Nielsen X509 *x; 1676db522d3aSSimon L. B. Nielsen char *storename; 1677db522d3aSSimon L. B. Nielsen const char *p; 1678db522d3aSSimon L. B. Nielsen int i, client_cert_idx; 1679db522d3aSSimon L. B. Nielsen HCERTSTORE hstore; 1680db522d3aSSimon L. B. Nielsen PCCERT_CONTEXT cert = NULL, excert = NULL; 1681db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 1682db522d3aSSimon L. B. Nielsen CAPI_KEY *key; 1683db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(e, capi_idx); 1684db522d3aSSimon L. B. Nielsen 1685db522d3aSSimon L. B. Nielsen *pcert = NULL; 1686db522d3aSSimon L. B. Nielsen *pkey = NULL; 1687db522d3aSSimon L. B. Nielsen 1688db522d3aSSimon L. B. Nielsen storename = ctx->ssl_client_store; 1689db522d3aSSimon L. B. Nielsen if (!storename) 1690db522d3aSSimon L. B. Nielsen storename = "MY"; 1691db522d3aSSimon L. B. Nielsen 1692db522d3aSSimon L. B. Nielsen hstore = capi_open_store(ctx, storename); 1693db522d3aSSimon L. B. Nielsen if (!hstore) 1694db522d3aSSimon L. B. Nielsen return 0; 1695db522d3aSSimon L. B. Nielsen /* Enumerate all certificates collect any matches */ 16966f9291ceSJung-uk Kim for (i = 0;; i++) { 1697db522d3aSSimon L. B. Nielsen cert = CertEnumCertificatesInStore(hstore, cert); 1698db522d3aSSimon L. B. Nielsen if (!cert) 1699db522d3aSSimon L. B. Nielsen break; 1700db522d3aSSimon L. B. Nielsen p = cert->pbCertEncoded; 1701db522d3aSSimon L. B. Nielsen x = d2i_X509(NULL, &p, cert->cbCertEncoded); 17026f9291ceSJung-uk Kim if (!x) { 1703db522d3aSSimon L. B. Nielsen CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); 1704db522d3aSSimon L. B. Nielsen continue; 1705db522d3aSSimon L. B. Nielsen } 1706db522d3aSSimon L. B. Nielsen if (cert_issuer_match(ca_dn, x) 17076f9291ceSJung-uk Kim && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0)) { 1708db522d3aSSimon L. B. Nielsen key = capi_get_cert_key(ctx, cert); 17096f9291ceSJung-uk Kim if (!key) { 1710db522d3aSSimon L. B. Nielsen X509_free(x); 1711db522d3aSSimon L. B. Nielsen continue; 1712db522d3aSSimon L. B. Nielsen } 17136f9291ceSJung-uk Kim /* 17146f9291ceSJung-uk Kim * Match found: attach extra data to it so we can retrieve the 17156f9291ceSJung-uk Kim * key later. 1716db522d3aSSimon L. B. Nielsen */ 1717db522d3aSSimon L. B. Nielsen excert = CertDuplicateCertificateContext(cert); 1718db522d3aSSimon L. B. Nielsen key->pcert = excert; 1719db522d3aSSimon L. B. Nielsen X509_set_ex_data(x, cert_capi_idx, key); 1720db522d3aSSimon L. B. Nielsen 1721db522d3aSSimon L. B. Nielsen if (!certs) 1722db522d3aSSimon L. B. Nielsen certs = sk_X509_new_null(); 1723db522d3aSSimon L. B. Nielsen 1724db522d3aSSimon L. B. Nielsen sk_X509_push(certs, x); 17256f9291ceSJung-uk Kim } else 1726db522d3aSSimon L. B. Nielsen X509_free(x); 1727db522d3aSSimon L. B. Nielsen 1728db522d3aSSimon L. B. Nielsen } 1729db522d3aSSimon L. B. Nielsen 1730db522d3aSSimon L. B. Nielsen if (cert) 1731db522d3aSSimon L. B. Nielsen CertFreeCertificateContext(cert); 1732db522d3aSSimon L. B. Nielsen if (hstore) 1733db522d3aSSimon L. B. Nielsen CertCloseStore(hstore, 0); 1734db522d3aSSimon L. B. Nielsen 1735db522d3aSSimon L. B. Nielsen if (!certs) 1736db522d3aSSimon L. B. Nielsen return 0; 1737db522d3aSSimon L. B. Nielsen 1738db522d3aSSimon L. B. Nielsen /* Select the appropriate certificate */ 1739db522d3aSSimon L. B. Nielsen 1740db522d3aSSimon L. B. Nielsen client_cert_idx = ctx->client_cert_select(e, ssl, certs); 1741db522d3aSSimon L. B. Nielsen 1742db522d3aSSimon L. B. Nielsen /* Set the selected certificate and free the rest */ 1743db522d3aSSimon L. B. Nielsen 17446f9291ceSJung-uk Kim for (i = 0; i < sk_X509_num(certs); i++) { 1745db522d3aSSimon L. B. Nielsen x = sk_X509_value(certs, i); 1746db522d3aSSimon L. B. Nielsen if (i == client_cert_idx) 1747db522d3aSSimon L. B. Nielsen *pcert = x; 17486f9291ceSJung-uk Kim else { 1749db522d3aSSimon L. B. Nielsen key = X509_get_ex_data(x, cert_capi_idx); 1750db522d3aSSimon L. B. Nielsen capi_free_key(key); 1751db522d3aSSimon L. B. Nielsen X509_free(x); 1752db522d3aSSimon L. B. Nielsen } 1753db522d3aSSimon L. B. Nielsen } 1754db522d3aSSimon L. B. Nielsen 1755db522d3aSSimon L. B. Nielsen sk_X509_free(certs); 1756db522d3aSSimon L. B. Nielsen 1757db522d3aSSimon L. B. Nielsen if (!*pcert) 1758db522d3aSSimon L. B. Nielsen return 0; 1759db522d3aSSimon L. B. Nielsen 1760db522d3aSSimon L. B. Nielsen /* Setup key for selected certificate */ 1761db522d3aSSimon L. B. Nielsen 1762db522d3aSSimon L. B. Nielsen key = X509_get_ex_data(*pcert, cert_capi_idx); 1763db522d3aSSimon L. B. Nielsen *pkey = capi_get_pkey(e, key); 1764db522d3aSSimon L. B. Nielsen X509_set_ex_data(*pcert, cert_capi_idx, NULL); 1765db522d3aSSimon L. B. Nielsen 1766db522d3aSSimon L. B. Nielsen return 1; 1767db522d3aSSimon L. B. Nielsen 1768db522d3aSSimon L. B. Nielsen } 1769db522d3aSSimon L. B. Nielsen 1770db522d3aSSimon L. B. Nielsen /* Simple client cert selection function: always select first */ 1771db522d3aSSimon L. B. Nielsen 1772db522d3aSSimon L. B. Nielsen static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) 1773db522d3aSSimon L. B. Nielsen { 1774db522d3aSSimon L. B. Nielsen return 0; 1775db522d3aSSimon L. B. Nielsen } 1776db522d3aSSimon L. B. Nielsen 1777db522d3aSSimon L. B. Nielsen # ifdef OPENSSL_CAPIENG_DIALOG 1778db522d3aSSimon L. B. Nielsen 17796f9291ceSJung-uk Kim /* 17806f9291ceSJung-uk Kim * More complex cert selection function, using standard function 1781db522d3aSSimon L. B. Nielsen * CryptUIDlgSelectCertificateFromStore() to produce a dialog box. 1782db522d3aSSimon L. B. Nielsen */ 1783db522d3aSSimon L. B. Nielsen 17846f9291ceSJung-uk Kim /* 17856f9291ceSJung-uk Kim * Definitions which are in cryptuiapi.h but this is not present in older 1786db522d3aSSimon L. B. Nielsen * versions of headers. 1787db522d3aSSimon L. B. Nielsen */ 1788db522d3aSSimon L. B. Nielsen 1789db522d3aSSimon L. B. Nielsen # ifndef CRYPTUI_SELECT_LOCATION_COLUMN 1790db522d3aSSimon L. B. Nielsen # define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010 1791db522d3aSSimon L. B. Nielsen # define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004 1792db522d3aSSimon L. B. Nielsen # endif 1793db522d3aSSimon L. B. Nielsen 1794db522d3aSSimon L. B. Nielsen # define dlg_title L"OpenSSL Application SSL Client Certificate Selection" 1795db522d3aSSimon L. B. Nielsen # define dlg_prompt L"Select a certificate to use for authentication" 1796db522d3aSSimon L. B. Nielsen # define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \ 1797db522d3aSSimon L. B. Nielsen |CRYPTUI_SELECT_INTENDEDUSE_COLUMN 1798db522d3aSSimon L. B. Nielsen 1799db522d3aSSimon L. B. Nielsen static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) 1800db522d3aSSimon L. B. Nielsen { 1801db522d3aSSimon L. B. Nielsen X509 *x; 1802db522d3aSSimon L. B. Nielsen HCERTSTORE dstore; 1803db522d3aSSimon L. B. Nielsen PCCERT_CONTEXT cert; 1804db522d3aSSimon L. B. Nielsen CAPI_CTX *ctx; 1805db522d3aSSimon L. B. Nielsen CAPI_KEY *key; 1806db522d3aSSimon L. B. Nielsen HWND hwnd; 1807db522d3aSSimon L. B. Nielsen int i, idx = -1; 1808db522d3aSSimon L. B. Nielsen if (sk_X509_num(certs) == 1) 1809db522d3aSSimon L. B. Nielsen return 0; 1810db522d3aSSimon L. B. Nielsen ctx = ENGINE_get_ex_data(e, capi_idx); 1811db522d3aSSimon L. B. Nielsen /* Create an in memory store of certificates */ 1812db522d3aSSimon L. B. Nielsen dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 1813db522d3aSSimon L. B. Nielsen CERT_STORE_CREATE_NEW_FLAG, NULL); 18146f9291ceSJung-uk Kim if (!dstore) { 1815db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE); 1816db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1817db522d3aSSimon L. B. Nielsen goto err; 1818db522d3aSSimon L. B. Nielsen } 1819db522d3aSSimon L. B. Nielsen /* Add all certificates to store */ 18206f9291ceSJung-uk Kim for (i = 0; i < sk_X509_num(certs); i++) { 1821db522d3aSSimon L. B. Nielsen x = sk_X509_value(certs, i); 1822db522d3aSSimon L. B. Nielsen key = X509_get_ex_data(x, cert_capi_idx); 1823db522d3aSSimon L. B. Nielsen 1824db522d3aSSimon L. B. Nielsen if (!CertAddCertificateContextToStore(dstore, key->pcert, 18256f9291ceSJung-uk Kim CERT_STORE_ADD_NEW, NULL)) { 1826db522d3aSSimon L. B. Nielsen CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT); 1827db522d3aSSimon L. B. Nielsen capi_addlasterror(); 1828db522d3aSSimon L. B. Nielsen goto err; 1829db522d3aSSimon L. B. Nielsen } 1830db522d3aSSimon L. B. Nielsen 1831db522d3aSSimon L. B. Nielsen } 1832db522d3aSSimon L. B. Nielsen hwnd = GetForegroundWindow(); 1833db522d3aSSimon L. B. Nielsen if (!hwnd) 1834db522d3aSSimon L. B. Nielsen hwnd = GetActiveWindow(); 1835db522d3aSSimon L. B. Nielsen if (!hwnd && ctx->getconswindow) 1836db522d3aSSimon L. B. Nielsen hwnd = ctx->getconswindow(); 1837db522d3aSSimon L. B. Nielsen /* Call dialog to select one */ 1838db522d3aSSimon L. B. Nielsen cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt, 1839db522d3aSSimon L. B. Nielsen dlg_columns, 0, NULL); 1840db522d3aSSimon L. B. Nielsen 1841db522d3aSSimon L. B. Nielsen /* Find matching cert from list */ 18426f9291ceSJung-uk Kim if (cert) { 18436f9291ceSJung-uk Kim for (i = 0; i < sk_X509_num(certs); i++) { 1844db522d3aSSimon L. B. Nielsen x = sk_X509_value(certs, i); 1845db522d3aSSimon L. B. Nielsen key = X509_get_ex_data(x, cert_capi_idx); 18466f9291ceSJung-uk Kim if (CertCompareCertificate 18476f9291ceSJung-uk Kim (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, 18486f9291ceSJung-uk Kim key->pcert->pCertInfo)) { 1849db522d3aSSimon L. B. Nielsen idx = i; 1850db522d3aSSimon L. B. Nielsen break; 1851db522d3aSSimon L. B. Nielsen } 1852db522d3aSSimon L. B. Nielsen } 1853db522d3aSSimon L. B. Nielsen } 1854db522d3aSSimon L. B. Nielsen 1855db522d3aSSimon L. B. Nielsen err: 1856db522d3aSSimon L. B. Nielsen if (dstore) 1857db522d3aSSimon L. B. Nielsen CertCloseStore(dstore, 0); 1858db522d3aSSimon L. B. Nielsen return idx; 1859db522d3aSSimon L. B. Nielsen 1860db522d3aSSimon L. B. Nielsen } 1861db522d3aSSimon L. B. Nielsen # endif 1862db522d3aSSimon L. B. Nielsen 18631f13597dSJung-uk Kim #else /* !__COMPILE_CAPIENG */ 1864db522d3aSSimon L. B. Nielsen # include <openssl/engine.h> 1865db522d3aSSimon L. B. Nielsen # ifndef OPENSSL_NO_DYNAMIC_ENGINE 1866db522d3aSSimon L. B. Nielsen OPENSSL_EXPORT 18671f13597dSJung-uk Kim int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); 18681f13597dSJung-uk Kim OPENSSL_EXPORT 18696f9291ceSJung-uk Kim int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) 18706f9291ceSJung-uk Kim { 18716f9291ceSJung-uk Kim return 0; 18726f9291ceSJung-uk Kim } 18736f9291ceSJung-uk Kim 1874db522d3aSSimon L. B. Nielsen IMPLEMENT_DYNAMIC_CHECK_FN() 18751f13597dSJung-uk Kim # else 18766f9291ceSJung-uk Kim void ENGINE_load_capi(void) 18776f9291ceSJung-uk Kim { 18786f9291ceSJung-uk Kim } 1879db522d3aSSimon L. B. Nielsen # endif 1880db522d3aSSimon L. B. Nielsen #endif 1881