commit 8d2563982066d9a2e2abab71a3a48377febde3fc
parent 89144945bba731dbdfc85554c211a4141b72266d
Author: lash <dev@holbrook.no>
Date:   Sat, 24 Jun 2023 22:04:42 +0100
Generate signature from signedinfo
Diffstat:
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