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,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
+ }