blob: 2783cf6369f478e56680a225f99ccb25731779d5 [file] [log] [blame]
Mate Toth-Pal51b61982022-03-17 14:19:30 +01001#!/usr/bin/env python3
2#-------------------------------------------------------------------------------
3# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7#-------------------------------------------------------------------------------
8
Mate Toth-Palb9057ff2022-04-29 16:03:21 +02009"""CLI tool for compiling token from a yaml file"""
10
Mate Toth-Pal51b61982022-03-17 14:19:30 +010011import argparse
12import logging
13import os
14import sys
15
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020016from iatverifier.util import read_token_map, convert_map_to_token, read_keyfile
17from iatverifier.util import get_cose_alg_from_key
Mate Toth-Pal51b61982022-03-17 14:19:30 +010018from iatverifier.psa_iot_profile1_token_verifier import PSAIoTProfile1TokenVerifier
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010019from iatverifier.attest_token_verifier import AttestationTokenVerifier, VerifierConfiguration
20from iatverifier.cca_token_verifier import CCATokenVerifier, CCAPlatformTokenVerifier
Mate Toth-Pal51b61982022-03-17 14:19:30 +010021
22if __name__ == '__main__':
23 logging.basicConfig(level=logging.INFO)
24
Mate Toth-Pal6978f7c2022-03-30 14:38:55 +020025 token_verifiers = {
26 "PSA-IoT-Profile1-token": PSAIoTProfile1TokenVerifier,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010027 "CCA-token": CCATokenVerifier,
28 "CCA-plat-token": CCAPlatformTokenVerifier,
Mate Toth-Pal6978f7c2022-03-30 14:38:55 +020029 }
30
Mate Toth-Pal51b61982022-03-17 14:19:30 +010031 parser = argparse.ArgumentParser()
32 parser.add_argument('source', help='Token source in YAML format')
33 parser.add_argument('-o', '--outfile',
34 help='''Output file for the compiled token. If this is not
35 specified, the token will be written to standard output.''')
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010036 parser.add_argument('--psa-iot-profile1-keyfile',
Mate Toth-Pal51b61982022-03-17 14:19:30 +010037 help='''Path to the key in PEM format that should be used to
38 sign the token. If this is not specified, the token will be
39 unsigned.''')
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010040 parser.add_argument('--cca-platform-token-keyfile',
41 help='''Path to the key in PEM format that should be used to
42 sign the CCA platform token. If this is not specified,
43 the token will be unsigned.''')
44 parser.add_argument('--cca-realm-token-keyfile',
45 help='''Path to the key in PEM format that should be used to
46 sign the CCA Realm token. If this is not specified, the
47 token will be unsigned.''')
Mate Toth-Pal51b61982022-03-17 14:19:30 +010048 group = parser.add_mutually_exclusive_group()
Mate Toth-Palbdb475e2022-04-24 12:11:22 +020049 parser.add_argument('-a', '--add-protected-header', action='store_true',
50 help='''
51 Add protected header to the COSE wrapper.
52 ''')
Mate Toth-Pal51b61982022-03-17 14:19:30 +010053 group.add_argument('-r', '--raw', action='store_true',
54 help='''Generate raw CBOR and do not create a signature
55 or COSE wrapper.''')
56 group.add_argument('-m', '--hmac', action='store_true',
57 help='''Generate a token wrapped in a Mac0 rather than
58 Sign1 COSE structure.''')
Mate Toth-Pal6978f7c2022-03-30 14:38:55 +020059 parser.add_argument('-t', '--token-type',
60 help='''The type of the Token.''',
61 choices=token_verifiers.keys(),
62 required=True)
Mate Toth-Pal51b61982022-03-17 14:19:30 +010063
64 args = parser.parse_args()
Mate Toth-Pal51b61982022-03-17 14:19:30 +010065
Mate Toth-Pal51b61982022-03-17 14:19:30 +010066 if args.hmac:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020067 METHOD = AttestationTokenVerifier.SIGN_METHOD_MAC0
Mate Toth-Pal51b61982022-03-17 14:19:30 +010068 elif args.raw:
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010069 if args.psa_iot_profile1_keyfile:
Mate Toth-Pal51b61982022-03-17 14:19:30 +010070 raise ValueError('A keyfile cannot be specified with --raw.')
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020071 METHOD = AttestationTokenVerifier.SIGN_METHOD_RAW
Mate Toth-Pal51b61982022-03-17 14:19:30 +010072 else:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020073 METHOD = AttestationTokenVerifier.SIGN_METHOD_SIGN1
Mate Toth-Pal51b61982022-03-17 14:19:30 +010074
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010075 configuration = VerifierConfiguration(strict=True, keep_going=False)
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020076
77 verifier_class = token_verifiers[args.token_type]
78 if verifier_class == PSAIoTProfile1TokenVerifier:
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010079 key = read_keyfile(args.psa_iot_profile1_keyfile, METHOD)
80 if METHOD == AttestationTokenVerifier.SIGN_METHOD_SIGN1:
81 cose_alg = get_cose_alg_from_key(
82 key,
83 AttestationTokenVerifier.COSE_ALG_ES256)
84 else:
85 cose_alg = AttestationTokenVerifier.COSE_ALG_HS256
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020086 verifier = PSAIoTProfile1TokenVerifier(
87 method=METHOD,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010088 cose_alg=cose_alg,
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020089 signing_key=key,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010090 configuration=configuration)
91 elif verifier_class == CCATokenVerifier:
92 if METHOD != AttestationTokenVerifier.SIGN_METHOD_SIGN1:
93 logging.error('Only sign1 method is supported by this token type.\n\t')
94 sys.exit(1)
95 platform_token_key = read_keyfile(args.cca_platform_token_keyfile, METHOD)
96 realm_token_key = read_keyfile(args.cca_realm_token_keyfile, METHOD)
97 realm_token_method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
98 platform_token_method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
99 realm_token_cose_alg = get_cose_alg_from_key(
100 realm_token_key,
101 AttestationTokenVerifier.COSE_ALG_ES384)
102 platform_token_cose_alg = get_cose_alg_from_key(
103 platform_token_key,
104 AttestationTokenVerifier.COSE_ALG_ES384)
105 verifier = CCATokenVerifier(
106 realm_token_method=realm_token_method,
107 realm_token_cose_alg=realm_token_cose_alg,
108 realm_token_key=realm_token_key,
109 platform_token_method=platform_token_method,
110 platform_token_cose_alg=platform_token_cose_alg,
111 platform_token_key=platform_token_key,
112 configuration=configuration)
113 elif verifier_class == CCAPlatformTokenVerifier:
114 key_checked = args.cca_platform_token_keyfile
115 key = read_keyfile(args.cca_platform_token_keyfile, METHOD)
116 cose_alg = get_cose_alg_from_key(key, AttestationTokenVerifier.COSE_ALG_ES384)
117 verifier = CCAPlatformTokenVerifier(
118 method=AttestationTokenVerifier.SIGN_METHOD_SIGN1,
119 cose_alg=cose_alg,
120 signing_key=key,
121 configuration=configuration,
122 necessity=None)
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200123 else:
124 logging.error(f'Invalid token type:{verifier_class}\n\t')
125 sys.exit(1)
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100126 token_map = read_token_map(args.source)
127
128 if args.outfile:
129 with open(args.outfile, 'wb') as wfh:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200130 convert_map_to_token(
131 token_map,
132 verifier,
133 wfh,
134 add_p_header=args.add_protected_header,
135 name_as_key=True,
136 parse_raw_value=True)
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100137 else:
138 with os.fdopen(sys.stdout.fileno(), 'wb') as wfh:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200139 convert_map_to_token(
140 token_map,
141 verifier,
142 wfh,
143 add_p_header=args.add_protected_header,
144 name_as_key=True,
145 parse_raw_value=True)