Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
78375608
Commit
78375608
authored
Feb 22, 2018
by
Nick Johnson
Committed by
Guillaume Ballet
Apr 08, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounts, internal: Changes in response to review
parent
f7027dd6
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
137 additions
and
118 deletions
+137
-118
hd.go
accounts/hd.go
+4
-4
apdu.go
accounts/scwallet/apdu.go
+12
-12
hub.go
accounts/scwallet/hub.go
+28
-11
securechannel.go
accounts/scwallet/securechannel.go
+36
-36
wallet.go
accounts/scwallet/wallet.go
+55
-55
api.go
internal/ethapi/api.go
+2
-0
No files found.
accounts/hd.go
View file @
78375608
...
@@ -139,12 +139,12 @@ func (path DerivationPath) MarshalJSON() ([]byte, error) {
...
@@ -139,12 +139,12 @@ func (path DerivationPath) MarshalJSON() ([]byte, error) {
return
[]
byte
(
fmt
.
Sprintf
(
"
\"
%s
\"
"
,
path
.
String
())),
nil
return
[]
byte
(
fmt
.
Sprintf
(
"
\"
%s
\"
"
,
path
.
String
())),
nil
}
}
func
(
dp
*
DerivationPath
)
UnmarshalJSON
(
b
[]
byte
)
error
{
func
(
path
*
DerivationPath
)
UnmarshalJSON
(
b
[]
byte
)
error
{
var
path
string
var
dp
string
var
err
error
var
err
error
if
err
=
json
.
Unmarshal
(
b
,
&
path
);
err
!=
nil
{
if
err
=
json
.
Unmarshal
(
b
,
&
dp
);
err
!=
nil
{
return
err
return
err
}
}
*
dp
,
err
=
ParseDerivationPath
(
path
)
*
path
,
err
=
ParseDerivationPath
(
dp
)
return
err
return
err
}
}
accounts/scwallet/apdu.go
View file @
78375608
...
@@ -22,20 +22,20 @@ import (
...
@@ -22,20 +22,20 @@ import (
)
)
const
(
const
(
CLA_
ISO7816
=
0
cla
ISO7816
=
0
INS_SELECT
=
0xA4
insSelect
=
0xA4
INS_GET_RESPONSE
=
0xC0
insGetResponse
=
0xC0
INS_PAIR
=
0x12
insPair
=
0x12
INS_UNPAIR
=
0x13
insUnpair
=
0x13
INS_OPEN_SECURE_CHANNEL
=
0x10
insOpenSecureChannel
=
0x10
INS_MUTUALLY_AUTHENTICATE
=
0x11
insMutuallyAuthenticate
=
0x11
SW1_GET_RESPONSE
=
0x61
sw1GetResponse
=
0x61
SW1_OK
=
0x90
sw1Ok
=
0x90
)
)
// CommandAPDU represents an application data unit sent to a smartcard
// CommandAPDU represents an application data unit sent to a smartcard
.
type
CommandAPDU
struct
{
type
CommandAPDU
struct
{
Cla
,
Ins
,
P1
,
P2
uint8
// Class, Instruction, Parameter 1, Parameter 2
Cla
,
Ins
,
P1
,
P2
uint8
// Class, Instruction, Parameter 1, Parameter 2
Data
[]
byte
// Command data
Data
[]
byte
// Command data
...
@@ -72,13 +72,13 @@ func (ca CommandAPDU) serialize() ([]byte, error) {
...
@@ -72,13 +72,13 @@ func (ca CommandAPDU) serialize() ([]byte, error) {
return
buf
.
Bytes
(),
nil
return
buf
.
Bytes
(),
nil
}
}
// ResponseAPDU represents an application data unit received from a smart card
// ResponseAPDU represents an application data unit received from a smart card
.
type
ResponseAPDU
struct
{
type
ResponseAPDU
struct
{
Data
[]
byte
// response data
Data
[]
byte
// response data
Sw1
,
Sw2
uint8
// status words 1 and 2
Sw1
,
Sw2
uint8
// status words 1 and 2
}
}
// deserialize deserializes a response APDU
// deserialize deserializes a response APDU
.
func
(
ra
*
ResponseAPDU
)
deserialize
(
data
[]
byte
)
error
{
func
(
ra
*
ResponseAPDU
)
deserialize
(
data
[]
byte
)
error
{
ra
.
Data
=
make
([]
byte
,
len
(
data
)
-
2
)
ra
.
Data
=
make
([]
byte
,
len
(
data
)
-
2
)
...
...
accounts/scwallet/hub.go
View file @
78375608
...
@@ -14,6 +14,22 @@
...
@@ -14,6 +14,22 @@
// You should have received a copy of the GNU Lesser General Public License
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// This package implements support for smartcard-based hardware wallets such as
// the one written by Status: https://github.com/status-im/hardware-wallet
//
// This implementation of smartcard wallets have a different interaction process
// to other types of hardware wallet. The process works like this:
//
// 1. (First use with a given client) Establish a pairing between hardware
// wallet and client. This requires a secret value called a 'PUK'. You can
// pair with an unpaired wallet with `personal.openWallet(URI, PUK)`.
// 2. (First use only) Initialize the wallet, which generates a keypair, stores
// it on the wallet, and returns it so the user can back it up. You can
// initialize a wallet with `personal.initializeWallet(URI)`.
// 3. Connect to the wallet using the pairing information established in step 1.
// You can connect to a paired wallet with `personal.openWallet(URI, PIN)`.
// 4. Interact with the wallet as normal.
package
scwallet
package
scwallet
import
(
import
(
...
@@ -32,6 +48,7 @@ import (
...
@@ -32,6 +48,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
)
)
// Scheme is the URI prefix for smartcard wallets.
const
Scheme
=
"pcsc"
const
Scheme
=
"pcsc"
// refreshCycle is the maximum time between wallet refreshes (if USB hotplug
// refreshCycle is the maximum time between wallet refreshes (if USB hotplug
...
@@ -41,9 +58,9 @@ const refreshCycle = 5 * time.Second
...
@@ -41,9 +58,9 @@ const refreshCycle = 5 * time.Second
// refreshThrottling is the minimum time between wallet refreshes to avoid thrashing.
// refreshThrottling is the minimum time between wallet refreshes to avoid thrashing.
const
refreshThrottling
=
500
*
time
.
Millisecond
const
refreshThrottling
=
500
*
time
.
Millisecond
//
S
martcardPairing contains information about a smart card we have paired with
//
s
martcardPairing contains information about a smart card we have paired with
// or might pair withub.
// or might pair with
the h
ub.
type
S
martcardPairing
struct
{
type
s
martcardPairing
struct
{
PublicKey
[]
byte
`json:"publicKey"`
PublicKey
[]
byte
`json:"publicKey"`
PairingIndex
uint8
`json:"pairingIndex"`
PairingIndex
uint8
`json:"pairingIndex"`
PairingKey
[]
byte
`json:"pairingKey"`
PairingKey
[]
byte
`json:"pairingKey"`
...
@@ -56,7 +73,7 @@ type Hub struct {
...
@@ -56,7 +73,7 @@ type Hub struct {
context
*
scard
.
Context
context
*
scard
.
Context
datadir
string
datadir
string
pairings
map
[
string
]
S
martcardPairing
pairings
map
[
string
]
s
martcardPairing
refreshed
time
.
Time
// Time instance when the list of wallets was last refreshed
refreshed
time
.
Time
// Time instance when the list of wallets was last refreshed
wallets
map
[
string
]
*
Wallet
// Mapping from reader names to wallet instances
wallets
map
[
string
]
*
Wallet
// Mapping from reader names to wallet instances
updateFeed
event
.
Feed
// Event feed to notify wallet additions/removals
updateFeed
event
.
Feed
// Event feed to notify wallet additions/removals
...
@@ -71,7 +88,7 @@ type Hub struct {
...
@@ -71,7 +88,7 @@ type Hub struct {
var
HubType
=
reflect
.
TypeOf
(
&
Hub
{})
var
HubType
=
reflect
.
TypeOf
(
&
Hub
{})
func
(
hub
*
Hub
)
readPairings
()
error
{
func
(
hub
*
Hub
)
readPairings
()
error
{
hub
.
pairings
=
make
(
map
[
string
]
S
martcardPairing
)
hub
.
pairings
=
make
(
map
[
string
]
s
martcardPairing
)
pairingFile
,
err
:=
os
.
Open
(
hub
.
datadir
+
"/smartcards.json"
)
pairingFile
,
err
:=
os
.
Open
(
hub
.
datadir
+
"/smartcards.json"
)
if
err
!=
nil
{
if
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
if
os
.
IsNotExist
(
err
)
{
...
@@ -84,7 +101,7 @@ func (hub *Hub) readPairings() error {
...
@@ -84,7 +101,7 @@ func (hub *Hub) readPairings() error {
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
var
pairings
[]
S
martcardPairing
var
pairings
[]
s
martcardPairing
if
err
:=
json
.
Unmarshal
(
pairingData
,
&
pairings
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
pairingData
,
&
pairings
);
err
!=
nil
{
return
err
return
err
}
}
...
@@ -101,7 +118,7 @@ func (hub *Hub) writePairings() error {
...
@@ -101,7 +118,7 @@ func (hub *Hub) writePairings() error {
return
err
return
err
}
}
pairings
:=
make
([]
S
martcardPairing
,
0
,
len
(
hub
.
pairings
))
pairings
:=
make
([]
s
martcardPairing
,
0
,
len
(
hub
.
pairings
))
for
_
,
pairing
:=
range
hub
.
pairings
{
for
_
,
pairing
:=
range
hub
.
pairings
{
pairings
=
append
(
pairings
,
pairing
)
pairings
=
append
(
pairings
,
pairing
)
}
}
...
@@ -118,7 +135,7 @@ func (hub *Hub) writePairings() error {
...
@@ -118,7 +135,7 @@ func (hub *Hub) writePairings() error {
return
pairingFile
.
Close
()
return
pairingFile
.
Close
()
}
}
func
(
hub
*
Hub
)
getPairing
(
wallet
*
Wallet
)
*
S
martcardPairing
{
func
(
hub
*
Hub
)
getPairing
(
wallet
*
Wallet
)
*
s
martcardPairing
{
pairing
,
ok
:=
hub
.
pairings
[
string
(
wallet
.
PublicKey
)]
pairing
,
ok
:=
hub
.
pairings
[
string
(
wallet
.
PublicKey
)]
if
ok
{
if
ok
{
return
&
pairing
return
&
pairing
...
@@ -126,7 +143,7 @@ func (hub *Hub) getPairing(wallet *Wallet) *SmartcardPairing {
...
@@ -126,7 +143,7 @@ func (hub *Hub) getPairing(wallet *Wallet) *SmartcardPairing {
return
nil
return
nil
}
}
func
(
hub
*
Hub
)
setPairing
(
wallet
*
Wallet
,
pairing
*
S
martcardPairing
)
error
{
func
(
hub
*
Hub
)
setPairing
(
wallet
*
Wallet
,
pairing
*
s
martcardPairing
)
error
{
if
pairing
==
nil
{
if
pairing
==
nil
{
delete
(
hub
.
pairings
,
string
(
wallet
.
PublicKey
))
delete
(
hub
.
pairings
,
string
(
wallet
.
PublicKey
))
}
else
{
}
else
{
...
@@ -158,7 +175,7 @@ func NewHub(scheme string, datadir string) (*Hub, error) {
...
@@ -158,7 +175,7 @@ func NewHub(scheme string, datadir string) (*Hub, error) {
return
hub
,
nil
return
hub
,
nil
}
}
// Wallets implements accounts.Backend, returning all the currently tracked
USB
// Wallets implements accounts.Backend, returning all the currently tracked
// devices that appear to be hardware wallets.
// devices that appear to be hardware wallets.
func
(
hub
*
Hub
)
Wallets
()
[]
accounts
.
Wallet
{
func
(
hub
*
Hub
)
Wallets
()
[]
accounts
.
Wallet
{
// Make sure the list of wallets is up to date
// Make sure the list of wallets is up to date
...
@@ -176,7 +193,7 @@ func (hub *Hub) Wallets() []accounts.Wallet {
...
@@ -176,7 +193,7 @@ func (hub *Hub) Wallets() []accounts.Wallet {
return
cpy
return
cpy
}
}
// refreshWallets scans the
USB
devices attached to the machine and updates the
// refreshWallets scans the devices attached to the machine and updates the
// list of wallets based on the found devices.
// list of wallets based on the found devices.
func
(
hub
*
Hub
)
refreshWallets
()
{
func
(
hub
*
Hub
)
refreshWallets
()
{
elapsed
:=
time
.
Since
(
hub
.
refreshed
)
elapsed
:=
time
.
Since
(
hub
.
refreshed
)
...
...
accounts/scwallet/securechannel.go
View file @
78375608
...
@@ -32,15 +32,15 @@ import (
...
@@ -32,15 +32,15 @@ import (
)
)
const
(
const
(
MAX_PAYLOAD_SIZE
=
223
maxPayloadSize
=
223
PAIR_P1_FIRST_STEP
=
0
pairP1FirstStep
=
0
PAIR_P1_LAST_STEP
=
1
pairP1LastStep
=
1
SC_SECRET_LENGTH
=
32
scSecretLength
=
32
SC_BLOCK_SIZE
=
16
scBlockSize
=
16
)
)
// SecureChannelSession enables secure communication with a hardware wallet
// SecureChannelSession enables secure communication with a hardware wallet
.
type
SecureChannelSession
struct
{
type
SecureChannelSession
struct
{
card
*
scard
.
Card
// A handle to the smartcard for communication
card
*
scard
.
Card
// A handle to the smartcard for communication
secret
[]
byte
// A shared secret generated from our ECDSA keys
secret
[]
byte
// A shared secret generated from our ECDSA keys
...
@@ -52,7 +52,7 @@ type SecureChannelSession struct {
...
@@ -52,7 +52,7 @@ type SecureChannelSession struct {
PairingIndex
uint8
// The pairing index
PairingIndex
uint8
// The pairing index
}
}
// NewSecureChannelSession creates a new secure channel for the given card and public key
// NewSecureChannelSession creates a new secure channel for the given card and public key
.
func
NewSecureChannelSession
(
card
*
scard
.
Card
,
keyData
[]
byte
)
(
*
SecureChannelSession
,
error
)
{
func
NewSecureChannelSession
(
card
*
scard
.
Card
,
keyData
[]
byte
)
(
*
SecureChannelSession
,
error
)
{
// Generate an ECDSA keypair for ourselves
// Generate an ECDSA keypair for ourselves
gen
:=
ecdh
.
NewEllipticECDH
(
crypto
.
S256
())
gen
:=
ecdh
.
NewEllipticECDH
(
crypto
.
S256
())
...
@@ -78,7 +78,7 @@ func NewSecureChannelSession(card *scard.Card, keyData []byte) (*SecureChannelSe
...
@@ -78,7 +78,7 @@ func NewSecureChannelSession(card *scard.Card, keyData []byte) (*SecureChannelSe
},
nil
},
nil
}
}
// Pair establishes a new pairing with the smartcard
// Pair establishes a new pairing with the smartcard
.
func
(
s
*
SecureChannelSession
)
Pair
(
sharedSecret
[]
byte
)
error
{
func
(
s
*
SecureChannelSession
)
Pair
(
sharedSecret
[]
byte
)
error
{
secretHash
:=
sha256
.
Sum256
(
sharedSecret
)
secretHash
:=
sha256
.
Sum256
(
sharedSecret
)
...
@@ -87,7 +87,7 @@ func (s *SecureChannelSession) Pair(sharedSecret []byte) error {
...
@@ -87,7 +87,7 @@ func (s *SecureChannelSession) Pair(sharedSecret []byte) error {
return
err
return
err
}
}
response
,
err
:=
s
.
pair
(
PAIR_P1_FIRST_STEP
,
challenge
)
response
,
err
:=
s
.
pair
(
pairP1FirstStep
,
challenge
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -107,7 +107,7 @@ func (s *SecureChannelSession) Pair(sharedSecret []byte) error {
...
@@ -107,7 +107,7 @@ func (s *SecureChannelSession) Pair(sharedSecret []byte) error {
md
.
Reset
()
md
.
Reset
()
md
.
Write
(
secretHash
[
:
])
md
.
Write
(
secretHash
[
:
])
md
.
Write
(
cardChallenge
)
md
.
Write
(
cardChallenge
)
response
,
err
=
s
.
pair
(
PAIR_P1_LAST_STEP
,
md
.
Sum
(
nil
))
response
,
err
=
s
.
pair
(
pairP1LastStep
,
md
.
Sum
(
nil
))
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -121,13 +121,13 @@ func (s *SecureChannelSession) Pair(sharedSecret []byte) error {
...
@@ -121,13 +121,13 @@ func (s *SecureChannelSession) Pair(sharedSecret []byte) error {
return
nil
return
nil
}
}
// Unpair disestablishes an existing pairing
// Unpair disestablishes an existing pairing
.
func
(
s
*
SecureChannelSession
)
Unpair
()
error
{
func
(
s
*
SecureChannelSession
)
Unpair
()
error
{
if
s
.
PairingKey
==
nil
{
if
s
.
PairingKey
==
nil
{
return
fmt
.
Errorf
(
"Cannot unpair: not paired"
)
return
fmt
.
Errorf
(
"Cannot unpair: not paired"
)
}
}
_
,
err
:=
s
.
TransmitEncrypted
(
CLA_SCWALLET
,
INS_UNPAIR
,
s
.
PairingIndex
,
0
,
[]
byte
{})
_
,
err
:=
s
.
TransmitEncrypted
(
claSCWallet
,
insUnpair
,
s
.
PairingIndex
,
0
,
[]
byte
{})
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -137,7 +137,7 @@ func (s *SecureChannelSession) Unpair() error {
...
@@ -137,7 +137,7 @@ func (s *SecureChannelSession) Unpair() error {
return
nil
return
nil
}
}
// Open initializes the secure channel
// Open initializes the secure channel
.
func
(
s
*
SecureChannelSession
)
Open
()
error
{
func
(
s
*
SecureChannelSession
)
Open
()
error
{
if
s
.
iv
!=
nil
{
if
s
.
iv
!=
nil
{
return
fmt
.
Errorf
(
"Session already opened"
)
return
fmt
.
Errorf
(
"Session already opened"
)
...
@@ -153,13 +153,13 @@ func (s *SecureChannelSession) Open() error {
...
@@ -153,13 +153,13 @@ func (s *SecureChannelSession) Open() error {
md
:=
sha512
.
New
()
md
:=
sha512
.
New
()
md
.
Write
(
s
.
secret
)
md
.
Write
(
s
.
secret
)
md
.
Write
(
s
.
PairingKey
)
md
.
Write
(
s
.
PairingKey
)
md
.
Write
(
response
.
Data
[
:
SC_SECRET_LENGTH
])
md
.
Write
(
response
.
Data
[
:
scSecretLength
])
keyData
:=
md
.
Sum
(
nil
)
keyData
:=
md
.
Sum
(
nil
)
s
.
sessionEncKey
=
keyData
[
:
SC_SECRET_LENGTH
]
s
.
sessionEncKey
=
keyData
[
:
scSecretLength
]
s
.
sessionMacKey
=
keyData
[
SC_SECRET_LENGTH
:
SC_SECRET_LENGTH
*
2
]
s
.
sessionMacKey
=
keyData
[
scSecretLength
:
scSecretLength
*
2
]
// The IV is the last bytes returned from the Open APDU.
// The IV is the last bytes returned from the Open APDU.
s
.
iv
=
response
.
Data
[
SC_SECRET_LENGTH
:
]
s
.
iv
=
response
.
Data
[
scSecretLength
:
]
if
err
:=
s
.
mutuallyAuthenticate
();
err
!=
nil
{
if
err
:=
s
.
mutuallyAuthenticate
();
err
!=
nil
{
return
err
return
err
...
@@ -171,12 +171,12 @@ func (s *SecureChannelSession) Open() error {
...
@@ -171,12 +171,12 @@ func (s *SecureChannelSession) Open() error {
// mutuallyAuthenticate is an internal method to authenticate both ends of the
// mutuallyAuthenticate is an internal method to authenticate both ends of the
// connection.
// connection.
func
(
s
*
SecureChannelSession
)
mutuallyAuthenticate
()
error
{
func
(
s
*
SecureChannelSession
)
mutuallyAuthenticate
()
error
{
data
:=
make
([]
byte
,
SC_SECRET_LENGTH
)
data
:=
make
([]
byte
,
scSecretLength
)
if
_
,
err
:=
rand
.
Read
(
data
);
err
!=
nil
{
if
_
,
err
:=
rand
.
Read
(
data
);
err
!=
nil
{
return
err
return
err
}
}
response
,
err
:=
s
.
TransmitEncrypted
(
CLA_SCWALLET
,
INS_MUTUALLY_AUTHENTICATE
,
0
,
0
,
data
)
response
,
err
:=
s
.
TransmitEncrypted
(
claSCWallet
,
insMutuallyAuthenticate
,
0
,
0
,
data
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -184,18 +184,18 @@ func (s *SecureChannelSession) mutuallyAuthenticate() error {
...
@@ -184,18 +184,18 @@ func (s *SecureChannelSession) mutuallyAuthenticate() error {
return
fmt
.
Errorf
(
"Got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x"
,
response
.
Sw1
,
response
.
Sw2
)
return
fmt
.
Errorf
(
"Got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x"
,
response
.
Sw1
,
response
.
Sw2
)
}
}
if
len
(
response
.
Data
)
!=
SC_SECRET_LENGTH
{
if
len
(
response
.
Data
)
!=
scSecretLength
{
return
fmt
.
Errorf
(
"Response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d"
,
len
(
response
.
Data
),
SC_SECRET_LENGTH
)
return
fmt
.
Errorf
(
"Response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d"
,
len
(
response
.
Data
),
scSecretLength
)
}
}
return
nil
return
nil
}
}
// open is an internal method that sends an open APDU
// open is an internal method that sends an open APDU
.
func
(
s
*
SecureChannelSession
)
open
()
(
*
ResponseAPDU
,
error
)
{
func
(
s
*
SecureChannelSession
)
open
()
(
*
ResponseAPDU
,
error
)
{
return
transmit
(
s
.
card
,
&
CommandAPDU
{
return
transmit
(
s
.
card
,
&
CommandAPDU
{
Cla
:
CLA_SCWALLET
,
Cla
:
claSCWallet
,
Ins
:
INS_OPEN_SECURE_CHANNEL
,
Ins
:
insOpenSecureChannel
,
P1
:
s
.
PairingIndex
,
P1
:
s
.
PairingIndex
,
P2
:
0
,
P2
:
0
,
Data
:
s
.
publicKey
,
Data
:
s
.
publicKey
,
...
@@ -203,11 +203,11 @@ func (s *SecureChannelSession) open() (*ResponseAPDU, error) {
...
@@ -203,11 +203,11 @@ func (s *SecureChannelSession) open() (*ResponseAPDU, error) {
})
})
}
}
// pair is an internal method that sends a pair APDU
// pair is an internal method that sends a pair APDU
.
func
(
s
*
SecureChannelSession
)
pair
(
p1
uint8
,
data
[]
byte
)
(
*
ResponseAPDU
,
error
)
{
func
(
s
*
SecureChannelSession
)
pair
(
p1
uint8
,
data
[]
byte
)
(
*
ResponseAPDU
,
error
)
{
return
transmit
(
s
.
card
,
&
CommandAPDU
{
return
transmit
(
s
.
card
,
&
CommandAPDU
{
Cla
:
CLA_SCWALLET
,
Cla
:
claSCWallet
,
Ins
:
INS_PAIR
,
Ins
:
insPair
,
P1
:
p1
,
P1
:
p1
,
P2
:
0
,
P2
:
0
,
Data
:
data
,
Data
:
data
,
...
@@ -215,7 +215,7 @@ func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*ResponseAPDU, error
...
@@ -215,7 +215,7 @@ func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*ResponseAPDU, error
})
})
}
}
// TransmitEncrypted sends an encrypted message, and decrypts and returns the response
// TransmitEncrypted sends an encrypted message, and decrypts and returns the response
.
func
(
s
*
SecureChannelSession
)
TransmitEncrypted
(
cla
,
ins
,
p1
,
p2
byte
,
data
[]
byte
)
(
*
ResponseAPDU
,
error
)
{
func
(
s
*
SecureChannelSession
)
TransmitEncrypted
(
cla
,
ins
,
p1
,
p2
byte
,
data
[]
byte
)
(
*
ResponseAPDU
,
error
)
{
if
s
.
iv
==
nil
{
if
s
.
iv
==
nil
{
return
nil
,
fmt
.
Errorf
(
"Channel not open"
)
return
nil
,
fmt
.
Errorf
(
"Channel not open"
)
...
@@ -225,7 +225,7 @@ func (s *SecureChannelSession) TransmitEncrypted(cla, ins, p1, p2 byte, data []b
...
@@ -225,7 +225,7 @@ func (s *SecureChannelSession) TransmitEncrypted(cla, ins, p1, p2 byte, data []b
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
meta
:=
[]
byte
{
cla
,
ins
,
p1
,
p2
,
byte
(
len
(
data
)
+
SC_BLOCK_SIZE
),
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
meta
:=
[]
byte
{
cla
,
ins
,
p1
,
p2
,
byte
(
len
(
data
)
+
scBlockSize
),
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
if
err
=
s
.
updateIV
(
meta
,
data
);
err
!=
nil
{
if
err
=
s
.
updateIV
(
meta
,
data
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -263,17 +263,17 @@ func (s *SecureChannelSession) TransmitEncrypted(cla, ins, p1, p2 byte, data []b
...
@@ -263,17 +263,17 @@ func (s *SecureChannelSession) TransmitEncrypted(cla, ins, p1, p2 byte, data []b
rapdu
:=
&
ResponseAPDU
{}
rapdu
:=
&
ResponseAPDU
{}
rapdu
.
deserialize
(
plainData
)
rapdu
.
deserialize
(
plainData
)
if
rapdu
.
Sw1
!=
SW1_OK
{
if
rapdu
.
Sw1
!=
sw1Ok
{
return
nil
,
fmt
.
Errorf
(
"Unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x"
,
cla
,
ins
,
rapdu
.
Sw1
,
rapdu
.
Sw2
)
return
nil
,
fmt
.
Errorf
(
"Unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x"
,
cla
,
ins
,
rapdu
.
Sw1
,
rapdu
.
Sw2
)
}
}
return
rapdu
,
nil
return
rapdu
,
nil
}
}
// encryptAPDU is an internal method that serializes and encrypts an APDU
// encryptAPDU is an internal method that serializes and encrypts an APDU
.
func
(
s
*
SecureChannelSession
)
encryptAPDU
(
data
[]
byte
)
([]
byte
,
error
)
{
func
(
s
*
SecureChannelSession
)
encryptAPDU
(
data
[]
byte
)
([]
byte
,
error
)
{
if
len
(
data
)
>
MAX_PAYLOAD_SIZE
{
if
len
(
data
)
>
maxPayloadSize
{
return
nil
,
fmt
.
Errorf
(
"Payload of %d bytes exceeds maximum of %d"
,
len
(
data
),
MAX_PAYLOAD_SIZE
)
return
nil
,
fmt
.
Errorf
(
"Payload of %d bytes exceeds maximum of %d"
,
len
(
data
),
maxPayloadSize
)
}
}
data
=
pad
(
data
,
0x80
)
data
=
pad
(
data
,
0x80
)
...
@@ -288,7 +288,7 @@ func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) {
...
@@ -288,7 +288,7 @@ func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) {
return
ret
,
nil
return
ret
,
nil
}
}
// pad applies message padding to a 16 byte boundary
// pad applies message padding to a 16 byte boundary
.
func
pad
(
data
[]
byte
,
terminator
byte
)
[]
byte
{
func
pad
(
data
[]
byte
,
terminator
byte
)
[]
byte
{
padded
:=
make
([]
byte
,
(
len
(
data
)
/
16
+
1
)
*
16
)
padded
:=
make
([]
byte
,
(
len
(
data
)
/
16
+
1
)
*
16
)
copy
(
padded
,
data
)
copy
(
padded
,
data
)
...
@@ -296,7 +296,7 @@ func pad(data []byte, terminator byte) []byte {
...
@@ -296,7 +296,7 @@ func pad(data []byte, terminator byte) []byte {
return
padded
return
padded
}
}
// decryptAPDU is an internal method that decrypts and deserializes an APDU
// decryptAPDU is an internal method that decrypts and deserializes an APDU
.
func
(
s
*
SecureChannelSession
)
decryptAPDU
(
data
[]
byte
)
([]
byte
,
error
)
{
func
(
s
*
SecureChannelSession
)
decryptAPDU
(
data
[]
byte
)
([]
byte
,
error
)
{
a
,
err
:=
aes
.
NewCipher
(
s
.
sessionEncKey
)
a
,
err
:=
aes
.
NewCipher
(
s
.
sessionEncKey
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -310,7 +310,7 @@ func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) {
...
@@ -310,7 +310,7 @@ func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) {
return
unpad
(
ret
,
0x80
)
return
unpad
(
ret
,
0x80
)
}
}
// unpad strips padding from a message
// unpad strips padding from a message
.
func
unpad
(
data
[]
byte
,
terminator
byte
)
([]
byte
,
error
)
{
func
unpad
(
data
[]
byte
,
terminator
byte
)
([]
byte
,
error
)
{
for
i
:=
1
;
i
<=
16
;
i
++
{
for
i
:=
1
;
i
<=
16
;
i
++
{
switch
data
[
len
(
data
)
-
i
]
{
switch
data
[
len
(
data
)
-
i
]
{
...
...
accounts/scwallet/wallet.go
View file @
78375608
This diff is collapsed.
Click to expand it.
internal/ethapi/api.go
View file @
78375608
...
@@ -473,6 +473,7 @@ func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args Sen
...
@@ -473,6 +473,7 @@ func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args Sen
return
s
.
SendTransaction
(
ctx
,
args
,
passwd
)
return
s
.
SendTransaction
(
ctx
,
args
,
passwd
)
}
}
// InitializeWallet initializes a new wallet at the provided URL, by generating and returning a new private key.
func
(
s
*
PrivateAccountAPI
)
InitializeWallet
(
ctx
context
.
Context
,
url
string
)
(
string
,
error
)
{
func
(
s
*
PrivateAccountAPI
)
InitializeWallet
(
ctx
context
.
Context
,
url
string
)
(
string
,
error
)
{
wallet
,
err
:=
s
.
am
.
Wallet
(
url
)
wallet
,
err
:=
s
.
am
.
Wallet
(
url
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -499,6 +500,7 @@ func (s *PrivateAccountAPI) InitializeWallet(ctx context.Context, url string) (s
...
@@ -499,6 +500,7 @@ func (s *PrivateAccountAPI) InitializeWallet(ctx context.Context, url string) (s
}
}
}
}
// Unpair deletes a pairing between wallet and geth.
func
(
s
*
PrivateAccountAPI
)
Unpair
(
ctx
context
.
Context
,
url
string
,
pin
string
)
error
{
func
(
s
*
PrivateAccountAPI
)
Unpair
(
ctx
context
.
Context
,
url
string
,
pin
string
)
error
{
wallet
,
err
:=
s
.
am
.
Wallet
(
url
)
wallet
,
err
:=
s
.
am
.
Wallet
(
url
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment