use p256::ecdsa::{signature::Signer as p256Signer, Signature, SigningKey};
use prost::Message;
use cmpb::accesscontrol::Member;
use cmpb::common::Payload;
type MemberType = i32;
const MEMBER_TYPE_CERT: MemberType = 0;
const MEMBER_TYPE_PUBLIC_KEY: MemberType = 2;
const MEMBER_TYPE_DID: MemberType = 3;
type SignerError = String;
pub trait Signer {
fn sign(&self, payload: &Payload) -> Result<Vec<u8>, SignerError>;
fn new_member(&self) -> Member;
}
pub struct PublicModeSigner {
publick_key: String,
signer: SigningKey,
}
impl PublicModeSigner {
pub fn from_sec_pem(s: &str) -> Result<Self, SignerError> {
let secret_key = match p256::SecretKey::from_sec1_pem(s) {
Err(e) => return Err(format!("failed to parse pem.")),
Ok(s) => s,
};
let publick_key = secret_key.public_key().to_string();
let signer = p256::ecdsa::SigningKey::from(secret_key);
Ok(PublicModeSigner {
publick_key,
signer,
})
}
}
impl Signer for PublicModeSigner {
fn sign(&self, payload: &Payload) -> Result<Vec<u8>, SignerError> {
let data = payload.encode_to_vec();
let s: Signature = self.signer.sign(data.as_ref());
Ok(s.to_der().as_bytes().to_vec())
}
fn new_member(&self) -> Member {
Member {
org_id: "".to_string(),
member_type: MEMBER_TYPE_PUBLIC_KEY,
member_info: self.publick_key.clone().as_bytes().to_vec(),
}
}
}