Skip to content

Commit ada4932

Browse files
committed
Merge branch 'release/3.0.2'
2 parents ff1a802 + 6182885 commit ada4932

File tree

9 files changed

+196
-149
lines changed

9 files changed

+196
-149
lines changed

README

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
pretty-bad-protocol (a.k.a. python-gnupg) |On PyPI|
55
*******************************************************
66

7-
Complete rewrite of `Vinay Sajip's python-gnupg <https://code.google.com/p/python-gnupg/>`__,
7+
Complete rewrite of `Vinay Sajip's python-gnupg <https://bitbucket.org/vinay.sajip/python-gnupg>`__,
88
including patches to fix a shell injection vulnerability due to unsanitised
99
inputs being passed to ``subprocess.Popen([...], shell=True)``.
1010

@@ -21,7 +21,7 @@ From `PyPI <https://pypi.python.org>`__
2121

2222
It's simple. Just do::
2323

24-
[sudo] pip install pretty-bad-security
24+
[sudo] pip install pretty-bad-protocol
2525

2626
Additionally, the legacy way to install versions of this library <
2727
3.0.0 is::
@@ -47,9 +47,13 @@ Optionally, to build the Sphinx documentation_, do::
4747
To get started using python-gnupg's API, see the documentation_,
4848
and import the module like so::
4949

