Present desktop OTP and sensitive outputs
This commit is contained in:
@@ -198,6 +198,9 @@ impl NativeClipboardManager {
|
||||
pub enum QrError {
|
||||
EmptyPayload,
|
||||
PayloadTooLarge,
|
||||
InvalidImage,
|
||||
NotFound,
|
||||
InvalidPayload,
|
||||
}
|
||||
|
||||
impl fmt::Display for QrError {
|
||||
@@ -205,6 +208,9 @@ impl fmt::Display for QrError {
|
||||
match self {
|
||||
Self::EmptyPayload => formatter.write_str("empty data cannot be encoded as a QR code"),
|
||||
Self::PayloadTooLarge => formatter.write_str("the QR payload is too large"),
|
||||
Self::InvalidImage => formatter.write_str("the selected file is not a supported image"),
|
||||
Self::NotFound => formatter.write_str("the image does not contain a QR code"),
|
||||
Self::InvalidPayload => formatter.write_str("the QR code contains invalid text"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,6 +239,26 @@ impl QrMatrix {
|
||||
Ok(Self { width, modules })
|
||||
}
|
||||
|
||||
/// Decode the first QR symbol from an encoded image without exposing the
|
||||
/// secret-derived payload to a presentation adapter.
|
||||
pub fn decode_image(image: &SecretBytes) -> Result<SecretBytes, QrError> {
|
||||
let grayscale = image::load_from_memory(image.expose())
|
||||
.map_err(|_| QrError::InvalidImage)?
|
||||
.into_luma8();
|
||||
let mut prepared = rqrr::PreparedImage::prepare_from_greyscale(
|
||||
grayscale.width() as usize,
|
||||
grayscale.height() as usize,
|
||||
|x, y| grayscale.get_pixel(x as u32, y as u32).0[0],
|
||||
);
|
||||
let grid = prepared
|
||||
.detect_grids()
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or(QrError::NotFound)?;
|
||||
let (_, payload) = grid.decode().map_err(|_| QrError::InvalidPayload)?;
|
||||
Ok(SecretBytes::new(payload.into_bytes()))
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user