source: TI12-security/trunk/python/Tests/xmlsec/decrypt3-tmp.py @ 1415

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/Tests/xmlsec/decrypt3-tmp.py@1415
Revision 1415, 7.7 KB checked in by pjkersha, 13 years ago (diff)

Include XML Security test programs.

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2#
3# $Id: decrypt3.py,v 1.4 2004/01/25 00:31:12 valos Exp $
4#
5# PyXMLSec example: Decrypting an encrypted file using a custom keys manager.
6#
7# Decrypts encrypted XML file using a custom files based keys manager.
8# We assume that key's name in <dsig:KeyName/> element is just
9# key's file name in the current folder.
10#
11# Usage:
12#       ./decrypt3.py <xml-enc>
13#
14# Example:
15#       ./decrypt3.py encrypt1-res.xml
16#       ./decrypt3.py encrypt2-res.xml
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 os, sys
25sys.path.insert(0, '../')
26
27import libxml2
28import xmlsec
29
30def main():
31    assert(sys.argv)
32   
33    # Add private key file as command line argument
34    #
35    # PJK
36    if len(sys.argv) != 3:
37#    if len(sys.argv) != 2:
38        print "Error: wrong number of arguments."
39#        print "Usage: %s <enc-file>" % sys.argv[0]
40        print "Usage: %s <enc-file> <private key file>" % sys.argv[0]
41
42        return sys.exit(1)
43   
44    res = 0
45    # Init libxml library
46    libxml2.initParser()
47    libxml2.substituteEntitiesDefault(1)
48
49    # Init xmlsec library
50    if xmlsec.init() < 0:
51        print "Error: xmlsec initialization failed."
52        return sys.exit(-1)
53   
54    # Check loaded library version
55    if xmlsec.checkVersion() != 1:
56        print "Error: loaded xmlsec library version is not compatible."
57        sys.exit(-1)
58
59    # Init crypto library
60    if xmlsec.cryptoAppInit(None) < 0:
61        print "Error: crypto initialization failed."
62   
63    # Init xmlsec-crypto library
64    if xmlsec.cryptoInit() < 0:
65        print "Error: xmlsec-crypto initialization failed."
66
67    # Create keys manager and load keys */
68    #mngr = create_files_keys_mngr()
69    mngr = loadPriKey(sys.argv[2])
70   
71    if mngr is not None:
72        res = decrypt_file(mngr, sys.argv[1])
73
74    # Shutdown xmlsec-crypto library
75    xmlsec.cryptoShutdown()
76
77    # Shutdown crypto library
78    xmlsec.cryptoAppShutdown()
79
80    # Shutdown xmlsec library
81    xmlsec.shutdown()
82
83    # Shutdown LibXML2
84    libxml2.cleanupParser()
85
86    sys.exit(res)
87
88
89# Callback function
90def getKeyCallback(keyInfoNode, keyInfoCtx):
91    # Convert PyCObject object into xmlNode and KeyInfoCtx Objects
92    node = libxml2.xmlNode(_obj=keyInfoNode)
93    ctx = xmlsec.KeyInfoCtx(_obj=keyInfoCtx)
94    return xmlsec.keysMngrGetKey(node, ctx)
95
96
97# Creates a files based keys manager
98# we assume that key name is the key file name
99# Returns newly created keys manager or None if an error occurs.
100def create_files_keys_mngr():
101    # Create files based keys store
102    storeId = xmlsec.KeyStoreId(0, 0, "files-based-keys-store",
103                                None, None, files_keys_store_find_key)
104    keysStore = xmlsec.KeyStore(storeId)
105
106    if keysStore is None:
107        print "Error: failed to create keys store."
108        return None
109   
110    # Create keys manager
111    mngr = xmlsec.KeysMngr()
112    if mngr is None:
113        print "Error: failed to create keys manager."
114        keysStore.destroy()
115        return None
116
117    # Add store to keys manager, from now on keys manager destroys the store
118    # if needed
119    if mngr.adoptKeysStore(keysStore) < 0:
120        print "Error: failed to add keys store to keys manager."
121        keysStore.destroy()
122        mngr.destroy()
123        return None
124   
125    # Initialize crypto library specific data in keys manager
126    if xmlsec.cryptoKeysMngrInit(mngr) < 0:
127        print "Error: failed to initialize crypto data in keys manager."
128        keysStore.destroy()
129        mngr.destroy()
130        return None
131
132    # Set the get key callback
133    mngr.getKey = getKeyCallback
134    return mngr
135
136
137# Decrypts the XML file enc_file using DES key files in mngr and
138# prints results to stdout.
139#
140# Returns 0 on success or a negative value if an error occurs.
141def decrypt_file(mngr, enc_file):
142    assert(mngr)
143    assert(enc_file)
144
145    # Load template
146    if not check_filename(enc_file):
147        return -1
148    doc = libxml2.parseFile(enc_file)
149    if doc is None or doc.getRootElement() is None:
150        print "Error: unable to parse file \"%s\"" % enc_file
151        return cleanup(doc)
152   
153    # Find start node
154    node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeEncryptedData,
155                           xmlsec.EncNs)
156    if node is None:
157        print "Error: start node not found in \"%s\"" % tmpl_file
158        return cleanup(doc)
159   
160    # Create encryption context
161    enc_ctx = xmlsec.EncCtx(mngr)
162    if enc_ctx is None:
163        print "Error: failed to create encryption context"
164        return cleanup(doc)
165
166    # Decrypt the data
167    if enc_ctx.decrypt(node) < 0 or enc_ctx.result is None:
168        print "Error: decryption failed"
169        return cleanup(doc, enc_ctx)
170
171    # Print decrypted data to stdout
172    if enc_ctx.resultReplaced != 0:
173        print "Decrypted XML data:"
174        doc.dump("-")
175    else:
176        print "Decrypted binary data (%d bytes):" % enc_ctx.result.getSize()
177        print enc_ctx.result.getData()
178
179    # Success
180    return cleanup(doc, enc_ctx, 1)
181
182
183# Lookups key in the store. The caller is responsible for destroying
184# returned key with destroy method.
185#
186# Returns key or None if key not found or an error occurs.
187def files_keys_store_find_key(store, name, keyInfoCtx):
188    assert(store)
189    assert(keyInfoCtx)
190   
191    ctx = xmlsec.KeyInfoCtx(_obj=keyInfoCtx)
192   
193    # It's possible to do not have the key name or desired key type
194    # but we could do nothing in this case
195    if name is None or ctx.keyReq.keyId == xmlsec.KeyDataIdUnknown:
196        print "Return None"
197        return None
198   
199    if ctx.keyReq.keyId == xmlsec.keyDataDsaId() or ctx.keyReq.keyId == xmlsec.keyDataRsaId():
200        # Load key from a pem file, if key is not found then it's an error (is it?)
201        key = xmlsec.CryptoAppKeyLoad(name, xmlsec.KeyDataFormatPem, None, None, None)
202        if key is None:
203            print "Error: failed to load public pem key from \"%s\"" % name
204            return None
205    else:
206        # Otherwise it's a binary key, if key is not found then it's an error (is it?)
207        key = xmlsec.keyReadBinaryFile(ctx.keyReq.keyId, name)
208        if key is None:
209            print "Error: failed to load key from binary file \"%s\"" % name
210            return None
211   
212    # Set key name
213    if key.setName(name) < 0:
214        print "Error: failed to set key name for key from \"%s\"" % name
215        key.destroy();
216        return None
217   
218    return key
219
220
221# Load private key into a simple keys manager
222#
223# PJK
224def loadPriKey(file):
225    assert(file)
226
227    # Create and initialize keys manager, we use a simple list based
228    # keys manager, implement your own KeysStore klass if you need
229    # something more sophisticated
230    mngr = xmlsec.KeysMngr()
231    if mngr is None:
232        print "Error: failed to create keys manager."
233        return None
234    if xmlsec.cryptoAppDefaultKeysMngrInit(mngr) < 0:
235        print "Error: failed to initialize keys manager."
236        mngr.destroy()
237        return None
238   
239    key = xmlsec.cryptoAppKeyLoad(file, xmlsec.KeyDataFormatPem, None, None, None)
240    if key is None:
241        print "Error: failed to load private key from file \"%s\"" % file
242        mngr.destroy()
243        return None
244   
245    # Add key to keys manager, from now on keys manager is responsible
246    # for destroying key
247    if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0:
248        print "Error: failed to add key from \"%s\" to keys manager" % file
249        key.destroy()
250        mngr.destroy()
251        return None
252   
253    return mngr
254
255
256def cleanup(doc=None, enc_ctx=None, res=-1):
257    if enc_ctx is not None:
258        enc_ctx.destroy()
259    if doc is not None:
260        doc.freeDoc()
261    return res
262
263
264def check_filename(filename):
265    if os.access(filename, os.R_OK):
266        return 1
267    else:
268        print "Error: XML file \"%s\" not found OR no read access" % filename
269        return 0
270
271
272if __name__ == "__main__":
273    main()
Note: See TracBrowser for help on using the repository browser.