Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | """ |
| 3 | cpisign.py |
| 4 | |
| 5 | Utility for signing CPI data |
| 6 | """ |
| 7 | |
| 8 | # SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org> |
| 9 | # SPDX-License-Identifier: Apache-2.0 |
| 10 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 11 | import os |
| 12 | import json |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 13 | import getpass |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 14 | import argparse |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 15 | from jose import jws |
| 16 | |
| 17 | from cryptography.hazmat.primitives.serialization import pkcs12 |
| 18 | from cryptography.hazmat.primitives import serialization |
| 19 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 20 | parser = argparse.ArgumentParser(description="CBSD CPI signature data generator") |
| 21 | parser.add_argument("-k", "--key", help="The file name of CPI key") |
| 22 | parser.add_argument( |
| 23 | "signFiles", |
| 24 | type=str, |
| 25 | nargs="+", |
| 26 | help="The file name of sigature data, can accept multiple files in a time.", |
| 27 | ) |
| 28 | args = parser.parse_args() |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 29 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 30 | if __name__ == "__main__": |
| 31 | # get password |
Zack Williams | 84cb77a | 2022-01-14 14:46:39 -0800 | [diff] [blame] | 32 | cpi_password = bytes( |
| 33 | getpass.getpass(prompt="Password for CPI Key %s: " % args.key), "ascii" |
| 34 | ) |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 35 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 36 | with open(args.key, "rb") as key_file: |
| 37 | (pkey, cert, addl_cert) = pkcs12.load_key_and_certificates( |
| 38 | key_file.read(), cpi_password |
| 39 | ) |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 40 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 41 | pkey_raw = pkey.private_bytes( |
| 42 | encoding=serialization.Encoding.PEM, |
| 43 | format=serialization.PrivateFormat.TraditionalOpenSSL, |
| 44 | encryption_algorithm=serialization.NoEncryption(), |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 45 | ) |
| 46 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 47 | if not os.path.exists("output"): |
| 48 | os.makedirs("output") |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 49 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 50 | for signFile in args.signFiles: |
| 51 | with open(signFile, "r") as inFile: |
| 52 | inFileJson = json.loads(inFile.read()) |
| 53 | # The output is 3 parameters concat with dot to a string |
| 54 | # 3 params are: protectedHeader, encodedCpiSignedData, digitalSignature |
| 55 | SIGNED = jws.sign(inFileJson, pkey_raw, algorithm="RS256") |
Zack Williams | 7af92fe | 2021-08-15 15:37:50 -0700 | [diff] [blame] | 56 | |
Wei-Yu Chen | 27f14ef | 2021-09-23 12:23:13 +0800 | [diff] [blame] | 57 | print(f"* {inFileJson['cbsdSerialNumber']} data was signed") |
| 58 | with open(f"output/{signFile}.signed", "w") as out_file: |
| 59 | out_file.write(SIGNED) |