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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/Tests/xmlsec/verify3-alt.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: Verifying a file signed with X509 certificate
6#
7# Verifies a file signed with X509 certificate.
8#
9# This example was developed and tested with OpenSSL crypto library. The
10# certificates management policies for another crypto library may break it.
11#
12# Usage:
13#       verify3.py <signed-file> <trusted-cert-pem-file1> [<trusted-cert-pem-file2> [...]]
14#
15# Example:
16#       ./verify3.py sign3-res.xml rootcert.pem
17#
18# This is free software; see COPYING file in the source
19# distribution for preciese wording.
20#
21# Copyright (C) 2003-2004 Valery Febvre <vfebvre@easter-eggs.com>
22#
23
24import sys, os
25sys.path.insert(0, '../')
26
27import libxml2
28import xmlsec
29
30def main():
31    assert(sys.argv)
32    if len(sys.argv) < 3:
33        print "Error: wrong number of arguments."
34        print "Usage: %s <xml-file> <cert-file1> [<cert-file2> [...]]" % sys.argv[0]
35        return sys.exit(1)
36   
37    # Init libxml library
38    libxml2.initParser()
39    libxml2.substituteEntitiesDefault(1)
40
41    # Init xmlsec library
42    if xmlsec.init() < 0:
43        print "Error: xmlsec initialization failed."
44        return sys.exit(-1)
45   
46    # Check loaded library version
47    if xmlsec.checkVersion() != 1:
48        print "Error: loaded xmlsec library version is not compatible.\n"
49        sys.exit(-1)
50
51    # Init crypto library
52    if xmlsec.cryptoAppInit(None) < 0:
53        print "Error: crypto initialization failed."
54   
55    # Init xmlsec-crypto library
56    if xmlsec.cryptoInit() < 0:
57        print "Error: xmlsec-crypto initialization failed."
58
59    # Create keys manager and load trusted certificates
60    mngr = load_trusted_certs(sys.argv[2:], len(sys.argv) - 2)
61
62    # Verify file
63    if mngr is not None:
64        res = verify_file(mngr, sys.argv[1])
65        # Destroy keys manager
66        mngr.destroy()
67   
68    # Shutdown xmlsec-crypto library
69    xmlsec.cryptoShutdown()
70
71    # Shutdown crypto library
72    xmlsec.cryptoAppShutdown()
73
74    # Shutdown xmlsec library
75    xmlsec.shutdown()
76
77    # Shutdown LibXML2
78    libxml2.cleanupParser()
79
80    sys.exit(res)
81
82
83# Creates simple keys manager and load trusted certificates from PEM files.
84# The caller is responsible for destroying returned keys manager using
85# destroy method.
86#
87# Returns the newly created keys manager or None if an error occurs.
88def load_trusted_certs(files, files_size):
89    assert(files)
90    assert(files_size > 0)
91
92    # Create and initialize keys manager, we use a simple list based
93    # keys manager, implement your own KeysStore klass if you need
94    # something more sophisticated
95    mngr = xmlsec.KeysMngr()
96    if mngr is None:
97        print "Error: failed to create keys manager."
98        return None
99    if xmlsec.cryptoAppDefaultKeysMngrInit(mngr) < 0:
100        print "Error: failed to initialize keys manager."
101        mngr.destroy()
102        return None
103    for file in files:
104        if not check_filename(file):
105            mngr.destroy()
106            return None
107        # Load trusted cert
108        if mngr.certLoad(file, xmlsec.KeyDataFormatPem,
109                         xmlsec.KeyDataTypeTrusted) < 0:
110            print "Error: failed to load pem certificate from \"%s\"", file
111            mngr.destroy()
112            return None
113    return mngr
114
115
116# Verifies XML signature in xml_file.
117# Returns 0 on success or a negative value if an error occurs.
118def verify_file(mngr, xml_file):
119    assert(mngr)
120    assert(xml_file)
121
122    # Load XML file
123    if not check_filename(xml_file):
124        return -1
125    doc = libxml2.parseFile(xml_file)
126    if doc is None or doc.getRootElement() is None:
127        print "Error: unable to parse file \"%s\"" % tmpl_file
128        return cleanup(doc)
129
130    # Find start node
131    node = xmlsec.findNode(doc.getRootElement(),
132                           xmlsec.NodeSignature, xmlsec.DSigNs)
133    if node is None:
134        print "Error: start node not found in \"%s\"", xml_file
135
136    # Create signature context
137    dsig_ctx = xmlsec.DSigCtx(mngr)
138    if dsig_ctx is None:
139        print "Error: failed to create signature context"
140        return cleanup(doc)
141
142    # Verify signature
143    if dsig_ctx.verify(node) < 0:
144        print "Error: signature verify"
145        return cleanup(doc, dsig_ctx)
146
147    # Print verification result to stdout
148    if dsig_ctx.status == xmlsec.DSigStatusSucceeded:
149        print "Signature is OK"
150    else:
151        print "Signature is INVALID"
152
153    # Success
154    return cleanup(doc, dsig_ctx, 1)
155
156
157def cleanup(doc=None, dsig_ctx=None, res=-1):
158    if dsig_ctx is not None:
159        dsig_ctx.destroy()
160    if doc is not None:
161        doc.freeDoc()
162    return res
163
164
165def check_filename(filename):
166    if os.access(filename, os.R_OK):
167        return 1
168    else:
169        print "Error: XML file \"%s\" not found OR no read access" % filename
170        return 0
171
172
173if __name__ == "__main__":
174    main()
Note: See TracBrowser for help on using the repository browser.