Add embedded file signature verification.
This commit is contained in:
@@ -10,7 +10,7 @@ import gnupg
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from .classes import KeyStub
|
from .classes import KeyStub
|
||||||
from .exceptions import KeyFetchingError
|
from .exceptions import KeyDoesNotExist, KeyFetchingError
|
||||||
from .literals import KEY_TYPE_PUBLIC, KEY_TYPE_SECRET
|
from .literals import KEY_TYPE_PUBLIC, KEY_TYPE_SECRET
|
||||||
from .settings import setting_gpg_path, setting_keyserver
|
from .settings import setting_gpg_path, setting_keyserver
|
||||||
|
|
||||||
@@ -62,3 +62,27 @@ class KeyManager(models.Manager):
|
|||||||
|
|
||||||
def private_keys(self):
|
def private_keys(self):
|
||||||
return self.filter(key_type=KEY_TYPE_SECRET)
|
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
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|||||||
Binary file not shown.
@@ -1,11 +1,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
TEST_GPG_HOME = '/tmp/test_gpg_home'
|
import os
|
||||||
TEST_KEY_FINGERPRINT = '6A24574E0A35004CDDFD22704125E9C571F378AC'
|
|
||||||
TEST_KEYSERVERS = ['pool.sks-keyservers.net']
|
|
||||||
|
|
||||||
TEST_SEARCH_UID = 'Roberto Rosario'
|
from django.conf import settings
|
||||||
TEST_SEARCH_FINGERPRINT = '607138F1AECC5A5CA31CB7715F3F7F75D210724D'
|
|
||||||
|
|
||||||
TEST_KEY_DATA = '''-----BEGIN PGP PRIVATE KEY BLOCK-----
|
TEST_KEY_DATA = '''-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
Version: GnuPG v1
|
Version: GnuPG v1
|
||||||
@@ -69,3 +66,14 @@ h4oCbUV5JHhOyB+89Y1w8haFU9LrgOER2kXff1xU6wMfLdcO5ApV/sRJcNdYL7Cg
|
|||||||
|
|
||||||
TEST_KEY_ID = '4125E9C571F378AC'
|
TEST_KEY_ID = '4125E9C571F378AC'
|
||||||
TEST_KEY_FINGERPRINT = '6A24574E0A35004CDDFD22704125E9C571F378AC'
|
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'
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from ..exceptions import KeyDoesNotExist
|
||||||
from ..models import Key
|
from ..models import Key
|
||||||
|
|
||||||
from .literals import (
|
from .literals import (
|
||||||
TEST_KEY_DATA, TEST_KEY_FINGERPRINT, TEST_SEARCH_FINGERPRINT,
|
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.all().count(), 1)
|
||||||
self.assertEqual(Key.objects.first().fingerprint, TEST_SEARCH_FINGERPRINT)
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user