Correct my email address for Debian work.
[dput.git] / dput / crypto.py
blobd1a2379f2b4589b0dedfee976e177bdbc6ef515a
1 # -*- coding: utf-8; -*-
3 # dput/crypto.py
4 # Part of ‘dput’, a Debian package upload toolkit.
6 # Copyright © 2016 Ben Finney <bignose@debian.org>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along
19 # with this program; if not, write to the Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 """ Cryptographic and hashing functionality. """
24 from __future__ import (absolute_import, unicode_literals)
26 import sys
28 import gpgme
31 def characterise_signature(signature):
32 """ Make a phrase characterising a GnuPG signature.
34 :param signature: A `gpgme.Signature` instance.
35 :return: A simple text phrase characterising the `signature`.
37 * If the signature is valid, the result is "valid".
38 * If the signature is not valid, but is good, the result is
39 "good".
40 * If the signature is not good, the result is "bad".
42 """
43 text = "UNKNOWN"
44 if (signature.summary & gpgme.SIGSUM_VALID):
45 text = "valid"
46 elif (signature.summary & gpgme.SIGSUM_RED):
47 text = "bad"
48 elif (signature.summary & gpgme.SIGSUM_GREEN):
49 text = "good"
51 return text
54 def describe_signature(signature):
55 """ Make a message describing a GnuPG signature.
57 :param signature: A `gpgme.Signature` instance.
58 :return: A text description of the salient points of the
59 `signature`.
61 The description includes the signature's character (whether it
62 is valid, good, or bad); and the key ID used to create the
63 signature.
65 """
66 character = characterise_signature(signature)
67 fpr_length = 16
68 text = "{character} signature from {fpr}".format(
69 character=character.title(),
70 fpr=signature.fpr[-fpr_length:])
72 return text
75 def check_file_signature(infile):
76 """ Verify the GnuPG signature on a file.
78 :param infile: The file containing a signed message.
79 :return: ``None``.
80 :raise gpgme.GpgmeError: When the signature verification fails.
82 The `infile` is a file-like object, open for reading, that
83 contains a message signed with OpenPGP (e.g. GnuPG).
85 """
86 context = gpgme.Context()
87 try:
88 with infile:
89 signatures = context.verify(infile, None, None)
90 except gpgme.GpgmeError as exc:
91 (__, code, message) = exc.args
92 sys.stderr.write("gpgme: {path}: error {code}: {message}\n".format(
93 path=infile.name, code=code, message=message))
94 raise
96 for signature in signatures:
97 description = describe_signature(signature)
98 sys.stderr.write(
99 "gpgme: {path}: {description}\n".format(
100 path=infile.name, sig=signature, description=description))
103 # Local variables:
104 # coding: utf-8
105 # mode: python
106 # End:
107 # vim: fileencoding=utf-8 filetype=python :