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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/Tests/xmlsec/encrypt4.py@1415
Revision 1415, 8.1 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], "badc-aa-key.pem")
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        res = encrypt_file(mngr, sys.argv[1], "badc-aa-key.pem")
70        # Destroy keys manager
71        mngr.destroy()
72   
73    # Shutdown xmlsec-crypto library
74    xmlsec.cryptoShutdown()
75
76    # Shutdown crypto library
77    xmlsec.cryptoAppShutdown()
78
79    # Shutdown xmlsec library
80    xmlsec.shutdown()
81
82    # Shutdown LibXML2
83    libxml2.cleanupParser()
84
85    sys.exit(res)
86
87
88# Creates simple keys manager and load RSA key from key_file in it.
89# The caller is responsible for destroying returned keys manager using destroy.
90#
91# Returns the newly created keys manager or None if an error occurs.
92def load_rsa_keys(key_file, priKeyFilePath):
93    assert(key_file)
94
95    # Create and initialize keys manager, we use a simple list based
96    # keys manager, implement your own KeysStore klass if you need
97    # something more sophisticated
98    mngr = xmlsec.KeysMngr()
99    if mngr is None:
100        print "Error: failed to create keys manager."
101        return None
102    if xmlsec.cryptoAppDefaultKeysMngrInit(mngr) < 0:
103        print "Error: failed to initialize keys manager."
104        mngr.destroy()
105        return None
106    # Load private RSA key
107    if not check_filename(key_file):
108        mngr.destroy()
109        return None
110#    key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
111#                                  None, None, None);
112    key = xmlsec.cryptoAppKeyLoad(key_file, 7,
113                                  None, None, None);
114    if key is None:
115        print "Error: failed to load rsa key from file \"%s\"" % key_file
116        mngr.destroy()
117        return None
118    # Set key name to the file name, this is just an example!
119    if key.setName(priKeyFilePath) < 0:
120        print "Error: failed to set key name for key from \"%s\"" % key_file
121        key.destroy()
122        mngr.destroy()
123        return None
124    # Add key to keys manager, from now on keys manager is responsible
125    # for destroying key
126    if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0:
127        print "Error: failed to add key from \"%s\" to keys manager" % file
128        key.destroy()
129        mngr.destroy()
130        return None
131    return mngr
132
133
134# Encrypts xml_file using a dynamicaly created template, a session DES key
135# and an RSA key from keys manager.
136# Returns 0 on success or a negative value if an error occurs.
137def encrypt_file(mngr, xml_file, key_name):
138    assert(mngr)
139    assert(xml_file)
140    assert(key_name)
141
142    # Load template
143    if not check_filename(xml_file):
144        return -1
145    doc = libxml2.parseFile(xml_file)
146    if doc is None or doc.getRootElement() is None:
147        print "Error: unable to parse file \"%s\"" % xml_file
148        return cleanup(doc)
149
150    # Create encryption template to encrypt XML file and replace
151    # its content with encryption result
152    enc_data_node = xmlsec.TmplEncData(doc, xmlsec.transformDes3CbcId(),
153                                       None, xmlsec.TypeEncElement, None, None)
154    if enc_data_node is None:
155        print "Error: failed to create encryption template"
156        cleanup(doc)
157
158    # We want to put encrypted data in the <enc:CipherValue/> node
159    if enc_data_node.ensureCipherValue() is None:
160        print "Error: failed to add CipherValue node"
161        cleanup(doc, enc_data_node)
162
163    # add <dsig:KeyInfo/>
164    key_info_node = enc_data_node.ensureKeyInfo(None)
165    if key_info_node is None:
166        print "Error: failed to add key info"
167        cleanup(doc, enc_data_node)
168
169    # Add <enc:EncryptedKey/> to store the encrypted session key
170    enc_key_node = key_info_node.addEncryptedKey(xmlsec.transformRsaOaepId(), 
171                                               None, None, None)
172    if enc_key_node is None:
173        print "Error: failed to add key info"
174        cleanup(doc, enc_data_node)
175
176    # We want to put encrypted key in the <enc:CipherValue/> node
177    if enc_key_node.ensureCipherValue() is None:
178        print "Error: failed to add CipherValue node"
179        cleanup(doc, enc_data_node)
180
181    # Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to <enc:EncryptedKey/>
182    key_info_node2 = enc_key_node.ensureKeyInfo(None)
183    if key_info_node2 is None:
184        print "Error: failed to add key info"
185        cleanup(doc, enc_data_node)
186   
187    # Set key name so we can lookup key when needed
188    if key_info_node2.addKeyName(key_name) is None:
189        print "Error: failed to add key name"
190        cleanup(doc, enc_data_node)
191
192
193    # P J Kershaw 06/09/05
194#    x509DataNode = key_info_node2.addX509Data()
195#    if x509DataNode is None:
196#        print "Error adding X509Data node"
197#        cleanup(doc, enc_data_node)
198
199##    if xmlsec.addChild(x509DataNode,
200##                       xmlsec.NodeX509Certificate) is None:
201##        print "Error adding %s node" % xmlsec.NodeX509Certificate
202##        cleanup(doc, enc_data_node)
203       
204#    if xmlsec.addChild(x509DataNode,
205#                       xmlsec.NodeX509SubjectName) is None:
206#        print "Error adding %s node" % xmlsec.NodeX509SubjectName
207#        cleanup(doc, enc_data_node)
208##       
209##    if xmlsec.addChild(x509DataNode,
210##                       xmlsec.NodeX509IssuerSerial) is None:
211##        print "Error adding %s node" % xmlsec.NodeX509IssuerSerial
212##        cleanup(doc, enc_data_node)
213
214       
215    # Create encryption context
216    enc_ctx = xmlsec.EncCtx(mngr)
217    if enc_ctx is None:
218        print "Error: failed to create encryption context"
219        cleanup(doc, enc_data_node)
220
221    # Generate a Triple DES key
222    key = xmlsec.keyGenerate(xmlsec.keyDataDesId(), 192,
223                             xmlsec.KeyDataTypeSession)
224    if key is None:
225        print "Error: failed to generate session DES key"
226        cleanup(doc, enc_data_node)
227
228    enc_ctx.encKey = key
229
230    # Encrypt the data
231    if enc_ctx.xmlEncrypt(enc_data_node, doc.getRootElement()) < 0:
232        print "Error: encryption failed"
233        return cleanup(doc, enc_data_node, enc_ctx)
234
235    doc.dump("-")
236
237    # Success
238    return cleanup(doc, None, enc_ctx, 1)
239
240
241def cleanup(doc=None, enc_data_node=None, enc_ctx=None, res=-1):
242    if enc_ctx is not None:
243        enc_ctx.destroy()
244    if enc_data_node is not None:
245         enc_data_node.freeNode()
246    if doc is not None:
247        doc.freeDoc()
248    return res
249
250
251def check_filename(filename):
252    if os.access(filename, os.R_OK):
253        return 1
254    else:
255        print "Error: XML file \"%s\" not found OR no read access" % filename
256        return 0
257
258
259if __name__ == "__main__":
260    main()
Note: See TracBrowser for help on using the repository browser.