xmlsig 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ }