Thomas Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 1 | #!/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 Fossati | 3450f2a | 2024-09-06 08:32:52 +0000 | [diff] [blame^] | 10 | Convert a PEM key into an equivalent COSE_Key, and optionally compute the CCA hash-lock claims. |
| 11 | The default is to strip the private part off the transformed key. Pass the '--no-strip-private' |
| 12 | argument if the desired behaviour is to convert a private key as-is. Note that this mode is |
| 13 | incompatible with CCA claims generation. |
Thomas Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 14 | |
| 15 | Examples: |
| 16 | ./pem2cose.py -h |
Thomas Fossati | 3450f2a | 2024-09-06 08:32:52 +0000 | [diff] [blame^] | 17 | ./pem2cose.py --no-strip-private ../tests/data/cca_realm.pem cca_realm.cbor |
Thomas Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 18 | ./pem2cose.py --hash-alg sha-256 ../tests/data/cca_realm.pem - > hashlock-claims.yaml |
| 19 | |
| 20 | """ |
Thomas Fossati | 3450f2a | 2024-09-06 08:32:52 +0000 | [diff] [blame^] | 21 | import sys |
Thomas Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 22 | import argparse |
| 23 | |
| 24 | from iatverifier.util import read_keyfile |
| 25 | from iatverifier.attest_token_verifier import AttestationTokenVerifier |
| 26 | from hashlib import sha256, sha384, sha512 |
| 27 | from base64 import b64encode |
Thomas Fossati | 3450f2a | 2024-09-06 08:32:52 +0000 | [diff] [blame^] | 28 | from pycose.keys import CoseKey |
| 29 | from pycose.keys.keyparam import EC2KpD |
| 30 | |
Thomas Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 31 | |
| 32 | hash_algorithms = { |
| 33 | 'sha-256': sha256, |
| 34 | 'sha-384': sha384, |
| 35 | 'sha-512': sha512, |
| 36 | } |
| 37 | |
| 38 | if __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 Fossati | 3450f2a | 2024-09-06 08:32:52 +0000 | [diff] [blame^] | 47 | parser.add_argument('--no-strip-private', help='do not strip the private key', |
| 48 | dest='strip_private', action='store_false') |
Thomas Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 49 | |
| 50 | args = parser.parse_args() |
| 51 | |
| 52 | cose_key = read_keyfile( |
| 53 | args.pemfile, AttestationTokenVerifier.SIGN_METHOD_SIGN1).encode() |
| 54 | |
Thomas Fossati | 3450f2a | 2024-09-06 08:32:52 +0000 | [diff] [blame^] | 55 | 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 Fossati | 5ebf483 | 2024-08-26 09:30:05 +0000 | [diff] [blame] | 67 | 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}') |