Skip to content

Commit

Permalink
Initial version.
Browse files Browse the repository at this point in the history
  • Loading branch information
TimDumol committed Mar 18, 2019
0 parents commit 3225539
Show file tree
Hide file tree
Showing 14 changed files with 437 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
noirbox
======

Cloud-KMS based repo cryptography inspired by Stack Exchange's blackbox.

Installation
-------------

Just add ``bin/`` to your ``PATH``.

Documentation
-------------

Right now, just look at the usage comments for all the scripts in ``bin/``.

75 changes: 75 additions & 0 deletions bin/_noirbox-common
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
set -e -u -o pipefail

key_size=256

up_to_noirbox_root() {
until [[ -d .noirbox ]]; do
cd ..
if [[ "$(pwd)" = "/" ]]; then
echo "No .noirbox directory found. Maybe noirbox-init?"
exit 1
fi
done
}

read_config() {
noirbox_dir="$(realpath .noirbox)"
location="$(cat "$noirbox_dir/config.yaml" | yq -r .location)"
key="$(cat "$noirbox_dir/config.yaml" | yq -r .key)"
keyring="$(cat "$noirbox_dir/config.yaml" | yq -r .keyring)"
}

cat_file() {
file="$1"
local_key="$2"
# black magic to capture only stderr: https://unix.stackexchange.com/questions/474177/how-to-redirect-stderr-in-a-variable-but-keep-stdout-in-the-console
set +e
{ err="$(echo "$local_key" | gpg --cipher-algo AES256 --batch -d --passphrase-fd 0 "$file.gpg" 2>&1 >&3 3>&-)"; } 3>&1
retval=$?
set -e
if [[ $retval -ne 0 ]]; then
echo "$err"
exit $retval
fi
}

decrypt_file() {
file="$1"
local_key="$2"
cat_file "$file" "$local_key" > "$file"
}

encrypt_file() {
file="$1"
local_key="$2"
rm -f "$file.gpg"
echo "$local_key" | gpg --cipher-algo AES256 --batch -c --passphrase-fd 0 "$file"
}



verbose="no"
debug="no"

for arg in "${@}"; do
opt="$(echo "$arg" | cut -d= -f1)"
val="$(echo "$arg" | cut -d= -f2)"
case "$opt" in
"--verbose")
verbose="yes"
;;
"--debug")
debug="yes"
;;
esac
done

if [[ "$verbose" = "yes" ]]; then
set -v
fi

if [[ "$debug" = "yes" ]]; then
set -x
fi

23 changes: 23 additions & 0 deletions bin/noirbox-cat
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Output contents of an encrypted file
# Usage: noirbox-cat filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config

local_key="$(gcloud kms decrypt \
--location="$location" \
--keyring="$keyring" \
--key="$key" \
--plaintext-file=- \
--ciphertext-file="$noirbox_dir/local-key.enc")"

file="${1%.gpg}"

cat_file "$file" "$local_key"

25 changes: 25 additions & 0 deletions bin/noirbox-decrypt-all-files
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Decrypts all files, for pre-deployment use.
# Usage: noirbox-decrypt-all-files
# Warning: Be sure to ``noirbox-shred-all-files`` afterwards.

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config

local_key="$(gcloud kms decrypt \
--location="$location" \
--keyring="$keyring" \
--key="$key" \
--plaintext-file=- \
--ciphertext-file="$noirbox_dir/local-key.enc")"

while IFS="" read -r file
do
decrypt_file "$file" "$local_key"
done < "$noirbox_dir/noirbox-files.txt"

23 changes: 23 additions & 0 deletions bin/noirbox-decrypt-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Decrypts a single file into the filesystem.
# Usage: noirbox-decrypt-file filenme

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config

local_key="$(gcloud kms decrypt \
--location="$location" \
--keyring="$keyring" \
--key="$key" \
--plaintext-file=- \
--ciphertext-file="$noirbox_dir/local-key.enc")"

file="${1%.gpg}"

decrypt_file "$file" "$local_key"

46 changes: 46 additions & 0 deletions bin/noirbox-deregister-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Removes a file from the list of encrypted files
# Usage: noirbox-deregister-file filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config

old_file="${1%.gpg}"

found=no
while IFS="" read -r file
do
if [[ "$file" = "$old_file" ]]; then
found=yes
break
fi
done < "$noirbox_dir/noirbox-files.txt"

if [[ "$found" = "no" ]]; then
echo "$old_file is not registered"
exit 1
fi

files="$(while IFS="" read -r file
do
if [[ "$file" != "$old_file" ]]; then
echo "$file"
fi
done < "$noirbox_dir/noirbox-files.txt")"
echo "$files" > "$noirbox_dir/noirbox-files.txt"

gitignore="$(while IFS="" read -r file
do
if [[ "$file" != "$old_file" ]]; then
echo "$file"
fi
done < ".gitignore")"
echo "$gitignore" > ".gitignore"

rm -f "$old_file"
git rm -f "$old_file.gpg"
16 changes: 16 additions & 0 deletions bin/noirbox-edit
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Edits a file in your $EDITOR.
# Usage: noirbox-edit filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config
file="${1%.gpg}"

"$script_dir/noirbox-edit-start" "${@}"
"$EDITOR" "$file"
"$script_dir/noirbox-edit-end" "${@}"
9 changes: 9 additions & 0 deletions bin/noirbox-edit-end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
# Call this after ``noirbox-edit-start``ing a file.
# Usage: noirbox-edit-end filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
exec "$script_dir/noirbox-encrypt-file" "${@}"
git add "${1%.gpg}.gpg"
8 changes: 8 additions & 0 deletions bin/noirbox-edit-start
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
# If you want to edit using your IDE or similar, use this, and then noirbox-edit-end afterwards.
# Usage: noirbox-edit-start filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
exec "$script_dir/noirbox-decrypt-file" "${@}"
23 changes: 23 additions & 0 deletions bin/noirbox-encrypt-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Encrypts a single file
# Usage: noirbox-encrypt-file filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config

local_key="$(gcloud kms decrypt \
--location="$location" \
--keyring="$keyring" \
--key="$key" \
--plaintext-file=- \
--ciphertext-file="$noirbox_dir/local-key.enc")"

file="${1%.gpg}"

encrypt_file "$file" "$local_key"

81 changes: 81 additions & 0 deletions bin/noirbox-init
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
# Initializes noirbox in your directory. Expects to be in a git repo.
# Usage: noirbox-init --location=location --key=key --keyring=keyring

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

mkdir -p .noirbox
noirbox_dir="$(realpath .noirbox)"

keyring=""
location=""
key=""
create_key="yes"
force=""

for arg in "${@}"; do
opt="$(echo "$arg" | cut -d= -f1)"
val="$(echo "$arg" | cut -d= -f2)"
case "$opt" in
"--keyring")
keyring="$val"
;;
"--location")
location="$val"
;;
"--key")
key="$val"
;;
"--create-key")
create_key="$val"
;;
"--force")
force="yes"
;;
esac
done

if [[ -d .noirbox ]] && [[ "$force" != "yes" ]]; then
echo "A .noirbox directory already exists; this noirbox seems already initialized."
exit 1
fi


if [[ -z "$keyring" ]] || [[ -z "$location" ]] || [[ -z "$key" ]]; then
echo "Please enter location (e.g. asia), a keyring name, and a key name."
exit 1
fi

cat >"$noirbox_dir/config.yaml" <<EOF
location: "$location"
keyring: "$keyring"
key: "$key"
EOF

if [[ "$create_key" = "yes" ]]; then
gcloud kms keyrings create "$keyring" \
--location "$location"
gcloud kms keys create "$key" \
--location "$location" \
--keyring "$keyring" \
--purpose encryption \
--rotation-period "30d" \
--next-rotation-time "+30d"
fi

# Cloud KMS allows up to a 64KiB file
set +o pipefail
local_key="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c $key_size)"
echo "$local_key" | gcloud kms encrypt \
--location="$location" \
--keyring="$keyring" \
--key="$key" \
--plaintext-file=- \
--ciphertext-file="$noirbox_dir/local-key.enc"

if [[ ! -f "$noirbox_dir/noirbox-files.txt" ]]; then
echo >"$noirbox_dir/noirbox-files.txt"
fi
40 changes: 40 additions & 0 deletions bin/noirbox-register-new-file
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Adds a new file to the list of encrypted files.
# Usage: noirbox-register-new-file filename

set -e -u -o pipefail

script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$script_dir/_noirbox-common"

up_to_noirbox_root
read_config

local_key="$(gcloud kms decrypt \
--location="$location" \
--keyring="$keyring" \
--key="$key" \
--plaintext-file=- \
--ciphertext-file="$noirbox_dir/local-key.enc")"

new_file="$1"

while IFS="" read -r file
do
if [[ "$file" = "$new_file" ]]; then
echo "$new_file is already registered"
exit 1
fi
done < "$noirbox_dir/noirbox-files.txt"

sorted_files="$( (cat "$noirbox_dir/noirbox-files.txt"; echo "$new_file") | sort)"
echo "$sorted_files" > "$noirbox_dir/noirbox-files.txt"

echo "$new_file" >> .gitignore

encrypt_file "$new_file" "$local_key"
git add "$new_file.gpg"
git rm -f "$new_file" 2>/dev/null || true
rm -f "$new_file"


Loading

0 comments on commit 3225539

Please sign in to comment.