summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Pujol <alexandre@pujol.io>2017-02-03 17:28:56 (GMT)
committer Alexandre Pujol <alexandre@pujol.io>2017-02-03 23:57:52 (GMT)
commit15164f5578a34a85a5821a331045cd2c11d369bd (patch)
tree9624f8ddb2190315b1bcf614851d24b77b7dfc89
parent53b7460274e8478ed955aa6b3ccd95fd502ac417 (diff)
Add sharing support for tomb key.
A tomb key can be encrypted with more than one recipient. Therefore, a tomb can be shared between different user. The multiple recipients are given using the -r (or/and -R) option and must be separated by ','. Multiple recipients can be given for the commands: forge, setket and passwd
-rwxr-xr-xextras/test/runtests41
-rwxr-xr-xtomb54
2 files changed, 82 insertions, 13 deletions
diff --git a/extras/test/runtests b/extras/test/runtests
index a89c591..e3af55a 100755
--- a/extras/test/runtests
+++ b/extras/test/runtests
@@ -58,7 +58,7 @@ command -v qrencode > /dev/null || QRENCODE=0
typeset -A results
tests=(dig forge lock badpass open close passwd chksum bind setkey recip-dig
recip-forge recip-lock recip-open recip-close recip-passwd recip-resize
-recip-setkey)
+recip-setkey shared shared-passwd shared-setkey)
{ test $RESIZER = 1 } && { tests+=(resize) }
{ test $KDF = 1 } && { tests+=(kdforge kdfpass kdflock kdfopen) }
{ test $STEGHIDE = 1 } && { tests+=(stgin stgout stgopen stgpipe stgimpl
@@ -191,6 +191,44 @@ test-tomb-recip() {
tt close recip
}
+test-tomb-shared() {
+
+ notice "wiping all shared.tomb* in /tmp"
+ rm -f /tmp/shared.tomb /tmp/shared.tomb.key
+
+ notice "Testing sharing a tomb"
+ res=0
+ tt dig -s 20 /tmp/shared.tomb
+ { test $? = 0 } || { res=1 }
+ tt forge /tmp/shared.tomb.key -r $gpgid_1,$gpgid_2 \
+ --ignore-swap --unsafe --use-urandom
+ { test $? = 0 } || { res=1 }
+ tt lock /tmp/shared.tomb -k /tmp/shared.tomb.key \
+ --ignore-swap --unsafe -r $gpgid_1
+ { test $? = 0 } || { res=1 }
+ tt open /tmp/shared.tomb -k /tmp/shared.tomb.key -r $gpgid_1
+ { test $? = 0 } || { res=1 }
+ tt close shared
+ { test $? = 0 } || { res=1 }
+ { test $res = 0 } && { results+=(shared SUCCESS) }
+
+ notice "Testing changing recipients on a shared Tomb"
+ tt passwd -k /tmp/shared.tomb.key -r $gpgid_1,$gpgid_2 \
+ -R $gpgid_2,$gpgid_1
+ { test $? = 0 } && { results+=(shared-passwd SUCCESS) }
+
+ notice "Testing setkey on a shared Tomb"
+ rm -f /tmp/new.shared.tomb.key
+ res=0
+ tt forge /tmp/new.shared.tomb.key -r $gpgid_1,$gpgid_2 \
+ --ignore-swap --unsafe --use-urandom
+ { test $? = 0 } || { res=1 }
+ tt setkey -k /tmp/new.shared.tomb.key /tmp/shared.tomb.key /tmp/shared.tomb \
+ -r $gpgid_2,$gpgid_1
+ { test $? = 0 } || { res=1 }
+ { test $res = 0 } && { results+=(shared-setkey SUCCESS) }
+}
+
test-bind-hooks() {
notice "Testing bind hooks"
@@ -300,6 +338,7 @@ startloops=(`sudo losetup -a |cut -d: -f1`)
# isolated function (also called with source)
test-tomb-create
test-tomb-recip
+test-tomb-shared
notice "Testing open with wrong password"
diff --git a/tomb b/tomb
index fc3f7c6..d7ad4b5 100755
--- a/tomb
+++ b/tomb
@@ -825,13 +825,43 @@ _ensure_dependencies() {
# {{{ Key operations
-# $1 is the key ID we are checking
+# $@ is the list of all the recipient used to encrypt a tomb key
is_valid_recipients() {
- local gpg_id="$1" # Unique argument is the GPG ID to test
+ typeset -a recipients
+ recipients=($@)
+
_verbose "is_valid_recipients"
- gpg --list-secret-keys "$gpg_id" &> /dev/null
- return $?
+ # All the keys ID must be valid (the public keys must be present in the database)
+ for gpg_id in ${recipients[@]}; do
+ gpg --list-keys "$gpg_id" &> /dev/null
+ [[ $? != 0 ]] && {
+ _warning "$gpg_id is not a valid key ID."
+ return 1
+ }
+ done
+
+ # At least one private key must be present
+ for gpg_id in $recipients; do
+ gpg --list-secret-keys "$gpg_id" &> /dev/null
+ [[ $? = 0 ]] && {
+ return 0
+ }
+ done
+
+ return 1
+}
+
+# $@ is the list of all the recipient used to encrypt a tomb key
+# Print the recipient arg to be used in gpg.
+_recipients_arg() {
+ typeset -a recipients
+ recipients=($@)
+
+ for gpg_id in ${recipients[@]}; do
+ print -R -n "--recipient $gpg_id "
+ done
+ return 0
}
# $1 is the encrypted key contents we are checking
@@ -952,9 +982,9 @@ gpg_decrypt() {
gpgpopt=(--passphrase-fd 0)
{ option_is_set -r } && {
- local gpgkey=`option_value -r`
- _verbose "using $gpgkey to decrypt a tomb key"
- { ! is_valid_recipients "$gpgkey" } && {
+ typeset -a recipients
+ recipients=(${(s:,:)$(option_value -r)})
+ { is_valid_recipients $recipients } || {
_failure "You set an invalid GPG ID."
}
gpgpass="$TOMBKEY"
@@ -1173,20 +1203,20 @@ gen_key() {
tombpasstmp=""
{ option_is_set -r } && {
+ typeset -a recipients
{ option_is_set -R } && {
- local gpgkey=`option_value -R`
+ recipients=(${(s:,:)$(option_value -R)})
} || {
- local gpgkey=`option_value -r`
+ recipients=(${(s:,:)$(option_value -r)})
}
- _verbose "using $gpgkey to encrypt a tomb key"
- { is_valid_recipients "$gpgkey" } || {
+ { is_valid_recipients $recipients } || {
_failure "You set an invalid GPG ID."
}
# Set gpg inputs and options
gpgpass="$TOMBSECRET"
- gpgopt=(--encrypt --recipient "$gpgkey")
+ gpgopt=(--encrypt `_recipients_arg $recipients`)
opt=''
} || {
if [ "$1" = "" ]; then