Skip to content

Commit 52ab853

Browse files
Merge pull request #4 from LedgerHQ/develop
Merge develop into master
2 parents 200e11d + 1919af5 commit 52ab853

145 files changed

Lines changed: 771 additions & 335 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clusterfuzzlite/Dockerfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest AS LITE_BUILDER
2+
3+
FROM gcr.io/oss-fuzz-base/base-builder:v1
4+
COPY . $SRC/app-kaspa
5+
COPY ./.clusterfuzzlite/build.sh $SRC/
6+
COPY --from=LITE_BUILDER /opt/ledger-secure-sdk $SRC/app-kaspa/BOLOS_SDK
7+
WORKDIR $SRC/app-kaspa

.clusterfuzzlite/build.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash -eu
2+
3+
# build fuzzers
4+
5+
pushd fuzzing
6+
cmake -DBOLOS_SDK=../BOLOS_SDK -Bbuild -H.
7+
make -C build
8+
mv ./build/fuzz_tx_parser $OUT
9+
mv ./build/fuzz_txin_parser $OUT
10+
mv ./build/fuzz_txout_parser $OUT
11+
popd

.clusterfuzzlite/project.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
language: c

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Checklist
2+
<!-- Put an `x` in each box when you have completed the items. -->
3+
- [ ] App update process has been followed <!-- See comment below -->
4+
- [ ] Target branch is `develop` <!-- unless you have a very good reason -->
5+
- [ ] Application version has been bumped <!-- required if your changes are to be deployed -->
6+
7+
<!-- Make sure you followed the process described in https://developers.ledger.com/docs/embedded-app/maintenance/ before opening your Pull Request.
8+
Don't hesitate to contact us directly on Discord if you have any questions ! https://developers.ledger.com/discord -->

.github/workflows/cflite_cron.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: ClusterFuzzLite cron tasks
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches:
6+
- main # Use your actual default branch here.
7+
schedule:
8+
- cron: '0 13 * * 6' # At 01:00 PM, only on Saturday
9+
permissions: read-all
10+
jobs:
11+
Fuzzing:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
include:
17+
- mode: batch
18+
sanitizer: address
19+
- mode: batch
20+
sanitizer: memory
21+
- mode: prune
22+
sanitizer: address
23+
- mode: coverage
24+
sanitizer: coverage
25+
steps:
26+
- name: Build Fuzzers (${{ matrix.mode }} - ${{ matrix.sanitizer }})
27+
id: build
28+
uses: google/clusterfuzzlite/actions/build_fuzzers@v1
29+
with:
30+
github-token: ${{ secrets.GITHUB_TOKEN }}
31+
language: c # Change this to the language you are fuzzing.
32+
sanitizer: ${{ matrix.sanitizer }}
33+
- name: Run Fuzzers (${{ matrix.mode }} - ${{ matrix.sanitizer }})
34+
id: run
35+
uses: google/clusterfuzzlite/actions/run_fuzzers@v1
36+
with:
37+
github-token: ${{ secrets.GITHUB_TOKEN }}
38+
fuzz-seconds: 300 # 5 minutes
39+
mode: ${{ matrix.mode }}
40+
sanitizer: ${{ matrix.sanitizer }}

