funga

Signer and keystore daemon and library for cryptocurrency software development
Log | Files | Refs | README | LICENSE

commit 8d2563982066d9a2e2abab71a3a48377febde3fc
parent 89144945bba731dbdfc85554c211a4141b72266d
Author: lash <dev@holbrook.no>
Date:   Sat, 24 Jun 2023 22:04:42 +0100

Generate signature from signedinfo

Diffstat:
Mfunga/xml/xml.py | 20+++++++++++++++-----
Mtests/test_xml.py | 18++++++++++--------
Mtests/testdata/sign.xml | 19++++++++++++-------
Atests/testdata/signedinfo.xml | 18++++++++++++++++++
4 files changed, 55 insertions(+), 20 deletions(-)

diff --git a/funga/xml/xml.py b/funga/xml/xml.py @@ -1,5 +1,7 @@ # standard imports import os +import io +import hashlib from enum import Enum import logging import xml.etree.ElementTree as ET @@ -68,6 +70,7 @@ class SignatureParser: sp = os.path.join(data_dir, 'xmldsig-core-schema.xsd') self.__schema = m.XMLSchema(sp, validation='lax') # TODO: add validation for xmldsig11 OR make work with xmldsig1-schema bundle + ET.register_namespace('', self.namespaces['']) def clear(self): @@ -84,10 +87,12 @@ class SignatureParser: self.order = None self.cofactor = None self.keyname = None + self.digest_outer = None + self.sign_material = None def __str__(self): - return 'order {}'.format(self.order) + return 'Signature Parser: order {}'.format(self.order) def set(self, k, v): if k.__class__.__name__ == 'SignatureAccept': @@ -109,6 +114,7 @@ class SignatureParser: if self.__schema == None: return self.__schema.validate(fp) + logg.debug('schema validation complete') def process_file(self, fp): @@ -124,6 +130,12 @@ class SignatureParser: r = self.__root.find('./KeyInfo', namespaces=self.namespaces) if r != None: self.__opt_verify_keyinfo(r) + r = self.__root.find('./SignedInfo', namespaces=self.namespaces) + v = ET.tostring(r) + self.sign_material = ET.canonicalize(xml_data=v) + h = hashlib.new('sha256') + h.update(self.sign_material.encode('utf-8')) + self.digest_outer = h.digest() def __verify_canonicalization(self, el): @@ -139,10 +151,8 @@ class SignatureParser: m = self.get(SignatureVerify.SIGNATURE) if m != None: assert m(b) - #self.signature = b - logg.debug('sig {}'.format(b.hex())) - self.sig_r = int.from_bytes(b[:32], byteorder='little') - self.sig_s = int.from_bytes(b[32:64], byteorder='little') + self.sig_r = int.from_bytes(b[:32], byteorder='big') + self.sig_s = int.from_bytes(b[32:64], byteorder='big') self.sig_v = int(b[64]) def __opt_verify_signedinfo(self, el): diff --git a/tests/test_xml.py b/tests/test_xml.py @@ -3,6 +3,7 @@ import logging import unittest import os from base64 import b64decode +from hashlib import sha256 # external imports from fastecdsa import curve @@ -46,7 +47,7 @@ class TestXmlSig(unittest.TestCase): with self.assertRaises(AssertionError): self.parser.process_file(self.xml_file) - self.parser.set(SignatureAccept.SIGNING, 'http://tools.ietf.org/html/rfc6931') + self.parser.set(SignatureAccept.SIGNING, 'http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256') with self.assertRaises(AssertionError): self.parser.process_file(self.xml_file) @@ -77,11 +78,10 @@ class TestXmlSig(unittest.TestCase): self.parser.set(SignatureVerify.PUBLICKEY, verify_pub_ok) self.parser.process_file(self.xml_file) - #self.assertEqual(self.parser.signature.hex(), 'af77767edbccdf46380fed6f06af43c807de4bedce2eda129923340e9577c97e76bc55d587103a367057167f351ae1cfd6b8dea6e0282257de3594fbe3d8780700') + #self.assertEqual(self.parser.signature.hex(), 'c2aa0be2d969248cdcb3b812ea4400212e71b39a5948560e2b24b908060b3b392131b1021b2bb792908fb9375a6e482e8d3fdcffbdf506e309041fc87365bf1200') self.assertEqual(self.parser.public_key.hex(), '049f6bb6a7e3f5b7ee71756a891233d1415658f8712bac740282e083dc9240f5368bdb3b256a5bf40a8f7f9753414cb447ee3f796c5f30f7eb40a7f5018fc7f02e') - self.assertEqual(self.parser.digest.hex(), '76b2e96714d3b5e6eb1d1c509265430b907b44f72b2a22b06fcd4d96372b8565') - - logg.debug('r {}'.format(self.parser)) + self.assertEqual(self.parser.digest.hex(), 'e08f5c88dd7b076fe3e42f9146980a3c8223324ef7aa3b5b9a6103a6ca657b42') + self.assertEqual(self.parser.digest_outer.hex(), 'c34e546b70afeb6962d6faa59eb7f9316fc254cc96534cd181aff6958004c5ee') c = curve.Curve( 'eth', @@ -102,13 +102,15 @@ class TestXmlSig(unittest.TestCase): y = int.from_bytes(self.parser.public_key[33:65], byteorder='big') pubk = Pubk(x, y) - ecdsa.verify( + r = ecdsa.verify( (self.parser.sig_r, self.parser.sig_s), - self.parser.digest, + #self.parser.digest, + self.parser.sign_material, pubk, curve=c, + hashfunc=sha256, ) - + self.assertTrue(r) if __name__ == '__main__': diff --git a/tests/testdata/sign.xml b/tests/testdata/sign.xml @@ -2,17 +2,22 @@ <Signature Id="sig-a0f819f9-6813-4f14-a7c8-f33c12f0c846" xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> - <SignatureMethod Algorithm="http://tools.ietf.org/html/rfc6931"/> - <Reference Type="http://www.w3.org/2000/09/xmldsig#SignatureProperties"> + <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/> + <Reference URI="sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"> <Transforms> - <Transform Algorithm="https://eips.ethereum.org/EIPS/eip-191#version-0x45-e" /> <Transform Algorithm="https://csrc.nist.gov/glossary/term/sha_256" /> + <Transform Algorithm="https://eips.ethereum.org/EIPS/eip-191#version-0x45-e" /> </Transforms> <DigestMethod Algorithm="https://csrc.nist.gov/glossary/term/sha_256" /> - <DigestValue>drLpZxTTtebrHRxQkmVDC5B7RPcrKiKwb81NljcrhWU=</DigestValue> + <DigestValue>4I9ciN17B2/j5C+RRpgKPIIjMk73qjtbmmEDpsple0I=</DigestValue> + </Reference> + <!--the timestamp the signature was made--> + <Reference URI="#ts-a0f819f9-6813-4f14-a7c8-f33c12f0c846" Type="http://www.w3.org/2000/09/xmldsig#SignatureProperties"> + <DigestMethod Algorithm="https://csrc.nist.gov/glossary/term/sha_256" /> + <DigestValue>sBUajLlBHMbzuaU+SiPjLpkzcMzjkKDvBqYhRvB0Lns=</DigestValue> </Reference> </SignedInfo> - <SignatureValue>r3d2ftvM30Y4D+1vBq9DyAfeS+3OLtoSmSM0DpV3yX52vFXVhxA6NnBXFn81GuHP1rjepuAoIlfeNZT749h4BwA=</SignatureValue> + <SignatureValue>wqoL4tlpJIzcs7gS6kQAIS5xs5pZSFYOKyS5CAYLOzkhMbECGyu3kpCPuTdabkgujT/c/731BuMJBB/Ic2W/EgA=</SignatureValue> <KeyInfo> <KeyName>6zkH7K10oAE8JZ1YdK5/Ity8yVw=</KeyName> @@ -38,8 +43,8 @@ <Object> <SignatureProperties> <SignatureProperty Id="ts-a0f819f9-6813-4f14-a7c8-f33c12f0c846" Target="sig-a0f819f9-6813-4f14-a7c8-f33c12f0c846"> - <timestamp xmlns="https://www.epochconverter.com/"> - <epochSeconds>1686900525</epochSeconds> + <timestamp xmlns="http://epochconverter.com"> + <epochSeconds>ZIwPLQ==</epochSeconds> </timestamp> </SignatureProperty> </SignatureProperties> diff --git a/tests/testdata/signedinfo.xml b/tests/testdata/signedinfo.xml @@ -0,0 +1,17 @@ +<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> + <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod> + <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"></SignatureMethod> + <Reference URI="sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"> + <Transforms> + <Transform Algorithm="https://csrc.nist.gov/glossary/term/sha_256"></Transform> + <Transform Algorithm="https://eips.ethereum.org/EIPS/eip-191#version-0x45-e"></Transform> + </Transforms> + <DigestMethod Algorithm="https://csrc.nist.gov/glossary/term/sha_256"></DigestMethod> + <DigestValue>4I9ciN17B2/j5C+RRpgKPIIjMk73qjtbmmEDpsple0I=</DigestValue> + </Reference> + + <Reference Type="http://www.w3.org/2000/09/xmldsig#SignatureProperties" URI="#ts-a0f819f9-6813-4f14-a7c8-f33c12f0c846"> + <DigestMethod Algorithm="https://csrc.nist.gov/glossary/term/sha_256"></DigestMethod> + <DigestValue>sBUajLlBHMbzuaU+SiPjLpkzcMzjkKDvBqYhRvB0Lns=</DigestValue> + </Reference> + </SignedInfo> +\ No newline at end of file