Giter Club home page Giter Club logo

libreauth's Introduction

LibreAuth

Build Status LibreAuth on crates.io LibreAuth on docs.rs License: CeCILL-C License: CeCILL-2.1

LibreAuth is a collection of tools for user authentication.

Features

  • Password / passphrase authentication
    • no character-set limitation
    • reasonable length limit (security vs. DOS)
    • strong, evolutive and retro-compatible password hashing functions
    • NFKC normalization for Unicode passwords
    • optional NIST Special Publication 800-63B compatibility
    • optional additional HMAC with an external salt before or after hashing the password
  • HOTP - HMAC-based One-time Password Algorithm (OATH - RFC 4226)
    • the key can be passed as bytes, an ASCII string, an hexadicimal string, a base32 string or a base64 string
    • customizable counter
    • customizable hash function (sha1, full sha2 family, sha3/Keccak fixed-size families)
    • customizable output length
    • customizable output alphabet
  • TOTP - Time-based One-time Password Algorithm (OATH - RFC 6238)
    • the key can be passed as bytes, an ASCII string, an hexadicimal string, a base32 string or a base64 string
    • customizable timestamp
    • customizable period
    • customizable initial time (T0)
    • customizable hash function (sha1, full sha2 family, sha3/Keccak fixed-size families)
    • customizable output length
    • customizable output alphabet
    • customizable positive and negative period tolerance
  • Random key generation
    • uses the platform's secure entropy source
    • customizable size
    • customizable output format (Vec, hexadecimal string, base32 string, base64 string)

Status

The project itself is still in development and therefore should not be used in production before version 1.0.0. Below is the list of features that will be present in the first stable version and their individual status.

  • OATH HOTP/TOTP: almost ready!
    • ✅ lot of features
    • ✅ stable API
    • ⚠️ lack of peer review
  • Password / passphrase authentication: almost ready!
    • ✅ sane defaults
    • ✅ stable API
    • ⚠️ lack of peer review
  • Random key generation: almost ready!
    • ✅ stable API
    • ⚠️ lack of peer review

Using within a Rust project

You can find LibreAuth on crates.io and include it in your Cargo.toml:

libreauth = "*"

Modules can be cherry-picked using default-features = false and then using only the features you want.

[dependencies.libreauth]
version = "*"
default-features = false
features = ["key", "oath", "pass"]

Using outside Rust

In order to build LibreAuth, you will need the Rust compiler and its package manager, Cargo. The minimum supported Rust version (MSRV) is 1.66, although it is recommended to use the latest stable one.

$ make
$ make install

Quick examples

Rust

More examples are available in the documentation.

use libreauth::oath::TOTPBuilder;

fn main() {
    let key = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ".to_string();
    let code = TOTPBuilder::new()
        .base32_key(&key)
        .finalize()
        .unwrap()
        .generate();
    assert_eq!(code.len(), 6);
}

C

#include <stdio.h>
#include <libreauth.h>

int main(void) {
  struct libreauth_totp_cfg cfg;
  char   code[7], key[] = "12345678901234567890";

  if (libreauth_totp_init(&cfg) != LIBREAUTH_OTP_SUCCESS) {
    return 1;
  }
  cfg.key = key;
  cfg.key_len = strlen(key);
  if (libreauth_totp_generate(&cfg, code) != LIBREAUTH_OTP_SUCCESS) {
    return 2;
  }

  printf("%s\n", code);

  return 0;
}
$ cc -o totp totp.c -llibreauth
$ ./totp
848085

License

LibreAuth is a free software available either under the CeCILL-C or the CeCILL 2.1 license. For a quick summary of those licenses, you can read the frequently asked questions on the licenses' website. A full copy of those licenses are available in this repository both in english and french.

While the CeCILL 2.1 is the original LibreAuth license, future versions may be published only under the CeCILL-C license. This change occurs because CeCILL 2.1 isn't really suited for a library since it is a "viral" license.

libreauth's People

Contributors

alexwl avatar asafdav2 avatar breard-r avatar deedasmi avatar dependabot-preview[bot] avatar lamafab avatar omegajak avatar robjtede avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

libreauth's Issues

Upgrade base64 for security

Hi,

