2018-12-14 10:10:15 -05:00
|
|
|
use Result;
|
2018-12-31 18:27:17 -05:00
|
|
|
use ring::rand;
|
|
|
|
use ring::signature::{self,Ed25519KeyPair,ED25519_PUBLIC_KEY_LEN,ED25519_PKCS8_V2_LEN};
|
|
|
|
use untrusted::Input;
|
|
|
|
use rustc_serialize::hex::{FromHex,ToHex};
|
2018-12-14 10:10:15 -05:00
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Keys for signing or verifying signatures. Small convenience
|
2018-12-31 18:27:17 -05:00
|
|
|
/// wrapper around `ring/ed25519`.
|
|
|
|
///
|
2018-12-14 10:10:15 -05:00
|
|
|
///
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
pub struct PublicKey([u8; ED25519_PUBLIC_KEY_LEN]);
|
|
|
|
pub struct KeyPair([u8; ED25519_PKCS8_V2_LEN]);
|
|
|
|
pub struct Signature(signature::Signature);
|
2018-12-14 10:10:15 -05:00
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
impl PublicKey {
|
|
|
|
pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey> {
|
|
|
|
let mut key = [0u8; ED25519_PUBLIC_KEY_LEN];
|
|
|
|
key.copy_from_slice(bytes);
|
|
|
|
Ok(PublicKey(key))
|
|
|
|
}
|
|
|
|
pub fn verify(&self, data: &[u8], signature: &[u8]) -> Result<()> {
|
|
|
|
let signature = Input::from(signature);
|
|
|
|
let data = Input::from(data);
|
|
|
|
let pubkey = Input::from(&self.0);
|
|
|
|
signature::verify(&signature::ED25519, pubkey, data, signature)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2018-12-14 10:10:15 -05:00
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
impl KeyPair {
|
2018-12-14 10:10:15 -05:00
|
|
|
/// Generate a new pair of signing/verifying keys using
|
|
|
|
/// the system random number generator. The resulting
|
2018-12-31 18:27:17 -05:00
|
|
|
/// `Ed25519KeyPair` can be extracted in an ascii
|
|
|
|
/// hex encoded pkcs#8 format for storage in configuration files
|
2018-12-14 10:10:15 -05:00
|
|
|
/// with the `to_hex()` method.
|
2018-12-31 18:27:17 -05:00
|
|
|
pub fn generate() -> Result<KeyPair> {
|
|
|
|
let rng = rand::SystemRandom::new();
|
|
|
|
let bytes = Ed25519KeyPair::generate_pkcs8(&rng)?;
|
|
|
|
KeyPair::from_bytes(&bytes)
|
|
|
|
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
pub fn from_hex(hex: &str) -> Result<KeyPair> {
|
|
|
|
KeyPair::from_bytes(&hex.from_hex()?)
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
fn from_bytes(bytes: &[u8]) -> Result<KeyPair> {
|
|
|
|
let mut pair = [0u8; ED25519_PKCS8_V2_LEN];
|
|
|
|
pair.copy_from_slice(bytes);
|
|
|
|
Ok(KeyPair(pair))
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
pub fn public_key_bytes(&self) -> Vec<u8> {
|
|
|
|
let pair = Ed25519KeyPair::from_pkcs8(Input::from(&self.0)).expect("failed to parse pkcs8 key");
|
|
|
|
pair.public_key_bytes().to_vec()
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
pub fn private_key_bytes(&self) -> Vec<u8> {
|
|
|
|
self.0.to_vec()
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
pub fn private_key_hex(&self) -> String {
|
|
|
|
self.0.to_hex()
|
|
|
|
}
|
|
|
|
pub fn public_key_hex(&self) -> String {
|
|
|
|
let pair = Ed25519KeyPair::from_pkcs8(Input::from(&self.0)).expect("failed to parse pkcs8 key");
|
|
|
|
pair.public_key_bytes().to_hex()
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
pub fn sign(&self, data: &[u8]) -> Result<Signature> {
|
|
|
|
let pair = Ed25519KeyPair::from_pkcs8(Input::from(&self.0))?;
|
|
|
|
let signature = pair.sign(data);
|
|
|
|
Ok(Signature(signature))
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
2018-12-31 18:27:17 -05:00
|
|
|
}
|
2018-12-14 10:10:15 -05:00
|
|
|
|
2018-12-31 18:27:17 -05:00
|
|
|
impl Signature {
|
|
|
|
pub fn to_bytes(&self) -> &[u8] {
|
|
|
|
self.0.as_ref()
|
2018-12-14 10:10:15 -05:00
|
|
|
}
|
|
|
|
}
|
2018-12-31 18:27:17 -05:00
|
|
|
|