Skip to content

Commit

Permalink
add target for psbt
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoerg committed Jun 18, 2024
1 parent bb472a1 commit fbb3129
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CXX = clang++
CC = clang
SOURCES := targets/bech32.cpp targets/tx_des.cpp targets/miniscript_string.cpp targets/block_des.cpp targets/prefilledtransaction.cpp
SOURCES := targets/psbt.cpp targets/bech32.cpp targets/tx_des.cpp targets/miniscript_string.cpp targets/block_des.cpp targets/prefilledtransaction.cpp
INCLUDES = dependencies/ dependencies/bitcoin/src/ dependencies/bitcoin/src/secp256k1/include
LIB_DIR = dependencies/bitcoin/src/ dependencies/bitcoin/src/.libs dependencies/bitcoin/src/secp256k1/.libs rust_bitcoin_lib/target/debug btcd_lib
OBJS := $(patsubst %.cpp, build/%.o, $(SOURCES))
Expand Down
3 changes: 3 additions & 0 deletions fuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "targets/prefilledtransaction.h"
#include "targets/tx_des.h"
#include "targets/bech32.h"
#include "targets/psbt.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
FuzzedDataProvider provider(data, size);
Expand All @@ -28,6 +29,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
TransactionDes(provider);
} else if (target == "bech32") {
Bech32(provider);
} else if (target == "psbt") {
Psbt(provider);
}

return 0; // Values other than 0 and -1 are reserved for future use.
Expand Down
1 change: 1 addition & 0 deletions rust_bitcoin_lib/rust_bitcoin_lib.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <string>

extern bool rust_miniscript_from_str(const char* miniscript_str);
extern char* rust_bitcoin_psbt(const char* miniscript_str);
extern char* rust_miniscript_from_str_check_key(const char* miniscript_str);
extern char* rust_bitcoin_des_block(const uint8_t *data, size_t len);
extern char* rust_bitcoin_prefilledtransaction(const uint8_t *data, size_t len);
20 changes: 20 additions & 0 deletions rust_bitcoin_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,26 @@ pub unsafe extern "C" fn rust_miniscript_from_str(input: *const c_char) -> bool
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_bitcoin_psbt(data: *const u8, len: usize) -> *mut c_char {
// Safety: Ensure that the data pointer is valid for the given length
let data_slice = slice::from_raw_parts(data, len);

let psbt: Result<bitcoin::psbt::Psbt, _> = bitcoin::psbt::Psbt::deserialize(data_slice);
match psbt {
Err(err) => {
println!("{}", err.to_string());
// Core doesn't check keys and rust-miniscript doesn't support all segwit flags
if err.to_string().starts_with("invalid xonly public key") ||
err.to_string().starts_with("bitcoin consensus encoding error") {
return str_to_c_string(&err.to_string());
}
str_to_c_string("")
},
Ok(_) => str_to_c_string("1"),
}
}

#[no_mangle]
pub unsafe extern "C" fn rust_miniscript_from_str_check_key(input: *const c_char) -> *mut c_char {
let Ok(desc) = c_str_to_str(input) else {
Expand Down
33 changes: 33 additions & 0 deletions targets/psbt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <fuzzer/FuzzedDataProvider.h>
#include <string>
#include <iostream>
#include <stdio.h>

#include "psbt.h"
#include "bitcoin/src/psbt.h"
#include "bitcoin/src/span.h"
#include "bitcoin/src/node/psbt.h"

extern "C" char* rust_bitcoin_psbt(uint8_t *data, size_t len);

bool PSBTCore(Span<const uint8_t> buffer)
{
PartiallySignedTransaction psbt_mut;
std::string error;
if (!DecodeRawPSBT(psbt_mut, MakeByteSpan(buffer), error)) {
return false;
}
return true;
}


void Psbt(FuzzedDataProvider& provider)
{
std::vector<uint8_t> buffer{provider.ConsumeRemainingBytes<uint8_t>()};
bool core{PSBTCore(buffer)};
std::string rust_bitcoin{rust_bitcoin_psbt(buffer.data(), buffer.size())};
if (rust_bitcoin == "invalid xonly public key" ||
rust_bitcoin == "bitcoin consensus encoding error") return;
if (core) assert(rust_bitcoin == "1");
else assert(rust_bitcoin == "0");
}
7 changes: 7 additions & 0 deletions targets/psbt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef PSBT_H
#define PSBT_H

#include <fuzzer/FuzzedDataProvider.h>

void Psbt(FuzzedDataProvider& provider);
#endif

0 comments on commit fbb3129

Please sign in to comment.