xmlsig 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. data/README.rdoc +0 -0
  2. data/ext/xmlsig/BioWrap.h +98 -0
  3. data/ext/xmlsig/DSig.cpp +109 -0
  4. data/ext/xmlsig/DSig.h +81 -0
  5. data/ext/xmlsig/DSigCtx.h +72 -0
  6. data/ext/xmlsig/Exceptions.cpp +151 -0
  7. data/ext/xmlsig/Exceptions.h +214 -0
  8. data/ext/xmlsig/Key.cpp +582 -0
  9. data/ext/xmlsig/Key.h +338 -0
  10. data/ext/xmlsig/KeyInfoCtx.h +67 -0
  11. data/ext/xmlsig/KeyStore.cpp +180 -0
  12. data/ext/xmlsig/KeyStore.h +157 -0
  13. data/ext/xmlsig/KeysMngrWrap.h +62 -0
  14. data/ext/xmlsig/NodeSet.h +60 -0
  15. data/ext/xmlsig/Signer.cpp +691 -0
  16. data/ext/xmlsig/Signer.h +373 -0
  17. data/ext/xmlsig/TrustVerifier.cpp +145 -0
  18. data/ext/xmlsig/TrustVerifier.h +174 -0
  19. data/ext/xmlsig/Verifier.cpp +677 -0
  20. data/ext/xmlsig/Verifier.h +313 -0
  21. data/ext/xmlsig/X509Certificate.cpp +362 -0
  22. data/ext/xmlsig/X509Certificate.h +146 -0
  23. data/ext/xmlsig/XPath.cpp +173 -0
  24. data/ext/xmlsig/XPath.h +156 -0
  25. data/ext/xmlsig/XPathCtx.h +68 -0
  26. data/ext/xmlsig/XmlCharBuf.h +60 -0
  27. data/ext/xmlsig/XmlDoc.cpp +278 -0
  28. data/ext/xmlsig/XmlDoc.h +157 -0
  29. data/ext/xmlsig/XmlElement.cpp +151 -0
  30. data/ext/xmlsig/XmlElement.h +134 -0
  31. data/ext/xmlsig/countptr.h +260 -0
  32. data/ext/xmlsig/extconf.rb +58 -0
  33. data/ext/xmlsig/runtests.rb +23 -0
  34. data/ext/xmlsig/swig/countptr.i +27 -0
  35. data/ext/xmlsig/swig/exceptions.i +79 -0
  36. data/ext/xmlsig/swig/ruby.i +17 -0
  37. data/ext/xmlsig/swig/xmlsig.i +405 -0
  38. data/ext/xmlsig/t/tc_cert.rb +34 -0
  39. data/ext/xmlsig/t/tc_interface.rb +158 -0
  40. data/ext/xmlsig/t/tc_signer.rb +501 -0
  41. data/ext/xmlsig/t/tc_tsik.rb +490 -0
  42. data/ext/xmlsig/t/tc_verifier.rb +151 -0
  43. data/ext/xmlsig/t/tsik_interop/sign.rb +48 -0
  44. data/ext/xmlsig/t/tsik_interop/verify.rb +31 -0
  45. data/ext/xmlsig/t/tsik_interop/verify_own.rb +46 -0
  46. data/ext/xmlsig/xmlsig.cpp +13363 -0
  47. data/lib/xmlsig.rb +1 -0
  48. metadata +113 -0
