tests/test_crypto_algorithms.py
author robin
Thu, 24 Oct 2019 15:53:59 +0100
changeset 4550 80dd9e83dad9
parent 4252 fe660f227cac
permissions -rw-r--r--
use assertEqual
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4252
fe660f227cac changes for release 3.3.0
robin
parents: 3721
diff changeset
     1
#copyright ReportLab Europe Limited. 2000-2016
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     2
#see license.txt for license details
4252
fe660f227cac changes for release 3.3.0
robin
parents: 3721
diff changeset
     3
__version__='3.3.0'
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     4
__doc__="""
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     5
This contains tests for the encryption algorithms.
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     6
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     7
The algorithmic approach is to take values from a known
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     8
readable-but-secured PDF file and put them in as assertions.
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
     9
If a platform varies in any way or we change an algorithm
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    10
by mistake, it should shriek at us.
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    11
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    12
It also generates a directory of files to scan by eyeball,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    13
with meaningful names to suggest the properties they have.
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    14
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    15
"""
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    16
import unittest
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    17
from reportlab.lib.testutils import setOutDir,makeSuiteForClasses, outputfile, printLocation
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    18
setOutDir(__name__)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    19
from reportlab.pdfgen.canvas import Canvas
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    20
from reportlab.lib.pdfencrypt import computeO, \
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    21
    computeU, hexText, unHexText, encryptionkey, encodePDF, \
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    22
    encryptCanvas
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    23
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    24
VERBOSE = 0
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    25
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    26
class EncryptionAlgorithmTestCase(unittest.TestCase):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    27
    """Acrobat algorithms.  Two specific cases known to work.
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    28
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    29
    We are dealing with 8 bit strings which may contain nasty
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    30
    escape characters, get trashed in FTP or editors etc.  Therefore
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    31
    I am using two explicit routines hexText and unHexText which
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    32
    provide a 'safe' way to represent strings as hex and which are
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    33
    not going to vary with Python versions"""
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    34
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    35
    def check0wnerHash40Bit(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    36
        "owner key calculation"
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    37
        ownerHash = computeO('userpass','ownerpass', revision=2)
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    38
        self.assertEqual(hexText(ownerHash),'<F86213EB0CED81F097947F3B343E34CAC8CA92CE8F6FEE2556FA31EC1FE968AF>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    39
        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    40
    def checkEncryptionKey40Bit(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    41
        userPass = 'userpass'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    42
        ownerHash = unHexText('<F86213EB0CED81F097947F3B343E34CAC8CA92CE8F6FEE2556FA31EC1FE968AF>')
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    43
        documentID = 'xxxxxxxxxxxxxxxx'        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    44
        permissions = -4
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    45
        encKey = encryptionkey(userPass, ownerHash, permissions, documentID, revision=2)
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    46
        self.assertEqual(hexText(encKey),'<7EBBD07A88>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    47
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    48
    def checkUserHash40Bit(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    49
        encKey = unHexText('<7EBBD07A88>')
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    50
        userHash = computeU(encKey, revision=2, documentId='xxxxxxxxxxxxxxxx')
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    51
        self.assertEqual(hexText(userHash),'<AA154131D8FA105317F7104D2001A345D78A3DEEFA3D85D032FC9B4B35DA72A0>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    52
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    53
    def checkEncryptString40Bit(self):
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    54
        self.assertEqual(hexText(encodePDF(unHexText('<3DC3EBDA71>'), 9, 0, 'anonymous')), '<57AC33DDEB5775982A>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    55
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    56
        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    57
    def check0wnerHash128Bit(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    58
        "owner key calculation"
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    59
        ownerHash = computeO('userpass','ownerpass', revision=3)
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    60
        self.assertEqual(hexText(ownerHash), '<68E5704AC779A5F0CD89704406587A52F25BF61CADC56A0F8DB6C4DB0052534D>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    61
        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    62
    def checkEncryptionKey128Bit(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    63
        userPass = 'userpass'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    64
        ownerHash = unHexText('<68E5704AC779A5F0CD89704406587A52F25BF61CADC56A0F8DB6C4DB0052534D>')
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    65
        documentID = 'xxxxxxxxxxxxxxxx'        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    66
        permissions = -4
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    67
        encKey = encryptionkey(userPass, ownerHash, permissions, documentID, revision=3)
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    68
        self.assertEqual(hexText(encKey), '<13DDE7585D9BE366C976DDD56AF541D1>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    69
        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    70
    def checkUserHash128Bit(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    71
        encKey = unHexText('<13DDE7585D9BE366C976DDD56AF541D1>')
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    72
        userHash = computeU(encKey, revision=3, documentId='xxxxxxxxxxxxxxxx')
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    73
        self.assertEqual(hexText(userHash), '<A9AE45CDE827FE0B7D6536267948836A00000000000000000000000000000000>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    74
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    75
    def checkEncryptString128Bit(self):
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    76
        self.assertEqual(hexText(encodePDF(unHexText('<3C0C5EBE0122D8EB2BDDF8A09FA8E29E>'),
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    77
                                 9,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    78
                                 0,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    79
                                 'anonymous')
4550
80dd9e83dad9 use assertEqual
robin
parents: 4252
diff changeset
    80
                       ),'<27FB3E943FCF61878B>')
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    81
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    82
class EyeballTestCase(unittest.TestCase):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    83
    "This makes a gaxillion self-explanatory files"
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    84
    def check40BitOptions(self):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    85
        userPass = 'userpass'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    86
        for canPrint in (0, 1):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    87
            for canModify in (0, 1):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    88
                for canCopy in (0, 1):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    89
                    for canAnnotate in (0, 1):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    90
                        for strength in (40, 128):
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    91
                            # work out a 4-char string to be a mnemonic for the options
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    92
                            p = m = c = a = 'x'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    93
                            if canPrint: p = 'P'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    94
                            if canModify: m = 'M'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    95
                            if canCopy: c = 'C'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    96
                            if canAnnotate: a = 'A'
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    97
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    98
                            filename = 'test_crypto_%03dbit_%s_%s%s%s%s.pdf' % (
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
    99
                                strength, userPass, p, m, c, a)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   100
                            import os
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   101
                            filepath = outputfile(filename)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   102
                            canv = Canvas(filepath)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   103
                            
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   104
                            canv.setFont('Helvetica', 24)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   105
                            canv.drawString(100,700, 'PDF Encryption test case')
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   106
                            canv.setFont('Helvetica', 16)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   107
                            canv.drawString(100, 675, 'Verify by looking at File - Document Info - Security')
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   108
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   109
                            canv.drawString(100, 600, 'open password = %s' % userPass)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   110
                            canv.drawString(100, 575, 'strength = %d buts' % strength)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   111
                            canv.drawString(100, 500, 'canPrint = %d' % canPrint)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   112
                            canv.drawString(100, 475, 'canModify = %d' % canModify)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   113
                            canv.drawString(100, 450, 'canCopy = %d' % canCopy)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   114
                            canv.drawString(100, 425, 'canAnnotate = %d' % canAnnotate)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   115
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   116
                            encryptCanvas(canv,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   117
                                          userPass,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   118
                                          canPrint=canPrint,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   119
                                          canModify=canModify,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   120
                                          canCopy=canCopy,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   121
                                          canAnnotate=canAnnotate,
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   122
                                          strength=strength)
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   123
                            
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   124
                            canv.save()
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   125
                            if VERBOSE: print('saved %s' % filepath)
3039
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   126
        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   127
def makeSuite():
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   128
    return unittest.TestSuite((
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   129
        unittest.makeSuite(EncryptionAlgorithmTestCase,'check'),
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   130
        unittest.makeSuite(EyeballTestCase,'check'),
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   131
        ))
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   132
        
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   133
if __name__=='__main__':
42ecfd4a9344 Moved encryption tests from rlextra.
jonas
parents:
diff changeset
   134
    unittest.TextTestRunner().run(makeSuite())