summaryrefslogtreecommitdiffstats
path: root/contrib/crypto/cmsdetach
diff options
context:
space:
mode:
authorSimon Rettberg2026-01-28 12:53:53 +0100
committerSimon Rettberg2026-01-28 12:53:53 +0100
commit8e82785c584dc13e20f9229decb95bd17bbe9cd1 (patch)
treea8b359e59196be5b2e3862bed189107f4bc9975f /contrib/crypto/cmsdetach
parentMerge branch 'master' into openslx (diff)
parent[prefix] Make unlzma.S compatible with 386 class CPUs (diff)
downloadipxe-openslx.tar.gz
ipxe-openslx.tar.xz
ipxe-openslx.zip
Merge branch 'master' into openslxopenslx
Diffstat (limited to 'contrib/crypto/cmsdetach')
-rwxr-xr-xcontrib/crypto/cmsdetach61
1 files changed, 61 insertions, 0 deletions
diff --git a/contrib/crypto/cmsdetach b/contrib/crypto/cmsdetach
new file mode 100755
index 000000000..a48d30c67
--- /dev/null
+++ b/contrib/crypto/cmsdetach
@@ -0,0 +1,61 @@
+#!/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)