Skip to content

Commit f92af6c

Browse files
committed
Ensure plaintext called in message encryption is an array ref type
The plaintext passed to hpke message encrpytion needs to be the correct A or B length respectively.
1 parent 78e01ab commit f92af6c

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

payjoin/src/receive/v2/mod.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use super::{
1616
v1, ImplementationError, InternalPayloadError, JsonError, OutputSubstitutionError,
1717
ReplyableError, SelectionError,
1818
};
19-
use crate::hpke::{decrypt_message_a, encrypt_message_b, HpkeKeyPair, HpkePublicKey};
19+
use crate::hpke::{decrypt_message_a, encrypt_message_b, HpkeError, HpkeKeyPair, HpkePublicKey};
2020
use crate::ohttp::{ohttp_decapsulate, ohttp_encapsulate, OhttpEncapsulationError, OhttpKeys};
2121
use crate::receive::{parse_payload, InputPair};
2222
use crate::uri::ShortId;
@@ -488,20 +488,31 @@ impl PayjoinProposal {
488488
&mut self,
489489
ohttp_relay: impl IntoUrl,
490490
) -> Result<(Request, ohttp::ClientResponse), Error> {
491+
use crate::hpke::PADDED_PLAINTEXT_B_LENGTH;
492+
491493
let target_resource: Url;
492494
let body: Vec<u8>;
493495
let method: &str;
494496

495497
if let Some(e) = &self.context.e {
496498
// Prepare v2 payload
497-
let payjoin_bytes = self.v1.psbt().serialize();
499+
let mut payjoin_bytes = self.v1.psbt().serialize();
498500
let sender_subdir = subdir_path_from_pubkey(e);
499501
target_resource = self
500502
.context
501503
.directory
502504
.join(&sender_subdir.to_string())
503505
.map_err(|e| ReplyableError::Implementation(e.into()))?;
504-
body = encrypt_message_b(payjoin_bytes, &self.context.s, e)?;
506+
payjoin_bytes.resize(PADDED_PLAINTEXT_B_LENGTH, 0);
507+
508+
body = encrypt_message_b(
509+
&payjoin_bytes.clone().try_into().map_err(|_| HpkeError::PayloadTooLarge {
510+
actual: payjoin_bytes.len(),
511+
max: PADDED_PLAINTEXT_B_LENGTH,
512+
})?,
513+
&self.context.s,
514+
e,
515+
)?;
505516
method = "POST";
506517
} else {
507518
// Prepare v2 wrapped and backwards-compatible v1 payload

payjoin/src/send/v2/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ use url::Url;
2929

3030
use super::error::BuildSenderError;
3131
use super::*;
32-
use crate::hpke::{decrypt_message_b, encrypt_message_a, HpkeSecretKey};
32+
use crate::hpke::{
33+
decrypt_message_b, encrypt_message_a, HpkeError, HpkeSecretKey, PADDED_PLAINTEXT_A_LENGTH,
34+
};
3335
use crate::ohttp::{ohttp_decapsulate, ohttp_encapsulate};
3436
use crate::send::v1;
3537
use crate::uri::{ShortId, UrlExt};
@@ -149,15 +151,22 @@ impl Sender {
149151
}
150152
let rs = self.extract_rs_pubkey()?;
151153
let url = self.v1.endpoint.clone();
152-
let body = serialize_v2_body(
154+
let mut plaintext = serialize_v2_body(
153155
&self.v1.psbt,
154156
self.v1.disable_output_substitution,
155157
self.v1.fee_contribution,
156158
self.v1.min_fee_rate,
157159
)?;
160+
plaintext.resize(PADDED_PLAINTEXT_A_LENGTH, 0);
161+
158162
let hpke_ctx = HpkeContext::new(rs, &self.reply_key);
159163
let body = encrypt_message_a(
160-
body,
164+
&plaintext.clone().try_into().map_err(|_| {
165+
InternalCreateRequestError::Hpke(HpkeError::PayloadTooLarge {
166+
actual: plaintext.len(),
167+
max: PADDED_PLAINTEXT_A_LENGTH,
168+
})
169+
})?,
161170
&hpke_ctx.reply_pair.public_key().clone(),
162171
&hpke_ctx.receiver.clone(),
163172
)
@@ -265,7 +274,7 @@ impl V2GetContext {
265274
.join(&subdir.to_string())
266275
.map_err(|e| InternalCreateRequestError::Url(e.into()))?;
267276
let body = encrypt_message_a(
268-
Vec::new(),
277+
&[0; PADDED_PLAINTEXT_A_LENGTH],
269278
&self.hpke_ctx.reply_pair.public_key().clone(),
270279
&self.hpke_ctx.receiver.clone(),
271280
)

0 commit comments

Comments
 (0)