Commit 4e1f626d4576af5577f072273a5efaad2d30fcf0
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 | ... | ... |