#!/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)