source: TI12-security/trunk/NDGSecurity/python/Tests/xmlsec/sign2.py @ 7080

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/Tests/xmlsec/sign2.py@7080
Revision 7080, 4.7 KB checked in by pjkersha, 9 years ago (diff)
  • Property svn:keywords set to Id
Line 
1#!/usr/bin/env python
2#
3# $Id$
4#
5# PyXMLSec example: Signing a file with a dynamicaly created template.
6#
7# Signs a file using a dynamicaly created template and key from PEM file.
8# The signature has one reference with one enveloped transform to sign
9# the whole document except the <dsig:Signature/> node itself.
10#
11# Usage:
12#       ./sign2.py <xml-doc> <pem-key>
13#
14# Example:
15#       ./sign2.py sign2-doc.xml rsakey.pem > sign2-res.xml
16#
17# The result signature could be validated using verify1 example:
18#       ./verify1.py sign2-res.xml rsapub.pem
19#
20# This is free software; see COPYING file in the source
21# distribution for preciese wording.
22#
23# Copyright (C) 2003-2004 Valery Febvre <vfebvre@easter-eggs.com>
24#
25
26import sys
27sys.path.insert(0, '../')
28
29import libxml2
30import xmlsec
31
32def main():
33    assert(sys.argv)
34    if len(sys.argv) < 3:
35        print "Error: wrong number of arguments."
36        print "Usage: %s <xml-tmpl> <pem-key>" % sys.argv[0]
37        return sys.exit(1)
38   
39    # Init libxml library
40    libxml2.initParser()
41    libxml2.substituteEntitiesDefault(1)
42
43    # Init xmlsec library
44    if xmlsec.init() < 0:
45        print "Error: xmlsec initialization failed."
46        return sys.exit(-1)
47   
48    # Check loaded library version
49    if xmlsec.checkVersion() != 1:
50        print "Error: loaded xmlsec library version is not compatible.\n"
51        sys.exit(-1)
52
53    # Init crypto library
54    if xmlsec.cryptoAppInit(None) < 0:
55        print "Error: crypto initialization failed."
56   
57    # Init xmlsec-crypto library
58    if xmlsec.cryptoInit() < 0:
59        print "Error: xmlsec-crypto initialization failed."
60
61    res = sign_file(sys.argv[1], sys.argv[2])
62
63    # Shutdown xmlsec-crypto library
64    xmlsec.cryptoShutdown()
65
66    # Shutdown crypto library
67    xmlsec.cryptoAppShutdown()
68
69    # Shutdown xmlsec library
70    xmlsec.shutdown()
71
72    # Shutdown LibXML2
73    libxml2.cleanupParser()
74
75    sys.exit(res)
76
77# Signs the xml_file using private key from key_file and dynamicaly
78# created enveloped signature template.
79# Returns 0 on success or a negative value if an error occurs.
80def sign_file(xml_file, key_file):
81    assert(xml_file)
82    assert(key_file)
83
84    # Load template
85    doc = libxml2.parseFile(xml_file)
86    if doc is None or doc.getRootElement() is None:
87        print "Error: unable to parse file \"%s\"" % xml_file
88        return cleanup(doc)
89
90    # Create signature template for RSA-SHA1 enveloped signature
91    signNode = xmlsec.TmplSignature(doc, xmlsec.transformExclC14NId(),
92                                    xmlsec.transformRsaSha1Id(), None)
93    if signNode is None:
94        print "Error: failed to create signature template"
95        return cleanup(doc)
96   
97    # Add <dsig:Signature/> node to the doc
98    doc.getRootElement().addChild(signNode)
99
100    # Add reference
101    refNode = signNode.addReference(xmlsec.transformSha1Id(),
102                                    None, None, None)
103    if refNode is None:
104        print "Error: failed to add reference to signature template"
105        return cleanup(doc)
106
107    # Add enveloped transform
108    if refNode.addTransform(xmlsec.transformEnvelopedId()) is None:
109        print "Error: failed to add enveloped transform to reference"
110        return cleanup(doc)
111
112    # Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name
113    # in the signed document
114    keyInfoNode = signNode.ensureKeyInfo(None)
115    if keyInfoNode is None:
116        print "Error: failed to add key info"
117        return cleanup(doc)
118   
119    keyNameInfo = keyInfoNode.addKeyName(None)
120    if keyNameInfo is None:
121        print "Error: failed to add key name"
122        return cleanup(doc)
123
124    # Create signature context, we don't need keys manager in this example
125    dsig_ctx = xmlsec.DSigCtx()
126    if dsig_ctx is None:
127        print "Error: failed to create signature context"
128        return cleanup(doc)
129
130    # Load private key, assuming that there is not password
131    key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
132                                  None, None, None)
133    if key is None:
134        print "Error: failed to load private pem key from \"%s\"" % key_file
135        return cleanup(doc, dsig_ctx)
136    dsig_ctx.signKey = key
137
138    # Set key name to the file name, this is just an example!
139    if key.setName(key_file) < 0:
140        print "Error: failed to set key name for key from \"%s\"" % key_file
141        return cleanup(doc, dsig_ctx)
142
143    # Sign the template
144    if dsig_ctx.sign(signNode) < 0:
145        print "Error: signature failed"
146        return cleanup(doc, dsig_ctx)
147
148    # Print signed document to stdout
149    doc.dump("-")
150
151    # Success
152    return cleanup(doc, dsig_ctx, 1)
153
154
155def cleanup(doc=None, dsig_ctx=None, res=-1):
156    if dsig_ctx is not None:
157        dsig_ctx.destroy()
158    if doc is not None:
159        doc.freeDoc()
160    return res
161
162
163if __name__ == "__main__":
164    main()
165
Note: See TracBrowser for help on using the repository browser.