From 5a80ff9870c879454c5f6af8fa6ad37a6f53e758 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 19 Oct 2025 23:57:49 +0800 Subject: [PATCH] feat: sign v2 --- src/lib.rs | 55 ++++++++++++++++++++++-- src/signature.rs | 110 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 158 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2004d84..eb75189 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,8 @@ mod util; pub use crate::keymap::KeyMap; use crate::sign::{ecdsaverify, EcdsaAlgorithm}; use crate::signature::{ - CardEcSignResult, ScriptSignature, ScriptSignatureAlgorithm, SIGNATURE_PREFIX, + CardEcSignResult, ScriptSignature, ScriptSignatureAlgorithm, ScriptSignatureVersion, + SIGNATURE_PREFIX, }; use crate::util::current_time; use digest::Digest; @@ -135,7 +136,48 @@ impl Script { None => return simple_error!("Sign key id: {} not found", &signature.key_id), Some(key) => key, }; - let key_bytes = hex::decode(&key.public_key_point_hex)?; + + let mut verify_public_key = key.public_key_point_hex.clone(); + if ScriptSignatureVersion::V2 == signature.ver { + match &signature.embed_signing_key { + Some(embed_signing_key) => { + let mut hasher = Sha256::new(); + hasher.update(embed_signing_key.time.as_bytes()); + hasher.update(&embed_signing_key.public_key); + let embed_digest_sha256 = hasher.finalize().to_vec(); + let key_bytes = hex::decode(&key.public_key_point_hex)?; + match embed_signing_key.algorithm { + ScriptSignatureAlgorithm::ES256 => { + match ecdsaverify( + EcdsaAlgorithm::P256, + &key_bytes, + &embed_digest_sha256, + &embed_signing_key.signature, + ) { + Ok(_) => { + verify_public_key = hex::encode(&embed_signing_key.public_key); + } + Err(e) => { + debugging!("Verify embed ecdsa signature failed: {}", e); + return Ok(false); + } + } + } + _ => { + return simple_error!( + "Not supported algorithm: {:?}", + signature.algorithm + ) + } + } + } + None => { + return simple_error!("Embed signing key not found"); + } + } + } + + let key_bytes = hex::decode(&verify_public_key)?; let digest_sha256 = self.normalize_content_lines_and_sha256(&signature.time); match signature.algorithm { ScriptSignatureAlgorithm::ES256 => { @@ -169,7 +211,9 @@ impl Script { ); if ecsign_result.algorithm == "ecdsa_p256_with_sha256" { self.signature = Some(ScriptSignature { + ver: ScriptSignatureVersion::V1, key_id: "yk-r1".to_string(), + embed_signing_key: None, algorithm: ScriptSignatureAlgorithm::ES256, time, signature: hex::decode(&ecsign_result.signed_data_hex)?, @@ -262,13 +306,16 @@ console.log("Hello world."); // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250122T233410+08:00.MEQCIGogDudoVpCVfGiNPu8Wn6YPDtFX5OXC4bKtsN1nw414AiAq+5EVdvOuKAlXdVeeE1d91mKX9TaSTR25jliUx0km6A=="##) .unwrap(); let script_str = script.as_string(); - assert_eq!(r##"#!/usr/bin/env -S deno run --allow-env + assert_eq!( + r##"#!/usr/bin/env -S deno run --allow-env console.log("Hello world."); // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250122T233410+08:00.MEQCIGogDudoVpCVfGiNPu8W // n6YPDtFX5OXC4bKtsN1nw414AiAq+5EVdvOuKAlXdVeeE1d91mKX9TaSTR25jliUx0km6A== -"##, script_str); +"##, + script_str + ); } #[test] diff --git a/src/signature.rs b/src/signature.rs index 29c1bda..b32c5ad 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -6,6 +6,7 @@ use serde::Deserialize; pub const SIGNATURE_PREFIX: &str = "// @SCRIPT-SIGNATURE-"; pub const SIGNATURE_V1: &str = "V1"; +pub const SIGNATURE_V2: &str = "V2"; #[derive(Debug, Eq, PartialEq)] pub enum ScriptSignatureAlgorithm { @@ -15,6 +16,12 @@ pub enum ScriptSignatureAlgorithm { ES521, } +#[derive(Debug, Eq, PartialEq)] +pub enum ScriptSignatureVersion { + V1, + V2, +} + impl ScriptSignatureAlgorithm { pub fn try_from(algo: &str) -> XResult { let upper_algo = algo.to_uppercase(); @@ -37,9 +44,19 @@ impl ScriptSignatureAlgorithm { } } +#[derive(Debug)] +pub struct EmbedSigningKey { + pub algorithm: ScriptSignatureAlgorithm, + pub time: String, + pub public_key: Vec, + pub signature: Vec, +} + #[derive(Debug)] pub struct ScriptSignature { + pub ver: ScriptSignatureVersion, pub key_id: String, + pub embed_signing_key: Option, pub algorithm: ScriptSignatureAlgorithm, pub time: String, pub signature: Vec, @@ -57,22 +74,75 @@ pub struct CardEcSignResult { impl ScriptSignature { pub fn parse(script_signature_line: &str) -> XResult { - // e.g. // @SCRIPT-SIGNATURE-V1: ..