Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
23487df8
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
23487df8
编写于
7月 29, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'alon/pull-libcacard.afe' into staging
上级
3046c984
0f94d6da
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
224 addition
and
78 deletion
+224
-78
configure
configure
+5
-0
libcacard/Makefile
libcacard/Makefile
+24
-3
libcacard/libcacard.pc.in
libcacard/libcacard.pc.in
+13
-0
libcacard/vcard_emul_nss.c
libcacard/vcard_emul_nss.c
+182
-75
未找到文件。
configure
浏览文件 @
23487df8
...
...
@@ -146,6 +146,7 @@ datadir="\${prefix}/share/qemu"
docdir
=
"
\$
{prefix}/share/doc/qemu"
bindir
=
"
\$
{prefix}/bin"
libdir
=
"
\$
{prefix}/lib"
includedir
=
"
\$
{prefix}/include"
sysconfdir
=
"
\$
{prefix}/etc"
confsuffix
=
"/qemu"
slirp
=
"yes"
...
...
@@ -544,6 +545,8 @@ for opt do
;;
--libdir
=
*
)
libdir
=
"
$optarg
"
;;
--includedir
=
*
)
includedir
=
"
$optarg
"
;;
--datadir
=
*
)
datadir
=
"
$optarg
"
;;
--docdir
=
*
)
docdir
=
"
$optarg
"
...
...
@@ -2594,6 +2597,7 @@ echo "Install prefix $prefix"
echo
"BIOS directory
`
eval echo
$datadir
`
"
echo
"binary directory
`
eval echo
$bindir
`
"
echo
"library directory
`
eval echo
$libdir
`
"
echo
"include directory
`
eval echo
$includedir
`
"
echo
"config directory
`
eval echo
$sysconfdir
`
"
if
test
"
$mingw32
"
=
"no"
;
then
echo
"Manual directory
`
eval echo
$mandir
`
"
...
...
@@ -2689,6 +2693,7 @@ echo all: >> $config_host_mak
echo
"prefix=
$prefix
"
>>
$config_host_mak
echo
"bindir=
$bindir
"
>>
$config_host_mak
echo
"libdir=
$libdir
"
>>
$config_host_mak
echo
"includedir=
$includedir
"
>>
$config_host_mak
echo
"mandir=
$mandir
"
>>
$config_host_mak
echo
"datadir=
$datadir
"
>>
$config_host_mak
echo
"sysconfdir=
$sysconfdir
"
>>
$config_host_mak
...
...
libcacard/Makefile
浏览文件 @
23487df8
...
...
@@ -2,7 +2,10 @@
-include
$(SRC_PATH)/Makefile.objs
-include
$(SRC_PATH)/rules.mak
$(call set-vpath, $(SRC_PATH)
:
$(SRC_PATH)/libcacard)
libcacard_srcpath
=
$(SRC_PATH)
/libcacard
libcacard_includedir
=
$(includedir)
/cacard
$(call set-vpath, $(SRC_PATH)
:
$(libcacard_srcpath))
# objects linked against normal qemu binaries, not compiled with libtool
QEMU_OBJS
=
$(
addprefix
../,
$
(
oslib-obj-y
)
qemu-malloc.o qemu-timer-common.o
$
(
trace-obj-y
))
...
...
@@ -18,7 +21,7 @@ vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o
$(
call
quiet-command,
$(CC)
$(libcacard_libs)
-lrt
-o
$@
$^
,
" LINK
$@
"
)
clean
:
rm
-f
*
.o
*
/
*
.o
*
.d
*
/
*
.d
*
.a
*
/
*
.a
*
~
*
/
*
~ vscclient
*
.lo .libs/
*
*
.la
rm
-f
*
.o
*
/
*
.o
*
.d
*
/
*
.d
*
.a
*
/
*
.a
*
~
*
/
*
~ vscclient
*
.lo .libs/
*
*
.la
*
.pc
rm
-Rf
.libs
all
:
vscclient
...
...
@@ -36,7 +39,25 @@ else
libcacard.la
:
$(libcacard.lib-y) $(QEMU_OBJS_LIB)
$(
call
quiet-command,libtool
--mode
=
link
--quiet
--tag
=
CC
$(CC)
$(libcacard_libs)
-lrt
-rpath
$(libdir)
-o
$@
$^
,
" lt LINK
$@
"
)
install-libcacard
:
libcacard.la
libcacard.pc
:
$(libcacard_srcpath)/libcacard.pc.in
sed
-e
's|@LIBDIR@|
$(libdir)
|'
\
-e
's|@INCLUDEDIR@|
$(libcacard_includedir)
|'
\
-e
's|@VERSION@|
$(
shell
cat
$(SRC_PATH)
/VERSION
)
|'
\
-e
's|@PREFIX@|
$(prefix)
|'
\
<
$(libcacard_srcpath)
/libcacard.pc.in
>
libcacard.pc
.PHONY
:
install-libcacard
install-libcacard
:
libcacard.pc libcacard.la vscclient
$(INSTALL_DIR)
"
$(DESTDIR)$(libdir)
"
$(INSTALL_DIR)
"
$(DESTDIR)$(libdir)
/pkgconfig"
$(INSTALL_DIR)
"
$(DESTDIR)$(libcacard_includedir)
"
$(INSTALL_DIR)
"
$(DESTDIR)$(bindir)
"
libtool
--mode
=
install
$(INSTALL_PROG)
vscclient
"
$(DESTDIR)$(bindir)
"
libtool
--mode
=
install
$(INSTALL_PROG)
libcacard.la
"
$(DESTDIR)$(libdir)
"
libtool
--mode
=
install
$(INSTALL_PROG)
libcacard.pc
"
$(DESTDIR)$(libdir)
/pkgconfig"
for
inc
in
*
.h
;
do
\
libtool
--mode
=
install
$(INSTALL_PROG)
$(libcacard_srcpath)
/
$$
inc
"
$(DESTDIR)$(libcacard_includedir)
"
;
\
done
endif
libcacard/libcacard.pc.in
0 → 100644
浏览文件 @
23487df8
prefix=@PREFIX@
exec_prefix=${prefix}
libdir=@LIBDIR@
includedir=@INCLUDEDIR@
Name: cacard
Description: CA Card library
Version: @VERSION@
Requires: nss
Libs: -L${libdir} -lcacard
Libs.private:
Cflags: -I${includedir}
libcacard/vcard_emul_nss.c
浏览文件 @
23487df8
...
...
@@ -33,10 +33,17 @@
#include "vreader.h"
#include "vevent.h"
typedef
enum
{
VCardEmulUnknown
=
-
1
,
VCardEmulFalse
=
0
,
VCardEmulTrue
=
1
}
VCardEmulTriState
;
struct
VCardKeyStruct
{
CERTCertificate
*
cert
;
PK11SlotInfo
*
slot
;
SECKEYPrivateKey
*
key
;
VCardEmulTriState
failedX509
;
};
...
...
@@ -140,6 +147,7 @@ vcard_emul_make_key(PK11SlotInfo *slot, CERTCertificate *cert)
/* NOTE: the cert is a temp cert, not necessarily the cert in the token,
* use the DER version of this function */
key
->
key
=
PK11_FindKeyByDERCert
(
slot
,
cert
,
NULL
);
key
->
failedX509
=
VCardEmulUnknown
;
return
key
;
}
...
...
@@ -208,13 +216,23 @@ vcard_emul_rsa_op(VCard *card, VCardKey *key,
{
SECKEYPrivateKey
*
priv_key
;
unsigned
signature_len
;
PK11SlotInfo
*
slot
;
SECStatus
rv
;
unsigned
char
buf
[
2048
];
unsigned
char
*
bp
=
NULL
;
int
pad_len
;
vcard_7816_status_t
ret
=
VCARD7816_STATUS_SUCCESS
;
if
((
!
nss_emul_init
)
||
(
key
==
NULL
))
{
/* couldn't get the key, indicate that we aren't logged in */
return
VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED
;
}
priv_key
=
vcard_emul_get_nss_key
(
key
);
if
(
priv_key
==
NULL
)
{
/* couldn't get the key, indicate that we aren't logged in */
return
VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED
;
}
slot
=
vcard_emul_card_get_slot
(
card
);
/*
* this is only true of the rsa signature
...
...
@@ -223,13 +241,116 @@ vcard_emul_rsa_op(VCard *card, VCardKey *key,
if
(
buffer_size
!=
signature_len
)
{
return
VCARD7816_STATUS_ERROR_DATA_INVALID
;
}
rv
=
PK11_PrivDecryptRaw
(
priv_key
,
buffer
,
&
signature_len
,
signature_len
,
buffer
,
buffer_size
);
if
(
rv
!=
SECSuccess
)
{
return
vcard_emul_map_error
(
PORT_GetError
());
/* be able to handle larger keys if necessariy */
bp
=
&
buf
[
0
];
if
(
sizeof
(
buf
)
<
signature_len
)
{
bp
=
qemu_malloc
(
signature_len
);
}
/*
* do the raw operations. Some tokens claim to do CKM_RSA_X_509, but then
* choke when they try to do the actual operations. Try to detect
* those cases and treat them as if the token didn't claim support for
* X_509.
*/
if
(
key
->
failedX509
!=
VCardEmulTrue
&&
PK11_DoesMechanism
(
slot
,
CKM_RSA_X_509
))
{
rv
=
PK11_PrivDecryptRaw
(
priv_key
,
bp
,
&
signature_len
,
signature_len
,
buffer
,
buffer_size
);
if
(
rv
==
SECSuccess
)
{
assert
(
buffer_size
==
signature_len
);
memcpy
(
buffer
,
bp
,
signature_len
);
key
->
failedX509
=
VCardEmulFalse
;
goto
cleanup
;
}
/*
* we've had a successful X509 operation, this failure must be
* somethine else
*/
if
(
key
->
failedX509
==
VCardEmulFalse
)
{
ret
=
vcard_emul_map_error
(
PORT_GetError
());
goto
cleanup
;
}
/*
* key->failedX509 must be Unknown at this point, try the
* non-x_509 case
*/
}
/* token does not support CKM_RSA_X509, emulate that with CKM_RSA_PKCS */
/* is this a PKCS #1 formatted signature? */
if
((
buffer
[
0
]
==
0
)
&&
(
buffer
[
1
]
==
1
))
{
int
i
;
for
(
i
=
2
;
i
<
buffer_size
;
i
++
)
{
/* rsa signature pad */
if
(
buffer
[
i
]
!=
0xff
)
{
break
;
}
}
if
((
i
<
buffer_size
)
&&
(
buffer
[
i
]
==
0
))
{
/* yes, we have a properly formated PKCS #1 signature */
/*
* NOTE: even if we accidentally got an encrypt buffer, which
* through shear luck started with 00, 01, ff, 00, it won't matter
* because the resulting Sign operation will effectively decrypt
* the real buffer.
*/
SECItem
signature
;
SECItem
hash
;
i
++
;
hash
.
data
=
&
buffer
[
i
];
hash
.
len
=
buffer_size
-
i
;
signature
.
data
=
bp
;
signature
.
len
=
signature_len
;
rv
=
PK11_Sign
(
priv_key
,
&
signature
,
&
hash
);
if
(
rv
!=
SECSuccess
)
{
ret
=
vcard_emul_map_error
(
PORT_GetError
());
goto
cleanup
;
}
assert
(
buffer_size
==
signature
.
len
);
memcpy
(
buffer
,
bp
,
signature
.
len
);
/*
* we got here because either the X509 attempt failed, or the
* token couldn't do the X509 operation, in either case stay
* with the PKCS version for future operations on this key
*/
key
->
failedX509
=
VCardEmulTrue
;
goto
cleanup
;
}
}
pad_len
=
buffer_size
-
signature_len
;
assert
(
pad_len
<
4
);
/*
* OK now we've decrypted the payload, package it up in PKCS #1 for the
* upper layer.
*/
buffer
[
0
]
=
0
;
buffer
[
1
]
=
2
;
/* RSA_encrypt */
pad_len
-=
3
;
/* format is 0 || 2 || pad || 0 || data */
/*
* padding for PKCS #1 encrypted data is a string of random bytes. The
* random butes protect against potential decryption attacks against RSA.
* Since PrivDecrypt has already stripped those bytes, we can't reconstruct
* them. This shouldn't matter to the upper level code which should just
* strip this code out anyway, so We'll pad with a constant 3.
*/
memset
(
&
buffer
[
2
],
0x03
,
pad_len
);
pad_len
+=
2
;
/* index to the end of the pad */
buffer
[
pad_len
]
=
0
;
pad_len
++
;
/* index to the start of the data */
memcpy
(
&
buffer
[
pad_len
],
bp
,
signature_len
);
/*
* we got here because either the X509 attempt failed, or the
* token couldn't do the X509 operation, in either case stay
* with the PKCS version for future operations on this key
*/
key
->
failedX509
=
VCardEmulTrue
;
cleanup:
if
(
bp
!=
buf
)
{
qemu_free
(
bp
);
}
assert
(
buffer_size
==
signature_len
);
return
VCARD7816_STATUS_SUCCESS
;
return
ret
;
}
/*
...
...
@@ -476,6 +597,7 @@ vcard_emul_mirror_card(VReader *vreader)
VCardKey
**
keys
;
PK11SlotInfo
*
slot
;
PRBool
ret
;
VCard
*
card
;
slot
=
vcard_emul_reader_get_slot
(
vreader
);
if
(
slot
==
NULL
)
{
...
...
@@ -535,7 +657,12 @@ vcard_emul_mirror_card(VReader *vreader)
}
/* now create the card */
return
vcard_emul_make_card
(
vreader
,
certs
,
cert_len
,
keys
,
cert_count
);
card
=
vcard_emul_make_card
(
vreader
,
certs
,
cert_len
,
keys
,
cert_count
);
qemu_free
(
certs
);
qemu_free
(
cert_len
);
qemu_free
(
keys
);
return
card
;
}
static
VCardEmulType
default_card_type
=
VCARD_EMUL_NONE
;
...
...
@@ -820,6 +947,9 @@ vcard_emul_init(const VCardEmulOptions *options)
vreader_free
(
vreader
);
has_readers
=
PR_TRUE
;
}
qemu_free
(
certs
);
qemu_free
(
cert_len
);
qemu_free
(
keys
);
}
/* if we aren't suppose to use hw, skip looking up hardware tokens */
...
...
@@ -925,17 +1055,6 @@ vcard_emul_replay_insertion_events(void)
/*
* Silly little functions to help parsing our argument string
*/
static
char
*
copy_string
(
const
char
*
str
,
int
str_len
)
{
char
*
new_str
;
new_str
=
qemu_malloc
(
str_len
+
1
);
memcpy
(
new_str
,
str
,
str_len
);
new_str
[
str_len
]
=
0
;
return
new_str
;
}
static
int
count_tokens
(
const
char
*
str
,
char
token
,
char
token_end
)
{
...
...
@@ -975,13 +1094,31 @@ find_blank(const char *str)
static
VCardEmulOptions
options
;
#define READER_STEP 4
/* Expects "args" to be at the beginning of a token (ie right after the ','
* ending the previous token), and puts the next token start in "token",
* and its length in "token_length". "token" will not be nul-terminated.
* After calling the macro, "args" will be advanced to the beginning of
* the next token.
* This macro may call continue or break.
*/
#define NEXT_TOKEN(token) \
(token) = args; \
args = strpbrk(args, ",)"); \
if (*args == 0) { \
break; \
} \
if (*args == ')') { \
args++; \
continue; \
} \
(token##_length) = args - (token); \
args = strip(args+1);
VCardEmulOptions
*
vcard_emul_options
(
const
char
*
args
)
{
int
reader_count
=
0
;
VCardEmulOptions
*
opts
;
char
type_str
[
100
];
int
type_len
;
/* Allow the future use of allocating the options structure on the fly */
memcpy
(
&
options
,
&
default_options
,
sizeof
(
options
));
...
...
@@ -996,63 +1133,32 @@ vcard_emul_options(const char *args)
* cert_2,cert_3...) */
if
(
strncmp
(
args
,
"soft="
,
5
)
==
0
)
{
const
char
*
name
;
size_t
name_length
;
const
char
*
vname
;
size_t
vname_length
;
const
char
*
type_params
;
size_t
type_params_length
;
char
type_str
[
100
];
VCardEmulType
type
;
int
name_length
,
vname_length
,
type_params_length
,
count
,
i
;
int
count
,
i
;
VirtualReaderOptions
*
vreaderOpt
=
NULL
;
args
=
strip
(
args
+
5
);
if
(
*
args
!=
'('
)
{
continue
;
}
name
=
args
;
args
=
strpbrk
(
args
+
1
,
",)"
);
if
(
*
args
==
0
)
{
break
;
}
if
(
*
args
==
')'
)
{
args
++
;
continue
;
}
args
=
strip
(
args
+
1
);
name_length
=
args
-
name
-
2
;
vname
=
args
;
args
=
strpbrk
(
args
+
1
,
",)"
);
if
(
*
args
==
0
)
{
break
;
}
if
(
*
args
==
')'
)
{
args
++
;
continue
;
}
vname_length
=
args
-
name
-
2
;
args
=
strip
(
args
+
1
);
type_len
=
strpbrk
(
args
,
",)"
)
-
args
;
assert
(
sizeof
(
type_str
)
>
type_len
);
strncpy
(
type_str
,
args
,
type_len
);
type_str
[
type_len
]
=
0
;
NEXT_TOKEN
(
name
)
NEXT_TOKEN
(
vname
)
NEXT_TOKEN
(
type_params
)
type_params_length
=
MIN
(
type_params_length
,
sizeof
(
type_str
)
-
1
);
strncpy
(
type_str
,
type_params
,
type_params_length
);
type_str
[
type_params_length
]
=
0
;
type
=
vcard_emul_type_from_string
(
type_str
);
args
=
strpbrk
(
args
,
",)"
);
if
(
*
args
==
0
)
{
break
;
}
if
(
*
args
==
')'
)
{
args
++
;
continue
;
}
args
=
strip
(
args
++
);
type_params
=
args
;
args
=
strpbrk
(
args
+
1
,
",)"
);
if
(
*
args
==
0
)
{
break
;
}
if
(
*
args
==
')'
)
{
args
++
;
continue
;
}
type_params_length
=
args
-
name
;
args
=
strip
(
args
++
);
NEXT_TOKEN
(
type_params
)
if
(
*
args
==
0
)
{
break
;
}
...
...
@@ -1067,18 +1173,19 @@ vcard_emul_options(const char *args)
}
opts
->
vreader
=
vreaderOpt
;
vreaderOpt
=
&
vreaderOpt
[
opts
->
vreader_count
];
vreaderOpt
->
name
=
copy_string
(
name
,
name_length
);
vreaderOpt
->
vname
=
copy_string
(
vname
,
vname_length
);
vreaderOpt
->
name
=
qemu_strndup
(
name
,
name_length
);
vreaderOpt
->
vname
=
qemu_strndup
(
vname
,
vname_length
);
vreaderOpt
->
card_type
=
type
;
vreaderOpt
->
type_params
=
copy_string
(
type_params
,
type_params_length
);
count
=
count_tokens
(
args
,
','
,
')'
);
qemu_strndup
(
type_params
,
type_params_length
);
count
=
count_tokens
(
args
,
','
,
')'
)
+
1
;
vreaderOpt
->
cert_count
=
count
;
vreaderOpt
->
cert_name
=
(
char
**
)
qemu_malloc
(
count
*
sizeof
(
char
*
));
for
(
i
=
0
;
i
<
count
;
i
++
)
{
const
char
*
cert
=
args
+
1
;
args
=
strpbrk
(
args
+
1
,
",)"
);
vreaderOpt
->
cert_name
[
i
]
=
copy_string
(
cert
,
args
-
cert
);
const
char
*
cert
=
args
;
args
=
strpbrk
(
args
,
",)"
);
vreaderOpt
->
cert_name
[
i
]
=
qemu_strndup
(
cert
,
args
-
cert
);
args
=
strip
(
args
+
1
);
}
if
(
*
args
==
')'
)
{
args
++
;
...
...
@@ -1104,7 +1211,7 @@ vcard_emul_options(const char *args)
args
=
strip
(
args
+
10
);
params
=
args
;
args
=
find_blank
(
args
);
opts
->
hw_type_params
=
copy_string
(
params
,
args
-
params
);
opts
->
hw_type_params
=
qemu_strndup
(
params
,
args
-
params
);
/* db="/data/base/path" */
}
else
if
(
strncmp
(
args
,
"db="
,
3
)
==
0
)
{
const
char
*
db
;
...
...
@@ -1115,7 +1222,7 @@ vcard_emul_options(const char *args)
args
++
;
db
=
args
;
args
=
strpbrk
(
args
,
"
\"\n
"
);
opts
->
nss_db
=
copy_string
(
db
,
args
-
db
);
opts
->
nss_db
=
qemu_strndup
(
db
,
args
-
db
);
if
(
*
args
!=
0
)
{
args
++
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录