summaryrefslogtreecommitdiff
path: root/secrets/get-local.sh
blob: 719a914f7d343de0ee7f6fa16e2f7e4e7ba9c813 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/bin/bash

set -euo pipefail

if [[ "$#" -gt 0 && ("$1" == "-h" || "$1" == "--help") ]]; then
    cat <<EOF
get-local: Retrieve and decrypt a secret from a localized store

Decrypts and outputs a secret value from a localized store. The store name
is read from the .szecret metadata file in the file's directory.

Usage:
  get-local <file-path>
  get-local -h|--help

Arguments:
  file-path    Path to the encrypted file to decrypt

The command will:
1. Read the store name from <directory>/.szecret
2. Retrieve the local store's private key from global store
3. Check if the encrypted file exists and is readable
4. Decrypt the file using age with the local store's private key
5. Output the decrypted content to stdout

Legacy usage (deprecated):
  get-local <local-store-name> <file-path>

Note: Exits with error if file doesn't exist or decryption fails.
EOF
    exit 0
fi

this_dir="$(cd "$(dirname "$0")" && pwd)"
source "${this_dir}/common.sh"

if [[ "$#" -lt 1 ]]; then
    >&2 echo "ERROR: Need file path"
    exit 1
fi

# Determine if using legacy or new syntax
if [[ "$#" -ge 2 ]]; then
    # Legacy syntax: get-local <store-name> <file-path>
    local_store_name="$1"
    file_path="$2"
    target_dir="$(dirname "${file_path}")"
    metadata_file="${target_dir}/.szecret"

    >&2 echo "WARN: Using deprecated syntax. Use: szecret get-local ${file_path}"
    if [[ ! -r "${metadata_file}" ]]; then
        >&2 echo "  To migrate, run: szecret create-local ${local_store_name} ${target_dir}"
    fi

    ensure_local_store "${local_store_name}"
    ensure_age
    # No pubkey verification for legacy syntax
else
    # New syntax: get-local <file-path>
    file_path="$1"
    target_dir="$(dirname "${file_path}")"
    metadata_file="${target_dir}/.szecret"

    if ! read_local_metadata "${metadata_file}"; then
        >&2 echo "ERROR: No .szecret metadata in ${target_dir}"
        >&2 echo "Run 'szecret create-local <store-name> ${target_dir}' first"
        exit 1
    fi

    local_store_name="${_metadata_store}"
    expected_pubkey="${_metadata_pubkey}"

    ensure_local_store "${local_store_name}"
    ensure_age

    # Verify pubkey matches
    actual_pubkey="$(get_local_public_key "${local_store_name}")"
    verify_local_pubkey "${expected_pubkey}" "${actual_pubkey}" "${local_store_name}"
fi

# Check if the encrypted file exists
if ! [[ -r "${file_path}" ]]; then
    >&2 echo "ERROR: File '${file_path}' not found or not readable"
    exit 1
fi

# Get the local private key from the global store
local_private_key="$(get_local_private_key "${local_store_name}")"

# Create a temporary file for the private key
temp_private_key="$(mktemp)"
trap 'rm -f "${temp_private_key}"' EXIT
echo "${local_private_key}" > "${temp_private_key}"

# Decrypt the file using the local private key
age_decrypt "${temp_private_key}" "${file_path}"