2017 m. rugsėjo 28 d., ketvirtadienis

Python libraries libxml2 and pyXMLSec for Digital Signature

Here is one ancient library, so yes, let's work with this libraries. Asking why, well.
Business, business, business, numbers.


libxml2


>>> doc = libxml2.parseDoc(xml_file) # Parsing file
>>> doc = libxml2.parseFile(xml_file)  # Parsing html

Node itteration
All nodes:
>>> ctxt = doc.xpathNewContext() 
>>> ctxt.xpathEval('//*')
[<xmlNode (Envelope) object at 0x7f55b8a329e0>, ...]

>>> for node in ctxt.xpathEval('//*'): print(node.name)
Envelope
Header
Body
deliverSecure
...

def serialize(self, encoding=None, format=0)
>>> xml = doc.serialize()

Creating nodes

>>> print(libxml2.newNode("Security"))
<Security/>


findChild(parent, name, ns=None)
Searches a direct child of the parent node having given name and namespace


<Sender>
<Id>42</Id>
<Name>Really good name</Name>
</Sender>


Creating namespace:
>>> nswsse = sec.newNs('http://test.xsd', 'wsse')

>>> print(nswsse)
 xmlns:wsse="http://test.xsd"
>>> sec.setNs(nswsse)

>>> print(sec)
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>

Adding attribute:
>>> sec.setProp("id", "900")
<xmlAttr (id) object at 0x7f30b8cc3638>
>>> print(sec)
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" id="900"/>


pyXMLSec

createTree
Creates a new XML tree with one root node rootNodeName.


>>> tets = xmlsec.createTree("test", "aa")
>>> print(tets)
<?xml version="1.0"?>
<test xmlns="aa"/>


findNode(parent, name, ns=None)
Searches all children of the parent node having given name and namespace href.

>>> find_node = xmlsec.findChild(doc, "Name")
>>> find_node.get_content()
'Really good name'

Information about element:

>>> xml_doc.getRootElement()

<xmlNode (Envelope) object at 0x7ffa545bfab8>



>>> xml_doc.getRootElement().nodePath()

'/soapenv:Envelope'

>>> xml_doc.nodePath()

'/'



>>> xml_doc.get_type()
'document_xml' or 'element'

>>> sign_node.get_name()
'Signature'

Variables:
>>> xmlsec.DSigNs
'http://www.w3.org/2000/09/xmldsig#'




Creating signature:

>>> signNode = xmlsec.TmplSignature(xml_doc, xmlsec.transformExclC14NId(), xmlsec.transformRsaSha1Id(), None)

>>> signNode.__str__()
'<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">\n<SignedInfo>\n<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>\n<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>\n</SignedInfo>\n<SignatureValue/>\n</Signature>'

>>> xmlsec.NodeSignature

'Signature'




Add reference:

>>> ref_node = signNode.addReference(xmlsec.transformSha1Id(), id=None, uri="", type=None)
>>> print(ref_node)
<Reference URI="">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue/>
</Reference>




Finding elements:



>>> xmlsec.findNode(xml_doc.getRootElement(), "Header", "http://website.com/schema/Method" )
<xmlNode (Header) object at 0x7f4e9804f710>





keyDataAesId()
The AES key data id.

keyDataX509Id()
The X509 key data id.

keyDataXmlWrite(id, key, node, keyInfoCtx)
Writes the key data of klass id from key to an XML node.

keyInfoNodeRead(keyInfoNode, key, keyInfoCtx)
Parses the <dsig:KeyInfo/> element keyInfoNode, extracts the key data and
stores into key.

keyInfoNodeWrite(keyInfoNode, key, keyInfoCtx)
Writes the key into the <dsig:KeyInfo/> element template keyInfoNode.

Resources:

libxml2

libxml2 tutorial - https://www.xml.com/pub/a/2003/05/14/py-xml.html
TODO:tocheck parsing file with libxml2 example -  https://www.programcreek.com/python/example/8012/libxml2.parseFile
Documentation - http://xmlsoft.org/python.html

pyXMLSec