Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
6759c79e
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
6759c79e
编写于
6月 29, 2018
作者:
M
Matt Witherspoon
提交者:
GitHub
6月 29, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4244 from EOSIO/se_wallet
Secure Enclave wallet support
上级
5a520fb2
fa9c4952
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
473 addition
and
23 deletion
+473
-23
plugins/wallet_plugin/CMakeLists.txt
plugins/wallet_plugin/CMakeLists.txt
+17
-1
plugins/wallet_plugin/include/eosio/wallet_plugin/macos_user_auth.h
...llet_plugin/include/eosio/wallet_plugin/macos_user_auth.h
+7
-0
plugins/wallet_plugin/include/eosio/wallet_plugin/se_wallet.hpp
...s/wallet_plugin/include/eosio/wallet_plugin/se_wallet.hpp
+41
-0
plugins/wallet_plugin/include/eosio/wallet_plugin/wallet_manager.hpp
...let_plugin/include/eosio/wallet_plugin/wallet_manager.hpp
+1
-1
plugins/wallet_plugin/macos_user_auth.m
plugins/wallet_plugin/macos_user_auth.m
+11
-0
plugins/wallet_plugin/se_wallet.cpp
plugins/wallet_plugin/se_wallet.cpp
+372
-0
plugins/wallet_plugin/wallet_manager.cpp
plugins/wallet_plugin/wallet_manager.cpp
+9
-0
plugins/wallet_plugin/wallet_plugin.cpp
plugins/wallet_plugin/wallet_plugin.cpp
+3
-3
programs/cleos/main.cpp
programs/cleos/main.cpp
+12
-18
未找到文件。
plugins/wallet_plugin/CMakeLists.txt
浏览文件 @
6759c79e
file
(
GLOB HEADERS
"include/eosio/wallet_plugin/*.hpp"
)
if
(
APPLE
)
set
(
SE_WALLET_SOURCES se_wallet.cpp macos_user_auth.m
)
set_source_files_properties
(
macos_user_presence.m PROPERTIES COMPILE_FLAGS
"-x objective-c"
)
find_library
(
security_framework security
)
find_library
(
localauthentication_framework localauthentication
)
find_library
(
corefoundation_framework corefoundation
)
find_library
(
cocoa_framework cocoa
)
if
(
MAS_KEYCHAIN_GROUP
)
add_definitions
(
-DMAS_KEYCHAIN_GROUP=
${
MAS_KEYCHAIN_GROUP
}
)
endif
(
MAS_KEYCHAIN_GROUP
)
endif
(
APPLE
)
add_library
(
wallet_plugin
wallet.cpp
wallet_plugin.cpp
wallet_manager.cpp
${
SE_WALLET_SOURCES
}
${
HEADERS
}
)
target_link_libraries
(
wallet_plugin eosio_chain appbase
)
target_link_libraries
(
wallet_plugin eosio_chain appbase
${
security_framework
}
${
corefoundation_framework
}
${
localauthentication_framework
}
${
cocoa_framework
}
)
target_include_directories
(
wallet_plugin PUBLIC
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/include"
)
plugins/wallet_plugin/include/eosio/wallet_plugin/macos_user_auth.h
0 → 100644
浏览文件 @
6759c79e
#pragma once
#include <CoreFoundation/CoreFoundation.h>
//ask for user authentication and call callback with true/false once compelte. **Note that the callback
// will be done in a separate thread**
extern
"C"
void
macos_user_auth
(
void
(
*
cb
)(
int
,
void
*
),
void
*
cb_userdata
,
CFStringRef
message
);
\ No newline at end of file
plugins/wallet_plugin/include/eosio/wallet_plugin/se_wallet.hpp
0 → 100644
浏览文件 @
6759c79e
#pragma once
#include <eosio/chain/types.hpp>
#include <eosio/wallet_plugin/wallet_api.hpp>
using
namespace
std
;
using
namespace
eosio
::
chain
;
namespace
eosio
{
namespace
wallet
{
namespace
detail
{
struct
se_wallet_impl
;
}
class
se_wallet
final
:
public
wallet_api
{
public:
se_wallet
();
~
se_wallet
();
private_key_type
get_private_key
(
public_key_type
pubkey
)
const
override
;
bool
is_locked
()
const
override
;
void
lock
()
override
;
void
unlock
(
string
password
)
override
;
void
check_password
(
string
password
)
override
;
void
set_password
(
string
password
)
override
;
map
<
public_key_type
,
private_key_type
>
list_keys
()
override
;
flat_set
<
public_key_type
>
list_public_keys
()
override
;
bool
import_key
(
string
wif_key
)
override
;
string
create_key
(
string
key_type
)
override
;
bool
remove_key
(
string
key
)
override
;
optional
<
signature_type
>
try_sign_digest
(
const
digest_type
digest
,
const
public_key_type
public_key
)
override
;
private:
std
::
unique_ptr
<
detail
::
se_wallet_impl
>
my
;
};
}}
\ No newline at end of file
plugins/wallet_plugin/include/eosio/wallet_plugin/wallet_manager.hpp
浏览文件 @
6759c79e
...
...
@@ -19,7 +19,7 @@ namespace wallet {
/// No const methods because timeout may cause lock_all() to be called.
class
wallet_manager
{
public:
wallet_manager
()
=
default
;
wallet_manager
();
wallet_manager
(
const
wallet_manager
&
)
=
delete
;
wallet_manager
(
wallet_manager
&&
)
=
delete
;
wallet_manager
&
operator
=
(
const
wallet_manager
&
)
=
delete
;
...
...
plugins/wallet_plugin/macos_user_auth.m
0 → 100644
浏览文件 @
6759c79e
#import
<
LocalAuthentication
/
LocalAuthentication
.
h
>
void
macos
_
user
_
auth
(
void
(*cb)(int, void*)
,
void
*
cb
_
userdata
,
CFStringRef
message
)
{
static
LAContext
*
ctx
;
if
(
ctx
)
[
ctx
dealloc
]
;
ctx
=
[[
LAContext
alloc
]
init
]
;
[
ctx
evaluatePolicy
:
kLAPolicyDeviceOwnerAuthentication
localizedReason
:
(
NSString
*
)
message
reply
:^
(
BOOL
success
,
NSError
*
error
)
{
cb
(
success
,
cb
_
userdata
)
;
}]
;
}
\ No newline at end of file
plugins/wallet_plugin/se_wallet.cpp
0 → 100644
浏览文件 @
6759c79e
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eosio/wallet_plugin/se_wallet.hpp>
#include <eosio/wallet_plugin/macos_user_auth.h>
#include <eosio/chain/exceptions.hpp>
#include <fc/crypto/openssl.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <Security/Security.h>
#include <future>
namespace
eosio
{
namespace
wallet
{
using
namespace
fc
::
crypto
::
r1
;
namespace
detail
{
static
void
auth_callback
(
int
success
,
void
*
data
)
{
promise
<
bool
>*
prom
=
(
promise
<
bool
>*
)
data
;
prom
->
set_value
(
success
);
}
struct
se_wallet_impl
{
static
public_key_data
get_public_key_data
(
SecKeyRef
key
)
{
SecKeyRef
pubkey
=
SecKeyCopyPublicKey
(
key
);
CFErrorRef
error
=
nullptr
;
CFDataRef
keyrep
=
nullptr
;
keyrep
=
SecKeyCopyExternalRepresentation
(
pubkey
,
&
error
);
public_key_data
pub_key_data
;
if
(
!
error
)
{
const
UInt8
*
cfdata
=
CFDataGetBytePtr
(
keyrep
);
memcpy
(
pub_key_data
.
data
+
1
,
cfdata
+
1
,
32
);
pub_key_data
.
data
[
0
]
=
0x02
+
(
cfdata
[
64
]
&
1
);
}
CFRelease
(
keyrep
);
CFRelease
(
pubkey
);
if
(
error
)
{
string
error_string
=
string_for_cferror
(
error
);
CFRelease
(
error
);
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Failed to get public key from Secure Enclave: ${m}"
,
(
"m"
,
error_string
));
}
return
pub_key_data
;
}
static
public_key_type
get_public_key
(
SecKeyRef
key
)
{
char
serialized_pub_key
[
sizeof
(
public_key_data
)
+
1
];
serialized_pub_key
[
0
]
=
0x01
;
public_key_data
pub_key_data
=
get_public_key_data
(
key
);
memcpy
(
serialized_pub_key
+
1
,
pub_key_data
.
data
,
sizeof
(
pub_key_data
));
public_key_type
pub_key
;
fc
::
datastream
<
const
char
*>
ds
(
serialized_pub_key
,
sizeof
(
serialized_pub_key
));
fc
::
raw
::
unpack
(
ds
,
pub_key
);
return
pub_key
;
}
static
string
string_for_cferror
(
CFErrorRef
error
)
{
CFStringRef
errorString
=
CFCopyDescription
(
error
);
char
buff
[
CFStringGetLength
(
errorString
)
+
1
];
string
ret
;
if
(
CFStringGetCString
(
errorString
,
buff
,
sizeof
(
buff
),
kCFStringEncodingUTF8
))
ret
=
buff
;
else
ret
=
"Unknown"
;
CFRelease
(
errorString
);
return
ret
;
}
#define XSTR(A) STR(A)
#define STR(A) #A
void
populate_existing_keys
()
{
const
void
*
keyAttrKeys
[]
=
{
kSecClass
,
kSecAttrKeyClass
,
kSecMatchLimit
,
kSecReturnRef
,
kSecAttrTokenID
,
kSecAttrAccessGroup
};
const
void
*
keyAttrValues
[]
=
{
kSecClassKey
,
kSecAttrKeyClassPrivate
,
kSecMatchLimitAll
,
kCFBooleanTrue
,
kSecAttrTokenIDSecureEnclave
,
#ifdef MAS_KEYCHAIN_GROUP
CFSTR
(
XSTR
(
MAS_KEYCHAIN_GROUP
))
#endif
};
CFDictionaryRef
keyAttrDic
=
CFDictionaryCreate
(
nullptr
,
keyAttrKeys
,
keyAttrValues
,
sizeof
(
keyAttrValues
)
/
sizeof
(
keyAttrValues
[
0
]),
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
CFArrayRef
keyRefs
=
nullptr
;
if
(
SecItemCopyMatching
(
keyAttrDic
,
(
CFTypeRef
*
)
&
keyRefs
)
||
!
keyRefs
)
{
CFRelease
(
keyAttrDic
);
return
;
}
CFIndex
count
=
CFArrayGetCount
(
keyRefs
);
for
(
long
i
=
0
;
i
<
count
;
++
i
)
{
public_key_type
pub
;
try
{
SecKeyRef
key
=
(
SecKeyRef
)
CFRetain
(
CFArrayGetValueAtIndex
(
keyRefs
,
i
));
_keys
[
get_public_key
(
key
)]
=
key
;
}
catch
(
chain
::
wallet_exception
&
)
{}
}
CFRelease
(
keyRefs
);
CFRelease
(
keyAttrDic
);
}
public_key_type
create
()
{
SecAccessControlRef
accessControlRef
=
SecAccessControlCreateWithFlags
(
nullptr
,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
,
kSecAccessControlPrivateKeyUsage
,
nullptr
);
int
keySizeValue
=
256
;
CFNumberRef
keySizeNumber
=
CFNumberCreate
(
NULL
,
kCFNumberIntType
,
&
keySizeValue
);
const
void
*
keyAttrKeys
[]
=
{
kSecAttrIsPermanent
,
kSecAttrAccessControl
,
kSecAttrAccessGroup
};
const
void
*
keyAttrValues
[]
=
{
kCFBooleanTrue
,
accessControlRef
,
#ifdef MAS_KEYCHAIN_GROUP
CFSTR
(
XSTR
(
MAS_KEYCHAIN_GROUP
))
#endif
};
CFDictionaryRef
keyAttrDic
=
CFDictionaryCreate
(
NULL
,
keyAttrKeys
,
keyAttrValues
,
sizeof
(
keyAttrValues
)
/
sizeof
(
keyAttrValues
[
0
]),
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
const
void
*
attrKeys
[]
=
{
kSecAttrKeyType
,
kSecAttrKeySizeInBits
,
kSecAttrTokenID
,
kSecPrivateKeyAttrs
};
const
void
*
atrrValues
[]
=
{
kSecAttrKeyTypeECSECPrimeRandom
,
keySizeNumber
,
kSecAttrTokenIDSecureEnclave
,
keyAttrDic
};
CFDictionaryRef
attributesDic
=
CFDictionaryCreate
(
NULL
,
attrKeys
,
atrrValues
,
sizeof
(
attrKeys
)
/
sizeof
(
attrKeys
[
0
]),
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
CFErrorRef
error
=
NULL
;
SecKeyRef
privateKey
=
SecKeyCreateRandomKey
(
attributesDic
,
&
error
);
string
error_string
;
if
(
error
)
{
error_string
=
string_for_cferror
(
error
);
CFRelease
(
error
);
}
CFRelease
(
attributesDic
);
CFRelease
(
keyAttrDic
);
CFRelease
(
keySizeNumber
);
CFRelease
(
accessControlRef
);
if
(
error_string
.
size
())
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Failed to create key in Secure Enclave: ${m}"
,
(
"m"
,
error_string
));
public_key_type
pub
;
try
{
pub
=
get_public_key
(
privateKey
);
}
catch
(
chain
::
wallet_exception
&
)
{
//possibly we should delete the key here?
CFRelease
(
privateKey
);
throw
;
}
_keys
[
pub
]
=
privateKey
;
return
pub
;
}
optional
<
signature_type
>
try_sign_digest
(
const
digest_type
d
,
const
public_key_type
public_key
)
{
auto
it
=
_keys
.
find
(
public_key
);
if
(
it
==
_keys
.
end
())
return
optional
<
signature_type
>
{};
fc
::
ecdsa_sig
sig
=
ECDSA_SIG_new
();
BIGNUM
*
r
=
BN_new
(),
*
s
=
BN_new
();
CFErrorRef
error
=
nullptr
;
CFDataRef
digestData
=
CFDataCreateWithBytesNoCopy
(
nullptr
,
(
UInt8
*
)
d
.
data
(),
d
.
data_size
(),
kCFAllocatorNull
);
CFDataRef
signature
=
SecKeyCreateSignature
(
it
->
second
,
kSecKeyAlgorithmECDSASignatureDigestX962SHA256
,
digestData
,
&
error
);
if
(
error
)
{
string
error_string
=
string_for_cferror
(
error
);
CFRelease
(
error
);
CFRelease
(
digestData
);
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Failed to sign digest in Secure Enclave: ${m}"
,
(
"m"
,
error_string
));
}
const
UInt8
*
der_bytes
=
CFDataGetBytePtr
(
signature
);
BN_bin2bn
(
der_bytes
+
4
,
der_bytes
[
3
],
r
);
BN_bin2bn
(
der_bytes
+
6
+
der_bytes
[
3
],
der_bytes
[
4
+
der_bytes
[
3
]
+
1
],
s
);
ECDSA_SIG_set0
(
sig
,
r
,
s
);
public_key_data
kd
;
compact_signature
compact_sig
;
try
{
kd
=
get_public_key_data
(
it
->
second
);
compact_sig
=
signature_from_ecdsa
(
key
,
kd
,
sig
,
d
);
}
catch
(
chain
::
wallet_exception
&
)
{
CFRelease
(
signature
);
CFRelease
(
digestData
);
throw
;
}
CFRelease
(
signature
);
CFRelease
(
digestData
);
char
serialized_signature
[
sizeof
(
compact_sig
)
+
1
];
serialized_signature
[
0
]
=
0x01
;
memcpy
(
serialized_signature
+
1
,
compact_sig
.
data
,
sizeof
(
compact_sig
));
signature_type
final_signature
;
fc
::
datastream
<
const
char
*>
ds
(
serialized_signature
,
sizeof
(
serialized_signature
));
fc
::
raw
::
unpack
(
ds
,
final_signature
);
return
final_signature
;
}
bool
remove_key
(
string
public_key
)
{
auto
it
=
_keys
.
find
(
public_key_type
{
public_key
});
if
(
it
==
_keys
.
end
())
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Given key to delete not found in Secure Enclave wallet"
);
promise
<
bool
>
prom
;
future
<
bool
>
fut
=
prom
.
get_future
();
macos_user_auth
(
auth_callback
,
&
prom
,
CFSTR
(
"remove a key from your EOSIO wallet"
));
if
(
!
fut
.
get
())
FC_THROW_EXCEPTION
(
chain
::
wallet_invalid_password_exception
,
"Local user authentication failed"
);
CFDictionaryRef
deleteDic
=
CFDictionaryCreate
(
nullptr
,
(
const
void
**
)
&
kSecValueRef
,
(
const
void
**
)
&
it
->
second
,
1
,
&
kCFTypeDictionaryKeyCallBacks
,
&
kCFTypeDictionaryValueCallBacks
);
OSStatus
ret
=
SecItemDelete
(
deleteDic
);
CFRelease
(
deleteDic
);
if
(
ret
)
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Failed to getremove key from Secure Enclave"
);
CFRelease
(
it
->
second
);
_keys
.
erase
(
it
);
return
true
;
}
~
se_wallet_impl
()
{
for
(
auto
&
k
:
_keys
)
CFRelease
(
k
.
second
);
}
map
<
public_key_type
,
SecKeyRef
>
_keys
;
fc
::
ec_key
key
=
EC_KEY_new_by_curve_name
(
NID_X9_62_prime256v1
);
bool
locked
=
true
;
};
static
void
check_signed
()
{
OSStatus
is_valid
{
0
};
pid_t
pid
=
getpid
();
SecCodeRef
code
=
nullptr
;
CFNumberRef
pidnumber
=
CFNumberCreate
(
kCFAllocatorDefault
,
kCFNumberSInt32Type
,
&
pid
);
CFDictionaryRef
piddict
=
CFDictionaryCreate
(
kCFAllocatorDefault
,
(
const
void
**
)
&
kSecGuestAttributePid
,
(
const
void
**
)
&
pidnumber
,
1
,
nullptr
,
nullptr
);
if
(
!
SecCodeCopyGuestWithAttributes
(
nullptr
,
piddict
,
kSecCSDefaultFlags
,
&
code
))
{
is_valid
=
SecCodeCheckValidity
(
code
,
kSecCSDefaultFlags
,
0
);
CFRelease
(
code
);
}
CFRelease
(
piddict
);
CFRelease
(
pidnumber
);
if
(
is_valid
!=
errSecSuccess
)
{
wlog
(
"Application does not have a valid signature; Secure Enclave support disabled"
);
FC_THROW
(
""
);
}
}
}
se_wallet
::
se_wallet
()
:
my
(
new
detail
::
se_wallet_impl
())
{
detail
::
check_signed
();
//How to figure out of SE is available?!
char
model
[
256
];
size_t
model_size
=
sizeof
(
model
);
if
(
sysctlbyname
(
"hw.model"
,
model
,
&
model_size
,
nullptr
,
0
)
==
0
)
{
if
(
strncmp
(
model
,
"iMacPro"
,
strlen
(
"iMacPro"
))
==
0
)
{
my
->
populate_existing_keys
();
return
;
}
unsigned
int
major
,
minor
;
if
(
sscanf
(
model
,
"MacBookPro%u,%u"
,
&
major
,
&
minor
)
==
2
)
{
if
(
major
>=
13
&&
minor
>=
2
)
{
my
->
populate_existing_keys
();
return
;
}
}
}
FC_THROW
(
"Secure Enclave not supported on this hardware"
);
}
se_wallet
::~
se_wallet
()
{
}
private_key_type
se_wallet
::
get_private_key
(
public_key_type
pubkey
)
const
{
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Obtaining private key for a key stored in Secure Enclave is impossible"
);
}
bool
se_wallet
::
is_locked
()
const
{
return
my
->
locked
;
}
void
se_wallet
::
lock
()
{
FC_ASSERT
(
!
is_locked
());
my
->
locked
=
true
;
}
void
se_wallet
::
unlock
(
string
password
)
{
promise
<
bool
>
prom
;
future
<
bool
>
fut
=
prom
.
get_future
();
macos_user_auth
(
detail
::
auth_callback
,
&
prom
,
CFSTR
(
"unlock your EOSIO wallet"
));
if
(
!
fut
.
get
())
FC_THROW_EXCEPTION
(
chain
::
wallet_invalid_password_exception
,
"Local user authentication failed"
);
my
->
locked
=
false
;
}
void
se_wallet
::
check_password
(
string
password
)
{
//just leave this as a noop for now; remove_key from wallet_mgr calls through here
}
void
se_wallet
::
set_password
(
string
password
)
{
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Secure Enclave wallet cannot have a password set"
);
}
map
<
public_key_type
,
private_key_type
>
se_wallet
::
list_keys
()
{
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"Getting the private keys from the Secure Enclave wallet is impossible"
);
}
flat_set
<
public_key_type
>
se_wallet
::
list_public_keys
()
{
flat_set
<
public_key_type
>
keys
;
boost
::
copy
(
my
->
_keys
|
boost
::
adaptors
::
map_keys
,
std
::
inserter
(
keys
,
keys
.
end
()));
return
keys
;
}
bool
se_wallet
::
import_key
(
string
wif_key
)
{
FC_THROW_EXCEPTION
(
chain
::
wallet_exception
,
"It is not possible to import a key in to the Secure Enclave wallet"
);
}
string
se_wallet
::
create_key
(
string
key_type
)
{
return
(
string
)
my
->
create
();
}
bool
se_wallet
::
remove_key
(
string
key
)
{
FC_ASSERT
(
!
is_locked
());
return
my
->
remove_key
(
key
);
}
optional
<
signature_type
>
se_wallet
::
try_sign_digest
(
const
digest_type
digest
,
const
public_key_type
public_key
)
{
return
my
->
try_sign_digest
(
digest
,
public_key
);
}
}}
\ No newline at end of file
plugins/wallet_plugin/wallet_manager.cpp
浏览文件 @
6759c79e
...
...
@@ -4,6 +4,7 @@
*/
#include <eosio/wallet_plugin/wallet_manager.hpp>
#include <eosio/wallet_plugin/wallet.hpp>
#include <eosio/wallet_plugin/se_wallet.hpp>
#include <eosio/chain/exceptions.hpp>
#include <boost/algorithm/string.hpp>
namespace
eosio
{
...
...
@@ -24,6 +25,14 @@ bool valid_filename(const string& name) {
return
boost
::
filesystem
::
path
(
name
).
filename
().
string
()
==
name
;
}
wallet_manager
::
wallet_manager
()
{
#ifdef __APPLE__
try
{
wallets
.
emplace
(
"SecureEnclave"
,
std
::
make_unique
<
se_wallet
>
());
}
catch
(
fc
::
exception
&
)
{}
#endif
}
void
wallet_manager
::
set_timeout
(
const
std
::
chrono
::
seconds
&
t
)
{
timeout
=
t
;
timeout_time
=
std
::
chrono
::
system_clock
::
now
()
+
timeout
;
...
...
plugins/wallet_plugin/wallet_plugin.cpp
浏览文件 @
6759c79e
...
...
@@ -16,9 +16,7 @@ namespace eosio {
static
appbase
::
abstract_plugin
&
_wallet_plugin
=
app
().
register_plugin
<
wallet_plugin
>
();
wallet_plugin
::
wallet_plugin
()
:
wallet_manager_ptr
(
new
wallet_manager
())
{
}
wallet_plugin
::
wallet_plugin
()
{}
wallet_manager
&
wallet_plugin
::
get_wallet_manager
()
{
return
*
wallet_manager_ptr
;
...
...
@@ -38,6 +36,8 @@ void wallet_plugin::set_program_options(options_description& cli, options_descri
void
wallet_plugin
::
plugin_initialize
(
const
variables_map
&
options
)
{
ilog
(
"initializing wallet plugin"
);
wallet_manager_ptr
=
std
::
make_unique
<
wallet_manager
>
();
if
(
options
.
count
(
"wallet-dir"
))
{
auto
dir
=
options
.
at
(
"wallet-dir"
).
as
<
boost
::
filesystem
::
path
>
();
if
(
dir
.
is_relative
())
...
...
programs/cleos/main.cpp
浏览文件 @
6759c79e
...
...
@@ -248,6 +248,15 @@ chain::action generate_nonce_action() {
return
chain
::
action
(
{},
config
::
null_account_name
,
"nonce"
,
fc
::
raw
::
pack
(
fc
::
time_point
::
now
().
time_since_epoch
().
count
()));
}
void
prompt_for_wallet_password
(
string
&
pw
,
const
string
&
name
)
{
if
(
pw
.
size
()
==
0
&&
name
!=
"SecureEnclave"
)
{
std
::
cout
<<
localized
(
"password: "
);
fc
::
set_console_echo
(
false
);
std
::
getline
(
std
::
cin
,
pw
,
'\n'
);
fc
::
set_console_echo
(
true
);
}
}
fc
::
variant
determine_required_keys
(
const
signed_transaction
&
trx
)
{
// TODO better error checking
//wdump((trx));
...
...
@@ -2188,12 +2197,7 @@ int main( int argc, char** argv ) {
unlockWallet
->
add_option
(
"-n,--name"
,
wallet_name
,
localized
(
"The name of the wallet to unlock"
));
unlockWallet
->
add_option
(
"--password"
,
wallet_pw
,
localized
(
"The password returned by wallet create"
));
unlockWallet
->
set_callback
([
&
wallet_name
,
&
wallet_pw
]
{
if
(
wallet_pw
.
size
()
==
0
)
{
std
::
cout
<<
localized
(
"password: "
);
fc
::
set_console_echo
(
false
);
std
::
getline
(
std
::
cin
,
wallet_pw
,
'\n'
);
fc
::
set_console_echo
(
true
);
}
prompt_for_wallet_password
(
wallet_pw
,
wallet_name
);
fc
::
variants
vs
=
{
fc
::
variant
(
wallet_name
),
fc
::
variant
(
wallet_pw
)};
call
(
wallet_url
,
wallet_unlock
,
vs
);
...
...
@@ -2226,12 +2230,7 @@ int main( int argc, char** argv ) {
removeKeyWallet
->
add_option
(
"key"
,
wallet_rm_key_str
,
localized
(
"Public key in WIF format to remove"
))
->
required
();
removeKeyWallet
->
add_option
(
"--password"
,
wallet_pw
,
localized
(
"The password returned by wallet create"
));
removeKeyWallet
->
set_callback
([
&
wallet_name
,
&
wallet_pw
,
&
wallet_rm_key_str
]
{
if
(
wallet_pw
.
size
()
==
0
)
{
std
::
cout
<<
localized
(
"password: "
);
fc
::
set_console_echo
(
false
);
std
::
getline
(
std
::
cin
,
wallet_pw
,
'\n'
);
fc
::
set_console_echo
(
true
);
}
prompt_for_wallet_password
(
wallet_pw
,
wallet_name
);
public_key_type
pubkey
;
try
{
pubkey
=
public_key_type
(
wallet_rm_key_str
);
...
...
@@ -2275,12 +2274,7 @@ int main( int argc, char** argv ) {
listPrivKeys
->
add_option
(
"-n,--name"
,
wallet_name
,
localized
(
"The name of the wallet to list keys from"
),
true
);
listPrivKeys
->
add_option
(
"--password"
,
wallet_pw
,
localized
(
"The password returned by wallet create"
));
listPrivKeys
->
set_callback
([
&
wallet_name
,
&
wallet_pw
]
{
if
(
wallet_pw
.
size
()
==
0
)
{
std
::
cout
<<
localized
(
"password: "
);
fc
::
set_console_echo
(
false
);
std
::
getline
(
std
::
cin
,
wallet_pw
,
'\n'
);
fc
::
set_console_echo
(
true
);
}
prompt_for_wallet_password
(
wallet_pw
,
wallet_name
);
fc
::
variants
vs
=
{
fc
::
variant
(
wallet_name
),
fc
::
variant
(
wallet_pw
)};
const
auto
&
v
=
call
(
wallet_url
,
wallet_list_keys
,
vs
);
std
::
cout
<<
fc
::
json
::
to_pretty_string
(
v
)
<<
std
::
endl
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录