Coverage for aiocoap/cli/keygen.py: 22%
32 statements
« prev ^ index » next coverage.py v7.6.8, created at 2024-11-28 12:34 +0000
« prev ^ index » next coverage.py v7.6.8, created at 2024-11-28 12:34 +0000
1# SPDX-FileCopyrightText: Christian Amsüss and the aiocoap contributors
2#
3# SPDX-License-Identifier: MIT
5"""A tool for creating key pairs for use in credentials
7Note that this tool operates on secrets stored in unencrypted files, protectd
8by restrictively set file system permissions. While this is common practice
9with many tools in the UNIX world, it might be surprising to users coming from
10multi-factor environments."""
12import aiocoap.meta
13import aiocoap.defaults
15import argparse
16from pathlib import Path
19def build_parser():
20 p = argparse.ArgumentParser(description=__doc__)
21 p.add_argument(
22 "--version", action="version", version="%(prog)s " + aiocoap.meta.version
23 )
25 subparsers = p.add_subparsers(required=True, dest="subcommand")
26 generate = subparsers.add_parser(
27 "generate",
28 help="This generates an"
29 " EDHOC key, stores it in a key file that is only readable by the"
30 " user, and prints the corresponding public key information in a way"
31 " suitable for inclusion in credentials maps.",
32 )
33 generate.add_argument("keyfile", help="File to store the secret key in", type=Path)
34 generate.add_argument(
35 "--kid", help="Hexadecimal key identifier", type=bytes.fromhex
36 )
37 generate.add_argument("--subject", help="Text placed in the CCS", type=str)
39 return p
42def main():
43 p = build_parser()
45 args = p.parse_args()
47 missmods = aiocoap.defaults.oscore_missing_modules()
48 if missmods:
49 p.error(
50 f"Dependencies missing, consider installing aiocoap as \"aiocoap[oscore]\" or \"aiocoap[all]\". Missing modules: {', '.join(missmods)}"
51 )
53 from aiocoap import edhoc
54 import cbor2
55 import cbor_diag
57 if args.subcommand == "generate":
58 try:
59 key = edhoc.CoseKeyForEdhoc.generate(args.keyfile)
60 except FileExistsError:
61 raise p.error("Output file already exists")
63 public = key.as_ccs(args.kid, args.subject)
64 print(cbor_diag.cbor2diag(cbor2.dumps(public, canonical=True), pretty=False))
65 else:
66 raise RuntimeError(f"Unimplemented subcommand {args.subcommand=}")
69if __name__ == "__main__":
70 main()