Files
ipxe/contrib/crypto/cmsdetach
Michael Brown 96dfaa7e7a [crypto] Switch to using python-asn1crypto instead of python-asn1
Version 3.0.0 of python-asn1 has a serious defect that causes it to
generate invalid DER.

Fix by switching to the asn1crypto module, which also allows for
simpler code to be used.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-11 12:40:22 +01:00

62 lines
1.8 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
from pathlib import Path
from asn1crypto.cms import ContentInfo, AuthEnvelopedData, EnvelopedData
# Parse command-line arguments
#
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-d", "--data", metavar="FILE", type=Path,
help="Write detached data (without envelope) to FILE")
parser.add_argument("-e", "--envelope", metavar="FILE", type=Path,
help="Write envelope (without data) to FILE")
parser.add_argument("-o", "--overwrite", action="store_true",
help="Overwrite output files")
parser.add_argument("file", type=Path, 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"
# Read input envelope
#
envelope = ContentInfo.load(args.file.read_bytes())
# Locate encrypted content info
#
content = envelope["content"]
if type(content) is AuthEnvelopedData:
encinfo = content["auth_encrypted_content_info"]
elif type(content) is EnvelopedData:
encinfo = content["encrypted_content_info"]
else:
parser.error("Input file does not contain any encrypted data")
# Detach encrypted content data
#
data = encinfo["encrypted_content"]
del encinfo["encrypted_content"]
# Write envelope (without data), if applicable
#
if args.envelope:
with args.envelope.open(mode=outmode) as fh:
fh.write(envelope.dump())
# Write data (without envelope), if applicable
#
if args.data:
with args.data.open(mode=outmode) as fh:
fh.write(data.contents)