-
Notifications
You must be signed in to change notification settings - Fork 39
/
gpg-sig-counter
executable file
·148 lines (136 loc) · 5.89 KB
/
gpg-sig-counter
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env bash
#-----------------------------------------------------------------------------
# gpg-sig-counter
# ----------------
# This is a script which can be used to keep track of the number of signatures
# for a GPG signing key. It is not meant for certifications
# (a.k.a. signatures) on others' keys. To use it, put it somewhere on your
# $PATH and create a repo somewhere for keeping a record of signatures. At the
# top of this script, fill out the variables $SIG_REPO, $REMOTE, $BRANCH for
# the local directory containing the repo for storing signature data, the name
# of the remote to push to, and the name of the branch, respectively.
#
# This script can be called like this, assuming you want to sign the file
# 'email.txt':
#
# ∃!isisⒶwintermute:(master *$)~ ∴ gpg-sig-counter -f email.txt \
# … -h patternsinthevoid.net
#
# Where the domain after the '-d' flag should be the domain name of your
# default GPG key which you are signing with. If you want you can put the
# locations of your signature repo in your signatures too, to do this put:
#
# sig-keyserver-url https://where.your.repo.is/
#
# into your gpg.conf. This script embeds the filename which you are signing,
# as well as the current count of signatures made by your key as notation data
# in each signature you make using this script. For example, looking at the
# following packet dump of the signature for 'email.txt', these would be the
# first two subpackets which start with 'Hashed Sub: notation data':
#
# ∃!isisⒶwintermute:(master *$)~ ∴ pgpdump -p email.txt.asc
# Old: Signature Packet(tag 2)(870 bytes)
# Ver 4 - new
# Sig type - Signature of a canonical text document(0x01).
# Pub alg - RSA Encrypt or Sign(pub 1)
# Hash alg - SHA512(hash 10)
# Hashed Sub: signature creation time(sub 2)(4 bytes)
# Time - Sat Sep 7 18:04:11 UTC 2013
# Hashed Sub: signature expiration time(sub 3)(critical)(4 bytes)
# Time - Sun Sep 7 18:04:11 UTC 2014
# Hashed Sub: notation data(sub 20)(41 bytes)
# Flag - Human-readable
# Name - [email protected]
# Value - 19
# Hashed Sub: notation data(sub 20)(61 bytes)
# Flag - Human-readable
# Name - [email protected]
# Value - /home/isis/email.txt
# Hashed Sub: notation data(sub 20)(74 bytes)
# Flag - Human-readable
# Name - [email protected]
# Value - 0A6A58A14B5946ABDE18E207A3ADB67A2CDB8B35
# Hashed Sub: policy URL(sub 26)(45 bytes)
# URL - https://blog.patternsinthevoid.net/policy.txt
# Hashed Sub: preferred key server(sub 24)(93 bytes)
# URL - https://code.patternsinthevoid.net/?p=sigs-0xA3ADB67A2CDB8B35.git;a=blob_plain;f=sigs;hb=HEAD
# Sub: issuer key ID(sub 16)(8 bytes)
# Key ID - 0xA3ADB67A2CDB8B35
# Hash left 2 bytes - d2 27
# RSA m^d mod n(4094 bits) - ...
# -> PKCS-1
#
# which show that this signature was the 19th one I made with this script, and
# the file I signed was 'email.txt'.
#
# So, what this script does:
# --------------------------
# 1. It embeds the above extra notation data into the signature packets.
#
# 2. Then it commits the file containing the signature count, with a commit
# message containing a timestamp and the signature count.
#
# 3. Next, *it signs the commit*, meaning that for every signature count
# *two* signatures are actually being made, but I only cared to keep
# trach of the first ones, so deal with it.
#
# 4. Then it tries to push to whatever remote you've configured.
#
# :authors: Isis Agora Lovecruft, 0xa3adb67a2cdb8b35
# :license: AGPLv3, see https://www.gnu.org/licenses/agpl-3.0.txt for text
# :version: 0.0.1
#-----------------------------------------------------------------------------
## SIG_REPO should be set to the local directory your signature count repo is
## located at:
SIG_REPO=~/.gnupg/sigs-0xA3ADB67A2CDB8B35
## REMOTE should be set to the name of the remote you wish to push to, if any:
REMOTE=origin
## BRANCH should be set the the name of the branch to push, if any:
BRANCH=master
## Don't touch anything else, unless you've found a bug and are patching it.
## ----------------------------------------------------------------------------
NAME=${0%%/}
function usage () {
printf "Usage: %s -f FILE -d DOMAIN [other gpg options]\n\n" $NAME
printf "Options:\n"
printf " -f FILE\tThe file to create a signature for\n"
printf " -d DOMAIN\tThe domain of the email address on your GPG key\n"
printf " -h\t\tThis cruft\n"
exit 1
}
## check that we have at least some arguments
if test "$#" -lt 1 ; then usage ; fi
while getopts f:d:h x; do
case $x in
f)
file=$OPTARG;
if test -n "${file}" -a -n "${domain}" ; then
break
fi ;;
d)
domain=$OPTARG;
if test -n "${file}" -a -n "${domain}" ; then
break
fi ;;
h) usage;;
*) break;;
esac
done
shift $((OPTIND - 1))
gpgopts=$*
if test -z "$gpgopts" ; then
gpgopts='-a --clearsign'
fi
scf="${SIG_REPO}"/sig-count
printf "Using signature count file %s" $scf
gpg -s $gpgopts \
--sig-notation signed.data@"$domain"="$file" \
--sig-notation sig.count@"$domain"=$(( `cat $scf` + 1 )) $file && \
{ ns=$(( `cat $scf` + 1 )) ;
echo -n "$ns" |& tee > "$scf" ; } && \
{ d=`date +"%s"`;
cd $SIG_REPO && \
{ git add $scf && \
git commit -q -S -m "$d $ns" </dev/null ;} && \
{ git push $REMOTE $BRANCH && \
git log --format=format:"%CredCommit hash:%Cgreen %>(2)%H %n%CredCommit message:%Cgreen %>(2)%s %n%CredSigned commit verification:%n%C(auto)%GG%n" HEAD^.. ;}; }