When adding .deb packages, default to sha1new algorithm to avoid problems with missin...
[0publish.git] / signing.py
blobe749e48673c5945814e38ae35531589b55ac98f8
1 from zeroinstall.injector import gpg
2 import tempfile, os, base64, sys
4 def check_signature(path):
5 data = file(path).read()
6 xml_comment = data.rfind('\n<!-- Base64 Signature')
7 if xml_comment >= 0:
8 data_stream, sigs = gpg.check_stream(file(path))
9 sign_fn = sign_xml
10 data = data[:xml_comment + 1]
11 data_stream.close()
12 elif data.startswith('-----BEGIN'):
13 data_stream, sigs = gpg.check_stream(file(path))
14 sign_fn = sign_plain
15 data = data_stream.read()
16 else:
17 return data, sign_unsigned, None
18 for sig in sigs:
19 if isinstance(sig, gpg.ValidSig):
20 return data, sign_fn, sig.fingerprint
21 print "ERROR: No valid signatures found!"
22 for sig in sigs:
23 print "Got:", sig
24 ok = raw_input('Ignore and load anyway? (y/N) ').lower()
25 if ok and 'yes'.startswith(ok):
26 return data, sign_unsigned, None
27 sys.exit(1)
29 def write_tmp(path, data):
30 """Create a temporary file in the same directory as 'path' and write data to it."""
31 fd, tmp = tempfile.mkstemp(prefix = 'tmp-', dir = os.path.dirname(path))
32 stream = os.fdopen(fd, 'w')
33 stream.write(data)
34 stream.close()
35 return tmp
37 def run_gpg(default_key, *arguments):
38 arguments = list(arguments)
39 if default_key is not None:
40 arguments = ['--default-key', default_key] + arguments
41 arguments.insert(0, 'gpg')
42 if os.spawnvp(os.P_WAIT, 'gpg', arguments):
43 raise Exception("Command '%s' failed" % arguments)
45 def sign_unsigned(path, data, key):
46 os.rename(write_tmp(path, data), path)
48 def sign_plain(path, data, key):
49 tmp = write_tmp(path, data)
50 try:
51 run_gpg(key, '--clearsign', tmp)
52 finally:
53 os.unlink(tmp)
54 os.rename(tmp + '.asc', path)
56 def sign_xml(path, data, key):
57 tmp = write_tmp(path, data)
58 try:
59 run_gpg(key, '--detach-sign', tmp)
60 finally:
61 os.unlink(tmp)
62 tmp += '.sig'
63 encoded = base64.encodestring(file(tmp).read())
64 os.unlink(tmp)
65 sig = "<!-- Base64 Signature\n" + encoded + "\n-->\n"
66 os.rename(write_tmp(path, data + sig), path)