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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/Tests/xmlsec/encrypt3.py@1415
Revision 1415, 7.9 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: encrypt3.py,v 1.3 2004/01/25 00:31:12 valos Exp $
4#
5# PyXMLSec example: Encrypting XML file with a session key and dynamicaly
6# created template.
7#
8# Encrypts XML file using a dynamicaly created template file and a session
9# DES key (encrypted with an RSA key).
10#
11# Usage:
12#       ./encrypt3.py <xml-doc> <rsa-pem-key-file>
13#
14# Example:
15#       ./encrypt3.py encrypt3-doc.xml rsakey.pem > encrypt3-res.xml
16#
17# The result could be decrypted with decrypt3 example:
18#       ./decrypt3.py encrypt3-res.xml
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, os
27sys.path.insert(0, '../')
28
29import libxml2
30import xmlsec
31import pdb
32
33def main():
34    #pdb.set_trace()
35    assert(sys.argv)
36    if len(sys.argv) != 3:
37        print "Error: wrong number of arguments."
38        print "Usage: %s <xml-file> <key-file>" % sys.argv[0]
39        return sys.exit(1)
40   
41    # Init libxml library
42    libxml2.initParser()
43    libxml2.substituteEntitiesDefault(1)
44
45    # Init xmlsec library
46    if xmlsec.init() < 0:
47        print "Error: xmlsec initialization failed."
48        return sys.exit(-1)
49   
50    # Check loaded library version
51    if xmlsec.checkVersion() != 1:
52        print "Error: loaded xmlsec library version is not compatible.\n"
53        sys.exit(-1)
54
55    # Init crypto library
56    if xmlsec.cryptoAppInit(None) < 0:
57        print "Error: crypto initialization failed."
58   
59    # Init xmlsec-crypto library
60    if xmlsec.cryptoInit() < 0:
61        print "Error: xmlsec-crypto initialization failed."
62
63    # Create keys manager and load keys
64    mngr = load_rsa_keys(sys.argv[2])
65
66    # We use key filename as key name here
67    if mngr is not None:
68        res = encrypt_file(mngr, sys.argv[1], sys.argv[2])
69        # Destroy keys manager
70        mngr.destroy()
71   
72    # Shutdown xmlsec-crypto library
73    xmlsec.cryptoShutdown()
74
75    # Shutdown crypto library
76    xmlsec.cryptoAppShutdown()
77
78    # Shutdown xmlsec library
79    xmlsec.shutdown()
80
81    # Shutdown LibXML2
82    libxml2.cleanupParser()
83
84    sys.exit(res)
85
86
87# Creates simple keys manager and load RSA key from key_file in it.
88# The caller is responsible for destroying returned keys manager using destroy.
89#
90# Returns the newly created keys manager or None if an error occurs.
91def load_rsa_keys(key_file):
92    assert(key_file)
93
94    # Create and initialize keys manager, we use a simple list based
95    # keys manager, implement your own KeysStore klass if you need
96    # something more sophisticated
97    mngr = xmlsec.KeysMngr()
98    if mngr is None:
99        print "Error: failed to create keys manager."
100        return None
101    if xmlsec.cryptoAppDefaultKeysMngrInit(mngr) < 0:
102        print "Error: failed to initialize keys manager."
103        mngr.destroy()
104        return None
105    # Load private RSA key
106    if not check_filename(key_file):
107        mngr.destroy()
108        return None
109    key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
110                                  None, None, None);
111    if key is None:
112        print "Error: failed to load rsa key from file \"%s\"" % key_file
113        mngr.destroy()
114        return None
115    # Set key name to the file name, this is just an example!
116    if key.setName(key_file) < 0:
117        print "Error: failed to set key name for key from \"%s\"" % key_file
118        key.destroy()
119        mngr.destroy()
120        return None
121    # Add key to keys manager, from now on keys manager is responsible
122    # for destroying key
123    if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0:
124        print "Error: failed to add key from \"%s\" to keys manager" % file
125        key.destroy()
126        mngr.destroy()
127        return None
128    return mngr
129
130
131# Encrypts xml_file using a dynamicaly created template, a session DES key
132# and an RSA key from keys manager.
133# Returns 0 on success or a negative value if an error occurs.
134def encrypt_file(mngr, xml_file, key_name):
135    assert(mngr)
136    assert(xml_file)
137    assert(key_name)
138
139    # Load template
140    if not check_filename(xml_file):
141        return -1
142    doc = libxml2.parseFile(xml_file)
143    if doc is None or doc.getRootElement() is None:
144        print "Error: unable to parse file \"%s\"" % xml_file
145        return cleanup(doc)
146
147    # Create encryption template to encrypt XML file and replace
148    # its content with encryption result
149    enc_data_node = xmlsec.TmplEncData(doc, xmlsec.transformDes3CbcId(),
150                                       None, xmlsec.TypeEncElement, None, None)
151    if enc_data_node is None:
152        print "Error: failed to create encryption template"
153        cleanup(doc)
154
155    # We want to put encrypted data in the <enc:CipherValue/> node
156    if enc_data_node.ensureCipherValue() is None:
157        print "Error: failed to add CipherValue node"
158        cleanup(doc, enc_data_node)
159
160    # add <dsig:KeyInfo/>
161    key_info_node = enc_data_node.ensureKeyInfo(None)
162    if key_info_node is None:
163        print "Error: failed to add key info"
164        cleanup(doc, enc_data_node)
165
166    # Add <enc:EncryptedKey/> to store the encrypted session key
167    enc_key_node = key_info_node.addEncryptedKey(xmlsec.transformRsaOaepId(), 
168                                               None, None, None)
169    if enc_key_node is None:
170        print "Error: failed to add key info"
171        cleanup(doc, enc_data_node)
172
173    # We want to put encrypted key in the <enc:CipherValue/> node
174    if enc_key_node.ensureCipherValue() is None:
175        print "Error: failed to add CipherValue node"
176        cleanup(doc, enc_data_node)
177
178    # Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to <enc:EncryptedKey/>
179    key_info_node2 = enc_key_node.ensureKeyInfo(None)
180    if key_info_node2 is None:
181        print "Error: failed to add key info"
182        cleanup(doc, enc_data_node)
183   
184    # Set key name so we can lookup key when needed
185##    if key_info_node2.addKeyName(key_name) is None:
186##      print "Error: failed to add key name"
187##        cleanup(doc, enc_data_node)
188
189
190    # P J Kershaw 06/09/05
191    x509DataNode = key_info_node2.addX509Data()
192    if x509DataNode is None:
193        print "Error adding X509Data node"
194        cleanup(doc, enc_data_node)
195
196##    if xmlsec.addChild(x509DataNode,
197##                       xmlsec.NodeX509Certificate) is None:
198##        print "Error adding %s node" % xmlsec.NodeX509Certificate
199##        cleanup(doc, enc_data_node)
200       
201    if xmlsec.addChild(x509DataNode,
202                       xmlsec.NodeX509SubjectName) is None:
203        print "Error adding %s node" % xmlsec.NodeX509SubjectName
204        cleanup(doc, enc_data_node)
205##       
206##    if xmlsec.addChild(x509DataNode,
207##                       xmlsec.NodeX509IssuerSerial) is None:
208##        print "Error adding %s node" % xmlsec.NodeX509IssuerSerial
209##        cleanup(doc, enc_data_node)
210
211       
212    # Create encryption context
213    enc_ctx = xmlsec.EncCtx(mngr)
214    if enc_ctx is None:
215        print "Error: failed to create encryption context"
216        cleanup(doc, enc_data_node)
217
218    # Generate a Triple DES key
219    key = xmlsec.keyGenerate(xmlsec.keyDataDesId(), 192,
220                             xmlsec.KeyDataTypeSession)
221    if key is None:
222        print "Error: failed to generate session DES key"
223        cleanup(doc, enc_data_node)
224
225    enc_ctx.encKey = key
226
227    # Encrypt the data
228    if enc_ctx.xmlEncrypt(enc_data_node, doc.getRootElement()) < 0:
229        print "Error: encryption failed"
230        return cleanup(doc, enc_data_node, enc_ctx)
231
232    doc.dump("-")
233
234    # Success
235    return cleanup(doc, None, enc_ctx, 1)
236
237
238def cleanup(doc=None, enc_data_node=None, enc_ctx=None, res=-1):
239    if enc_ctx is not None:
240        enc_ctx.destroy()
241    if enc_data_node is not None:
242         enc_data_node.freeNode()
243    if doc is not None:
244        doc.freeDoc()
245    return res
246
247
248def check_filename(filename):
249    if os.access(filename, os.R_OK):
250        return 1
251    else:
252        print "Error: XML file \"%s\" not found OR no read access" % filename
253        return 0
254
255
256if __name__ == "__main__":
257    main()
Note: See TracBrowser for help on using the repository browser.