passwors 0.1.1

Passwors is a simple password handling library that utilises Rust's type system to enfore better password handling. Use it as a basic building block for more complex authentication systems.
//! Passwors is a simple password handling library
//! that utilises Rust's type system to enfore better
//! password handling.  Use it as a basic building
//! block for more complex authentication systems.
//!
//! ```rust
//! extern crate passwors;
//!
//! use passwors::*;
//!
//! fn main() {
//!     // ... some code...
//!
//!     # let some_password_source = "asdf1234 is a really shitty password!".to_owned();
//!     // Read a user's password into a clear text password
//!     // to generate and compare hashes.
//!     let pw      = ClearTextPassword::from_string(some_password_source).unwrap();
//!     let salt    = HashSalt::new().unwrap(); // You should grab this from your database.
//!     let a2hash  = Argon2PasswordHasher::default();
//!     let pw_hash = pw.hash(&a2hash, &salt);
//!
//!     # let stored_hash = pw.hash(&a2hash, &salt);
//!     // Grab the password hash to compare from your database.
//!     // You should always calculate password hashes, even if
//!     // the user who wants to log in doesn't exist.
//!     assert_eq!(pw_hash, stored_hash, "Login failed!");
//!
//!     // ... more code...
//! }
//! ```
//!
//! # The Types
//!
//! There are four types involved when it comes to
//! handling passwords.
//!
//! - `ClearTextPassword` is what you get from a user's
//!   inputs. This is a secret token that only its creator
//!   should know.
//! - `HashedPassword` is what you use to validate one's
//!   identity. It is there to be compared, stored, read,
//!   and what not.
//! - `HashSalt` is a blob of random data, generated using
//!   strong CSPRNGs only. It should be uniquely generated
//!   for each of your users and is used to randomise the
//!   outcome of hashing a clear text password.
//! - `PasswordHasher` is a trait for... well... password
//!   hashers. They are the only unsafe component here, as
//!   they are the only ones that are able to read a user's
//!   clear text password.
//!
//! ## Clear Text Password
//!
//! As this is a secret token, this type does not leak any
//! kind of information to anyone but password hashers.
//!
//! - You cannot query the clear text password's length.
//! - You cannot read the clear text password data.
//! - You cannot modify the clear text password.
//! - You cannot compare clear text passwords.
//! - You cannot duplicate clear text passwords.
//! - Additionally, on `drop`, the clear text password's
//!   memory will be zero-filled.
//!
//! ## Hashed Password
//!
//! This is what you compare, store into databases,
//! look at, or whatever else. A hashed password is created
//! from a clear text password by giving it a hash salt and
//! a password hasher. Ideally, it is impossible to guess
//! a clear text password by looking at its hash.
//!
//! ## Hash Salt
//!
//! A hash salt should be unique for all users, which is
//! why they are only created using a CSPRNG. You can safely
//! move them around or store them into a data base. But as
//! they should be unique, you cannot clone or copy them.
//!
//! Of course, if you really wanted to have duplicate salts,
//! you could just serialise the same salt for multiple user
//! database entries.
//!
//! ## Password Hasher
//!
//! They are the only ones being able to read clear text
//! passwords. Additionally, the whole security depends on
//! how strong the hash function of choice is. You could,
//! for example, hash the user's passwords using good ol'
//! *MD5*, or you could use *scrypt* instead.
//!
//! Don't forget to store a hasher's configuration next to
//! the user's hashed password in your database, so you can
//! always upgrade your server's hasher settings to fit
//! today's increased computational password cracking power.
#![feature(box_syntax, core_intrinsics, question_mark, pub_restricted)]
#![cfg_attr(any(test, feature = "use_serde", feature = "default"), feature(custom_derive, plugin))]
#![cfg_attr(any(test, feature = "use_serde", feature = "default"), plugin(serde_macros))]
#![cfg_attr(test, feature(test))]

#[cfg(any(feature = "use_argon2rs", feature = "default"))] extern crate argon2rs;
#[cfg(any(test, feature = "use_serde", feature = "default"))] extern crate serde;
#[cfg(test)] extern crate serde_test;
#[cfg(test)] extern crate test;
extern crate rand;



pub use self::clear_text_password::ClearTextPassword;
pub use self::hashed_password::HashedPassword;
pub use self::password_hasher::PasswordHasher;
pub use self::hash_salt::HashSalt;

pub use self::clear_text_password::CLEAR_TEXT_LEN;
pub use self::clear_text_password::MIN_CLEAR_TEXT_LEN;
pub use self::hashed_password::HASHED_PASSWORD_LEN;
pub use self::hash_salt::HASH_SALT_LEN;

#[cfg(any(feature = "use_argon2rs", feature = "default"))]
pub use self::argon2_password_hasher::{ Argon2PasswordHasher, Argon2Err, Argon2Settings };



mod clear_text_password;
mod hashed_password;
mod password_hasher;
mod hash_salt;

#[cfg(any(feature = "use_argon2rs", feature = "default"))]
mod argon2_password_hasher;



#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}