use super::errors::GhostkeyError;
use super::util::{sign_with_hash, verify_with_hash};
use blind_rsa_signatures::{
KeyPair as RSAKeyPair, PublicKey as RSAVerifyingKey, SecretKey as RSASigningKey,
};
use ed25519_dalek::*;
use rand_core::OsRng;
use serde::{Deserialize, Serialize};
use crate::armorable::Armorable;
use crate::FREENET_MASTER_VERIFYING_KEY_BASE64;
#[derive(Serialize, Deserialize, Clone)]
pub struct DelegateCertificateV1 {
pub payload: DelegatePayload,
pub signature: Signature,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct DelegatePayload {
pub delegate_verifying_key: RSAVerifyingKey,
pub info: String,
}
impl DelegateCertificateV1 {
pub fn new(
master_signing_key: &SigningKey,
info: &String,
) -> Result<(Self, RSASigningKey), Box<GhostkeyError>> {
let delegate_keypair = RSAKeyPair::generate(&mut OsRng, 2048)
.map_err(|e| GhostkeyError::RSAError(e.to_string()))?;
let payload = DelegatePayload {
delegate_verifying_key: delegate_keypair.pk,
info: info.clone(),
};
let signature = sign_with_hash(&master_signing_key, &payload)?;
let certificate = DelegateCertificateV1 {
payload,
signature: Signature::from(signature),
};
Ok((certificate, delegate_keypair.sk))
}
pub fn verify(
&self,
&master_verifying_key: &Option<VerifyingKey>,
) -> Result<String, Box<GhostkeyError>> {
let master_verifying_key = master_verifying_key.unwrap_or(VerifyingKey::from_base64(FREENET_MASTER_VERIFYING_KEY_BASE64).unwrap());
let verification = verify_with_hash(&master_verifying_key, &self.payload, &self.signature)?;
if verification {
Ok(self.payload.info.clone())
} else {
Err(Box::new(GhostkeyError::SignatureVerificationError(
"Failed to verify delegate certificate".to_string(),
)))
}
}
}
#[cfg(test)]
mod tests {
use crate::util::create_keypair;
use super::*;
#[test]
fn test_delegate_certificate_creation_and_verification() {
let (master_signing_key, master_verifying_key) = create_keypair(&mut OsRng).unwrap();
let info = "Test Delegate".to_string();
let (certificate, _delegate_signing_key) =
DelegateCertificateV1::new(&master_signing_key, &info).unwrap();
let verified_info = certificate.verify(&Some(master_verifying_key)).unwrap();
assert_eq!(verified_info, info);
}
#[test]
fn test_delegate_certificate_invalid_signature() {
let (master_signing_key, _) = create_keypair(&mut OsRng).unwrap();
let (_, wrong_verifying_key) = create_keypair(&mut OsRng).unwrap();
let info = "Test Delegate".to_string();
let (certificate, _delegate_signing_key) =
DelegateCertificateV1::new(&master_signing_key, &info).unwrap();
let result = certificate.verify(&Some(wrong_verifying_key));
assert!(result.is_err());
assert!(matches!(
result.unwrap_err().as_ref(),
GhostkeyError::SignatureVerificationError(_)
));
}
#[test]
fn test_delegate_certificate_payload_integrity() {
let (master_signing_key, master_verifying_key) = create_keypair(&mut OsRng).unwrap();
let info = "Test Delegate".to_string();
let (mut certificate, _delegate_signing_key) =
DelegateCertificateV1::new(&master_signing_key, &info).unwrap();
assert!(certificate.verify(&Some(master_verifying_key)).is_ok());
certificate.payload.info = "Tampered Info".to_string();
let result = certificate.verify(&Some(master_verifying_key));
assert!(result.is_err());
assert!(matches!(
result.unwrap_err().as_ref(),
GhostkeyError::SignatureVerificationError(_)
));
}
}