-
Notifications
You must be signed in to change notification settings - Fork 403
avoid panic when truncating payer_note in UTF-8 code point #3750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -393,36 +393,51 @@ fn verify_metadata<T: secp256k1::Signing>( | |
secp_ctx, | ||
&SecretKey::from_slice(hmac.as_byte_array()).unwrap(), | ||
); | ||
if fixed_time_eq(&signing_pubkey.serialize(), &derived_keys.public_key().serialize()) { | ||
#[allow(unused_mut)] | ||
let mut ok = fixed_time_eq(&signing_pubkey.serialize(), &derived_keys.public_key().serialize()); | ||
joostjager marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#[cfg(fuzzing)] | ||
if metadata[0] & 1 == 0 { | ||
ok = true; | ||
} | ||
if ok { | ||
Ok(Some(derived_keys)) | ||
} else { | ||
Err(()) | ||
} | ||
} else if metadata[Nonce::LENGTH..].len() == Sha256::LEN { | ||
if fixed_time_eq(&metadata[Nonce::LENGTH..], &hmac.to_byte_array()) { | ||
} else { | ||
#[allow(unused_mut)] | ||
let mut ok = metadata.len() == Nonce::LENGTH + Sha256::LEN | ||
&& fixed_time_eq(&metadata[Nonce::LENGTH..], &hmac.to_byte_array()); | ||
#[cfg(fuzzing)] | ||
if metadata.is_empty() || metadata[0] & 1 == 0 { | ||
ok = true; | ||
} | ||
if ok { | ||
Ok(None) | ||
} else { | ||
Err(()) | ||
} | ||
} else { | ||
Err(()) | ||
} | ||
} | ||
|
||
fn hmac_for_message<'a>( | ||
metadata: &[u8], expanded_key: &ExpandedKey, iv_bytes: &[u8; IV_LEN], | ||
tlv_stream: impl core::iter::Iterator<Item = TlvRecord<'a>>, | ||
) -> Result<HmacEngine<Sha256>, ()> { | ||
if metadata.len() < Nonce::LENGTH { | ||
return Err(()); | ||
} | ||
|
||
let nonce = match Nonce::try_from(&metadata[..Nonce::LENGTH]) { | ||
Ok(nonce) => nonce, | ||
Err(_) => return Err(()), | ||
}; | ||
let mut hmac = expanded_key.hmac_for_offer(); | ||
hmac.input(iv_bytes); | ||
|
||
let nonce = if metadata.len() < Nonce::LENGTH { | ||
// In fuzzing its relatively challenging for the fuzzer to find cases where we have issues | ||
// in a BOLT 12 object but also have a right-sized nonce. So instead we allow any size | ||
// nonce. | ||
Comment on lines
+431
to
+433
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we simply make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kinda liked the idea of running through the same flow as we do in production, including the verfiy? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm... but most everything is being skipped. Like we aren't adding any nonce bytes or TLV records as input to the HMAC by returning early. We could at least do that and not change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmm, fair, I pushed an updated version that uses more common path by having a default nonce. |
||
if !cfg!(fuzzing) { | ||
return Err(()); | ||
} | ||
Nonce::try_from(&[42; Nonce::LENGTH][..]).unwrap() | ||
} else { | ||
Nonce::try_from(&metadata[..Nonce::LENGTH])? | ||
}; | ||
hmac.input(&nonce.0); | ||
|
||
for record in tlv_stream { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somehow I expected this call not here directly, but a fuzzer that indirectly hits it via channel manager. But that would be a whole different fuzz test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, hitting something that requires eg 3 specific TLVs to line up as a part of a much, much larger target is probably an infeasible level of complexity for a fuzzer.