Elaborate "PW status bytes", fix broken naming of members.
Implement set_pw_status_bytes(). Add test code to card-functionality.
This commit is contained in:
parent
c14664b9d5
commit
cb8f3c7cb1
6 changed files with 107 additions and 10 deletions
|
@ -36,9 +36,13 @@ fn main() -> Result<()> {
|
|||
//
|
||||
// panic!();
|
||||
|
||||
print!("Verify");
|
||||
let verify_out = run_test(&mut card, test_verify, &[])?;
|
||||
println!(" {:x?}", verify_out);
|
||||
// print!("Verify");
|
||||
// let verify_out = run_test(&mut card, test_verify, &[])?;
|
||||
// println!(" {:x?}", verify_out);
|
||||
|
||||
print!("PW Status bytes");
|
||||
let pw_out = run_test(&mut card, test_pw_status, &[])?;
|
||||
println!(" {:x?}", pw_out);
|
||||
|
||||
println!();
|
||||
}
|
||||
|
|
|
@ -352,6 +352,31 @@ pub fn test_set_user_data(
|
|||
Ok(vec![])
|
||||
}
|
||||
|
||||
pub fn test_pw_status(
|
||||
ca: &mut CardApp,
|
||||
_param: &[&str],
|
||||
) -> Result<TestOutput, TestError> {
|
||||
let mut out = vec![];
|
||||
|
||||
let ard = ca.get_app_data()?;
|
||||
let mut pws = ard.get_pw_status_bytes()?;
|
||||
|
||||
println!("pws {:?}", pws);
|
||||
|
||||
ca.verify_pw3("12345678")?;
|
||||
|
||||
pws.set_pw1_cds_multi(true);
|
||||
pws.set_pw1_pin_block(true);
|
||||
|
||||
ca.set_pw_status_bytes(&pws, false)?;
|
||||
|
||||
let ard = ca.get_app_data()?;
|
||||
let pws = ard.get_pw_status_bytes()?;
|
||||
println!("pws {:?}", pws);
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
/// Outputs:
|
||||
/// - verify pw3 (check) -> Status
|
||||
/// - verify pw1 (check) -> Status
|
||||
|
|
|
@ -118,6 +118,11 @@ pub(crate) fn put_url(url: Vec<u8>) -> Command {
|
|||
put_data(&[0x5f, 0x50], url)
|
||||
}
|
||||
|
||||
/// PUT DO "PW status bytes"
|
||||
pub(crate) fn put_pw_status(data: Vec<u8>) -> Command {
|
||||
put_data(&[0xc4], data)
|
||||
}
|
||||
|
||||
/// Change PW1 (user pin).
|
||||
/// This can be used to reset the counter and set a pin.
|
||||
pub(crate) fn change_pw1(pin: Vec<u8>) -> Command {
|
||||
|
|
|
@ -11,7 +11,7 @@ use anyhow::{anyhow, Result};
|
|||
use crate::algorithm::{Algo, AlgoInfo, AlgoSimple, RsaAttrs};
|
||||
use crate::apdu::{commands, response::Response};
|
||||
use crate::card_do::{
|
||||
ApplicationRelatedData, Cardholder, SecuritySupportTemplate, Sex,
|
||||
ApplicationRelatedData, Cardholder, PWStatus, SecuritySupportTemplate, Sex,
|
||||
};
|
||||
use crate::crypto_data::{
|
||||
CardUploadableKey, Cryptogram, EccType, Hash, PublicKeyMaterial,
|
||||
|
@ -450,6 +450,28 @@ impl CardApp {
|
|||
apdu::send_command(self.card(), fp_cmd, false)?.try_into()
|
||||
}
|
||||
|
||||
/// Set PW Status Bytes.
|
||||
///
|
||||
/// If `long` is false, send 1 byte to the card, otherwise 4.
|
||||
/// According to the spec, length information should not be changed.
|
||||
///
|
||||
/// So, effectively, with 'long == false' the setting `pw1_cds_multi`
|
||||
/// can be changed.
|
||||
/// With 'long == true', the settings `pw1_pin_block` and `pw3_pin_block`
|
||||
/// can also be changed.
|
||||
///
|
||||
/// (See OpenPGP card spec, pg. 28)
|
||||
pub fn set_pw_status_bytes(
|
||||
&mut self,
|
||||
pw_status: &PWStatus,
|
||||
long: bool,
|
||||
) -> Result<Response, OpenpgpCardError> {
|
||||
let data = pw_status.serialize_for_put(long);
|
||||
|
||||
let cmd = commands::put_pw_status(data);
|
||||
apdu::send_command(self.card(), cmd, false)?.try_into()
|
||||
}
|
||||
|
||||
/// Set algorithm attributes [4.4.3.9 Algorithm Attributes]
|
||||
pub fn set_algorithm_attributes(
|
||||
&mut self,
|
||||
|
|
|
@ -319,16 +319,28 @@ impl From<u8> for Sex {
|
|||
#[derive(Debug)]
|
||||
pub struct PWStatus {
|
||||
pub(crate) pw1_cds_multi: bool,
|
||||
pub(crate) pw1_derived: bool,
|
||||
pub(crate) pw1_pin_block: bool,
|
||||
pub(crate) pw1_len: u8,
|
||||
pub(crate) rc_len: u8,
|
||||
pub(crate) pw3_derived: bool,
|
||||
pub(crate) pw3_pin_block: bool,
|
||||
pub(crate) pw3_len: u8,
|
||||
pub(crate) err_count_pw1: u8,
|
||||
pub(crate) err_count_rst: u8,
|
||||
pub(crate) err_count_pw3: u8,
|
||||
}
|
||||
|
||||
impl PWStatus {
|
||||
pub fn set_pw1_cds_multi(&mut self, val: bool) {
|
||||
self.pw1_cds_multi = val;
|
||||
}
|
||||
pub fn set_pw1_pin_block(&mut self, val: bool) {
|
||||
self.pw1_pin_block = val;
|
||||
}
|
||||
pub fn set_pw3_pin_block(&mut self, val: bool) {
|
||||
self.pw3_pin_block = val;
|
||||
}
|
||||
}
|
||||
|
||||
/// Fingerprint
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct Fingerprint([u8; 20]);
|
||||
|
|
|
@ -10,10 +10,10 @@ impl PWStatus {
|
|||
pub fn try_from(input: &[u8]) -> Result<Self, OpenpgpCardError> {
|
||||
if input.len() == 7 {
|
||||
let pw1_cds_multi = input[0] == 0x01;
|
||||
let pw1_derived = input[1] & 0x80 != 0;
|
||||
let pw1_pin_block = input[1] & 0x80 != 0;
|
||||
let pw1_len = input[1] & 0x7f;
|
||||
let rc_len = input[2];
|
||||
let pw3_derived = input[3] & 0x80 != 0;
|
||||
let pw3_pin_block = input[3] & 0x80 != 0;
|
||||
let pw3_len = input[3] & 0x7f;
|
||||
let err_count_pw1 = input[4];
|
||||
let err_count_rst = input[5];
|
||||
|
@ -21,10 +21,10 @@ impl PWStatus {
|
|||
|
||||
Ok(Self {
|
||||
pw1_cds_multi,
|
||||
pw1_derived,
|
||||
pw1_pin_block,
|
||||
pw1_len,
|
||||
rc_len,
|
||||
pw3_derived,
|
||||
pw3_pin_block,
|
||||
pw3_len,
|
||||
err_count_pw1,
|
||||
err_count_rst,
|
||||
|
@ -37,4 +37,33 @@ impl PWStatus {
|
|||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// PUT DO for PW Status Bytes accepts either 1 or 4 bytes of data.
|
||||
/// This method generates the 1 byte version for 'long==false' and the
|
||||
/// 4 bytes version for 'long==true'.
|
||||
///
|
||||
/// (See OpenPGP card spec, pg. 28)
|
||||
pub fn serialize_for_put(&self, long: bool) -> Vec<u8> {
|
||||
let mut data = vec![];
|
||||
|
||||
data.push(if !self.pw1_cds_multi { 0 } else { 1 });
|
||||
|
||||
if long {
|
||||
let mut b2 = self.pw1_len;
|
||||
if self.pw1_pin_block {
|
||||
b2 |= 0x80;
|
||||
}
|
||||
data.push(b2);
|
||||
|
||||
data.push(self.rc_len);
|
||||
|
||||
let mut b4 = self.pw3_len;
|
||||
if self.pw3_pin_block {
|
||||
b4 |= 0x80;
|
||||
}
|
||||
data.push(b4);
|
||||
}
|
||||
|
||||
data
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue