gl_client/signer/
mod.rs

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;
7/// The core signer system. It runs in a dedicated thread or using the
8/// caller thread, streaming incoming requests, verifying them,
9/// signing if ok, and then shipping the response to the node.
10use 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";
53// This is the same derivation key that is used by core lightning itself.
54const 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    /// Cached version of the init response
65    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        // The persister takes care of persisting metadata across
123        // restarts
124        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            // TODO: Remove once we have fully switched over to zero-fee anchors
131            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        // TODO Remove this once VLS has implemented the fee budget
139        // per payment, rather than the fee budget per HTLC.
140        // Ref: https://github.com/Blockstream/greenlight/issues/538
141        {
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            // TODO: Remove once we have implemented zero invoice support
153            rules: vec![
154                FilterRule::new_warn("policy-routing-balanced"),
155                FilterRule::new_warn("policy-htlc-fee-range"),
156            ],
157        });
158
159        // TODO: Remove once we found the desync issue
160        policy.filter.merge(PolicyFilter {
161            rules: vec![
162                // "policy failure: get_per_commitment_secret: cannot
163                // revoke commitment_number 312 when
164                // next_holder_commit_num is 313"
165                FilterRule::new_warn("policy-revoke-new-commitment-signed"),
166            ],
167        });
168
169        // Increase the invoices limit. Results in a larger state, but
170        // bumping into this is rather annoying.
171        policy.max_invoices = 10_000usize;
172
173        // Relaxed max_routing_fee since we no longer have the
174        // presplitter which was causing the HTLCs to be smaller.
175        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        // Calling init on the `InitHandler` from above puts it into a
194        // state that it can be upgraded into the `RootHandler` that
195        // we need for the rest of the run.
196        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        // Init master rune. We create the rune seed from the nodes
205        // seed by deriving a hardened key tagged with "rune secret".
206        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    /// Create an `init` request that we can pass to the signer.
261    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    /// Filter out any request that is not signed, such that the
288    /// remainder is the minimal set to reconcile state changes
289    /// against.
290    ///
291    /// Returns an error if a signature failed verification or if the
292    /// rune verification failed.
293    fn check_request_auth(
294        &self,
295        requests: Vec<crate::pb::PendingRequest>,
296    ) -> Vec<Result<crate::pb::PendingRequest, anyhow::Error>> {
297        // Filter out requests lacking a required field. They are unverifiable anyway.
298        // Todo: partition results to provide more detailed errors.
299        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 we have a timestamp associated we must add it to
307                // the payload being checked. Same thing happens on
308                // the client too.
309                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    /// Verifies that the public key of the request and the signers rune version
324    /// match the corresponding restrictions of the rune.
325    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        // A valid gl-rune must contain a pubkey field as this  is bound to the
330        // signer. Against the rules of runes we do not accept a rune that has
331        // no restriction on a public key.
332        if !rune.to_string().contains("pubkey=") {
333            return Err(anyhow!("rune is missing pubkey field"));
334        }
335
336        // Currently we only use a 0 unique_id and a pubkey field to allow
337        // for delegation in the future but we could also set the public
338        // key as the unique_id in the future and add a method that allows
339        // to create new empty runes.
340        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        // Check that the request points to `cln.Node`.
347        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        // Extract the method from the request uri: eg. `/cln.Node/CreateInvoice`
363        // becomes `createinvoice`.
364        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    /// Given the URI of the running node, connect to it and stream
386    /// requests from it. The requests are then verified and processed
387    /// using the `Hsmd`.
388    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        // Quick path out of here: we can't find a resolution for a
469        // request, then abort!
470        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        // The first two bytes represent the message type. Check that
488        // it is not a `sign-message` request (type 23).
489        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        // If present, add the close_to_addr to the allowlist
530        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        // Match over root and client handler.
568        let response = match req.context.clone() {
569            Some(HsmRequestContext { dbid: 0, .. }) | None => {
570                // This is the main daemon talking to us.
571                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    /// Retrieve the messages we know `lightningd` will ask when
616    /// starting. Since we can't be attached during startup, or on
617    /// background sync runs, we need to stash them at the `scheduler`
618    /// so we can start without a signer present.
619    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            // v22.11 introduced an addiotiona startup message, the
634            // bolt12 key generation
635            vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
636                info: Octets("bolt12-invoice-base".as_bytes().to_vec()),
637            }),
638            // SCB needs a secret derived too
639            vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
640                info: Octets("scb secret".as_bytes().to_vec()),
641            }),
642            // Commando needs a secret for its runes
643            vls_protocol::msgs::Message::DeriveSecret(vls_protocol::msgs::DeriveSecret {
644                info: Octets("commando".as_bytes().to_vec()),
645            }),
646            // The node alias key
647            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    /// Connect to the scheduler given by the environment variable
719    /// `GL_SCHEDULER_GRPC_URI` (of the default URI) and wait for the
720    /// node to be scheduled. Once scheduled, connect to the node
721    /// directly and start streaming and processing requests.
722    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    /// Create and, if necessary, upgrade the scheduler
731    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        // Upgrade node if necessary.
747        // If it fails due to connection error, sleep and retry. Re-throw all other errors.
748        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    /// The core signer loop. Connects to the signer and keeps the connection alive.
781    ///
782    /// Used as inner loop for `run_forever_with_uri`.
783    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                    // This `wait` parameter means that the scheduler will
794                    // not automatically schedule the node. Rather we are
795                    // telling the scheduler we want to be told as soon as
796                    // the node is being scheduled so we can re-attach to
797                    // that.
798                    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 inbound_future = scheduler.signer_requests_stream(outbound);
867
868        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        // Can only sign for it's own id!
913        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        // Check that the signature matches
923        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        // Decode rune as we expect it to be in byte format in the pending request.
928        let rune = general_purpose::URL_SAFE
929            .decode(req.rune.clone())
930            .map_err(|e| Error::ApprovePairingRequestError(e.to_string()))?;
931
932        // Check that the rune matches
933        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        // Create the rune that approves pairing
949        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    // TODO See comment on `sign_device_key`.
968    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    /// Signs the devices public key. This signature is meant to be appended
977    /// to any payload signed by the device so that the signer can verify that
978    /// it knows the device.
979    ///
980    // TODO Use a lower-level API that bypasses the LN message
981    // prefix. This will allow us to re-expose the sign-message API to
982    // node users.
983    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    /// Signs a message with the hsmd client. Returns a tuple with the signature
992    /// and the unmodified recovery id.
993    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        // The signature returned by VLS consists of the signature with the
1015        // recovery id appended.
1016        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    /// Signs an invoice.
1023    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    /// Create a Node stub from this instance of the signer, configured to
1036    /// talk to the corresponding node.
1037    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    /// Creates a base64 string called a rune which is used to authorize
1049    /// commands on the node and to issue signatures from the signer. Each new
1050    /// rune must contain a `pubkey` field that equals the public key that is
1051    /// used to sign-off signature requests. Nobody can remove restrictions from
1052    /// a rune.
1053    ///
1054    /// If a `rune` is supplied the restrictions are added to this rune. This
1055    /// way one can invoke a rune that only allows for a subset of commands.
1056    ///
1057    /// `restrictions` is a vector of restrictions where each restriction itself
1058    /// is a vector of one ore more alternatives.
1059    ///
1060    /// - =: passes if equal ie. identical. e.g. method=withdraw
1061    /// - /: not equals, e.g. method/withdraw
1062    /// - ^: starts with, e.g. id^024b9a1fa8e006f1e3937f
1063    /// - $: ends with, e.g. id$381df1cc449605.
1064    /// - ~: contains, e.g. id~006f1e3937f65f66c40.
1065    /// - <: is a decimal integer, and is less than. e.g. time<1656759180
1066    /// - \>: is a decimal integer, and is greater than. e.g. time>1656759180
1067    /// - {: preceeds in alphabetical order (or matches but is shorter), e.g. id{02ff.
1068    /// - }: follows in alphabetical order (or matches but is longer), e.g. id}02ff.
1069    /// - #: a comment, ignored, e.g. dumb example#.
1070    /// - !: only passes if the name does not exist. e.g. something!.  Every other operator except # fails if name does not exist!
1071    ///
1072    /// # Examples
1073    /// This creates a fresh rune that is only restricted to a pubkey:
1074    ///
1075    /// `create_rune(None, vec![vec!["pubkey=000000"]])`
1076    ///
1077    /// "wjEjvKoFJToMLBv4QVbJpSbMoGFlnYVxs8yy40PIBgs9MC1nbDAmcHVia2V5PTAwMDAwMA"
1078    ///
1079    /// This adds a restriction to the rune, in this case a restriction that only
1080    /// allows to call methods that start with "list" or "get", basically a
1081    /// read-only rune:
1082    ///
1083    /// `create_rune("wjEjvKoFJToMLBv4QVbJpSbMoGFlnYVxs8yy40PIBgs9MC1nbDAmcHVia2V5PTAwMDAwMA", vec![vec!["method^list", "method^get"]])`
1084    ///
1085    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            // We got a rune, add restrictions to it!
1092            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            // New rune, we need a unique id.
1108            // FIXME: Add a counter that persists in SSS.
1109            let unique_id = 0;
1110
1111            // Check that at least one restriction has a `pubkey` field set.
1112            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
1132/// Look through the context requests and update the state
1133/// accordingly. This is useful to modify allowlists and invoice lists
1134/// extracted from the authenticated requests.
1135fn 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
1172/// Used to decode incoming requests into their corresponding protobuf
1173/// message. This is used by the E2E verification to verify that
1174/// incoming requests match up with the user intent. User intent here
1175/// refers to there being a user-signed command that matches the
1176/// effects we are being asked to sign off.
1177fn decode_request(r: crate::pb::PendingRequest) -> Result<model::Request, anyhow::Error> {
1178    // Strip the compressions flag (1 byte) and the length prefix (4
1179    // bytes big endian) and we're left with just the payload. See
1180    // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
1181    // for technical details.
1182    //
1183    // Notice that we assume that the compression flag is off.
1184    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
1191/// A `(request, response)`-tuple passed to the scheduler to allow
1192/// signerless startups.
1193pub 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    /// We should not sign messages that we get from the node, since
1214    /// we're using the sign_message RPC message to create TLS
1215    /// certificate attestations. We can remove this limitation once
1216    /// we switch over to a salted hash when signing those
1217    /// attestations.
1218    #[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    /// We should reject a signing request with an empty message.
1241    #[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        // We test if we reject a message that is too long.
1276        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    /// Some users were relying on the broken behavior of
1284    /// `bip32_ext_key`. We need to ensure that the behavior remains
1285    /// stable for the time being until we have ensured no users of it
1286    /// remain.
1287    #[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    /// We want to ensure that we can not generate a rune that is unrestricted
1310    /// on the public key "pubkey=<public-key-of-devices-tls-cert>".
1311    #[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        // Check empty restrictions.
1324        assert!(signer.create_rune(None, vec![]).is_err());
1325
1326        // Check wrong restriction.
1327        assert!(signer.create_rune(None, vec![vec![wrong_alt]]).is_err());
1328
1329        // Check good restriction.
1330        assert!(signer.create_rune(None, vec![vec![alt]]).is_ok());
1331
1332        // Check at least one alternative in one restriction.
1333        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        // This is just a placeholder public key, could also be a different one;
1365        let pubkey = signer.node_id();
1366        let pubkey_rest = format!("pubkey={}", hex::encode(&pubkey));
1367
1368        // Create a rune that allows methods that start with `create`.
1369        let rune = signer
1370            .create_rune(None, vec![vec![&pubkey_rest], vec!["method^create"]])
1371            .unwrap();
1372
1373        // A method/uri that starts with `create` is ok.
1374        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        // method/uri `Pay` is not allowed by the rune.
1386        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        // The `greenlight.Node` service also needs to be accepted for
1398        // setting the `close_to_addr`.
1399        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        // A service other than `cln.Node` and `greenlight.Node` is
1411        // not allowed.
1412        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        // This is just a placeholder public key, could also be a different one;
1430        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        // This is just a placeholder public key, could also be a different one;
1453        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}