Add a method to get session secret for onion packet to KeysInterface
authorYuntai Kyong <yuntai.kyong@gmail.com>
Mon, 26 Nov 2018 11:10:01 +0000 (20:10 +0900)
committerYuntai Kyong <yuntai.kyong@gmail.com>
Tue, 27 Nov 2018 01:44:51 +0000 (10:44 +0900)
fuzz/fuzz_targets/full_stack_target.rs
src/chain/keysinterface.rs
src/ln/channel.rs
src/ln/channelmanager.rs
src/util/mod.rs

index 3b277906b0bea91d9bac2c89c194b5b147e952ac..354625604c1e13cc5eacd6dc7cda286de635057a 100644 (file)
@@ -21,7 +21,7 @@ use lightning::ln::channelmanager::{ChannelManager, PaymentFailReason};
 use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
 use lightning::ln::router::Router;
 use lightning::util::events::{EventsProvider,Event};
-use lightning::util::reset_rng_state;
+use lightning::util::{reset_rng_state, fill_bytes};
 use lightning::util::logger::Logger;
 use lightning::util::sha2::Sha256;
 use lightning::util::config::UserConfig;
@@ -265,6 +265,12 @@ impl KeysInterface for KeyProvider {
                        }
                }
        }
+
+       fn get_session_key(&self) -> SecretKey {
+               let mut session_key = [0; 32];
+               fill_bytes(&mut session_key);
+               SecretKey::from_slice(&Secp256k1::without_caps(), &session_key).unwrap()
+       }
 }
 
 #[inline]
index 8e71625df73c29338d71a7457180c8f59d4d962e..4e35e6764d246ced9b431ad473bfe84bf13ecb7f 100644 (file)
@@ -79,6 +79,8 @@ pub trait KeysInterface: Send + Sync {
        /// Get a new set of ChannelKeys for per-channel secrets. These MUST be unique even if you
        /// restarted with some stale data!
        fn get_channel_keys(&self, inbound: bool) -> ChannelKeys;
+       /// Get a secret for construting an onion packet
+       fn get_session_key(&self) -> SecretKey;
 }
 
 /// Set of lightning keys needed to operate a channel as described in BOLT 3
@@ -158,6 +160,8 @@ pub struct KeysManager {
        shutdown_pubkey: PublicKey,
        channel_master_key: ExtendedPrivKey,
        channel_child_index: AtomicUsize,
+       session_master_key: ExtendedPrivKey,
+       session_child_index: AtomicUsize,
 
        logger: Arc<Logger>,
 }
@@ -184,6 +188,7 @@ impl KeysManager {
                                        Err(_) => panic!("Your RNG is busted"),
                                };
                                let channel_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(3)).expect("Your RNG is busted");
+                               let session_master_key = master_key.ckd_priv(&secp_ctx, ChildNumber::from_hardened_idx(4)).expect("Your RNG is busted");
                                KeysManager {
                                        secp_ctx,
                                        node_secret,
@@ -191,6 +196,8 @@ impl KeysManager {
                                        shutdown_pubkey,
                                        channel_master_key,
                                        channel_child_index: AtomicUsize::new(0),
+                                       session_master_key,
+                                       session_child_index: AtomicUsize::new(0),
 
                                        logger,
                                }
@@ -235,4 +242,19 @@ impl KeysInterface for KeysManager {
                sha.result(&mut seed);
                ChannelKeys::new_from_seed(&seed)
        }
+
+       fn get_session_key(&self) -> SecretKey {
+               let mut sha = Sha256::new();
+               let mut res = [0u8; 32];
+
+               let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
+               sha.input(&byte_utils::be32_to_array(now.subsec_nanos()));
+               sha.input(&byte_utils::be64_to_array(now.as_secs()));
+
+               let child_ix = self.session_child_index.fetch_add(1, Ordering::AcqRel);
+               let child_privkey = self.session_master_key.ckd_priv(&self.secp_ctx, ChildNumber::from_hardened_idx(child_ix as u32)).expect("Your RNG is busted");
+               sha.input(&child_privkey.secret_key[..]);
+               sha.result(&mut res);
+               SecretKey::from_slice(&self.secp_ctx, &res).expect("Your RNG is busted")
+       }
 }
index e0fdcaf9080627a3dae94786adadc080707aca82..4fcebe25dcbbdd847ba57964205533ff32fb4c49 100644 (file)
@@ -3902,6 +3902,7 @@ mod tests {
                }
 
                fn get_channel_keys(&self, _inbound: bool) -> ChannelKeys { self.chan_keys.clone() }
+               fn get_session_key(&self) -> SecretKey { panic!(); }
        }
 
        #[test]
index 6933198c608e0e56f59ffe510d2b2b6583fb3dde..ac4fa819f52d7447adb6bce7c181496f1a48297f 100644 (file)
@@ -1199,11 +1199,7 @@ impl ChannelManager {
                        }
                }
 
-               let session_priv = SecretKey::from_slice(&self.secp_ctx, &{
-                       let mut session_key = [0; 32];
-                       rng::fill_bytes(&mut session_key);
-                       session_key
-               }).expect("RNG is bad!");
+               let session_priv = self.keys_manager.get_session_key();
 
                let cur_height = self.latest_block_height.load(Ordering::Acquire) as u32 + 1;
 
index 842fbea605baba0f89e88d880f305a209c81a068..3df1529e0720f876b98d77ae00819a7d56a05ba3 100644 (file)
@@ -25,7 +25,7 @@ pub mod sha2;
 pub(crate) mod sha2;
 
 #[cfg(feature = "fuzztarget")]
-pub use self::rng::reset_rng_state;
+pub use self::rng::{reset_rng_state, fill_bytes};
 
 #[cfg(test)]
 pub(crate) mod test_utils;