diff --git a/mayan/apps/django_gpg/managers.py b/mayan/apps/django_gpg/managers.py index 89c5100308..a84a3d45b2 100644 --- a/mayan/apps/django_gpg/managers.py +++ b/mayan/apps/django_gpg/managers.py @@ -10,7 +10,7 @@ import gnupg from django.db import models from .classes import KeyStub -from .exceptions import KeyFetchingError +from .exceptions import KeyDoesNotExist, KeyFetchingError from .literals import KEY_TYPE_PUBLIC, KEY_TYPE_SECRET from .settings import setting_gpg_path, setting_keyserver @@ -62,3 +62,27 @@ class KeyManager(models.Manager): def private_keys(self): return self.filter(key_type=KEY_TYPE_SECRET) + + def verify_file(self, file_object, signature_file=None): + temporary_directory = tempfile.mkdtemp() + + gpg = gnupg.GPG( + gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value + ) + + verify_result = gpg.verify_file(file=file_object) + + if 'no public key' in verify_result.status: + # File is signed but we need the key for full verification + try: + key = self.get(fingerprint__endswith=verify_result.key_id) + except self.model.DoesNotExist: + raise KeyDoesNotExist('Signature key is not found in keyring') + else: + gpg.import_keys(key_data=key.key_data) + file_object.seek(0) + verify_result = gpg.verify_file(file=file_object) + + shutil.rmtree(temporary_directory) + + return verify_result diff --git a/mayan/apps/django_gpg/migrations/0005_remove_key_key_id.py b/mayan/apps/django_gpg/migrations/0005_remove_key_key_id.py index 6acb9c702e..7f6b0718aa 100644 --- a/mayan/apps/django_gpg/migrations/0005_remove_key_key_id.py +++ b/mayan/apps/django_gpg/migrations/0005_remove_key_key_id.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import migrations, models +from django.db import migrations class Migration(migrations.Migration): diff --git a/mayan/apps/django_gpg/tests/contrib/test_files/test_file.txt.gpg b/mayan/apps/django_gpg/tests/contrib/test_files/test_file.txt.gpg new file mode 100644 index 0000000000..97c77a242b Binary files /dev/null and b/mayan/apps/django_gpg/tests/contrib/test_files/test_file.txt.gpg differ diff --git a/mayan/apps/django_gpg/tests/literals.py b/mayan/apps/django_gpg/tests/literals.py index 0936a239d1..d37e28ba1f 100644 --- a/mayan/apps/django_gpg/tests/literals.py +++ b/mayan/apps/django_gpg/tests/literals.py @@ -1,11 +1,8 @@ from __future__ import unicode_literals -TEST_GPG_HOME = '/tmp/test_gpg_home' -TEST_KEY_FINGERPRINT = '6A24574E0A35004CDDFD22704125E9C571F378AC' -TEST_KEYSERVERS = ['pool.sks-keyservers.net'] +import os -TEST_SEARCH_UID = 'Roberto Rosario' -TEST_SEARCH_FINGERPRINT = '607138F1AECC5A5CA31CB7715F3F7F75D210724D' +from django.conf import settings TEST_KEY_DATA = '''-----BEGIN PGP PRIVATE KEY BLOCK----- Version: GnuPG v1 @@ -69,3 +66,14 @@ h4oCbUV5JHhOyB+89Y1w8haFU9LrgOER2kXff1xU6wMfLdcO5ApV/sRJcNdYL7Cg TEST_KEY_ID = '4125E9C571F378AC' TEST_KEY_FINGERPRINT = '6A24574E0A35004CDDFD22704125E9C571F378AC' +TEST_KEY_PASSPHRASE = 'testpassphrase' + +TEST_KEYSERVERS = ['pool.sks-keyservers.net'] + +TEST_SEARCH_UID = 'Roberto Rosario' +TEST_SEARCH_FINGERPRINT = '607138F1AECC5A5CA31CB7715F3F7F75D210724D' + +TEST_SIGNED_FILE = os.path.join( + settings.BASE_DIR, 'mayan', 'apps', 'django_gpg', 'tests', 'contrib', + 'test_files', 'test_file.txt.gpg' +) diff --git a/mayan/apps/django_gpg/tests/test_models.py b/mayan/apps/django_gpg/tests/test_models.py index bcb97cda34..a4fd8426db 100644 --- a/mayan/apps/django_gpg/tests/test_models.py +++ b/mayan/apps/django_gpg/tests/test_models.py @@ -2,11 +2,12 @@ from __future__ import unicode_literals from django.test import TestCase +from ..exceptions import KeyDoesNotExist from ..models import Key from .literals import ( TEST_KEY_DATA, TEST_KEY_FINGERPRINT, TEST_SEARCH_FINGERPRINT, - TEST_SEARCH_UID + TEST_SEARCH_UID, TEST_SIGNED_FILE ) @@ -31,3 +32,17 @@ class KeyTestCase(TestCase): self.assertEqual(Key.objects.all().count(), 1) self.assertEqual(Key.objects.first().fingerprint, TEST_SEARCH_FINGERPRINT) + + def test_embedded_verification_no_key(self): + with open(TEST_SIGNED_FILE) as signed_file: + with self.assertRaises(KeyDoesNotExist): + Key.objects.verify_file(signed_file) + + def test_embedded_verification_with_key(self): + Key.objects.create(key_data=TEST_KEY_DATA) + + with open(TEST_SIGNED_FILE) as signed_file: + result = Key.objects.verify_file(signed_file) + + self.assertTrue(result) + self.assertEqual(result.fingerprint, TEST_KEY_FINGERPRINT)