xmlsig 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +0 -0
- data/ext/xmlsig/BioWrap.h +98 -0
- data/ext/xmlsig/DSig.cpp +109 -0
- data/ext/xmlsig/DSig.h +81 -0
- data/ext/xmlsig/DSigCtx.h +72 -0
- data/ext/xmlsig/Exceptions.cpp +151 -0
- data/ext/xmlsig/Exceptions.h +214 -0
- data/ext/xmlsig/Key.cpp +582 -0
- data/ext/xmlsig/Key.h +338 -0
- data/ext/xmlsig/KeyInfoCtx.h +67 -0
- data/ext/xmlsig/KeyStore.cpp +180 -0
- data/ext/xmlsig/KeyStore.h +157 -0
- data/ext/xmlsig/KeysMngrWrap.h +62 -0
- data/ext/xmlsig/NodeSet.h +60 -0
- data/ext/xmlsig/Signer.cpp +691 -0
- data/ext/xmlsig/Signer.h +373 -0
- data/ext/xmlsig/TrustVerifier.cpp +145 -0
- data/ext/xmlsig/TrustVerifier.h +174 -0
- data/ext/xmlsig/Verifier.cpp +677 -0
- data/ext/xmlsig/Verifier.h +313 -0
- data/ext/xmlsig/X509Certificate.cpp +362 -0
- data/ext/xmlsig/X509Certificate.h +146 -0
- data/ext/xmlsig/XPath.cpp +173 -0
- data/ext/xmlsig/XPath.h +156 -0
- data/ext/xmlsig/XPathCtx.h +68 -0
- data/ext/xmlsig/XmlCharBuf.h +60 -0
- data/ext/xmlsig/XmlDoc.cpp +278 -0
- data/ext/xmlsig/XmlDoc.h +157 -0
- data/ext/xmlsig/XmlElement.cpp +151 -0
- data/ext/xmlsig/XmlElement.h +134 -0
- data/ext/xmlsig/countptr.h +260 -0
- data/ext/xmlsig/extconf.rb +58 -0
- data/ext/xmlsig/runtests.rb +23 -0
- data/ext/xmlsig/swig/countptr.i +27 -0
- data/ext/xmlsig/swig/exceptions.i +79 -0
- data/ext/xmlsig/swig/ruby.i +17 -0
- data/ext/xmlsig/swig/xmlsig.i +405 -0
- data/ext/xmlsig/t/tc_cert.rb +34 -0
- data/ext/xmlsig/t/tc_interface.rb +158 -0
- data/ext/xmlsig/t/tc_signer.rb +501 -0
- data/ext/xmlsig/t/tc_tsik.rb +490 -0
- data/ext/xmlsig/t/tc_verifier.rb +151 -0
- data/ext/xmlsig/t/tsik_interop/sign.rb +48 -0
- data/ext/xmlsig/t/tsik_interop/verify.rb +31 -0
- data/ext/xmlsig/t/tsik_interop/verify_own.rb +46 -0
- data/ext/xmlsig/xmlsig.cpp +13363 -0
- data/lib/xmlsig.rb +1 -0
- metadata +113 -0
@@ -0,0 +1,490 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# (C) Copyright 2006 VeriSign, Inc.
|
4
|
+
# Developed by Sxip Identity
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License")
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'test/unit'
|
19
|
+
require 'xmlsig'
|
20
|
+
|
21
|
+
class TC_TSIK < Test::Unit::TestCase
|
22
|
+
|
23
|
+
|
24
|
+
# def setup
|
25
|
+
# end
|
26
|
+
|
27
|
+
# def teardown
|
28
|
+
# end
|
29
|
+
|
30
|
+
def resdir
|
31
|
+
return 't/res/tsik_tcport/'
|
32
|
+
end
|
33
|
+
|
34
|
+
def publicKey
|
35
|
+
key = Xmlsig::Key.new
|
36
|
+
assert_equal(0, key.loadFromFile(resdir() + 'mypub.pem', 'pem', ''), "loadFromFile of a key")
|
37
|
+
assert_equal(1, key.isValid(), "isValid key")
|
38
|
+
return key
|
39
|
+
end
|
40
|
+
|
41
|
+
def privateKey
|
42
|
+
key = Xmlsig::Key.new
|
43
|
+
assert_equal(0, key.loadFromFile(resdir() + 'mypriv.pem', 'pem', ''), "loadFromFile of a key")
|
44
|
+
assert_equal(1, key.isValid(), "isValid key")
|
45
|
+
key.setName("")
|
46
|
+
return key
|
47
|
+
end
|
48
|
+
|
49
|
+
def loadDoc(filename)
|
50
|
+
doc = Xmlsig::XmlDoc.new
|
51
|
+
fullfilename = resdir() + filename
|
52
|
+
assert_equal(0, doc.loadFromFile(fullfilename), "loadFromFile of a XmlDoc")
|
53
|
+
return doc
|
54
|
+
end
|
55
|
+
|
56
|
+
def sign1(inFileName, privateKey, publicKey, cert)
|
57
|
+
doc = loadDoc(inFileName)
|
58
|
+
if (cert != NIL)
|
59
|
+
signer = Xmlsig::Signer.new(doc, privateKey)
|
60
|
+
signer.addCertFromFile(cert, 'pem')
|
61
|
+
return signer
|
62
|
+
elsif (publicKey != NIL)
|
63
|
+
return Xmlsig::Signer.new(doc, privateKey, publicKey)
|
64
|
+
else
|
65
|
+
return Xmlsig::Signer.new(doc, privateKey)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def sign2(signer, type, outFileName)
|
70
|
+
if (type == "")
|
71
|
+
d = signer.sign()
|
72
|
+
else
|
73
|
+
d = signer.sign(Xmlsig::XPath.new(type))
|
74
|
+
if (outFileName != NIL)
|
75
|
+
d.toFile(outFileName)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
return d
|
79
|
+
end
|
80
|
+
|
81
|
+
def verify(inDoc, signatureLocation, publicKey, mustHavePublicKey, mustHaveCert)
|
82
|
+
xpath = Xmlsig::XPath.new(signatureLocation)
|
83
|
+
xpath.addNamespace("ds", "http://www.w3.org/2000/09/xmldsig#")
|
84
|
+
xpath.addNamespace("s2", "http://ns.s2ml.org/s2ml")
|
85
|
+
xpath.addNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/")
|
86
|
+
xpath.addNamespace("EMS", "http://ems.verisign.com/2001/05/ems-s2ml#")
|
87
|
+
|
88
|
+
verifier = Xmlsig::Verifier.new(inDoc, xpath)
|
89
|
+
pubKey = publicKey
|
90
|
+
if (mustHavePublicKey)
|
91
|
+
pubKey = verifier.getVerifyingKey()
|
92
|
+
if (pubKey == NIL)
|
93
|
+
print("Cannot find public key")
|
94
|
+
return 0
|
95
|
+
end
|
96
|
+
end
|
97
|
+
if (mustHaveCert)
|
98
|
+
cert = verifier.getCertificate()
|
99
|
+
if (cert == NIL)
|
100
|
+
print("Cannot find certificate")
|
101
|
+
return 0
|
102
|
+
end
|
103
|
+
end
|
104
|
+
verified = 0
|
105
|
+
verified = verifier.verify(pubKey) == 1
|
106
|
+
return verified
|
107
|
+
end
|
108
|
+
|
109
|
+
### Port of the TSIK org.apache.tsik.xmlsig.test.XmlSigTest class
|
110
|
+
###
|
111
|
+
|
112
|
+
def test_SignInPlace
|
113
|
+
### TSIK XmlSigTest.testSignInPlace
|
114
|
+
# Load document
|
115
|
+
doc = loadDoc("SomeTest.xml")
|
116
|
+
|
117
|
+
# Sign document
|
118
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), publicKey())
|
119
|
+
xpath = Xmlsig::XPath.new('/')
|
120
|
+
assert_equal(0, signer.signInPlace(xpath), "signInPlace")
|
121
|
+
|
122
|
+
# Verify document
|
123
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
124
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
125
|
+
v = Xmlsig::Verifier.new(doc, xpath)
|
126
|
+
assert_equal(1, v.verify(publicKey()), "Verify")
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_SignInPlace2
|
130
|
+
### TSIK XmlSigTest.testSignInPlace2
|
131
|
+
# Load document
|
132
|
+
doc = loadDoc("Test2.xml")
|
133
|
+
|
134
|
+
# Sign document
|
135
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), publicKey())
|
136
|
+
xpath = Xmlsig::XPath.new('/test/test2')
|
137
|
+
assert_equal(0, signer.signInPlace(xpath, 1), "signInPlace")
|
138
|
+
|
139
|
+
# Verify document
|
140
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
141
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
142
|
+
v = Xmlsig::Verifier.new(doc, xpath)
|
143
|
+
assert_equal(1, v.verify(publicKey()), "Verify")
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_SignInPlaceEnveloping
|
147
|
+
### TSIK XmlSigTest.testSignInPlaceEnveloping
|
148
|
+
# Load document
|
149
|
+
doc = loadDoc("Test2.xml")
|
150
|
+
|
151
|
+
# Sign document
|
152
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), publicKey())
|
153
|
+
assert_equal(0, signer.signInPlace(), "signInPlace")
|
154
|
+
|
155
|
+
# Verify document
|
156
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
157
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
158
|
+
v = Xmlsig::Verifier.new(doc, xpath)
|
159
|
+
assert_equal(1, v.verify(publicKey()), "Verify")
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_VerifyingKeyWithCerts
|
163
|
+
### TSIK XmlSigTest.testVerifyingKeyWithCerts
|
164
|
+
doc = loadDoc('in.xml')
|
165
|
+
cert = Xmlsig::X509Certificate.new
|
166
|
+
if (cert.loadFromFile(resdir() + 'mycert.x509', 'cert_pem') < 0)
|
167
|
+
raise "IOException - Couldn't load 'mycert.x509'"
|
168
|
+
end
|
169
|
+
verifyingKey = cert.getKey()
|
170
|
+
# Sign document
|
171
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), verifyingKey)
|
172
|
+
xpath = Xmlsig::XPath.new('/')
|
173
|
+
d = signer.sign(xpath)
|
174
|
+
|
175
|
+
# Verify document
|
176
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
177
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
178
|
+
v = Xmlsig::Verifier.new(d, xpath)
|
179
|
+
v.setKeyStore(Xmlsig::KeyStore.new)
|
180
|
+
assert_equal(1, v.verify(publicKey()), "Verify")
|
181
|
+
assert_equal(1, v.verify(), "Verify")
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_SigningAndVerifyingKey
|
185
|
+
### TSIK XmlSigTest.testSigningAndVerifyingKey
|
186
|
+
doc = loadDoc('in.xml')
|
187
|
+
# Sign document
|
188
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), publicKey())
|
189
|
+
xpath = Xmlsig::XPath.new('/books')
|
190
|
+
signer.attachPublicKey(1)
|
191
|
+
d = signer.sign(xpath)
|
192
|
+
# Verify document
|
193
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
194
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
195
|
+
v = Xmlsig::Verifier.new(d, xpath)
|
196
|
+
assert_equal(1, v.verify(publicKey()), "Verify")
|
197
|
+
assert_equal(1, v.verify(), "Verify")
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_CertOnly
|
201
|
+
### TSIK XmlSigTest.testCertOnly
|
202
|
+
doc = loadDoc('testCertOnly_in.xml')
|
203
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
204
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
205
|
+
v = Xmlsig::Verifier.new(doc, xpath)
|
206
|
+
assert_equal(1, v.verify(), "Verify")
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_Hmac
|
210
|
+
### TSIK XmlSigTest.testHmac
|
211
|
+
doc = loadDoc('in.xml')
|
212
|
+
sigKey = Xmlsig::Key.new
|
213
|
+
sigKey.loadHMACFromString('ab')
|
214
|
+
signer = Xmlsig::Signer.new(doc, sigKey)
|
215
|
+
xpath = Xmlsig::XPath.new('/')
|
216
|
+
d = signer.sign(xpath)
|
217
|
+
xpath = Xmlsig::XPath.new('//ds:Signature')
|
218
|
+
xpath.addNamespace('ds', "http://www.w3.org/2000/09/xmldsig#")
|
219
|
+
v = Xmlsig::Verifier.new(d, xpath)
|
220
|
+
verKey = Xmlsig::Key.new
|
221
|
+
verKey.loadHMACFromString('ab')
|
222
|
+
assert_equal(1, v.verify(verKey), "Verify")
|
223
|
+
verKey.loadHMACFromString('bb')
|
224
|
+
assert_equal(0, v.verify(verKey), "Verify")
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_EmptyNamespace
|
228
|
+
### TSIK XmlSigTest.testEmptyNamespace
|
229
|
+
# original testEmptyNamespace.xml was
|
230
|
+
# <elem xmlns="default namespace"/>
|
231
|
+
# changed to
|
232
|
+
# <elem xmlns="http://default/namespace"/>
|
233
|
+
# because the former was being flagged by the libxml2 parser as
|
234
|
+
# having an invalid URI
|
235
|
+
signer = sign1('testEmptyNamespace.xml', privateKey(), publicKey(), NIL)
|
236
|
+
doc = sign2(signer, '/', NIL)
|
237
|
+
assert_equal(false, doc.nil?)
|
238
|
+
assert_equal(true, verify(doc, '//ds:Signature', publicKey(), 0, 0), "Verify")
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_Stele
|
242
|
+
### TSIK XmlSigTest.testStele
|
243
|
+
signer = sign1('testStele.xml', privateKey(), publicKey(), NIL)
|
244
|
+
xpath = Xmlsig::XPath.new("/SOAP-ENV:Envelope/SOAP-ENV:Body")
|
245
|
+
xpath.addNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/")
|
246
|
+
signer.addReference(xpath)
|
247
|
+
doc = sign2(signer, '/', NIL)
|
248
|
+
assert_equal(false, doc.nil?)
|
249
|
+
assert_equal(true, verify(doc, '//ds:Signature', publicKey(), 0, 0), "Verify")
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_Cert
|
253
|
+
### TSIK XmlSigTest.testCert
|
254
|
+
signer = sign1('in.xml', privateKey(), NIL, resdir() + 'mycert.x509')
|
255
|
+
signer.attachPublicKey(1)
|
256
|
+
assert_equal(false, signer.nil?)
|
257
|
+
doc = sign2(signer, '/', NIL)
|
258
|
+
assert_equal(false, doc.nil?)
|
259
|
+
sigLoc = '/books/ds:Signature'
|
260
|
+
|
261
|
+
assert_equal(true, verify(doc, sigLoc, publicKey(), 0, 0), "Verify")
|
262
|
+
assert_equal(true, verify(doc, sigLoc, NIL, 1, 0), "Verify")
|
263
|
+
assert_equal(true, verify(doc, sigLoc, NIL, 1, 1), "Verify")
|
264
|
+
xpath = Xmlsig::XPath.new(sigLoc)
|
265
|
+
xpath.addNamespace("ds", "http://www.w3.org/2000/09/xmldsig#")
|
266
|
+
verifier = Xmlsig::Verifier.new(doc, xpath)
|
267
|
+
l = verifier.getCertificateChain()
|
268
|
+
assert_equal(1, l.length, "Chain length")
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_MultipleCert
|
272
|
+
### TSIK XmlSigTest.testMultipleCert
|
273
|
+
cert = Xmlsig::X509Certificate.new
|
274
|
+
if (cert.loadFromFile(resdir() + 'mycert.x509', 'cert_pem') < 0)
|
275
|
+
raise "IOException - Couldn't load 'mycert.x509'"
|
276
|
+
end
|
277
|
+
verifyingKey = cert.getKey()
|
278
|
+
doc = loadDoc('in.xml')
|
279
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), verifyingKey)
|
280
|
+
signer.attachPublicKey(1)
|
281
|
+
signer.addReference(Xmlsig::XPath.new("/books/book[2]"))
|
282
|
+
d = signer.sign(Xmlsig::XPath.new("/books/book[1]"))
|
283
|
+
assert_equal(false, d.nil?)
|
284
|
+
sigLoc = '//ds:Signature'
|
285
|
+
|
286
|
+
assert_equal(true, verify(d, sigLoc, publicKey(), 0, 0), "Verify")
|
287
|
+
assert_equal(true, verify(d, sigLoc, NIL, 1, 0), "Verify")
|
288
|
+
assert_equal(true, verify(d, sigLoc, NIL, 1, 1), "Verify")
|
289
|
+
xpath = Xmlsig::XPath.new(sigLoc)
|
290
|
+
xpath.addNamespace("ds", "http://www.w3.org/2000/09/xmldsig#")
|
291
|
+
verifier = Xmlsig::Verifier.new(d, xpath)
|
292
|
+
l = verifier.getCertificateChain()
|
293
|
+
assert_equal(1, l.length, "Chain length")
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_Enveloped
|
297
|
+
### TSIK XmlSigTest.testEnveloped
|
298
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
299
|
+
doc = sign2(signer, '/', NIL)
|
300
|
+
assert_equal(false, doc.nil?)
|
301
|
+
assert_equal(true, verify(doc, '/books/ds:Signature', publicKey(), 0, 0), "Verify")
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_Enveloping
|
305
|
+
### TSIK XmlSigTest.testEnveloping
|
306
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
307
|
+
doc = sign2(signer, '', NIL)
|
308
|
+
assert_equal(false, doc.nil?)
|
309
|
+
assert_equal(true, verify(doc, '/ds:Signature', publicKey(), 0, 0), "Verify")
|
310
|
+
assert_equal(true, verify(doc, '/ds:Signature', NIL, 1, 0), "Verify")
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_Detached
|
314
|
+
### TSIK XmlSigTest.testDetached
|
315
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
316
|
+
doc = sign2(signer, '/books/book[1]', NIL)
|
317
|
+
assert_equal(false, doc.nil?)
|
318
|
+
assert_equal(true, verify(doc, '/books/book[1]/ds:Signature', publicKey(), 0, 0), "Verify")
|
319
|
+
assert_equal(true, verify(doc, '/books/book[1]/ds:Signature', NIL, 1, 0), "Verify")
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_MultipleRefsDetached
|
323
|
+
### TSIK XmlSigTest.testMultipleRefsDetached
|
324
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
325
|
+
|
326
|
+
for expr in ['/', '/books', '/books/book[2]', '/books/book[1]',
|
327
|
+
"/books/book[@name='Professional XML']"]
|
328
|
+
xpath = Xmlsig::XPath.new(expr)
|
329
|
+
signer.addReference(xpath)
|
330
|
+
end
|
331
|
+
|
332
|
+
doc = sign2(signer, '/books/book[1]', NIL)
|
333
|
+
assert_equal(false, doc.nil?)
|
334
|
+
assert_equal(true, verify(doc, '/books/book[1]/ds:Signature', publicKey(), 0, 0), "Verify")
|
335
|
+
assert_equal(true, verify(doc, '/books/book[1]/ds:Signature', NIL, 1, 0), "Verify")
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_BadXPath1
|
339
|
+
### TSIK XmlSigTest.testBadXPath1
|
340
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
341
|
+
xpath = Xmlsig::XPath.new('bad xpath')
|
342
|
+
signer.addReference(xpath)
|
343
|
+
d = sign2(signer, '/', NIL)
|
344
|
+
rescue
|
345
|
+
assert_equal(true, d.nil?)
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_BadXPath2
|
349
|
+
### TSIK XmlSigTest.testBadXPath2
|
350
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
351
|
+
xpath = Xmlsig::XPath.new('here()')
|
352
|
+
signer.addReference(xpath)
|
353
|
+
d = sign2(signer, '/', NIL)
|
354
|
+
rescue
|
355
|
+
assert_equal(true, d.nil?)
|
356
|
+
end
|
357
|
+
|
358
|
+
def test_MultipleSignatures
|
359
|
+
### TSIK XmlSigTest.testMultipleSignatures
|
360
|
+
signer = sign1('in.xml', privateKey(), publicKey(), NIL)
|
361
|
+
signer.addReference(Xmlsig::XPath.new('/books/book[2]'))
|
362
|
+
doc = signer.sign(Xmlsig::XPath.new('/books/book[1]'), 1)
|
363
|
+
assert_equal(false, doc.nil?)
|
364
|
+
signer = Xmlsig::Signer.new(doc, privateKey(), publicKey())
|
365
|
+
# TSIK uses /books/ds:Signature for this reference, which
|
366
|
+
# matches multiple Signature elements. This causes problems
|
367
|
+
# because a Signature should not refer to itself, so we've
|
368
|
+
# changed it to refer to the first Signature only which was
|
369
|
+
# presumably the intent. (modified TSIK output reference xml)
|
370
|
+
xpath = Xmlsig::XPath.new('/books/ds:Signature[1]')
|
371
|
+
xpath.addNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#')
|
372
|
+
signer.addReference(xpath)
|
373
|
+
doc = signer.sign(Xmlsig::XPath.new('/books/book[2]'), 1)
|
374
|
+
assert_equal(false, doc.nil?)
|
375
|
+
sigLoc1 = '/books/ds:Signature[1]'
|
376
|
+
sigLoc2 = '/books/ds:Signature[2]'
|
377
|
+
assert_equal(true, verify(doc, sigLoc1, publicKey(), 0, 0), "Verify")
|
378
|
+
assert_equal(true, verify(doc, sigLoc2, publicKey(), 0, 0), "Verify")
|
379
|
+
assert_equal(true, verify(doc, sigLoc1, NIL, 1, 0), "Verify")
|
380
|
+
assert_equal(true, verify(doc, sigLoc2, NIL, 1, 0), "Verify")
|
381
|
+
end
|
382
|
+
|
383
|
+
def test_MerlinEnvelopedDsa
|
384
|
+
### TSIK XmlSigTest.testMerlinEnvelopedDsa
|
385
|
+
doc = loadDoc("merlin-xmldsig-fifteen/signature-enveloped-dsa.xml")
|
386
|
+
assert_equal(true, verify(doc, '//ds:Signature', NIL, 1, 0), "Verify")
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_MerlinEnvelopingDsa
|
390
|
+
### TSIK XmlSigTest.testMerlinEnvelopingDsa
|
391
|
+
doc = loadDoc("merlin-xmldsig-fifteen/signature-enveloping-dsa.xml")
|
392
|
+
assert_equal(true, verify(doc, '//ds:Signature', NIL, 1, 0), "Verify")
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_MerlinEnvelopingBase64Dsa
|
396
|
+
### TSIK XmlSigTest.testMerlinEnvelopingBase64Dsa
|
397
|
+
doc = loadDoc("merlin-xmldsig-fifteen/signature-enveloping-b64-dsa.xml")
|
398
|
+
assert_equal(true, verify(doc, '//ds:Signature', NIL, 1, 0), "Verify")
|
399
|
+
end
|
400
|
+
|
401
|
+
### Port of the TSIK org.apache.tsik.xmlsig.test.XmlSigTestExcC14n class
|
402
|
+
###
|
403
|
+
|
404
|
+
def test_EmptyList
|
405
|
+
### TSIK XmlSigTestExcC14n.testEmptyList
|
406
|
+
s = sign1('testStele.xml', privateKey(), publicKey(), NIL)
|
407
|
+
s.useExclusiveCanonicalizer('')
|
408
|
+
xp = Xmlsig::XPath.new("//*[@Id='ID1']")
|
409
|
+
# Unused in TSIK, if we leave this out our Reference URIs match
|
410
|
+
#xp.addNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/")
|
411
|
+
s.addReference(xp)
|
412
|
+
doc = sign2(s, '/', NIL)
|
413
|
+
assert_equal(false, doc.nil?)
|
414
|
+
assert_equal(true, verify(doc, '//ds:Signature', publicKey(), 0, 0), "Verify")
|
415
|
+
assert_equal(true, verify(doc, '//ds:Signature', NIL, 1, 0), "Verify")
|
416
|
+
end
|
417
|
+
|
418
|
+
### Port of the TSIK org.apache.tsik.xmlsig.test.XmlSigTestDigsig class
|
419
|
+
###
|
420
|
+
|
421
|
+
def test_XPath
|
422
|
+
### TSIK XmlSigTestDigsig.testXPath
|
423
|
+
doc = loadDoc("digsig-ratified/xpath_out.xml")
|
424
|
+
sigLoc = "//ds:Signature"
|
425
|
+
assert_equal(true, verify(doc, sigLoc, NIL, 1, 0), "Verify")
|
426
|
+
end
|
427
|
+
|
428
|
+
def test_XPointer
|
429
|
+
### TSIK XmlSigTestDigsig.testXPointer
|
430
|
+
doc = loadDoc("digsig-ratified/xpointer_out.xml")
|
431
|
+
# Id attribute must be set, see
|
432
|
+
# http://www.aleksey.com/xmlsec/faq.html#section_3_2
|
433
|
+
doc.addIdAttr('Id', 'elem', '')
|
434
|
+
sigLoc = "//ds:Signature"
|
435
|
+
assert_equal(true, verify(doc, sigLoc, NIL, 1, 0), "Verify")
|
436
|
+
end
|
437
|
+
|
438
|
+
def test_XPathEnveloped
|
439
|
+
### TSIK XmlSigTestDigsig.testXPathEnveloped
|
440
|
+
doc = loadDoc("digsig-ratified/envelopedsignature_out.xml")
|
441
|
+
# Id attribute must be set, see
|
442
|
+
# http://www.aleksey.com/xmlsec/faq.html#section_3_2
|
443
|
+
doc.addIdAttr('Id', 'RegisterResult', 'http://www.xkms.org/schema/xkms-2001-01-20')
|
444
|
+
sigLoc = "//ds:Signature"
|
445
|
+
assert_equal(true, verify(doc, sigLoc, NIL, 1, 0), "Verify")
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_Merlin2
|
449
|
+
### TSIK XmlSigTestDigsig.testMerlin2
|
450
|
+
doc = loadDoc("merlin-xmldsig-fifteen/signature-enveloping-rsa.xml")
|
451
|
+
sigLoc = "//ds:Signature"
|
452
|
+
assert_equal(true, verify(doc, sigLoc, NIL, 1, 0), "Verify")
|
453
|
+
end
|
454
|
+
|
455
|
+
|
456
|
+
### Port of the TSIK org.apache.tsik.xmlsig.test.XmlSigTestMerlin23 class
|
457
|
+
###
|
458
|
+
|
459
|
+
def HMACKey
|
460
|
+
key = Xmlsig::Key.new
|
461
|
+
key.loadHMACFromString('secret')
|
462
|
+
return key
|
463
|
+
end
|
464
|
+
|
465
|
+
def test_Merlin23
|
466
|
+
### TSIK XmlSigTestMerlin23
|
467
|
+
xpath = Xmlsig::XPath.new("//ds:Signature")
|
468
|
+
xpath.addNamespace("ds", "http://www.w3.org/2000/09/xmldsig#")
|
469
|
+
for res in ['signature-enveloped-dsa',
|
470
|
+
'signature-enveloping-b64-dsa',
|
471
|
+
'signature-enveloping-rsa',
|
472
|
+
'signature-external-b64-dsa',
|
473
|
+
'signature-external-dsa',
|
474
|
+
'signature-x509-crt-crl',
|
475
|
+
'signature-x509-crt',
|
476
|
+
'signature-enveloping-hmac-sha1']
|
477
|
+
fullfilename = resdir() + "merlin-xmldsig-twenty-three/" + res + ".xml"
|
478
|
+
doc = Xmlsig::XmlDoc.new
|
479
|
+
if doc.loadFromFile(fullfilename) < 0
|
480
|
+
raise "IOError - Couldn't open XML file " + fullfilename
|
481
|
+
end
|
482
|
+
verifier = Xmlsig::Verifier.new(doc, xpath)
|
483
|
+
if res == 'signature-enveloping-hmac-sha1'
|
484
|
+
assert_equal(1, verifier.verify(HMACKey()), "Verify Merlin32")
|
485
|
+
else
|
486
|
+
assert_equal(1, verifier.verify(), "Verify Merlin32")
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# (C) Copyright 2006 VeriSign, Inc.
|
4
|
+
# Developed by Sxip Identity
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'test/unit'
|
19
|
+
require 'xmlsig'
|
20
|
+
|
21
|
+
class TC_Verifier < Test::Unit::TestCase
|
22
|
+
# def setup
|
23
|
+
# end
|
24
|
+
|
25
|
+
# def teardown
|
26
|
+
# end
|
27
|
+
|
28
|
+
def test_basics
|
29
|
+
x = Xmlsig::XmlDoc.new
|
30
|
+
xml = <<-XML
|
31
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
32
|
+
<sxip:envelope xmlns:foo="http://sxip.com/xml-dsig/test/foo#" xmlns:sxip="http://sxip.com/xml-dsig/test#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><sxip:header><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#xpointer(/sxip:envelope/sxip:body/foo:morestuff)"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>NuSUptSOayIh51kdIONXjFeYxMQ=</ds:DigestValue></ds:Reference><ds:Reference URI="#xpointer(/sxip:envelope/sxip:body/sxip:evenMoreSxipStuff)"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>oT0HFNUy26Iea8HBnXsz0+IzPU4=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>V64bOOa8ve14Qg0LYETMrV+Eby3go3AAjPgMMwM1swegZKiFYUntin14M7o8v6/TlNMFPlBx
|
33
|
+
x7vajc6AgVGshLkkvsrzKWktNqcya1k1YGqswxNIPdFsscMRzileSc+Dx61JuXm9Yw2PPl+0
|
34
|
+
aSmaxeKlrWjo9NOHLdHcmskCTPzqk20glB5SIYIspCnktCnCo1cj6xksOXi6G+ueEk8AVWnR
|
35
|
+
p07UIPgjWftXtWTDLJNxuhWOHUkpyBcMhCZjbNALq7wIm/pebMPC3gHFWaA8jIz+IIuRzwwj
|
36
|
+
ik7w/bp7Y81PYQyQGgFXuTs45x+twx4u7BX/RTpfGthpU/Ph3j0EtA==</ds:SignatureValue><ds:KeyInfo><ds:KeyName>Public key of certificate</ds:KeyName><ds:KeyValue><ds:RSAKeyValue><ds:Modulus>oGgoDlqu7bl/TsvRjQs7JnocBR6/Sf8YNSzEc84/4JKiWK/X/3/VALmp8IXazpXSkGbRMqQY
|
37
|
+
nz9NVirxB6tB7z5p6yCh1oNLglH/vNDLi314RtAy0AU799EcQOJa8ybJR4phLK6uy1IxcBrd
|
38
|
+
AO2TAh/5QfYTUDsgAmH+FxWOJbwRd76u4+8RCqOFnEbHiKUBA1/N5C6H78+o3fIjfEApSADy
|
39
|
+
pVegB9UY5rkzPVLCTgKcQb7SOp5WHVteD3IzP0HSB0YsP3Pie9bwVyAzfoh1iq5Enoqnx4eV
|
40
|
+
APjOAWDf9WqoiBfxmwjqAHTWclDBYw2TOg+e3Lb03rqsKr60imT2uQ==</ds:Modulus><ds:Exponent>AQAB</ds:Exponent></ds:RSAKeyValue></ds:KeyValue><ds:X509Data><ds:X509Certificate>MIIDATCCAemgAwIBAgIGAQoqb98SMA0GCSqGSIb3DQEBCwUAMEExEzARBgoJkiaJk/IsZAEZ
|
41
|
+
EwNjb20xFDASBgoJkiaJk/IsZAEZEwRzeGlwMRQwEgYDVQQDEwtJc3N1ZXIgTmFtZTAeFw0w
|
42
|
+
NjAzMjQwNDA3NTVaFw0yMDAxMDEwODAwMDBaMEIxEzARBgoJkiaJk/IsZAEZEwNjb20xFDAS
|
43
|
+
BgoJkiaJk/IsZAEZEwRzeGlwMRUwEwYDVQQDEwxTdWJqZWN0IE5hbWUwggEiMA0GCSqGSIb3
|
44
|
+
DQEBAQUAA4IBDwAwggEKAoIBAQCgaCgOWq7tuX9Oy9GNCzsmehwFHr9J/xg1LMRzzj/gkqJY
|
45
|
+
r9f/f9UAuanwhdrOldKQZtEypBifP01WKvEHq0HvPmnrIKHWg0uCUf+80MuLfXhG0DLQBTv3
|
46
|
+
0RxA4lrzJslHimEsrq7LUjFwGt0A7ZMCH/lB9hNQOyACYf4XFY4lvBF3vq7j7xEKo4WcRseI
|
47
|
+
pQEDX83kLofvz6jd8iN8QClIAPKlV6AH1RjmuTM9UsJOApxBvtI6nlYdW14PcjM/QdIHRiw/
|
48
|
+
c+J71vBXIDN+iHWKrkSeiqfHh5UA+M4BYN/1aqiIF/GbCOoAdNZyUMFjDZM6D57ctvTeuqwq
|
49
|
+
vrSKZPa5AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAArJTw0B6ZXSqs0oxFkgu5UAws0xdi/8
|
50
|
+
fuQCYMcV1e1Y8VXYVrmJQv8oaft/iSueyc7QmhOgUpXbqB+ApYhS3Hrk2F5EQthEIFGTWG1K
|
51
|
+
uxQno0OriMvRTn880SNo5wnl/UeKkp6OwAYGrsVZnxZ1cij+5EVWB8eBXN5OZPbktc/tAuj9
|
52
|
+
gS3CaEtoO7KQKZjGugwSMBGZwhiECaSn9jb4MotovtZCo5Qp8FJyeYWTgw2S+/HDc5Ot4i2b
|
53
|
+
pa/U87KGxffQASJcj05ij7HgHnAznvFBuFamNQo2s2sdXTIEKQpJ9804oSGdrdq7VuAOMnXN
|
54
|
+
uswvjAEdbUfaEBzym0OMghY=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></sxip:header><sxip:body id="Body"><foo:morestuff>Here is more stuff!</foo:morestuff><foo:evenMoreStuff>Here is more stuff!</foo:evenMoreStuff><sxip:evenMoreSxipStuff>Here is more stuff!</sxip:evenMoreSxipStuff></sxip:body></sxip:envelope>
|
55
|
+
XML
|
56
|
+
if x.loadFromString(xml) == -1
|
57
|
+
raise "failed to create XML document"
|
58
|
+
end
|
59
|
+
xp = Xmlsig::XPath.new()
|
60
|
+
xp.addNamespace('ds', 'http://www.w3.org/2000/09/xmldsig#')
|
61
|
+
xp.setXPath('/descendant::ds:Signature[position()=1]')
|
62
|
+
v = Xmlsig::Verifier.new(x,xp)
|
63
|
+
rc = v.verify
|
64
|
+
assert_equal(1,rc,"verify document with namespace using xpath")
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_plain_key
|
68
|
+
x = Xmlsig::XmlDoc.new
|
69
|
+
xml = <<-XML
|
70
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
71
|
+
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
72
|
+
<SignedInfo>
|
73
|
+
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
74
|
+
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
|
75
|
+
<Reference URI="#object">
|
76
|
+
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
77
|
+
<DigestValue>7/XTsHaBSOnJ/jXD5v0zL6VKYsk=</DigestValue>
|
78
|
+
</Reference>
|
79
|
+
</SignedInfo>
|
80
|
+
<SignatureValue>BMGn3ftGz476A4ZyCOTf1X2GZ/yMK/o5J3kTg8WSh+56cgLRCQiOrA==</SignatureValue>
|
81
|
+
<KeyInfo>
|
82
|
+
<KeyValue>
|
83
|
+
<DSAKeyValue>
|
84
|
+
<P>
|
85
|
+
mTNzLdDnUE8esvAOW+m5/GR+2xAuv/5XHRuGP216C1Lh0ofU2978HuCIZgu29ggW
|
86
|
+
d6nYkRAhpprnw0MvnwQynyvZMs51YyHbSHFIb3eefyg14+Y4/003LrhOQwaPkptA
|
87
|
+
iUHohW9w7dhqRxKgDbD9T3yYiWr066v02u0jZhMCX/0=
|
88
|
+
</P>
|
89
|
+
<Q>
|
90
|
+
vMMOrPdYTfgRjIwMxAGrvGqpxZM=
|
91
|
+
</Q>
|
92
|
+
<G>
|
93
|
+
kAzI1xXPJ1Qd9V/OKNWuKliEvAWpPcPrshOPajErPXhG2qT15c+oP/CxauG+96RV
|
94
|
+
qoArUoluexWjySPm6SAZNr+hHQrE/OnV0IIgsiRlUJqxLNNEI6wn6G6FOw6ymUay
|
95
|
+
RCLAha5VDyoeQ90XA2QdZ7EDXhmom+q6ZjGAsn4dtNk=
|
96
|
+
</G>
|
97
|
+
<Y>
|
98
|
+
bmInlV3nwDyJ/8vck3jOYj3bB2c6gXrvdKQlxNsUvxy5rVfGY7DY+N/5Q4v6S8Q3
|
99
|
+
Cy6+GgMWIKjnolIpFt8khUUmwV0SNDcgLwsrnEMrZ0kQlMybFBaWqbuTk0FC+ORK
|
100
|
+
giAQbEuMveocyjZPdHNAHJmDe87nn1nbmBlPpxLQwTg=
|
101
|
+
</Y>
|
102
|
+
</DSAKeyValue>
|
103
|
+
</KeyValue>
|
104
|
+
</KeyInfo>
|
105
|
+
<Object Id="object">some text</Object>
|
106
|
+
</Signature>
|
107
|
+
XML
|
108
|
+
if x.loadFromString(xml) == -1
|
109
|
+
raise "failed to create XML document"
|
110
|
+
end
|
111
|
+
v = Xmlsig::Verifier.new(x)
|
112
|
+
rc = v.verify
|
113
|
+
assert_equal(1,rc,"verify document containing plain key")
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_bad_input
|
117
|
+
xml = <<-XML
|
118
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
119
|
+
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
120
|
+
<SignedInfo>
|
121
|
+
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
|
122
|
+
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />
|
123
|
+
<Reference URI="http://www.w3.org/TR/xml-stylesheet">
|
124
|
+
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
|
125
|
+
<DigestValue>60NvZvtdTB+7UnlLp/H24p7h4bs=</DigestValue>
|
126
|
+
</Reference>
|
127
|
+
</SignedInfo>
|
128
|
+
<SignatureValue>
|
129
|
+
MUOjiqG0dbjvR6+qYYPL85nKSt2FeZGQBQkYudv48KyJhJLG1Bp+bA==
|
130
|
+
</SignatureValue>
|
131
|
+
<KeyInfo>
|
132
|
+
<X509Data>
|
133
|
+
<X509SubjectName>
|
134
|
+
CN=Badb,OU=X/Secure,O=Baltimore Technologies Ltd.,ST=Dublin,C=IE
|
135
|
+
</X509SubjectName>
|
136
|
+
</X509Data>
|
137
|
+
</KeyInfo>
|
138
|
+
</Signature>
|
139
|
+
XML
|
140
|
+
x = Xmlsig::XmlDoc.new
|
141
|
+
x.loadFromString(xml)
|
142
|
+
ks = Xmlsig::KeyStore.new
|
143
|
+
ks.addTrustedCertFromFile('t/keys/ca.pem', 'pem')
|
144
|
+
ks.addTrustedCertFromFile('t/keys/badb.pem', 'pem')
|
145
|
+
ks.addKeyFromFile('t/keys/badb.pem', 'cert_pem', '')
|
146
|
+
v = Xmlsig::Verifier.new(x)
|
147
|
+
v.setKeyStore(ks)
|
148
|
+
assert_equal(1,v.verify, "should work")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'xmlsig'
|
3
|
+
|
4
|
+
in_path = '../res/tsik/in/'
|
5
|
+
key_path = '../res/tsik/keys/'
|
6
|
+
out_path = '../'
|
7
|
+
|
8
|
+
x = Xmlsig::XmlDoc.new
|
9
|
+
x.loadFromFile(in_path + "in.xml")
|
10
|
+
k = Xmlsig::Key.new
|
11
|
+
k.loadFromFile(key_path + 'alice.pfx','pkcs12','password')
|
12
|
+
s = Xmlsig::Signer.new(x,k)
|
13
|
+
s.signInPlace()
|
14
|
+
x.toFile(out_path + "out_1.xml")
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
x = Xmlsig::XmlDoc.new
|
19
|
+
x.loadFromFile(in_path + "in.xml")
|
20
|
+
k = Xmlsig::Key.new
|
21
|
+
k.loadFromFile(key_path + 'alice.pfx','pkcs12','password')
|
22
|
+
s = Xmlsig::Signer.new(x,k)
|
23
|
+
s.addCertFromFile(key_path + 'Alice.cer', 'cert_der')
|
24
|
+
xp = Xmlsig::XPath.new()
|
25
|
+
xp.addNamespace('cert', 'http://example.com/cert')
|
26
|
+
xp.setXPath('/cert:cert')
|
27
|
+
x = s.sign(xp)
|
28
|
+
x.toFile(out_path + "out_2.xml")
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
x = Xmlsig::XmlDoc.new
|
33
|
+
x.loadFromFile(in_path + "in.xml")
|
34
|
+
k = Xmlsig::Key.new
|
35
|
+
k.loadFromFile(key_path + 'alice.pfx','pkcs12','password')
|
36
|
+
|
37
|
+
pk = Xmlsig::Key.new
|
38
|
+
pk.loadFromFile(key_path + 'Alice.cer', 'cert_der', '')
|
39
|
+
|
40
|
+
s = Xmlsig::Signer.new(x,k,pk)
|
41
|
+
xp = Xmlsig::XPath.new()
|
42
|
+
xp.addNamespace('cert', 'http://example.com/cert')
|
43
|
+
xp.setXPath('/cert:cert')
|
44
|
+
x = s.sign(xp)
|
45
|
+
x.toFile(out_path + "out_3.xml")
|
46
|
+
|
47
|
+
|
48
|
+
|