diff --git a/src/rsa/core.rs b/src/rsa/core.rs index fe98d04..0ad600b 100644 --- a/src/rsa/core.rs +++ b/src/rsa/core.rs @@ -3,6 +3,8 @@ use num::bigint::BigUint; use rsa::errors::RSAError; use simple_asn1::{ASN1Block,ASN1DecodeErr}; +/// A valid key size for RSA keys, basically, and a (slightly annoying) +/// trait that is used to tie these types to their Barrett value types. pub trait RSAMode { type Barrett; } diff --git a/src/rsa/errors.rs b/src/rsa/errors.rs index 3ced3c8..f1013d3 100644 --- a/src/rsa/errors.rs +++ b/src/rsa/errors.rs @@ -1,6 +1,8 @@ use simple_asn1::ASN1DecodeErr; use rand; +/// A bunch of errors that you can get generating, reading, or +/// writing RSA keys. #[derive(Debug)] pub enum RSAError { BadMessageSize, diff --git a/src/rsa/mod.rs b/src/rsa/mod.rs index 0c4bf90..71b5ef2 100644 --- a/src/rsa/mod.rs +++ b/src/rsa/mod.rs @@ -57,11 +57,24 @@ fn diff(a: &T, b: &T) -> T } } +/// An RSA key pair containing keys of the given size; keeping them in the +/// type means you'll never forget which one you have. +/// +/// As an aside: +/// * `U512` should only be used for testing +/// * `U1024` should only be used to support old protocols or devices +/// * `U2048` is probably your bare minimum +/// * `U3072` is a very reasonable choice +/// * **`U4096` is what you should use** +/// * `U8192` is starting to get a bit silly (and slow) +/// * `U15360` is for when you're using encryption to heat your house or server room pub struct RSAKeyPair { pub public: RSAPublicKey, pub private: RSAPrivateKey } +/// A generic RSA key pair that is agnostic about its key size. It's not +/// totally clear why this is useful, at this point. #[derive(PartialEq)] pub enum RSAPair { R512(RSAPublicKey, RSAPrivateKey), diff --git a/src/rsa/private.rs b/src/rsa/private.rs index 0a8a872..7eeffcb 100644 --- a/src/rsa/private.rs +++ b/src/rsa/private.rs @@ -5,6 +5,8 @@ use rsa::errors::RSAError; use rsa::oaep::OAEPParams; use rsa::signing_hashes::SigningHash; +/// An RSA private key. Useful for signing messages and decrypting encrypted +/// content. #[derive(Clone,PartialEq)] pub struct RSAPrivateKey { @@ -12,6 +14,7 @@ pub struct RSAPrivateKey pub(crate) d: R } +/// A generic RSA private key which is agnostic to its key size. #[derive(Clone,PartialEq)] pub enum RSAPrivate { Key512(RSAPrivateKey), @@ -27,11 +30,19 @@ macro_rules! generate_rsa_private { ($num: ident, $bar: ident, $size: expr) => { impl RSAPrivateKey<$num> { + /// Generate a new private key with the given modulus and private + /// number (`d`). This operation actually does a bit of computation + /// under the hood, in order to speed up future ones, so you might + /// want to strongly consider sharing rather than multiple + /// instantiation. But you do you. pub fn new(n: $num, d: $num) -> RSAPrivateKey<$num> { let nu = $bar::new(n.clone()); RSAPrivateKey{ nu: nu, d: d } } + /// Sign the given message with the given SigningHash, returning + /// the signature. This uses a deterministic PKCS1 method for + /// signing messages, so no RNG required. pub fn sign(&self, signhash: &SigningHash, msg: &[u8]) -> Vec { @@ -43,6 +54,13 @@ macro_rules! generate_rsa_private sig } + /// Decrypted the provided encrypted blob using the given + /// parameters. This does standard RSA OAEP decryption, which is + /// rather slow. If you have a choice, you should probably do + /// something clever, like only use this encryption/decryption + /// method to encrypt/decrypt a shared symmetric key, like an + /// AES key. That way, you only do this operation (which is + /// SO SLOW) for a relatively small amount of data. pub fn decrypt(&self, oaep: &OAEPParams, msg: &[u8]) -> Result,RSAError> where H: Default + Digest + FixedOutput diff --git a/src/rsa/public.rs b/src/rsa/public.rs index f002353..941813a 100644 --- a/src/rsa/public.rs +++ b/src/rsa/public.rs @@ -12,6 +12,8 @@ use simple_asn1::{ASN1Block,ASN1DecodeErr,ASN1EncodeErr, use std::fmt; use utils::TranslateNums; +/// An RSA public key. Useful for verifying signatures or encrypting data to +/// send to the private key holder. #[derive(Clone,PartialEq)] pub struct RSAPublicKey { pub(crate) n: R, @@ -19,6 +21,7 @@ pub struct RSAPublicKey { pub(crate) e: R } +/// A generic private key that is agnostic to the key size. #[derive(Clone,PartialEq)] pub enum RSAPublic { Key512( RSAPublicKey), @@ -31,6 +34,9 @@ pub enum RSAPublic { } impl RSAPublic { + /// Verify that the given signature is for the given message, passing + /// in the same signing arguments used to sign the message in the + /// first place. pub fn verify(&self, signhash: &SigningHash, msg: &[u8], sig: &[u8]) -> bool { match self {