blob: 90ee6ad79489159463b667e9620007fae60ad27e [file] [log] [blame]
Thomas Fossati5ebf4832024-08-26 09:30:05 +00001#!/usr/bin/env python3
2# -----------------------------------------------------------------------------
3# Copyright (c) 2024, Linaro Limited. All rights reserved.
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7# -----------------------------------------------------------------------------
8
9"""
Thomas Fossati3450f2a2024-09-06 08:32:52 +000010Convert a PEM key into an equivalent COSE_Key, and optionally compute the CCA hash-lock claims.
11The default is to strip the private part off the transformed key. Pass the '--no-strip-private'
12argument if the desired behaviour is to convert a private key as-is. Note that this mode is
13incompatible with CCA claims generation.
Thomas Fossati5ebf4832024-08-26 09:30:05 +000014
15Examples:
16 ./pem2cose.py -h
Thomas Fossati3450f2a2024-09-06 08:32:52 +000017 ./pem2cose.py --no-strip-private ../tests/data/cca_realm.pem cca_realm.cbor
Thomas Fossati5ebf4832024-08-26 09:30:05 +000018 ./pem2cose.py --hash-alg sha-256 ../tests/data/cca_realm.pem - > hashlock-claims.yaml
19
20"""
Thomas Fossati3450f2a2024-09-06 08:32:52 +000021import sys
Thomas Fossati5ebf4832024-08-26 09:30:05 +000022import argparse
23
24from iatverifier.util import read_keyfile
25from iatverifier.attest_token_verifier import AttestationTokenVerifier
26from hashlib import sha256, sha384, sha512
27from base64 import b64encode
Thomas Fossati3450f2a2024-09-06 08:32:52 +000028from pycose.keys import CoseKey
29from pycose.keys.keyparam import EC2KpD
30
Thomas Fossati5ebf4832024-08-26 09:30:05 +000031
32hash_algorithms = {
33 'sha-256': sha256,
34 'sha-384': sha384,
35 'sha-512': sha512,
36}
37
38if __name__ == '__main__':
39 parser = argparse.ArgumentParser(
40 description='convert a PEM key into an equivalent COSE_Key; optionally compute the CCA hash-lock claims')
41
42 parser.add_argument('pemfile', type=str, help='input PEM file')
43 parser.add_argument(
44 'cosefile', type=str, help='output COSE_Key file (pass "-" to write to stdout)')
45 parser.add_argument('--hash-alg', type=str, help='compute the hash lock using the specified algorithm',
46 choices=hash_algorithms.keys())
Thomas Fossati3450f2a2024-09-06 08:32:52 +000047 parser.add_argument('--no-strip-private', help='do not strip the private key',
48 dest='strip_private', action='store_false')
Thomas Fossati5ebf4832024-08-26 09:30:05 +000049
50 args = parser.parse_args()
51
52 cose_key = read_keyfile(
53 args.pemfile, AttestationTokenVerifier.SIGN_METHOD_SIGN1).encode()
54
Thomas Fossati3450f2a2024-09-06 08:32:52 +000055 if not args.strip_private and args.hash_alg is not None:
56 print('Private key conversion and CCA claims generation are mutually exclusive')
57 sys.exit(1)
58
59 if args.strip_private:
60 tmp = CoseKey.decode(cose_key)
61 try:
62 del tmp[EC2KpD]
63 except KeyError:
64 pass
65 cose_key = CoseKey.encode(tmp)
66
Thomas Fossati5ebf4832024-08-26 09:30:05 +000067 if args.cosefile == '-':
68 b64_cose_key = b64encode(cose_key).decode()
69 print(f'cca_realm_pub_key: !!binary {b64_cose_key}')
70 else:
71 with open(args.cosefile, 'wb') as f:
72 f.write(cose_key)
73
74 if args.hash_alg is not None:
75 h = hash_algorithms[args.hash_alg]()
76 h.update(cose_key)
77 b64_hash_lock = b64encode(h.digest()).decode()
78 print(f'cca_platform_challenge: !!binary {b64_hash_lock}')
79 print(f'cca_realm_pub_key_hash_algo_id: {args.hash_alg}')