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