Verify stored keychain SSH signatures

This commit is contained in:
Eric Wendland 2026-05-19 18:58:07 +02:00
commit f7f14f6b27
10 changed files with 160 additions and 15 deletions

View file

@ -73,6 +73,7 @@ impl Store {
CREATE TABLE IF NOT EXISTS keychain_signatures (
op_id TEXT NOT NULL,
signer TEXT NOT NULL,
signer_public_key TEXT NOT NULL DEFAULT '',
namespace TEXT NOT NULL,
signature BLOB NOT NULL,
created_at_ms INTEGER NOT NULL,
@ -205,6 +206,30 @@ impl Store {
INSERT OR IGNORE INTO meta(key, value) VALUES ('schema_version', '1');
"#,
)?;
self.add_column_if_missing(
"keychain_signatures",
"signer_public_key",
"TEXT NOT NULL DEFAULT ''",
)?;
Ok(())
}
fn add_column_if_missing(
&self,
table: &str,
column: &str,
definition: &str,
) -> Result<(), StoreError> {
let mut stmt = self.conn.prepare(&format!("PRAGMA table_info({table})"))?;
let columns = stmt
.query_map([], |row| row.get::<_, String>(1))?
.collect::<Result<Vec<_>, _>>()?;
if !columns.iter().any(|name| name == column) {
self.conn.execute(
&format!("ALTER TABLE {table} ADD COLUMN {column} {definition}"),
[],
)?;
}
Ok(())
}
@ -935,12 +960,13 @@ impl Store {
) -> Result<(), StoreError> {
self.conn.execute(
r#"INSERT OR REPLACE INTO keychain_signatures(
op_id, signer, namespace, signature, created_at_ms
op_id, signer, signer_public_key, namespace, signature, created_at_ms
)
VALUES (?1, ?2, ?3, ?4, ?5)"#,
VALUES (?1, ?2, ?3, ?4, ?5, ?6)"#,
params![
signature.op_id,
signature.signer,
signature.signer_public_key,
signature.namespace,
signature.signature,
signature.created_at_ms
@ -951,16 +977,17 @@ impl Store {
pub fn list_keychain_signatures(&self) -> Result<Vec<StoredKeychainSignature>, StoreError> {
let mut stmt = self.conn.prepare(
r#"SELECT op_id, signer, namespace, signature, created_at_ms
r#"SELECT op_id, signer, signer_public_key, namespace, signature, created_at_ms
FROM keychain_signatures ORDER BY created_at_ms, op_id, signer, namespace"#,
)?;
let rows = stmt.query_map([], |row| {
Ok(StoredKeychainSignature {
op_id: row.get(0)?,
signer: row.get(1)?,
namespace: row.get(2)?,
signature: row.get(3)?,
created_at_ms: row.get(4)?,
signer_public_key: row.get(2)?,
namespace: row.get(3)?,
signature: row.get(4)?,
created_at_ms: row.get(5)?,
})
})?;
rows.collect::<Result<Vec<_>, _>>()
@ -1342,6 +1369,7 @@ pub struct StoredKeychainOp {
pub struct StoredKeychainSignature {
pub op_id: String,
pub signer: String,
pub signer_public_key: String,
pub namespace: String,
pub signature: Vec<u8>,
pub created_at_ms: i64,
@ -1547,6 +1575,7 @@ mod tests {
let signature = StoredKeychainSignature {
op_id: "op:keychain:1".to_owned(),
signer: "ssh:blake3:admin".to_owned(),
signer_public_key: "ssh-ed25519 AAAAADMIN eric@geth".to_owned(),
namespace: "geth.keychain.v1@geth.local".to_owned(),
signature: b"-----BEGIN SSH SIGNATURE-----".to_vec(),
created_at_ms: 3,