It seems this library uses a version of the library base64 which is vulnerable to security issues. Please refer to https://github.com/RustSec/advisory-db/blob/master/Advisories.toml#L53 .

patch commit : marshallpierce/rust-base64@24ead98
patched version : [">= 0.5.2"]
used version : base64 = "^0.4.1"

This is done using crates.io data. Feel free to close this issue if it's not relevant or fixed.

Please consider adding cargo-audit to the CI to get notified in the future.

Thanks

Thanks

Best practices regarding password authentication for a Web service

Hi. I'd like to ask some advice regarding the best way to use this library to implement password authentication for a Web service. I understand this might be out of scope of the project so please forgive me if I'm asking too much.

I'm using HTTPS to connect to server. My client is in Rust compiled to WASM, server is in Rust. There are several questions:

  1. I've read that applying salt to hashed password is a good practice. How do I obtain this salt so that it would make sense
    from cryptography point of view? Doesn't look like I can pick any string of any length. Also, does it need to change? Should it be per user or per request? Should I apply it before or after hashing (since library has both)?
  2. Do I transmit the password in plain text over HTTPS and hash it on the server? I've read conflicting arguments on this. I believe this is the correct way to hash password and store it in the database because otherwise I'm trusting client's code and the password hash itself becomes visible on the wire for any MITM attacker (hence becoming the password).
  3. Example of doing password authentication has a case for password schema update. It says we should hash it again. Since we're not storing the original password, we should be doing a password reset procedure for the user, so that they can enter their old and new passwords, and we could hash new one and update the schema. Is that correct?

Password authentication status

Hi!

The README says that password authentication is not ready yet.

I've read the code and it seems to me that all the necessary features are implemented and the API is pretty clear.

Is there anything that should be done before password authentication can be considered ready/complete ?

Rust error API unnecessarily degraded to match C interface

The current Rust return type for most methods in this crate looks something like Result<_, ErrorCode>. The ErrorCode enum includes types of errors that, as far as I can tell, are not possible when using this crate from Rust (ErrorCode::Sucess, ErrorCode::NullPtr, etc). This means that, when using this crate purely from Rust, to satisfy the Rust compiler, you must either resort to unwrap()/expect() or, if you pattern match the returned Result, you must match against error codes that are not possible.

Additionally, it would be nice if the returned errors gave relevant information - for example, for PasswordTooShort, return the actual length and the minimum length.

It looks to me like this was done primarily to support the usage of this crate through the C bindings -- this allows the exact same type to be returned from the Rust interface as it is from the C interface. However, we lose some of Rust's power in doing so. What I would love to see instead is a more idiomatic Rust error interface, which is mapped to the broader C error code interface inside the C bindings.

I'll be taking a stab at this for the pass module. This will mean a breaking API change, which I think is worth it in this case, but I'll understand if you don't think so.

Thanks for the great crate!

Fail to Compile on Windows 10 (Visual Studio 2017)

