commit 89144945bba731dbdfc85554c211a4141b72266d
parent 88c01e7edfae7bf4e2d4687ca521ab3778ba0528
Author: lash <dev@holbrook.no>
Date: Fri, 23 Jun 2023 21:31:22 +0100
Verify sig from xml curve params
Diffstat:
4 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/funga/xml/xml.py b/funga/xml/xml.py
@@ -20,6 +20,15 @@ def cryptobinary_to_int(v):
return int.from_bytes(b, byteorder='big')
+def cryptobinary_to_pair(v):
+ b = b64decode(v)
+ b = b[1:] # TODO: force uncompressed
+ l = int(len(b) / 2)
+ x = int.from_bytes(b[:l], byteorder='big')
+ y = int.from_bytes(b[l:], byteorder='big')
+ return (x, y,)
+
+
class SignatureParser:
namespaces = {
@@ -62,18 +71,24 @@ class SignatureParser:
def clear(self):
- self.signature = None
+ self.sig_r = None
+ self.sig_s = None
+ self.sig_v = None
self.digest = None
self.public_key = None
self.prime = None
self.curve_a = None
self.curve_b = None
- self.base = None
+ self.base_x = None
+ self.base_y = None
self.order = None
self.cofactor = None
self.keyname = None
+ def __str__(self):
+ return 'order {}'.format(self.order)
+
def set(self, k, v):
if k.__class__.__name__ == 'SignatureAccept':
self.__settings[k.value - 1].append(v)
@@ -124,7 +139,11 @@ class SignatureParser:
m = self.get(SignatureVerify.SIGNATURE)
if m != None:
assert m(b)
- self.signature = 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_v = int(b[64])
def __opt_verify_signedinfo(self, el):
r = el.find('./DigestMethod', namespaces=self.namespaces)
@@ -164,7 +183,7 @@ class SignatureParser:
r = el.find('./dsig11:ECParameters/dsig11:Curve/dsig11:B', namespaces=self.namespaces)
self.curve_b = cryptobinary_to_int(r.text)
r = el.find('./dsig11:ECParameters/dsig11:Base', namespaces=self.namespaces)
- self.base = cryptobinary_to_int(r.text)
+ (self.base_x, self.base_y) = cryptobinary_to_pair(r.text)
r = el.find('./dsig11:ECParameters/dsig11:Order', namespaces=self.namespaces)
self.order = cryptobinary_to_int(r.text)
r = el.find('./dsig11:ECParameters/dsig11:CoFactor', namespaces=self.namespaces)
diff --git a/test_requirements.txt b/test_requirements.txt
@@ -0,0 +1 @@
+fastecdsa~=2.3.0
diff --git a/tests/test_xml.py b/tests/test_xml.py
@@ -4,6 +4,10 @@ import unittest
import os
from base64 import b64decode
+# external imports
+from fastecdsa import curve
+from fastecdsa import ecdsa
+
# local imports
from funga.xml import SignatureParser
from funga.xml import SignatureAccept
@@ -73,10 +77,39 @@ 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(), 'af77767edbccdf46380fed6f06af43c807de4bedce2eda129923340e9577c97e76bc55d587103a367057167f351ae1cfd6b8dea6e0282257de3594fbe3d8780700')
self.assertEqual(self.parser.public_key.hex(), '049f6bb6a7e3f5b7ee71756a891233d1415658f8712bac740282e083dc9240f5368bdb3b256a5bf40a8f7f9753414cb447ee3f796c5f30f7eb40a7f5018fc7f02e')
self.assertEqual(self.parser.digest.hex(), '76b2e96714d3b5e6eb1d1c509265430b907b44f72b2a22b06fcd4d96372b8565')
+ logg.debug('r {}'.format(self.parser))
+
+ c = curve.Curve(
+ 'eth',
+ self.parser.prime,
+ self.parser.curve_a,
+ self.parser.curve_b,
+ self.parser.order,
+ self.parser.base_x,
+ self.parser.base_y,
+ )
+
+ class Pubk:
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+ x = int.from_bytes(self.parser.public_key[1:33], byteorder='big')
+ y = int.from_bytes(self.parser.public_key[33:65], byteorder='big')
+ pubk = Pubk(x, y)
+
+ ecdsa.verify(
+ (self.parser.sig_r, self.parser.sig_s),
+ self.parser.digest,
+ pubk,
+ curve=c,
+ )
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/testdata/sign.xml b/tests/testdata/sign.xml
@@ -26,8 +26,8 @@
</Prime>
</FieldID>
<Curve>
- <A>AAo=</A>
- <B>Bwo=</B>
+ <A>AA==</A>
+ <B>Bw==</B>
</Curve>
<Base>BHm+Zn753LusVaBilc6HCwcCm/zbLc4o2VnygVsW+BeYSDradyajxGVdpPv8DhEIqP0XtEimhVQZnEfQj/sQ1Lg=</Base>
<Order>/////////////////////rqu3OavSKA7v9JejNA2QUE=</Order>