first use of sqlx
This commit is contained in:
commit
9c8fcfd768
|
@ -0,0 +1,15 @@
|
|||
db/
|
||||
data/
|
||||
tmp/
|
||||
|
||||
result
|
||||
|
||||
secrets/
|
||||
.direnv/
|
||||
target/
|
||||
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
|
|
@ -0,0 +1 @@
|
|||
/nix/store/jg6yhrj8z8jb1x00fwhidh9kddzvwxj2-pre-commit-config.json
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
name = "cll2v0"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
# license = "MIT" -- set to apache
|
||||
|
||||
[package.metadata.release]
|
||||
release = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.95"
|
||||
clap = { version = "4.5.18", features = ["derive"] }
|
||||
ed25519-dalek = "2.1.1"
|
||||
futures = "0.3.30"
|
||||
hex = "0.4.3"
|
||||
libp2p = { version = "0.54.1", features = ["tokio", "gossipsub", "mdns", "noise", "macros", "tcp", "yamux", "quic", "identify", "ping", "relay", "dcutr", "rendezvous", "kad"] }
|
||||
libp2p-identity = { version = "0.2.9", features = ["ed25519", "peerid"] }
|
||||
owo-colors = "4.1.0"
|
||||
quick-protobuf = "0.8.1"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.213", features = ["derive"] }
|
||||
sqlx = { version = "0.8.2", features = ["sqlite", "macros", "runtime-tokio"] }
|
||||
tokio = { version = "1.40.0", features = ["full", "tracing"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
|
@ -0,0 +1,140 @@
|
|||
# CL L2 V0
|
||||
|
||||
This repo is a sandbox for the Cardano Lightning's L2 (V0).
|
||||
|
||||
A key aim of this repo is to try and assess available libraries in order to
|
||||
establish our key dependencies.
|
||||
|
||||
## Setup
|
||||
|
||||
This repo use nix flakes with a shell available. Otherwise ymmv.
|
||||
|
||||
## Context
|
||||
|
||||
CL depends on the use on signing/verification key pair cryptography. The signing
|
||||
key may be used to handover all the participants funds. The signing key must be
|
||||
handled with care.
|
||||
|
||||
A router node must run their infrastructure on highly available machines, in
|
||||
order to provide good service to their partners. The router might choose to use
|
||||
an infrastructure provider to host their nodes. The router must produce the
|
||||
signatures for cheques and snapshots in the course of standard channel
|
||||
operations. A priori the machine will contain signing keys. What if the machine
|
||||
is compromised?
|
||||
|
||||
An attacker with access to the machine could send all funds to the partner of
|
||||
the channel, or produce a tx that a partner signs, making it a valid mutual tx.
|
||||
In either case, they are at the detriment of the router.
|
||||
|
||||
Instead, we may outsource the signing process to a separate machine - the
|
||||
signing server. This sever can:
|
||||
|
||||
- serve requests to only whitelisted requesters. It can be more easily protected
|
||||
from ddos type attacks and probing by an attacker.
|
||||
- has minimal, relatively fixed, API. It will receive fewer updates each of
|
||||
which can be reviewed more thoroughly, and have shorter/tighter software
|
||||
supply chains, than might be true for the general service on the HA machine.
|
||||
|
||||
In addition, the signing service could be split using, say, FROST.
|
||||
|
||||
## Design
|
||||
|
||||
### Data
|
||||
|
||||
#### Persistent keys
|
||||
|
||||
These are the signing keys available to the machine and found at startup of the
|
||||
service.
|
||||
|
||||
#### Ephemeral keys
|
||||
|
||||
Perhaps also called proxy keys.
|
||||
|
||||
An ephemeral key consists of the following properties:
|
||||
|
||||
1. Verification key
|
||||
1. Persistent key
|
||||
1. Expires at
|
||||
1. Signature
|
||||
|
||||
### Actions
|
||||
|
||||
#### Sign
|
||||
|
||||
A sign action is the "standard" action that will occur.
|
||||
|
||||
A `sign` request has the following fields
|
||||
|
||||
1. Verification key
|
||||
2. Payload
|
||||
3. Signature
|
||||
|
||||
The request is deemed valid
|
||||
|
||||
1. The verification key exists in the database
|
||||
1. The verification key has not expired
|
||||
1. The signature is valid wrt the payload and verification key
|
||||
1. The payload is "sensible" (TBC) - this is context specific.
|
||||
|
||||
The response to a valid request
|
||||
|
||||
1. The signature produced by the persistent key associated to the verification
|
||||
key for the same payload.
|
||||
|
||||
#### Add
|
||||
|
||||
An add is performed by "admin" to create new ephemeral keys.
|
||||
|
||||
An `add` request has the following fields
|
||||
|
||||
1. Verification key
|
||||
2. Persistent key
|
||||
3. Expires at
|
||||
4. Signature
|
||||
|
||||
The request is deemed valid
|
||||
|
||||
1. The persistent key is in the database
|
||||
1. The signature is valid wrt the persistent key, and the payload created by
|
||||
`(verification_key, expires_at)` (with some prefix?)
|
||||
|
||||
The result of a valid `add` request is the ephemeral key is added to the
|
||||
database with the obvious fields.
|
||||
|
||||
The response is either `Ok()` or `Error("help message!")`
|
||||
|
||||
#### Revoke
|
||||
|
||||
A revoke is the opposite of add. It is also performed exclusively by admin.
|
||||
|
||||
An `revoke` request has the following fields
|
||||
|
||||
2. Verification key
|
||||
3. Signature
|
||||
|
||||
The request is deemed valid
|
||||
|
||||
1. The verification key is in the database
|
||||
1. The signature is valid wrt the associated persistent key, and the payload
|
||||
created by `verification_key` (with some prefix?)
|
||||
|
||||
The result of a valid `revoke` request is the ephemeral key is removed from the
|
||||
database.
|
||||
|
||||
The response is either `Ok()` or `Error("help message!")`
|
||||
|
||||
## Notes
|
||||
|
||||
### sqlx
|
||||
|
||||
The sqlx tool has a cli (available via the flake). This can handle migrations
|
||||
provided its opinionated design choices are adopted. See
|
||||
[here](https://docs.rs/sqlx/latest/sqlx/migrate/trait.MigrationSource.html).
|
||||
|
||||
```sh
|
||||
export DATABASE_URL=sqlite:./db/cll2v0.db
|
||||
sqlx database create
|
||||
sqlx migration run
|
||||
```
|
||||
|
||||
The database must be initialised before starting the application.
|
|
@ -0,0 +1,191 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1696426674,
|
||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1733312601,
|
||||
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks-nix": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734797603,
|
||||
"narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"git-hooks-nix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1735264675,
|
||||
"narHash": "sha256-MgdXpeX2GuJbtlBrH9EdsUeWl/yXEubyvxM1G+yO4Ak=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d49da4c08359e3c39c4e27c74ac7ac9b70085966",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1733096140,
|
||||
"narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1730741070,
|
||||
"narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1728538411,
|
||||
"narHash": "sha256-f0SBJz1eZ2yOuKUr5CA9BHULGXVSn6miBuUWdTyhUhU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b69de56fac8c2b6f8fd27f2eca01dcda8e0a4221",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"git-hooks-nix": "git-hooks-nix",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735352767,
|
||||
"narHash": "sha256-3zXufMRWUdwmp8/BTmxVW/k4MyqsPjLnnt/IlQyZvhc=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "a16b9a7cac7f4d39a84234d62e91890370c57d76",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1735135567,
|
||||
"narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
description = "CL L2 V0";
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
|
||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
git-hooks-nix.url = "github:cachix/git-hooks.nix";
|
||||
git-hooks-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = inputs:
|
||||
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
|
||||
imports = [
|
||||
./nix/rust.nix
|
||||
inputs.git-hooks-nix.flakeModule
|
||||
inputs.treefmt-nix.flakeModule
|
||||
];
|
||||
flake = {
|
||||
# Put your original flake attributes here.
|
||||
};
|
||||
systems = [
|
||||
# systems for which you want to build the `perSystem` attributes
|
||||
"x86_64-linux"
|
||||
# ...
|
||||
];
|
||||
perSystem = {
|
||||
self',
|
||||
config,
|
||||
inputs',
|
||||
pkgs,
|
||||
lib,
|
||||
system,
|
||||
...
|
||||
}: {
|
||||
treefmt = {
|
||||
projectRootFile = "flake.nix";
|
||||
flakeFormatter = true;
|
||||
programs = {
|
||||
prettier = {
|
||||
enable = true;
|
||||
settings = {
|
||||
printWidth = 80;
|
||||
proseWrap = "always";
|
||||
};
|
||||
};
|
||||
alejandra.enable = true;
|
||||
rustfmt.enable = true;
|
||||
};
|
||||
};
|
||||
pre-commit.settings.hooks.treefmt.enable = true;
|
||||
_module.args.pkgs = import inputs.nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
inputs.rust-overlay.overlays.default
|
||||
];
|
||||
config = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
CREATE TABLE IF NOT EXISTS persistent_keys
|
||||
(
|
||||
id BLOB PRIMARY KEY NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ephemeral_keys
|
||||
(
|
||||
id BLOB PRIMARY KEY NOT NULL,
|
||||
persistent_key BLOB NOT NULL,
|
||||
expires_at INTEGER NOT NULL,
|
||||
signature BLOB NOT NULL,
|
||||
FOREIGN KEY(persistent_key) REFERENCES persistent_keys(id)
|
||||
);
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
perSystem = {
|
||||
config,
|
||||
self',
|
||||
inputs',
|
||||
pkgs,
|
||||
lib,
|
||||
system,
|
||||
...
|
||||
}: let
|
||||
osxDependencies = with pkgs;
|
||||
lib.optionals stdenv.isDarwin
|
||||
[
|
||||
darwin.apple_sdk.frameworks.Security
|
||||
darwin.apple_sdk.frameworks.CoreServices
|
||||
];
|
||||
|
||||
cargoTomlContents = builtins.readFile ../Cargo.toml;
|
||||
version = (builtins.fromTOML cargoTomlContents).package.version;
|
||||
echo-net = pkgs.rustPlatform.buildRustPackage {
|
||||
inherit version;
|
||||
name = "cll2v0";
|
||||
buildInputs = with pkgs; [openssl] ++ osxDependencies;
|
||||
nativeBuildInputs = with pkgs; [pkg-config openssl.dev];
|
||||
src = let
|
||||
baseDir = ./../.;
|
||||
fileHasAnySuffix = fileSuffixes: file: (lib.lists.any (s: lib.hasSuffix s file.name) fileSuffixes);
|
||||
rustFilter = basePath: (
|
||||
let
|
||||
mainFilter = lib.fileset.fileFilter (fileHasAnySuffix [".rs" ".toml"]) basePath;
|
||||
in
|
||||
lib.fileset.unions [mainFilter (basePath + "/Cargo.toml") (basePath + "/Cargo.lock")]
|
||||
);
|
||||
in
|
||||
pkgs.lib.fileset.toSource {
|
||||
root = baseDir;
|
||||
fileset = rustFilter baseDir;
|
||||
};
|
||||
cargoLock.lockFile = ../Cargo.lock;
|
||||
meta = {
|
||||
description = "Cardano Lightning L2 V0";
|
||||
homepage = "cardano-lightning.org";
|
||||
# license = licenses.mit;
|
||||
};
|
||||
};
|
||||
|
||||
packages = {
|
||||
echo-net = echo-net;
|
||||
default = packages.echo-net;
|
||||
};
|
||||
|
||||
# FIXME :: I don't know if this is necessary,
|
||||
# but I don't know to fix it.
|
||||
# overlays.default = final: prev: {echo-net = packages.echo-net;};
|
||||
|
||||
gitRev =
|
||||
if (builtins.hasAttr "rev" self')
|
||||
then self'.rev
|
||||
else "dirty";
|
||||
in {
|
||||
inherit packages; # overlays;
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
config.treefmt.build.wrapper
|
||||
];
|
||||
shellHook = ''
|
||||
export GIT_REVISION=${gitRev}
|
||||
${config.pre-commit.installationScript}
|
||||
'';
|
||||
buildInputs = with pkgs;
|
||||
[
|
||||
pkg-config
|
||||
openssl
|
||||
cargo-insta
|
||||
(pkgs.rust-bin.stable.latest.default.override {
|
||||
extensions = ["rust-src" "clippy" "rustfmt" "rust-analyzer"];
|
||||
# targets = [ "wasm32-unknown-unknown" ];
|
||||
})
|
||||
sqlx-cli
|
||||
sqlite
|
||||
# nodePackages_latest.nodejs
|
||||
# nodePackages_latest.typescript-language-server
|
||||
# cmake
|
||||
# wasm-pack
|
||||
# protobuf
|
||||
# sqlite
|
||||
]
|
||||
++ osxDependencies;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use ed25519_dalek::{Signature, SigningKey, VerifyingKey};
|
||||
use hex;
|
||||
use sqlx::sqlite::SqlitePool;
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
#[command(subcommand)]
|
||||
cmd: Option<Command>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
Add {
|
||||
ephemeral_key: String,
|
||||
persistent_key: String,
|
||||
expires_at: i64,
|
||||
signature: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let args = Args::parse();
|
||||
let keys_path = env::var("CLL2V0_KEYS").expect("Expect `CLL2V0_KEYS` to be set");
|
||||
// let db_url = env::var("CLL2V0_DB").expect("Expect `CLL2V0_DB` to be set");
|
||||
let db_url = env::var("DATABASE_URL").expect("Expect `DATABASE_URL` to be set");
|
||||
let signing_keys = read_to_string(&keys_path).expect("Error reading file");
|
||||
|
||||
let pool = SqlitePool::connect(&db_url).await?;
|
||||
|
||||
let mut keychain: HashMap<[u8; 32], SigningKey> = HashMap::new();
|
||||
for key in signing_keys.lines() {
|
||||
let secret_key = hex::decode(key.trim()).unwrap().try_into().unwrap();
|
||||
let skey = SigningKey::from_bytes(&secret_key);
|
||||
let vkey = skey.verifying_key();
|
||||
keychain.insert(vkey.to_bytes(), skey);
|
||||
let _ = add_persistent_key(&pool, vkey).await;
|
||||
}
|
||||
|
||||
match args.cmd {
|
||||
Some(Command::Add {
|
||||
ephemeral_key,
|
||||
persistent_key,
|
||||
expires_at,
|
||||
signature,
|
||||
}) => {
|
||||
println!("Adding new ephemeral key '{ephemeral_key}'");
|
||||
let e = VerifyingKey::from_bytes(
|
||||
&hex::decode(ephemeral_key)
|
||||
.expect("Cannot parse ephemeral key")
|
||||
.try_into()
|
||||
.expect("wrong length"),
|
||||
)
|
||||
.expect("bad key");
|
||||
let p = VerifyingKey::from_bytes(
|
||||
&hex::decode(persistent_key)
|
||||
.expect("Cannot parse persistent")
|
||||
.try_into()
|
||||
.expect("wrong length"),
|
||||
)
|
||||
.expect("bad key");
|
||||
let s = Signature::from_bytes(
|
||||
&hex::decode(signature)
|
||||
.expect("Cannot parse persistent")
|
||||
.try_into()
|
||||
.expect("wrong length"),
|
||||
);
|
||||
|
||||
let res = add_ephemeral_key(&pool, &e, &p, expires_at, &s).await?;
|
||||
println!("Added new ekey: {}", res);
|
||||
}
|
||||
None => {
|
||||
println!("Printing list of all todos");
|
||||
list_persistent_keys(&pool).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_persistent_key(pool: &SqlitePool, vkey: VerifyingKey) -> anyhow::Result<i64> {
|
||||
let mut conn = pool.acquire().await?;
|
||||
let b = Into::<Vec<u8>>::into(vkey.to_bytes());
|
||||
|
||||
// Insert the task, then obtain the ID of this row
|
||||
let id = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO persistent_keys ( id )
|
||||
VALUES ( ?1 )
|
||||
"#,
|
||||
b
|
||||
)
|
||||
.execute(&mut *conn)
|
||||
.await?
|
||||
.last_insert_rowid();
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
async fn add_ephemeral_key(
|
||||
pool: &SqlitePool,
|
||||
ephemeral_key: &VerifyingKey,
|
||||
persistent_key: &VerifyingKey,
|
||||
expires_at: i64,
|
||||
signature: &Signature,
|
||||
) -> anyhow::Result<i64> {
|
||||
let mut conn = pool.acquire().await?;
|
||||
|
||||
let ephemeral_key_ = Into::<Vec<u8>>::into(ephemeral_key.to_bytes());
|
||||
let persistent_key_ = Into::<Vec<u8>>::into(persistent_key.to_bytes());
|
||||
let signature_ = Into::<Vec<u8>>::into(signature.to_bytes());
|
||||
// Insert the task, then obtain the ID of this row
|
||||
let res = sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO ephemeral_keys (
|
||||
id,
|
||||
persistent_key,
|
||||
expires_at,
|
||||
signature
|
||||
)
|
||||
VALUES ( ?1, ?2, ?3, ?4 )
|
||||
"#,
|
||||
ephemeral_key_,
|
||||
persistent_key_,
|
||||
expires_at,
|
||||
signature_,
|
||||
)
|
||||
.execute(&mut *conn)
|
||||
.await?
|
||||
.last_insert_rowid();
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
async fn list_persistent_keys(pool: &SqlitePool) -> anyhow::Result<()> {
|
||||
let recs = sqlx::query!(
|
||||
r#"
|
||||
SELECT id
|
||||
FROM persistent_keys
|
||||
ORDER BY id
|
||||
"#
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
for rec in recs {
|
||||
println!("- [{}]", hex::encode(rec.id),);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_key() {
|
||||
// Useful for setting up some keys
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
println!("{}", hex::encode(SigningKey::generate(&mut rng).to_bytes()));
|
||||
}
|
Loading…
Reference in New Issue