blob: b91702a7306ef19d097902b82558ecb56d03c351 [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-Pal1cb66cd2022-04-26 15:40:07 +02008import argparse
9import json
10import logging
11import sys
12
13from iatverifier.util import extract_iat_from_cose, recursive_bytes_to_strings
14from iatverifier.psa_iot_profile1_token_verifier import PSAIoTProfile1TokenVerifier
15from iatverifier.verifiers import VerifierConfiguration, AttestationTokenVerifier
16
17logger = logging.getLogger('iat-verify')
18
19def main():
20
21 token_verifiers = {
22 "PSA-IoT-Profile1-token": PSAIoTProfile1TokenVerifier,
23 }
24
25 parser = argparse.ArgumentParser(
26 description='''
27 Validates a signed Initial Attestation Token (IAT), checking
28 that the signature is valid, the token contian the required
29 fields, and those fields are in a valid format.
30 ''')
31 parser.add_argument('-k', '--keyfile',
32 help='''
33 Path to a file containing signing key in PEM format.
34 ''')
35 parser.add_argument('tokenfile',
36 help='''
37 path to a file containing a signed IAT.
38 ''')
39 parser.add_argument('-K', '--keep-going', action='store_true',
40 help='''
41 Do not stop upon encountering a validation error.
42 ''')
43 parser.add_argument('-p', '--print-iat', action='store_true',
44 help='''
45 Print the decoded token in JSON format.
46 ''')
47 parser.add_argument('-s', '--strict', action='store_true',
48 help='''
49 Report failure if unknown claim is encountered.
50 ''')
51 parser.add_argument('-c', '--check-protected-header', action='store_true',
52 help='''
53 Check the presence and content of COSE protected header.
54 ''')
55 parser.add_argument('-m', '--method', choices=['sign', 'mac'], default='sign',
56 help='''
57 Specify how this token is wrapped -- whether Sign1Message or
58 Mac0Message COSE structure is used.
59 ''')
60 parser.add_argument('-t', '--token-type',
61 help='''The type of the Token.''',
62 choices=token_verifiers.keys(),
63 required=True)
64
65 args = parser.parse_args()
66
67 logging.basicConfig(level=logging.INFO)
68
69 config = VerifierConfiguration(keep_going=args.keep_going, strict=args.strict)
70 verifier = token_verifiers[args.token_type].get_verifier(config)
71 if args.method == 'mac':
72 verifier.method = AttestationTokenVerifier.SIGN_METHOD_MAC0
73 verifier.cose_alg = AttestationTokenVerifier.COSE_ALG_HS256
74
75 try:
76 raw_iat = extract_iat_from_cose(args.keyfile, args.tokenfile, verifier, args.check_protected_header)
77 if args.keyfile:
78 print('Signature OK')
79 except ValueError as e:
80 logger.error('Could not extract IAT from COSE:\n\t{}'.format(e))
81 sys.exit(1)
82
83 try:
84 token = verifier.decode_and_validate_iat(raw_iat)
85 if not verifier.seen_errors:
86 print('Token format OK')
87 except ValueError as e:
88 logger.error('Could not validate IAT:\n\t{}'.format(e))
89 sys.exit(1)
90
91 if args.print_iat:
92 print('Token:')
93 json.dump(recursive_bytes_to_strings(token, in_place=True),
94 sys.stdout, indent=4)
95 print('')
96
97if __name__ == '__main__':
98 main()