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

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/Tests/xmlsec/encrypt3-tmp.py@1415
Revision 1415, 7.3 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   
110    # Load in as PEM Cert - '7' is equivalent to XMLSec 'xmlSecKeyDataFormatCertPem' enumerated type
111    #
112    # PJK
113    key = xmlsec.cryptoAppKeyLoad(key_file, 7,
114                                  None, None, None);
115#    key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
116#                                  None, None, None);
117    if key is None:
118        print "Error: failed to load rsa key from file \"%s\"" % key_file
119        mngr.destroy()
120        return None
121    # Set key name to the file name, this is just an example!
122    if key.setName(key_file) < 0:
123        print "Error: failed to set key name for key from \"%s\"" % key_file
124        key.destroy()
125        mngr.destroy()
126        return None
127       
128    # Add key to keys manager, from now on keys manager is responsible
129    # for destroying key
130    if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(mngr, key) < 0:
131        print "Error: failed to add key from \"%s\" to keys manager" % file
132        key.destroy()
133        mngr.destroy()
134        return None
135    return mngr
136
137
138# Encrypts xml_file using a dynamicaly created template, a session DES key
139# and an RSA key from keys manager.
140# Returns 0 on success or a negative value if an error occurs.
141def encrypt_file(mngr, xml_file, key_name):
142    assert(mngr)
143    assert(xml_file)
144    assert(key_name)
145
146    # Load template
147    if not check_filename(xml_file):
148        return -1
149    doc = libxml2.parseFile(xml_file)
150    if doc is None or doc.getRootElement() is None:
151        print "Error: unable to parse file \"%s\"" % xml_file
152        return cleanup(doc)
153
154    # Create encryption template to encrypt XML file and replace
155    # its content with encryption result
156    enc_data_node = xmlsec.TmplEncData(doc, xmlsec.transformDes3CbcId(),
157                                       None, xmlsec.TypeEncElement, None, None)
158    if enc_data_node is None:
159        print "Error: failed to create encryption template"
160        cleanup(doc)
161
162    # We want to put encrypted data in the <enc:CipherValue/> node
163    if enc_data_node.ensureCipherValue() is None:
164        print "Error: failed to add CipherValue node"
165        cleanup(doc, enc_data_node)
166
167    # add <dsig:KeyInfo/>
168    key_info_node = enc_data_node.ensureKeyInfo(None)
169    if key_info_node is None:
170        print "Error: failed to add key info"
171        cleanup(doc, enc_data_node)
172
173    # Add <enc:EncryptedKey/> to store the encrypted session key
174    enc_key_node = key_info_node.addEncryptedKey(xmlsec.transformRsaOaepId(), 
175                                               None, None, None)
176    if enc_key_node is None:
177        print "Error: failed to add key info"
178        cleanup(doc, enc_data_node)
179
180    # We want to put encrypted key in the <enc:CipherValue/> node
181    if enc_key_node.ensureCipherValue() is None:
182        print "Error: failed to add CipherValue node"
183        cleanup(doc, enc_data_node)
184
185    # Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to <enc:EncryptedKey/>
186    key_info_node2 = enc_key_node.ensureKeyInfo(None)
187    if key_info_node2 is None:
188        print "Error: failed to add key info"
189        cleanup(doc, enc_data_node)
190
191    # Key name not needed - PJK
192    #   
193    # Set key name so we can lookup key when needed
194    if key_info_node2.addKeyName(key_name) is None:
195        print "Error: failed to add key name"
196        cleanup(doc, enc_data_node)
197       
198    # Create encryption context
199    enc_ctx = xmlsec.EncCtx(mngr)
200    if enc_ctx is None:
201        print "Error: failed to create encryption context"
202        cleanup(doc, enc_data_node)
203
204    # Generate a Triple DES key
205    key = xmlsec.keyGenerate(xmlsec.keyDataDesId(), 192,
206                             xmlsec.KeyDataTypeSession)
207    if key is None:
208        print "Error: failed to generate session DES key"
209        cleanup(doc, enc_data_node)
210
211    enc_ctx.encKey = key
212
213    # Encrypt the data
214    if enc_ctx.xmlEncrypt(enc_data_node, doc.getRootElement()) < 0:
215        print "Error: encryption failed"
216        return cleanup(doc, enc_data_node, enc_ctx)
217
218    doc.dump("-")
219
220    # Success
221    return cleanup(doc, None, enc_ctx, 1)
222
223
224def cleanup(doc=None, enc_data_node=None, enc_ctx=None, res=-1):
225    if enc_ctx is not None:
226        enc_ctx.destroy()
227    if enc_data_node is not None:
228         enc_data_node.freeNode()
229    if doc is not None:
230        doc.freeDoc()
231    return res
232
233
234def check_filename(filename):
235    if os.access(filename, os.R_OK):
236        return 1
237    else:
238        print "Error: XML file \"%s\" not found OR no read access" % filename
239        return 0
240
241
242if __name__ == "__main__":
243    main()
Note: See TracBrowser for help on using the repository browser.