diff --git a/utils/extract_merkle_tree_key.py b/utils/extract_merkle_tree_key.py new file mode 100755 index 0000000..170fbc3 --- /dev/null +++ b/utils/extract_merkle_tree_key.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import xml.etree.ElementTree as ET + + +def parse_args(): + parser = argparse.ArgumentParser( + prog='extract_merkle_tree_key.py', + description=('Extracts the ECDSA public key from ' + 'an XML file for a Merkle tree')) + parser.add_argument('input_file') + return parser.parse_args() + + +def main(): + args = parse_args() + tree = ET.parse(args.input_file) + root = tree.getroot() + pk = root.find('body').find('MerkleTree').find('PublicKey') + print(pk.find('point').text) + + +if __name__ == '__main__': + main() diff --git a/utils/run_test_vectors.sh b/utils/run_test_vectors.sh index b0bc652..842856d 100755 --- a/utils/run_test_vectors.sh +++ b/utils/run_test_vectors.sh @@ -25,6 +25,8 @@ CONVERT=$GALILEO_OSNMA_DIR/osnma-test-vectors-to-galmon/target/release/osnma-tes GALMON_OSNMA=$GALILEO_OSNMA_DIR/galmon-osnma/target/release/galmon-osnma GET_MERKLE=$GALILEO_OSNMA_DIR/utils/extract_merkle_tree_root.py GET_PUBKEY=$GALILEO_OSNMA_DIR/utils/extract_public_key.py +GET_PUBKEY_FROM_MERKLE=$GALILEO_OSNMA_DIR/utils/extract_merkle_tree_key.py +SEC1_TO_PEM=$GALILEO_OSNMA_DIR/utils/sec1_to_pem.py PUBKEY=/tmp/pubkey.pem @@ -194,9 +196,12 @@ $CONVERT "${TEST_VECTOR_DIR}/osnma_test_vectors/nmt_step3/07_OCT_2023_GST_14_45_ echo "Test vector: New Merkle Tree (step 2 only, starting with Merkle tree 3 and PKID 1)" -openssl x509 \ - -in "${TEST_VECTOR_DIR}/cryptographic_material/Merkle_tree_3/PublicKey/OSNMA_PublicKey_20231008111500_PKID_1.crt" \ - -noout -pubkey > $PUBKEY +# The PublicKey files for Merkle_tree_3 are wrong (they don't match the public key in the +# Merkle tree XML file, nor the pubkey used in the OSNMA test vectors). +# +# We load the pubkey from the Merkle tree instead + +$SEC1_TO_PEM $($GET_PUBKEY_FROM_MERKLE ${TEST_VECTOR_DIR}/cryptographic_material/Merkle_tree_3/MerkleTree/OSNMA_MerkleTree_20231007201500_PKID_1.xml) > $PUBKEY PKID=1 MERKLE="$($GET_MERKLE ${TEST_VECTOR_DIR}/cryptographic_material/Merkle_tree_3/MerkleTree/OSNMA_MerkleTree_20231007201500_PKID_1.xml)" diff --git a/utils/sec1_to_pem.py b/utils/sec1_to_pem.py new file mode 100755 index 0000000..f38ee92 --- /dev/null +++ b/utils/sec1_to_pem.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 + +import argparse +import sys + +import ecdsa + + +def parse_args(): + parser = argparse.ArgumentParser( + prog='sec1_to_pem.py', + description='Converts a SEC1 encoded public key in hex to PEM format') + parser.add_argument('--curve', default='NIST256p') + parser.add_argument('sec1_hex') + return parser.parse_args() + + +def main(): + args = parse_args() + curve = getattr(ecdsa, args.curve) + sec1 = bytes.fromhex(args.sec1_hex) + vk = ecdsa.VerifyingKey.from_string(sec1, curve=curve) + print(str(vk.to_pem(), encoding='ascii'), end='') + + +if __name__ == '__main__': + main()