Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Openssl
提交
7a18ecb2
T
Third Party Openssl
项目概览
OpenHarmony
/
Third Party Openssl
10 个月 前同步成功
通知
8
Star
18
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Openssl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7a18ecb2
编写于
5月 31, 2008
作者:
D
Dr. Stephen Henson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add CryptoAPI ENGINE from stable branch.
上级
174c86a2
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
1554 addition
and
4 deletion
+1554
-4
engines/Makefile
engines/Makefile
+7
-4
engines/e_capi.c
engines/e_capi.c
+1428
-0
engines/e_capi.ec
engines/e_capi.ec
+1
-0
engines/e_capi_err.h
engines/e_capi_err.h
+118
-0
未找到文件。
engines/Makefile
浏览文件 @
7a18ecb2
...
@@ -26,7 +26,7 @@ TEST=
...
@@ -26,7 +26,7 @@ TEST=
APPS
=
APPS
=
LIB
=
$(TOP)
/libcrypto.a
LIB
=
$(TOP)
/libcrypto.a
LIBNAMES
=
4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock
LIBNAMES
=
4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock
capi
LIBSRC
=
e_4758cca.c
\
LIBSRC
=
e_4758cca.c
\
e_aep.c
\
e_aep.c
\
...
@@ -37,7 +37,8 @@ LIBSRC= e_4758cca.c \
...
@@ -37,7 +37,8 @@ LIBSRC= e_4758cca.c \
e_nuron.c
\
e_nuron.c
\
e_sureware.c
\
e_sureware.c
\
e_ubsec.c
\
e_ubsec.c
\
e_padlock.c
e_padlock.c
\
e_capi.c
LIBOBJ
=
e_4758cca.o
\
LIBOBJ
=
e_4758cca.o
\
e_aep.o
\
e_aep.o
\
e_atalla.o
\
e_atalla.o
\
...
@@ -47,7 +48,8 @@ LIBOBJ= e_4758cca.o \
...
@@ -47,7 +48,8 @@ LIBOBJ= e_4758cca.o \
e_nuron.o
\
e_nuron.o
\
e_sureware.o
\
e_sureware.o
\
e_ubsec.o
\
e_ubsec.o
\
e_padlock.o
e_padlock.o
\
e_capi.o
SRC
=
$(LIBSRC)
SRC
=
$(LIBSRC)
...
@@ -60,7 +62,8 @@ HEADER= e_4758cca_err.c e_4758cca_err.h \
...
@@ -60,7 +62,8 @@ HEADER= e_4758cca_err.c e_4758cca_err.h \
e_chil_err.c e_chil_err.h
\
e_chil_err.c e_chil_err.h
\
e_nuron_err.c e_nuron_err.h
\
e_nuron_err.c e_nuron_err.h
\
e_sureware_err.c e_sureware_err.h
\
e_sureware_err.c e_sureware_err.h
\
e_ubsec_err.c e_ubsec_err.h
e_ubsec_err.c e_ubsec_err.h
\
e_capi_err.c e_capi_err.h
ALL
=
$(GENERAL)
$(SRC)
$(HEADER)
ALL
=
$(GENERAL)
$(SRC)
$(HEADER)
...
...
engines/e_capi.c
0 → 100644
浏览文件 @
7a18ecb2
/* engines/e_capi.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/engine.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#ifdef OPENSSL_SYS_WIN32
#ifndef OPENSSL_NO_CAPIENG
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x400
#endif
#include <windows.h>
#include <wincrypt.h>
#include "e_capi_err.h"
#include "e_capi_err.c"
static
const
char
*
engine_capi_id
=
"capi"
;
static
const
char
*
engine_capi_name
=
"CryptoAPI ENGINE"
;
typedef
struct
CAPI_CTX_st
CAPI_CTX
;
typedef
struct
CAPI_KEY_st
CAPI_KEY
;
static
void
capi_addlasterror
(
void
);
static
void
capi_adderror
(
DWORD
err
);
static
void
CAPI_trace
(
CAPI_CTX
*
ctx
,
char
*
format
,
...);
static
int
capi_list_providers
(
CAPI_CTX
*
ctx
,
BIO
*
out
);
static
int
capi_list_containers
(
CAPI_CTX
*
ctx
,
BIO
*
out
);
int
capi_list_certs
(
CAPI_CTX
*
ctx
,
BIO
*
out
,
char
*
storename
);
void
capi_free_key
(
CAPI_KEY
*
key
);
static
PCCERT_CONTEXT
capi_find_cert
(
CAPI_CTX
*
ctx
,
const
char
*
id
,
HCERTSTORE
hstore
);
CAPI_KEY
*
capi_find_key
(
CAPI_CTX
*
ctx
,
const
char
*
id
);
static
EVP_PKEY
*
capi_load_privkey
(
ENGINE
*
eng
,
const
char
*
key_id
,
UI_METHOD
*
ui_method
,
void
*
callback_data
);
static
int
capi_rsa_sign
(
int
dtype
,
const
unsigned
char
*
m
,
unsigned
int
m_len
,
unsigned
char
*
sigret
,
unsigned
int
*
siglen
,
const
RSA
*
rsa
);
static
int
capi_rsa_priv_enc
(
int
flen
,
const
unsigned
char
*
from
,
unsigned
char
*
to
,
RSA
*
rsa
,
int
padding
);
static
int
capi_rsa_priv_dec
(
int
flen
,
const
unsigned
char
*
from
,
unsigned
char
*
to
,
RSA
*
rsa
,
int
padding
);
static
int
capi_rsa_free
(
RSA
*
rsa
);
static
DSA_SIG
*
capi_dsa_do_sign
(
const
unsigned
char
*
digest
,
int
dlen
,
DSA
*
dsa
);
static
int
capi_dsa_free
(
DSA
*
dsa
);
/* This structure contains CAPI ENGINE specific data:
* it contains various global options and affects how
* other functions behave.
*/
#define CAPI_DBG_TRACE 2
#define CAPI_DBG_ERROR 1
struct
CAPI_CTX_st
{
int
debug_level
;
char
*
debug_file
;
/* Parameters to use for container lookup */
DWORD
keytype
;
LPTSTR
cspname
;
DWORD
csptype
;
/* Certificate store name to use */
LPTSTR
storename
;
/* Lookup string meanings in load_private_key */
/* Substring of subject: uses "storename" */
#define CAPI_LU_SUBSTR 0
/* Friendly name: uses storename */
#define CAPI_LU_FNAME 1
/* Container name: uses cspname, keytype */
#define CAPI_LU_CONTNAME 2
int
lookup_method
;
/* Info to dump with dumpcerts option */
/* Issuer and serial name strings */
#define CAPI_DMP_SUMMARY 0x1
/* Friendly name */
#define CAPI_DMP_FNAME 0x2
/* Full X509_print dump */
#define CAPI_DMP_FULL 0x4
/* Dump PEM format certificate */
#define CAPI_DMP_PEM 0x8
/* Dump pseudo key (if possible) */
#define CAPI_DMP_PSKEY 0x10
/* Dump key info (if possible) */
#define CAPI_DMP_PKEYINFO 0x20
DWORD
dump_flags
;
};
static
CAPI_CTX
*
capi_ctx_new
();
static
void
capi_ctx_free
(
CAPI_CTX
*
ctx
);
static
int
capi_ctx_set_provname
(
CAPI_CTX
*
ctx
,
LPSTR
pname
,
DWORD
type
,
int
check
);
static
int
capi_ctx_set_provname_idx
(
CAPI_CTX
*
ctx
,
int
idx
);
#define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE
#define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1)
#define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2)
#define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3)
#define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4)
#define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5)
#define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6)
#define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7)
#define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8)
#define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9)
#define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10)
#define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11)
static
const
ENGINE_CMD_DEFN
capi_cmd_defns
[]
=
{
{
CAPI_CMD_LIST_CERTS
,
"list_certs"
,
"List all certificates in store"
,
ENGINE_CMD_FLAG_NO_INPUT
},
{
CAPI_CMD_LOOKUP_CERT
,
"lookup_cert"
,
"Lookup and output certificates"
,
ENGINE_CMD_FLAG_STRING
},
{
CAPI_CMD_DEBUG_LEVEL
,
"debug_level"
,
"debug level (1=errors, 2=trace)"
,
ENGINE_CMD_FLAG_NUMERIC
},
{
CAPI_CMD_DEBUG_FILE
,
"debug_file"
,
"debugging filename)"
,
ENGINE_CMD_FLAG_STRING
},
{
CAPI_CMD_KEYTYPE
,
"key_type"
,
"Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE"
,
ENGINE_CMD_FLAG_NUMERIC
},
{
CAPI_CMD_LIST_CSPS
,
"list_csps"
,
"List all CSPs"
,
ENGINE_CMD_FLAG_NO_INPUT
},
{
CAPI_CMD_SET_CSP_IDX
,
"csp_idx"
,
"Set CSP by index"
,
ENGINE_CMD_FLAG_NUMERIC
},
{
CAPI_CMD_SET_CSP_NAME
,
"csp_name"
,
"Set CSP name, (default CSP used if not specified)"
,
ENGINE_CMD_FLAG_STRING
},
{
CAPI_CMD_SET_CSP_TYPE
,
"csp_type"
,
"Set CSP type, (default RSA_PROV_FULL)"
,
ENGINE_CMD_FLAG_NUMERIC
},
{
CAPI_CMD_LIST_CONTAINERS
,
"list_containers"
,
"list container names"
,
ENGINE_CMD_FLAG_NO_INPUT
},
{
CAPI_CMD_LIST_OPTIONS
,
"list_options"
,
"Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
"32=private key info)"
,
ENGINE_CMD_FLAG_NUMERIC
},
{
CAPI_CMD_LOOKUP_METHOD
,
"lookup_method"
,
"Set key lookup method (1=substring, 2=friendlyname, 3=container name)"
,
ENGINE_CMD_FLAG_NUMERIC
},
{
0
,
NULL
,
NULL
,
0
}
};
static
int
capi_idx
=
-
1
;
static
int
rsa_capi_idx
=
-
1
;
static
int
dsa_capi_idx
=
-
1
;
static
int
capi_ctrl
(
ENGINE
*
e
,
int
cmd
,
long
i
,
void
*
p
,
void
(
*
f
)(
void
))
{
int
ret
=
1
;
CAPI_CTX
*
ctx
;
BIO
*
out
;
if
(
capi_idx
==
-
1
)
{
CAPIerr
(
CAPI_F_CAPI_CTRL
,
CAPI_R_ENGINE_NOT_INITIALIZED
);
return
0
;
}
ctx
=
ENGINE_get_ex_data
(
e
,
capi_idx
);
out
=
BIO_new_fp
(
stdout
,
BIO_NOCLOSE
);
switch
(
cmd
)
{
case
CAPI_CMD_LIST_CSPS
:
ret
=
capi_list_providers
(
ctx
,
out
);
break
;
case
CAPI_CMD_LIST_CERTS
:
ret
=
capi_list_certs
(
ctx
,
out
,
NULL
);
break
;
case
CAPI_CMD_LOOKUP_CERT
:
ret
=
capi_list_certs
(
ctx
,
out
,
p
);
break
;
case
CAPI_CMD_LIST_CONTAINERS
:
ret
=
capi_list_containers
(
ctx
,
out
);
break
;
case
CAPI_CMD_DEBUG_LEVEL
:
ctx
->
debug_level
=
(
int
)
i
;
CAPI_trace
(
ctx
,
"Setting debug level to %d
\n
"
,
ctx
->
debug_level
);
break
;
case
CAPI_CMD_DEBUG_FILE
:
ctx
->
debug_file
=
BUF_strdup
(
p
);
CAPI_trace
(
ctx
,
"Setting debug file to %s
\n
"
,
ctx
->
debug_file
);
break
;
case
CAPI_CMD_KEYTYPE
:
ctx
->
keytype
=
i
;
CAPI_trace
(
ctx
,
"Setting key type to %d
\n
"
,
ctx
->
keytype
);
break
;
case
CAPI_CMD_SET_CSP_IDX
:
ret
=
capi_ctx_set_provname_idx
(
ctx
,
i
);
break
;
case
CAPI_CMD_LIST_OPTIONS
:
ctx
->
dump_flags
=
i
;
break
;
case
CAPI_CMD_LOOKUP_METHOD
:
if
(
i
<
1
||
i
>
3
)
{
CAPIerr
(
CAPI_F_CAPI_CTRL
,
CAPI_R_INVALID_LOOKUP_METHOD
);
return
0
;
}
ctx
->
lookup_method
=
i
;
break
;
case
CAPI_CMD_SET_CSP_NAME
:
ret
=
capi_ctx_set_provname
(
ctx
,
p
,
ctx
->
csptype
,
1
);
break
;
case
CAPI_CMD_SET_CSP_TYPE
:
ctx
->
csptype
=
i
;
break
;
default:
CAPIerr
(
CAPI_F_CAPI_CTRL
,
CAPI_R_UNKNOWN_COMMAND
);
ret
=
0
;
}
BIO_free
(
out
);
return
ret
;
}
static
RSA_METHOD
capi_rsa_method
=
{
"CryptoAPI RSA method"
,
0
,
/* pub_enc */
0
,
/* pub_dec */
capi_rsa_priv_enc
,
/* priv_enc */
capi_rsa_priv_dec
,
/* priv_dec */
0
,
/* rsa_mod_exp */
0
,
/* bn_mod_exp */
0
,
/* init */
capi_rsa_free
,
/* finish */
RSA_FLAG_SIGN_VER
,
/* flags */
NULL
,
/* app_data */
capi_rsa_sign
,
/* rsa_sign */
0
/* rsa_verify */
};
static
DSA_METHOD
capi_dsa_method
=
{
"CryptoAPI DSA method"
,
capi_dsa_do_sign
,
/* dsa_do_sign */
0
,
/* dsa_sign_setup */
0
,
/* dsa_do_verify */
0
,
/* dsa_mod_exp */
0
,
/* bn_mod_exp */
0
,
/* init */
capi_dsa_free
,
/* finish */
0
,
/* flags */
NULL
,
/* app_data */
0
,
/* dsa_paramgen */
0
/* dsa_keygen */
};
static
int
capi_init
(
ENGINE
*
e
)
{
CAPI_CTX
*
ctx
;
const
RSA_METHOD
*
ossl_rsa_meth
;
const
DSA_METHOD
*
ossl_dsa_meth
;
capi_idx
=
ENGINE_get_ex_new_index
(
0
,
NULL
,
NULL
,
NULL
,
0
);
ctx
=
capi_ctx_new
();
if
(
!
ctx
||
(
capi_idx
<
0
))
goto
memerr
;
ENGINE_set_ex_data
(
e
,
capi_idx
,
ctx
);
/* Setup RSA_METHOD */
rsa_capi_idx
=
RSA_get_ex_new_index
(
0
,
NULL
,
NULL
,
NULL
,
0
);
ossl_rsa_meth
=
RSA_PKCS1_SSLeay
();
capi_rsa_method
.
rsa_pub_enc
=
ossl_rsa_meth
->
rsa_pub_enc
;
capi_rsa_method
.
rsa_pub_dec
=
ossl_rsa_meth
->
rsa_pub_dec
;
capi_rsa_method
.
rsa_mod_exp
=
ossl_rsa_meth
->
rsa_mod_exp
;
capi_rsa_method
.
bn_mod_exp
=
ossl_rsa_meth
->
bn_mod_exp
;
/* Setup DSA Method */
dsa_capi_idx
=
DSA_get_ex_new_index
(
0
,
NULL
,
NULL
,
NULL
,
0
);
ossl_dsa_meth
=
DSA_OpenSSL
();
capi_dsa_method
.
dsa_do_verify
=
ossl_dsa_meth
->
dsa_do_verify
;
capi_dsa_method
.
dsa_mod_exp
=
ossl_dsa_meth
->
dsa_mod_exp
;
capi_dsa_method
.
bn_mod_exp
=
ossl_dsa_meth
->
bn_mod_exp
;
return
1
;
memerr:
CAPIerr
(
CAPI_F_CAPI_INIT
,
ERR_R_MALLOC_FAILURE
);
return
0
;
return
1
;
}
static
int
capi_destroy
(
ENGINE
*
e
)
{
ERR_unload_CAPI_strings
();
return
1
;
}
static
int
capi_finish
(
ENGINE
*
e
)
{
CAPI_CTX
*
ctx
;
ctx
=
ENGINE_get_ex_data
(
e
,
capi_idx
);
capi_ctx_free
(
ctx
);
ENGINE_set_ex_data
(
e
,
capi_idx
,
NULL
);
return
1
;
}
/* CryptoAPI key application data. This contains
* a handle to the private key container (for sign operations)
* and a handle to the key (for decrypt operations).
*/
struct
CAPI_KEY_st
{
HCRYPTPROV
hprov
;
HCRYPTKEY
key
;
};
static
int
bind_capi
(
ENGINE
*
e
)
{
if
(
!
ENGINE_set_id
(
e
,
engine_capi_id
)
||
!
ENGINE_set_name
(
e
,
engine_capi_name
)
||
!
ENGINE_set_init_function
(
e
,
capi_init
)
||
!
ENGINE_set_finish_function
(
e
,
capi_finish
)
||
!
ENGINE_set_destroy_function
(
e
,
capi_destroy
)
||
!
ENGINE_set_RSA
(
e
,
&
capi_rsa_method
)
||
!
ENGINE_set_DSA
(
e
,
&
capi_dsa_method
)
||
!
ENGINE_set_load_privkey_function
(
e
,
capi_load_privkey
)
||
!
ENGINE_set_cmd_defns
(
e
,
capi_cmd_defns
)
||
!
ENGINE_set_ctrl_function
(
e
,
capi_ctrl
))
return
0
;
ERR_load_CAPI_strings
();
return
1
;
}
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
static
int
bind_helper
(
ENGINE
*
e
,
const
char
*
id
)
{
if
(
id
&&
(
strcmp
(
id
,
engine_capi_id
)
!=
0
))
return
0
;
if
(
!
bind_capi
(
e
))
return
0
;
return
1
;
}
IMPLEMENT_DYNAMIC_CHECK_FN
()
IMPLEMENT_DYNAMIC_BIND_FN
(
bind_helper
)
#else
static
ENGINE
*
engine_capi
(
void
)
{
ENGINE
*
ret
=
ENGINE_new
();
if
(
!
ret
)
return
NULL
;
if
(
!
bind_capi
(
ret
))
{
ENGINE_free
(
ret
);
return
NULL
;
}
return
ret
;
}
void
ENGINE_load_capi
(
void
)
{
/* Copied from eng_[openssl|dyn].c */
ENGINE
*
toadd
=
engine_capi
();
if
(
!
toadd
)
return
;
ENGINE_add
(
toadd
);
ENGINE_free
(
toadd
);
ERR_clear_error
();
}
#endif
static
int
lend_tobn
(
BIGNUM
*
bn
,
unsigned
char
*
bin
,
int
binlen
)
{
int
i
;
/* Reverse buffer in place: since this is a keyblob structure
* that will be freed up after conversion anyway it doesn't
* matter if we change it.
*/
for
(
i
=
0
;
i
<
binlen
/
2
;
i
++
)
{
unsigned
char
c
;
c
=
bin
[
i
];
bin
[
i
]
=
bin
[
binlen
-
i
-
1
];
bin
[
binlen
-
i
-
1
]
=
c
;
}
if
(
!
BN_bin2bn
(
bin
,
binlen
,
bn
))
return
0
;
return
1
;
}
static
EVP_PKEY
*
capi_load_privkey
(
ENGINE
*
eng
,
const
char
*
key_id
,
UI_METHOD
*
ui_method
,
void
*
callback_data
)
{
EVP_PKEY
*
ret
=
NULL
;
CAPI_CTX
*
ctx
;
CAPI_KEY
*
key
;
unsigned
char
*
pubkey
=
NULL
;
DWORD
len
;
BLOBHEADER
*
bh
;
RSA
*
rkey
=
NULL
;
DSA
*
dkey
=
NULL
;
ctx
=
ENGINE_get_ex_data
(
eng
,
capi_idx
);
if
(
!
ctx
)
{
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_CANT_FIND_CAPI_CONTEXT
);
return
NULL
;
}
key
=
capi_find_key
(
ctx
,
key_id
);
if
(
!
key
)
return
NULL
;
len
=
0
;
if
(
!
CryptExportKey
(
key
->
key
,
0
,
PUBLICKEYBLOB
,
0
,
NULL
,
&
len
))
{
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR
);
capi_addlasterror
();
return
NULL
;
}
pubkey
=
OPENSSL_malloc
(
len
);
if
(
!
pubkey
)
goto
memerr
;
if
(
!
CryptExportKey
(
key
->
key
,
0
,
PUBLICKEYBLOB
,
0
,
pubkey
,
&
len
))
{
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_PUBKEY_EXPORT_ERROR
);
capi_addlasterror
();
goto
err
;
}
bh
=
(
BLOBHEADER
*
)
pubkey
;
if
(
bh
->
bType
!=
PUBLICKEYBLOB
)
{
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_INVALID_PUBLIC_KEY_BLOB
);
goto
err
;
}
if
(
bh
->
aiKeyAlg
==
CALG_RSA_SIGN
||
bh
->
aiKeyAlg
==
CALG_RSA_KEYX
)
{
RSAPUBKEY
*
rp
;
DWORD
rsa_modlen
;
unsigned
char
*
rsa_modulus
;
rp
=
(
RSAPUBKEY
*
)(
bh
+
1
);
if
(
rp
->
magic
!=
0x31415352
)
{
char
magstr
[
10
];
BIO_snprintf
(
magstr
,
10
,
"%lx"
,
rp
->
magic
);
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER
);
ERR_add_error_data
(
2
,
"magic=0x"
,
magstr
);
goto
err
;
}
rsa_modulus
=
(
unsigned
char
*
)(
rp
+
1
);
rkey
=
RSA_new_method
(
eng
);
if
(
!
rkey
)
goto
memerr
;
rkey
->
e
=
BN_new
();
rkey
->
n
=
BN_new
();
if
(
!
rkey
->
e
||
!
rkey
->
n
)
goto
memerr
;
if
(
!
BN_set_word
(
rkey
->
e
,
rp
->
pubexp
))
goto
memerr
;
rsa_modlen
=
rp
->
bitlen
/
8
;
if
(
!
lend_tobn
(
rkey
->
n
,
rsa_modulus
,
rsa_modlen
))
goto
memerr
;
RSA_set_ex_data
(
rkey
,
rsa_capi_idx
,
key
);
if
(
!
(
ret
=
EVP_PKEY_new
()))
goto
memerr
;
EVP_PKEY_assign_RSA
(
ret
,
rkey
);
rkey
=
NULL
;
}
else
if
(
bh
->
aiKeyAlg
==
CALG_DSS_SIGN
)
{
DSSPUBKEY
*
dp
;
DWORD
dsa_plen
;
unsigned
char
*
btmp
;
dp
=
(
DSSPUBKEY
*
)(
bh
+
1
);
if
(
dp
->
magic
!=
0x31535344
)
{
char
magstr
[
10
];
BIO_snprintf
(
magstr
,
10
,
"%lx"
,
dp
->
magic
);
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER
);
ERR_add_error_data
(
2
,
"magic=0x"
,
magstr
);
goto
err
;
}
dsa_plen
=
dp
->
bitlen
/
8
;
btmp
=
(
unsigned
char
*
)(
dp
+
1
);
dkey
=
DSA_new_method
(
eng
);
if
(
!
dkey
)
goto
memerr
;
dkey
->
p
=
BN_new
();
dkey
->
q
=
BN_new
();
dkey
->
g
=
BN_new
();
dkey
->
pub_key
=
BN_new
();
if
(
!
dkey
->
p
||
!
dkey
->
q
||
!
dkey
->
g
||
!
dkey
->
pub_key
)
goto
memerr
;
if
(
!
lend_tobn
(
dkey
->
p
,
btmp
,
dsa_plen
))
goto
memerr
;
btmp
+=
dsa_plen
;
if
(
!
lend_tobn
(
dkey
->
q
,
btmp
,
20
))
goto
memerr
;
btmp
+=
20
;
if
(
!
lend_tobn
(
dkey
->
g
,
btmp
,
dsa_plen
))
goto
memerr
;
btmp
+=
dsa_plen
;
if
(
!
lend_tobn
(
dkey
->
pub_key
,
btmp
,
dsa_plen
))
goto
memerr
;
btmp
+=
dsa_plen
;
DSA_set_ex_data
(
dkey
,
dsa_capi_idx
,
key
);
if
(
!
(
ret
=
EVP_PKEY_new
()))
goto
memerr
;
EVP_PKEY_assign_DSA
(
ret
,
dkey
);
dkey
=
NULL
;
}
else
{
char
algstr
[
10
];
BIO_snprintf
(
algstr
,
10
,
"%lx"
,
bh
->
aiKeyAlg
);
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM
);
ERR_add_error_data
(
2
,
"aiKeyAlg=0x"
,
algstr
);
goto
err
;
}
err:
if
(
pubkey
)
OPENSSL_free
(
pubkey
);
if
(
!
ret
)
{
if
(
rkey
)
RSA_free
(
rkey
);
if
(
dkey
)
DSA_free
(
dkey
);
if
(
key
)
capi_free_key
(
key
);
}
return
ret
;
memerr:
CAPIerr
(
CAPI_F_CAPI_LOAD_PRIVKEY
,
ERR_R_MALLOC_FAILURE
);
goto
err
;
}
/* CryptoAPI RSA operations */
int
capi_rsa_priv_enc
(
int
flen
,
const
unsigned
char
*
from
,
unsigned
char
*
to
,
RSA
*
rsa
,
int
padding
)
{
CAPIerr
(
CAPI_F_CAPI_RSA_PRIV_ENC
,
CAPI_R_FUNCTION_NOT_SUPPORTED
);
return
-
1
;
}
int
capi_rsa_sign
(
int
dtype
,
const
unsigned
char
*
m
,
unsigned
int
m_len
,
unsigned
char
*
sigret
,
unsigned
int
*
siglen
,
const
RSA
*
rsa
)
{
ALG_ID
alg
;
HCRYPTHASH
hash
;
DWORD
slen
;
unsigned
int
i
;
int
ret
=
-
1
;
CAPI_KEY
*
capi_key
;
CAPI_CTX
*
ctx
;
ctx
=
ENGINE_get_ex_data
(
rsa
->
engine
,
capi_idx
);
CAPI_trace
(
ctx
,
"Called CAPI_rsa_sign()
\n
"
);
capi_key
=
RSA_get_ex_data
(
rsa
,
rsa_capi_idx
);
if
(
!
capi_key
)
{
CAPIerr
(
CAPI_F_CAPI_RSA_SIGN
,
CAPI_R_CANT_GET_KEY
);
return
-
1
;
}
/* Convert the signature type to a CryptoAPI algorithm ID */
switch
(
dtype
)
{
case
NID_sha1
:
alg
=
CALG_SHA1
;
break
;
case
NID_md5
:
alg
=
CALG_MD5
;
break
;
case
NID_md5_sha1
:
alg
=
CALG_SSL3_SHAMD5
;
break
;
default:
{
char
algstr
[
10
];
BIO_snprintf
(
algstr
,
10
,
"%lx"
,
dtype
);
CAPIerr
(
CAPI_F_CAPI_RSA_SIGN
,
CAPI_R_UNSUPPORTED_ALGORITHM_NID
);
ERR_add_error_data
(
2
,
"NID=0x"
,
algstr
);
return
-
1
;
}
}
/* Create the hash object */
if
(
!
CryptCreateHash
(
capi_key
->
hprov
,
alg
,
0
,
0
,
&
hash
))
{
CAPIerr
(
CAPI_F_CAPI_RSA_SIGN
,
CAPI_R_CANT_CREATE_HASH_OBJECT
);
capi_addlasterror
();
return
-
1
;
}
/* Set the hash value to the value passed */
if
(
!
CryptSetHashParam
(
hash
,
HP_HASHVAL
,
(
unsigned
char
*
)
m
,
0
))
{
CAPIerr
(
CAPI_F_CAPI_RSA_SIGN
,
CAPI_R_CANT_SET_HASH_VALUE
);
capi_addlasterror
();
goto
err
;
}
/* Finally sign it */
slen
=
RSA_size
(
rsa
);
if
(
!
CryptSignHash
(
hash
,
AT_KEYEXCHANGE
,
NULL
,
0
,
sigret
,
&
slen
))
{
CAPIerr
(
CAPI_F_CAPI_RSA_SIGN
,
CAPI_R_ERROR_SIGNING_HASH
);
capi_addlasterror
();
goto
err
;
}
else
{
ret
=
1
;
/* Inplace byte reversal of signature */
for
(
i
=
0
;
i
<
slen
/
2
;
i
++
)
{
unsigned
char
c
;
c
=
sigret
[
i
];
sigret
[
i
]
=
sigret
[
slen
-
i
-
1
];
sigret
[
slen
-
i
-
1
]
=
c
;
}
*
siglen
=
slen
;
}
/* Now cleanup */
err:
CryptDestroyHash
(
hash
);
return
ret
;
}
int
capi_rsa_priv_dec
(
int
flen
,
const
unsigned
char
*
from
,
unsigned
char
*
to
,
RSA
*
rsa
,
int
padding
)
{
int
i
;
unsigned
char
*
tmpbuf
;
CAPI_KEY
*
capi_key
;
CAPI_CTX
*
ctx
;
ctx
=
ENGINE_get_ex_data
(
rsa
->
engine
,
capi_idx
);
CAPI_trace
(
ctx
,
"Called capi_rsa_priv_dec()
\n
"
);
capi_key
=
RSA_get_ex_data
(
rsa
,
rsa_capi_idx
);
if
(
!
capi_key
)
{
CAPIerr
(
CAPI_F_CAPI_RSA_PRIV_DEC
,
CAPI_R_CANT_GET_KEY
);
return
-
1
;
}
if
(
padding
!=
RSA_PKCS1_PADDING
)
{
char
errstr
[
10
];
BIO_snprintf
(
errstr
,
10
,
"%d"
,
padding
);
CAPIerr
(
CAPI_F_CAPI_RSA_PRIV_DEC
,
CAPI_R_UNSUPPORTED_PADDING
);
ERR_add_error_data
(
2
,
"padding="
,
errstr
);
return
-
1
;
}
/* Create temp reverse order version of input */
if
(
!
(
tmpbuf
=
OPENSSL_malloc
(
flen
))
)
{
CAPIerr
(
CAPI_F_CAPI_RSA_PRIV_DEC
,
ERR_R_MALLOC_FAILURE
);
return
-
1
;
}
for
(
i
=
0
;
i
<
flen
;
i
++
)
tmpbuf
[
flen
-
i
-
1
]
=
from
[
i
];
/* Finally decrypt it */
if
(
!
CryptDecrypt
(
capi_key
->
key
,
0
,
TRUE
,
0
,
tmpbuf
,
&
flen
))
{
CAPIerr
(
CAPI_F_CAPI_RSA_PRIV_DEC
,
CAPI_R_DECRYPT_ERROR
);
capi_addlasterror
();
OPENSSL_free
(
tmpbuf
);
return
-
1
;
}
else
memcpy
(
to
,
tmpbuf
,
flen
);
OPENSSL_free
(
tmpbuf
);
return
flen
;
}
static
int
capi_rsa_free
(
RSA
*
rsa
)
{
CAPI_KEY
*
capi_key
;
capi_key
=
RSA_get_ex_data
(
rsa
,
rsa_capi_idx
);
capi_free_key
(
capi_key
);
RSA_set_ex_data
(
rsa
,
rsa_capi_idx
,
0
);
return
1
;
}
/* CryptoAPI DSA operations */
static
DSA_SIG
*
capi_dsa_do_sign
(
const
unsigned
char
*
digest
,
int
dlen
,
DSA
*
dsa
)
{
HCRYPTHASH
hash
;
DWORD
slen
;
DSA_SIG
*
ret
=
NULL
;
CAPI_KEY
*
capi_key
;
CAPI_CTX
*
ctx
;
unsigned
char
csigbuf
[
40
];
ctx
=
ENGINE_get_ex_data
(
dsa
->
engine
,
capi_idx
);
CAPI_trace
(
ctx
,
"Called CAPI_dsa_do_sign()
\n
"
);
capi_key
=
DSA_get_ex_data
(
dsa
,
dsa_capi_idx
);
if
(
!
capi_key
)
{
CAPIerr
(
CAPI_F_CAPI_DSA_DO_SIGN
,
CAPI_R_CANT_GET_KEY
);
return
NULL
;
}
if
(
dlen
!=
20
)
{
CAPIerr
(
CAPI_F_CAPI_DSA_DO_SIGN
,
CAPI_R_INVALID_DIGEST_LENGTH
);
return
NULL
;
}
/* Create the hash object */
if
(
!
CryptCreateHash
(
capi_key
->
hprov
,
CALG_SHA1
,
0
,
0
,
&
hash
))
{
CAPIerr
(
CAPI_F_CAPI_DSA_DO_SIGN
,
CAPI_R_CANT_CREATE_HASH_OBJECT
);
capi_addlasterror
();
return
NULL
;
}
/* Set the hash value to the value passed */
if
(
!
CryptSetHashParam
(
hash
,
HP_HASHVAL
,
(
unsigned
char
*
)
digest
,
0
))
{
CAPIerr
(
CAPI_F_CAPI_DSA_DO_SIGN
,
CAPI_R_CANT_SET_HASH_VALUE
);
capi_addlasterror
();
goto
err
;
}
/* Finally sign it */
slen
=
sizeof
(
csigbuf
);
if
(
!
CryptSignHash
(
hash
,
AT_SIGNATURE
,
NULL
,
0
,
csigbuf
,
&
slen
))
{
CAPIerr
(
CAPI_F_CAPI_DSA_DO_SIGN
,
CAPI_R_ERROR_SIGNING_HASH
);
capi_addlasterror
();
goto
err
;
}
else
{
ret
=
DSA_SIG_new
();
if
(
!
ret
)
goto
err
;
ret
->
r
=
BN_new
();
ret
->
s
=
BN_new
();
if
(
!
ret
->
r
||
!
ret
->
s
)
goto
err
;
if
(
!
lend_tobn
(
ret
->
r
,
csigbuf
,
20
)
||
!
lend_tobn
(
ret
->
s
,
csigbuf
+
20
,
20
))
{
DSA_SIG_free
(
ret
);
ret
=
NULL
;
goto
err
;
}
}
/* Now cleanup */
err:
OPENSSL_cleanse
(
csigbuf
,
40
);
CryptDestroyHash
(
hash
);
return
ret
;
}
static
int
capi_dsa_free
(
DSA
*
dsa
)
{
CAPI_KEY
*
capi_key
;
capi_key
=
DSA_get_ex_data
(
dsa
,
dsa_capi_idx
);
capi_free_key
(
capi_key
);
DSA_set_ex_data
(
dsa
,
dsa_capi_idx
,
0
);
return
1
;
}
static
void
capi_vtrace
(
CAPI_CTX
*
ctx
,
int
level
,
char
*
format
,
va_list
argptr
)
{
BIO
*
out
;
if
(
!
ctx
||
(
ctx
->
debug_level
<
level
)
||
(
!
ctx
->
debug_file
))
return
;
out
=
BIO_new_file
(
ctx
->
debug_file
,
"a+"
);
BIO_vprintf
(
out
,
format
,
argptr
);
BIO_free
(
out
);
}
static
void
CAPI_trace
(
CAPI_CTX
*
ctx
,
char
*
format
,
...)
{
va_list
args
;
va_start
(
args
,
format
);
capi_vtrace
(
ctx
,
CAPI_DBG_TRACE
,
format
,
args
);
va_end
(
args
);
}
static
void
capi_addlasterror
(
void
)
{
capi_adderror
(
GetLastError
());
}
static
void
capi_adderror
(
DWORD
err
)
{
char
errstr
[
10
];
BIO_snprintf
(
errstr
,
10
,
"%lX"
,
err
);
ERR_add_error_data
(
2
,
"Error code= 0x"
,
errstr
);
}
static
char
*
wide_to_asc
(
LPWSTR
wstr
)
{
char
*
str
;
if
(
!
wstr
)
return
NULL
;
str
=
OPENSSL_malloc
(
wcslen
(
wstr
)
+
1
);
if
(
!
str
)
{
CAPIerr
(
CAPI_F_WIDE_TO_ASC
,
ERR_R_MALLOC_FAILURE
);
return
NULL
;
}
sprintf
(
str
,
"%S"
,
wstr
);
return
str
;
}
static
int
capi_get_provname
(
CAPI_CTX
*
ctx
,
LPSTR
*
pname
,
DWORD
*
ptype
,
DWORD
idx
)
{
LPSTR
name
;
DWORD
len
,
err
;
CAPI_trace
(
ctx
,
"capi_get_provname, index=%d
\n
"
,
idx
);
if
(
!
CryptEnumProviders
(
idx
,
NULL
,
0
,
ptype
,
NULL
,
&
len
))
{
err
=
GetLastError
();
if
(
err
==
ERROR_NO_MORE_ITEMS
)
return
2
;
CAPIerr
(
CAPI_F_CAPI_GET_PROVNAME
,
CAPI_R_CRYPTENUMPROVIDERS_ERROR
);
capi_adderror
(
err
);
return
0
;
}
name
=
OPENSSL_malloc
(
len
);
if
(
!
CryptEnumProviders
(
idx
,
NULL
,
0
,
ptype
,
name
,
&
len
))
{
err
=
GetLastError
();
if
(
err
==
ERROR_NO_MORE_ITEMS
)
return
2
;
CAPIerr
(
CAPI_F_CAPI_GET_PROVNAME
,
CAPI_R_CRYPTENUMPROVIDERS_ERROR
);
capi_adderror
(
err
);
return
0
;
}
*
pname
=
name
;
CAPI_trace
(
ctx
,
"capi_get_provname, returned name=%s, type=%d
\n
"
,
name
,
*
ptype
);
return
1
;
}
static
int
capi_list_providers
(
CAPI_CTX
*
ctx
,
BIO
*
out
)
{
DWORD
idx
,
ptype
;
int
ret
;
LPTSTR
provname
=
NULL
;
CAPI_trace
(
ctx
,
"capi_list_providers
\n
"
);
BIO_printf
(
out
,
"Available CSPs:
\n
"
);
for
(
idx
=
0
;
;
idx
++
)
{
ret
=
capi_get_provname
(
ctx
,
&
provname
,
&
ptype
,
idx
);
if
(
ret
==
2
)
break
;
if
(
ret
==
0
)
break
;
BIO_printf
(
out
,
"%d. %s, type %d
\n
"
,
idx
,
provname
,
ptype
);
OPENSSL_free
(
provname
);
}
return
1
;
}
static
int
capi_list_containers
(
CAPI_CTX
*
ctx
,
BIO
*
out
)
{
int
ret
=
1
;
HCRYPTPROV
hprov
;
DWORD
err
,
idx
,
flags
,
buflen
=
0
,
clen
;
LPSTR
cname
;
CAPI_trace
(
ctx
,
"Listing containers CSP=%s, type = %d
\n
"
,
ctx
->
cspname
,
ctx
->
csptype
);
if
(
!
CryptAcquireContext
(
&
hprov
,
NULL
,
ctx
->
cspname
,
ctx
->
csptype
,
CRYPT_VERIFYCONTEXT
))
{
CAPIerr
(
CAPI_F_CAPI_LIST_CONTAINERS
,
CAPI_R_CRYPTACQUIRECONTEXT_ERROR
);
capi_addlasterror
();
return
0
;
}
if
(
!
CryptGetProvParam
(
hprov
,
PP_ENUMCONTAINERS
,
NULL
,
&
buflen
,
CRYPT_FIRST
))
{
CAPIerr
(
CAPI_F_CAPI_LIST_CONTAINERS
,
CAPI_R_ENUMCONTAINERS_ERROR
);
capi_addlasterror
();
return
0
;
}
CAPI_trace
(
ctx
,
"Got max container len %d
\n
"
,
buflen
);
if
(
buflen
==
0
)
buflen
=
1024
;
cname
=
OPENSSL_malloc
(
buflen
);
if
(
!
cname
)
{
CAPIerr
(
CAPI_F_CAPI_LIST_CONTAINERS
,
ERR_R_MALLOC_FAILURE
);
goto
err
;
}
for
(
idx
=
0
;;
idx
++
)
{
clen
=
buflen
;
cname
[
0
]
=
0
;
if
(
idx
==
0
)
flags
=
CRYPT_FIRST
;
else
flags
=
0
;
if
(
!
CryptGetProvParam
(
hprov
,
PP_ENUMCONTAINERS
,
cname
,
&
clen
,
flags
))
{
err
=
GetLastError
();
if
(
err
==
ERROR_NO_MORE_ITEMS
)
goto
done
;
CAPIerr
(
CAPI_F_CAPI_LIST_CONTAINERS
,
CAPI_R_ENUMCONTAINERS_ERROR
);
capi_adderror
(
err
);
goto
err
;
}
CAPI_trace
(
ctx
,
"Container name %s, len=%d, index=%d, flags=%d
\n
"
,
cname
,
clen
,
idx
,
flags
);
if
(
!
cname
[
0
]
&&
(
clen
==
buflen
))
{
CAPI_trace
(
ctx
,
"Enumerate bug: using workaround
\n
"
);
goto
done
;
}
BIO_printf
(
out
,
"%d. %s
\n
"
,
idx
,
cname
);
}
err:
ret
=
0
;
done:
if
(
cname
)
OPENSSL_free
(
cname
);
CryptReleaseContext
(
hprov
,
0
);
return
ret
;
}
CRYPT_KEY_PROV_INFO
*
capi_get_prov_info
(
CAPI_CTX
*
ctx
,
PCCERT_CONTEXT
cert
)
{
DWORD
len
;
CRYPT_KEY_PROV_INFO
*
pinfo
;
if
(
!
CertGetCertificateContextProperty
(
cert
,
CERT_KEY_PROV_INFO_PROP_ID
,
NULL
,
&
len
))
return
NULL
;
pinfo
=
OPENSSL_malloc
(
len
);
if
(
!
pinfo
)
{
CAPIerr
(
CAPI_F_CAPI_GET_PROV_INFO
,
ERR_R_MALLOC_FAILURE
);
return
NULL
;
}
if
(
!
CertGetCertificateContextProperty
(
cert
,
CERT_KEY_PROV_INFO_PROP_ID
,
pinfo
,
&
len
))
{
CAPIerr
(
CAPI_F_CAPI_GET_PROV_INFO
,
CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO
);
capi_addlasterror
();
OPENSSL_free
(
pinfo
);
return
NULL
;
}
return
pinfo
;
}
static
void
capi_dump_prov_info
(
CAPI_CTX
*
ctx
,
BIO
*
out
,
CRYPT_KEY_PROV_INFO
*
pinfo
)
{
char
*
provname
=
NULL
,
*
contname
=
NULL
;
if
(
!
pinfo
)
{
BIO_printf
(
out
,
" No Private Key
\n
"
);
return
;
}
provname
=
wide_to_asc
(
pinfo
->
pwszProvName
);
contname
=
wide_to_asc
(
pinfo
->
pwszContainerName
);
if
(
!
provname
||
!
contname
)
goto
err
;
BIO_printf
(
out
,
" Private Key Info:
\n
"
);
BIO_printf
(
out
,
" Provider Name: %s, Provider Type %d
\n
"
,
provname
,
pinfo
->
dwProvType
);
BIO_printf
(
out
,
" Container Name: %s, Key Type %d
\n
"
,
contname
,
pinfo
->
dwKeySpec
);
err:
if
(
provname
)
OPENSSL_free
(
provname
);
if
(
contname
)
OPENSSL_free
(
contname
);
}
char
*
capi_cert_get_fname
(
CAPI_CTX
*
ctx
,
PCCERT_CONTEXT
cert
)
{
LPWSTR
wfname
;
DWORD
dlen
;
CAPI_trace
(
ctx
,
"capi_cert_get_fname
\n
"
);
if
(
!
CertGetCertificateContextProperty
(
cert
,
CERT_FRIENDLY_NAME_PROP_ID
,
NULL
,
&
dlen
))
return
NULL
;
wfname
=
OPENSSL_malloc
(
dlen
);
if
(
CertGetCertificateContextProperty
(
cert
,
CERT_FRIENDLY_NAME_PROP_ID
,
wfname
,
&
dlen
))
{
char
*
fname
=
wide_to_asc
(
wfname
);
OPENSSL_free
(
wfname
);
return
fname
;
}
CAPIerr
(
CAPI_F_CAPI_CERT_GET_FNAME
,
CAPI_R_ERROR_GETTING_FRIENDLY_NAME
);
capi_addlasterror
();
OPENSSL_free
(
wfname
);
return
NULL
;
}
void
capi_dump_cert
(
CAPI_CTX
*
ctx
,
BIO
*
out
,
PCCERT_CONTEXT
cert
)
{
X509
*
x
;
unsigned
char
*
p
;
unsigned
long
flags
=
ctx
->
dump_flags
;
if
(
flags
&
CAPI_DMP_FNAME
)
{
char
*
fname
;
fname
=
capi_cert_get_fname
(
ctx
,
cert
);
if
(
fname
)
{
BIO_printf
(
out
,
" Friendly Name
\"
%s
\"\n
"
,
fname
);
OPENSSL_free
(
fname
);
}
else
BIO_printf
(
out
,
" <No Friendly Name>
\n
"
);
}
p
=
cert
->
pbCertEncoded
;
x
=
d2i_X509
(
NULL
,
&
p
,
cert
->
cbCertEncoded
);
if
(
!
x
)
BIO_printf
(
out
,
" <Can't parse certificate>
\n
"
);
if
(
flags
&
CAPI_DMP_SUMMARY
)
{
BIO_printf
(
out
,
" Subject: "
);
X509_NAME_print_ex
(
out
,
X509_get_subject_name
(
x
),
0
,
XN_FLAG_ONELINE
);
BIO_printf
(
out
,
"
\n
Issuer: "
);
X509_NAME_print_ex
(
out
,
X509_get_issuer_name
(
x
),
0
,
XN_FLAG_ONELINE
);
BIO_printf
(
out
,
"
\n
"
);
}
if
(
flags
&
CAPI_DMP_FULL
)
X509_print_ex
(
out
,
x
,
XN_FLAG_ONELINE
,
0
);
if
(
flags
&
CAPI_DMP_PKEYINFO
)
{
CRYPT_KEY_PROV_INFO
*
pinfo
;
pinfo
=
capi_get_prov_info
(
ctx
,
cert
);
capi_dump_prov_info
(
ctx
,
out
,
pinfo
);
if
(
pinfo
)
OPENSSL_free
(
pinfo
);
}
if
(
flags
&
CAPI_DMP_PEM
)
PEM_write_bio_X509
(
out
,
x
);
X509_free
(
x
);
}
HCERTSTORE
capi_open_store
(
CAPI_CTX
*
ctx
,
char
*
storename
)
{
HCERTSTORE
hstore
;
if
(
!
storename
)
storename
=
ctx
->
storename
;
if
(
!
storename
)
storename
=
"MY"
;
CAPI_trace
(
ctx
,
"Opening certificate store %s
\n
"
,
storename
);
hstore
=
CertOpenSystemStore
(
0
,
storename
);
if
(
!
hstore
)
{
CAPIerr
(
CAPI_F_CAPI_OPEN_STORE
,
CAPI_R_ERROR_OPENING_STORE
);
capi_addlasterror
();
}
return
hstore
;
}
int
capi_list_certs
(
CAPI_CTX
*
ctx
,
BIO
*
out
,
char
*
id
)
{
char
*
storename
;
int
idx
;
int
ret
=
1
;
HCERTSTORE
hstore
;
PCCERT_CONTEXT
cert
=
NULL
;
storename
=
ctx
->
storename
;
if
(
!
storename
)
storename
=
"MY"
;
CAPI_trace
(
ctx
,
"Listing certs for store %s
\n
"
,
storename
);
hstore
=
capi_open_store
(
ctx
,
storename
);
if
(
!
hstore
)
return
0
;
if
(
id
)
{
cert
=
capi_find_cert
(
ctx
,
id
,
hstore
);
if
(
!
cert
)
{
ret
=
0
;
goto
err
;
}
capi_dump_cert
(
ctx
,
out
,
cert
);
CertFreeCertificateContext
(
cert
);
}
else
{
for
(
idx
=
0
;;
idx
++
)
{
LPWSTR
fname
=
NULL
;
cert
=
CertEnumCertificatesInStore
(
hstore
,
cert
);
if
(
!
cert
)
break
;
BIO_printf
(
out
,
"Certificate %d
\n
"
,
idx
);
capi_dump_cert
(
ctx
,
out
,
cert
);
}
}
err:
CertCloseStore
(
hstore
,
0
);
return
ret
;
}
static
PCCERT_CONTEXT
capi_find_cert
(
CAPI_CTX
*
ctx
,
const
char
*
id
,
HCERTSTORE
hstore
)
{
PCCERT_CONTEXT
cert
=
NULL
;
char
*
fname
=
NULL
;
int
match
;
switch
(
ctx
->
lookup_method
)
{
case
CAPI_LU_SUBSTR
:
return
CertFindCertificateInStore
(
hstore
,
X509_ASN_ENCODING
,
0
,
CERT_FIND_SUBJECT_STR_A
,
id
,
NULL
);
case
CAPI_LU_FNAME
:
for
(;;)
{
cert
=
CertEnumCertificatesInStore
(
hstore
,
cert
);
if
(
!
cert
)
return
NULL
;
fname
=
capi_cert_get_fname
(
ctx
,
cert
);
if
(
fname
)
{
if
(
strcmp
(
fname
,
id
))
match
=
0
;
else
match
=
1
;
OPENSSL_free
(
fname
);
if
(
match
)
return
cert
;
}
}
default:
return
NULL
;
}
}
static
CAPI_KEY
*
capi_get_key
(
CAPI_CTX
*
ctx
,
const
char
*
contname
,
char
*
provname
,
DWORD
ptype
,
DWORD
keyspec
)
{
CAPI_KEY
*
key
;
key
=
OPENSSL_malloc
(
sizeof
(
CAPI_KEY
));
CAPI_trace
(
ctx
,
"capi_get_key, contname=%s, provname=%s, type=%d
\n
"
,
contname
,
provname
,
ptype
);
if
(
!
CryptAcquireContext
(
&
key
->
hprov
,
contname
,
provname
,
ptype
,
0
))
{
CAPIerr
(
CAPI_F_CAPI_GET_KEY
,
CAPI_R_CRYPTACQUIRECONTEXT_ERROR
);
capi_addlasterror
();
goto
err
;
}
if
(
!
CryptGetUserKey
(
key
->
hprov
,
keyspec
,
&
key
->
key
))
{
CAPIerr
(
CAPI_F_CAPI_GET_KEY
,
CAPI_R_GETUSERKEY_ERROR
);
capi_addlasterror
();
CryptReleaseContext
(
key
->
hprov
,
0
);
goto
err
;
}
return
key
;
err:
OPENSSL_free
(
key
);
return
NULL
;
}
static
CAPI_KEY
*
capi_get_cert_key
(
CAPI_CTX
*
ctx
,
PCCERT_CONTEXT
cert
)
{
CAPI_KEY
*
key
;
CRYPT_KEY_PROV_INFO
*
pinfo
=
NULL
;
char
*
provname
=
NULL
,
*
contname
=
NULL
;
pinfo
=
capi_get_prov_info
(
ctx
,
cert
);
if
(
!
pinfo
)
goto
err
;
provname
=
wide_to_asc
(
pinfo
->
pwszProvName
);
contname
=
wide_to_asc
(
pinfo
->
pwszContainerName
);
if
(
!
provname
||
!
contname
)
return
0
;
key
=
capi_get_key
(
ctx
,
contname
,
provname
,
pinfo
->
dwProvType
,
pinfo
->
dwKeySpec
);
err:
if
(
pinfo
)
OPENSSL_free
(
pinfo
);
if
(
provname
)
OPENSSL_free
(
provname
);
if
(
contname
)
OPENSSL_free
(
contname
);
return
key
;
}
CAPI_KEY
*
capi_find_key
(
CAPI_CTX
*
ctx
,
const
char
*
id
)
{
PCCERT_CONTEXT
cert
;
HCERTSTORE
hstore
;
CAPI_KEY
*
key
=
NULL
;
switch
(
ctx
->
lookup_method
)
{
case
CAPI_LU_SUBSTR
:
case
CAPI_LU_FNAME
:
hstore
=
capi_open_store
(
ctx
,
NULL
);
if
(
!
hstore
)
return
NULL
;
cert
=
capi_find_cert
(
ctx
,
id
,
hstore
);
if
(
cert
)
{
key
=
capi_get_cert_key
(
ctx
,
cert
);
CertFreeCertificateContext
(
cert
);
}
CertCloseStore
(
hstore
,
0
);
break
;
case
CAPI_LU_CONTNAME
:
key
=
capi_get_key
(
ctx
,
id
,
ctx
->
cspname
,
ctx
->
csptype
,
ctx
->
keytype
);
break
;
}
return
key
;
}
void
capi_free_key
(
CAPI_KEY
*
key
)
{
if
(
!
key
)
return
;
CryptDestroyKey
(
key
->
key
);
CryptReleaseContext
(
key
->
hprov
,
0
);
OPENSSL_free
(
key
);
}
/* Initialize a CAPI_CTX structure */
static
CAPI_CTX
*
capi_ctx_new
()
{
CAPI_CTX
*
ctx
;
ctx
=
OPENSSL_malloc
(
sizeof
(
CAPI_CTX
));
if
(
!
ctx
)
{
CAPIerr
(
CAPI_F_CAPI_CTX_NEW
,
ERR_R_MALLOC_FAILURE
);
return
NULL
;
}
ctx
->
cspname
=
NULL
;
ctx
->
csptype
=
PROV_RSA_FULL
;
ctx
->
dump_flags
=
CAPI_DMP_SUMMARY
|
CAPI_DMP_FNAME
;
ctx
->
keytype
=
AT_KEYEXCHANGE
;
ctx
->
storename
=
NULL
;
ctx
->
lookup_method
=
CAPI_LU_SUBSTR
;
ctx
->
debug_level
=
0
;
ctx
->
debug_file
=
NULL
;
return
ctx
;
}
static
void
capi_ctx_free
(
CAPI_CTX
*
ctx
)
{
CAPI_trace
(
ctx
,
"Calling capi_ctx_free with %lx
\n
"
,
ctx
);
if
(
!
ctx
)
return
;
if
(
ctx
->
cspname
)
OPENSSL_free
(
ctx
->
cspname
);
if
(
ctx
->
debug_file
)
OPENSSL_free
(
ctx
->
debug_file
);
if
(
ctx
->
storename
)
OPENSSL_free
(
ctx
->
storename
);
OPENSSL_free
(
ctx
);
}
static
int
capi_ctx_set_provname
(
CAPI_CTX
*
ctx
,
LPSTR
pname
,
DWORD
type
,
int
check
)
{
CAPI_trace
(
ctx
,
"capi_ctx_set_provname, name=%s, type=%d
\n
"
,
pname
,
type
);
if
(
check
)
{
HCRYPTPROV
hprov
;
if
(
!
CryptAcquireContext
(
&
hprov
,
NULL
,
pname
,
type
,
CRYPT_VERIFYCONTEXT
))
{
CAPIerr
(
CAPI_F_CAPI_CTX_SET_PROVNAME
,
CAPI_R_CRYPTACQUIRECONTEXT_ERROR
);
capi_addlasterror
();
return
0
;
}
CryptReleaseContext
(
hprov
,
0
);
}
ctx
->
cspname
=
BUF_strdup
(
pname
);
ctx
->
csptype
=
type
;
return
1
;
}
static
int
capi_ctx_set_provname_idx
(
CAPI_CTX
*
ctx
,
int
idx
)
{
LPSTR
pname
;
DWORD
type
;
if
(
capi_get_provname
(
ctx
,
&
pname
,
&
type
,
idx
)
!=
1
)
return
0
;
return
capi_ctx_set_provname
(
ctx
,
pname
,
type
,
0
);
}
#endif
#endif
engines/e_capi.ec
0 → 100644
浏览文件 @
7a18ecb2
L CAPI e_capi_err.h e_capi_err.c
engines/e_capi_err.h
0 → 100644
浏览文件 @
7a18ecb2
/* ====================================================================
* Copyright (c) 2001-2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_CAPI_ERR_H
#define HEADER_CAPI_ERR_H
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
static
void
ERR_load_CAPI_strings
(
void
);
static
void
ERR_unload_CAPI_strings
(
void
);
static
void
ERR_CAPI_error
(
int
function
,
int
reason
,
char
*
file
,
int
line
);
#define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__)
/* Error codes for the CAPI functions. */
/* Function codes. */
#define CAPI_F_CAPI_CERT_GET_FNAME 99
#define CAPI_F_CAPI_CTRL 100
#define CAPI_F_CAPI_CTX_NEW 101
#define CAPI_F_CAPI_CTX_SET_PROVNAME 102
#define CAPI_F_CAPI_DSA_DO_SIGN 114
#define CAPI_F_CAPI_GET_KEY 103
#define CAPI_F_CAPI_GET_PROVNAME 104
#define CAPI_F_CAPI_GET_PROV_INFO 105
#define CAPI_F_CAPI_INIT 106
#define CAPI_F_CAPI_LIST_CONTAINERS 107
#define CAPI_F_CAPI_LOAD_PRIVKEY 108
#define CAPI_F_CAPI_OPEN_STORE 109
#define CAPI_F_CAPI_RSA_PRIV_DEC 110
#define CAPI_F_CAPI_RSA_PRIV_ENC 111
#define CAPI_F_CAPI_RSA_SIGN 112
#define CAPI_F_WIDE_TO_ASC 113
/* Reason codes. */
#define CAPI_R_CANT_CREATE_HASH_OBJECT 99
#define CAPI_R_CANT_FIND_CAPI_CONTEXT 100
#define CAPI_R_CANT_GET_KEY 101
#define CAPI_R_CANT_SET_HASH_VALUE 102
#define CAPI_R_CRYPTACQUIRECONTEXT_ERROR 103
#define CAPI_R_CRYPTENUMPROVIDERS_ERROR 104
#define CAPI_R_DECRYPT_ERROR 105
#define CAPI_R_ENGINE_NOT_INITIALIZED 106
#define CAPI_R_ENUMCONTAINERS_ERROR 107
#define CAPI_R_ERROR_GETTING_FRIENDLY_NAME 108
#define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO 109
#define CAPI_R_ERROR_OPENING_STORE 110
#define CAPI_R_ERROR_SIGNING_HASH 111
#define CAPI_R_FUNCTION_NOT_SUPPORTED 112
#define CAPI_R_GETUSERKEY_ERROR 113
#define CAPI_R_INVALID_DIGEST_LENGTH 124
#define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 122
#define CAPI_R_INVALID_LOOKUP_METHOD 114
#define CAPI_R_INVALID_PUBLIC_KEY_BLOB 115
#define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 123
#define CAPI_R_PUBKEY_EXPORT_ERROR 116
#define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR 117
#define CAPI_R_UNKNOWN_COMMAND 118
#define CAPI_R_UNSUPPORTED_ALGORITHM_NID 119
#define CAPI_R_UNSUPPORTED_PADDING 120
#define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 121
#ifdef __cplusplus
}
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录