Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
b2506fd950
|
|||
8811cff6d1
|
|||
99787b614c
|
|||
ee28f87148
|
|||
196356fe3b
|
|||
3ff7e698bd
|
|||
04d0d60fb3
|
|||
e64f777c54
|
|||
8465949b44
|
|||
![]() |
06bed03e7b | ||
![]() |
36f82e7c3a |
20
.drone.yml
20
.drone.yml
@@ -8,21 +8,21 @@ steps:
|
||||
- rustup component add rustfmt
|
||||
- cargo fmt --all -- --check
|
||||
- name: test
|
||||
image: rust:1.43.0
|
||||
commands:
|
||||
- apt update && apt install -y libkeyutils-dev libclang-dev clang pkg-config
|
||||
- echo 'deb http://http.us.debian.org/debian unstable main non-free contrib' >> /etc/apt/sources.list.d/unstable.list && apt update && apt install -y libcryptsetup-dev
|
||||
- cargo test
|
||||
|
||||
- name: publish
|
||||
image: rust:1.43.0
|
||||
image: ubuntu:focal
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
commands:
|
||||
- apt update && apt install -y cargo libkeyutils-dev libclang-dev clang pkg-config libcryptsetup-dev
|
||||
- cargo test --locked
|
||||
- name: publish
|
||||
image: ubuntu:focal
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
CARGO_REGISTRY_TOKEN:
|
||||
from_secret: cargo_tkn
|
||||
commands:
|
||||
- grep -E 'version ?= ?"${DRONE_TAG}"' -i Cargo.toml || (printf "incorrect crate/tag version" && exit 1)
|
||||
- apt update && apt install -y libkeyutils-dev libclang-dev clang pkg-config
|
||||
- echo 'deb http://http.us.debian.org/debian unstable main non-free contrib' >> /etc/apt/sources.list.d/unstable.list && apt update && apt install -y libcryptsetup-dev
|
||||
- apt update && apt install -y cargo libkeyutils-dev libclang-dev clang pkg-config libcryptsetup-dev
|
||||
- cargo package --all-features
|
||||
- cargo publish --all-features
|
||||
when:
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -377,7 +377,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fido2luks"
|
||||
version = "0.2.10"
|
||||
version = "0.2.12"
|
||||
dependencies = [
|
||||
"ctap_hmac",
|
||||
"failure",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "fido2luks"
|
||||
version = "0.2.10"
|
||||
version = "0.2.12"
|
||||
authors = ["shimunn <shimun@shimun.net>"]
|
||||
edition = "2018"
|
||||
|
||||
|
24
PKGBUILD
Normal file
24
PKGBUILD
Normal file
@@ -0,0 +1,24 @@
|
||||
# Maintainer: shimunn <shimun@shimun.net>
|
||||
pkgname=fido2luks
|
||||
pkgver=0.2.12
|
||||
pkgrel=1
|
||||
makedepends=('rust' 'cargo' 'cryptsetup' 'clang')
|
||||
depends=('cryptsetup')
|
||||
arch=('i686' 'x86_64' 'armv6h' 'armv7h')
|
||||
pkgdesc="Decrypt your LUKS partition using a FIDO2 compatible authenticator"
|
||||
url="https://github.com/shimunn/fido2luks"
|
||||
license=('MPL-2.0')
|
||||
|
||||
pkgver() {
|
||||
# Use tag version if possible otherwise concat project version and git ref
|
||||
git describe --exact-match --tags HEAD 2> /dev/null || \
|
||||
echo "$(cargo pkgid | cut -d':' -f3).$(git describe --always)"
|
||||
}
|
||||
|
||||
build() {
|
||||
cargo build --release --locked --all-features --target-dir=target
|
||||
}
|
||||
|
||||
package() {
|
||||
install -Dm 755 target/release/${pkgname} -t "${pkgdir}/usr/bin"
|
||||
}
|
11
README.md
11
README.md
@@ -1,6 +1,6 @@
|
||||
# fido2luks [](https://crates.io/crates/fido2luks)
|
||||
|
||||
This will allow you to unlock your luks encrypted disk with an fido2 compatible key
|
||||
This will allow you to unlock your LUKS encrypted disk with an FIDO2 compatible key.
|
||||
|
||||
Note: This has only been tested under Fedora 31, [Ubuntu 20.04](initramfs-tools/), [NixOS](https://nixos.org/nixos/manual/#sec-luks-file-systems-fido2) using a Solo Key, Trezor Model T
|
||||
|
||||
@@ -65,7 +65,7 @@ cp /usr/bin/fido2luks /boot/fido2luks/
|
||||
cp /etc/fido2luks.conf /boot/fido2luks/
|
||||
```
|
||||
|
||||
## Test
|
||||
## Testing
|
||||
|
||||
Just reboot and see if it works, if that's the case you should remove your old less secure password from your LUKS header:
|
||||
|
||||
@@ -96,6 +96,13 @@ set -a
|
||||
|
||||
Then add the new secret to each device and update dracut afterwards `dracut -f`
|
||||
|
||||
### Multiple keys
|
||||
|
||||
Additional/backup keys are supported, Multiple fido2luks credentials can be added to your /etc/fido2luks.conf file. Credential tokens are comma separated.
|
||||
```
|
||||
FIDO2LUKS_CREDENTIAL_ID=<CREDENTIAL1>,<CREDENTIAL2>,<CREDENTIAL3>
|
||||
```
|
||||
|
||||
## Removal
|
||||
|
||||
Remove `rd.luks.2fa` from `GRUB_CMDLINE_LINUX` in /etc/default/grub
|
||||
|
@@ -1,13 +1,34 @@
|
||||
## Initramfs-tools based systems(Ubuntu and derivatives)
|
||||
|
||||
After installation generate your credentials and add keys to your disk as described in the top-level README
|
||||
then add `initramfs,keyscript=fido2luks` to your `/etc/crypttab`
|
||||
For easiest installation [download and install the precompiled deb from releases.](https://github.com/shimunn/fido2luks/releases). However it is possible to build from source via the instructions on the main readme.
|
||||
|
||||
Example:
|
||||
```
|
||||
sda6_crypt UUID=9793d81a-4cfb-4712-85f3-c7a8d715112c none luks,discard,initramfs,keyscript=fido2luks
|
||||
```
|
||||
sudo -s
|
||||
|
||||
But don't forget to run `make install` which will install all necessary scripts and regenerate your intrid.
|
||||
# Insert FIDO key.
|
||||
fido2luks credential
|
||||
# Tap FIDO key
|
||||
# Copy returned string <CREDENTIAL>
|
||||
|
||||
nano /etc/fido2luks.conf
|
||||
# Insert <CREDENTIAL>
|
||||
# FIDO2LUKS_CREDENTIAL_ID=<CREDENTIAL>
|
||||
|
||||
set -a
|
||||
. /etc/fido2luks.conf
|
||||
fido2luks -i add-key /dev/<LUKS PARTITION>
|
||||
# Current password: <Any current LUKS password>
|
||||
# Password: <Password used as FIDO challange>
|
||||
# Tap FIDO key
|
||||
|
||||
nano /etc/crypttab
|
||||
# Append to end ",discard,initramfs,keyscript=fido2luks"
|
||||
# E.g. sda6_crypt UUID=XXXXXXXXXX none luks,discard,initramfs,keyscript=fido2luks
|
||||
|
||||
update-initramfs -u
|
||||
|
||||
|
||||
```
|
||||
|
||||
[Recording showing part of the setup](https://shimun.net/fido2luks/setup.svg)
|
||||
|
||||
|
@@ -1,3 +1,3 @@
|
||||
FIDO2LUKS_SALT=Ask
|
||||
#FIDO2LUKS_PASSWORD_HELPER="/usr/bin/plymouth ask-for-password --promt 'FIDO2 password salt'"
|
||||
#FIDO2LUKS_PASSWORD_HELPER="/usr/bin/plymouth ask-for-password --prompt 'FIDO2 password salt'"
|
||||
FIDO2LUKS_CREDENTIAL_ID=
|
||||
|
@@ -4,8 +4,7 @@ set -a
|
||||
|
||||
if [ -z "$FIDO2LUKS_PASSWORD_HELPER" ]; then
|
||||
MSG="FIDO2 password salt for $CRYPTTAB_NAME"
|
||||
export FIDO2LUKS_PASSWORD_HELPER="plymouth ask-for-password --promt '$MSG'"
|
||||
plymouth message --text "$MSG"
|
||||
export FIDO2LUKS_PASSWORD_HELPER="plymouth ask-for-password --prompt '$MSG'"
|
||||
fi
|
||||
|
||||
fido2luks print-secret --bin
|
||||
|
31
src/cli.rs
31
src/cli.rs
@@ -7,7 +7,7 @@ use ctap::{FidoCredential, FidoErrorKind};
|
||||
use failure::_core::fmt::{Display, Error, Formatter};
|
||||
use failure::_core::str::FromStr;
|
||||
use failure::_core::time::Duration;
|
||||
use std::io::Write;
|
||||
use std::io::{Read, Write};
|
||||
use std::process::exit;
|
||||
use std::thread;
|
||||
|
||||
@@ -15,6 +15,7 @@ use crate::luks::{Fido2LuksToken, LuksDevice};
|
||||
use crate::util::sha256;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::fs::File;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
@@ -77,6 +78,10 @@ pub struct AuthenticatorParameters {
|
||||
#[structopt(short = "P", long = "pin")]
|
||||
pub pin: bool,
|
||||
|
||||
/// Location to read PIN from
|
||||
#[structopt(long = "pin-source", env = "FIDO2LUKS_PIN_SOURCE")]
|
||||
pub pin_source: Option<PathBuf>,
|
||||
|
||||
/// Await for an authenticator to be connected, timeout after n seconds
|
||||
#[structopt(
|
||||
long = "await-dev",
|
||||
@@ -87,6 +92,18 @@ pub struct AuthenticatorParameters {
|
||||
pub await_time: u64,
|
||||
}
|
||||
|
||||
impl AuthenticatorParameters {
|
||||
fn read_pin(&self) -> Fido2LuksResult<String> {
|
||||
if let Some(src) = self.pin_source.as_ref() {
|
||||
let mut pin = String::new();
|
||||
File::open(src)?.read_to_string(&mut pin)?;
|
||||
Ok(pin)
|
||||
} else {
|
||||
util::read_password("Authenticator PIN", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct LuksParameters {
|
||||
#[structopt(env = "FIDO2LUKS_DEVICE")]
|
||||
@@ -165,10 +182,6 @@ fn derive_secret(
|
||||
Ok((sha256(&[salt, &unsalted[..]]), cred.clone()))
|
||||
}
|
||||
|
||||
fn read_pin() -> Fido2LuksResult<String> {
|
||||
util::read_password("Authenticator PIN", false)
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub struct Args {
|
||||
/// Request passwords via Stdin instead of using the password helper
|
||||
@@ -345,7 +358,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
} => {
|
||||
let pin_string;
|
||||
let pin = if authenticator.pin {
|
||||
pin_string = read_pin()?;
|
||||
pin_string = authenticator.read_pin()?;
|
||||
Some(pin_string.as_ref())
|
||||
} else {
|
||||
None
|
||||
@@ -362,7 +375,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
} => {
|
||||
let pin_string;
|
||||
let pin = if authenticator.pin {
|
||||
pin_string = read_pin()?;
|
||||
pin_string = authenticator.read_pin()?;
|
||||
Some(pin_string.as_ref())
|
||||
} else {
|
||||
None
|
||||
@@ -406,7 +419,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
..
|
||||
} => {
|
||||
let pin = if authenticator.pin {
|
||||
Some(read_pin()?)
|
||||
Some(authenticator.read_pin()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -522,7 +535,7 @@ pub fn run_cli() -> Fido2LuksResult<()> {
|
||||
} => {
|
||||
let pin_string;
|
||||
let pin = if authenticator.pin {
|
||||
pin_string = read_pin()?;
|
||||
pin_string = authenticator.read_pin()?;
|
||||
Some(pin_string.as_ref())
|
||||
} else {
|
||||
None
|
||||
|
@@ -135,10 +135,9 @@ impl PasswordHelper {
|
||||
Systemd => unimplemented!(),
|
||||
Stdin => Ok(util::read_password("Password", true)?),
|
||||
Script(password_helper) => {
|
||||
let mut helper_parts = password_helper.split(' ');
|
||||
|
||||
let password = Command::new((&mut helper_parts).next().unwrap())
|
||||
.args(helper_parts)
|
||||
let password = Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(&password_helper)
|
||||
.output()
|
||||
.map_err(|e| Fido2LuksError::AskPassError {
|
||||
cause: error::AskPassError::IO(e),
|
||||
|
@@ -21,10 +21,7 @@ mod util;
|
||||
fn main() -> Fido2LuksResult<()> {
|
||||
match run_cli() {
|
||||
Err(e) => {
|
||||
#[cfg(debug_assertions)]
|
||||
eprintln!("{:?}", e);
|
||||
#[cfg(not(debug_assertions))]
|
||||
eprintln!("{}", e);
|
||||
exit(e.exit_code())
|
||||
}
|
||||
_ => exit(0),
|
||||
|
Reference in New Issue
Block a user