@@ -0,0 +1,677 @@
1
+ /*
2
+ * (C) Copyright 2006 VeriSign, Inc.
3
+ * Developed by Sxip Identity
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ #include <iostream>
18
+
19
+ #include <libxml/tree.h>
20
+ #include <libxml/xmlmemory.h>
21
+ #include <libxml/parser.h>
22
+ #ifndef XMLSEC_NO_XSLT
23
+ #include <libxslt/xslt.h>
24
+ #endif /* XMLSEC_NO_XSLT */
25
+ #include <xmlsec/xmlsec.h>
26
+ #include <xmlsec/xmltree.h>
27
+ #include <xmlsec/xmldsig.h>
28
+ #include <xmlsec/templates.h>
29
+ #include <xmlsec/openssl/x509.h>
30
+ #include <xmlsec/base64.h>
31
+ #include <assert.h>
32
+
33
+ #include "Verifier.h"
34
+ #include "Key.h"
35
+ #include "XmlDoc.h"
36
+ #include "DSigCtx.h"
37
+ #include "KeyStore.h"
38
+ #include "XPath.h"
39
+ #include "KeyInfoCtx.h"
40
+ #include "BioWrap.h"
41
+ #include "XmlCharBuf.h"
42
+ #include "NodeSet.h"
43
+ using namespace std;
44
+
45
+
46
+ Verifier::Verifier (XmlDocClassPtr doc)
47
+ : mXmlDoc (doc),
48
+ xPath (0),
49
+ skipCertCheckFlag (0)
50
+ {
51
+ verifierInit();
52
+ }
53
+
54
+
55
+ Verifier::Verifier (XmlDocClassPtr doc, XPathPtr newXPath)
56
+ : mXmlDoc (doc),
57
+ xPath (newXPath),
58
+ skipCertCheckFlag (0)
59
+ {
60
+ verifierInit();
61
+
62
+ // Check that xPath points to a single Signature element
63
+ xmlXPathObjectPtr isRefXP = xPath ? xPath->evalExpression(mXmlDoc) : NULL;
64
+ if (isRefXP && isRefXP->nodesetval->nodeNr != 1)
65
+ {
66
+ THROW_NORET(XPathError, "XPath expression must refer to a single node");
67
+ }
68
+ }
69
+
70
+
71
+ void Verifier::verifierInit ()
72
+ {
73
+ mKeyStore = NULL;
74
+ mDefaultKeyStore = new KeyStore();
75
+ if (!mDefaultKeyStore)
76
+ {
77
+ THROW_NORET(MemoryError, "Could not create default KeyStore");
78
+ }
79
+ }
80
+
81
+
82
+ Verifier::~Verifier ()
83
+ {
84
+ assert(mDefaultKeyStore);
85
+ mDefaultKeyStore = 0;
86
+ }
87
+
88
+
89
+ int Verifier::setKeyStore (KeyStorePtr keyStore)
90
+ {
91
+ assert(keyStore);
92
+ if (keyStore->getKeyStore() == NULL)
93
+ {
94
+ THROW(ValueError, "Invalid keystore parameter", -1);
95
+ }
96
+ mKeyStore = keyStore;
97
+ return 0;
98
+ }
99
+
100
+
101
+ int Verifier::verify ()
102
+ {
103
+ return doVerify(NULL);
104
+ }
105
+
106
+
107
+ int Verifier::verify (KeyPtr verifyingKey)
108
+ {
109
+ return doVerify(verifyingKey);
110
+ }
111
+
112
+
113
+ int Verifier::doVerify (KeyPtr verifyingKey)
114
+ {
115
+ KeyPtr key = verifyingKey;
116
+ if (!key)
117
+ {
118
+ key = getVerifyingKey();
119
+ }
120
+ if (!key && !mKeyStore)
121
+ {
122
+ THROW(KeyError, "No verifying key available", -1);
123
+ }
124
+ if (!mXmlDoc || !(*mXmlDoc))
125
+ {
126
+ THROW(DocError, "XML document was not loaded", -1);
127
+ }
128
+
129
+ xmlNodePtr node = NULL;
130
+ if ((findStartNode(*mXmlDoc, &node) < 0) || (node == NULL))
131
+ {
132
+ THROW(XMLError, "Can't find start node in document", -1);
133
+ }
134
+
135
+ int ret = verifyNode(*mXmlDoc, node, key);
136
+ return ret;
137
+ }
138
+
139
+
140
+ int Verifier::findStartNode (xmlDocPtr doc, xmlNodePtr* node)
141
+ {
142
+ int res = -1;
143
+ if (xPath)
144
+ {
145
+ if (findSignatureXPath(doc, node) < 0)
146
+ {
147
+ return res;
148
+ }
149
+ }
150
+ else
151
+ {
152
+ *node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature,
153
+ xmlSecDSigNs);
154
+ }
155
+ return 0;
156
+ }
157
+
158
+
159
+ int Verifier::findSignatureXPath (xmlDocPtr doc, xmlNodePtr* node)
160
+ {
161
+ assert(xPath);
162
+ xmlXPathObjectPtr xpObj = xPath->evalExpression(mXmlDoc);
163
+ if (xpObj == NULL)
164
+ {
165
+ THROW(XPathError, "Unable to evaluate XPath expression", -1);
166
+ }
167
+ //fprintf(stderr, "'%s' found %d nodes\n", xPath->getXPath().c_str(),
168
+ // xpObj->nodesetval->nodeNr);
169
+ if (xpObj->nodesetval->nodeNr <= 0)
170
+ {
171
+ THROW(XPathError, "Can't find signature node at XPath expression", -1);
172
+ }
173
+ // Return only the first node in the xpath node set
174
+ *node = xpObj->nodesetval->nodeTab[0];
175
+ return 0;
176
+ }
177
+
178
+
179
+ xmlSecKeysMngrPtr Verifier::getKeysMngr ()
180
+ {
181
+ KeyStorePtr keyStore = mDefaultKeyStore;
182
+ if (mKeyStore)
183
+ {
184
+ keyStore = mKeyStore;
185
+ }
186
+ assert(keyStore);
187
+ return keyStore->getKeyStore();
188
+ }
189
+
190
+
191
+ int Verifier::verifyNode (xmlDocPtr doc, xmlNodePtr node, KeyPtr key)
192
+ {
193
+ assert(doc);
194
+ assert(node);
195
+
196
+ // create signature context
197
+ DSigCtx dsigCtx (getKeysMngr());
198
+ if (!dsigCtx)
199
+ {
200
+ return -1;
201
+ }
202
+ if (key)
203
+ {
204
+ dsigCtx->signKey = key->dupKey();
205
+ }
206
+
207
+ // Set cert chain not to verify on key info read if requested
208
+ if (skipCertCheckFlag)
209
+ {
210
+ dsigCtx->keyInfoReadCtx.flags |=
211
+ XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS;
212
+ }
213
+
214
+ // Verify signature
215
+ if (xmlSecDSigCtxVerify(dsigCtx, node) < 0)
216
+ {
217
+ THROW(LibError, "Signature verify fn failure", -1);
218
+ }
219
+
220
+ // return verification result
221
+ return (dsigCtx->status == xmlSecDSigStatusSucceeded);
222
+ }
223
+
224
+
225
+ KeyPtr Verifier::getVerifyingKey ()
226
+ {
227
+ if (!mXmlDoc || !(*mXmlDoc))
228
+ {
229
+ THROW(DocError, "XML document was not loaded", 0);
230
+ }
231
+
232
+ xmlNodePtr sigNode = NULL;
233
+ if (findStartNode(*mXmlDoc, &sigNode) < 0)
234
+ {
235
+ THROW(XMLError, "Can't find start node in document", 0);
236
+ }
237
+ // find keyinfo node
238
+ xmlNodePtr node = xmlSecFindNode(sigNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
239
+ if (node == NULL)
240
+ {
241
+ // not an error, keyinfo may not exist
242
+ return 0;
243
+ }
244
+
245
+ KeyPtr keyObj = new Key();
246
+ int ret = -1;
247
+ try
248
+ {
249
+ ret = keyObj->loadFromKeyInfo(node, getKeysMngr());
250
+ if (ret >= 0)
251
+ {
252
+ X509CertificatePtr x509cert = getCertificate();
253
+ if (x509cert)
254
+ {
255
+ // Return null if key is not equal to certificate's key
256
+ // since both exists
257
+ KeyPtr certKeyObj = x509cert->getKey();
258
+ if (*certKeyObj != *keyObj)
259
+ return 0;
260
+ }
261
+ }
262
+ }
263
+ catch (LibError&)
264
+ {}
265
+ if (ret < 0)
266
+ {
267
+ X509CertificatePtr x509cert = getCertificate();
268
+ if (x509cert)
269
+ {
270
+ keyObj = x509cert->getKey();
271
+ }
272
+ }
273
+ return keyObj;
274
+ }
275
+
276
+
277
+ X509CertificatePtr Verifier::getCertificate ()
278
+ {
279
+ vector<X509CertificatePtr> certChain = getCertificateChain();
280
+ if (certChain.size())
281
+ {
282
+ return certChain[0];
283
+ }
284
+ return 0;
285
+ }
286
+
287
+
288
+ // TODO sort chain into subject-issuer order?
289
+ vector<X509CertificatePtr> Verifier::getCertificateChain ()
290
+ {
291
+ vector<X509CertificatePtr> certChain;
292
+ if (!mXmlDoc || !(*mXmlDoc))
293
+ {
294
+ THROW(DocError, "XML document was not loaded", certChain);
295
+ }
296
+
297
+ xmlNodePtr sigNode = NULL;
298
+ if (findStartNode(*mXmlDoc, &sigNode) < 0)
299
+ {
300
+ THROW(XMLError, "Can't find start node in document", certChain);
301
+ }
302
+ // find keyinfo node
303
+ xmlNodePtr node = xmlSecFindNode(sigNode, xmlSecNodeKeyInfo, xmlSecDSigNs);
304
+ if (node == NULL)
305
+ {
306
+ // not an error, keyinfo may not exist
307
+ return certChain;
308
+ }
309
+ if (!xmlSecCheckNodeName(node, xmlSecNodeKeyInfo, xmlSecDSigNs))
310
+ {
311
+ THROW(XMLError, "Invalid key info node", certChain);
312
+ }
313
+ KeyInfoCtx keyInfoCtx;
314
+ if (!keyInfoCtx)
315
+ {
316
+ return certChain;
317
+ }
318
+ keyInfoCtx->mode = xmlSecKeyInfoModeRead;
319
+ keyInfoCtx->flags = XMLSEC_KEYINFO_FLAGS_DONT_STOP_ON_KEY_FOUND |
320
+ XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS;
321
+ keyInfoCtx->keysMngr = getKeysMngr();
322
+ Key keyObj;
323
+ keyObj.create();
324
+ if (xmlSecKeyInfoNodeRead(node, keyObj, keyInfoCtx) < 0)
325
+ {
326
+ THROW(LibError, "Couldn't read key info node", certChain);
327
+ }
328
+ if (!keyObj)
329
+ {
330
+ try
331
+ {
332
+ certChain = getX509Data(node);
333
+ }
334
+ catch (XMLError&)
335
+ {}
336
+ }
337
+ else
338
+ {
339
+ certChain = keyObj.getCertificateChain();
340
+ }
341
+ return certChain;
342
+ }
343
+
344
+
345
+ vector<X509CertificatePtr> Verifier::getX509Data (xmlNodePtr node)
346
+ {
347
+ vector<X509CertificatePtr> certChain;
348
+
349
+ node = xmlSecFindNode(node, xmlSecNodeX509Data, xmlSecDSigNs);
350
+ if (node == NULL)
351
+ {
352
+ THROW(XMLError, "Can't find X509Data node", certChain);
353
+ }
354
+ for (xmlNodePtr cur = xmlSecGetNextElementNode(node->children);
355
+ cur != NULL;
356
+ cur = xmlSecGetNextElementNode(cur->next))
357
+ {
358
+ if (xmlSecCheckNodeName(cur, xmlSecNodeX509Certificate, xmlSecDSigNs))
359
+ {
360
+ X509CertificatePtr x509 = getX509CertificateNode(cur);
361
+ if (x509)
362
+ {
363
+ certChain.push_back(x509);
364
+ }
365
+ }
366
+ }
367
+ return certChain;
368
+ }
369
+
370
+
371
+ X509CertificatePtr Verifier::getX509CertificateNode (xmlNodePtr node)
372
+ {
373
+ if ((node == NULL) ||
374
+ (!xmlSecCheckNodeName(node, xmlSecNodeX509Certificate, xmlSecDSigNs)))
375
+ {
376
+ return 0;
377
+ }
378
+ XmlCharBuf buf (xmlNodeGetContent(node));
379
+ if (!(int)buf || xmlSecIsEmptyString(buf))
380
+ {
381
+ THROW(XMLError, "X509Certificate has no content", 0);
382
+ }
383
+ int size = xmlSecBase64Decode(buf, (xmlSecByte*)buf, xmlStrlen(buf));
384
+ if (size < 0)
385
+ {
386
+ THROW(XMLError, "Failed to decode X509Certificate content", 0);
387
+ }
388
+ BioWrap mem;
389
+ if (!(int)mem || (mem.write(buf, size) <= 0))
390
+ {
391
+ return 0;
392
+ }
393
+ X509* cert = d2i_X509_bio(mem, NULL);
394
+ if (cert == NULL)
395
+ {
396
+ THROW(LibError, "Couldn't load certificate from BIO", 0);
397
+ }
398
+ return new X509Certificate(cert);
399
+ }
400
+
401
+
402
+ int Verifier::isContained (xmlSecNodeSetPtr nodeSet, XPathPtr xPathElem)
403
+ {
404
+ assert(xPathElem);
405
+ xmlXPathObjectPtr isRefXP = xPathElem->evalExpression(mXmlDoc);
406
+ if (isRefXP == 0)
407
+ {
408
+ return -1;
409
+ }
410
+ if (isRefXP->nodesetval->nodeNr != 1)
411
+ {
412
+ THROW(XPathError, "XPath expression must refer to a single node", -1);
413
+ }
414
+ xmlNodePtr node = *(isRefXP->nodesetval->nodeTab);
415
+ assert(node);
416
+
417
+ return xmlSecNodeSetContains(nodeSet, node, node->parent);
418
+ }
419
+
420
+
421
+ int Verifier::refNodes (Verifier::refNodesCallback callbackFn, void* data)
422
+ {
423
+ assert(mXmlDoc);
424
+ if (!mXmlDoc || !(*mXmlDoc))
425
+ {
426
+ THROW(DocError, "XML document was not loaded", -1);
427
+ }
428
+
429
+ // create signature context
430
+ DSigCtx dsigCtx (getKeysMngr());
431
+ if (!dsigCtx)
432
+ {
433
+ return -1;
434
+ }
435
+ xmlNodePtr node = 0;
436
+ if (findStartNode(*mXmlDoc, &node) < 0)
437
+ {
438
+ THROW(XMLError, "Can't find start node in document", -1);
439
+ }
440
+ dsigCtx->operation = xmlSecTransformOperationVerify;
441
+ dsigCtx->status = xmlSecDSigStatusUnknown;
442
+ dsigCtx->id = xmlGetProp(node, xmlSecAttrId);
443
+ //xmlSecAddIDs(node->doc, node, xmlSecDSigIds);
444
+
445
+ node = xmlSecGetNextElementNode(node->children);
446
+ if ((node == NULL) ||
447
+ (!xmlSecCheckNodeName(node, xmlSecNodeSignedInfo, xmlSecDSigNs)))
448
+ {
449
+ THROW(XMLError, "Expected signed info node", -1);
450
+ }
451
+
452
+ // Get c14 method and add it to new transform ctx
453
+ xmlNodePtr cur = xmlSecGetNextElementNode(node->children);
454
+ if ((cur != NULL) &&
455
+ (xmlSecCheckNodeName(cur, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs)))
456
+ {
457
+ dsigCtx->c14nMethod =
458
+ xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx),
459
+ cur,
460
+ xmlSecTransformUsageC14NMethod);
461
+ if (dsigCtx->c14nMethod == NULL)
462
+ {
463
+ THROW(LibError, "Unable to create transform context with c14n method from node", -1);
464
+ }
465
+ }
466
+ else if (dsigCtx->defC14NMethodId != xmlSecTransformIdUnknown)
467
+ {
468
+ dsigCtx->c14nMethod =
469
+ xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx),
470
+ dsigCtx->defC14NMethodId);
471
+ if (dsigCtx->c14nMethod == NULL)
472
+ {
473
+ THROW(LibError, "Unable to create transform ctx with c14n method", -1);
474
+ }
475
+ }
476
+ else
477
+ {
478
+ THROW(XMLError, "Expected c14n method", -1);
479
+ }
480
+
481
+ // Set up signature method
482
+ cur = xmlSecGetNextElementNode(cur->next);
483
+ if ((cur != NULL) &&
484
+ (xmlSecCheckNodeName(cur, xmlSecNodeSignatureMethod, xmlSecDSigNs)))
485
+ {
486
+ dsigCtx->signMethod =
487
+ xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx),
488
+ cur, xmlSecTransformUsageSignatureMethod);
489
+ if (dsigCtx->signMethod == NULL)
490
+ {
491
+ THROW(LibError, "Unable to read signature method from node", -1);
492
+ }
493
+ }
494
+ else if (dsigCtx->defSignMethodId != xmlSecTransformIdUnknown)
495
+ {
496
+ dsigCtx->signMethod =
497
+ xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx),
498
+ dsigCtx->defSignMethodId);
499
+ if (dsigCtx->signMethod == NULL)
500
+ {
501
+ THROW(LibError, "Unable to create signature method", -1);
502
+ }
503
+ }
504
+ else
505
+ {
506
+ THROW(XMLError, "Expected signature method", -1);
507
+ }
508
+
509
+ cur = xmlSecGetNextElementNode(cur->next);
510
+ while ((cur != NULL) &&
511
+ (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs)))
512
+ {
513
+ // Don't have to call xmlSecDSigReferenceCtxDestroy because
514
+ // dsigCtx will own dsigRefCtx
515
+ xmlSecDSigReferenceCtxPtr dsigRefCtx =
516
+ xmlSecDSigReferenceCtxCreate(dsigCtx,
517
+ xmlSecDSigReferenceOriginSignedInfo);
518
+ if (dsigRefCtx == NULL)
519
+ {
520
+ THROW(LibError, "Couldn't create DSIG reference context", -1);
521
+ }
522
+ if (xmlSecPtrListAdd(&(dsigCtx->signedInfoReferences), dsigRefCtx) < 0)
523
+ {
524
+ THROW(LibError, "Couldn't add reference ctx to dsigCtx", -1);
525
+ }
526
+ if (xmlSecDSigReferenceCtxProcessNode(dsigRefCtx, cur) < 0)
527
+ {
528
+ THROW(LibError, "Failed to process reference node", -1);
529
+ }
530
+ if (dsigRefCtx->status != xmlSecDSigStatusSucceeded)
531
+ {
532
+ THROW(LibError, "Process reference node status failure", -1);
533
+ }
534
+ // xmlSecDSigReferenceCtxDebugDump(dsigRefCtx, stderr);
535
+ NodeSet nodes (nodeSetFromTransformCtx(&(dsigRefCtx->transformCtx), *mXmlDoc));
536
+ if (!nodes)
537
+ {
538
+ return 0;
539
+ }
540
+ dsigRefCtx->transformCtx.result = NULL;
541
+ dsigRefCtx->transformCtx.status = xmlSecTransformStatusNone;
542
+
543
+ xmlSecTransformPtr transformPtr = dsigRefCtx->transformCtx.first;
544
+ while (transformPtr != NULL)
545
+ {
546
+ transformPtr->inNodes = NULL;
547
+ transformPtr->outNodes = NULL;
548
+ transformPtr = transformPtr->next;
549
+ }
550
+
551
+ if (xmlSecTransformCtxXmlExecute(&(dsigRefCtx->transformCtx), nodes) < 0)
552
+ {
553
+ THROW(LibError, "Transform execute failure", -1);
554
+ }
555
+
556
+ transformPtr = dsigRefCtx->transformCtx.first;
557
+ while (transformPtr != NULL)
558
+ {
559
+ if (transformPtr->next &&
560
+ (transformPtr->next->id->usage | xmlSecTransformUsageC14NMethod))
561
+ {
562
+ break;
563
+ }
564
+ transformPtr = transformPtr->next;
565
+ }
566
+ if (!transformPtr || !transformPtr->outNodes)
567
+ {
568
+ THROW(XMLError, "Couldn't find transform node", -1);
569
+ }
570
+ {
571
+ int ret = (*callbackFn)(transformPtr->outNodes, this, data);
572
+ if (ret != 0)
573
+ {
574
+ return ret;
575
+ }
576
+ }
577
+ cur = xmlSecGetNextElementNode(cur->next);
578
+ }
579
+ return 0;
580
+ }
581
+
582
+
583
+ int Verifier::isReferencedCallback (xmlSecNodeSetPtr nset, Verifier* verifier, void* data)
584
+ {
585
+ assert(verifier);
586
+ assert(data);
587
+ if (nset == NULL)
588
+ {
589
+ return 0;
590
+ }
591
+ XPathPtr xPathElem (*(XPathPtr*)data);
592
+ return verifier->isContained(nset, xPathElem);
593
+ }
594
+
595
+
596
+ int Verifier::isReferenced (XPathPtr xPathElem)
597
+ {
598
+ assert(xPathElem);
599
+ return refNodes(Verifier::isReferencedCallback, &xPathElem);
600
+ }
601
+
602
+
603
+ int Verifier::getElementsCallback (xmlSecNodeSetPtr, xmlNodePtr cur, xmlNodePtr, void *data)
604
+ {
605
+ try
606
+ {
607
+ XmlElementPtr element (new XmlElement(cur));
608
+ if (element)
609
+ {
610
+ if (*element)
611
+ {
612
+ vector<XmlElementPtr>& elementVec (*(vector<XmlElementPtr>*)data);
613
+ elementVec.push_back(element);
614
+ }
615
+ }
616
+ }
617
+ // ignore exception thrown if cur node is not of element type
618
+ catch (XMLError)
619
+ {}
620
+ return 0;
621
+ }
622
+
623
+
624
+ int Verifier::getReferencedElementsCallback (xmlSecNodeSetPtr nset, Verifier* verifier, void* data)
625
+ {
626
+ assert(verifier);
627
+ assert(data);
628
+ if (nset == NULL)
629
+ {
630
+ return 0;
631
+ }
632
+ if (xmlSecNodeSetWalk(nset, Verifier::getElementsCallback, data) < 0)
633
+ {
634
+ THROW(LibError, "Node set walk failure", -1);
635
+ }
636
+ return 0;
637
+ }
638
+
639
+
640
+ vector<XmlElementPtr> Verifier::getReferencedElements ()
641
+ {
642
+ vector<XmlElementPtr> elementVec;
643
+ if (refNodes(Verifier::getReferencedElementsCallback, &elementVec) < 0)
644
+ {
645
+ vector<XmlElementPtr> nullVec;
646
+ return nullVec;
647
+ }
648
+ return elementVec;
649
+ }
650
+
651
+
652
+ xmlSecNodeSetPtr Verifier::nodeSetFromTransformCtx (xmlSecTransformCtxPtr ctx, xmlDocPtr doc)
653
+ {
654
+ xmlSecNodeSetPtr nodes;
655
+
656
+ if ((ctx->uri != NULL) &&
657
+ (xmlStrlen(ctx->uri) > 0))
658
+ {
659
+ return NULL;
660
+ }
661
+
662
+ if ((ctx->xptrExpr != NULL) && (xmlStrlen(ctx->xptrExpr) > 0))
663
+ {
664
+ // our xpointer transform takes care of providing correct nodes set
665
+ nodes = xmlSecNodeSetCreate(doc, NULL, xmlSecNodeSetNormal);
666
+ }
667
+ else
668
+ {
669
+ // we do not want to have comments for empty URI
670
+ nodes = xmlSecNodeSetGetChildren(doc, NULL, 0, 0);
671
+ }
672
+ if (nodes == NULL)
673
+ {
674
+ THROW(LibError, "Unable to create nodeset", 0);
675
+ }
676
+ return nodes;
677
+ }