Force program address off the curve (#11323)

This commit is contained in:
Jack May
2020-08-05 16:35:54 -07:00
committed by GitHub
parent 964cfb05ea
commit 03263c850a
14 changed files with 240 additions and 45 deletions

View File

@ -1885,6 +1885,7 @@ dependencies = [
"bv",
"byteorder 1.3.4",
"chrono",
"curve25519-dalek",
"ed25519-dalek",
"generic-array 0.14.3",
"hex",

View File

@ -30,6 +30,10 @@ extern uint64_t entrypoint(const uint8_t *input) {
return ERROR_INVALID_ARGUMENT;
}
uint8_t nonce1 = params.data[1];
uint8_t nonce2 = params.data[2];
uint8_t nonce3 = params.data[3];
switch (params.data[0]) {
case TEST_SUCCESS: {
sol_log("Call system program");
@ -81,6 +85,18 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
}
sol_log("Test create_program_address");
{
uint8_t seed1[] = {'Y', 'o', 'u', ' ', 'p', 'a', 's', 's',
' ', 'b', 'u', 't', 't', 'e', 'r'};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{&nonce1, 1}};
SolPubkey address;
sol_assert(SUCCESS == sol_create_program_address(seeds1, SOL_ARRAY_SIZE(seeds1),
params.program_id, &address));
sol_assert(SolPubkey_same(&address, accounts[DERIVED_KEY1_INDEX].key));
}
sol_log("Test derived signers");
{
sol_assert(!accounts[DERIVED_KEY1_INDEX].is_signer);
@ -92,19 +108,15 @@ extern uint64_t entrypoint(const uint8_t *input) {
{accounts[DERIVED_KEY1_INDEX].key, true, true},
{accounts[DERIVED_KEY2_INDEX].key, true, false},
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {TEST_DERIVED_SIGNERS};
uint8_t data[] = {TEST_DERIVED_SIGNERS, nonce2, nonce3};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
uint8_t seed1[] = {'Y', 'o', 'u', ' ', 'p', 'a', 's', 's',
' ', 'b', 'u', 't', 't', 'e', 'r'};
uint8_t seed2[] = {'L', 'i', 'l', '\''};
uint8_t seed3[] = {'B', 'i', 't', 's'};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)}};
const SolSignerSeed seeds2[] = {{seed2, SOL_ARRAY_SIZE(seed2)},
{seed3, SOL_ARRAY_SIZE(seed3)}};
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
{seeds2, SOL_ARRAY_SIZE(seeds2)}};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{&nonce1, 1}};
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)}};
sol_assert(SUCCESS == sol_invoke_signed(&instruction, accounts,
SOL_ARRAY_SIZE(accounts),
signers_seeds,

View File

@ -92,6 +92,9 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
sol_assert(!accounts[DERIVED_KEY2_INDEX].is_signer);
uint8_t nonce2 = params.data[1];
uint8_t nonce3 = params.data[2];
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY1_INDEX].key, true, false},
{accounts[DERIVED_KEY2_INDEX].key, true, true},
@ -103,9 +106,11 @@ extern uint64_t entrypoint(const uint8_t *input) {
uint8_t seed1[] = {'L', 'i', 'l', '\''};
uint8_t seed2[] = {'B', 'i', 't', 's'};
const SolSignerSeed seeds1[] = {{seed1, SOL_ARRAY_SIZE(seed1)},
{seed2, SOL_ARRAY_SIZE(seed2)}};
{seed2, SOL_ARRAY_SIZE(seed2)},
{&nonce2, 1}};
const SolSignerSeed seeds2[] = {
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY}};
{(uint8_t *)accounts[DERIVED_KEY2_INDEX].key, SIZE_PUBKEY},
{&nonce3, 1}};
const SolSignerSeeds signers_seeds[] = {{seeds1, SOL_ARRAY_SIZE(seeds1)},
{seeds2, SOL_ARRAY_SIZE(seeds2)}};

