mirror of
https://github.com/ipxe/ipxe
synced 2025-12-09 10:50:28 +03:00
The python-asn1 documentation indicates that end of file may be detected either by obtaining a True value from .eof() or by obtaining a None value from .peek(), but does not mention any way to detect the end of a constructed tag (rather than the end of the overall file). We currently use .eof() to detect the end of a constructed tag, based on the observed behaviour of the library. The behaviour of .eof() changed between versions 2.8.0 and 3.0.0, such that .eof() no longer returns True at the end of a constructed tag. Switch to testing for a None value returned from .peek() to determine when we have reached the end of a constructed tag, since this works on both newer and older versions. Continue to treat .eof() as a necessary but not sufficient condition for reaching the overall end of file, to maintain compatibility with older versions. Signed-off-by: Michael Brown <mcb30@ipxe.org>
80 lines
2.1 KiB
Python
Executable File
80 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
"""Detach CMS encrypted data.
|
|
|
|
Detach encrypted data from a CMS envelopedData or authEnvelopedData
|
|
message into a separate file.
|
|
"""
|
|
|
|
import argparse
|
|
|
|
import asn1
|
|
|
|
# Parse command-line arguments
|
|
#
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
)
|
|
parser.add_argument("-d", "--data", metavar="FILE",
|
|
help="Write detached data (without envelope) to FILE")
|
|
parser.add_argument("-e", "--envelope", metavar="FILE",
|
|
help="Write envelope (without data) to FILE")
|
|
parser.add_argument("-o", "--overwrite", action="store_true",
|
|
help="Overwrite output files")
|
|
parser.add_argument("file", help="Input envelope file")
|
|
args = parser.parse_args()
|
|
if args.data is None and args.envelope is None:
|
|
parser.error("at least one of --data and --envelope is required")
|
|
outmode = "wb" if args.overwrite else "xb"
|
|
|
|
# Create decoder
|
|
#
|
|
decoder = asn1.Decoder()
|
|
with open(args.file, mode="rb") as fh:
|
|
decoder.start(fh.read())
|
|
|
|
# Create encoder
|
|
#
|
|
encoder = asn1.Encoder()
|
|
encoder.start()
|
|
|
|
# Detach encrypted data
|
|
#
|
|
data = None
|
|
datastack = [
|
|
asn1.Numbers.Sequence, 0, asn1.Numbers.Sequence, asn1.Numbers.Sequence
|
|
]
|
|
stack = []
|
|
while stack or not decoder.eof():
|
|
tag = decoder.peek()
|
|
if tag is None:
|
|
encoder.leave()
|
|
decoder.leave()
|
|
stack.pop()
|
|
elif tag.typ == asn1.Types.Constructed:
|
|
encoder.enter(nr=tag.nr, cls=tag.cls)
|
|
decoder.enter()
|
|
stack.append(tag.nr)
|
|
else:
|
|
(tag, value) = decoder.read()
|
|
if stack == datastack and tag.nr == 0:
|
|
data = value
|
|
else:
|
|
encoder.write(value, nr=tag.nr, cls=tag.cls)
|
|
envelope = encoder.output()
|
|
if data is None:
|
|
parser.error("Input file does not contain any encrypted data")
|
|
|
|
# Write envelope (without data), if applicable
|
|
#
|
|
if args.envelope:
|
|
with open(args.envelope, mode=outmode) as fh:
|
|
fh.write(envelope)
|
|
|
|
# Write data (without envelope), if applicable
|
|
#
|
|
if args.data:
|
|
with open(args.data, mode=outmode) as fh:
|
|
fh.write(data)
|