Skip to content

Commit 977c7ff

Browse files
authored
add validity checks for incoming node and bill ids (#558)
1 parent b95d194 commit 977c7ff

File tree

16 files changed

+659
-8
lines changed

16 files changed

+659
-8
lines changed

crates/bcr-ebill-api/src/data/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,25 @@ pub use bcr_ebill_core::PostalAddress;
1515
pub use bcr_ebill_core::PublicKey;
1616
pub use bcr_ebill_core::SecretKey;
1717
pub use bcr_ebill_core::UploadFileResult;
18+
use bcr_ebill_core::ValidationError;
19+
use log::warn;
20+
21+
use crate::get_config;
22+
23+
pub fn validate_node_id_network(node_id: &NodeId) -> Result<(), ValidationError> {
24+
if node_id.network() != get_config().bitcoin_network() {
25+
warn!("Detected node id of wrong network {node_id}");
26+
return Err(ValidationError::InvalidNodeId);
27+
}
28+
29+
Ok(())
30+
}
31+
32+
pub fn validate_bill_id_network(bill_id: &bill::BillId) -> Result<(), ValidationError> {
33+
if bill_id.network() != get_config().bitcoin_network() {
34+
warn!("Detected bill id of wrong network {bill_id}");
35+
return Err(ValidationError::InvalidBillId);
36+
}
37+
38+
Ok(())
39+
}

crates/bcr-ebill-api/src/service/bill_service/blocks.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use bcr_ebill_core::{
2323
util::BcrKeys,
2424
};
2525

26+
use crate::data::validate_node_id_network;
27+
2628
use super::{BillAction, Result, error::Error, service::BillService};
2729

2830
impl BillService {
@@ -126,6 +128,7 @@ impl BillService {
126128
}
127129
// has to be ident to req recourse
128130
BillAction::RequestRecourse(recoursee, recourse_reason) => {
131+
validate_node_id_network(&recoursee.node_id)?;
129132
if let BillParticipant::Ident(signer) = signer_public_data {
130133
let (sum, currency, reason) = match *recourse_reason {
131134
RecourseReason::Accept => (
@@ -163,6 +166,7 @@ impl BillService {
163166
}
164167
// has to be ident to recourse
165168
BillAction::Recourse(recoursee, sum, currency, recourse_reason) => {
169+
validate_node_id_network(&recoursee.node_id)?;
166170
if let BillParticipant::Ident(signer) = signer_public_data {
167171
let reason = match *recourse_reason {
168172
RecourseReason::Accept => BillRecourseReasonBlockData::Accept,
@@ -194,6 +198,7 @@ impl BillService {
194198
}
195199
// can be anon to mint
196200
BillAction::Mint(mint, sum, currency) => {
201+
validate_node_id_network(&mint.node_id())?;
197202
let block_data = BillMintBlockData {
198203
endorser: if holder_is_anon {
199204
// if holder is anon, we need to continue as anon
@@ -221,6 +226,7 @@ impl BillService {
221226
}
222227
// can be anon to offer to sell
223228
BillAction::OfferToSell(buyer, sum, currency) => {
229+
validate_node_id_network(&buyer.node_id())?;
224230
let address_to_pay = self.bitcoin_client.get_address_to_pay(
225231
&bill_keys.public_key,
226232
&signer_public_data.node_id().pub_key(),
@@ -253,6 +259,7 @@ impl BillService {
253259
}
254260
// can be anon to sell
255261
BillAction::Sell(buyer, sum, currency, payment_address) => {
262+
validate_node_id_network(&buyer.node_id())?;
256263
let block_data = BillSellBlockData {
257264
seller: if holder_is_anon {
258265
// if holder is anon, we need to continue as anon
@@ -281,6 +288,7 @@ impl BillService {
281288
}
282289
// can be anon to endorse
283290
BillAction::Endorse(endorsee) => {
291+
validate_node_id_network(&endorsee.node_id())?;
284292
let block_data = BillEndorseBlockData {
285293
endorser: if holder_is_anon {
286294
// if holder is anon, we need to continue as anon

crates/bcr-ebill-api/src/service/bill_service/issue.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{BillAction, BillServiceApi, Result, error::Error, service::BillService};
2-
use crate::{get_config, util};
2+
use crate::{data::validate_node_id_network, get_config, util};
33
use bcr_ebill_core::{
44
File, PublicKey, Validate, ValidationError,
55
bill::{
@@ -40,6 +40,9 @@ impl BillService {
4040
"issuing bill with type {}, blank: {}",
4141
&data.t, &data.blank_issue
4242
);
43+
validate_node_id_network(&data.drawee)?;
44+
validate_node_id_network(&data.payee)?;
45+
validate_node_id_network(&data.drawer_public_data.node_id())?;
4346
let (sum, bill_type) = validate_bill_issue(&data)?;
4447

4548
let drawer = match data.drawer_public_data {

crates/bcr-ebill-api/src/service/bill_service/mod.rs

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6459,4 +6459,293 @@ pub mod tests {
64596459
.await;
64606460
assert!(res.is_ok());
64616461
}
6462+
6463+
#[tokio::test]
6464+
async fn wrong_network_failures() {
6465+
let participant =
6466+
BillParticipant::Ident(bill_identified_participant_only_node_id(node_id_test()));
6467+
let mainnet_node_id = NodeId::new(BcrKeys::new().pub_key(), bitcoin::Network::Bitcoin);
6468+
let mainnet_participant = BillParticipant::Ident(bill_identified_participant_only_node_id(
6469+
mainnet_node_id.clone(),
6470+
));
6471+
let mainnet_bill_id = BillId::new(BcrKeys::new().pub_key(), bitcoin::Network::Bitcoin);
6472+
let identity = get_baseline_identity();
6473+
let ctx = get_ctx();
6474+
let service = get_service(ctx);
6475+
6476+
assert!(matches!(
6477+
service
6478+
.get_combined_bitcoin_key_for_bill(&mainnet_bill_id, &participant, &BcrKeys::new())
6479+
.await,
6480+
Err(Error::Validation(ValidationError::InvalidBillId))
6481+
));
6482+
assert!(matches!(
6483+
service
6484+
.get_combined_bitcoin_key_for_bill(
6485+
&bill_id_test(),
6486+
&mainnet_participant,
6487+
&BcrKeys::new()
6488+
)
6489+
.await,
6490+
Err(Error::Validation(ValidationError::InvalidNodeId))
6491+
));
6492+
assert!(matches!(
6493+
service
6494+
.get_detail(
6495+
&mainnet_bill_id,
6496+
&identity.identity,
6497+
&node_id_test(),
6498+
1731593928
6499+
)
6500+
.await,
6501+
Err(Error::Validation(ValidationError::InvalidBillId))
6502+
));
6503+
assert!(matches!(
6504+
service
6505+
.get_detail(
6506+
&bill_id_test(),
6507+
&identity.identity,
6508+
&mainnet_node_id,
6509+
1731593928
6510+
)
6511+
.await,
6512+
Err(Error::Validation(ValidationError::InvalidNodeId))
6513+
));
6514+
assert!(matches!(
6515+
service.get_bill_keys(&mainnet_bill_id).await,
6516+
Err(Error::Validation(ValidationError::InvalidBillId))
6517+
));
6518+
6519+
assert!(matches!(
6520+
service
6521+
.check_payment_for_bill(&mainnet_bill_id, &identity.identity)
6522+
.await,
6523+
Err(Error::Validation(ValidationError::InvalidBillId))
6524+
));
6525+
assert!(matches!(
6526+
service
6527+
.check_offer_to_sell_payment_for_bill(&mainnet_bill_id, &identity)
6528+
.await,
6529+
Err(Error::Validation(ValidationError::InvalidBillId))
6530+
));
6531+
assert!(matches!(
6532+
service
6533+
.check_recourse_payment_for_bill(&mainnet_bill_id, &identity)
6534+
.await,
6535+
Err(Error::Validation(ValidationError::InvalidBillId))
6536+
));
6537+
assert!(matches!(
6538+
service
6539+
.get_past_endorsees(&mainnet_bill_id, &node_id_test())
6540+
.await,
6541+
Err(Error::Validation(ValidationError::InvalidBillId))
6542+
));
6543+
assert!(matches!(
6544+
service
6545+
.get_past_endorsees(&bill_id_test(), &mainnet_node_id)
6546+
.await,
6547+
Err(Error::Validation(ValidationError::InvalidNodeId))
6548+
));
6549+
assert!(matches!(
6550+
service
6551+
.get_past_payments(&mainnet_bill_id, &participant, &BcrKeys::new(), 1731593928)
6552+
.await,
6553+
Err(Error::Validation(ValidationError::InvalidBillId))
6554+
));
6555+
assert!(matches!(
6556+
service
6557+
.get_past_payments(
6558+
&bill_id_test(),
6559+
&mainnet_participant,
6560+
&BcrKeys::new(),
6561+
1731593928
6562+
)
6563+
.await,
6564+
Err(Error::Validation(ValidationError::InvalidNodeId))
6565+
));
6566+
assert!(matches!(
6567+
service
6568+
.get_endorsements(&mainnet_bill_id, &node_id_test())
6569+
.await,
6570+
Err(Error::Validation(ValidationError::InvalidBillId))
6571+
));
6572+
assert!(matches!(
6573+
service
6574+
.get_endorsements(&bill_id_test(), &mainnet_node_id)
6575+
.await,
6576+
Err(Error::Validation(ValidationError::InvalidNodeId))
6577+
));
6578+
assert!(matches!(
6579+
service
6580+
.request_to_mint(
6581+
&mainnet_bill_id,
6582+
&node_id_test(),
6583+
&participant,
6584+
&BcrKeys::new(),
6585+
1731593928
6586+
)
6587+
.await,
6588+
Err(Error::Validation(ValidationError::InvalidBillId))
6589+
));
6590+
assert!(matches!(
6591+
service
6592+
.request_to_mint(
6593+
&bill_id_test(),
6594+
&mainnet_node_id,
6595+
&participant,
6596+
&BcrKeys::new(),
6597+
1731593928
6598+
)
6599+
.await,
6600+
Err(Error::Validation(ValidationError::InvalidNodeId))
6601+
));
6602+
assert!(matches!(
6603+
service
6604+
.request_to_mint(
6605+
&bill_id_test(),
6606+
&node_id_test(),
6607+
&mainnet_participant,
6608+
&BcrKeys::new(),
6609+
1731593928
6610+
)
6611+
.await,
6612+
Err(Error::Validation(ValidationError::InvalidNodeId))
6613+
));
6614+
assert!(matches!(
6615+
service
6616+
.get_mint_state(&mainnet_bill_id, &node_id_test())
6617+
.await,
6618+
Err(Error::Validation(ValidationError::InvalidBillId))
6619+
));
6620+
assert!(matches!(
6621+
service
6622+
.get_mint_state(&bill_id_test(), &mainnet_node_id)
6623+
.await,
6624+
Err(Error::Validation(ValidationError::InvalidNodeId))
6625+
));
6626+
assert!(matches!(
6627+
service.cancel_request_to_mint("", &mainnet_node_id).await,
6628+
Err(Error::Validation(ValidationError::InvalidNodeId))
6629+
));
6630+
assert!(matches!(
6631+
service
6632+
.check_mint_state(&mainnet_bill_id, &node_id_test())
6633+
.await,
6634+
Err(Error::Validation(ValidationError::InvalidBillId))
6635+
));
6636+
assert!(matches!(
6637+
service
6638+
.check_mint_state(&bill_id_test(), &mainnet_node_id)
6639+
.await,
6640+
Err(Error::Validation(ValidationError::InvalidNodeId))
6641+
));
6642+
assert!(matches!(
6643+
service
6644+
.accept_mint_offer("", &mainnet_participant, &BcrKeys::new(), 1731593928)
6645+
.await,
6646+
Err(Error::Validation(ValidationError::InvalidNodeId))
6647+
));
6648+
assert!(matches!(
6649+
service.reject_mint_offer("", &mainnet_node_id).await,
6650+
Err(Error::Validation(ValidationError::InvalidNodeId))
6651+
));
6652+
// issue
6653+
assert!(matches!(
6654+
service
6655+
.issue_new_bill(BillIssueData {
6656+
t: 2,
6657+
country_of_issuing: String::from("UK"),
6658+
city_of_issuing: String::from("London"),
6659+
issue_date: String::from("2030-01-01"),
6660+
maturity_date: String::from("2030-04-01"),
6661+
drawee: mainnet_node_id.clone(),
6662+
payee: node_id_test(),
6663+
sum: String::from("100"),
6664+
currency: String::from("sat"),
6665+
country_of_payment: String::from("AT"),
6666+
city_of_payment: String::from("Vienna"),
6667+
language: String::from("en-UK"),
6668+
file_upload_ids: vec!["some_file_id".to_string()],
6669+
drawer_public_data: participant.clone(),
6670+
drawer_keys: BcrKeys::new(),
6671+
timestamp: 1731593928,
6672+
blank_issue: false,
6673+
})
6674+
.await,
6675+
Err(Error::Validation(ValidationError::InvalidNodeId))
6676+
));
6677+
assert!(matches!(
6678+
service
6679+
.issue_new_bill(BillIssueData {
6680+
t: 2,
6681+
country_of_issuing: String::from("UK"),
6682+
city_of_issuing: String::from("London"),
6683+
issue_date: String::from("2030-01-01"),
6684+
maturity_date: String::from("2030-04-01"),
6685+
drawee: node_id_test(),
6686+
payee: mainnet_node_id.clone(),
6687+
sum: String::from("100"),
6688+
currency: String::from("sat"),
6689+
country_of_payment: String::from("AT"),
6690+
city_of_payment: String::from("Vienna"),
6691+
language: String::from("en-UK"),
6692+
file_upload_ids: vec!["some_file_id".to_string()],
6693+
drawer_public_data: participant.clone(),
6694+
drawer_keys: BcrKeys::new(),
6695+
timestamp: 1731593928,
6696+
blank_issue: false,
6697+
})
6698+
.await,
6699+
Err(Error::Validation(ValidationError::InvalidNodeId))
6700+
));
6701+
assert!(matches!(
6702+
service
6703+
.issue_new_bill(BillIssueData {
6704+
t: 2,
6705+
country_of_issuing: String::from("UK"),
6706+
city_of_issuing: String::from("London"),
6707+
issue_date: String::from("2030-01-01"),
6708+
maturity_date: String::from("2030-04-01"),
6709+
drawee: node_id_test(),
6710+
payee: node_id_test(),
6711+
sum: String::from("100"),
6712+
currency: String::from("sat"),
6713+
country_of_payment: String::from("AT"),
6714+
city_of_payment: String::from("Vienna"),
6715+
language: String::from("en-UK"),
6716+
file_upload_ids: vec!["some_file_id".to_string()],
6717+
drawer_public_data: mainnet_participant.clone(),
6718+
drawer_keys: BcrKeys::new(),
6719+
timestamp: 1731593928,
6720+
blank_issue: false,
6721+
})
6722+
.await,
6723+
Err(Error::Validation(ValidationError::InvalidNodeId))
6724+
));
6725+
// execute bill action
6726+
assert!(matches!(
6727+
service
6728+
.execute_bill_action(
6729+
&mainnet_bill_id,
6730+
BillAction::Accept,
6731+
&participant,
6732+
&BcrKeys::new(),
6733+
1731593928
6734+
)
6735+
.await,
6736+
Err(Error::Validation(ValidationError::InvalidBillId))
6737+
));
6738+
assert!(matches!(
6739+
service
6740+
.execute_bill_action(
6741+
&bill_id_test(),
6742+
BillAction::Accept,
6743+
&mainnet_participant,
6744+
&BcrKeys::new(),
6745+
1731593928
6746+
)
6747+
.await,
6748+
Err(Error::Validation(ValidationError::InvalidNodeId))
6749+
));
6750+
}
64626751
}

0 commit comments

Comments
 (0)