diff --git a/README.md b/README.md index d858cfe..b2ae10c 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,9 @@ Anagram of "Gorgon". ## Actions - * `cargo run -- create eli.key`: makes a new key. + * `cargo run -- create eli.key eli.publickey`: makes a new key. * `cargo run -- sign eli.key message.txt [message.sig]`: signs a message, optionally writes the signature to a file. + * `cargo run -- validate eli.publickey message.txt message.signed`: validates a signature. ## TODO diff --git a/gongor.rs b/gongor.rs index 0e34fdd..b26625f 100644 --- a/gongor.rs +++ b/gongor.rs @@ -6,6 +6,10 @@ use rand::rngs::OsRng; use ed25519_dalek::SigningKey; use ed25519_dalek::Signature; use ed25519_dalek::Signer; +use ed25519_dalek::Verifier; +use ed25519_dalek::VerifyingKey; +use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH}; + fn main() -> std::io::Result<()>{ let action = std::env::args().nth(1).expect("no command given"); @@ -16,7 +20,7 @@ fn main() -> std::io::Result<()>{ let mut keyfile = File::open(&keyfilepath).expect("no file found"); - let mut keybuffer: [u8; 32] = [0; 32]; + let mut keybuffer: [u8; 32] = [0; SECRET_KEY_LENGTH]; keyfile.read(&mut keybuffer).expect("buffer overflow"); let signing_key: SigningKey = SigningKey::from_bytes(&keybuffer); @@ -38,18 +42,50 @@ fn main() -> std::io::Result<()>{ } else { println!("Signture: {signature}"); } - return Ok(()) + } else if action == "validate" { + let public_key_filepath = std::env::args().nth(2).expect("no key filepath given"); + let message_filepath = std::env::args().nth(3).expect("no message filepath given"); + let signature_filepath = std::env::args().nth(4).expect("no signature filepath given"); + + let mut public_keyfile = File::open(&public_key_filepath).expect("no file found"); + let mut public_keybuffer: [u8; PUBLIC_KEY_LENGTH] = [0; PUBLIC_KEY_LENGTH]; + public_keyfile.read(&mut public_keybuffer).expect("buffer overflow"); + let public_key: VerifyingKey = VerifyingKey::from_bytes(&public_keybuffer).expect("Faled to make a key"); + + let messagefile= File::open(&message_filepath).expect("no file found"); + let mut messagereader = BufReader::new(messagefile); + let mut messagebuf = Vec::new(); + messagereader.read_to_end(&mut messagebuf)?; + + let signature_file = File::open(&signature_filepath).expect("no file found"); + let mut signature_reader = BufReader::new(signature_file); + let mut signature_buf: [u8; SIGNATURE_LENGTH] = [0; SIGNATURE_LENGTH]; + signature_reader.read(&mut signature_buf).expect("buffer overflow"); + let signature: Signature = Signature::try_from(&signature_buf[..]).expect("not a signature"); + + if public_key.verify(&messagebuf, &signature).is_ok() { + println!("Yep, that checks out."); + } else { + println!("Invalid signature."); + } } else if action == "create" { - let keyfilepath = std::env::args().nth(2).expect("no keyfilepath given"); + let signing_key_filepath = std::env::args().nth(2).expect("no signing key file path given"); + let verifying_key_filepath = std::env::args().nth(3).expect("no verifying key file path given"); + let mut csprng = OsRng; let signing_key: SigningKey = SigningKey::generate(&mut csprng); - println!("Writing new key to {keyfilepath}"); - let mut file = File::create(keyfilepath)?; + println!("Writing new private key to {signing_key_filepath}"); + let mut file = File::create(signing_key_filepath)?; file.write_all(&signing_key.to_bytes())?; - return Ok(()); + + println!("Writing new public key to {verifying_key_filepath}"); + let verifying_key: VerifyingKey = signing_key.verifying_key(); + file = File::create(verifying_key_filepath)?; + file.write_all(&verifying_key.to_bytes())?; + } else { println!("Unrecognized command {action}"); - return Ok(()); } + return Ok(()); }