Permalink
Browse files

FEAT: adds Trezor support.

  • Loading branch information...
qtxie
qtxie committed Sep 24, 2018
1 parent c657e0c commit f5ee1d0ce6639166bf389d83a584b424cbcee5f8
View
@@ -9,25 +9,8 @@ Red [
}
]
#include %rlp.red
to-bin8: func [v [integer! char!]][
to binary! to char! 256 + v and 255
]
to-bin16: func [v [integer! char!]][ ;-- big-endian encoding
skip to-binary to-integer v 2
]
to-bin32: func [v [integer! char!]][ ;-- big-endian encoding
to-binary to-integer v
]
to-int16: func [b [binary!]][
to-integer copy/part b 2
]
ledger: context [
name: "Ledger Nano S"
vendor-id: 2C97h
product-id: 1
@@ -37,17 +20,30 @@ ledger: context [
PACKET_SIZE: #either config/OS = 'Windows [65][64]
MAX_APDU_SIZE: 260
dongle: none
dongle: none
buffer: make binary! MAX_APDU_SIZE
data-frame: make binary! PACKET_SIZE
request-pin-state: 'Init
connect: func [][
unless dongle [
dongle: hid/open vendor-id product-id
]
dongle
]
init: func [][true]
close-pin-requesting: does [
request-pin-state: 'Init
]
request-pin: func [return: [word!]] [
request-pin-state: 'HasRequested
request-pin-state
]
read-apdu: func [
timeout [integer!] ;-- seconds
/local idx total msg-len data
@@ -115,37 +111,39 @@ ledger: context [
]
]
get-address: func [idx [integer!] /local data pub-key-len addr-len][
get-eth-address: func [bip32-path [block!] /local data pub-key-len addr-len][
data: make binary! 20
append data reduce [
E0h
02h
0
0
4 * 4 + 1
4
to-bin32 8000002Ch
to-bin32 8000003Ch
to-bin32 80000000h
to-bin32 idx
4 * (length? bip32-path) + 1
]
append data collect [
keep length? bip32-path
forall bip32-path [keep to-bin32 bip32-path/1]
]
write-apdu data
data: read-apdu 1
case [
40 < length? data [
;-- parse reply data
pub-key-len: to-integer data/1
addr-len: to-integer pick skip data pub-key-len + 1 1
rejoin ["0x" to-string copy/part skip data pub-key-len + 2 addr-len]
either 40 < length? data [
request-pin-state: 'HasRequested
;-- parse reply data
pub-key-len: to-integer data/1
addr-len: to-integer pick skip data pub-key-len + 1 1
rejoin ["0x" to-string copy/part skip data pub-key-len + 2 addr-len]
][
request-pin-state: 'Requesting
case [
#{BF00018D} = data ['browser-support-on]
#{6804} = data ['locked]
#{6700} = data ['plug]
]
#{BF00018D} = data ['browser-support-on]
#{6804} = data ['locked]
#{6700} = data ['plug]
]
]
sign-eth-tx: func [addr-idx [integer!] tx [block!] /local data max-sz sz signed][
sign-eth-tx: func [bip32-path [block!] tx [block!] /local data max-sz sz signed][
;-- tx: [nonce, gasprice, startgas, to, value, data]
tx-bin: rlp/encode tx
chunk: make binary! 200
@@ -158,14 +156,11 @@ ledger: context [
chunk/2: 04h
chunk/3: either head? tx-bin [0][80h]
chunk/4: 0
chunk/5: either head? tx-bin [sz + 17][sz]
chunk/5: either head? tx-bin [sz + (4 * (length? bip32-path) + 1)][sz]
if head? tx-bin [
append chunk reduce [
4
to-bin32 8000002Ch
to-bin32 8000003Ch
to-bin32 80000000h
to-bin32 addr-idx
append chunk collect [
keep length? bip32-path
forall bip32-path [keep to-bin32 bip32-path/1]
]
]
append/part chunk tx-bin sz
@@ -177,7 +172,7 @@ ledger: context [
either 4 > length? signed [none][signed]
]
get-signed-data: func [idx tx /local signed][
get-eth-signed-data: func [idx tx chain-id /local signed][
signed: sign-eth-tx idx tx
either all [signed binary? signed][
append tx reduce [
@@ -0,0 +1,195 @@
Red [
Title: "bushound data parser"
Author: "bitbegin"
File: %bushound-parser.red
Usage: comment {1. .\red.exe -r .\keys\Trezor\bushound-parser.red
2. we will get bushound-parser.exe from step 1
3. ./bushound-parser.exe bushound-file
}
Tabs: 4
License: "BSD-3 - https://github.com/red/red/blob/master/BSD-3-License.txt"
]
#include %../../libs/int-encode.red
#include %../../libs/proto-encode.red
#include %trezor-message.red
bushound-parser: context [
debug-level: 0
space: charset " ^-^/"
notspace: complement space
digit: charset [#"0" - #"9"]
hex-char: charset [#"a" - #"f"]
hex-digit: union digit hex-char
message: make binary! 1000
message-id: 0
message-size: 0
package: make binary! 65
last-phase: ""
parse-file: func [
file [file!]
return: [string!]
/local
ret [logic!]
content [string!]
header-start [string!]
header-end [string!]
header-data [string!]
header [block!]
dlm-start [string!]
dlm-end [string!]
dlm-data [string!]
dlm [block!]
item-start
item-end
item
item-len
data-start [string!]
data-end [string!]
data-item [string!]
data-data [string!]
data [binary!]
data-begin? [logic!]
len-pos
phase-pos
data-pos
len-value
phase-first?
count
len
res
name
][
content: read file
header: copy []
header-end: find content "^/---"
header-start: find/reverse/tail header-end lf
header-end: find/tail header-end lf
header-data: copy/part header-start header-end
dlm: copy []
dlm-start: header-end
dlm-end: find/tail dlm-start "^/"
dlm-data: copy/part dlm-start dlm-end
item-start: dlm-data
forever [
item-start: find item-start notspace
if item-start = none [break]
item-end: find/tail item-start space
either item-end = none [
item-len: offset? item-start tail dlm-data
][
item-len: offset? item-start item-end
]
append/only dlm reduce [index? item-start item-len - 1]
if item-end = none [break]
item-start: item-end
]
foreach item dlm [
append header reduce [trim/head/tail copy/part at header-data item/1 item/2 item]
]
len-pos: select header "Length"
phase-pos: select header "Phase"
if none = phase-pos [return false]
data-pos: select header "Data"
if none = data-pos [return false]
data-start: dlm-end
until [
clear package
phase-first?: true
until [
data-end: find/tail data-start lf
if data-end = none [data-end: tail content]
data-item: copy/part data-start data-end
phase-value: trim/head/tail copy/part at data-item phase-pos/1 phase-pos/2
either phase-value <> "" [
either phase-first? [
data-data: trim/all copy/part at data-item data-pos/1 data-pos/2
append package debase/base data-data 16
phase-first?: false
last-phase: phase-value
][
break
]
][
data-data: trim/all copy/part at data-item data-pos/1 data-pos/2
append package debase/base data-data 16
]
data-start: data-end
tail? data-end
]
if debug-level > 1 [print ["debug-2:: " last-phase ": package: " package]]
if any [package/1 <> to integer! #{00} package/2 <> to integer! #{3f}] [return data-item]
either all [package/3 = to integer! #{ff} package/4 = to integer! #{ff}][
print ["------------------------------------------------------"]
print [last-phase ": get hid version"]
print ["------------------------------------------------------" lf]
][
either all [package/3 = to integer! #{23} package/4 = to integer! #{23}][
message-id: to-int16 skip package 4
message-size: to-int32 skip package 6
count: 0
clear message
either message-size > (65 - 10) [
count: 65 - 10
append message copy/part skip package 10 count
][
if message-size <> 0 [append message copy/part skip package 10 message-size]
count: message-size
print ["------------------------------------------------------"]
if debug-level > 0 [print ["debug-1:: " last-phase ": message: " message]]
res: make map! []
name: trezor-message/get-type-name message-id
print [last-phase ": " "message type: " name]
len: proto-encode/decode trezor-message/messages name res message
if block! = type? len [probe len return data-item]
probe res
print ["------------------------------------------------------" lf]
]
][
either message-size > (63 + count) [
count: count + 63
append message copy/part skip package 2 63
][
append message copy/part skip package 2 (message-size - count)
count: message-size
print ["------------------------------------------------------"]
if debug-level > 0 [print ["debug-1:: " last-phase ": message: " message]]
res: make map! []
name: trezor-message/get-type-name message-id
print [last-phase ": " "message type: " name]
len: proto-encode/decode trezor-message/messages name res message
if block! = type? len [probe len return data-item]
probe res
print ["------------------------------------------------------" lf]
]
]
]
tail? data-end
]
]
]
main: does [
if none? system/options/args [print "please input file name!" exit]
file: to file! system/options/args/1
print system/options/args/2
if system/options/args/2 <> none [bushound-parser/debug-level: to integer! system/options/args/2 print "debug-level: " bushound-parser/debug-level]
print bushound-parser/parse-file file
]
main
@@ -0,0 +1,19 @@
Red [
Title: "generate trezor messages in new format"
Author: "bitbegin"
File: %generate-msg.red
Usage: comment {1. ./red.exe keys/Trezor/generate-msg.red
2. we will get messages.red from step 1
3. include %messages.red to a block!
}
Tabs: 4
License: "BSD-3 - https://github.com/red/red/blob/master/BSD-3-License.txt"
]
#include %../../libs/proto-parser.red
blk: []
print proto-parser/parse-files [%protob/types.proto %protob/messages.proto] blk
write %messages.red {Red [Title: "auto generated, don't modify it manully!"]}
write/append %messages.red blk
View

Large diffs are not rendered by default.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit f5ee1d0

Please sign in to comment.