blob: 8193b848161c76ca1a408d7b30ec4a31d5f94c5d [file] [log] [blame]
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +02001# -----------------------------------------------------------------------------
2# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
Mate Toth-Pal51b61982022-03-17 14:19:30 +01003#
4# SPDX-License-Identifier: BSD-3-Clause
5#
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +02006# -----------------------------------------------------------------------------
Mate Toth-Pal51b61982022-03-17 14:19:30 +01007
Mate Toth-Palb9057ff2022-04-29 16:03:21 +02008"""CLI script for verifying an IAT."""
9
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020010import argparse
11import json
12import logging
13import sys
14
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020015from iatverifier.util import recursive_bytes_to_strings, read_keyfile, get_cose_alg_from_key
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020016from iatverifier.psa_iot_profile1_token_verifier import PSAIoTProfile1TokenVerifier
Mate Toth-Palbb187d02022-04-26 16:01:51 +020017from iatverifier.attest_token_verifier import VerifierConfiguration, AttestationTokenVerifier
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020018
19logger = logging.getLogger('iat-verify')
20
21def main():
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020022 """Main function for verifying an IAT"""
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020023
24 token_verifiers = {
25 "PSA-IoT-Profile1-token": PSAIoTProfile1TokenVerifier,
26 }
27
28 parser = argparse.ArgumentParser(
29 description='''
30 Validates a signed Initial Attestation Token (IAT), checking
31 that the signature is valid, the token contian the required
32 fields, and those fields are in a valid format.
33 ''')
34 parser.add_argument('-k', '--keyfile',
35 help='''
36 Path to a file containing signing key in PEM format.
37 ''')
38 parser.add_argument('tokenfile',
39 help='''
40 path to a file containing a signed IAT.
41 ''')
42 parser.add_argument('-K', '--keep-going', action='store_true',
43 help='''
44 Do not stop upon encountering a validation error.
45 ''')
46 parser.add_argument('-p', '--print-iat', action='store_true',
47 help='''
48 Print the decoded token in JSON format.
49 ''')
50 parser.add_argument('-s', '--strict', action='store_true',
51 help='''
52 Report failure if unknown claim is encountered.
53 ''')
54 parser.add_argument('-c', '--check-protected-header', action='store_true',
55 help='''
56 Check the presence and content of COSE protected header.
57 ''')
58 parser.add_argument('-m', '--method', choices=['sign', 'mac'], default='sign',
59 help='''
60 Specify how this token is wrapped -- whether Sign1Message or
61 Mac0Message COSE structure is used.
62 ''')
63 parser.add_argument('-t', '--token-type',
64 help='''The type of the Token.''',
65 choices=token_verifiers.keys(),
66 required=True)
67
68 args = parser.parse_args()
69
70 logging.basicConfig(level=logging.INFO)
71
72 config = VerifierConfiguration(keep_going=args.keep_going, strict=args.strict)
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020073 if args.method == 'mac':
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020074 method = AttestationTokenVerifier.SIGN_METHOD_MAC0
75 else:
76 method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020077
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020078 key = read_keyfile(keyfile=args.keyfile, method=method)
79
80 if args.method == 'mac':
81 cose_alg = AttestationTokenVerifier.COSE_ALG_HS256
82 else:
83 if key is not None:
84 cose_alg = get_cose_alg_from_key(key)
85 else:
86 cose_alg = AttestationTokenVerifier.COSE_ALG_ES256
87
88 verifier_class = token_verifiers[args.token_type]
89 if verifier_class == PSAIoTProfile1TokenVerifier:
90 verifier = PSAIoTProfile1TokenVerifier(
91 method=method,
92 cose_alg=cose_alg,
93 signing_key=key,
94 configuration=config)
95 else:
96 logger.error(f'Invalid token type:{verifier_class}\n\t')
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020097 sys.exit(1)
98
99 try:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200100 with open(args.tokenfile, 'rb') as token_file:
101 token = verifier.parse_token(
102 token=token_file.read(),
103 verify=True,
104 check_p_header=args.check_protected_header,
105 lower_case_key=False)
106 if args.keyfile:
107 print('Signature OK')
108 print('Token format OK')
109 except ValueError as exc:
110 logger.error(f'Could not extract IAT from COSE:\n\t{exc}')
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +0200111 sys.exit(1)
112
113 if args.print_iat:
114 print('Token:')
115 json.dump(recursive_bytes_to_strings(token, in_place=True),
116 sys.stdout, indent=4)
117 print('')
118
119if __name__ == '__main__':
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200120 main()