.github/workflows/cflite_pr.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: ClusterFuzzLite PR fuzzing
2+
on:
3+
pull_request:
4+
paths:
5+
- '**'
6+
permissions: read-all
7+
jobs:
8+
PR:
9+
runs-on: ubuntu-latest
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
sanitizer: [address, undefined, memory] # Override this with the sanitizers you want.
17+
steps:
18+
- name: Build Fuzzers (${{ matrix.sanitizer }})
19+
id: build
20+
uses: google/clusterfuzzlite/actions/build_fuzzers@v1
21+
with:
22+
language: c # Change this to the language you are fuzzing.
23+
github-token: ${{ secrets.GITHUB_TOKEN }}
24+
sanitizer: ${{ matrix.sanitizer }}
25+
# Optional but recommended: used to only run fuzzers that are affected
26+
# by the PR.
27+
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git
28+
# storage-repo-branch: main # Optional. Defaults to "main"
29+
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages".
30+
- name: Run Fuzzers (${{ matrix.sanitizer }})
31+
id: run
32+
uses: google/clusterfuzzlite/actions/run_fuzzers@v1
33+
with:
34+
github-token: ${{ secrets.GITHUB_TOKEN }}
35+
fuzz-seconds: 300 # 5 minutes
36+
mode: 'code-change'
37+
sanitizer: ${{ matrix.sanitizer }}
38+
output-sarif: true
39+
# Optional but recommended: used to download the corpus produced by
40+
# batch fuzzing.
41+
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git
42+
# storage-repo-branch: main # Optional. Defaults to "main"
43+
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages".

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ APPNAME = "Kaspa"
3030
# Application version
3131
APPVERSION_M = 1
3232
APPVERSION_N = 0
33-
APPVERSION_P = 0
33+
APPVERSION_P = 2
3434
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"
3535

3636
ifeq ($(TARGET_NAME),TARGET_NANOS)

doc/COMMANDS.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
| `GET_APP_NAME` | 0x04 | Get ASCII encoded application name |
99
| `GET_PUBLIC_KEY` | 0x05 | Get public key given BIP32 path |
1010
| `SIGN_TX` | 0x06 | Sign transaction given transaction info, utxos and outputs |
11+
| `SIGN_MESSAGE` | 0x07 | Sign the personal message |
1112

1213
## GET_VERSION
1314

@@ -55,11 +56,11 @@ Keys for kaspa normally use the derivation path `m/44'/111111'/<account>'/<type>
5556

5657
| CData Part | Description |
5758
| --- | --- |
58-
| `purpose` | Must be `44'` or `80000002c` |
59-
| `coin_type` | Must be `111111'` or `8001b207` |
60-
| `account` | Current wallets all use `80000000` (aka. `0'`) for default account but any value from `00000000` to `11111111` is accepted if passed |
61-
| `type` | Current wallets use either `00000000` for Receive Address or `00000001` for Change Address, but any value from `00000000` to `11111111` is accepted if passed |
62-
| `index` | Any value from `00000000` to `11111111` if passed |
59+
| `purpose` | Must be `44'` or `0x80000002c` |
60+
| `coin_type` | Must be `111111'` or `0x8001b207` |
61+
| `account` | Current wallets all use `0x80000000` (aka. `0'`) for default account but any value from `0x80000000` to `0xFFFFFFFF` is accepted if passed |
62+
| `type` | Current wallets use either `0x00000000` for Receive Address or `0x00000001` for Change Address, but any value from `0x00000000` to `0xFFFFFFFF` is accepted if passed |
63+
| `index` | Any value from `0x00000000` to `0xFFFFFFFF` if passed |
6364

6465
If you want to generate addresses using a root public key,
6566

@@ -88,7 +89,7 @@ Transactions signed with ECDSA are currently not supported.
8889

8990
| P1 Value | Usage | CData |
9091
| --- | --- | --- |
91-
| 0x00 | Sending transaction metadata | `version (2)` \|\| `output_len (1)` \|\| `input_len (1)` |
92+
| 0x00 | Sending transaction metadata | `version (2)` \|\| `output_len (1)` \|\| `input_len (1)` \|\| `change_address_type (1)` \|\| `change_address_index (4)` \|\| `account (4)` |
9293
| 0x01 | Sending a tx output | `value (8)` \|\| `script_public_key (34/35)` |
9394
| 0x02 | Sending a tx input | `value (8)` \|\| `tx_id (32)` \|\| `address_type (1)` \|\| `address_index (4)` \|\| `outpoint_index (1)` |
9495
| 0x03 | Requesting for next signature | - |
@@ -102,7 +103,7 @@ Transactions signed with ECDSA are currently not supported.
102103
`P2` value is used only if `P1 in {0x00, 0x01, 0x02}`. If `P1 = 0x03`, `P2` is ignored.
103104

