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,691 @@
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
+ #include <libxml/uri.h>
23
+ #include <libxml/debugXML.h>
24
+ #ifndef XMLSEC_NO_XSLT
25
+ #include <libxslt/xslt.h>
26
+ #endif /* XMLSEC_NO_XSLT */
27
+ #include <xmlsec/xmlsec.h>
28
+ #include <xmlsec/xmltree.h>
29
+ #include <xmlsec/xmldsig.h>
30
+ #include <xmlsec/templates.h>
31
+ #include <xmlsec/openssl/app.h>
32
+ #include <xmlsec/openssl/crypto.h>
33
+ #if defined(WIN32) && defined(PHP_EXPORTS)
34
+ #define IN_XMLSEC
35
+ #endif
36
+ #include <xmlsec/openssl/symbols.h>
37
+ #include <assert.h>
38
+
39
+ #include "Signer.h"
40
+ #include "Key.h"
41
+ #include "XmlDoc.h"
42
+ #include "XPath.h"
43
+ #include "DSigCtx.h"
44
+ #include "KeysMngrWrap.h"
45
+ #include "XmlCharBuf.h"
46
+ using namespace std;
47
+
48
+
49
+ Signer::Signer (XmlDocClassPtr doc, KeyPtr key)
50
+ : mXmlDoc(doc),
51
+ mKey(key),
52
+ mVerifyKey(0),
53
+ c14n_excl(0),
54
+ mAddKeyInfo(0),
55
+ mAddKeyValue(0)
56
+ {}
57
+
58
+
59
+ Signer::Signer (XmlDocClassPtr doc, KeyPtr key, KeyPtr verifyKey)
60
+ : mXmlDoc(doc),
61
+ mKey(key),
62
+ mVerifyKey(verifyKey),
63
+ c14n_excl(0),
64
+ mAddKeyInfo(0),
65
+ mAddKeyValue(0)
66
+ {
67
+ if (!mVerifyKey)
68
+ {
69
+ return;
70
+ }
71
+ key->addCert(mVerifyKey);
72
+ mAddKeyInfo = 1;
73
+ mAddKeyValue = 1;
74
+ }
75
+
76
+
77
+ Signer::Signer (XmlDocClassPtr doc, KeyPtr key, X509CertificatePtr cert)
78
+ : mXmlDoc(doc),
79
+ mKey(key),
80
+ mVerifyKey(0),
81
+ c14n_excl(0),
82
+ mAddKeyInfo(0),
83
+ mAddKeyValue(0)
84
+ {
85
+ if (key && key->isValid() && cert)
86
+ {
87
+ mVerifyKey = cert->getKey();
88
+ if (mKey->addCert(cert) >= 0)
89
+ {
90
+ mAddKeyInfo = 1;
91
+ }
92
+ }
93
+ }
94
+
95
+
96
+ Signer::Signer (XmlDocClassPtr doc, KeyPtr key, vector<X509CertificatePtr> cert)
97
+ : mXmlDoc(doc),
98
+ mKey(key),
99
+ mVerifyKey(0),
100
+ c14n_excl(0),
101
+ mAddKeyInfo(0),
102
+ mAddKeyValue(0)
103
+ {
104
+ if (key && key->isValid() && (cert.size() > 0))
105
+ {
106
+ mVerifyKey = cert[0]->getKey();
107
+ if (mKey->addCert(cert) >= 0)
108
+ {
109
+ mAddKeyInfo = 1;
110
+ }
111
+ }
112
+ }
113
+
114
+
115
+ Signer::~Signer ()
116
+ {}
117
+
118
+
119
+ XmlDocClassPtr Signer::sign ()
120
+ {
121
+ return sign((XPathPtr)0);
122
+ }
123
+
124
+
125
+ XmlDocClassPtr Signer::sign (XPathPtr xPath)
126
+ {
127
+ return sign(xPath, false);
128
+ }
129
+
130
+
131
+ XmlDocClassPtr Signer::sign (XPathPtr xPath, bool insertBefore)
132
+ {
133
+ assert(mXmlDoc);
134
+ XmlDocClassPtr copyDoc = new XmlDoc(*mXmlDoc);
135
+ if (!copyDoc)
136
+ {
137
+ THROW(MemoryError, "Unable to create duplicate XML document", 0);
138
+ }
139
+ XmlDocClassPtr origXmlDoc = mXmlDoc;
140
+ mXmlDoc = copyDoc;
141
+ int retVal = xPath ? signInPlace(xPath, insertBefore) : signInPlace();
142
+ mXmlDoc = origXmlDoc;
143
+ if (retVal < 0)
144
+ {
145
+ return 0;
146
+ }
147
+ return copyDoc;
148
+ }
149
+
150
+
151
+ int Signer::signInPlace ()
152
+ {
153
+ assert(mXmlDoc);
154
+ if (!*mXmlDoc)
155
+ {
156
+ THROW(DocError, "Document was not loaded", -1);
157
+ }
158
+ if (!validateXPathRefs())
159
+ {
160
+ THROW(XPathError, "Invalid XPath references", -1);
161
+ }
162
+ xmlNodePtr sigNode = xmlSecFindNode(xmlDocGetRootElement(*mXmlDoc),
163
+ xmlSecNodeSignature, xmlSecDSigNs);
164
+ if (sigNode == NULL)
165
+ {
166
+ sigNode = createTemplate(*mXmlDoc, 0, false);
167
+ }
168
+ return signNode(sigNode);
169
+ }
170
+
171
+
172
+ int Signer::signInPlace (XPathPtr xPath)
173
+ {
174
+ return signInPlace(xPath, false);
175
+ }
176
+
177
+
178
+ int Signer::signInPlace (XPathPtr xPath, bool insertBefore)
179
+ {
180
+ assert(xPath);
181
+ assert(mXmlDoc);
182
+ if (!*mXmlDoc)
183
+ {
184
+ THROW(DocError, "Document was not loaded", -1);
185
+ }
186
+ if (!validateXPathRefs())
187
+ {
188
+ THROW(XPathError, "Invalid XPath references", -1);
189
+ }
190
+ xmlNodePtr node = locateSignature(xPath);
191
+ if (!node)
192
+ {
193
+ return -1;
194
+ }
195
+ xmlNodePtr sigNode = checkForSignatureElement(node, insertBefore);
196
+ if (!sigNode)
197
+ {
198
+ sigNode = createTemplate(*mXmlDoc, node, insertBefore);
199
+ }
200
+ return signNode(sigNode);
201
+ }
202
+
203
+
204
+ xmlNodePtr Signer::locateSignature (XPathPtr xPath)
205
+ {
206
+ xmlXPathObjectPtr xpObj = xPath->evalExpression(mXmlDoc);
207
+ if (xpObj == NULL)
208
+ {
209
+ THROW(XPathError, "Unable to evaluate XPath expression", 0);
210
+ }
211
+ //fprintf(stderr, "'%s' found %d nodes\n", xpathstr, xpObj->nodesetval->nodeNr);
212
+ if (xpObj->nodesetval->nodeNr == 0)
213
+ {
214
+ THROW(XPathError, "No nodes found for XPath expression", 0);
215
+ }
216
+ if (xpObj->nodesetval->nodeNr > 1)
217
+ {
218
+ THROW(XPathError, "Multiple nodes found for XPath expression", 0);
219
+ }
220
+ xmlNodePtr node = *(xpObj->nodesetval->nodeTab);
221
+ if (node->type == XML_DOCUMENT_NODE)
222
+ {
223
+ // take care of the "/" xpath case; we sign the first child of the doc
224
+ // instead of the entire doc (a fine but necessary distinction)
225
+ node = node->children;
226
+ }
227
+ //xmlElemDump(stderr, *mXmlDoc, node);
228
+ return node;
229
+ }
230
+
231
+
232
+ xmlNodePtr Signer::checkForSignatureElement (xmlNodePtr node, int insertBefore)
233
+ {
234
+ xmlNodePtr sigNode = 0;
235
+ if (node)
236
+ {
237
+ if (insertBefore && (node->parent->type != XML_DOCUMENT_NODE))
238
+ {
239
+ // Check previous sibling
240
+ node = node->prev;
241
+ }
242
+ else
243
+ {
244
+ // Check children
245
+ node = xmlSecFindChild(node, xmlSecNodeSignature, xmlSecDSigNs);
246
+ }
247
+ }
248
+ else
249
+ {
250
+ // check root element
251
+ node = xmlDocGetRootElement(*mXmlDoc);
252
+ }
253
+ if (node && xmlSecCheckNodeName(node, xmlSecNodeSignature, xmlSecDSigNs))
254
+ {
255
+ sigNode = node;
256
+ }
257
+ return sigNode;
258
+ }
259
+
260
+
261
+ int Signer::setKeyStore (KeyStorePtr newKeyStore)
262
+ {
263
+ keyStore = newKeyStore;
264
+ return keyStore ? 0 : -1;
265
+ }
266
+
267
+
268
+ void Signer::attachPublicKey (int value)
269
+ {
270
+ mAddKeyValue = value;
271
+ }
272
+
273
+
274
+ int Signer::addCertFromFile (string fileName, string format)
275
+ {
276
+ assert(mKey);
277
+ if (mKey->addCertFromFile(fileName, format) < 0)
278
+ {
279
+ return -1;
280
+ }
281
+ mAddKeyInfo = 1;
282
+ return 0;
283
+ }
284
+
285
+
286
+ int Signer::addCert (X509CertificatePtr cert)
287
+ {
288
+ assert(mKey);
289
+ if (mKey->addCert(cert) < 0)
290
+ {
291
+ return -1;
292
+ }
293
+ mAddKeyInfo = 1;
294
+ return 0;
295
+ }
296
+
297
+
298
+ int Signer::useExclusiveCanonicalizer (string prefixes)
299
+ {
300
+ c14n_excl = 1;
301
+ c14n_excl_incprefixes = prefixes;
302
+ return 0;
303
+ }
304
+
305
+
306
+ void Signer::addReference (XPathPtr xPathPtr)
307
+ {
308
+ assert(xPathPtr);
309
+ XPath xPath (*xPathPtr);
310
+ xPathRefs.push_back(xPath);
311
+ }
312
+
313
+
314
+ xmlSecTransformId Signer::c14nMethod () const
315
+ {
316
+ return c14n_excl ?
317
+ xmlSecTransformExclC14NId :
318
+ xmlSecTransformInclC14NId;
319
+ }
320
+
321
+
322
+ xmlNodePtr Signer::c14nMethodTransform (xmlNodePtr refNode)
323
+ {
324
+ assert(refNode);
325
+ xmlNodePtr xformNode = xmlSecTmplReferenceAddTransform(refNode,
326
+ c14nMethod());
327
+ if (xformNode == 0)
328
+ {
329
+ THROW(LibError, "Failed to add c14n transform to reference", 0);
330
+ }
331
+ return xformNode;
332
+ }
333
+
334
+
335
+ int Signer::isEnveloped (xmlNodePtr refNode, XPath& xPath)
336
+ {
337
+ xmlXPathObjectPtr xpObj = xPath.evalExpression(mXmlDoc);
338
+ if (xpObj == NULL)
339
+ {
340
+ THROW(XPathError, "Unable to evaluate XPath expression", -1);
341
+ }
342
+ xmlSecNodeSetPtr nodes = xmlSecNodeSetCreate(*mXmlDoc,
343
+ xpObj->nodesetval,
344
+ xmlSecNodeSetTree);
345
+ if (nodes == NULL)
346
+ {
347
+ THROW(LibError, "Unable to create node set from XPath results", -1);
348
+ }
349
+ int ret = xmlSecNodeSetContains(nodes, refNode, refNode->parent);
350
+ if (ret < 0)
351
+ {
352
+ THROW(LibError, "Failure checking containment in node set", ret);
353
+ }
354
+ return ret;
355
+ }
356
+
357
+
358
+ int Signer::certAdded ()
359
+ {
360
+ int certAdded = 0;
361
+ if (mKey)
362
+ {
363
+ X509CertificatePtr cert = mKey->getCertificate();
364
+ certAdded = ((const void*)cert != 0);
365
+ }
366
+ return certAdded;
367
+ }
368
+
369
+
370
+ xmlNodePtr Signer::createTemplate (xmlDocPtr doc, xmlNodePtr node, bool insertBefore)
371
+ {
372
+ assert(doc);
373
+ assert(mKey);
374
+ assert(mKey->getKey());
375
+ assert(mKey->getKey()->value);
376
+ assert(mKey->getKey()->value->id);
377
+
378
+ XmlCharBuf objectId (xmlSecGenerateID(BAD_CAST "obj-", 10));
379
+ if (!(int)objectId)
380
+ {
381
+ THROW(MemoryError, "Unable to allocate generated ID", 0);
382
+ }
383
+
384
+ xmlSecKeyDataId keyDataId = mKey->getKey()->value->id;
385
+ xmlSecTransformId signatureTransformId = NULL;
386
+ if (keyDataId == xmlSecKeyDataDsaId)
387
+ {
388
+ signatureTransformId = xmlSecTransformDsaSha1Id;
389
+ }
390
+ else if (keyDataId == xmlSecKeyDataRsaId)
391
+ {
392
+ signatureTransformId = xmlSecTransformRsaSha1Id;
393
+ }
394
+ else if (keyDataId == xmlSecKeyDataHmacId)
395
+ {
396
+ signatureTransformId = xmlSecTransformHmacSha1Id;
397
+ }
398
+ else
399
+ {
400
+ THROW(KeyError, "Unable to find signature transform for key type", 0);
401
+ }
402
+ xmlNodePtr sigNode =
403
+ #ifdef HAVE_XMLSECTMPLSIGNATURECREATENSPREF
404
+ xmlSecTmplSignatureCreateNsPref(doc, c14nMethod(), signatureTransformId, NULL, BAD_CAST "ds");
405
+ #else
406
+ xmlSecTmplSignatureCreate(doc, c14nMethod(), signatureTransformId, NULL);
407
+ #endif
408
+ if (sigNode == NULL)
409
+ {
410
+ THROW(LibError, "Failed to create signature template", 0);
411
+ }
412
+
413
+ // enveloping if no location to put the signature
414
+ if (node == NULL)
415
+ {
416
+ // add <dsig:Signature/> node to the doc
417
+ xmlNodePtr objContents = xmlDocGetRootElement(doc);
418
+ xmlDocSetRootElement(doc, sigNode);
419
+
420
+ // Add ObjectNode
421
+ xmlNodePtr objNode = xmlSecTmplSignatureAddObject(xmlDocGetRootElement(doc),
422
+ BAD_CAST objectId, NULL, NULL);
423
+ if (objNode == NULL)
424
+ {
425
+ THROW(LibError, "Failed to add object to signature template", 0);
426
+ }
427
+
428
+ xmlAddChild(objNode, objContents);
429
+ }
430
+
431
+ if (c14n_excl)
432
+ {
433
+ xmlNodePtr c14nMethodNode = xmlSecTmplSignatureGetC14NMethodNode(sigNode);
434
+ if (c14nMethodNode == NULL)
435
+ {
436
+ THROW(LibError, "Couldn't retrieve C14N method node", 0);
437
+ }
438
+ if (c14n_excl_incprefixes.length() > 0)
439
+ {
440
+ if (xmlSecTmplTransformAddC14NInclNamespaces(c14nMethodNode,
441
+ BAD_CAST c14n_excl_incprefixes.c_str()) < 0)
442
+ {
443
+ THROW(LibError, "Couldn't set C14N incl namespaces", 0);
444
+ }
445
+ }
446
+ }
447
+
448
+ if (xPathRefs.size() > 0)
449
+ {
450
+ for (vector<XPath>::iterator xPathRef = xPathRefs.begin();
451
+ xPathRef != xPathRefs.end(); xPathRef++)
452
+ {
453
+ int enveloped = 0;
454
+ string uri ("");
455
+ // don't use xpointer(/), use "" instead for greater compatibility
456
+ if (xPathRef->getXPath() != "/")
457
+ {
458
+ uri = "#";
459
+ uri += xPathRef->getNamespaceStr();
460
+ if (node == NULL)
461
+ {
462
+ uri += "xmlns(dsig=http://www.w3.org/2000/09/xmldsig#)xpointer(";
463
+ uri += "/descendant::dsig:Object[@Id='";
464
+ uri += (const char*)objectId;
465
+ uri += "']";
466
+ }
467
+ else
468
+ {
469
+ uri += "xpointer(";
470
+ }
471
+ uri += xPathRef->getXPath();
472
+ uri += ")";
473
+ }
474
+ else
475
+ {
476
+ // reference is "/", so we're definitely enveloped
477
+ enveloped = 1;
478
+ }
479
+ xmlNodePtr refNode =
480
+ xmlSecTmplSignatureAddReference(sigNode, xmlSecTransformSha1Id,
481
+ NULL, BAD_CAST uri.c_str(), NULL);
482
+ if (refNode == NULL)
483
+ {
484
+ THROW(LibError, "Failed to add reference to signature template", 0);
485
+ }
486
+ if (node)
487
+ {
488
+ enveloped = enveloped || isEnveloped(node, *xPathRef);
489
+ if (enveloped < 0)
490
+ {
491
+ return 0;
492
+ }
493
+ else if (enveloped)
494
+ {
495
+ // add enveloped transform
496
+ if (xmlSecTmplReferenceAddTransform(refNode,
497
+ xmlSecTransformEnvelopedId) == NULL)
498
+ {
499
+ THROW(LibError, "Failed to add enveloped transform to reference", 0);
500
+ }
501
+ }
502
+ }
503
+ if (c14nMethodTransform(refNode) == 0)
504
+ {
505
+ return 0;
506
+ }
507
+ }
508
+ }
509
+ else if (node)
510
+ {
511
+ // add reference
512
+ xmlNodePtr refNode =
513
+ xmlSecTmplSignatureAddReference(sigNode, xmlSecTransformSha1Id,
514
+ NULL, BAD_CAST "", NULL);
515
+ if (refNode == NULL)
516
+ {
517
+ THROW(LibError, "Failed to add reference to signature template", 0);
518
+ }
519
+
520
+ // add enveloped transform
521
+ if (xmlSecTmplReferenceAddTransform(refNode,
522
+ xmlSecTransformEnvelopedId) == NULL)
523
+ {
524
+ THROW(LibError, "Failed to add enveloped transform to reference", 0);
525
+ }
526
+ if (c14nMethodTransform(refNode) == 0)
527
+ {
528
+ return 0;
529
+ }
530
+ }
531
+ else
532
+ {
533
+ string objectRef;
534
+ objectRef += "#";
535
+ objectRef += (const char*)objectId;
536
+ xmlNodePtr refNode =
537
+ xmlSecTmplSignatureAddReference(xmlDocGetRootElement(doc),
538
+ xmlSecTransformSha1Id,
539
+ NULL, BAD_CAST objectRef.c_str(), NULL);
540
+ if (refNode == NULL)
541
+ {
542
+ THROW(LibError, "Failed to add reference to signature template", 0);
543
+ }
544
+ if (c14nMethodTransform(refNode) == 0)
545
+ {
546
+ return 0;
547
+ }
548
+ }
549
+
550
+ // add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name
551
+ // in the signed document
552
+ // Don't add <dsig:KeyInfo/> unless absolutely necessary though
553
+ xmlNodePtr keyInfoNode = NULL;
554
+
555
+ if (mAddKeyInfo || mAddKeyValue || keyStore)
556
+ {
557
+ if (!keyInfoNode)
558
+ {
559
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(sigNode, NULL);
560
+ if (keyInfoNode == NULL)
561
+ {
562
+ THROW(LibError, "Failed to add key info to signature template", 0);
563
+ }
564
+ }
565
+ if (mAddKeyValue) {
566
+ if (xmlSecTmplKeyInfoAddKeyValue(keyInfoNode) == NULL)
567
+ {
568
+ THROW(LibError, "Failed to add key value to signature template", 0);
569
+ }
570
+ }
571
+ }
572
+
573
+ if (certAdded() > 0)
574
+ {
575
+ if (!keyInfoNode)
576
+ {
577
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(sigNode, NULL);
578
+ if (keyInfoNode == NULL)
579
+ {
580
+ THROW(LibError, "Failed to add key info to signature template", 0);
581
+ }
582
+ }
583
+ if (xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL)
584
+ {
585
+ THROW(LibError, "Failed to add X509Data node to signature template", 0);
586
+ }
587
+ }
588
+
589
+ if (mKey->getName().length())
590
+ {
591
+ if (!keyInfoNode)
592
+ {
593
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(sigNode, NULL);
594
+ if (keyInfoNode == NULL)
595
+ {
596
+ THROW(LibError, "Failed to add key info to signature template", 0);
597
+ }
598
+ }
599
+ if (xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL)
600
+ {
601
+ THROW(LibError, "Failed to add key name to signature template", 0);
602
+ }
603
+ }
604
+
605
+ if (node)
606
+ {
607
+ if (insertBefore && (node->parent->type != XML_DOCUMENT_NODE))
608
+ {
609
+ return xmlAddPrevSibling(node, sigNode);
610
+ }
611
+ return xmlAddChild(node, sigNode);
612
+ }
613
+ return xmlDocGetRootElement(doc);
614
+ }
615
+
616
+
617
+ int Signer::signNode (xmlNodePtr sigNode)
618
+ {
619
+ //xmlDocDump(stderr, sigNode->doc);
620
+ if (!sigNode ||
621
+ !xmlSecCheckNodeName(sigNode, xmlSecNodeSignature, xmlSecDSigNs))
622
+ {
623
+ THROW(XMLError, "Invalid signature node", -1);
624
+ }
625
+
626
+ if (!mKey || !(*mKey))
627
+ {
628
+ THROW(KeyError, "Key was not loaded", -1);
629
+ }
630
+
631
+ // create a keys manager if necessary
632
+ KeysMngr localKeysMngr;
633
+ xmlSecKeysMngrPtr keysMngr = 0;
634
+ if (keyStore)
635
+ {
636
+ keysMngr = *keyStore;
637
+ }
638
+ else
639
+ {
640
+ keysMngr = localKeysMngr;
641
+ }
642
+
643
+ if (mVerifyKey)
644
+ {
645
+ if ((!keysMngr) ||
646
+ (xmlSecOpenSSLAppDefaultKeysMngrInit(keysMngr) < 0))
647
+ {
648
+ THROW(LibError, "Key manager not created", -1);
649
+ }
650
+ // create a duplicate so keys mngr can adopt it & destroy later
651
+ xmlSecKeyPtr vKey = mVerifyKey->dupKey();
652
+ if (vKey == NULL)
653
+ {
654
+ return -1;
655
+ }
656
+ if (xmlSecOpenSSLAppDefaultKeysMngrAdoptKey(keysMngr, vKey) < 0)
657
+ {
658
+ THROW(LibError, "Unable to adopt verify key into key manager", -1);
659
+ }
660
+ }
661
+
662
+ DSigCtx dsigCtx(keysMngr);
663
+ if (!dsigCtx)
664
+ {
665
+ return -1;
666
+ }
667
+ // dsigCtx destruction also tries to free key, so give it a dup
668
+ dsigCtx->signKey = mKey->dupKey();
669
+
670
+ // sign the template
671
+ if (xmlSecDSigCtxSign(dsigCtx, sigNode) < 0)
672
+ {
673
+ THROW(LibError, "Signature failed", -1);
674
+ }
675
+ // success
676
+ return 0;
677
+ }
678
+
679
+
680
+ int Signer::validateXPathRefs ()
681
+ {
682
+ int valid = 1;
683
+ for (vector<XPath>::iterator xPathRef = xPathRefs.begin();
684
+ xPathRef != xPathRefs.end(); xPathRef++)
685
+ {
686
+ valid = valid && (xPathRef->evalExpression(mXmlDoc) != 0);
687
+ // fprintf(stderr, "Checking '%s': valid %d\n",
688
+ // xPathRef->getXPath().c_str(), valid);
689
+ }
690
+ return valid;
691
+ }