Actually I use this Crate within SSO Crate: (https://github.com/mojzu/sso)
When compiling, an error message appears as below.

...
" "opengl32.lib" "pdh.lib" "psapi.lib" "secur32.lib" "synchronization.lib" "user32.lib" "winspool.lib" "ws2_32.lib" "advapi32.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "msvcrt.lib" "/DLL" "/IMPLIB:C:\\Users\\Altair\\RustLang\\sso\\sso\\target\\debug\\deps\\libreauth-31d786d1841dfabd.dll.lib"
  = note: lib.def : error LNK2001: unresolved external symbol _ZN101_$LT$core..ops..range..RangeTo$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$5index17h7d997d5ad475efa6E
          lib.def : error LNK2001: unresolved external symbol _ZN101_$LT$core..ops..range..RangeTo$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$9index_mut17hfcd3004d59b55041E
          lib.def : error LNK2001: unresolved external symbol _ZN4core10intrinsics23is_aligned_and_not_null17h004f31e9d3749227E
          lib.def : error LNK2001: unresolved external symbol _ZN4core3mem8align_of17h76a8694b42f8ab7bE
          lib.def : error LNK2001: unresolved external symbol _ZN4core3ptr20slice_from_raw_parts17h5eb3363f98bacd21E
          lib.def : error LNK2001: unresolved external symbol _ZN4core3ptr24slice_from_raw_parts_mut17h0d81b01af03b334aE          lib.def : error LNK2001: unresolved external symbol _ZN4core3ptr31_$LT$impl$u20$$BP$mut$u20$T$GT$6offset17h2be3b22172cbf407E
          lib.def : error LNK2001: unresolved external symbol _ZN4core3ptr31_$LT$impl$u20$$BP$mut$u20$T$GT$7is_null17h5d256813897e7b1fE
          lib.def : error LNK2001: unresolved external symbol _ZN4core5slice14from_raw_parts17h7eda3e6aa83543c9E
          lib.def : error LNK2001: unresolved external symbol _ZN4core5slice18from_raw_parts_mut17h24ee7f49401cd13bE
          lib.def : error LNK2001: unresolved external symbol _ZN4core5slice29_$LT$impl$u20$$u5b$T$u5d$$GT$10as_mut_ptr17h585545c221974ffdE
          lib.def : error LNK2001: unresolved external symbol _ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h9eb3c88cffc0b562E
          lib.def : error LNK2001: unresolved external symbol _ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17h5105de3abfcbdcf6E
          lib.def : error LNK2001: unresolved external symbol _ZN55_$LT$$RF$T$u20$as$u20$core..convert..AsRef$LT$U$GT$$GT$6as_ref17hca492517a62ed7bdE
          lib.def : error LNK2001: unresolved external symbol _ZN63_$LT$I$u20$as$u20$core..iter..traits..collect..IntoIterator$GT$9into_iter17h47b87f9cd88a80edE
          lib.def : error LNK2001: unresolved external symbol _ZN63_$LT$I$u20$as$u20$core..iter..traits..collect..IntoIterator$GT$9into_iter17h67ee80a0073fb05eE
          lib.def : error LNK2001: unresolved external symbol _ZN85_$LT$core..slice..Iter$LT$T$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17h236d91582e3fea51E
          lib.def : error LNK2001: unresolved external symbol _ZN88_$LT$core..slice..IterMut$LT$T$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17h8e0ae1d9ba60fce8E
          lib.def : error LNK2001: unresolved external symbol _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$13get_unchecked17he3dc0bafa3708c12E
          lib.def : error LNK2001: unresolved external symbol _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$17get_unchecked_mut17hc008b1af8b00e9c3E
          lib.def : error LNK2001: unresolved external symbol _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$5index17h20d37ee486013a67E
          lib.def : error LNK2001: unresolved external symbol _ZN99_$LT$core..ops..range..Range$LT$usize$GT$$u20$as$u20$core..slice..SliceIndex$LT$$u5b$T$u5d$$GT$$GT$9index_mut17h46dd287dd867c731E
          C:\Users\Afrizal Yusren\RustLang\sso\sso\target\debug\deps\libreauth-31d786d1841dfabd.dll.lib : fatal error LNK1120: 22 unresolved externals


error: aborting due to previous error

error: Could not compile `libreauth`.
warning: build failed, waiting for other jobs to finish...

Is there a special library for Windows that I need to include?
thank you for your attention.

[Question] Design goals

I been reading the source code and I am hoping you will correct my current understanding of what this crate does.

My understanding is that this crate only has 3 areas of functionality

  • Generate and verify TOTP codes from a key passed in
  • Generate and verify HOTP codes from a a key passed in
  • Generate PHC format from password and salt and verify password against PHC string?

Additionally each of these areas have excellent user facing documentation, C library bindings, and thorough tests which are very nice. The API is simple and easy to use.

The password verification functionality is what I am most interested in because I do not understand what is going on inside pass::is_valid(password: &str, reference: &str) -> bool. I think reference is the PHC format password hash information string. First the PHC string is inspected to choose the right hash function (with same salt and workfactor). Once the hash function "closure" is set up, hash the user provided password. Next is where I get lost. A random 32 byte key is generated and used to sign and HMAC value for both the reference PHC string and the PHC string generated from the user password. The password is verified only if the HMAC values match.

To me there is real value with parsing and serializing the PHC format. I like that API boundary decision because it lets me use a single DB column value. What I do not understand is why not use the crypto library's pbkdf2::verify implementation instead of this double HMAC result checking scheme?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.