104105
#### Flow
105-
1. Send the first APDU `P1 = 0x00` with the version, output length and input length
106+
1. Send the first APDU `P1 = 0x00` with the version, output length and input length, change address type and index, and account (for UTXOs and change)
106107
2. For each output (up to 2), send `P1 = 0x01` with the output CData
107108
3. For each UTXO input send `P1 = 0x02` with the input CData. When sending the last UTXO input set `P2 = 0x00` to indicate that it is the last APDU. The signatures will later be sent back to you in the same order these inputs come in.
108109
4. [Display] User will be able to view the transaction info and choose to `Approve` or `Reject`.
@@ -133,12 +134,13 @@ Transactions signed with ECDSA are currently not supported.
133134

134135
| CLA | INS | P1 | P2 | Lc | CData |
135136
| --- | --- | --- | --- | --- | --- |
136-
| 0xE0 | 0x07 | 0x00 | 0x00 | var | `address_type (1)` \|\| `address_index (4)` \|\|<br>`message_len (1 bytes)` \|\| `message (var bytes)` |
137+
| 0xE0 | 0x07 | 0x00 | 0x00 | var | `address_type (1)` \|\| `address_index (4)` \|\|<br>`account (4)` \|\|<br>`message_len (1 bytes)` \|\| `message (var bytes)` |
137138

138139
| CData Part | Description |
139140
| --- | --- |
140141
| `address_type` | Either `00` for Receive Address or `01` for Change Address |
141-
| `address_index` | Any value from `00000000` to `11111111` |
142+
| `address_index` | Any value from `00000000` to `FFFFFFFF` |
143+
| `account` | Any value from `80000000` to `FFFFFFFF` |
142144
| `message_len` | How long the message is. Must be a value from `1` to `128`, inclusive |
143145
| `message` | The message to sign |
144146

doc/TRANSACTION.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@ For ECDSA-signed addresses (supported by this app only as a send address), it be
2525
| `n_outputs` | 1 | The number of outputs. Exactly 1 or 2.
2626
| `change_address_type` | 1 | `0` if `RECEIVE` or `1` if `CHANGE`* |
2727
| `change_address_index` | 4 | `0x00000000` to `0xFFFFFFFF`**|
28+
| `account` | 4 | `0x80000000` to `0xFFFFFFFF`, normally should use `0x80000000` (the default account)***|
2829

2930
\* While this will be used for the change, the path may be either `RECEIVE` or `CHANGE`.
3031
This is necessary in case the user wants to send the change back to the same address.
3132
In this case, the `change_address_type` has to be set to `RECEIVE`.
3233

3334
\*\* `change_address_type` and `change_address_index` are ignored if `n_outputs == 1`. If `n_outputs == 2` then the path defined here must resolve to the same `script_public_key` in `outputs[1]`.
35+
36+
\*\*\* `account` is the BIP44 account. A transaction can only come from a single account. Current Kaspa ecosystem only uses `0'` (or `0x80000000`) but support this is in anticipation of wider account-based support.
37+
3438
### Transaction Input
3539

3640
Total bytes: 46
@@ -54,7 +58,7 @@ Total bytes: 43 (max)
5458
| Field | Size (bytes) | Description |
5559
| --- | --- | --- |
5660
| `value` | 8 | The amount of KAS in sompi that will go send to the address |
57-
| `script_public_key` | 35 | Schnorr: `20` + public_key (32 bytes) + `ac` <br/> ECDSA: `20` + public_key (33 bytes) + `ab` <br/> P2SH: `aa20` + public_key (32 bytes) + `87` |
61+
| `script_public_key` | 35 | Schnorr: `0x20` + public_key (32 bytes) + `0xac` <br/> ECDSA: `0x20` + public_key (33 bytes) + `0xab` <br/> P2SH: `0xaa, 0x20` + script_hash (32 bytes) + `0x87` |
5862