50+
.. code-block:: python
51+
5052
>>> from pretty_bad_protocol import gnupg
5153
52-
The primary interface class you'll likely want to interact with is ``gnupg.GPG``::
54+
The primary interface class you'll likely want to interact with is ``gnupg.GPG``:
55+
56+
.. code-block:: python
5357
5458
>>> gpg = gnupg.GPG(binary='/usr/bin/gpg',
5559
... homedir='./keys',
@@ -72,7 +76,7 @@ The primary interface class you'll likely want to interact with is ``gnupg.GPG``
7276
>>> message = "The crow flies at midnight."
7377
>>> encrypted = str(gpg.encrypt(message, key.fingerprint))
7478
>>> decrypted = str(gpg.decrypt(encrypted))
75-
>>> assert(decrypted == message)
79+
>>> assert decrypted == message
7680
7781
.. _documentation: https://pythonhosted.org/gnupg/
7882

pretty_bad_protocol/_meta.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import locale
3333
import os
3434
import platform
35+
import re
3536
import shlex
3637
import subprocess
3738
import sys
@@ -53,6 +54,8 @@
5354
from ._parsers import _sanitise_list
5455
from ._util import log
5556

57+
_VERSION_RE = re.compile('^\d+\.\d+\.\d+$')
58+
5659

5760
class GPGMeta(type):
5861
"""Metaclass for changing the :meth:GPG.__init__ initialiser.
@@ -521,8 +524,12 @@ def _check_sane_and_get_gpg_version(self):
521524
"Are you sure you specified the corrent (and full) "
522525
"path to the gpg binary?"))
523526

524-
version_line = str(result.data).partition(':version:')[2]
527+
version_line = result.data.partition(b':version:')[2].decode()
528+
if not version_line:
529+
raise RuntimeError("Got invalid version line from gpg: %s\n" % result.data)
525530
self.binary_version = version_line.split('\n')[0]
531+
if not _VERSION_RE.match(self.binary_version):
532+
raise RuntimeError("Got invalid version line from gpg: %s\n" % self.binary_version)
526533
log.debug("Using GnuPG version %s" % self.binary_version)
527534

528535
def _make_args(self, args, passphrase=False):
@@ -641,7 +648,15 @@ def _read_response(self, stream, result):
641648
the ``handle_status()`` method of that class will be
642649
called in order to parse the output of ``stream``.
643650
"""
651+
# All of the userland messages (i.e. not status-fd lines) we're not
652+
# interested in passing to our logger
653+
userland_messages_to_ignore = []
654+
655+
if self.ignore_homedir_permissions:
656+
userland_messages_to_ignore.append('unsafe ownership on homedir')
657+
644658
lines = []
659+
645660
while True:
646661
line = stream.readline()
647662
if len(line) == 0:
@@ -657,15 +672,19 @@ def _read_response(self, stream, result):
657672
line = _util._deprefix(line, 'gpg: ')
658673
keyword, value = _util._separate_keyword(line)
659674

660-
# Log gpg's userland messages at our own levels:
661-
if keyword.upper().startswith("WARNING"):
662-
log.warn("%s" % value)
663-
elif keyword.upper().startswith("FATAL"):
664-
log.critical("%s" % value)
665-
# Handle the gpg2 error where a missing trustdb.gpg is,
666-
# for some stupid reason, considered fatal:
667-
if value.find("trustdb.gpg") and value.find("No such file"):
668-
result._handle_status('NEED_TRUSTDB', '')
675+
# Silence warnings from gpg we're supposed to ignore
676+
ignore = any(msg in value for msg in userland_messages_to_ignore)
677+
678+
if not ignore:
679+
# Log gpg's userland messages at our own levels:
680+
if keyword.upper().startswith("WARNING"):
681+
log.warn("%s" % value)
682+
elif keyword.upper().startswith("FATAL"):
683+
log.critical("%s" % value)
684+
# Handle the gpg2 error where a missing trustdb.gpg is,
685+
# for some stupid reason, considered fatal:
686+
if value.find("trustdb.gpg") and value.find("No such file"):
687+
result._handle_status('NEED_TRUSTDB', '')
669688
else:
670689
if self.verbose:
671690
log.info("%s" % line)
@@ -936,7 +955,7 @@ def _encrypt(self, data, recipients,
936955
>>> encrypted = str(gpg.encrypt(message, key.fingerprint))
937956
>>> assert encrypted != message
938957
>>> assert not encrypted.isspace()
939-
>>> decrypted = str(gpg.decrypt(encrypted))
958+
>>> decrypted = str(gpg.decrypt(encrypted, passphrase='foo'))
940959
>>> assert not decrypted.isspace()
941960
>>> decrypted
942961
'The crow flies at midnight.'

pretty_bad_protocol/_parsers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ def _handle_status(self, key, value):
10911091
elif key == "NODATA":
10921092
self.status = nodata(value)
10931093
elif key == "PROGRESS":
1094-
self.status = progress(value.split(" ", 1)[0])
1094+
self.status = progress(value.split(' ', 1)[0])
10951095
else:
10961096
raise ValueError("Unknown status message: %r" % key)
10971097

@@ -1343,13 +1343,14 @@ def _handle_status(self, key, value):
13431343
13441344
:raises ValueError: if the status message is unknown.
13451345
"""
1346+
informational_keys = ["KEY_CONSIDERED"]
13461347
if key in ("EXPORTED"):
13471348
self.fingerprints.append(value)
13481349
elif key == "EXPORT_RES":
13491350
export_res = value.split()
13501351
for x in self.counts.keys():
13511352
self.counts[x] += int(export_res.pop(0))
1352-
else:
1353+
elif key not in informational_keys:
13531354
raise ValueError("Unknown status message: %r" % key)
13541355

13551356
def summary(self):

pretty_bad_protocol/gnupg.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ def __init__(self, binary=None, homedir=None, verbose=False,
7070
sufficient permissions.
7171
7272
:param str homedir: Full pathname to directory containing the public
73-
and private keyrings. Default is whatever GnuPG
74-
defaults to.
73+
and private keyrings. Default is
74+
`~/.config/python-gnupg`.
7575
7676
:type ignore_homedir_permissions: :obj:`bool`
7777
:param ignore_homedir_permissions: If true, bypass check that homedir
@@ -369,7 +369,7 @@ def recv_keys(self, *keyids, **kwargs):
369369
"""Import keys from a keyserver.
370370
371371
>>> gpg = gnupg.GPG(homedir="doctests")
372-
>>> key = gpg.recv_keys('hkp://pgp.mit.edu', '3FF0DB166A7476EA')
372+
>>> key = gpg.recv_keys('3FF0DB166A7476EA', keyserver='hkp://pgp.mit.edu')
373373
>>> assert key
374374
375375
:param str keyids: Each ``keyids`` argument should be a string
@@ -629,6 +629,8 @@ def expire(self, keyid, expiration_time='1y', passphrase=None, expire_subkeys=Tr
629629
p.stdin.write(expiration_input)
630630

631631
result = self._result_map['expire'](self)
632+
p.stdin.write(expiration_input)
633+
632634
self._collect_output(p, result, stdin=p.stdin)
633635
return result
634636

@@ -1029,7 +1031,7 @@ def encrypt(self, data, *recipients, **kwargs):
10291031
>>> encrypted = str(gpg.encrypt(message, key.fingerprint))
10301032
>>> assert encrypted != message
10311033
>>> assert not encrypted.isspace()
1032-
>>> decrypted = str(gpg.decrypt(encrypted))
1034+
>>> decrypted = str(gpg.decrypt(encrypted, passphrase='foo'))
10331035
>>> assert not decrypted.isspace()
10341036
>>> decrypted
10351037
'The crow flies at midnight.'
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
-----BEGIN PGP PUBLIC KEY BLOCK-----
2-
Version: GnuPG v2
2+
Version: GnuPG v1
33

44
mQENBFPcAbUBCADyAcv3Xb3A+j0ndtFNEw3fxfwcTnMBePTmLGmsz60y+DL8N0mb
55
U2qpmglb2ONkFJJDa2fhl9XHwalmKCxynNE0kMNvTnTJFhFL3QSS8BPDUYKrCPfH
66
NcuDtpAwEZJF6PnTy+8eNciT3Ru/NT1cw1K9YkTT5XqKvfgqhaSybHSMrPlx4rAE
77
Is5oX0MwX3RdEtX+GzvGiz8s8+pPMX2Vh09pj6wsV+zBexXNvQnO0VzP2eteTEwV
88
5ezgvmh6Ss3OMPJTKxc98jczRMVYtZlv05KdziKK0VWtshp2Xubt2VVRKSCOYk8r
99
trR75b6yyDeFrGrvl22X2IUdttyb3XlMCJ+rABEBAAG0OXB5dGhvbi1nbnVwZyB0
10-
ZXN0IGtleSAjMSAoRE8gTk9UIFVTRSkgPHRlc3RAcHl0aG9uLWdudXBnPokBPgQT
11-
AQIAKAIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AFAlbazHQFCQxkzD8ACgkQ
12-
dMU6jvwynOPnswf+O23ssUsXdjEzDWo06m4w2tCxMRaP6gg3JSrHCxDtDBtwnoIz
13-
QL4rX+rA4ZGHz6QKsxg1pD+ze/dxKlyJ9p7qYvN1hln+JX0c72EsmXEbmHITW0qC
14-
sUJ+PpuIGO/kN0as++y/T9zmAeTYkrdBiy1ZAw/gNqHkEvnP24r7A4FSFPmo3RWD
15-
HCvlGPFEKU+BInmGTauhf2EkXa4NgMO9aucxj+q3kflFYwqEXYm+VeUg3qnBNpbx
16-
CihL2uufqLqI9crJ//FfQ6ICUw1s7PM1UR9RTHYbfWKgIlxlxKYl+VauK8+1nHwx
17-
GiYTrvN5XBitrEnqS45A6OlCEHvutaIhfBLhp7kBDQRT3AG1AQgAv40d8IxornLJ
18-
s15tOdWqhf5VQeJDgVYKBSQc/MZWiLE3L7d6GO1GwBDUblUIaU28MAC4/m5ioSSg
19-
Cq60J+lAi6Caan+VXxYpkNK++nTXRLj/HGGZL7dBxDdpkY0+PhGIwx7fDgO9eDn7
20-
wt+y1ky46QjXI89eD6Re+XvnQ04newCFTvXrNmOJhcjfNApQPZXQyJ57MIajcq0p
21-
LkcUBDzIkY5RgPznLVhN2Yps4kPHf4/r6wTjljo1vb8XJMdb7BGx9BkFxMnFnw/A
22-
PSciLTCDeBb+BxkiDVmUsvtJSAm3tJsfhXLB7bOzIRjL3WH8UtuF8nclAUmsPHdT
23-
Oew4I6Ve1QARAQABiQElBBgBAgAPBQJT3AG1AhsMBQkB4TOAAAoJEHTFOo78Mpzj
24-
dTYIANSpZj8aV6mxNfimC2tw7tKYLPcO0WrbnPtCdnRefhajdJX7R/iqcr+SBrq6
25-
ZY30vF9A+s8IfK3T8753KrDiyb5J3dhYMkpstqquMjM4vupM3DB9pX8S0UT6Rmqp
26-
Bbh4IhdrnpoJ5XxROsDG4KwHAgVI8WT8c1yj7Is31dJAA6Nvq/eOhDPjaI2pujD2
27-
7+4OCcEx4YzS/y84s8S9geZjMv2gtJE+MeMFzpzVAEoGQhhPDQQIlnenUXT0A2Ap
28-
S6KDKWh/mmaGRyzSNOmQZvnctjFXrVRFh12JJPh3qqi68a8HPGu8/D9tCp1EbklX
29-
OiFXr2E+pzFNE2UmGT5K+CMJmBQ=
30-
=IKK0
10+
ZXN0IGtleSAjMSAoRE8gTk9UIFVTRSkgPHRlc3RAcHl0aG9uLWdudXBnPokBOAQT
11+
AQIAIgIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AFAltY46EACgkQdMU6jvwy
12+
nOOwGQgA6szPLpeOcIpuW62S1x5zW+9//Nir0AMq+Vkx6p6OdqpcdcEHqAi0jLUY
13+
r40jTUmTjdQOxe7E4M1pwklrANuVee6wh6oJSSyane/oDhD5lsn4sfsfzY/BaHFw
14+
qMvEbHNVAXU9PcFDHv3UVUPXdjWlPc8SUVjpnlg6Tn3NS6vFH5XvZtoP9eLUwtEV
15+
tn+TW4qyu3KO04iiS4PdWEQX2l5FSNNA6qc5YPEqEF8Wm9pUA8UjGzn7J7bPe+Rq
16+
L+3PYp0k4VoMB6++9tjEj9FUHze/lAz72mMlq4YJpYm8noZAFdu7R1kQhy/KMWIN
17+
0xsNvOl+98bSnZrpXFFODcgcsCVEE7kBDQRT3AG1AQgAv40d8IxornLJs15tOdWq
18+
hf5VQeJDgVYKBSQc/MZWiLE3L7d6GO1GwBDUblUIaU28MAC4/m5ioSSgCq60J+lA
19+
i6Caan+VXxYpkNK++nTXRLj/HGGZL7dBxDdpkY0+PhGIwx7fDgO9eDn7wt+y1ky4
20+
6QjXI89eD6Re+XvnQ04newCFTvXrNmOJhcjfNApQPZXQyJ57MIajcq0pLkcUBDzI
21+
kY5RgPznLVhN2Yps4kPHf4/r6wTjljo1vb8XJMdb7BGx9BkFxMnFnw/APSciLTCD
22+
eBb+BxkiDVmUsvtJSAm3tJsfhXLB7bOzIRjL3WH8UtuF8nclAUmsPHdTOew4I6Ve
23+
1QARAQABiQEfBBgBAgAJAhsMBQJbWOOEAAoJEHTFOo78MpzjZPMIAMuUn9qsK7tK
24+
wuxoL/dBWps6dvzupm3sbld3hm5aK04LWOO0yNTT5Lmi77QKposycOxWKaJpoutR
25+
tkWhF5A0gw9tfle1kHFQBISGAns/B73NauXLEEnu0PLoIZCsnvDwm4yeN/Bm/DVv
26+
9f3wbNQCpAeO7QXasFa7W4sC5Sx3erD4CP5B4cXbujIjl1q4UA0jMWoJ95DPy22r
27+
LwMygHmXCXj8Ai4YFWupxbM8RePJsjdeCWF7lOpnIajE6Y+GBRbZzB7DObtxcBvM
28+
IAYWxvJ9wA8TPC2r/1Ap2PwZGHsG9ZPNbzECwQyWA5TjIVfZVyniuQGfKFdKtBNP
29+
Uh6hM2yznQg=
30+
=6++F
3131
-----END PGP PUBLIC KEY BLOCK-----
Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-----BEGIN PGP PRIVATE KEY BLOCK-----
2-
Version: GnuPG v2
2+
Version: GnuPG v1
33

44
lQOYBFPcAbUBCADyAcv3Xb3A+j0ndtFNEw3fxfwcTnMBePTmLGmsz60y+DL8N0mb
55
U2qpmglb2ONkFJJDa2fhl9XHwalmKCxynNE0kMNvTnTJFhFL3QSS8BPDUYKrCPfH
@@ -21,38 +21,38 @@ bXmxwiuT+5DMj5nZmfT1Lijwn/KZZHMEAJumBFXr+9pwnr4hsYOutIUnuPo0ikn+
2121
Z1GXDJM8RvHDvm2/nOWBmIbMIiiYUK09SaPNa+gsXWCmpw8geMQr88scx8KsRSAX
2222
wOVyWHaieuvtSOWpTJG8XDZ3wT9bgYEff3dh7Xn+URtPEkcoF/JWQE0aLq8Olnnv
2323
ckI2TSUbjMO+PoO0OXB5dGhvbi1nbnVwZyB0ZXN0IGtleSAjMSAoRE8gTk9UIFVT
24-
RSkgPHRlc3RAcHl0aG9uLWdudXBnPokBPgQTAQIAKAIbAwYLCQgHAwIGFQgCCQoL
25-
BBYCAwECHgECF4AFAlbazHQFCQxkzD8ACgkQdMU6jvwynOPnswf+O23ssUsXdjEz
26-
DWo06m4w2tCxMRaP6gg3JSrHCxDtDBtwnoIzQL4rX+rA4ZGHz6QKsxg1pD+ze/dx
27-
KlyJ9p7qYvN1hln+JX0c72EsmXEbmHITW0qCsUJ+PpuIGO/kN0as++y/T9zmAeTY
28-
krdBiy1ZAw/gNqHkEvnP24r7A4FSFPmo3RWDHCvlGPFEKU+BInmGTauhf2EkXa4N
29-
gMO9aucxj+q3kflFYwqEXYm+VeUg3qnBNpbxCihL2uufqLqI9crJ//FfQ6ICUw1s
30-
7PM1UR9RTHYbfWKgIlxlxKYl+VauK8+1nHwxGiYTrvN5XBitrEnqS45A6OlCEHvu
31-
taIhfBLhp50DmART3AG1AQgAv40d8IxornLJs15tOdWqhf5VQeJDgVYKBSQc/MZW
32-
iLE3L7d6GO1GwBDUblUIaU28MAC4/m5ioSSgCq60J+lAi6Caan+VXxYpkNK++nTX
33-
RLj/HGGZL7dBxDdpkY0+PhGIwx7fDgO9eDn7wt+y1ky46QjXI89eD6Re+XvnQ04n
34-
ewCFTvXrNmOJhcjfNApQPZXQyJ57MIajcq0pLkcUBDzIkY5RgPznLVhN2Yps4kPH
35-
f4/r6wTjljo1vb8XJMdb7BGx9BkFxMnFnw/APSciLTCDeBb+BxkiDVmUsvtJSAm3
36-
tJsfhXLB7bOzIRjL3WH8UtuF8nclAUmsPHdTOew4I6Ve1QARAQABAAf9GLyxKqD/
37-
XdP+H1do9KiWwoIjYYRGYnwJhDtzMOOuRi3YqiVgM7rkwaYKwQrjMLI0xOA7A8Se
38-
oR/ZOTfxlRvm1YFSn8FFOYfjq0vEFRUkvb/EVlZ2UXaxnBTp4b2jVaGvDz+735P1
39-
EoMuc66u6kTzNkkJe5rqk0uPZlmtdoAv0g735/vc8IwtobO8DQ0eSl/upSw0Ulgh
40-
7KZ+ztaAVOgqAaHVs73iq2iZlzsPyy4BWASlGOrJrSxaaT+s4R0s8i/AlCq0MSjy
41-
tOk4EdYq8O1X8U8YIAxb+mAXc29E2GkICVllmBM5K7ajo/OlRvdkf9qND37+qJ71
42-
4Gou8uei0HV2sQQAwKeBTG97ZpoGZanxYO27MrzuAIE5hGH7+SR6z1UcFgPFhZ5j
43-
/zyZPVMV/FWbxR0YoRAp5IbXQFGpuvgLLVsS/fAUWHWr9GZfDKjLOXn2wPXqbxQc
44-
SMJSCeaGICLn3Ref5Ox0EN/DNUJY3XRflvLXWignBdf6aefGm2WmXFfQORkEAP6I
45-
wuNV8Z0UR8C7xhtSgk8gbbkdPL/SgXF0H6+U5zrTPMz8o0S7H9tPTxksER5ohA2p
46-
ilLFde+7ioUfBCOTWSaBS4VfDXzVyHYlJZN1rawbB2Lb7KaD9+TzXU1Ur2I/K6/p
47-
3gBw5mS3bzV1UKHc2KmeXJQ7Hy5D7m1bapKMh/8dBACpb/qsyELNu4imgQbOSTeK
48-
OicBzVFIlWSOXPnOYFSfaHEqb2CI5l1/tUmuh5ip/vP8s0CRvJ+xK5LyTeWJU9NF
49-
2gbYQuM+nFodR2qOdj5yDXGwhDDgaQah/rhxPxrRStUc2NZSfhgSuj3+CftcsE6/
50-
QE1EbCLDDZyAjBnOdMWC90FNiQElBBgBAgAPBQJT3AG1AhsMBQkB4TOAAAoJEHTF
51-
Oo78MpzjdTYIANSpZj8aV6mxNfimC2tw7tKYLPcO0WrbnPtCdnRefhajdJX7R/iq
52-
cr+SBrq6ZY30vF9A+s8IfK3T8753KrDiyb5J3dhYMkpstqquMjM4vupM3DB9pX8S
53-
0UT6RmqpBbh4IhdrnpoJ5XxROsDG4KwHAgVI8WT8c1yj7Is31dJAA6Nvq/eOhDPj
54-
aI2pujD27+4OCcEx4YzS/y84s8S9geZjMv2gtJE+MeMFzpzVAEoGQhhPDQQIlnen
55-
UXT0A2ApS6KDKWh/mmaGRyzSNOmQZvnctjFXrVRFh12JJPh3qqi68a8HPGu8/D9t
56-
Cp1EbklXOiFXr2E+pzFNE2UmGT5K+CMJmBQ=
57-
=pZI3
24+
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
56+
KFdKtBNPUh6hM2yznQg=
57+
=w7N6
5858
-----END PGP PRIVATE KEY BLOCK-----
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
-----BEGIN PGP PUBLIC KEY BLOCK-----
2-
Version: GnuPG v2
2+
Version: GnuPG v1
33

44
mQENBFPcAfMBCADbXmLUb4kYJO1DfKLwmPZ7AFHTqYCFABr2QwMP59llR7VyPU8W
55
7v9pER/D+IGOQ9Hw/vx9YEcb7qvN5kDBAEwUyU0KjJXrIpsPooAj3YcMHGRwiITV
66
o40+1ZojGOEAb4+Nos8whYFMT0IOlfaRtUkoUwiQ/HdNFxbo8YUnHrLK44fAG4qn
77
B/Nw5lAUy7HfxCQ5JmV/Qsv8A7sBqD0Pijf/6LAGGlo1EVLpaec6mnjZlUoR5a7Y
88
a3WCrvN2js4esn7hj8hGX17qgbHLI5ktFbkyw8IhjiSlF5SZRuM3dukcGp+O1cDC
99
kAcEOZiAfoGRWL2Uy/vwW+TmtXNG0COPf4Q9ABEBAAG0OnB5dGhvbi1nbnVwZyB0
10-
ZXN0IGtleSAjMiAoRE8gTk9UIFVTRSkgPHRlc3QyQHB5dGhvbi1nbnVwZz6JAT4E
11-
EwECACgCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheABQJW2syHBQkMZMwUAAoJ
12-
EC/3/4irrDSi2RQH+wau1P2QYB42J/vJe8wachmTvXKpCNwGJVWAnj3XU2sgP1A/
13-
pcFo6oBJxfGx+g9jpahHZUHS4am9rkxPou6/H0rliQgBKl/mvJjKv3DHuWZsHlh7
14-
uHnhaoMqk84hxoOK6XNRKJ5HMl6RqyvNJmNx3cFDMMjQn7b6jzk5TYx9pkxAdwap
15-
x5FxnxZIzf/05Ifey6KCP747DmqfA5xsNNLHDnDh6pp5fVEthJwMK+m+D25M4IPW
16-
ER31mv7mT32bR4oG8EOrvTydE+QS0cXETXvWQL7xgeawPDbUkvubGKBvvrob3mf4
17-
JYp1lXUN5bQ2J9UZuBvfwsBUd6II8f2wh4tOFNi5AQ0EU9wB8wEIAMAUN6oVuvfT
18-
Koci7BrKlSRpZYeLkxxS7b7gQUkPu665rIREyT6AfBrk1NK/ILho6JmF1TjOZLuG
19-
rOXrFT+SCSqPoMUUVpp5f9Xn55W9MTJje9u8skbdxYZm6l/pKlQJbrhKacFdrbqU
20-
w/zHC2BIlP4Ve1aGoJGW5CRHYSvH6fZLMvJbNb0Yy75oXdBHQ4aawD6IL0Z++oXc
21-
VvQOKhkRqvnbbzFRDgQRjng9+FjCbfXZgzdUWq1japl1U7sn95n+I4dLO9WESqOQ
22-
o9Prpxk2C4jHzFThRy4W83xm8sfLv2GHfCeqD9p0diQarIeuOMJZ/cDjj1a5j0q2
23-
LfIwyFZNyR8AEQEAAYkBJQQYAQIADwUCU9wB8wIbDAUJAeEzgAAKCRAv9/+Iq6w0
24-
ovftCACsGvKitzjyHamFts5qccBgd5a/sssLea9BqP4zPQuubO+brM3dqunCpGbh
25-
msWfPF7iDGfXJH8TC6QhMi0UDzFd5EsF4PozMV0KjkgzIFFYh8DB+HxdNsx03YoZ
26-
7qxC5LW+kWzLzZ1492CqxjrPNucxEkTd7PQ15I6LZteffBceQsamK1IGaV5qPo82
27-
DVotfrX4ziYGcPF3yXKPKQLi1D1M9eEObNbdVz8J4tbYEDzZ3S+eqhSiqpSX6cIF
28-
2I+A3+1uOz0bvCMgEnXk4aa62xF1GYHJ4QJ5P+sRUnThBXzktN9suJdsevHOuHuu
29-
Xl8+ntjPe8a7wEqullJG2p+dnIm8
30-
=KyUg
10+
ZXN0IGtleSAjMiAoRE8gTk9UIFVTRSkgPHRlc3QyQHB5dGhvbi1nbnVwZz6JATgE
11+
EwECACICGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheABQJbWOT4AAoJEC/3/4ir
12+
rDSiAkMH/jWCh+wM9XRpGi+KtAH/74XXSjmHrLtpc7jjKb4rmRoAh40QerHocU8S
13+
tQouOrlfn/QcvnzPBIBACMqcEDnA4Jnuew+KMDQ2Kh72dDF6SclFZ3T3/MTVzEx4
14+
LAWuJgJrSD8MLdq3nziEmZ7mguzfERT0jvLQPYvxJSD+RrvJJXDY6TbtN9HueKWi
15+
f8MvG+QbYkFh9nYrNcdQV027B+sh/Ozb6vzQslrTzFVkxcDhxV2L88bDblV6rZhK
16+
M7hBtPGTcLpLdImvi0iotnxHnTh4p3edFDGv8GN5O+bRDBTA9w1EIaKQO8YPJb6m
17+
lU3kah/WW3++Bz52dORMmKwbgYg3pwi5AQ0EU9wB8wEIAMAUN6oVuvfTKoci7BrK
18+
lSRpZYeLkxxS7b7gQUkPu665rIREyT6AfBrk1NK/ILho6JmF1TjOZLuGrOXrFT+S
19+
CSqPoMUUVpp5f9Xn55W9MTJje9u8skbdxYZm6l/pKlQJbrhKacFdrbqUw/zHC2BI
20+
lP4Ve1aGoJGW5CRHYSvH6fZLMvJbNb0Yy75oXdBHQ4aawD6IL0Z++oXcVvQOKhkR
21+
qvnbbzFRDgQRjng9+FjCbfXZgzdUWq1japl1U7sn95n+I4dLO9WESqOQo9Prpxk2
22+
C4jHzFThRy4W83xm8sfLv2GHfCeqD9p0diQarIeuOMJZ/cDjj1a5j0q2LfIwyFZN
23+
yR8AEQEAAYkBHwQYAQIACQIbDAUCW1jlBgAKCRAv9/+Iq6w0otHvB/9N9d+CGDX2
24+
y9DfRK+3z/mCdGFqaOeoi6K4D6uHd0hfiQjMD/EjrB+BvUcM9Aommydvi7lk9WGQ
25+
EQUYwZBGIdddj4jFzc/7m/27pQb2zwpxD90riybNQpcCC6EEzKXxEskYcm457ZOd
26+
za743hdQXC9W4TjIKA/evfxn87UfZBW4wduh5Vznhu3JkGKOQy5iWea7jR6SzZ/y
27+
gn0mqLzF3BNyfvSpVf/f1KNSZbCah+T/Geuj6qDuiKDCbjR05XyiZMWxfMEzfBCf
28+
EzgXCgUHH3jUgKXRTP/AOM3R+tn6/cKBqnkvWqFRbyaJ4eHaqG9+njgbIK9gXXBI
29+
bZXs8K4e1EgF
30+
=tUCn
3131
-----END PGP PUBLIC KEY BLOCK-----

0 commit comments

Comments
 (0)