Skip to content

Commit

Permalink
Revert "Merge pull request #1180 from getlipa/fix/decrypt-phone-numbe…
Browse files Browse the repository at this point in the history
…r-ln-addresses-in-lnurl-recipient-field" (#1183)

This reverts commit 0cab752, reversing
changes made to da3eff2..

The reason for reverting this is that we expect the phone number to now be delivered in plaintext, while encryption will take place on the communication channel itself
  • Loading branch information
gcomte authored Sep 5, 2024
1 parent 64c200d commit 8405855
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 120 deletions.
18 changes: 0 additions & 18 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,24 +332,6 @@ impl NotificationHandlingErrorCode {
}
}

#[derive(PartialEq, Eq, Debug, Clone)]
pub enum PhoneNumberAddressDecryptErrorCode {
InvalidLnAddress,
HexDecodingError,
DecryptionError,
Utf8ConversionError,
}

impl Display for PhoneNumberAddressDecryptErrorCode {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}

pub type PhoneNumberAddressDecryptError = perro::Error<PhoneNumberAddressDecryptErrorCode>;
pub type PhoneNumberAddressDecryptResult<T> =
std::result::Result<T, PhoneNumberAddressDecryptError>;

/// Enum representing possible errors why parsing could fail.
#[derive(Debug, thiserror::Error)]
pub enum ParseError {
Expand Down
104 changes: 2 additions & 102 deletions src/notification_handling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@ use crate::analytics::{derive_analytics_keys, AnalyticsInterceptor};
use crate::async_runtime::AsyncRuntime;
use crate::auth::{build_async_auth, build_auth};
use crate::data_store::DataStore;
use crate::errors::{
NotificationHandlingErrorCode, NotificationHandlingResult, PhoneNumberAddressDecryptErrorCode,
PhoneNumberAddressDecryptResult,
};
use crate::errors::{NotificationHandlingErrorCode, NotificationHandlingResult};
use crate::event::report_event_for_analytics;
use crate::exchange_rate_provider::{ExchangeRateProvider, ExchangeRateProviderImpl};
use crate::logger::init_logger_once;
use crate::symmetric_encryption::decrypt;
use crate::util::LogIgnoreError;
use crate::{
enable_backtrace, register_webhook_url, sanitize_input, start_sdk, Config, EnableStatus,
Expand Down Expand Up @@ -313,37 +309,11 @@ fn handle_lnurl_pay_request_notification(
let db_path = format!("{}/{DB_FILENAME}", config.local_persistence_path);
let mut data_store = DataStore::new(&db_path)
.map_runtime_error_using(NotificationHandlingErrorCode::from_runtime_error)?;

let persistence_encryption_key = crate::key_derivation::derive_persistence_encryption_key(
&get_strong_typed_seed(&config).map_to_permanent_failure("Failed to derive keys")?,
)
.map_to_permanent_failure("Failed to derive keys")?;

let received_recipient = match decrypt_phone_number_ln_address(
&data.recipient,
&persistence_encryption_key,
) {
Ok(decrypted) => decrypted,
Err(perro::Error::RuntimeError {
code:
PhoneNumberAddressDecryptErrorCode::HexDecodingError
| PhoneNumberAddressDecryptErrorCode::DecryptionError,
..
}) => {
debug!("Recipient in LNURL pay request is likely a regular lightning address (not an encrypted phone number): {}", data.recipient);
data.recipient.clone()
}
Err(_) => {
debug!("Recipient in LNURL pay request is likely not a lightning address, but a basic LNURL-pay request: {}", data.recipient);
data.recipient.clone()
}
};

match data_store
.retrieve_lightning_addresses()
.map_runtime_error_using(NotificationHandlingErrorCode::from_runtime_error)?
.iter()
.find(|(stored_address, _)| received_recipient == *stored_address)
.find(|(a, _)| data.recipient == *a)
{
None => {
permanent_failure!(
Expand Down Expand Up @@ -471,36 +441,6 @@ fn handle_lnurl_pay_request_notification(
})
}

fn decrypt_phone_number_ln_address(
encrypted_ln_address: &str,
persistence_encryption_key: &[u8; 32],
) -> PhoneNumberAddressDecryptResult<String> {
let (first_part, domain) = encrypted_ln_address.split_once('@').ok_or_runtime_error(
PhoneNumberAddressDecryptErrorCode::InvalidLnAddress,
"Failed to split lightning address at @",
)?;

let encrypted_phone_number = hex::decode(first_part).map_to_runtime_error(
PhoneNumberAddressDecryptErrorCode::HexDecodingError,
"First part of lightning address is not a hex string",
)?;

let decrypted_number = decrypt(&encrypted_phone_number, persistence_encryption_key)
.map_to_runtime_error(
PhoneNumberAddressDecryptErrorCode::DecryptionError,
"First part of lightning address wasn't encrypted with local persistence key",
)?;

let phone_number = std::str::from_utf8(&decrypted_number).map_to_runtime_error(
PhoneNumberAddressDecryptErrorCode::Utf8ConversionError,
"Failed to convert decrypted bytes to utf8",
)?;

let phone_number = phone_number.replacen('+', "-", 1);

Ok(format!("{phone_number}@{domain}"))
}

fn report_insuficcient_inbound_liquidity(
rt: AsyncRuntime,
backend_url: &str,
Expand Down Expand Up @@ -702,44 +642,4 @@ mod tests {
} if data.amount_msat == 12345 && data.recipient == "recipient" && data.payer_comment.is_none() && data.id == "id"
));
}

#[test]
fn test_ln_address_decryption() {
use super::*;
use crate::symmetric_encryption::encrypt;

const PHONE_NUMBER: &str = "+41791234567";
const DOMAIN: &str = "wallet.lipa.swiss";
const PHONE_NUMBER_ADDRESS: &str = "-41791234567@wallet.lipa.swiss";
const REGULAR_LN_ADDRESS: &str = "wavy.ice@wallet.lipa.swiss";
const FOREIGN_LN_ADDRESS: &str = "07052a903a080fc75e3b0a80184f085dac422ea0910335810c6a8d6e275455b68a69c1fc90de8e4d@wallet.lipa.swiss";
const ENCRYPTION_KEY: [u8; 32] = [0; 32];

let encrypted_phone_nr = encrypt(PHONE_NUMBER.as_bytes(), &ENCRYPTION_KEY).unwrap();
let encrypted_ln_address = format!("{}@{}", &hex::encode(encrypted_phone_nr), DOMAIN);

let decrypted_phone_number_address =
decrypt_phone_number_ln_address(&encrypted_ln_address, &ENCRYPTION_KEY).unwrap();
assert_eq!(decrypted_phone_number_address, PHONE_NUMBER_ADDRESS);

let decryption_error =
decrypt_phone_number_ln_address(REGULAR_LN_ADDRESS, &ENCRYPTION_KEY).unwrap_err();
assert!(matches!(
decryption_error,
perro::Error::RuntimeError {
code: PhoneNumberAddressDecryptErrorCode::HexDecodingError,
..
}
));

let decryption_error =
decrypt_phone_number_ln_address(FOREIGN_LN_ADDRESS, &ENCRYPTION_KEY).unwrap_err();
assert!(matches!(
decryption_error,
perro::Error::RuntimeError {
code: PhoneNumberAddressDecryptErrorCode::DecryptionError,
..
}
));
}
}

0 comments on commit 8405855

Please sign in to comment.