blob: 34ec781f45d2beab9a4ac13d65196930674a6dc5 [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
Thomas Fossatif4e1ca32024-08-16 16:01:31 +000016from pycose.algorithms import Es256, Es384, HMAC256
17
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020018from iatverifier.util import read_token_map, convert_map_to_token, read_keyfile
19from iatverifier.util import get_cose_alg_from_key
Mate Toth-Pal51b61982022-03-17 14:19:30 +010020from iatverifier.psa_iot_profile1_token_verifier import PSAIoTProfile1TokenVerifier
Tamas Ban1e7944a2022-07-04 13:09:03 +020021from iatverifier.psa_2_0_0_token_verifier import PSA_2_0_0_TokenVerifier
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010022from iatverifier.attest_token_verifier import AttestationTokenVerifier, VerifierConfiguration
23from iatverifier.cca_token_verifier import CCATokenVerifier, CCAPlatformTokenVerifier
Mate Toth-Pal51b61982022-03-17 14:19:30 +010024
25if __name__ == '__main__':
26 logging.basicConfig(level=logging.INFO)
27
Mate Toth-Pal6978f7c2022-03-30 14:38:55 +020028 token_verifiers = {
29 "PSA-IoT-Profile1-token": PSAIoTProfile1TokenVerifier,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010030 "CCA-token": CCATokenVerifier,
31 "CCA-plat-token": CCAPlatformTokenVerifier,
Tamas Ban1e7944a2022-07-04 13:09:03 +020032 "PSA-2.0.0-token": PSA_2_0_0_TokenVerifier,
Mate Toth-Pal6978f7c2022-03-30 14:38:55 +020033 }
34
Mate Toth-Pal51b61982022-03-17 14:19:30 +010035 parser = argparse.ArgumentParser()
36 parser.add_argument('source', help='Token source in YAML format')
37 parser.add_argument('-o', '--outfile',
38 help='''Output file for the compiled token. If this is not
39 specified, the token will be written to standard output.''')
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020040 parser.add_argument('-k', '--key',
Mate Toth-Pal51b61982022-03-17 14:19:30 +010041 help='''Path to the key in PEM format that should be used to
42 sign the token. If this is not specified, the token will be
43 unsigned.''')
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020044 parser.add_argument('--platform-key',
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010045 help='''Path to the key in PEM format that should be used to
46 sign the CCA platform token. If this is not specified,
47 the token will be unsigned.''')
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020048 parser.add_argument('--realm-key',
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010049 help='''Path to the key in PEM format that should be used to
50 sign the CCA Realm token. If this is not specified, the
51 token will be unsigned.''')
Mate Toth-Pal1527a3c2022-11-30 11:27:54 +010052 parser.add_argument('-m', '--method', choices=['sign', 'mac', 'raw'], default='sign',
53 help='''
54 Specify how this token is to be wrapped -- whether Sign1Message or
55 Mac0Message COSE structure is to be used. In case of 'raw' no COSE envelope is
56 added to the compiled token.
57 ''')
Mate Toth-Pal6978f7c2022-03-30 14:38:55 +020058 parser.add_argument('-t', '--token-type',
59 help='''The type of the Token.''',
60 choices=token_verifiers.keys(),
61 required=True)
Mate Toth-Pal51b61982022-03-17 14:19:30 +010062
63 args = parser.parse_args()
Mate Toth-Pal51b61982022-03-17 14:19:30 +010064
Mate Toth-Pal1527a3c2022-11-30 11:27:54 +010065 if args.method == 'mac':
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020066 METHOD = AttestationTokenVerifier.SIGN_METHOD_MAC0
Mate Toth-Pal1527a3c2022-11-30 11:27:54 +010067 elif args.method == 'raw':
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020068 if args.key:
Mate Toth-Pal51b61982022-03-17 14:19:30 +010069 raise ValueError('A keyfile cannot be specified with --raw.')
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020070 METHOD = AttestationTokenVerifier.SIGN_METHOD_RAW
Mate Toth-Pal1527a3c2022-11-30 11:27:54 +010071 elif args.method == 'sign':
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020072 METHOD = AttestationTokenVerifier.SIGN_METHOD_SIGN1
Mate Toth-Pal1527a3c2022-11-30 11:27:54 +010073 else:
74 assert False
Mate Toth-Pal51b61982022-03-17 14:19:30 +010075
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010076 configuration = VerifierConfiguration(strict=True, keep_going=False)
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020077
78 verifier_class = token_verifiers[args.token_type]
79 if verifier_class == PSAIoTProfile1TokenVerifier:
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020080 key = read_keyfile(args.key, METHOD)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010081 if METHOD == AttestationTokenVerifier.SIGN_METHOD_SIGN1:
Thomas Fossatif4e1ca32024-08-16 16:01:31 +000082 cose_alg = get_cose_alg_from_key(key, Es256)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010083 else:
Thomas Fossatif4e1ca32024-08-16 16:01:31 +000084 cose_alg = HMAC256
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020085 verifier = PSAIoTProfile1TokenVerifier(
86 method=METHOD,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010087 cose_alg=cose_alg,
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020088 signing_key=key,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010089 configuration=configuration)
90 elif verifier_class == CCATokenVerifier:
91 if METHOD != AttestationTokenVerifier.SIGN_METHOD_SIGN1:
92 logging.error('Only sign1 method is supported by this token type.\n\t')
93 sys.exit(1)
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020094 platform_token_key = read_keyfile(args.platform_key, METHOD)
95 realm_token_key = read_keyfile(args.realm_key, METHOD)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010096 realm_token_method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
97 platform_token_method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
Thomas Fossatif4e1ca32024-08-16 16:01:31 +000098 realm_token_cose_alg = get_cose_alg_from_key(realm_token_key, Es384)
99 platform_token_cose_alg = get_cose_alg_from_key(platform_token_key, Es384)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100100 verifier = CCATokenVerifier(
101 realm_token_method=realm_token_method,
102 realm_token_cose_alg=realm_token_cose_alg,
103 realm_token_key=realm_token_key,
104 platform_token_method=platform_token_method,
105 platform_token_cose_alg=platform_token_cose_alg,
106 platform_token_key=platform_token_key,
107 configuration=configuration)
108 elif verifier_class == CCAPlatformTokenVerifier:
Mate Toth-Pala8b46b12022-10-07 13:30:54 +0200109 key_checked = args.platform_key
110 key = read_keyfile(args.platform_key, METHOD)
Thomas Fossatif4e1ca32024-08-16 16:01:31 +0000111 cose_alg = get_cose_alg_from_key(key, Es384)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100112 verifier = CCAPlatformTokenVerifier(
113 method=AttestationTokenVerifier.SIGN_METHOD_SIGN1,
114 cose_alg=cose_alg,
115 signing_key=key,
116 configuration=configuration,
117 necessity=None)
Tamas Ban1e7944a2022-07-04 13:09:03 +0200118 elif verifier_class == PSA_2_0_0_TokenVerifier:
Mate Toth-Pala8b46b12022-10-07 13:30:54 +0200119 key_checked = args.key
120 key = read_keyfile(keyfile=args.key, method=METHOD)
Tamas Ban1e7944a2022-07-04 13:09:03 +0200121 if METHOD == AttestationTokenVerifier.SIGN_METHOD_SIGN1:
Thomas Fossatif4e1ca32024-08-16 16:01:31 +0000122 cose_alg = get_cose_alg_from_key(key, Es256)
Tamas Ban1e7944a2022-07-04 13:09:03 +0200123 else:
Thomas Fossatif4e1ca32024-08-16 16:01:31 +0000124 cose_alg = HMAC256
Tamas Ban1e7944a2022-07-04 13:09:03 +0200125 verifier = PSA_2_0_0_TokenVerifier(
126 method=METHOD,
127 cose_alg=cose_alg,
128 signing_key=key,
129 configuration=configuration)
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200130 else:
131 logging.error(f'Invalid token type:{verifier_class}\n\t')
132 sys.exit(1)
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100133 token_map = read_token_map(args.source)
134
135 if args.outfile:
136 with open(args.outfile, 'wb') as wfh:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200137 convert_map_to_token(
138 token_map,
139 verifier,
140 wfh,
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200141 name_as_key=True,
142 parse_raw_value=True)
Mate Toth-Pal51b61982022-03-17 14:19:30 +0100143 else:
144 with os.fdopen(sys.stdout.fileno(), 'wb') as wfh:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200145 convert_map_to_token(
146 token_map,
147 verifier,
148 wfh,
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200149 name_as_key=True,
150 parse_raw_value=True)