|
@@ -0,0 +1,121 @@
|
|
|
+#!/usr/bin/env bash
|
|
|
+
|
|
|
+#Scipt to encrypt a file with some known keys,
|
|
|
+#the script will combin the encryptions to ensure that a minimum quorum defined in "combinate" variable is needed to open the file.
|
|
|
+#the script will not auto-adjust to an arbitrary change of "combinate" since one or more loops in the main loop should be tuned,
|
|
|
+#right now it's adjusted ofr a quorum of 3 recipients.
|
|
|
+#
|
|
|
+#usage: gpg-quorum_3of5.sh filename_to_encrypt.ext
|
|
|
+
|
|
|
+#retrieve the email list
|
|
|
+readarray -t emails < emails.txt
|
|
|
+file=$1
|
|
|
+#debug email if you want to self-decrypt:
|
|
|
+debug="-r youermail@provider.net"
|
|
|
+#counters:
|
|
|
+counter=0
|
|
|
+firstrun=0
|
|
|
+#minimum numbers of recipients that needs to agree to decypher the file:
|
|
|
+combinate=3
|
|
|
+#work directory:
|
|
|
+workdir="_WORKDIR"
|
|
|
+#lenght of array:
|
|
|
+max=${#emails[@]} # Take the length of that array
|
|
|
+
|
|
|
+
|
|
|
+#-----
|
|
|
+#CALCULATE number of combinations for our emails
|
|
|
+
|
|
|
+#function for factorial calculation
|
|
|
+function fun_fact {
|
|
|
+ num=$1
|
|
|
+ fact=1
|
|
|
+ for((i=2;i<=num;i++))
|
|
|
+ {
|
|
|
+ fact=$((fact * i)) #fact = fact * i
|
|
|
+ }
|
|
|
+ echo $fact
|
|
|
+}
|
|
|
+
|
|
|
+#n is the lenght of the array
|
|
|
+n=$max
|
|
|
+#r is the number of recipients needed to open the file
|
|
|
+r=$combinate
|
|
|
+
|
|
|
+a=$( fun_fact $n )
|
|
|
+b=$( fun_fact $r )
|
|
|
+c=$(( $n - $r ))
|
|
|
+d=$( fun_fact $c )
|
|
|
+t=$(( $b * $d ))
|
|
|
+ans=$(( $a / $t ))
|
|
|
+
|
|
|
+#echo "max number of combinations: "$ans
|
|
|
+#-----
|
|
|
+
|
|
|
+
|
|
|
+#create our workdir if it does not exist:
|
|
|
+if [ ! -d "$workdir" ]
|
|
|
+then
|
|
|
+ echo "creating dir"
|
|
|
+ mkdir $workdir
|
|
|
+else
|
|
|
+ echo "Directory $workdir exists, exiting"
|
|
|
+ exit
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+#main loop:
|
|
|
+for ((idxA=0; idxA<max; idxA++)); do # iterate idxA from 0 to length
|
|
|
+ for ((idxB=idxA; idxB<max; idxB++)); do # iterate idxB from idxA to length
|
|
|
+ for ((idxC=idxB; idxC<max; idxC++)); do # iterate idxC from idxB to length
|
|
|
+
|
|
|
+ if [ "${emails[$idxA]}" == "${emails[$idxB]}" ] || [ "${emails[$idxB]}" == "${emails[$idxC]}" ] || [ "${emails[$idxA]}" == "${emails[$idxC]}" ]; then
|
|
|
+
|
|
|
+ echo "A, B or C are the same"
|
|
|
+ continue
|
|
|
+
|
|
|
+ else
|
|
|
+ #custom execution for first run:
|
|
|
+ if [ "$counter" == 0 ]; then
|
|
|
+ gpg -ea -r "${emails[$idxA]}" -r "${emails[$idxB]}" -r "${emails[$idxC]}" "$debug" --output $workdir/$file.step$counter $file
|
|
|
+
|
|
|
+ #custom execution for last run:
|
|
|
+ elif [ "$counter" == $((ans-1)) ]; then
|
|
|
+ gpg -ea -r "${emails[$idxA]}" -r "${emails[$idxB]}" -r "${emails[$idxC]}" "$debug" --output $file.ENCRYPTED $workdir/$file.step$((counter-1))
|
|
|
+
|
|
|
+ #normal execution:
|
|
|
+ else
|
|
|
+ gpg -ea -r "${emails[$idxA]}" -r "${emails[$idxB]}" -r "${emails[$idxC]}" "$debug" --output $workdir/$file.step$counter $workdir/$file.step$((counter-1))
|
|
|
+
|
|
|
+ fi
|
|
|
+ #increase loop counter:
|
|
|
+ ((counter++))
|
|
|
+
|
|
|
+ fi
|
|
|
+ done
|
|
|
+ done
|
|
|
+done
|
|
|
+
|
|
|
+#remove work directory:
|
|
|
+rm -rf $workdir
|
|
|
+
|
|
|
+
|
|
|
+#the combination matrix for a quorum of 3 recipients on 5:
|
|
|
+#recipients: A,B,C,D,E
|
|
|
+#
|
|
|
+#A,B,C
|
|
|
+#A,B,D
|
|
|
+#A,B,E
|
|
|
+#A,C,D
|
|
|
+#A,C,E
|
|
|
+#A,D,E
|
|
|
+#B,C,D
|
|
|
+#B,C,E
|
|
|
+#B,D,E
|
|
|
+#C,D,E
|
|
|
+
|
|
|
+
|
|
|
+#SOURCES:
|
|
|
+#http://www.anonhack.in/2018/05/program-to-calculate-combination-ncr-in-bash-shell-scripting/
|
|
|
+#https://www.log2base2.com/shell-script-examples/loop/shell-script-to-find-factorial-of-a-number.html
|
|
|
+
|