feat: support draft-ffm-rats-cca-token-00 encoding
Add support for the new CCA token profile(s) defined in
draft-ffm-rats-cca-token-00.
In particular, claim 44237 (`cca_realm_pub_key`') now encodes the RAK as
a CBOR-serialised COSE_Key rather than a raw public key.
This non-backwards compatible encoding is signalled by the new (in-band)
profile identifier `"tag:arm.com,2023:realm#1.0.0"`.
The legacy profile `"http://arm.com/CCA-SSD/1.0.0"` with the raw RAK
encoding is still fully processed, but its use triggers a deprecation
warning.
Change-Id: I381fb0a885cba99191622ba2f38688a357eaf736
Signed-off-by: Thomas Fossati <thomas.fossati@linaro.org>
diff --git a/iat-verifier/dev_scripts/generate-key.py b/iat-verifier/dev_scripts/generate-key.py
index 6c1eee7..ceb5cc6 100755
--- a/iat-verifier/dev_scripts/generate-key.py
+++ b/iat-verifier/dev_scripts/generate-key.py
@@ -6,14 +6,31 @@
#
# -----------------------------------------------------------------------------
-import sys
+import argparse
-from ecdsa import SigningKey, NIST256p
-
+from ecdsa import SigningKey, NIST256p, NIST384p
+from pycose.keys import EC2Key, CoseKey
+from ecdsa.curves import curve_by_name
if __name__ == '__main__':
- outfile = sys.argv[1]
+ parser = argparse.ArgumentParser(description='generate an ECDSA key')
- sk = SigningKey.generate(curve=NIST256p)
- with open(outfile, 'wb') as wfh:
- wfh.write(sk.to_pem())
+ parser.add_argument('outfile', type=str, help='output file')
+ parser.add_argument('--crv', type=str, help='ECDSA curve',
+ choices=[NIST256p.name, NIST384p.name], default='NIST256p')
+ parser.add_argument('--fmt', type=str, help='key format',
+ choices=['PEM', 'COSE'], default='PEM')
+
+ args = parser.parse_args()
+
+ sk = SigningKey.generate(curve_by_name(args.crv))
+
+ pem_key = sk.to_pem().decode('utf-8')
+
+ if args.fmt == 'PEM':
+ o = pem_key
+ elif args.fmt == 'COSE':
+ o = CoseKey.from_pem_private_key(pem_key)
+
+ with open(args.outfile, 'wb') as wfh:
+ wfh.write(o.encode())
diff --git a/iat-verifier/dev_scripts/pem2cose.py b/iat-verifier/dev_scripts/pem2cose.py
new file mode 100755
index 0000000..f6c62c7
--- /dev/null
+++ b/iat-verifier/dev_scripts/pem2cose.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# -----------------------------------------------------------------------------
+# Copyright (c) 2024, Linaro Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# -----------------------------------------------------------------------------
+
+"""
+Convert a PEM key into an equivalent COSE_Key, and optionally compute the CCA hash-lock claims
+
+Examples:
+ ./pem2cose.py -h
+ ./pem2cose.py ../tests/data/cca_realm.pem cca_realm.cbor
+ ./pem2cose.py --hash-alg sha-256 ../tests/data/cca_realm.pem - > hashlock-claims.yaml
+
+"""
+import argparse
+
+from iatverifier.util import read_keyfile
+from iatverifier.attest_token_verifier import AttestationTokenVerifier
+from hashlib import sha256, sha384, sha512
+from base64 import b64encode
+
+hash_algorithms = {
+ 'sha-256': sha256,
+ 'sha-384': sha384,
+ 'sha-512': sha512,
+}
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(
+ description='convert a PEM key into an equivalent COSE_Key; optionally compute the CCA hash-lock claims')
+
+ parser.add_argument('pemfile', type=str, help='input PEM file')
+ parser.add_argument(
+ 'cosefile', type=str, help='output COSE_Key file (pass "-" to write to stdout)')
+ parser.add_argument('--hash-alg', type=str, help='compute the hash lock using the specified algorithm',
+ choices=hash_algorithms.keys())
+
+ args = parser.parse_args()
+
+ cose_key = read_keyfile(
+ args.pemfile, AttestationTokenVerifier.SIGN_METHOD_SIGN1).encode()
+
+ if args.cosefile == '-':
+ b64_cose_key = b64encode(cose_key).decode()
+ print(f'cca_realm_pub_key: !!binary {b64_cose_key}')
+ else:
+ with open(args.cosefile, 'wb') as f:
+ f.write(cose_key)
+
+ if args.hash_alg is not None:
+ h = hash_algorithms[args.hash_alg]()
+ h.update(cose_key)
+ b64_hash_lock = b64encode(h.digest()).decode()
+ print(f'cca_platform_challenge: !!binary {b64_hash_lock}')
+ print(f'cca_realm_pub_key_hash_algo_id: {args.hash_alg}')