Commit 4e1f626d4576af5577f072273a5efaad2d30fcf0

Authored by Christian Herdtweck
1 parent 0dfa259f

crypto: use msoffcrypto's is_encrypted if possible

There were cases where our own test of byte 0x15 of SummaryInformation
stream was incorrect. So leave test to the professionals ;-)
Showing 1 changed file with 33 additions and 1 deletions
oletools/crypto.py
... ... @@ -197,8 +197,40 @@ def is_encrypted(some_file):
197 197 :returns: True if (and only if) the file contains encrypted content
198 198 """
199 199 log.debug('is_encrypted')
  200 +
  201 + # ask msoffcrypto if possible
  202 + if check_msoffcrypto():
  203 + log.debug('Checking for encryption using msoffcrypto')
  204 + file_handle = None
  205 + file_pos = None
  206 + try:
  207 + if isinstance(some_file, OleFileIO):
  208 + # TODO: hacky, replace once msoffcrypto-tools accepts OleFileIO
  209 + file_handle = some_file.fp
  210 + file_pos = file_handle.tell()
  211 + file_handle.seek(0)
  212 + else:
  213 + file_handle = open(some_file, 'rb')
  214 +
  215 + return msoffcrypto.OfficeFile(file_handle).is_encrypted()
  216 +
  217 + except Exception as exc:
  218 + log.warning('msoffcrypto failed to interpret file {} or determine '
  219 + 'whether it is encrypted: {}'
  220 + .format(file_handle.name, exc))
  221 +
  222 + finally:
  223 + try:
  224 + if file_pos is not None: # input was OleFileIO
  225 + file_handle.seek(file_pos)
  226 + else: # input was file name
  227 + file_handle.close()
  228 + except Exception as exc:
  229 + log.warning('Ignoring error during clean up: {}'.format(exc))
  230 +
  231 + # if that failed, try ourselves with older and less accurate code
200 232 if isinstance(some_file, OleFileIO):
201   - return _is_encrypted_ole(some_file) # assume it is OleFileIO
  233 + return _is_encrypted_ole(some_file)
202 234 if zipfile.is_zipfile(some_file):
203 235 return _is_encrypted_zip(some_file)
204 236 # otherwise assume it is the name of an ole file
... ...