summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2013-11-04 15:09:40 -0200
committerdrebs <drebs@leap.se>2013-11-04 15:10:26 -0200
commit933731e4671c8ed3b7fa16bf1222e06f76eea215 (patch)
tree6d0fab57953d5bddc8a149548bd326754e3c1326
parenta22efb595cee79fbcab830d8024a173a6a68d6aa (diff)
Add verification of detached signatures.
-rw-r--r--changes/feature-4375_add-verification-of-detached-sigs1
-rw-r--r--src/leap/keymanager/__init__.py12
-rw-r--r--src/leap/keymanager/keys.py9
-rw-r--r--src/leap/keymanager/openpgp.py25
-rw-r--r--src/leap/keymanager/tests/test_keymanager.py14
5 files changed, 48 insertions, 13 deletions
diff --git a/changes/feature-4375_add-verification-of-detached-sigs b/changes/feature-4375_add-verification-of-detached-sigs
new file mode 100644
index 0000000..ee09cbe
--- /dev/null
+++ b/changes/feature-4375_add-verification-of-detached-sigs
@@ -0,0 +1 @@
+ o Add verification of detached signatures. Closes #4375.
diff --git a/src/leap/keymanager/__init__.py b/src/leap/keymanager/__init__.py
index a550598..61213d3 100644
--- a/src/leap/keymanager/__init__.py
+++ b/src/leap/keymanager/__init__.py
@@ -473,15 +473,18 @@ class KeyManager(object):
data, privkey, digest_algo=digest_algo, clearsign=clearsign,
detach=detach, binary=binary)
- def verify(self, data, pubkey):
+ def verify(self, data, pubkey, detached_sig=None):
"""
- Verify signed C{data} with C{pubkey}.
+ Verify signed C{data} with C{pubkey}, eventually using
+ C{detached_sig}.
:param data: The data to be verified.
:type data: str
-
:param pubkey: The public key to be used on verification.
:type pubkey: EncryptionKey
+ :param detached_sig: A detached signature. If given, C{data} is
+ verified using this detached signature.
+ :type detached_sig: str
:return: The signed data.
:rtype: str
@@ -489,7 +492,8 @@ class KeyManager(object):
leap_assert_type(pubkey, EncryptionKey)
leap_assert(pubkey.__class__ in self._wrapper_map, 'Unknown key type.')
leap_assert(pubkey.private is False, 'Key is not public.')
- return self._wrapper_map[pubkey.__class__].verify(data, pubkey)
+ return self._wrapper_map[pubkey.__class__].verify(
+ data, pubkey, detached_sig=detached_sig)
from ._version import get_versions
__version__ = get_versions()['version']
diff --git a/src/leap/keymanager/keys.py b/src/leap/keymanager/keys.py
index b8e88d4..ec1bfeb 100644
--- a/src/leap/keymanager/keys.py
+++ b/src/leap/keymanager/keys.py
@@ -340,15 +340,18 @@ class EncryptionScheme(object):
pass
@abstractmethod
- def verify(self, data, pubkey):
+ def verify(self, data, pubkey, detached_sig=None):
"""
- Verify signed C{data} with C{pubkey}.
+ Verify signed C{data} with C{pubkey}, eventually using
+ C{detached_sig}.
:param data: The data to be verified.
:type data: str
-
:param pubkey: The public key to be used on verification.
:type pubkey: EncryptionKey
+ :param detached_sig: A detached signature. If given, C{data} is
+ verified against this sdetached signature.
+ :type detached_sig: str
:return: The signed data.
:rtype: str
diff --git a/src/leap/keymanager/openpgp.py b/src/leap/keymanager/openpgp.py
index 8ec8639..111dfaf 100644
--- a/src/leap/keymanager/openpgp.py
+++ b/src/leap/keymanager/openpgp.py
@@ -30,6 +30,7 @@ import locale
from gnupg import GPG
from gnupg.gnupg import GPGUtilities
+from gnupg._util import _make_binary_stream
from leap.common.check import leap_assert, leap_assert_type
from leap.keymanager import errors
@@ -570,15 +571,18 @@ class OpenPGPScheme(EncryptionScheme):
'%s != %s' % (rfprint, kfprint))
return result.data
- def verify(self, data, pubkey):
+ def verify(self, data, pubkey, detached_sig=None):
"""
- Verify signed C{data} with C{pubkey}.
+ Verify signed C{data} with C{pubkey}, eventually using
+ C{detached_sig}.
:param data: The data to be verified.
:type data: str
-
:param pubkey: The public key to be used on verification.
:type pubkey: OpenPGPKey
+ :param detached_sig: A detached signature. If given, C{data} is
+ verified against this detached signature.
+ :type detached_sig: str
:return: The ascii-armored signed data.
:rtype: str
@@ -586,7 +590,20 @@ class OpenPGPScheme(EncryptionScheme):
leap_assert_type(pubkey, OpenPGPKey)
leap_assert(pubkey.private is False)
with self._temporary_gpgwrapper(pubkey) as gpg:
- result = gpg.verify(data)
+ result = None
+ if detached_sig is None:
+ result = gpg.verify(data)
+ else:
+ # to verify using a detached sig we have to use
+ # gpg.verify_file(), which receives the data as a binary
+ # stream and the name of a file containing the signature.
+ sf, sfname = tempfile.mkstemp()
+ sfd = os.fdopen(sf, 'w')
+ sfd.write(detached_sig)
+ sfd.close()
+ df = _make_binary_stream(data, gpg._encoding)
+ result = gpg.verify_file(df, sig_file=sfname)
+ df.close()
gpgpubkey = gpg.list_keys().pop()
valid = result.valid
rfprint = result.fingerprint
diff --git a/src/leap/keymanager/tests/test_keymanager.py b/src/leap/keymanager/tests/test_keymanager.py
index 2512604..67676e9 100644
--- a/src/leap/keymanager/tests/test_keymanager.py
+++ b/src/leap/keymanager/tests/test_keymanager.py
@@ -294,7 +294,7 @@ class OpenPGPCryptoTestCase(KeyManagerWithSoledadTestCase):
pgp.put_ascii_key(PRIVATE_KEY)
data = 'data'
privkey = pgp.get_key(ADDRESS, private=True)
- signed = pgp.sign(data, privkey)
+ signed = pgp.sign(data, privkey, detach=False)
pubkey = pgp.get_key(ADDRESS, private=False)
self.assertTrue(pgp.verify(signed, pubkey))
@@ -314,6 +314,16 @@ class OpenPGPCryptoTestCase(KeyManagerWithSoledadTestCase):
encrypted_and_signed, privkey2, verify=pubkey)
self.assertTrue(data, res)
+ def test_sign_verify_detached_sig(self):
+ pgp = openpgp.OpenPGPScheme(
+ self._soledad, gpgbinary=GPG_BINARY_PATH)
+ pgp.put_ascii_key(PRIVATE_KEY)
+ data = 'data'
+ privkey = pgp.get_key(ADDRESS, private=True)
+ signature = pgp.sign(data, privkey, detach=True)
+ pubkey = pgp.get_key(ADDRESS, private=False)
+ self.assertTrue(pgp.verify(data, pubkey, detached_sig=signature))
+
class KeyManagerKeyManagementTestCase(KeyManagerWithSoledadTestCase):
@@ -490,7 +500,7 @@ class KeyManagerCryptoTestCase(KeyManagerWithSoledadTestCase):
privkey = km.get_key(
ADDRESS, OpenPGPKey, private=True, fetch_remote=False)
# encrypt
- signdata = km.sign(self.RAW_DATA, privkey)
+ signdata = km.sign(self.RAW_DATA, privkey, detach=False)
self.assertNotEqual(self.RAW_DATA, signdata)
# get public key for verifying
pubkey = km.get_key(