This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / tools / age-detect / age-detect
4.0 kB 110 lines
1#!/usr/bin/env bash 2set -euo pipefail 3 4# age-detect: Detects connected age-compatible security keys 5# Returns identity file path and detected key information 6 7# Function to detect connected security keys and their age identities 8detect_age_keys() { 9 local temp_identities 10 temp_identities=$(mktemp) 11 12 # Check for Secure Enclave on macOS (highest priority) 13 if [[ "$(uname)" == "Darwin" ]] && command -v age-plugin-se >/dev/null 2>&1; then 14 rm -f "$temp_identities" 15 echo "DETECTED_KEY=se" 16 echo "KEY_TYPE=se" 17 return 18 fi 19 20 # Check for TPM on Linux (second priority - built-in, no USB needed) 21 # Requires: TPM device, hostname.age with age1tpm1/age1tag1 recipient, and identity in ~/.config/age/ 22 # Newer age-plugin-tpm emits native p256tag (age1tag1) recipients by default. 23 if [[ -c /dev/tpmrm0 ]] && [[ -f ~/.config/age/tpm-identity.txt ]]; then 24 local hostname_key 25 hostname_key="${AGE_DETECT_KEYS_DIR:-}/age/$(hostname).age" 26 if [[ -f "$hostname_key" ]] && grep -qE "^age1(tpm|tag)1" "$hostname_key" 2>/dev/null; then 27 rm -f "$temp_identities" 28 echo "DETECTED_KEY=tpm" 29 echo "KEY_TYPE=tpm" 30 return 31 fi 32 fi 33 34 # Check for gpg-agent with an encryption subkey (third priority). 35 # Frictionless after the first decrypt because gpg-agent caches the 36 # passphrase / smartcard PIN, so we prefer it over yubikey/solo2. 37 if command -v gpg-connect-agent >/dev/null 2>&1 \ 38 && gpg-connect-agent /bye >/dev/null 2>&1 \ 39 && gpg --list-secret-keys --with-colons 2>/dev/null \ 40 | awk -F: '$1 == "ssb" && $12 ~ /e/ { found=1 } END { exit !found }'; then 41 echo "AGE-PLUGIN-GPG-1H40XPM" > "$temp_identities" 42 echo "IDENTITY_FILE=$temp_identities" 43 echo "DETECTED_KEY=gpg" 44 echo "KEY_TYPE=gpg" 45 return 46 fi 47 48 # Check for YubiKeys (fourth priority) 49 if command -v ykman >/dev/null 2>&1; then 50 local yubikey_serial 51 yubikey_serial=$(ykman info 2>/dev/null | grep "Serial number:" | cut -d: -f2 | tr -d ' ' || true) 52 if [[ -n "$yubikey_serial" ]]; then 53 echo "AGE-PLUGIN-YUBIKEY-1M2PLUQYZ242EPUSSHDFWJ" > "$temp_identities" 54 echo "IDENTITY_FILE=$temp_identities" 55 case "$yubikey_serial" in 56 "16679898") 57 echo "DETECTED_KEY=yubi1" 58 ;; 59 "11342136") 60 echo "DETECTED_KEY=yubi2" 61 ;; 62 *) 63 echo "DETECTED_KEY=yubikey-${yubikey_serial}" 64 ;; 65 esac 66 echo "KEY_TYPE=yubikey" 67 return 68 fi 69 fi 70 71 # Check for Solo2 (lowest priority) 72 if command -v fido2-token >/dev/null 2>&1; then 73 if fido2-token -L 2>/dev/null | grep -q "Solo 2"; then 74 # FIDO2-HMAC doesn't use identity file 75 rm -f "$temp_identities" 76 echo "IDENTITY_FILE=" 77 echo "DETECTED_KEY=solo2" 78 echo "KEY_TYPE=solo2" 79 return 80 fi 81 fi 82 83 # No keys detected 84 rm -f "$temp_identities" 85 echo "IDENTITY_FILE=" 86 echo "DETECTED_KEY=" 87 echo "KEY_TYPE=" 88} 89 90# Parse command line arguments 91case "${1:-detect}" in 92 detect) 93 detect_age_keys 94 ;; 95 --help|-h) 96 echo "Usage: age-detect [detect]" 97 echo "" 98 echo "Detects the first available age-compatible security key and outputs:" 99 echo " IDENTITY_FILE=<path> - Path to temporary identity file for age (empty for Solo2)" 100 echo " DETECTED_KEY=<name> - Name of the detected key (e.g., yubi1, solo2, se)" 101 echo " KEY_TYPE=<type> - Type of key (yubikey, solo2, se)" 102 echo "" 103 echo "Priority order: se > tpm > gpg > yubikey > solo2" 104 ;; 105 *) 106 echo "Unknown command: $1" >&2 107 echo "Use --help for usage information" >&2 108 exit 1 109 ;; 110esac