"""
import argparse
+from pathlib import Path
-import asn1
+from asn1crypto.cms import ContentInfo, AuthEnvelopedData, EnvelopedData
# Parse command-line arguments
#
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
-parser.add_argument("-d", "--data", metavar="FILE",
+parser.add_argument("-d", "--data", metavar="FILE", type=Path,
help="Write detached data (without envelope) to FILE")
-parser.add_argument("-e", "--envelope", metavar="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", help="Input envelope file")
+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"
-# Create decoder
+# Read input envelope
#
-decoder = asn1.Decoder()
-with open(args.file, mode="rb") as fh:
- decoder.start(fh.read())
+envelope = ContentInfo.load(args.file.read_bytes())
-# Create encoder
+# Locate encrypted content info
#
-encoder = asn1.Encoder()
-encoder.start()
+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 data
+# Detach encrypted content 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")
+data = encinfo["encrypted_content"]
+del encinfo["encrypted_content"]
# Write envelope (without data), if applicable
#
if args.envelope:
- with open(args.envelope, mode=outmode) as fh:
- fh.write(envelope)
+ with args.envelope.open(mode=outmode) as fh:
+ fh.write(envelope.dump())
# Write data (without envelope), if applicable
#
if args.data:
- with open(args.data, mode=outmode) as fh:
- fh.write(data)
+ with args.data.open(mode=outmode) as fh:
+ fh.write(data.contents)