Unlock tergent keystore with termux-fingerprint
This commit is contained in:
parent
b373b3dfff
commit
9d88b391a1
@ -0,0 +1,106 @@
|
||||
From 87ab008deb2bd7701da6e91f3998e51e68ec2bcf Mon Sep 17 00:00:00 2001
|
||||
From: Daniil Gentili <daniil@daniil.it>
|
||||
Date: Wed, 30 Sep 2020 18:21:05 +0200
|
||||
Subject: [PATCH 1/2] Automatically unlock keystore using fingerprint, if
|
||||
possible
|
||||
|
||||
---
|
||||
src/bridge/mod.rs | 51 ++++++++++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 44 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/bridge/mod.rs b/src/bridge/mod.rs
|
||||
index 4b00164..9e6a8bc 100644
|
||||
--- a/src/bridge/mod.rs
|
||||
+++ b/src/bridge/mod.rs
|
||||
@@ -7,12 +7,15 @@ use std::error::Error;
|
||||
use std::io::{Read, Write};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
+use serde_json;
|
||||
+use serde_json::{Value};
|
||||
+
|
||||
use base64;
|
||||
|
||||
/// Send a request to `termux-api` to list all the keys.
|
||||
/// Returns a string that contains a JSON object.
|
||||
pub fn list_keys() -> Result<String, Box<dyn Error>> {
|
||||
- Ok(communicate(&["list", "--ez", "detailed", "true"], &[0; 0])?)
|
||||
+ Ok(communicate(&"Keystore", &["-e", "command", "list", "--ez", "detailed", "true"], &[0; 0])?)
|
||||
}
|
||||
|
||||
/// Send some data to `termux-api` to be signed.
|
||||
@@ -23,16 +26,48 @@ pub fn list_keys() -> Result<String, Box<dyn Error>> {
|
||||
///
|
||||
/// [Signature algorithms]:
|
||||
/// https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature
|
||||
+fn sign_internal(alias: &str, algorithm: &str, data: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
+ let args = [
|
||||
+ "-e", "command", "sign",
|
||||
+ "-e", "alias", alias,
|
||||
+ "-e", "algorithm", algorithm
|
||||
+ ];
|
||||
+ let output = communicate(&"Keystore", &args, data)?;
|
||||
+ let res = base64::decode(output)?;
|
||||
+ if res.len() == 0 {
|
||||
+ return Err("Could not sign!".into())
|
||||
+ }
|
||||
+ Ok(res)
|
||||
+}
|
||||
+
|
||||
+pub fn unlock() -> Result<(), Box<dyn Error>> {
|
||||
+ let args = [
|
||||
+ "--es", "title", "Tergent",
|
||||
+ "--es", "description", "Use your fingerprint to unlock the keystore",
|
||||
+ ];
|
||||
+ let json = communicate(&"Fingerprint", &args, &[0; 0])?;
|
||||
+ let decoded: Value = serde_json::from_str::<serde_json::Value>(&json)?;
|
||||
+ let res = decoded["auth_result"].as_str().ok_or("Invalid result")?;
|
||||
+ if res == "AUTH_RESULT_FAILURE" {
|
||||
+ return Err("Fingerprint authentication failed".into())
|
||||
+ }
|
||||
+ Ok(())
|
||||
+}
|
||||
+
|
||||
pub fn sign(alias: &str, algorithm: &str, data: &[u8]) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
- let args = ["sign", "-e", "alias", alias, "-e", "algorithm", algorithm];
|
||||
- let output = communicate(&args, data)?;
|
||||
- return Ok(base64::decode(output)?);
|
||||
+ match sign_internal(&alias, &algorithm, &data) {
|
||||
+ Ok(res) => Ok(res),
|
||||
+ Err(_) => match unlock() {
|
||||
+ Ok(_) => Ok(sign_internal(&alias, &algorithm, &data)?),
|
||||
+ Err(e) => Err(e)
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/// Performs a generic call to `termux-api`, providing `args` to its receiver.
|
||||
/// Sets up proper sockets so that the `input` is provided to `termux-api` and
|
||||
/// its output is returned from this function.
|
||||
-fn communicate(args: &[&str], input: &[u8]) -> Result<String, Box<dyn Error>> {
|
||||
+fn communicate(method: &str, args: &[&str], input: &[u8]) -> Result<String, Box<dyn Error>> {
|
||||
let mut input_socket = socket::Socket::new()?;
|
||||
let mut output_socket = socket::Socket::new()?;
|
||||
|
||||
@@ -43,7 +78,7 @@ fn communicate(args: &[&str], input: &[u8]) -> Result<String, Box<dyn Error>> {
|
||||
.args(&["-n", "com.termux.api/.TermuxApiReceiver"])
|
||||
.args(&["--es", "socket_input", &output_socket.address()])
|
||||
.args(&["--es", "socket_output", &input_socket.address()])
|
||||
- .args(&["--es", "api_method", "Keystore", "-e", "command"])
|
||||
+ .args(&["--es", "api_method", method])
|
||||
.args(args)
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
@@ -65,6 +100,8 @@ fn communicate(args: &[&str], input: &[u8]) -> Result<String, Box<dyn Error>> {
|
||||
input_socket.close()?;
|
||||
|
||||
// We need to reap our children otherwise they will stay as zombies.
|
||||
- command.wait()?;
|
||||
+ // Ignore result, since this may error if the process has already closed
|
||||
+ command.wait();
|
||||
+
|
||||
Ok(output)
|
||||
}
|
||||
--
|
||||
2.30.1
|
||||
|
@ -3,7 +3,7 @@ TERMUX_PKG_DESCRIPTION="A cryptoki/PKCS#11 library for Termux that uses Android
|
||||
TERMUX_PKG_LICENSE="GPL-3.0"
|
||||
TERMUX_PKG_MAINTAINER="@termux"
|
||||
TERMUX_PKG_VERSION=1.0.0
|
||||
TERMUX_PKG_REVISION=2
|
||||
TERMUX_PKG_REVISION=3
|
||||
TERMUX_PKG_SRCURL=https://github.com/aeolwyr/tergent/archive/${TERMUX_PKG_VERSION}.tar.gz
|
||||
TERMUX_PKG_SHA256=0b59cf0ced3f693fb19396a986326963f3763e6bf65d3e56af0a03d206d69428
|
||||
TERMUX_PKG_DEPENDS="termux-api"
|
||||
|
Loading…
Reference in New Issue
Block a user