Add age plugin support

See https://github.com/str4d/rage/tree/main/age-plugin.

Example usage:

	RAGE_DIR=$PWD/../Rust/rage
	(cd $RAGE_DIR; cargo build --all)
	export PATH=$PATH:$RAGE_DIR/target/debug

	age-plugin-trezor -i "John Doe" | tee trezor.id
	R=$(grep recipient trezor.id | cut -f 3 -d ' ')

	date | tee msg.txt
	rage -er $R < msg.txt > enc.txt
	rage -di trezor.id < enc.txt
This commit is contained in:
Roman Zeyde
2020-12-16 20:33:50 +02:00
parent 2a6a47f400
commit f0769655ad
9 changed files with 242 additions and 7 deletions

48
libagent/age/client.py Normal file
View File

@@ -0,0 +1,48 @@
"""Device abstraction layer for AGE operations."""
import logging
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from ..device import interface
log = logging.getLogger(__name__)
def create_identity(user_id):
"""Create AGE identity for hardware device."""
result = interface.Identity(identity_str='age://', curve_name="ed25519")
result.identity_dict['host'] = user_id
return result
class Client:
"""Sign messages and get public keys from a hardware device."""
def __init__(self, device):
"""C-tor."""
self.device = device
def pubkey(self, identity, ecdh=False):
"""Return public key as VerifyingKey object."""
with self.device:
pubkey = bytes(self.device.pubkey(ecdh=ecdh, identity=identity))
assert len(pubkey) == 32
return pubkey
def ecdh(self, identity, peer_pubkey):
"""Derive shared secret using ECDH from peer public key."""
log.info('please confirm AGE decryption on %s for "%s"...',
self.device, identity.to_string())
with self.device:
assert len(peer_pubkey) == 32
result, self_pubkey = self.device.ecdh_with_pubkey(
pubkey=(b"\x40" + peer_pubkey), identity=identity)
assert result[:1] == b"\x04"
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=32,
salt=((peer_pubkey + self_pubkey)),
info=b"age-encryption.org/v1/X25519")
return hkdf.derive(result[1:])