View File

@ -10,7 +10,7 @@ use solana_sdk::{
entrypoint,
entrypoint::ProgramResult,
info,
program::{invoke, invoke_signed},
program::{create_program_address, invoke, invoke_signed},
program_error::ProgramError,
pubkey::Pubkey,
system_instruction,
@ -34,12 +34,16 @@ const FROM_INDEX: usize = 10;
entrypoint!(process_instruction);
fn process_instruction(
_program_id: &Pubkey,
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
info!("invoke Rust program");
let nonce1 = instruction_data[1];
let nonce2 = instruction_data[2];
let nonce3 = instruction_data[3];
match instruction_data[0] {
TEST_SUCCESS => {
info!("Call system program");
@ -91,6 +95,12 @@ fn process_instruction(
);
}
info!("Test create_program_address");
{
let address = create_program_address(&[b"You pass butter", &[nonce1]], program_id)?;
assert_eq!(&address, accounts[DERIVED_KEY1_INDEX].key);
}
info!("Test derived signers");
{
assert!(!accounts[DERIVED_KEY1_INDEX].is_signer);
@ -105,12 +115,12 @@ fn process_instruction(
(accounts[DERIVED_KEY2_INDEX].key, true, false),
(accounts[DERIVED_KEY3_INDEX].key, false, false),
],
vec![TEST_DERIVED_SIGNERS],
vec![TEST_DERIVED_SIGNERS, nonce2, nonce3],
);
invoke_signed(
&invoked_instruction,
accounts,
&[&[b"You pass butter"], &[b"Lil'", b"Bits"]],
&[&[b"You pass butter", &[nonce1]]],
)?;
}

View File

@ -120,6 +120,8 @@ fn process_instruction(
assert!(!accounts[DERIVED_KEY2_INDEX].is_signer);
assert!(!accounts[DERIVED_KEY3_INDEX].is_signer);
let nonce2 = instruction_data[1];
let nonce3 = instruction_data[2];
let invoked_instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[
@ -133,8 +135,8 @@ fn process_instruction(
&invoked_instruction,
accounts,
&[
&[b"Lil'", b"Bits"],
&[accounts[DERIVED_KEY2_INDEX].key.as_ref()],
&[b"Lil'", b"Bits", &[nonce2]],
&[accounts[DERIVED_KEY2_INDEX].key.as_ref(), &[nonce3]],
],
)?;
}

View File

@ -358,13 +358,12 @@ mod bpf {
let account = Account::new(43, 0, &solana_sdk::system_program::id());
bank.store_account(&from_keypair.pubkey(), &account);
let derived_key1 =
Pubkey::create_program_address(&[b"You pass butter"], &invoke_program_id).unwrap();
let derived_key2 =
Pubkey::create_program_address(&[b"Lil'", b"Bits"], &invoked_program_id).unwrap();
let derived_key3 =
Pubkey::create_program_address(&[derived_key2.as_ref()], &invoked_program_id)
.unwrap();
let (derived_key1, nonce1) =
Pubkey::find_program_address(&[b"You pass butter"], &invoke_program_id);
let (derived_key2, nonce2) =
Pubkey::find_program_address(&[b"Lil'", b"Bits"], &invoked_program_id);
let (derived_key3, nonce3) =
Pubkey::find_program_address(&[derived_key2.as_ref()], &invoked_program_id);
let mint_pubkey = mint_keypair.pubkey();
let account_metas = vec![
@ -383,8 +382,11 @@ mod bpf {
// success cases
let instruction =
Instruction::new(invoke_program_id, &TEST_SUCCESS, account_metas.clone());
let instruction = Instruction::new(
invoke_program_id,
&[TEST_SUCCESS, nonce1, nonce2, nonce3],
account_metas.clone(),
);
let message = Message::new(&[instruction], Some(&mint_pubkey));
assert!(bank_client
.send_and_confirm_message(