bitwarden_pin/
cli.rs

1use clap::{Parser, Subcommand};
2
3#[derive(Parser)]
4#[command(name = "bitwarden-pin", subcommand_value_name = "KDF")]
5pub struct Args {
6    /// PIN-encrypted User Key
7    #[clap(short, long)]
8    pub encrypted: String,
9
10    /// Email address (salt)
11    #[clap(short = 'm', long)]
12    pub email: String,
13
14    /// Number of digits in the PIN
15    #[clap(short, long, default_value = "4")]
16    pub pin_length: usize,
17
18    /// Key Deriviation Function (KDF) configuration
19    #[command(subcommand)]
20    pub kdf_config: Option<KDFConfig>,
21}
22
23#[derive(Subcommand, Clone, Copy, Debug)]
24pub enum KDFConfig {
25    /// kdfType=0: Password Based Key Derivation Function 2 (default)
26    Pbkdf2 {
27        /// Number of pbkdf2 iterations
28        #[clap(short, long, default_value = "600000")]
29        iterations: u32,
30    },
31    /// kdfType=1: Argon2
32    Argon2 {
33        /// Memory cost, in MiB. Note: this changes the hash output!
34        #[clap(short, long, default_value = "64")]
35        memory: u32,
36        /// Time cost, number of argon2 iterations, time cost
37        #[clap(short, long, default_value = "3")]
38        iterations: u32,
39        /// Parallelism, number of argon2 threads. Note: this changes the hash output!
40        #[clap(short, long, default_value = "4")]
41        parallelism: u32,
42    },
43}
44
45impl Default for KDFConfig {
46    fn default() -> Self {
47        KDFConfig::Pbkdf2 { iterations: 600000 }
48    }
49}