Commit 1f04b96d5eb601fa84e97274d84136d78d6ab0e2

Authored by Christian Herdtweck
1 parent 826bee0b

crypto: layout how to best integrate crypto into code

Showing 1 changed file with 37 additions and 0 deletions
oletools/crypto.py
@@ -8,6 +8,43 @@ information on encryption in OLE files. @@ -8,6 +8,43 @@ information on encryption in OLE files.
8 Uses :py:mod:`msoffcrypto-tool` to decrypt if it is available. Otherwise 8 Uses :py:mod:`msoffcrypto-tool` to decrypt if it is available. Otherwise
9 decryption will fail with an ImportError. 9 decryption will fail with an ImportError.
10 10
  11 +Encryption/Write-Protection can be realized in many different ways. They range
  12 +from setting a single flag in an otherwise unprotected file to embedding a
  13 +regular file (e.g. xlsx) in an EncryptedStream inside an OLE file. That means
  14 +that (1) that lots of bad things are accesible even if no encryption password
  15 +is known, and (2) even basic attributes like the file type can change by
  16 +decryption. Therefore I suggest the following general routine to deal with
  17 +potentially encrypted files::
  18 +
  19 + def script_main_function(input_file, args):
  20 + '''Wrapper around main function to deal with encrypted files.'''
  21 + initial_stuff(input_file, args)
  22 + result = None
  23 + try:
  24 + result = do_your_thing_assuming_no_encryption(input_file)
  25 + if not crypto_is_encrypted(input_file):
  26 + return result
  27 + except Exception:
  28 + if not crypto_is_encrypted(input_file):
  29 + raise
  30 + decrypted_file = None
  31 + try:
  32 + decrypted_file = crypto.decrypt(input_file)
  33 + except Exception:
  34 + raise
  35 + finally: # clean up
  36 + try: # (maybe file was not yet created)
  37 + os.unlink(decrypted_file)
  38 + except Exception:
  39 + pass
  40 +
  41 +That means that caller code needs another wrapper around its main function. I
  42 +did try it another way first (a transparent on-demand unencrypt) but for the
  43 +above reasons I believe this is the better way. Also, non-top-level-code can
  44 +just assume that it works on unencrypted data and fail with an exception if
  45 +encrypted data makes its work impossible. No need to check `if is_encrypted()`
  46 +at the start of functions.
  47 +
11 .. seealso:: [MS-OFFCRYPTO] 48 .. seealso:: [MS-OFFCRYPTO]
12 .. seealso:: https://github.com/nolze/msoffcrypto-tool 49 .. seealso:: https://github.com/nolze/msoffcrypto-tool
13 50