Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
resolver = "2"
members = [
"mid-types",
"mid-signer",
"kms-types",
"kms-verifier",
"kms-client",
Expand Down
9 changes: 4 additions & 5 deletions kms-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ crate-type = ["rlib"]
# Shared envelope types.
kms-types = { path = "../kms-types", version = "0.2.0" }

# The device-signing seam: `DeviceSigner` and the in-memory signer live in
# their own leaf so implementations and consumers need not pull this crate.
mid-signer = { path = "../mid-signer", version = "0.2.0" }

# ECDSA P-256 — same primitive as kms-verifier and the existing M5 keys
# managed by `mata-identity` / `mata-sync`.
p256 = { version = "0.13", default-features = false, features = ["ecdsa", "std"] }
Expand All @@ -30,11 +34,6 @@ serde_json = "1"
# Typed client errors.
thiserror = "1"

# OS randomness for the `InMemoryDeviceSigner::generate` test helper. The
# trait `DeviceSigner` itself never touches the RNG; this is only for the
# helper that callers can opt out of by constructing a SigningKey themselves.
rand_core = { version = "0.6", features = ["getrandom"] }

# wasm32 needs the older getrandom 0.2 (pulled by rand_core 0.6 → p256 0.13)
# enabled with the `js` feature so it can pull entropy from crypto.getRandomValues().
[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
4 changes: 1 addition & 3 deletions kms-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,7 @@ impl KmsClient {
.await
.map_err(|e| ClientError::BadResponseBody(e.to_string()))?;

envelope
.validate()
.map_err(ClientError::InvalidEnvelope)?;
envelope.validate().map_err(ClientError::InvalidEnvelope)?;

Ok(envelope)
}
Expand Down
3 changes: 1 addition & 2 deletions kms-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@

mod client;
mod sign;
mod signer;

pub use client::{ClientError, KmsClient};
pub use mid_signer::{DeviceSigner, InMemoryDeviceSigner};
pub use sign::{sign_assertion, sign_roster_update};
pub use signer::{DeviceSigner, InMemoryDeviceSigner};

// Re-exported so callers don't need to depend on kms-types directly.
pub use kms_types::{
Expand Down
97 changes: 0 additions & 97 deletions kms-client/src/signer.rs

This file was deleted.

31 changes: 31 additions & 0 deletions mid-signer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "mid-signer"
version = "0.2.0"
readme = "README.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/Remade-With-Rust/mid"
edition = "2021"
description = "The device-signing seam of MATA mID: the DeviceSigner trait (a stable device id and a low-s ECDSA P-256 signature over a 32-byte prehash) and the in-memory software signer. no_std (the trait needs no allocator), so a secure element, an eFuse key or a microcontroller implements the same contract kms-client, mid-issuer and mata-sign consume."

[lib]
crate-type = ["rlib"]

[features]
default = ["std"]
# `std`: p256's std error types and the `InMemoryDeviceSigner::generate`
# helper (OS randomness). `alloc`: the in-memory signer (it owns a `String`
# and hands out a `Vec`). With neither the crate is the trait and the low-s
# rule over `core` alone — what a microcontroller without an allocator links.
std = ["alloc", "p256/std", "dep:rand_core"]
alloc = ["p256/alloc"]

[dependencies]
# ECDSA P-256 — the same primitive as kms-verifier and the M5 keys.
p256 = { version = "0.13", default-features = false, features = ["ecdsa"] }

# OS randomness for `InMemoryDeviceSigner::generate` only. The trait never
# touches an RNG.
rand_core = { version = "0.6", features = ["getrandom"], optional = true }

[dev-dependencies]
sha2 = "0.10"
31 changes: 31 additions & 0 deletions mid-signer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# mid-signer

The device-signing seam of MATA mID, as a leaf crate.

Every place a device signs — `kms-client`'s assertions, `mid-issuer`'s genesis
roster, `mata-sign`'s tokens, a Janus microcontroller's capability manifest —
asks the same two things of the key: a stable device id, and a canonical
(low-s) ECDSA P-256 signature over a 32-byte prehash. That contract is the
`DeviceSigner` trait, and this crate is where it lives, so:

- a hardware-backed implementation (secure element, eFuse key, an ESP32's DS
peripheral) depends on `mid-signer` and `p256` and nothing else — no HTTP
client, no runtime;
- every consumer names one trait, and the software signer
(`InMemoryDeviceSigner`) is the reference each implementation is checked
against: same key, same prehash, same 64 bytes (RFC 6979).

`no_std` without the default `std` feature; `alloc` (implied by `std`) is what
`InMemoryDeviceSigner` needs, and without it the crate is the trait and the
low-s rule alone — a microcontroller with its key in hardware links nothing
else. `std` adds p256's std error types and the `generate` helper's OS
randomness.

```rust
use mid_signer::{DeviceSigner, InMemoryDeviceSigner};

let signer = InMemoryDeviceSigner::generate("dev-laptop");
let sig: [u8; 64] = signer.sign_prehash(&prehash); // low-s, always
```

`kms-client` re-exports both names, so existing code keeps compiling.
Loading