1use crate::credentials::{RuneProvider, TlsConfigProvider};
2use crate::pb::scheduler::{scheduler_client::SchedulerClient, NodeInfoRequest, UpgradeRequest};
3use crate::pb::{node_client::NodeClient, Empty, HsmRequest, HsmRequestContext, HsmResponse};
7use crate::runes;
8use crate::signer::resolve::Resolver;
9use crate::tls::TlsConfig;
10use crate::{node, node::Client};
11use anyhow::{anyhow, Result};
12use base64::engine::general_purpose;
13use base64::Engine;
14use bytes::BufMut;
15use http::uri::InvalidUri;
16use lightning_signer::bitcoin::hashes::Hash;
17use lightning_signer::bitcoin::secp256k1::PublicKey;
18use lightning_signer::bitcoin::Network;
19use lightning_signer::node::NodeServices;
20use lightning_signer::policy::filter::FilterRule;
21use lightning_signer::util::crypto_utils;
22use log::{debug, error, info, trace, warn};
23use runeauth::{Condition, Restriction, Rune, RuneError};
24use std::convert::{TryFrom, TryInto};
25use std::sync::Arc;
26use std::sync::Mutex;
27use std::time::SystemTime;
28use tokio::sync::mpsc;
29use tokio::time::{sleep, Duration};
30use tonic::transport::{Endpoint, Uri};
31use tonic::{Code, Request};
32use vls_protocol::msgs::{DeBolt, HsmdInitReplyV4};
33use vls_protocol::serde_bolt::Octets;
34use vls_protocol_signer::approver::{Approve, MemoApprover};
35use vls_protocol_signer::handler;
36use vls_protocol_signer::handler::Handler;
37
38mod approver;
39mod auth;
40pub mod model;
41mod report;
42mod resolve;
43
44const VERSION: &str = "v24.02";
45const GITHASH: &str = env!("GIT_HASH");
46const RUNE_VERSION: &str = "gl0";
47const RUNE_DERIVATION_SECRET: &str = "gl-commando";
49
50#[derive(Clone)]
51pub struct Signer {
52 secret: [u8; 32],
53 master_rune: Rune,
54 services: NodeServices,
55 tls: TlsConfig,
56 id: Vec<u8>,
57
58 init: Vec<u8>,
60
61 network: Network,
62 state: Arc<Mutex<crate::persist::State>>,
63}
64
65#[derive(thiserror::Error, Debug)]
66pub enum Error {
67 #[error("could not connect to scheduler: ")]
68 SchedulerConnection(),
69
70 #[error("scheduler returned an error: {0}")]
71 Scheduler(tonic::Status),
72
73 #[error("could not connect to node: {0}")]
74 NodeConnection(#[from] tonic::transport::Error),
75
76 #[error("connection to node lost: {0}")]
77 NodeDisconnect(#[from] tonic::Status),
78
79 #[error("authentication error: {0}")]
80 Auth(crate::Error),
81
82 #[error("scheduler returned faulty URI: {0}")]
83 InvalidUri(#[from] InvalidUri),
84
85 #[error("resolver error: request {0:?}, context: {1:?}")]
86 Resolver(Vec<u8>, Vec<crate::signer::model::Request>),
87
88 #[error("error asking node to be upgraded: {0}")]
89 Upgrade(tonic::Status),
90
91 #[error("protocol error: {0}")]
92 Protocol(#[from] vls_protocol::Error),
93
94 #[error("other: {0}")]
95 Other(anyhow::Error),
96}
97
98impl Signer {
99 pub fn new<T>(secret: Vec<u8>, network: Network, creds: T) -> Result<Signer, anyhow::Error>
100 where
101 T: TlsConfigProvider,
102 {
103 use lightning_signer::policy::{
104 filter::PolicyFilter, simple_validator::SimpleValidatorFactory,
105 };
106 use lightning_signer::signer::ClockStartingTimeFactory;
107 use lightning_signer::util::clock::StandardClock;
108
109 info!("Initializing signer for {VERSION} ({GITHASH}) (VLS)");
110 let mut sec: [u8; 32] = [0; 32];
111 sec.copy_from_slice(&secret[0..32]);
112
113 let persister = Arc::new(crate::persist::MemoryPersister::new());
116 let mut policy = lightning_signer::policy::simple_validator::make_simple_policy(network);
117
118 policy.filter = PolicyFilter::default();
119 policy.filter.merge(PolicyFilter {
120 rules: vec![
122 FilterRule::new_warn("policy-channel-safe-type-anchors"),
123 FilterRule::new_warn("policy-routing-balanced"),
124 ],
125 });
126
127 policy.filter.merge(PolicyFilter {
128 rules: vec![
130 FilterRule::new_warn("policy-routing-balanced"),
131 FilterRule::new_warn("policy-htlc-fee-range"),
132 ],
133 });
134
135 policy.max_invoices = 10_000usize;
138
139 policy.max_routing_fee_msat = 1_000_000;
142
143 let validator_factory = Arc::new(SimpleValidatorFactory::new_with_policy(policy));
144 let starting_time_factory = ClockStartingTimeFactory::new();
145 let clock = Arc::new(StandardClock());
146
147 let services = NodeServices {
148 validator_factory,
149 starting_time_factory,
150 persister: persister.clone(),
151 clock,
152 };
153
154 let mut handler = handler::HandlerBuilder::new(network, 0 as u64, services.clone(), sec)
155 .build()
156 .map_err(|e| anyhow!("building root_handler: {:?}", e))?
157 .0;
158
159 let init = Signer::initmsg(&mut handler)?;
163
164 let init = HsmdInitReplyV4::from_vec(init).unwrap();
165
166 let id = init.node_id.0.to_vec();
167 use vls_protocol::msgs::SerBolt;
168 let init = init.as_vec();
169
170 let rune_secret = crypto_utils::hkdf_sha256(&sec, RUNE_DERIVATION_SECRET.as_bytes(), &[]);
173 let mr = Rune::new_master_rune(&rune_secret, vec![], None, Some(RUNE_VERSION.to_string()))?;
174
175 trace!("Initialized signer for node_id={}", hex::encode(&id));
176 Ok(Signer {
177 secret: sec,
178 master_rune: mr,
179 services,
180 tls: creds.tls_config(),
181 id,
182 init,
183 network,
184 state: persister.state(),
185 })
186 }
187
188 fn init_handler(&self) -> Result<handler::InitHandler, anyhow::Error> {
189 let h = handler::HandlerBuilder::new(
190 self.network,
191 0 as u64,
192 self.services.clone(),
193 self.secret,
194 )
195 .build()
196 .map_err(|e| anyhow!("building root_handler: {:?}", e))?
197 .0;
198
199 Ok(h)
200 }
201
202 fn handler(&self) -> Result<handler::RootHandler, anyhow::Error> {
203 let mut h = self.init_handler()?;
204 h.handle(Signer::initreq())
205 .expect("handling the hsmd_init message");
206 Ok(h.into_root_handler())
207 }
208
209 fn handler_with_approver(
210 &self,
211 approver: Arc<dyn Approve>,
212 ) -> Result<handler::RootHandler, Error> {
213 let mut h = handler::HandlerBuilder::new(
214 self.network,
215 0 as u64,
216 self.services.clone(),
217 self.secret,
218 )
219 .approver(approver)
220 .build()
221 .map_err(|e| crate::signer::Error::Other(anyhow!("Could not create handler: {:?}", e)))?
222 .0;
223 h.handle(Signer::initreq())
224 .expect("handling the hsmd_init message");
225 Ok(h.into_root_handler())
226 }
227
228 fn initreq() -> vls_protocol::msgs::Message {
230 vls_protocol::msgs::Message::HsmdInit(vls_protocol::msgs::HsmdInit {
231 key_version: vls_protocol::model::Bip32KeyVersion {
232 pubkey_version: 0,
233 privkey_version: 0,
234 },
235 chain_params: lightning_signer::bitcoin::BlockHash::all_zeros(),
236 encryption_key: None,
237 dev_privkey: None,
238 dev_bip32_seed: None,
239 dev_channel_secrets: None,
240 dev_channel_secrets_shaseed: None,
241 hsm_wire_min_version: 5,
242 hsm_wire_max_version: 5,
243 })
244 }
245
246 fn bolt12initreq() -> vls_protocol::msgs::Message {
247 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
248 info: Octets("bolt12-invoice-base".as_bytes().to_vec()),
249 })
250 }
251
252 fn scbinitreq() -> vls_protocol::msgs::Message {
253 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
254 info: Octets("scb secret".as_bytes().to_vec()),
255 })
256 }
257
258 fn commandoinitreq() -> vls_protocol::msgs::Message {
259 vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
260 info: Octets("commando".as_bytes().to_vec()),
261 })
262 }
263
264 fn initmsg(handler: &mut vls_protocol_signer::handler::InitHandler) -> Result<Vec<u8>, Error> {
265 Ok(handler.handle(Signer::initreq()).unwrap().1.as_vec())
266 }
267
268 fn check_request_auth(
275 &self,
276 requests: Vec<crate::pb::PendingRequest>,
277 ) -> Vec<Result<crate::pb::PendingRequest, anyhow::Error>> {
278 use ring::signature::{UnparsedPublicKey, ECDSA_P256_SHA256_FIXED};
280 requests
282 .into_iter()
283 .filter(|r| !r.pubkey.is_empty() && !r.signature.is_empty() && !r.rune.is_empty())
284 .map(|r| {
285 let pk = UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, &r.pubkey);
286 let mut data = r.request.clone();
287
288 if r.timestamp != 0 {
292 data.put_u64(r.timestamp);
293 }
294
295 pk.verify(&data, &r.signature)
296 .map_err(|e| anyhow!("signature verification failed: {}", e))?;
297
298 self.verify_rune(r.clone())
299 .map(|_| r)
300 .map_err(|e| anyhow!("rune verification failed: {}", e))
301 })
302 .collect()
303 }
304
305 fn verify_rune(&self, request: crate::pb::PendingRequest) -> Result<(), anyhow::Error> {
308 let rune64 = general_purpose::URL_SAFE.encode(request.rune);
309 let rune = Rune::from_base64(&rune64)?;
310
311 if !rune.to_string().contains("pubkey=") {
315 return Err(anyhow!("rune is missing pubkey field"));
316 }
317
318 let unique_id = rune.get_id();
323 let ver_id = match unique_id {
324 Some(id) => format!("{}-{}", id, RUNE_VERSION),
325 None => String::default(),
326 };
327
328 let mut parts = request.uri.split('/');
330 parts.next();
331 match parts.next() {
332 Some(service) => {
333 if service != "cln.Node" && service != "greenlight.Node" {
334 debug!("request from unknown service {}.", service);
335 return Err(anyhow!("service {} is not valid", service));
336 }
337 }
338 None => {
339 debug!("could not extract service from the uri while verifying rune.");
340 return Err(anyhow!("can not extract service from uri"));
341 }
342 };
343
344 let method = match parts.next() {
347 Some(m) => m.to_lowercase(),
348 None => {
349 debug!("could not extract method from uri while verifying rune.");
350 return Err(anyhow!("can not extract uri form request"));
351 }
352 };
353
354 let ctx = runes::Context {
355 method,
356 pubkey: hex::encode(request.pubkey),
357 time: SystemTime::now(),
358 unique_id: ver_id,
359 };
360
361 match self.master_rune.check_with_reason(&rune64, ctx) {
362 Ok(_) => Ok(()),
363 Err(e) => Err(e.into()),
364 }
365 }
366
367 pub async fn run_once(&self, node_uri: Uri) -> Result<(), Error> {
371 debug!("Connecting to node at {}", node_uri);
372 let c = Endpoint::from_shared(node_uri.to_string())?
373 .tls_config(self.tls.inner.clone().domain_name("localhost"))?
374 .tcp_keepalive(Some(crate::TCP_KEEPALIVE))
375 .http2_keep_alive_interval(crate::TCP_KEEPALIVE)
376 .keep_alive_timeout(crate::TCP_KEEPALIVE_TIMEOUT)
377 .keep_alive_while_idle(true)
378 .connect_lazy();
379
380 let mut client = NodeClient::new(c);
381
382 let mut stream = client
383 .stream_hsm_requests(Request::new(Empty::default()))
384 .await?
385 .into_inner();
386
387 debug!("Starting to stream signer requests");
388 loop {
389 let req = match stream
390 .message()
391 .await
392 .map_err(|e| Error::NodeDisconnect(e))?
393 {
394 Some(r) => r,
395 None => {
396 warn!("Signer request stream ended, the node shouldn't do this.");
397 return Ok(());
398 }
399 };
400 let hex_req = hex::encode(&req.raw);
401 let signer_state = req.signer_state.clone();
402 trace!("Received request {}", hex_req);
403
404 match self.process_request(req).await {
405 Ok(response) => {
406 trace!("Sending response {}", hex::encode(&response.raw));
407 client
408 .respond_hsm_request(response)
409 .await
410 .map_err(|e| Error::NodeDisconnect(e))?;
411 }
412 Err(e) => {
413 warn!(
414 "Ignoring error {} for request {} with state {:?}",
415 e, hex_req, signer_state,
416 )
417 }
418 };
419 }
420 }
421
422 fn authenticate_request(
423 &self,
424 msg: &vls_protocol::msgs::Message,
425 reqs: &Vec<model::Request>,
426 ) -> Result<(), Error> {
427 log::trace!(
428 "Resolving signature request against pending grpc commands: {:?}",
429 reqs
430 );
431
432 Resolver::try_resolve(msg, &reqs)?;
435
436 Ok(())
437 }
438
439 async fn process_request(&self, req: HsmRequest) -> Result<HsmResponse, Error> {
440 let diff: crate::persist::State = req.signer_state.clone().into();
441
442 let prestate = {
443 debug!("Updating local signer state with state from node");
444 let mut state = self.state.lock().unwrap();
445 state.merge(&diff).unwrap();
446 trace!("Processing request {}", hex::encode(&req.raw));
447 state.clone()
448 };
449
450 if let &[h, l, ..] = req.raw.as_slice() {
453 let typ = ((h as u16) << 8) | (l as u16);
454 if typ == 23 {
455 warn!("Refusing to process sign-message request");
456 return Err(Error::Other(anyhow!(
457 "Cannot process sign-message requests from node."
458 )));
459 }
460 }
461
462 let ctxrequests: Vec<model::Request> = self
463 .check_request_auth(req.requests.clone())
464 .into_iter()
465 .filter_map(|r| r.ok())
466 .map(|r| decode_request(r))
467 .filter_map(|r| match r {
468 Ok(r) => Some(r),
469 Err(e) => {
470 log::error!("Unable to decode request in context: {}", e);
471 None
472 }
473 })
474 .collect::<Vec<model::Request>>();
475
476 let msg = vls_protocol::msgs::from_vec(req.raw.clone()).map_err(|e| Error::Protocol(e))?;
477 log::debug!("Handling message {:?}", msg);
478 log::trace!("Signer state {}", serde_json::to_string(&prestate).unwrap());
479
480 if let Err(e) = self.authenticate_request(&msg, &ctxrequests) {
481 report::Reporter::report(crate::pb::scheduler::SignerRejection {
482 msg: e.to_string(),
483 request: Some(req.clone()),
484 git_version: GITHASH.to_string(),
485 })
486 .await;
487 #[cfg(not(feature = "permissive"))]
488 return Err(Error::Resolver(req.raw, ctxrequests));
489 };
490
491 for parsed_request in ctxrequests.iter() {
493 match parsed_request {
494 model::Request::GlConfig(gl_config) => {
495 let pubkey = PublicKey::from_slice(&self.id);
496 match pubkey {
497 Ok(p) => {
498 let _ = self
499 .services
500 .persister
501 .update_node_allowlist(&p, vec![gl_config.close_to_addr.clone()]);
502 }
503 Err(e) => debug!("Could not parse public key {:?}: {:?}", self.id, e),
504 }
505 }
506 _ => {}
507 }
508 }
509
510 use auth::Authorizer;
511 let auth = auth::GreenlightAuthorizer {};
512 let approvals = auth.authorize(&ctxrequests).map_err(|e| Error::Auth(e))?;
513 debug!("Current approvals: {:?}", approvals);
514
515 let approver = Arc::new(MemoApprover::new(approver::ReportingApprover::new(
516 #[cfg(feature = "permissive")]
517 vls_protocol_signer::approver::PositiveApprover(),
518 #[cfg(not(feature = "permissive"))]
519 vls_protocol_signer::approver::NegativeApprover(),
520 )));
521 approver.approve(approvals);
522 let root_handler = self.handler_with_approver(approver)?;
523
524 log::trace!("Updating state from context");
525 update_state_from_context(&ctxrequests, &root_handler)
526 .expect("Updating state from context requests");
527 log::trace!("State updated");
528
529 let response = match req.context {
531 Some(HsmRequestContext { dbid: 0, .. }) | None => {
532 root_handler.handle(msg)
534 }
535 Some(c) => {
536 let pk: [u8; 33] = c.node_id.try_into().unwrap();
537 let pk = vls_protocol::model::PubKey(pk);
538 root_handler
539 .for_new_client(1 as u64, pk, c.dbid)
540 .handle(msg)
541 }
542 }
543 .map_err(|e| Error::Other(anyhow!("processing request: {e:?}")))?;
544
545 let signer_state: Vec<crate::pb::SignerStateEntry> = {
546 debug!("Serializing state changes to report to node");
547 let state = self.state.lock().unwrap();
548 state.clone().into()
549 };
550
551 Ok(HsmResponse {
552 raw: response.0.as_vec(),
553 request_id: req.request_id,
554 signer_state,
555 })
556 }
557
558 pub fn node_id(&self) -> Vec<u8> {
559 self.id.clone()
560 }
561
562 pub fn get_init(&self) -> Vec<u8> {
563 self.init.clone()
564 }
565
566 pub fn get_startup_messages(&self) -> Vec<StartupMessage> {
571 let mut init_handler = self.init_handler().unwrap();
572
573 let init = StartupMessage {
574 request: Signer::initreq().inner().as_vec(),
575 response: init_handler.handle(Signer::initreq()).unwrap().1.as_vec(),
576 };
577
578 let requests = vec![
579 Signer::bolt12initreq(),
582 Signer::scbinitreq(),
584 Signer::commandoinitreq(),
586 ];
587
588 let serialized: Vec<Vec<u8>> = requests.iter().map(|m| m.inner().as_vec()).collect();
589 let responses: Vec<Vec<u8>> = requests
590 .into_iter()
591 .map(|r| self.handler().unwrap().handle(r).unwrap().0.as_vec())
592 .collect();
593
594 let mut msgs: Vec<StartupMessage> = serialized
595 .into_iter()
596 .zip(responses)
597 .map(|r| {
598 log::debug!("Storing canned request-response: {:?} -> {:?}", r.0, r.1);
599
600 StartupMessage {
601 request: r.0,
602 response: r.1,
603 }
604 })
605 .collect();
606
607 msgs.insert(0, init);
608
609 msgs
610 }
611
612 pub fn bip32_ext_key(&self) -> Vec<u8> {
613 use vls_protocol::{msgs, msgs::Message};
614 let initmsg = msgs::from_vec(self.init.clone()).expect("unparseable init message");
615
616 match initmsg {
617 Message::HsmdInit2Reply(m) => m.bip32.0.to_vec(),
618 Message::HsmdInitReplyV4(m) => m.bip32.0.to_vec(),
619 Message::HsmdInitReplyV2(m) => m.bip32.0.to_vec(),
620 m => panic!("Unknown initmsg {:?}, cannot extract bip32 key", m),
621 }
622 }
623
624 pub fn legacy_bip32_ext_key(&self) -> Vec<u8> {
625 let mut handler = self.init_handler().expect("retrieving the handler");
626 let req = vls_protocol::msgs::Message::HsmdInit(vls_protocol::msgs::HsmdInit {
627 key_version: vls_protocol::model::Bip32KeyVersion {
628 pubkey_version: 0,
629 privkey_version: 0,
630 },
631 chain_params: lightning_signer::bitcoin::BlockHash::all_zeros(),
632 encryption_key: None,
633 dev_privkey: None,
634 dev_bip32_seed: None,
635 dev_channel_secrets: None,
636 dev_channel_secrets_shaseed: None,
637 hsm_wire_min_version: 1,
638 hsm_wire_max_version: 2,
639 });
640
641 let initmsg = handler
642 .handle(req)
643 .expect("handling legacy init message")
644 .1
645 .as_vec();
646 initmsg[35..].to_vec()
647 }
648
649 pub async fn run_forever(&self, shutdown: mpsc::Receiver<()>) -> Result<(), anyhow::Error> {
654 let scheduler_uri = crate::utils::scheduler_uri();
655 Self::run_forever_with_uri(&self, shutdown, scheduler_uri).await
656 }
657
658 async fn init_scheduler(
660 &self,
661 scheduler_uri: String,
662 ) -> Result<SchedulerClient<tonic::transport::channel::Channel>> {
663 debug!("Connecting to scheduler at {scheduler_uri}");
664
665 let channel = Endpoint::from_shared(scheduler_uri)?
666 .tls_config(self.tls.inner.clone())?
667 .tcp_keepalive(Some(crate::TCP_KEEPALIVE))
668 .http2_keep_alive_interval(crate::TCP_KEEPALIVE)
669 .keep_alive_timeout(crate::TCP_KEEPALIVE_TIMEOUT)
670 .keep_alive_while_idle(true)
671 .connect_lazy();
672 let mut scheduler = SchedulerClient::new(channel);
673
674 loop {
677 #[allow(deprecated)]
678 let maybe_upgrade_res = scheduler
679 .maybe_upgrade(UpgradeRequest {
680 initmsg: self.init.clone(),
681 signer_version: self.version().to_owned(),
682 startupmsgs: self
683 .get_startup_messages()
684 .into_iter()
685 .map(|s| s.into())
686 .collect(),
687 })
688 .await;
689
690 if let Err(err_status) = maybe_upgrade_res {
691 match err_status.code() {
692 Code::Unavailable => {
693 debug!("Cannot connect to scheduler, sleeping and retrying");
694 sleep(Duration::from_secs(3)).await;
695 continue;
696 }
697 _ => {
698 return Err(Error::Upgrade(err_status))?;
699 }
700 }
701 }
702
703 break;
704 }
705 Ok(scheduler)
706 }
707
708 async fn run_forever_inner(
712 &self,
713 mut scheduler: SchedulerClient<tonic::transport::channel::Channel>,
714 ) -> Result<(), anyhow::Error> {
715 loop {
716 debug!("Calling scheduler.get_node_info");
717 let node_info_res = scheduler
718 .get_node_info(NodeInfoRequest {
719 node_id: self.id.clone(),
720
721 wait: true,
727 })
728 .await;
729
730 let node_info = match node_info_res.map(|v| v.into_inner()) {
731 Ok(v) => {
732 debug!("Got node_info from scheduler: {:?}", v);
733 v
734 }
735 Err(e) => {
736 trace!("Got an error from the scheduler: {e}. Sleeping before retrying");
737 sleep(Duration::from_millis(1000)).await;
738 continue;
739 }
740 };
741
742 if node_info.grpc_uri.is_empty() {
743 trace!("Got an empty GRPC URI, node is not scheduled, sleeping and retrying");
744 sleep(Duration::from_millis(1000)).await;
745 continue;
746 }
747
748 if let Err(e) = self
749 .run_once(Uri::from_maybe_shared(node_info.grpc_uri)?)
750 .await
751 {
752 warn!("Error running against node: {e}");
753 }
754 }
755 }
756
757 pub async fn run_forever_with_uri(
758 &self,
759 mut shutdown: mpsc::Receiver<()>,
760 scheduler_uri: String,
761 ) -> Result<(), anyhow::Error> {
762 let scheduler = self.init_scheduler(scheduler_uri).await?;
763 tokio::select! {
764 run_forever_inner_res = self.run_forever_inner(scheduler) => {
765 error!("Inner signer loop exited unexpectedly: {run_forever_inner_res:?}");
766 },
767 _ = shutdown.recv() => debug!("Received the signal to exit the signer loop")
768 };
769
770 info!("Exiting the signer loop");
771 Ok(())
772 }
773
774 pub fn sign_challenge(&self, challenge: Vec<u8>) -> Result<Vec<u8>, anyhow::Error> {
776 if challenge.len() != 32 {
777 return Err(anyhow!("challenge is not 32 bytes long"));
778 }
779 let (sig, _) = self.sign_message(challenge)?;
780 Ok(sig)
781 }
782
783 pub fn sign_device_key(&self, key: &[u8]) -> Result<Vec<u8>, anyhow::Error> {
791 if key.len() != 65 {
792 return Err(anyhow!("key is not 65 bytes long"));
793 }
794 let (sig, _) = self.sign_message(key.to_vec())?;
795 Ok(sig)
796 }
797
798 pub fn sign_message(&self, msg: Vec<u8>) -> Result<(Vec<u8>, u8), anyhow::Error> {
801 if msg.len() > u16::MAX as usize {
802 return Err(anyhow!("Message exceeds max len of {}", u16::MAX));
803 }
804
805 let len = u16::to_be_bytes(msg.len() as u16);
806 if len.len() != 2 {
807 return Err(anyhow!(
808 "Message to be signed has unexpected len {}",
809 len.len()
810 ));
811 }
812
813 let req = vls_protocol::msgs::SignMessage {
814 message: Octets(msg),
815 };
816 let response = self
817 .handler()?
818 .handle(vls_protocol::msgs::Message::SignMessage(req))
819 .unwrap();
820
821 let complete_sig = response.0.as_vec();
824 let sig = complete_sig[2..66].to_vec();
825 let recovery_id = complete_sig[66];
826 Ok((sig, recovery_id))
827 }
828
829 pub fn sign_invoice(&self, msg: Vec<u8>) -> Result<Vec<u8>, anyhow::Error> {
831 if msg.len() > u16::MAX as usize {
832 return Err(anyhow!("Message exceeds max len of {}", u16::MAX));
833 }
834
835 let sig = self
836 .handler()?
837 .handle(vls_protocol::msgs::from_vec(msg.clone())?)
838 .map_err(|_| anyhow!("Sign invoice failed"))?;
839 Ok(sig.0.as_vec()[2..67].to_vec())
840 }
841
842 pub async fn node<Creds>(&self, creds: Creds) -> Result<Client, anyhow::Error>
845 where
846 Creds: TlsConfigProvider + RuneProvider,
847 {
848 node::Node::new(self.node_id(), creds)?.schedule().await
849 }
850
851 pub fn version(&self) -> &'static str {
852 VERSION
853 }
854
855 pub fn create_rune(
893 &self,
894 rune: Option<&str>,
895 restrictions: Vec<Vec<&str>>,
896 ) -> Result<String, anyhow::Error> {
897 if let Some(rune) = rune {
898 let mut rune: Rune = Rune::from_base64(rune)?;
900 restrictions.into_iter().for_each(|alts| {
901 let joined = alts.join("|");
902 _ = rune.add_restriction(joined.as_str())
903 });
904 return Ok(rune.to_base64());
905 } else {
906 let res: Vec<Restriction> = restrictions
907 .into_iter()
908 .map(|alts| {
909 let joined = alts.join("|");
910 Restriction::try_from(joined.as_str())
911 })
912 .collect::<Result<Vec<Restriction>, RuneError>>()?;
913
914 let unique_id = 0;
917
918 let has_pubkey_field = res.iter().any(|r: &Restriction| {
920 r.alternatives
921 .iter()
922 .any(|a| a.get_field() == *"pubkey" && a.get_condition() == Condition::Equal)
923 });
924 if !has_pubkey_field {
925 return Err(anyhow!("Missing a restriction on the pubkey"));
926 }
927
928 let rune = Rune::new(
929 self.master_rune.authcode(),
930 res,
931 Some(unique_id.to_string()),
932 Some(RUNE_VERSION.to_string()),
933 )?;
934 Ok(rune.to_base64())
935 }
936 }
937}
938
939fn update_state_from_context(
943 requests: &Vec<model::Request>,
944 handler: &handler::RootHandler,
945) -> Result<(), Error> {
946 log::debug!("Updating state from {} context request", requests.len());
947 let node = handler.node();
948
949 requests
950 .iter()
951 .for_each(|r| update_state_from_request(r, &node).unwrap());
952 Ok(())
953}
954
955fn update_state_from_request(
956 request: &model::Request,
957 node: &lightning_signer::node::Node,
958) -> Result<(), Error> {
959 use lightning_signer::invoice::Invoice;
960 use std::str::FromStr;
961 match request {
962 model::Request::SendPay(model::cln::SendpayRequest {
963 bolt11: Some(inv), ..
964 }) => {
965 let invoice = Invoice::from_str(inv).unwrap();
966 log::debug!(
967 "Adding invoice {:?} as side-effect of this sendpay {:?}",
968 invoice,
969 request
970 );
971 node.add_invoice(invoice).unwrap();
972 }
973 _ => {}
974 }
975
976 Ok(())
977}
978
979fn decode_request(r: crate::pb::PendingRequest) -> Result<model::Request, anyhow::Error> {
985 assert_eq!(r.request[0], 0u8);
992 let payload = &r.request[5..];
993
994 crate::signer::model::cln::decode_request(&r.uri, payload)
995 .or_else(|_| crate::signer::model::greenlight::decode_request(&r.uri, payload))
996}
997
998pub struct StartupMessage {
1001 request: Vec<u8>,
1002 response: Vec<u8>,
1003}
1004
1005impl From<StartupMessage> for crate::pb::scheduler::StartupMessage {
1006 fn from(r: StartupMessage) -> Self {
1007 Self {
1008 request: r.request,
1009 response: r.response,
1010 }
1011 }
1012}
1013
1014#[cfg(test)]
1015mod tests {
1016 use super::*;
1017 use crate::credentials;
1018 use crate::pb;
1019
1020 #[tokio::test]
1026 async fn test_sign_message_rejection() {
1027 let signer = Signer::new(
1028 vec![0 as u8; 32],
1029 Network::Bitcoin,
1030 credentials::Nobody::default(),
1031 )
1032 .unwrap();
1033
1034 let msg = hex::decode("0017000B48656c6c6f20776f726c64").unwrap();
1035 assert!(signer
1036 .process_request(HsmRequest {
1037 request_id: 0,
1038 context: None,
1039 raw: msg,
1040 signer_state: vec![],
1041 requests: Vec::new(),
1042 },)
1043 .await
1044 .is_err());
1045 }
1046
1047 #[tokio::test]
1049 async fn test_empty_message() {
1050 let signer = Signer::new(
1051 vec![0 as u8; 32],
1052 Network::Bitcoin,
1053 credentials::Nobody::default(),
1054 )
1055 .unwrap();
1056
1057 assert_eq!(
1058 signer
1059 .process_request(HsmRequest {
1060 request_id: 0,
1061 context: None,
1062 raw: vec![],
1063 signer_state: vec![],
1064 requests: Vec::new(),
1065 },)
1066 .await
1067 .unwrap_err()
1068 .to_string(),
1069 *"protocol error: ShortRead"
1070 )
1071 }
1072
1073 #[test]
1074 fn test_sign_message_max_size() {
1075 let signer = Signer::new(
1076 vec![0u8; 32],
1077 Network::Bitcoin,
1078 credentials::Nobody::default(),
1079 )
1080 .unwrap();
1081
1082 let msg = [0u8; u16::MAX as usize + 1];
1084 assert_eq!(
1085 signer.sign_message(msg.to_vec()).unwrap_err().to_string(),
1086 format!("Message exceeds max len of {}", u16::MAX)
1087 );
1088 }
1089
1090 #[test]
1095 fn test_legacy_bip32_key() {
1096 let signer = Signer::new(
1097 vec![0u8; 32],
1098 Network::Bitcoin,
1099 credentials::Nobody::default(),
1100 )
1101 .unwrap();
1102
1103 let bip32 = signer.legacy_bip32_ext_key();
1104 let expected: Vec<u8> = vec![
1105 4, 136, 178, 30, 2, 175, 86, 45, 251, 0, 0, 0, 0, 119, 232, 160, 181, 114, 16, 182, 23,
1106 70, 246, 204, 254, 122, 233, 131, 242, 174, 134, 193, 120, 104, 70, 176, 202, 168, 243,
1107 142, 127, 239, 60, 157, 212, 3, 162, 85, 18, 86, 240, 176, 177, 84, 94, 241, 92, 64,
1108 175, 69, 165, 146, 101, 79, 180, 195, 27, 117, 8, 66, 110, 100, 36, 246, 115, 48, 193,
1109 189, 3, 247, 195, 58, 236, 143, 230, 177, 91, 217, 66, 67, 19, 204, 22, 96, 65, 140,
1110 86, 195, 109, 50, 228, 94, 193, 173, 103, 252, 196, 192, 173, 243, 223,
1111 ];
1112
1113 assert_eq!(bip32, expected);
1114 }
1115
1116 #[test]
1119 fn test_rune_expects_pubkey() {
1120 let signer = Signer::new(
1121 vec![0u8; 32],
1122 Network::Bitcoin,
1123 credentials::Nobody::default(),
1124 )
1125 .unwrap();
1126
1127 let alt = "pubkey=112233";
1128 let wrong_alt = "pubkey^112233";
1129
1130 assert!(signer.create_rune(None, vec![]).is_err());
1132
1133 assert!(signer.create_rune(None, vec![vec![wrong_alt]]).is_err());
1135
1136 assert!(signer.create_rune(None, vec![vec![alt]]).is_ok());
1138
1139 assert!(signer
1141 .create_rune(None, vec![vec![wrong_alt], vec![wrong_alt, alt]])
1142 .is_ok());
1143 }
1144
1145 #[test]
1146 fn test_rune_expansion() {
1147 let signer = Signer::new(
1148 vec![0u8; 32],
1149 Network::Bitcoin,
1150 credentials::Nobody::default(),
1151 )
1152 .unwrap();
1153 let rune = "wjEjvKoFJToMLBv4QVbJpSbMoGFlnYVxs8yy40PIBgs9MC1nbDAmcHVia2V5PTAwMDAwMA==";
1154
1155 let new_rune = signer
1156 .create_rune(Some(rune), vec![vec!["method^get"]])
1157 .unwrap();
1158 let rs = Rune::from_base64(&new_rune).unwrap().to_string();
1159 assert!(rs.contains("0-gl0&pubkey=000000&method^get"))
1160 }
1161
1162 #[test]
1163 fn test_rune_checks_method() {
1164 let signer = Signer::new(
1165 vec![0u8; 32],
1166 Network::Bitcoin,
1167 credentials::Nobody::default(),
1168 )
1169 .unwrap();
1170
1171 let pubkey = signer.node_id();
1173 let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1174
1175 let rune = signer
1177 .create_rune(None, vec![vec![&pubkey_rest], vec!["method^create"]])
1178 .unwrap();
1179
1180 let uri = "/cln.Node/CreateInvoice".to_string();
1182 let r = pb::PendingRequest {
1183 request: vec![],
1184 uri,
1185 signature: vec![],
1186 pubkey: pubkey.clone(),
1187 timestamp: 0,
1188 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1189 };
1190 assert!(signer.verify_rune(r).is_ok());
1191
1192 let uri = "/cln.Node/Pay".to_string();
1194 let r = pb::PendingRequest {
1195 request: vec![],
1196 uri,
1197 signature: vec![],
1198 pubkey: pubkey.clone(),
1199 timestamp: 0,
1200 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1201 };
1202 assert!(signer.verify_rune(r).is_err());
1203
1204 let uri = "/greenlight.Node/CreateInvoice".to_string();
1207 let r = pb::PendingRequest {
1208 request: vec![],
1209 uri,
1210 signature: vec![],
1211 pubkey: pubkey.clone(),
1212 timestamp: 0,
1213 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1214 };
1215 assert!(signer.verify_rune(r).is_ok());
1216
1217 let uri = "/wrong.Service/CreateInvoice".to_string();
1220 let r = pb::PendingRequest {
1221 request: vec![],
1222 uri,
1223 signature: vec![],
1224 pubkey: pubkey.clone(),
1225 timestamp: 0,
1226 rune: general_purpose::URL_SAFE.decode(&rune).unwrap(),
1227 };
1228 assert!(signer.verify_rune(r).is_err());
1229 }
1230
1231 #[test]
1232 fn test_empty_rune_is_valid() {
1233 let creds = credentials::Nobody::default();
1234 let signer = Signer::new(vec![0u8; 32], Network::Bitcoin, creds).unwrap();
1235
1236 let pubkey = signer.node_id();
1238 let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1239
1240 let rune = signer.create_rune(None, vec![vec![&pubkey_rest]]).unwrap();
1241 let uri = "/cln.Node/Pay".to_string();
1242 assert!(signer
1243 .verify_rune(crate::pb::PendingRequest {
1244 request: vec![],
1245 uri,
1246 signature: vec![],
1247 pubkey,
1248 timestamp: 0,
1249 rune: general_purpose::URL_SAFE.decode(rune).unwrap(),
1250 })
1251 .is_ok());
1252 }
1253
1254 #[test]
1255 fn test_empty_rune_checks_pubkey() {
1256 let creds = credentials::Nobody::default();
1257 let signer = Signer::new(vec![0u8; 32], Network::Bitcoin, creds).unwrap();
1258
1259 let pubkey = signer.node_id();
1261 let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1262
1263 let rune = signer.create_rune(None, vec![vec![&pubkey_rest]]).unwrap();
1264 let uri = "/cln.Node/Pay".to_string();
1265 assert!(signer
1266 .verify_rune(crate::pb::PendingRequest {
1267 request: vec![],
1268 uri,
1269 signature: vec![],
1270 pubkey: hex::decode("33aabb").unwrap(),
1271 timestamp: 0,
1272 rune: general_purpose::URL_SAFE.decode(rune).unwrap(),
1273 })
1274 .is_err());
1275 }
1276}