5963
### Transaction Requirements
6064
- Fee = (total inputs amount) - (total outputs amount)

fuzzing/CMakeLists.txt

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,53 @@ endif()
88
project(FuzzTxParser
99
VERSION 1.0
1010
DESCRIPTION "Fuzzing of transaction parser"
11-
LANGUAGES CXX)
11+
LANGUAGES C)
1212

1313
# guard against bad build-type strings
1414
if (NOT CMAKE_BUILD_TYPE)
1515
set(CMAKE_BUILD_TYPE "Debug")
1616
endif()
1717

18+
if (NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
19+
message(FATAL_ERROR "Fuzzer needs to be built with Clang")
20+
endif()
21+
22+
if (NOT DEFINED BOLOS_SDK)
23+
message(FATAL_ERROR "BOLOS_SDK environment variable not found.")
24+
endif()
25+
1826
# guard against in-source builds
1927
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
2028
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
2129
endif()
2230

31+
# compatible with ClusterFuzzLite
32+
if (NOT DEFINED ENV{LIB_FUZZING_ENGINE})
33+
set(COMPILATION_FLAGS_ "-g -Wall -fsanitize=fuzzer,address,undefined")
34+
else()
35+
set(COMPILATION_FLAGS_ "$ENV{LIB_FUZZING_ENGINE} $ENV{CXXFLAGS}")
36+
endif()
37+
2338
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
2439

2540
add_compile_definitions(MAX_INPUT_COUNT=15 MAX_MESSAGE_LEN=200 USB_SEGMENT_SIZE=64)
2641

42+
string(REPLACE " " ";" COMPILATION_FLAGS ${COMPILATION_FLAGS_})
43+
2744
include(extra/TxParser.cmake)
2845

29-
add_executable(fuzz_tx_parser fuzz_tx_parser.cc)
30-
add_executable(fuzz_txout_parser fuzz_txout_parser.cc)
31-
add_executable(fuzz_txin_parser fuzz_txin_parser.cc)
32-
33-
target_compile_options(fuzz_tx_parser
34-
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O2 -fsanitize=fuzzer,address,undefined>
35-
)
36-
target_compile_options(fuzz_txout_parser
37-
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O2 -fsanitize=fuzzer,address,undefined>
38-
)
39-
target_compile_options(fuzz_txin_parser
40-
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O2 -fsanitize=fuzzer,address,undefined>
41-
)
42-
43-
target_link_libraries(fuzz_tx_parser
44-
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address,undefined>
45-
PUBLIC txparser
46-
)
47-
target_link_libraries(fuzz_txout_parser
48-
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address,undefined>
49-
PUBLIC txparser
50-
)
51-
target_link_libraries(fuzz_txin_parser
52-
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address,undefined>
53-
PUBLIC txparser
54-
)
46+
add_executable(fuzz_tx_parser fuzz_tx_parser.c)
47+
add_executable(fuzz_txout_parser fuzz_txout_parser.c)
48+
add_executable(fuzz_txin_parser fuzz_txin_parser.c)
49+
50+
target_compile_options(fuzz_tx_parser PUBLIC ${COMPILATION_FLAGS})
51+
target_link_options(fuzz_tx_parser PUBLIC ${COMPILATION_FLAGS})
52+
target_link_libraries(fuzz_tx_parser PUBLIC txparser)
53+
54+
target_compile_options(fuzz_txout_parser PUBLIC ${COMPILATION_FLAGS})
55+
target_link_options(fuzz_txout_parser PUBLIC ${COMPILATION_FLAGS})
56+
target_link_libraries(fuzz_txout_parser PUBLIC txparser)
57+
58+
target_compile_options(fuzz_txin_parser PUBLIC ${COMPILATION_FLAGS})
59+
target_link_options(fuzz_txin_parser PUBLIC ${COMPILATION_FLAGS})
60+
target_link_libraries(fuzz_txin_parser PUBLIC txparser)

0 commit comments

Comments
 (0)