Skip to content

Commit

Permalink
Update based on the spec (RC4 CryptoAPI Encryption Header)
Browse files Browse the repository at this point in the history
  • Loading branch information
nolze committed May 23, 2024
1 parent d6832ff commit f144612
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 61 deletions.
24 changes: 23 additions & 1 deletion msoffcrypto/format/common.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import io
import logging
from struct import unpack

Expand All @@ -13,7 +14,6 @@ def _parse_encryptionheader(blob):
(algId,) = unpack("<I", blob.read(4))
(algIdHash,) = unpack("<I", blob.read(4))
(keySize,) = unpack("<I", blob.read(4))
keySize = 40 if keySize == 0 else keySize
(providerType,) = unpack("<I", blob.read(4))
(reserved1,) = unpack("<I", blob.read(4))
(reserved2,) = unpack("<I", blob.read(4))
Expand Down Expand Up @@ -50,3 +50,25 @@ def _parse_encryptionverifier(blob, algorithm):
"encryptedVerifierHash": encryptedVerifierHash,
}
return verifier


def _parse_header_RC4CryptoAPI(encryptionHeader):
flags = encryptionHeader.read(4)
(headerSize,) = unpack("<I", encryptionHeader.read(4))
logger.debug(headerSize)
blob = io.BytesIO(encryptionHeader.read(headerSize))
header = _parse_encryptionheader(blob)
logger.debug(header)
# NOTE: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/36cfb17f-9b15-4a9b-911a-f401f60b3991
keySize = 0x00000028 if header["keySize"] == 0 else header["keySize"]

blob = io.BytesIO(encryptionHeader.read())
verifier = _parse_encryptionverifier(blob, "RC4") # TODO: Fix (cf. ooxml.py)
logger.debug(verifier)
info = {
"salt": verifier["salt"],
"keySize": keySize,
"encryptedVerifier": verifier["encryptedVerifier"],
"encryptedVerifierHash": verifier["encryptedVerifierHash"],
}
return info
21 changes: 1 addition & 20 deletions msoffcrypto/format/doc97.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from msoffcrypto import exceptions
from msoffcrypto.format import base
from msoffcrypto.format.common import _parse_encryptionheader, _parse_encryptionverifier
from msoffcrypto.format.common import _parse_header_RC4CryptoAPI
from msoffcrypto.method.rc4 import DocumentRC4
from msoffcrypto.method.rc4_cryptoapi import DocumentRC4CryptoAPI

Expand Down Expand Up @@ -258,25 +258,6 @@ def _parse_header_RC4(encryptionHeader):
return info


def _parse_header_RC4CryptoAPI(encryptionHeader):
flags = encryptionHeader.read(4)
(headerSize,) = unpack("<I", encryptionHeader.read(4))
logger.debug(headerSize)
blob = io.BytesIO(encryptionHeader.read(headerSize))
header = _parse_encryptionheader(blob)
logger.debug(header)
blob = io.BytesIO(encryptionHeader.read())
verifier = _parse_encryptionverifier(blob, "RC4") # TODO: Fix (cf. ooxml.py)
logger.debug(verifier)
info = {
"salt": verifier["salt"],
"keySize": header["keySize"],
"encryptedVerifier": verifier["encryptedVerifier"],
"encryptedVerifierHash": verifier["encryptedVerifierHash"],
}
return info


class Doc97File(base.BaseOfficeFile):
"""Return a MS-DOC file object.
Expand Down
21 changes: 1 addition & 20 deletions msoffcrypto/format/ppt97.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from msoffcrypto import exceptions
from msoffcrypto.format import base
from msoffcrypto.format.common import _parse_encryptionheader, _parse_encryptionverifier
from msoffcrypto.format.common import _parse_header_RC4CryptoAPI
from msoffcrypto.method.rc4_cryptoapi import DocumentRC4CryptoAPI

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -502,25 +502,6 @@ def construct_persistobjectdirectory(data):
return persistobjectdirectory


def _parse_header_RC4CryptoAPI(encryptionInfo):
flags = encryptionInfo.read(4)
(headerSize,) = unpack("<I", encryptionInfo.read(4))
logger.debug(headerSize)
blob = io.BytesIO(encryptionInfo.read(headerSize))
header = _parse_encryptionheader(blob)
logger.debug(header)
blob = io.BytesIO(encryptionInfo.read())
verifier = _parse_encryptionverifier(blob, "RC4") # TODO: Fix (cf. ooxml.py)
logger.debug(verifier)
info = {
"salt": verifier["salt"],
"keySize": header["keySize"],
"encryptedVerifier": verifier["encryptedVerifier"],
"encryptedVerifierHash": verifier["encryptedVerifierHash"],
}
return info


class Ppt97File(base.BaseOfficeFile):
"""Return a MS-PPT file object.
Expand Down
21 changes: 1 addition & 20 deletions msoffcrypto/format/xls97.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from msoffcrypto import exceptions
from msoffcrypto.format import base
from msoffcrypto.format.common import _parse_encryptionheader, _parse_encryptionverifier
from msoffcrypto.format.common import _parse_header_RC4CryptoAPI
from msoffcrypto.method.rc4 import DocumentRC4
from msoffcrypto.method.rc4_cryptoapi import DocumentRC4CryptoAPI
from msoffcrypto.method.xor_obfuscation import DocumentXOR
Expand Down Expand Up @@ -386,25 +386,6 @@ def _parse_header_RC4(encryptionInfo):
return info


def _parse_header_RC4CryptoAPI(encryptionInfo):
flags = encryptionInfo.read(4)
(headerSize,) = unpack("<I", encryptionInfo.read(4))
logger.debug(headerSize)
blob = io.BytesIO(encryptionInfo.read(headerSize))
header = _parse_encryptionheader(blob)
logger.debug(header)
blob = io.BytesIO(encryptionInfo.read())
verifier = _parse_encryptionverifier(blob, "RC4") # TODO: Fix (cf. ooxml.py)
logger.debug(verifier)
info = {
"salt": verifier["salt"],
"keySize": header["keySize"],
"encryptedVerifier": verifier["encryptedVerifier"],
"encryptedVerifierHash": verifier["encryptedVerifierHash"],
}
return info


class _BIFFStream:
def __init__(self, data):
self.data = data
Expand Down

0 comments on commit f144612

Please sign in to comment.