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
e273031d
Commit
e273031d
authored
Mar 20, 2019
by
Guillaume Ballet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix key derivation
parent
7ec6fa03
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
66 deletions
+33
-66
wallet.go
accounts/scwallet/wallet.go
+33
-66
No files found.
accounts/scwallet/wallet.go
View file @
e273031d
...
...
@@ -40,6 +40,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/log"
pcsc
"github.com/gballet/go-libpcsclite"
"github.com/status-im/keycard-go/derivationpath"
)
// ErrPairingPasswordNeeded is returned if opening the smart card requires pairing with a pairing
...
...
@@ -67,9 +68,9 @@ var ErrAlreadyOpen = errors.New("smartcard: already open")
var
ErrPubkeyMismatch
=
errors
.
New
(
"smartcard: recovered public key mismatch"
)
var
(
// appletAID = []byte{0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x57, 0x61, 0x6C, 0x6C, 0x65, 0x74, 0x41, 0x70, 0x70
}
appletAID
=
[]
byte
{
0xA0
,
0x00
,
0x00
,
0x08
,
0x04
,
0x00
,
0x01
,
0x01
,
0x01
}
DerivationSignatureHash
=
sha256
.
Sum256
(
[]
byte
(
"STATUS KEY DERIVATION"
))
appletAID
=
[]
byte
{
0xA0
,
0x00
,
0x00
,
0x08
,
0x04
,
0x00
,
0x01
,
0x01
,
0x01
}
// DerivationSignatureHash is used to derive the public key from the signature of this hash
DerivationSignatureHash
=
sha256
.
Sum256
(
common
.
Hash
{}
.
Bytes
(
))
)
const
(
...
...
@@ -926,93 +927,59 @@ func (s *Session) initialize(seed []byte) error {
// derive derives a new HD key path on the card.
func
(
s
*
Session
)
derive
(
path
accounts
.
DerivationPath
)
(
accounts
.
Account
,
error
)
{
// If the current path is a prefix of the desired path, we don't have to
// start again.
remainingPath
:=
path
pubkey
,
err
:=
s
.
publicKey
()
if
err
!=
nil
{
return
accounts
.
Account
{},
err
}
currentPath
,
err
:=
s
.
derivationPath
()
startingPoint
,
path
,
err
:=
derivationpath
.
Decode
(
path
.
String
())
if
err
!=
nil
{
return
accounts
.
Account
{},
err
}
reset
:=
false
if
len
(
currentPath
)
<=
len
(
path
)
{
for
i
:=
0
;
i
<
len
(
currentPath
);
i
++
{
if
path
[
i
]
!=
currentPath
[
i
]
{
reset
=
true
break
}
}
if
!
reset
{
remainingPath
=
path
[
len
(
currentPath
)
:
]
}
}
else
{
reset
=
true
var
p1
uint8
switch
startingPoint
{
case
derivationpath
.
StartingPointMaster
:
p1
=
P1DeriveKeyFromMaster
case
derivationpath
.
StartingPointParent
:
p1
=
P1DeriveKeyFromParent
case
derivationpath
.
StartingPointCurrent
:
p1
=
P1DeriveKeyFromCurrent
default
:
return
accounts
.
Account
{},
fmt
.
Errorf
(
"invalid startingPoint %d"
,
startingPoint
)
}
for
_
,
pathComponent
:=
range
remainingPath
{
pubkey
,
err
=
s
.
deriveKeyAssisted
(
reset
,
pathComponent
)
reset
=
false
if
err
!=
nil
{
data
:=
new
(
bytes
.
Buffer
)
for
_
,
segment
:=
range
path
{
if
err
:=
binary
.
Write
(
data
,
binary
.
BigEndian
,
segment
);
err
!=
nil
{
return
accounts
.
Account
{},
err
}
}
pub
,
err
:=
crypto
.
UnmarshalPubkey
(
pubkey
)
_
,
err
=
s
.
Channel
.
TransmitEncrypted
(
claSCWallet
,
insDeriveKey
,
p1
,
0
,
data
.
Bytes
())
if
err
!=
nil
{
return
accounts
.
Account
{},
err
}
return
s
.
Wallet
.
makeAccount
(
crypto
.
PubkeyToAddress
(
*
pub
),
path
),
nil
}
// keyDerivationInfo contains information on the current key derivation step.
type
keyDerivationInfo
struct
{
PublicKeyX
[]
byte
`asn1:"tag:3"`
// The X coordinate of the current public key
Signature
struct
{
R
*
big
.
Int
S
*
big
.
Int
}
}
// deriveKeyAssisted does one step of assisted key generation, asking the card to generate
// a specific path, and performing the necessary computations to finish the public key
// generation step.
func
(
s
*
Session
)
deriveKeyAssisted
(
reset
bool
,
pathComponent
uint32
)
([]
byte
,
error
)
{
p1
:=
deriveP1Assisted
if
!
reset
{
p1
|=
deriveP1Append
}
buf
:=
new
(
bytes
.
Buffer
)
if
err
:=
binary
.
Write
(
buf
,
binary
.
BigEndian
,
pathComponent
);
err
!=
nil
{
return
nil
,
err
}
response
,
err
:=
s
.
Channel
.
TransmitEncrypted
(
claSCWallet
,
insDeriveKey
,
p1
,
deriveP2KeyPath
,
buf
.
Bytes
())
response
,
err
:=
s
.
Channel
.
TransmitEncrypted
(
claSCWallet
,
insSign
,
0
,
0
,
DerivationSignatureHash
[
:
])
if
err
!=
nil
{
return
nil
,
err
return
accounts
.
Account
{}
,
err
}
keyinfo
:=
new
(
keyDerivationInfo
)
if
_
,
err
:=
asn1
.
UnmarshalWithParams
(
response
.
Data
,
keyinfo
,
"tag:2
"
);
err
!=
nil
{
return
nil
,
err
sigdata
:=
new
(
signatureData
)
if
_
,
err
:=
asn1
.
UnmarshalWithParams
(
response
.
Data
,
sigdata
,
"tag:0
"
);
err
!=
nil
{
return
accounts
.
Account
{}
,
err
}
rbytes
,
sbytes
:=
keyinfo
.
Signature
.
R
.
Bytes
(),
keyinfo
.
Signature
.
S
.
Bytes
()
rbytes
,
sbytes
:=
sigdata
.
Signature
.
R
.
Bytes
(),
sigdata
.
Signature
.
S
.
Bytes
()
sig
:=
make
([]
byte
,
65
)
copy
(
sig
[
32
-
len
(
rbytes
)
:
32
],
rbytes
)
copy
(
sig
[
64
-
len
(
sbytes
)
:
64
],
sbytes
)
pubkey
,
err
:=
determinePublicKey
(
sig
,
keyinfo
.
PublicKeyX
)
pubkey
,
err
:=
determinePublicKey
(
sig
,
sigdata
.
PublicKey
)
if
err
!=
nil
{
return
nil
,
err
return
accounts
.
Account
{}
,
err
}
_
,
err
=
s
.
Channel
.
TransmitEncrypted
(
claSCWallet
,
insDeriveKey
,
deriveP1Assisted
|
deriveP1Append
,
deriveP2PublicKey
,
pubkey
)
pub
,
err
:=
crypto
.
UnmarshalPubkey
(
pubkey
)
if
err
!=
nil
{
return
nil
,
err
return
accounts
.
Account
{}
,
err
}
return
pubkey
,
nil
return
s
.
Wallet
.
makeAccount
(
crypto
.
PubkeyToAddress
(
*
pub
),
path
)
,
nil
}
// keyExport contains information on an exported keypair.
...
...
@@ -1085,7 +1052,7 @@ func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) {
sig
[
64
]
=
byte
(
v
)
pubkey
,
err
:=
crypto
.
Ecrecover
(
DerivationSignatureHash
[
:
],
sig
)
if
err
==
nil
{
if
bytes
.
Equal
(
pubkey
[
1
:
33
]
,
pubkeyX
)
{
if
bytes
.
Equal
(
pubkey
,
pubkeyX
)
{
return
pubkey
,
nil
}
}
else
if
v
==
1
||
err
!=
secp256k1
.
ErrRecoverFailed
{
...
...
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