1use crate::credentials::{RuneProvider, TlsConfigProvider};
2use crate::pb::scheduler::{scheduler_client::SchedulerClient, NodeInfoRequest, UpgradeRequest};
3use crate::pb::scheduler::{
4 signer_request, signer_response, ApprovePairingRequest, ApprovePairingResponse, SignerResponse,
5};
6use crate::pb::PendingRequest;
7use crate::pb::{node_client::NodeClient, Empty, HsmRequest, HsmRequestContext, HsmResponse};
11use crate::runes;
12use crate::signer::resolve::Resolver;
13use crate::tls::TlsConfig;
14use crate::{node, node::Client};
15use anyhow::{anyhow, Result};
16use base64::engine::general_purpose;
17use base64::Engine;
18use bytes::BufMut;
19use http::uri::InvalidUri;
20use lightning_signer::bitcoin::hashes::Hash;
21use lightning_signer::bitcoin::secp256k1::PublicKey;
22use lightning_signer::bitcoin::Network;
23use lightning_signer::node::NodeServices;
24use lightning_signer::policy::filter::FilterRule;
25use lightning_signer::util::crypto_utils;
26use log::{debug, error, info, trace, warn};
27use ring::signature::{UnparsedPublicKey, ECDSA_P256_SHA256_FIXED};
28use runeauth::{Condition, Restriction, Rune, RuneError};
29use std::convert::{TryFrom, TryInto};
30use std::sync::Arc;
31use std::sync::Mutex;
32use std::time::SystemTime;
33use tokio::sync::mpsc;
34use tokio::time::{sleep, Duration};
35use tokio_stream::wrappers::ReceiverStream;
36use tonic::transport::{Endpoint, Uri};
37use tonic::{Code, Request};
38use vls_protocol::msgs::{DeBolt, HsmdInitReplyV4};
39use vls_protocol::serde_bolt::Octets;
40use vls_protocol_signer::approver::{Approve, MemoApprover};
41use vls_protocol_signer::handler;
42use vls_protocol_signer::handler::Handler;
43
44mod approver;
45mod auth;
46pub mod model;
47mod report;
48mod resolve;
49
50const VERSION: &str = "v25.05";
51const GITHASH: &str = env!("GIT_HASH");
52const RUNE_VERSION: &str = "gl0";
53const RUNE_DERIVATION_SECRET: &str = "gl-commando";
55
56#[derive(Clone)]
57pub struct Signer {
58 secret: [u8; 32],
59 master_rune: Rune,
60 services: NodeServices,
61 tls: TlsConfig,
62 id: Vec<u8>,
63
64 init: Vec<u8>,
66
67 network: Network,
68 state: Arc<Mutex<crate::persist::State>>,
69}
70
71#[derive(thiserror::Error, Debug)]
72pub enum Error {
73 #[error("could not connect to scheduler: ")]
74 SchedulerConnection(),
75
76 #[error("scheduler returned an error: {0}")]
77 Scheduler(tonic::Status),
78
79 #[error("could not connect to node: {0}")]
80 NodeConnection(#[from] tonic::transport::Error),
81
82 #[error("connection to node lost: {0}")]
83 NodeDisconnect(#[from] tonic::Status),
84
85 #[error("authentication error: {0}")]
86 Auth(crate::Error),
87
88 #[error("scheduler returned faulty URI: {0}")]
89 InvalidUri(#[from] InvalidUri),
90
91 #[error("resolver error: request {0:?}, context: {1:?}")]
92 Resolver(Vec<u8>, Vec<crate::signer::model::Request>),
93
94 #[error("error asking node to be upgraded: {0}")]
95 Upgrade(tonic::Status),
96
97 #[error("protocol error: {0}")]
98 Protocol(#[from] vls_protocol::Error),
99
100 #[error("other: {0}")]
101 Other(anyhow::Error),
102
103 #[error("could not approve pairing request: {0}")]
104 ApprovePairingRequestError(String),
105}
106
107impl Signer {
108 pub fn new<T>(secret: Vec<u8>, network: Network, creds: T) -> Result<Signer, anyhow::Error>
109 where
110 T: TlsConfigProvider,
111 {
112 use lightning_signer::policy::{
113 filter::PolicyFilter, simple_validator::SimpleValidatorFactory,
114 };
115 use lightning_signer::signer::ClockStartingTimeFactory;
116 use lightning_signer::util::clock::StandardClock;
117
118 info!("Initializing signer for {VERSION} ({GITHASH}) (VLS)");
119 let mut sec: [u8; 32] = [0; 32];
120 sec.copy_from_slice(&secret[0..32]);
121
122 let persister = Arc::new(crate::persist::MemoryPersister::new());
125 let mut policy =
126 lightning_signer::policy::simple_validator::make_default_simple_policy(network);
127
128 policy.filter = PolicyFilter::default();
129 policy.filter.merge(PolicyFilter {
130 rules: vec![
132 FilterRule::new_warn("policy-channel-safe-type-anchors"),
133 FilterRule::new_warn("policy-routing-balanced"),
134 FilterRule::new_warn("policy-commitment-retry-same"),
135 ],
136 });
137
138 {
142 policy.max_feerate_per_kw = 150_000;
143 policy.filter.merge(PolicyFilter {
144 rules: vec![
145 FilterRule::new_warn("policy-commitment-fee-range"),
146 FilterRule::new_warn("policy-mutual-fee-range"),
147 ],
148 });
149 }
150
151 policy.filter.merge(PolicyFilter {
152 rules: vec![
154 FilterRule::new_warn("policy-routing-balanced"),
155 FilterRule::new_warn("policy-htlc-fee-range"),
156 ],
157 });
158
159 policy.filter.merge(PolicyFilter {
161 rules: vec![
162 FilterRule::new_warn("policy-revoke-new-commitment-signed"),
166 ],
167 });
168
169 policy.max_invoices = 10_000usize;
172
173 policy.max_routing_fee_msat = 1_000_000;
176
177 let validator_factory = Arc::new(SimpleValidatorFactory::new_with_policy(policy));
178 let starting_time_factory = ClockStartingTimeFactory::new();
179 let clock = Arc::new(StandardClock());
180
181 let services = NodeServices {
182 validator_factory,
183 starting_time_factory,
184 persister: persister.clone(),
185 trusted_oracle_pubkeys: vec![],
186 clock,
187 };
188
189 let mut handler = handler::HandlerBuilder::new(network, 0 as u64, services.clone(), sec)
190 .build()
191 .map_err(|e| anyhow!("building root_handler: {:?}", e))?;
192
193 let init = Signer::initmsg(&mut handler)?;
197
198 let init = HsmdInitReplyV4::from_vec(init).unwrap();
199
200 let id = init.node_id.0.to_vec();
201 use vls_protocol::msgs::SerBolt;
202 let init = init.as_vec();
203
204 let rune_secret = crypto_utils::hkdf_sha256(&sec, RUNE_DERIVATION_SECRET.as_bytes(), &[]);
207 let mr = Rune::new_master_rune(&rune_secret, vec![], None, Some(RUNE_VERSION.to_string()))?;
208
209 trace!("Initialized signer for node_id={}", hex::encode(&id));
210 Ok(Signer {
211 secret: sec,
212 master_rune: mr,
213 services,
214 tls: creds.tls_config(),
215 id,
216 init,
217 network,
218 state: persister.state(),
219 })
220 }
221
222 fn init_handler(&self) -> Result<handler::InitHandler, anyhow::Error> {
223 let h = handler::HandlerBuilder::new(
224 self.network,
225 0 as u64,
226 self.services.clone(),
227 self.secret,
228 )
229 .build()
230 .map_err(|e| anyhow!("building root_handler: {:?}", e))?;
231
232 Ok(h)
233 }
234
235 fn handler(&self) -> Result<handler::RootHandler, anyhow::Error> {
236 let mut h = self.init_handler()?;
237 h.handle(Signer::initreq())
238 .expect("handling the hsmd_init message");
239 Ok(h.into())
240 }
241
242 fn handler_with_approver(
243 &self,
244 approver: Arc<dyn Approve>,
245 ) -> Result<handler::RootHandler, Error> {
246 let mut h = handler::HandlerBuilder::new(
247 self.network,
248 0 as u64,
249 self.services.clone(),
250 self.secret,
251 )
252 .approver(approver)
253 .build()
254 .map_err(|e| crate::signer::Error::Other(anyhow!("Could not create handler: {:?}", e)))?;
255 h.handle(Signer::initreq())
256 .expect("handling the hsmd_init message");
257 Ok(h.into())
258 }
259
260 fn initreq() -> vls_protocol::msgs::Message {
262 vls_protocol::msgs::Message::HsmdInit(vls_protocol::msgs::HsmdInit {
263 key_version: vls_protocol::model::Bip32KeyVersion {
264 pubkey_version: 0,
265 privkey_version: 0,
266 },
267 chain_params: lightning_signer::bitcoin::BlockHash::all_zeros(),
268 encryption_key: None,
269 dev_privkey: None,
270 dev_bip32_seed: None,
271 dev_channel_secrets: None,
272 dev_channel_secrets_shaseed: None,
273 hsm_wire_min_version: 4,
274 hsm_wire_max_version: 6,
275 })
276 }
277
278 fn initmsg(handler: &mut vls_protocol_signer::handler::InitHandler) -> Result<Vec<u8>, Error> {
279 Ok(handler
280 .handle(Signer::initreq())
281 .unwrap()
282 .1
283 .map(|a| a.as_vec())
284 .unwrap_or_default())
285 }
286
287 fn check_request_auth(
294 &self,
295 requests: Vec<crate::pb::PendingRequest>,
296 ) -> Vec<Result<crate::pb::PendingRequest, anyhow::Error>> {
297 requests
300 .into_iter()
301 .filter(|r| !r.pubkey.is_empty() && !r.signature.is_empty() && !r.rune.is_empty())
302 .map(|r| {
303 let pk = UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, &r.pubkey);
304 let mut data = r.request.clone();
305
306 if r.timestamp != 0 {
310 data.put_u64(r.timestamp);
311 }
312
313 pk.verify(&data, &r.signature)
314 .map_err(|e| anyhow!("signature verification failed: {}", e))?;
315
316 self.verify_rune(r.clone())
317 .map(|_| r)
318 .map_err(|e| anyhow!("rune verification failed: {}", e))
319 })
320 .collect()
321 }
322
323 fn verify_rune(&self, request: crate::pb::PendingRequest) -> Result<(), anyhow::Error> {
326 let rune64 = general_purpose::URL_SAFE.encode(request.rune);
327 let rune = Rune::from_base64(&rune64)?;
328
329 if !rune.to_string().contains("pubkey=") {
333 return Err(anyhow!("rune is missing pubkey field"));
334 }
335
336 let unique_id = rune.get_id();
341 let ver_id = match unique_id {
342 Some(id) => format!("{}-{}", id, RUNE_VERSION),
343 None => String::default(),
344 };
345
346 let mut parts = request.uri.split('/');
348 parts.next();
349 match parts.next() {
350 Some(service) => {
351 if service != "cln.Node" && service != "greenlight.Node" {
352 debug!("request from unknown service {}.", service);
353 return Err(anyhow!("service {} is not valid", service));
354 }
355 }
356 None => {
357 debug!("could not extract service from the uri while verifying rune.");
358 return Err(anyhow!("can not extract service from uri"));
359 }
360 };
361
362 let method = match parts.next() {
365 Some(m) => m.to_lowercase(),
366 None => {
367 debug!("could not extract method from uri while verifying rune.");
368 return Err(anyhow!("can not extract uri form request"));
369 }
370 };
371
372 let ctx = runes::Context {
373 method,
374 pubkey: hex::encode(request.pubkey),
375 time: SystemTime::now(),
376 unique_id: ver_id,
377 };
378
379 match self.master_rune.check_with_reason(&rune64, ctx) {
380 Ok(_) => Ok(()),
381 Err(e) => Err(e.into()),
382 }
383 }
384
385 pub async fn run_once(&self, node_uri: Uri) -> Result<(), Error> {
389 info!("Connecting to node at {}", node_uri);
390
391 let tls_config = if node_uri.host().unwrap_or_default().contains("blckstrm") {
392 self.tls.inner.clone()
393 } else {
394 self.tls.inner.clone().domain_name("localhost")
395 };
396
397 let c = Endpoint::from_shared(node_uri.to_string())?
398 .tls_config(tls_config)?
399 .tcp_keepalive(Some(crate::TCP_KEEPALIVE))
400 .http2_keep_alive_interval(crate::TCP_KEEPALIVE)
401 .keep_alive_timeout(crate::TCP_KEEPALIVE_TIMEOUT)
402 .keep_alive_while_idle(true)
403 .connect_lazy();
404
405 let mut client = NodeClient::new(c);
406
407 let mut stream = client
408 .stream_hsm_requests(Request::new(Empty::default()))
409 .await?
410 .into_inner();
411
412 debug!("Starting to stream signer requests");
413 loop {
414 let req = match stream
415 .message()
416 .await
417 .map_err(|e| Error::NodeDisconnect(e))?
418 {
419 Some(r) => r,
420 None => {
421 warn!("Signer request stream ended, the node shouldn't do this.");
422 return Ok(());
423 }
424 };
425 let request_id = req.request_id;
426 let hex_req = hex::encode(&req.raw);
427 let signer_state = req.signer_state.clone();
428 trace!("Received request {}", hex_req);
429
430 match self.process_request(req).await {
431 Ok(response) => {
432 trace!("Sending response {}", hex::encode(&response.raw));
433 client
434 .respond_hsm_request(response)
435 .await
436 .map_err(|e| Error::NodeDisconnect(e))?;
437 }
438 Err(e) => {
439 let response = HsmResponse {
440 raw: vec![],
441 request_id,
442 error: format!("{:?}", e),
443 signer_state: vec![],
444 };
445 client
446 .respond_hsm_request(response)
447 .await
448 .map_err(|e| Error::NodeDisconnect(e))?;
449 warn!(
450 "Ignoring error {} for request {} with state {:?}",
451 e, hex_req, signer_state,
452 )
453 }
454 };
455 }
456 }
457
458 fn authenticate_request(
459 &self,
460 msg: &vls_protocol::msgs::Message,
461 reqs: &Vec<model::Request>,
462 ) -> Result<(), Error> {
463 log::trace!(
464 "Resolving signature request against pending grpc commands: {:?}",
465 reqs
466 );
467
468 Resolver::try_resolve(msg, &reqs)?;
471
472 Ok(())
473 }
474
475 async fn process_request(&self, req: HsmRequest) -> Result<HsmResponse, Error> {
476 debug!("Processing request {:?}", req);
477 let diff: crate::persist::State = req.signer_state.clone().into();
478
479 let prestate = {
480 debug!("Updating local signer state with state from node");
481 let mut state = self.state.lock().unwrap();
482 state.merge(&diff).unwrap();
483 trace!("Processing request {}", hex::encode(&req.raw));
484 state.clone()
485 };
486
487 if let &[h, l, ..] = req.raw.as_slice() {
490 let typ = ((h as u16) << 8) | (l as u16);
491 if typ == 23 {
492 warn!("Refusing to process sign-message request");
493 return Err(Error::Other(anyhow!(
494 "Cannot process sign-message requests from node."
495 )));
496 }
497 }
498
499 let ctxrequests: Vec<model::Request> = self
500 .check_request_auth(req.requests.clone())
501 .into_iter()
502 .filter_map(|r| r.ok())
503 .map(|r| decode_request(r))
504 .filter_map(|r| match r {
505 Ok(r) => Some(r),
506 Err(e) => {
507 log::error!("Unable to decode request in context: {}", e);
508 None
509 }
510 })
511 .collect::<Vec<model::Request>>();
512
513 let msg = vls_protocol::msgs::from_vec(req.raw.clone()).map_err(|e| Error::Protocol(e))?;
514 log::debug!("Handling message {:?}", msg);
515 log::trace!("Signer state {}", serde_json::to_string(&prestate).unwrap());
516
517 if let Err(e) = self.authenticate_request(&msg, &ctxrequests) {
518 report::Reporter::report(crate::pb::scheduler::SignerRejection {
519 msg: e.to_string(),
520 request: Some(req.clone()),
521 git_version: GITHASH.to_string(),
522 node_id: self.node_id(),
523 })
524 .await;
525 #[cfg(not(feature = "permissive"))]
526 return Err(Error::Resolver(req.raw, ctxrequests));
527 };
528
529 for parsed_request in ctxrequests.iter() {
531 match parsed_request {
532 model::Request::GlConfig(gl_config) => {
533 let pubkey = PublicKey::from_slice(&self.id);
534 match pubkey {
535 Ok(p) => {
536 let _ = self
537 .services
538 .persister
539 .update_node_allowlist(&p, vec![gl_config.close_to_addr.clone()]);
540 }
541 Err(e) => debug!("Could not parse public key {:?}: {:?}", self.id, e),
542 }
543 }
544 _ => {}
545 }
546 }
547
548 use auth::Authorizer;
549 let auth = auth::GreenlightAuthorizer {};
550 let approvals = auth.authorize(&ctxrequests).map_err(|e| Error::Auth(e))?;
551 debug!("Current approvals: {:?}", approvals);
552
553 let approver = Arc::new(MemoApprover::new(approver::ReportingApprover::new(
554 #[cfg(feature = "permissive")]
555 vls_protocol_signer::approver::PositiveApprover(),
556 #[cfg(not(feature = "permissive"))]
557 vls_protocol_signer::approver::NegativeApprover(),
558 )));
559 approver.approve(approvals);
560 let root_handler = self.handler_with_approver(approver)?;
561
562 log::trace!("Updating state from context");
563 update_state_from_context(&ctxrequests, &root_handler)
564 .expect("Updating state from context requests");
565 log::trace!("State updated");
566
567 let response = match req.context.clone() {
569 Some(HsmRequestContext { dbid: 0, .. }) | None => {
570 root_handler.handle(msg)
572 }
573 Some(c) => {
574 let pk: [u8; 33] = c.node_id.try_into().unwrap();
575 let pk = vls_protocol::model::PubKey(pk);
576 root_handler
577 .for_new_client(1 as u64, pk, c.dbid)
578 .handle(msg)
579 }
580 };
581
582 if let Err(e) = response {
583 report::Reporter::report(crate::pb::scheduler::SignerRejection {
584 msg: format!("{:?}", e),
585 request: Some(req.clone()),
586 git_version: GITHASH.to_string(),
587 node_id: self.node_id(),
588 })
589 .await;
590 return Err(Error::Other(anyhow!("processing request: {e:?}")));
591 }
592
593 let response = response.unwrap();
594 let signer_state: Vec<crate::pb::SignerStateEntry> = {
595 debug!("Serializing state changes to report to node");
596 let state = self.state.lock().unwrap();
597 state.clone().into()
598 };
599 Ok(HsmResponse {
600 raw: response.as_vec(),
601 request_id: req.request_id,
602 signer_state,
603 error: "".to_owned(),
604 })
605 }
606
607 pub fn node_id(&self) -> Vec<u8> {
608 self.id.clone()
609 }
610
611 pub fn get_init(&self) -> Vec<u8> {
612 self.init.clone()
613 }
614
615 pub fn get_startup_messages(&self) -> Vec<StartupMessage> {
620 let mut init_handler = self.init_handler().unwrap();
621
622 let init = StartupMessage {
623 request: Signer::initreq().inner().as_vec(),
624 response: init_handler
625 .handle(Signer::initreq())
626 .unwrap()
627 .1
628 .map(|a| a.as_vec())
629 .unwrap_or_default(),
630 };
631
632 let requests = vec![
633 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
636 info: Octets("bolt12-invoice-base".as_bytes().to_vec()),
637 }),
638 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
640 info: Octets("scb secret".as_bytes().to_vec()),
641 }),
642 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
644 info: Octets("commando".as_bytes().to_vec()),
645 }),
646 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
648 info: Octets("node-alias-base".as_bytes().to_vec()),
649 }),
650 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
651 info: Octets("offer-blinded-path".as_bytes().to_vec()),
652 }),
653 ];
654
655 let serialized: Vec<Vec<u8>> = requests.iter().map(|m| m.inner().as_vec()).collect();
656 let responses: Vec<Vec<u8>> = requests
657 .into_iter()
658 .map(|r| self.handler().unwrap().handle(r).unwrap().as_vec())
659 .collect();
660
661 let mut msgs: Vec<StartupMessage> = serialized
662 .into_iter()
663 .zip(responses)
664 .map(|r| {
665 log::debug!("Storing canned request-response: {:?} -> {:?}", r.0, r.1);
666
667 StartupMessage {
668 request: r.0,
669 response: r.1,
670 }
671 })
672 .collect();
673
674 msgs.insert(0, init);
675
676 msgs
677 }
678
679 pub fn bip32_ext_key(&self) -> Vec<u8> {
680 use vls_protocol::{msgs, msgs::Message};
681 let initmsg = msgs::from_vec(self.init.clone()).expect("unparseable init message");
682
683 match initmsg {
684 Message::HsmdInit2Reply(m) => m.bip32.0.to_vec(),
685 Message::HsmdInitReplyV4(m) => m.bip32.0.to_vec(),
686 Message::HsmdInitReplyV2(m) => m.bip32.0.to_vec(),
687 m => panic!("Unknown initmsg {:?}, cannot extract bip32 key", m),
688 }
689 }
690
691 pub fn legacy_bip32_ext_key(&self) -> Vec<u8> {
692 let mut handler = self.init_handler().expect("retrieving the handler");
693 let req = vls_protocol::msgs::Message::HsmdInit(vls_protocol::msgs::HsmdInit {
694 key_version: vls_protocol::model::Bip32KeyVersion {
695 pubkey_version: 0,
696 privkey_version: 0,
697 },
698 chain_params: lightning_signer::bitcoin::BlockHash::all_zeros(),
699 encryption_key: None,
700 dev_privkey: None,
701 dev_bip32_seed: None,
702 dev_channel_secrets: None,
703 dev_channel_secrets_shaseed: None,
704 hsm_wire_min_version: 1,
705 hsm_wire_max_version: 2,
706 });
707
708 let initmsg = handler
709 .handle(req)
710 .expect("handling legacy init message")
711 .1
712 .map(|a| a.as_vec())
713 .unwrap_or_default();
714
715 initmsg[35..].to_vec()
716 }
717
718 pub async fn run_forever(&self, shutdown: mpsc::Receiver<()>) -> Result<(), anyhow::Error> {
723 let scheduler_uri = crate::utils::scheduler_uri();
724 debug!("Starting signer run loop");
725 let res = Self::run_forever_with_uri(&self, shutdown, scheduler_uri).await;
726 debug!("Exited signer run loop");
727 res
728 }
729
730 async fn init_scheduler(
732 &self,
733 scheduler_uri: String,
734 ) -> Result<SchedulerClient<tonic::transport::channel::Channel>> {
735 info!("Connecting to scheduler at {scheduler_uri}");
736
737 let channel = Endpoint::from_shared(scheduler_uri.clone())?
738 .tls_config(self.tls.inner.clone())?
739 .tcp_keepalive(Some(crate::TCP_KEEPALIVE))
740 .http2_keep_alive_interval(crate::TCP_KEEPALIVE)
741 .keep_alive_timeout(crate::TCP_KEEPALIVE_TIMEOUT)
742 .keep_alive_while_idle(true)
743 .connect_lazy();
744 let mut scheduler = SchedulerClient::new(channel);
745
746 loop {
749 #[allow(deprecated)]
750 let res = scheduler
751 .maybe_upgrade(UpgradeRequest {
752 initmsg: self.init.clone(),
753 signer_version: self.version().to_owned(),
754 startupmsgs: self
755 .get_startup_messages()
756 .into_iter()
757 .map(|s| s.into())
758 .collect(),
759 })
760 .await;
761
762 match res {
763 Err(e) => match e.code() {
764 Code::Unavailable => {
765 debug!("Cannot connect to scheduler, sleeping and retrying");
766 sleep(Duration::from_secs(3)).await;
767 continue;
768 }
769 _ => Err(Error::Upgrade(e))?,
770 },
771 Ok(r) => {
772 debug!("Server reports version {}", r.into_inner().old_version)
773 }
774 }
775 break;
776 }
777 Ok(scheduler)
778 }
779
780 async fn run_forever_inner(
784 &self,
785 mut scheduler: SchedulerClient<tonic::transport::channel::Channel>,
786 ) -> Result<(), anyhow::Error> {
787 loop {
788 debug!("Calling scheduler.get_node_info");
789 let node_info_res = scheduler
790 .get_node_info(NodeInfoRequest {
791 node_id: self.id.clone(),
792
793 wait: true,
799 })
800 .await;
801
802 let node_info = match node_info_res.map(|v| v.into_inner()) {
803 Ok(v) => {
804 debug!("Got node_info from scheduler: {:?}", v);
805 v
806 }
807 Err(e) => {
808 trace!("Got an error from the scheduler: {e}. Sleeping before retrying");
809 sleep(Duration::from_millis(1000)).await;
810 continue;
811 }
812 };
813
814 if node_info.grpc_uri.is_empty() {
815 trace!("Got an empty GRPC URI, node is not scheduled, sleeping and retrying");
816 sleep(Duration::from_millis(1000)).await;
817 continue;
818 }
819
820 if let Err(e) = self
821 .run_once(Uri::from_maybe_shared(node_info.grpc_uri)?)
822 .await
823 {
824 warn!("Error running against node: {e}");
825 }
826 }
827 }
828
829 pub async fn run_forever_with_uri(
830 &self,
831 mut shutdown: mpsc::Receiver<()>,
832 scheduler_uri: String,
833 ) -> Result<(), anyhow::Error> {
834 let scheduler = self.init_scheduler(scheduler_uri).await?;
835 tokio::select! {
836 run_forever_inner_res = self.run_forever_inner(scheduler.clone()) => {
837 error!("Inner signer loop exited unexpectedly: {run_forever_inner_res:?}");
838 },
839 run_forever_scheduler_res = self.run_forever_scheduler(scheduler) => {
840 error!("Scheduler signer loop exited unexpectedly: {run_forever_scheduler_res:?}")
841 }
842 _ = shutdown.recv() => debug!("Received the signal to exit the signer loop")
843 };
844
845 info!("Exiting the signer loop");
846 Ok(())
847 }
848
849 async fn run_forever_scheduler(
850 &self,
851 scheduler: SchedulerClient<tonic::transport::Channel>,
852 ) -> Result<(), anyhow::Error> {
853 loop {
854 if let Err(e) = self.run_once_scheduler(scheduler.clone()).await {
855 warn!("Error running schduler, trying again: {e}");
856 }
857 }
858 }
859
860 async fn run_once_scheduler(
861 &self,
862 mut scheduler: SchedulerClient<tonic::transport::Channel>,
863 ) -> Result<(), anyhow::Error> {
864 let (sender, rx) = mpsc::channel(1);
865 let outbound = ReceiverStream::new(rx);
866 let mut stream = scheduler
869 .signer_requests_stream(outbound)
870 .await?
871 .into_inner();
872
873 trace!("Starting to stream signer requests from scheduler");
874
875 loop {
876 match stream.message().await {
877 Ok(Some(msg)) => {
878 let req_id = msg.request_id;
879 trace!("Processing scheduler request {}", req_id);
880 match msg.request {
881 Some(signer_request::Request::ApprovePairing(req)) => {
882 if let Err(e) = self
883 .process_pairing_approval(req_id, req, sender.clone())
884 .await
885 {
886 debug!("Could not process pairing approval: {:?}", e);
887 }
888 }
889 None => {
890 debug!("Received an empty signing request");
891 }
892 };
893 }
894 Ok(None) => {
895 debug!("End of stream, this should not happen by the server");
896 return Err(anyhow!("Scheduler closed the stream"));
897 }
898 Err(e) => {
899 debug!("Got an error from the scheduler {}", e);
900 return Err(anyhow!("Scheduler stream error {e:?}"));
901 }
902 };
903 }
904 }
905
906 async fn process_pairing_approval(
907 &self,
908 req_id: u32,
909 req: ApprovePairingRequest,
910 stream: mpsc::Sender<SignerResponse>,
911 ) -> Result<()> {
912 let node_id = self.node_id();
914
915 let mut data = vec![];
916 data.put(req.device_id.as_bytes());
917 data.put_u64(req.timestamp);
918 data.put(&node_id[..]);
919 data.put(req.device_name.as_bytes());
920 data.put(req.restrictions.as_bytes());
921
922 let pk = UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, req.pubkey.clone());
924 pk.verify(&data, &req.sig)
925 .map_err(|e| Error::ApprovePairingRequestError(e.to_string()))?;
926
927 let rune = general_purpose::URL_SAFE
929 .decode(req.rune.clone())
930 .map_err(|e| Error::ApprovePairingRequestError(e.to_string()))?;
931
932 self.verify_rune(PendingRequest {
934 request: vec![],
935 uri: "/cln.Node/ApprovePairing".to_string(),
936 signature: req.sig,
937 pubkey: req.pubkey,
938 timestamp: req.timestamp,
939 rune,
940 })?;
941
942 let restrs: Vec<Vec<&str>> = req
943 .restrictions
944 .split('&')
945 .map(|s| s.split('|').collect::<Vec<&str>>())
946 .collect();
947
948 let rune = self.create_rune(None, restrs)?;
950
951 let _ = stream
952 .send(SignerResponse {
953 request_id: req_id,
954 response: Some(signer_response::Response::ApprovePairing(
955 ApprovePairingResponse {
956 device_id: req.device_id,
957 node_id,
958 rune,
959 },
960 )),
961 })
962 .await?;
963
964 Ok(())
965 }
966
967 pub fn sign_challenge(&self, challenge: Vec<u8>) -> Result<Vec<u8>, anyhow::Error> {
969 if challenge.len() != 32 {
970 return Err(anyhow!("challenge is not 32 bytes long"));
971 }
972 let (sig, _) = self.sign_message(challenge)?;
973 Ok(sig)
974 }
975
976 pub fn sign_device_key(&self, key: &[u8]) -> Result<Vec<u8>, anyhow::Error> {
984 if key.len() != 65 {
985 return Err(anyhow!("key is not 65 bytes long"));
986 }
987 let (sig, _) = self.sign_message(key.to_vec())?;
988 Ok(sig)
989 }
990
991 pub fn sign_message(&self, msg: Vec<u8>) -> Result<(Vec<u8>, u8), anyhow::Error> {
994 if msg.len() > u16::MAX as usize {
995 return Err(anyhow!("Message exceeds max len of {}", u16::MAX));
996 }
997
998 let len = u16::to_be_bytes(msg.len() as u16);
999 if len.len() != 2 {
1000 return Err(anyhow!(
1001 "Message to be signed has unexpected len {}",
1002 len.len()
1003 ));
1004 }
1005
1006 let req = vls_protocol::msgs::SignMessage {
1007 message: Octets(msg),
1008 };
1009 let response = self
1010 .handler()?
1011 .handle(vls_protocol::msgs::Message::SignMessage(req))
1012 .unwrap();
1013
1014 let complete_sig = response.as_vec();
1017 let sig = complete_sig[2..66].to_vec();
1018 let recovery_id = complete_sig[66];
1019 Ok((sig, recovery_id))
1020 }
1021
1022 pub fn sign_invoice(&self, msg: Vec<u8>) -> Result<Vec<u8>, anyhow::Error> {
1024 if msg.len() > u16::MAX as usize {
1025 return Err(anyhow!("Message exceeds max len of {}", u16::MAX));
1026 }
1027
1028 let sig = self
1029 .handler()?
1030 .handle(vls_protocol::msgs::from_vec(msg.clone())?)
1031 .map_err(|_| anyhow!("Sign invoice failed"))?;
1032 Ok(sig.as_vec()[2..67].to_vec())
1033 }
1034
1035 pub async fn node<Creds>(&self, creds: Creds) -> Result<Client, anyhow::Error>
1038 where
1039 Creds: TlsConfigProvider + RuneProvider,
1040 {
1041 node::Node::new(self.node_id(), creds)?.schedule().await
1042 }
1043
1044 pub fn version(&self) -> &'static str {
1045 VERSION
1046 }
1047
1048 pub fn create_rune(
1086 &self,
1087 rune: Option<&str>,
1088 restrictions: Vec<Vec<&str>>,
1089 ) -> Result<String, anyhow::Error> {
1090 if let Some(rune) = rune {
1091 let mut rune: Rune = Rune::from_base64(rune)?;
1093 restrictions.into_iter().for_each(|alts| {
1094 let joined = alts.join("|");
1095 _ = rune.add_restriction(joined.as_str())
1096 });
1097 return Ok(rune.to_base64());
1098 } else {
1099 let res: Vec<Restriction> = restrictions
1100 .into_iter()
1101 .map(|alts| {
1102 let joined = alts.join("|");
1103 Restriction::try_from(joined.as_str())
1104 })
1105 .collect::<Result<Vec<Restriction>, RuneError>>()?;
1106
1107 let unique_id = 0;
1110
1111 let has_pubkey_field = res.iter().any(|r: &Restriction| {
1113 r.alternatives
1114 .iter()
1115 .any(|a| a.get_field() == *"pubkey" && a.get_condition() == Condition::Equal)
1116 });
1117 if !has_pubkey_field {
1118 return Err(anyhow!("Missing a restriction on the pubkey"));
1119 }
1120
1121 let rune = Rune::new(
1122 self.master_rune.authcode(),
1123 res,
1124 Some(unique_id.to_string()),
1125 Some(RUNE_VERSION.to_string()),
1126 )?;
1127 Ok(rune.to_base64())
1128 }
1129 }
1130}
1131
1132fn update_state_from_context(
1136 requests: &Vec<model::Request>,
1137 handler: &handler::RootHandler,
1138) -> Result<(), Error> {
1139 log::debug!("Updating state from {} context request", requests.len());
1140 let node = handler.node();
1141
1142 requests
1143 .iter()
1144 .for_each(|r| update_state_from_request(r, &node).unwrap());
1145 Ok(())
1146}
1147
1148fn update_state_from_request(
1149 request: &model::Request,
1150 node: &lightning_signer::node::Node,
1151) -> Result<(), Error> {
1152 use lightning_signer::invoice::Invoice;
1153 use std::str::FromStr;
1154 match request {
1155 model::Request::SendPay(model::cln::SendpayRequest {
1156 bolt11: Some(inv), ..
1157 }) => {
1158 let invoice = Invoice::from_str(inv).unwrap();
1159 log::debug!(
1160 "Adding invoice {:?} as side-effect of this sendpay {:?}",
1161 invoice,
1162 request
1163 );
1164 node.add_invoice(invoice).unwrap();
1165 }
1166 _ => {}
1167 }
1168
1169 Ok(())
1170}
1171
1172fn decode_request(r: crate::pb::PendingRequest) -> Result<model::Request, anyhow::Error> {
1178 assert_eq!(r.request[0], 0u8);
1185 let payload = &r.request[5..];
1186
1187 crate::signer::model::cln::decode_request(&r.uri, payload)
1188 .or_else(|_| crate::signer::model::greenlight::decode_request(&r.uri, payload))
1189}
1190
1191pub struct StartupMessage {
1194 request: Vec<u8>,
1195 response: Vec<u8>,
1196}
1197
1198impl From<StartupMessage> for crate::pb::scheduler::StartupMessage {
1199 fn from(r: StartupMessage) -> Self {
1200 Self {
1201 request: r.request,
1202 response: r.response,
1203 }
1204 }
1205}
1206
1207#[cfg(test)]
1208mod tests {
1209 use super::*;
1210 use crate::credentials;
1211 use crate::pb;
1212
1213 #[tokio::test]
1219 async fn test_sign_message_rejection() {
1220 let signer = Signer::new(
1221 vec![0 as u8; 32],
1222 Network::Bitcoin,
1223 credentials::Nobody::default(),
1224 )
1225 .unwrap();
1226
1227 let msg = hex::decode("0017000B48656c6c6f20776f726c64").unwrap();
1228 assert!(signer
1229 .process_request(HsmRequest {
1230 request_id: 0,
1231 context: None,
1232 raw: msg,
1233 signer_state: vec![],
1234 requests: Vec::new(),
1235 },)
1236 .await
1237 .is_err());
1238 }
1239
1240 #[tokio::test]
1242 async fn test_empty_message() {
1243 let signer = Signer::new(
1244 vec![0 as u8; 32],
1245 Network::Bitcoin,
1246 credentials::Nobody::default(),
1247 )
1248 .unwrap();
1249
1250 assert_eq!(
1251 signer
1252 .process_request(HsmRequest {
1253 request_id: 0,
1254 context: None,
1255 raw: vec![],
1256 signer_state: vec![],
1257 requests: Vec::new(),
1258 },)
1259 .await
1260 .unwrap_err()
1261 .to_string(),
1262 *"protocol error: ShortRead"
1263 )
1264 }
1265
1266 #[test]
1267 fn test_sign_message_max_size() {
1268 let signer = Signer::new(
1269 vec![0u8; 32],
1270 Network::Bitcoin,
1271 credentials::Nobody::default(),
1272 )
1273 .unwrap();
1274
1275 let msg = [0u8; u16::MAX as usize + 1];
1277 assert_eq!(
1278 signer.sign_message(msg.to_vec()).unwrap_err().to_string(),
1279 format!("Message exceeds max len of {}", u16::MAX)
1280 );
1281 }
1282
1283 #[test]
1288 fn test_legacy_bip32_key() {
1289 let signer = Signer::new(
1290 vec![0u8; 32],
1291 Network::Bitcoin,
1292 credentials::Nobody::default(),
1293 )
1294 .unwrap();
1295
1296 let bip32 = signer.legacy_bip32_ext_key();
1297 let expected: Vec<u8> = vec![
1298 4, 136, 178, 30, 2, 175, 86, 45, 251, 0, 0, 0, 0, 119, 232, 160, 181, 114, 16, 182, 23,
1299 70, 246, 204, 254, 122, 233, 131, 242, 174, 134, 193, 120, 104, 70, 176, 202, 168, 243,
1300 142, 127, 239, 60, 157, 212, 3, 162, 85, 18, 86, 240, 176, 177, 84, 94, 241, 92, 64,
1301 175, 69, 165, 146, 101, 79, 180, 195, 27, 117, 8, 66, 110, 100, 36, 246, 115, 48, 193,
1302 189, 3, 247, 195, 58, 236, 143, 230, 177, 91, 217, 66, 67, 19, 204, 22, 96, 65, 140,
1303 86, 195, 109, 50, 228, 94, 193, 173, 103, 252, 196, 192, 173, 243, 223,
1304 ];
1305
1306 assert_eq!(bip32, expected);
1307 }
1308
1309 #[test]
1312 fn test_rune_expects_pubkey() {
1313 let signer = Signer::new(
1314 vec![0u8; 32],
1315 Network::Bitcoin,
1316 credentials::Nobody::default(),
1317 )
1318 .unwrap();
1319
1320 let alt = "pubkey=112233";
1321 let wrong_alt = "pubkey^112233";
1322
1323 assert!(signer.create_rune(None, vec![]).is_err());
1325
1326 assert!(signer.create_rune(None, vec![vec![wrong_alt]]).is_err());
1328
1329 assert!(signer.create_rune(None, vec![vec![alt]]).is_ok());
1331
1332 assert!(signer
1334 .create_rune(None, vec![vec![wrong_alt], vec![wrong_alt, alt]])
1335 .is_ok());
1336 }
1337
1338 #[test]
1339 fn test_rune_expansion() {
1340 let signer = Signer::new(
1341 vec![0u8; 32],
1342 Network::Bitcoin,
1343 credentials::Nobody::default(),
1344 )
1345 .unwrap();
1346 let rune = "wjEjvKoFJToMLBv4QVbJpSbMoGFlnYVxs8yy40PIBgs9MC1nbDAmcHVia2V5PTAwMDAwMA==";
1347
1348 let new_rune = signer
1349 .create_rune(Some(rune), vec![vec!["method^get"]])
1350 .unwrap();
1351 let stream = Rune::from_base64(&new_rune).unwrap().to_string();
1352 assert!(stream.contains("0-gl0&pubkey=000000&method^get"))
1353 }
1354
1355 #[test]
1356 fn test_rune_checks_method() {
1357 let signer = Signer::new(
1358 vec![0u8; 32],
1359 Network::Bitcoin,
1360 credentials::Nobody::default(),
1361 )
1362 .unwrap();
1363
1364 let pubkey = signer.node_id();
1366 let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1367
1368 let rune = signer
1370 .create_rune(None, vec![vec![&pubkey_rest], vec!["method^create"]])
1371 .unwrap();
1372
1373 let uri = "/cln.Node/CreateInvoice".to_string();
1375 let r = pb::PendingRequest {
1376 request: vec![],
1377 uri,
1378 signature: vec![],
1379 pubkey: pubkey.clone(),
1380 timestamp: 0,
1381 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1382 };
1383 assert!(signer.verify_rune(r).is_ok());
1384
1385 let uri = "/cln.Node/Pay".to_string();
1387 let r = pb::PendingRequest {
1388 request: vec![],
1389 uri,
1390 signature: vec![],
1391 pubkey: pubkey.clone(),
1392 timestamp: 0,
1393 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1394 };
1395 assert!(signer.verify_rune(r).is_err());
1396
1397 let uri = "/greenlight.Node/CreateInvoice".to_string();
1400 let r = pb::PendingRequest {
1401 request: vec![],
1402 uri,
1403 signature: vec![],
1404 pubkey: pubkey.clone(),
1405 timestamp: 0,
1406 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1407 };
1408 assert!(signer.verify_rune(r).is_ok());
1409
1410 let uri = "/wrong.Service/CreateInvoice".to_string();
1413 let r = pb::PendingRequest {
1414 request: vec![],
1415 uri,
1416 signature: vec![],
1417 pubkey: pubkey.clone(),
1418 timestamp: 0,
1419 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1420 };
1421 assert!(signer.verify_rune(r).is_err());
1422 }
1423
1424 #[test]
1425 fn test_empty_rune_is_valid() {
1426 let creds = credentials::Nobody::default();
1427 let signer = Signer::new(vec![0u8; 32], Network::Bitcoin, creds).unwrap();
1428
1429 let pubkey = signer.node_id();
1431 let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1432
1433 let rune = signer.create_rune(None, vec![vec![&pubkey_rest]]).unwrap();
1434 let uri = "/cln.Node/Pay".to_string();
1435 assert!(signer
1436 .verify_rune(crate::pb::PendingRequest {
1437 request: vec![],
1438 uri,
1439 signature: vec![],
1440 pubkey,
1441 timestamp: 0,
1442 rune: general_purpose::URL_SAFE.decode(rune).unwrap(),
1443 })
1444 .is_ok());
1445 }
1446
1447 #[test]
1448 fn test_empty_rune_checks_pubkey() {
1449 let creds = credentials::Nobody::default();
1450 let signer = Signer::new(vec![0u8; 32], Network::Bitcoin, creds).unwrap();
1451
1452 let pubkey = signer.node_id();
1454 let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1455
1456 let rune = signer.create_rune(None, vec![vec![&pubkey_rest]]).unwrap();
1457 let uri = "/cln.Node/Pay".to_string();
1458 assert!(signer
1459 .verify_rune(crate::pb::PendingRequest {
1460 request: vec![],
1461 uri,
1462 signature: vec![],
1463 pubkey: hex::decode("33aabb").unwrap(),
1464 timestamp: 0,
1465 rune: general_purpose::URL_SAFE.decode(rune).unwrap(),
1466 })
1467 .is_err());
1468 }
1469}