blob: 69947427471bc2b0df24a044b1271ee44580c96d [file] [log] [blame]
Mate Toth-Pal530106f2022-05-03 15:29:49 +02001#!/usr/bin/env python3
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +02002# -----------------------------------------------------------------------------
3# Copyright (c) 2019-2022, Arm Limited. All rights reserved.
Mate Toth-Pal51b61982022-03-17 14:19:30 +01004#
5# SPDX-License-Identifier: BSD-3-Clause
6#
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +02007# -----------------------------------------------------------------------------
Mate Toth-Pal51b61982022-03-17 14:19:30 +01008
Mate Toth-Palb9057ff2022-04-29 16:03:21 +02009"""CLI script for verifying an IAT."""
10
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020011import argparse
12import json
13import logging
14import sys
15
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020016from iatverifier.util import recursive_bytes_to_strings, read_keyfile, get_cose_alg_from_key
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020017from iatverifier.psa_iot_profile1_token_verifier import PSAIoTProfile1TokenVerifier
Tamas Ban1e7944a2022-07-04 13:09:03 +020018from iatverifier.psa_2_0_0_token_verifier import PSA_2_0_0_TokenVerifier
Mate Toth-Palbb187d02022-04-26 16:01:51 +020019from iatverifier.attest_token_verifier import VerifierConfiguration, AttestationTokenVerifier
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010020from iatverifier.cca_token_verifier import CCATokenVerifier, CCAPlatformTokenVerifier
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020021
22logger = logging.getLogger('iat-verify')
23
24def main():
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020025 """Main function for verifying an IAT"""
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020026
27 token_verifiers = {
28 "PSA-IoT-Profile1-token": PSAIoTProfile1TokenVerifier,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010029 "CCA-token": CCATokenVerifier,
30 "CCA-plat-token": CCAPlatformTokenVerifier,
Tamas Ban1e7944a2022-07-04 13:09:03 +020031 "PSA-2.0.0-token": PSA_2_0_0_TokenVerifier,
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020032 }
33
34 parser = argparse.ArgumentParser(
35 description='''
36 Validates a signed Initial Attestation Token (IAT), checking
37 that the signature is valid, the token contian the required
38 fields, and those fields are in a valid format.
39 ''')
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020040 parser.add_argument('-k', '--key',
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010041 help='''Path to the key in PEM format that should be used to
42 verify the token. If this is not specified, the token signature
43 will not be checked.''')
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020044 parser.add_argument('tokenfile',
45 help='''
46 path to a file containing a signed IAT.
47 ''')
48 parser.add_argument('-K', '--keep-going', action='store_true',
49 help='''
50 Do not stop upon encountering a validation error.
51 ''')
52 parser.add_argument('-p', '--print-iat', action='store_true',
53 help='''
54 Print the decoded token in JSON format.
55 ''')
56 parser.add_argument('-s', '--strict', action='store_true',
57 help='''
58 Report failure if unknown claim is encountered.
59 ''')
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020060 parser.add_argument('-m', '--method', choices=['sign', 'mac'], default='sign',
61 help='''
62 Specify how this token is wrapped -- whether Sign1Message or
63 Mac0Message COSE structure is used.
64 ''')
65 parser.add_argument('-t', '--token-type',
66 help='''The type of the Token.''',
67 choices=token_verifiers.keys(),
68 required=True)
69
70 args = parser.parse_args()
71
72 logging.basicConfig(level=logging.INFO)
73
74 config = VerifierConfiguration(keep_going=args.keep_going, strict=args.strict)
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020075 if args.method == 'mac':
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020076 method = AttestationTokenVerifier.SIGN_METHOD_MAC0
77 else:
78 method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +020079
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010080 key_checked = False
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020081
82 verifier_class = token_verifiers[args.token_type]
83 if verifier_class == PSAIoTProfile1TokenVerifier:
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020084 key_checked = args.key
85 key = read_keyfile(keyfile=args.key, method=method)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010086 if method == AttestationTokenVerifier.SIGN_METHOD_SIGN1:
87 cose_alg = get_cose_alg_from_key(key, AttestationTokenVerifier.COSE_ALG_ES256)
88 else:
89 cose_alg = AttestationTokenVerifier.COSE_ALG_HS256
Mate Toth-Palb9057ff2022-04-29 16:03:21 +020090 verifier = PSAIoTProfile1TokenVerifier(
91 method=method,
92 cose_alg=cose_alg,
93 signing_key=key,
94 configuration=config)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +010095 elif verifier_class == CCATokenVerifier:
96 if method != AttestationTokenVerifier.SIGN_METHOD_SIGN1:
97 logger.error('Only sign1 method is supported by this token type.\n\t'.format(verifier_class))
98 sys.exit(1)
Mate Toth-Pala8b46b12022-10-07 13:30:54 +020099 key_checked = args.key
100 platform_token_key = read_keyfile(args.key, method)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100101 realm_token_method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
102 platform_token_method = AttestationTokenVerifier.SIGN_METHOD_SIGN1
103 realm_token_cose_alg = get_cose_alg_from_key(
Mate Toth-Palb21ae522022-09-01 12:02:21 +0200104 None,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100105 AttestationTokenVerifier.COSE_ALG_ES384)
106 platform_token_cose_alg = get_cose_alg_from_key(
107 platform_token_key,
108 AttestationTokenVerifier.COSE_ALG_ES384)
109 verifier = CCATokenVerifier(
110 realm_token_method=realm_token_method,
111 realm_token_cose_alg=realm_token_cose_alg,
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100112 platform_token_method=platform_token_method,
113 platform_token_cose_alg=platform_token_cose_alg,
114 platform_token_key=platform_token_key,
115 configuration=config)
116 elif verifier_class == CCAPlatformTokenVerifier:
Mate Toth-Pala8b46b12022-10-07 13:30:54 +0200117 key_checked = args.key
118 key = read_keyfile(args.key, method)
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100119 cose_alg = get_cose_alg_from_key(key, AttestationTokenVerifier.COSE_ALG_ES384)
120 verifier = CCAPlatformTokenVerifier(
121 method=AttestationTokenVerifier.SIGN_METHOD_SIGN1,
122 cose_alg=cose_alg,
123 signing_key=key,
124 configuration=config,
125 necessity=None)
Tamas Ban1e7944a2022-07-04 13:09:03 +0200126 elif verifier_class == PSA_2_0_0_TokenVerifier:
Mate Toth-Pala8b46b12022-10-07 13:30:54 +0200127 key_checked = args.key
128 key = read_keyfile(keyfile=args.key, method=method)
Tamas Ban1e7944a2022-07-04 13:09:03 +0200129 if method == AttestationTokenVerifier.SIGN_METHOD_SIGN1:
130 cose_alg = get_cose_alg_from_key(key, AttestationTokenVerifier.COSE_ALG_ES256)
131 else:
132 cose_alg = AttestationTokenVerifier.COSE_ALG_HS256
133 verifier = PSA_2_0_0_TokenVerifier(method=method, cose_alg=cose_alg, signing_key=key, configuration=config)
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200134 else:
135 logger.error(f'Invalid token type:{verifier_class}\n\t')
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +0200136 sys.exit(1)
137
138 try:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200139 with open(args.tokenfile, 'rb') as token_file:
140 token = verifier.parse_token(
141 token=token_file.read(),
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200142 lower_case_key=False)
Mate Toth-Palc7404e92022-07-15 11:11:13 +0200143 token.verify()
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100144 if key_checked:
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200145 print('Signature OK')
146 print('Token format OK')
147 except ValueError as exc:
Mate Toth-Pal5ebca512022-03-24 16:45:51 +0100148 logger.error(f'Token verification failed:\n\t{exc}')
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +0200149 sys.exit(1)
150
151 if args.print_iat:
152 print('Token:')
Mate Toth-Palc7404e92022-07-15 11:11:13 +0200153 token_map = token.get_token_map()
154 json.dump(recursive_bytes_to_strings(token_map, in_place=True),
Mate Toth-Pal1cb66cd2022-04-26 15:40:07 +0200155 sys.stdout, indent=4)
156 print('')
157
158if __name__ == '__main__':
Mate Toth-Palb9057ff2022-04-29 16:03:21 +0200159 main()