File: DSIGSignature.hpp

package info (click to toggle)
xml-security-c 1.5.1-3%2Bsqueeze3
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 7,424 kB
  • ctags: 5,832
  • sloc: cpp: 45,357; sh: 8,270; makefile: 689
file content (1010 lines) | stat: -rw-r--r-- 30,456 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
/*
 * Copyright 2002-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * XSEC
 *
 * DSIGSignature := Class for checking and setting up signature nodes in a DSIG signature
 *
 * Author(s): Berin Lautenbach
 *
 * $Id: DSIGSignature.hpp 566299 2007-08-15 18:51:47Z scantor $
 *
 */

#ifndef DSIGSIGNATURE_INCLUDE
#define DSIGSIGNATURE_INCLUDE

// XSEC Includes
#include <xsec/utils/XSECSafeBufferFormatter.hpp>
#include <xsec/dsig/DSIGTransform.hpp>
#include <xsec/dsig/DSIGKeyInfoList.hpp>
#include <xsec/dsig/DSIGConstants.hpp>
#include <xsec/dsig/DSIGSignedInfo.hpp>

// Xerces Includes

#include <xercesc/dom/DOM.hpp>

class XSECEnv;
class XSECBinTXFMInputStream;
class XSECURIResolver;
class XSECKeyInfoResolver;
class DSIGKeyInfoValue;
class DSIGKeyInfoX509;
class DSIGKeyInfoName;
class DSIGKeyInfoPGPData;
class DSIGKeyInfoSPKIData;
class DSIGKeyInfoMgmtData;
class DSIGObject;

/**
 * @ingroup pubsig
 */
/*\@{*/

/**
 * @brief The main class used for manipulating XML Digital Signatures.
 *
 * <p>The DSIGSignature class is used to manipulate and verify
 * \<signature\> blocks.  It should only ever be created via the 
 * XSECProvider class.</p>
 *
 */

class DSIG_EXPORT DSIGSignature {

protected:

    /** @name Constructors and Destructors */
    //@{
	
    /**
	 * \brief Contructor for use with existing XML signatures or templates.
	 *
	 * <p>Create a DSIGSignature object based on an already existing
	 * DSIG Signature XML node.  It is assumed that the underlying
	 * DOM structure is in place and works correctly.</p>
	 *
	 * <p>It is required that the caller pass in the signature DOM Node
	 * as there may be more than one signature in a document.  The caller
	 * needs to specify which signature tree is to be used.</p>
	 *
	 * @param doc The DOM document node in which the signature is embedded.
	 * @param sigNode The DOM node (within doc) that is to be used as the base of the signature.
	 * @see #load
	 */

	DSIGSignature(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc, 
				  XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *sigNode);

	~DSIGSignature();
    //@}
	
public:

	/** @name Load and Setup Functions */
	//@{

	/**
	  * \brief Load the signature information from the DOM source.
	  *
	  * Used to tell the DSIGSignature object to read from the DOM tree
	  * into local structures.  Will throw various exceptions if it finds that
	  * the DOM structure is not in line with the XML Signature standard.
	  *
	  */

	void load(void);

	/**
	  * \brief Externally set the signing/verification key
	  *
	  * Used prior to a verify or sign operation to set the signature key (public or
	  * private respectively) to be used for the operation.
	  *
	  * @note Once passed in via this call, the key is owned by the Signature.  It will
	  * deleted when a new key is loaded or the signature is released.
	  *
	  * @see #verify
	  * @see #sign
	  */

	void setSigningKey(XSECCryptoKey *k);

	//@}

	/** @name Signature Operations */
	//@{

	/**
	  * \brief Verify that a signature is valid.
	  *
	  * <p>The <I>verify</I> function will validate the signature of an XML document
	  * previously loaded into the DSIGSignature structure via a <I>load</I>.</p>
	  *
	  * <p>It performs the following operations : </p>
	  * <ul>
	  *		<li>Iterate through each reference and validate the hash;
	  *		<li>Iterate through references contained in \<manifest\> elements;
	  *		<li>Calculate the hash of the \<SignedInfo\> element; and
	  *		<li>Validate the signature of the hash previously calculated.
	  * </ul>
	  * 
	  * @returns true/false
	  *		<ul>
	  *        <li><b>true</b> = Signature (and all references) validated correctly.
	  *		   <li><b>false</b> = Signature validation failed.  An error list can be found via a
	  *          call to #getErrMsgs.
	  *		</ul>
	  * @see #load
	  * @see #getErrMsgs
	  */

	bool verify(void);

	/**
	  * \brief Verify a signature is valid (skip references).
	  *
	  * <p>This function is almost the same as #verify except it will skip the
	  * reference checks.
	  *
	  * @see #load
	  * @see #verify
	  */

	bool verifySignatureOnly(void);

	/**
	  * \brief Sign a DSIGSignature DOM structure.
	  *
	  * <p>The #sign function will create the reference hash values and signature
	  * value in a DOM structure previously created via a #load or #createBlankSignature
	  * call </p>
	  *
	  * <p>It performs the following operations : </p>
	  * <ul>
	  *		<li>Iterate through each reference, calculate and set the hash value;
	  *		<li>Iterate through references contained in \<manifest\> elements and set their values;
	  *		<li>Calculate the hash of the \<SignedInfo\> element; and
	  *		<li>Calculate (and set) the signature value given the hash previously calculated.
	  * </ul>
	  * 
	  * @note The key to use for signing must have been set prior to call to sign using #setSigningKey
	  *
	  * @throws XSECException (for errors during the XML formatting and loading)
	  * @throws XSECCryptoException (for errors during the cryptographic operations)
	  *
	  * @see #setSigningKey
	  * @see #load
	  * @see #getErrMsgs
	  */

	void sign(void);
	//@}

	/** @name Functions to create and manipulate signature elements. */
	//@{
	
	/**
	  * \brief Set the prefix be used for the DSIG namespace.
	  *
	  * <p>When the XSEC library creates XML Element nodes, it uses the prefix here
	  * for all nodes created.  By default, the library assumes that the default
	  * namespace is used.</p>
	  *
	  * <p>The #createBlankSignature function will use this prefix to setup the
	  * dsig namespace.  E.g. (assuming a call has been made to set the prefix to "ds")
	  * the \<Signature\> element will have a namespace attribute added of</p>
	  *
	  * <p>xmlns:ds="http://www.w3.org/2000/09/xmldsig#"</p>
	  *
	  * <p>If no prefix has been set, this attribute will be set as the default namespace</p>
	  *
	  * @see #createBlankSignature
	  * @param prefix The UTF-16 encoided NS prefix to use for the XML 
	  * Digital Signature nodes
	  */

	void setDSIGNSPrefix(const XMLCh * prefix);

	/**
	  * \brief Set the prefix be used for the Exclusive Canonicalisation namespace.
	  *
	  * The Exclusive Canonicalisation specification defines a new namespace for the
	  * InclusiveNamespaces node.  This function can be used to set the prefix
	  * that the library will use when creating nodes within this namespace.
	  *
	  * <p>xmlns:ds="http://www.w3.org/2001/10/xml-exc-c14n#"</p>
	  *
	  * If no prefix is set, the default namespace will be used
	  *
	  * @see #createBlankSignature
	  * @param prefix The UTF-16 encoided NS prefix to use for the XML 
	  * Exclusive Canonicalisation nodes
	  */

	void setECNSPrefix(const XMLCh * prefix);

	/**
	  * \brief Set the prefix be used for the XPath-Filter2 namespace.
	  *
	  * The XPathFilter definition uses its own namespace.  This
	  * method can be used to set the prefix that the library will use
	  * when creating elements in this namespace
	  *
	  * <p>xmlns:ds="http://www.w3.org/2002/06/xmldsig-filter2"</p>
	  *
	  * If no prefix is set, the default namespace will be used
	  *
	  * @see #createBlankSignature
	  * @param prefix The UTF-16 encoided NS prefix to use for the XPath
	  * filter nodes
	  */

	void setXPFNSPrefix(const XMLCh * prefix);

	/**
	 * \brief Set Pretty Print
	 *
	 * The pretty print functions controls whether the library will output
	 * CR/LF after the elements it adds to a document
	 *
	 * By default the library will do pretty printing (flag is true)
	 *
	 * @param flag Value to set for Pretty Printing (true = do pretty printing)
	 */

	void setPrettyPrint(bool flag);

	/**
	 * \brief Tell caller whether PrettyPrinting is active
	 *
	 * @returns True if Pretty Printing is active, false if not
	 */

	bool getPrettyPrint(void) const;

	/**
	 * \brief Create a \<Signature\> DOM structure.
	 *
	 * <p>The DOM structure created is still divorced from the document.  The callee
	 * needs to take the returned \<Signature\> Element node and insert it at the
	 * appropriate place in their document.</p>
	 *
	 * <p>The signature is a skeleton only.  There are no references or KeyInfo
	 * elements inserted.  However the DSIGSignature structures are set up with the
	 * new information, so once an element has been created and a signing key has been
	 * set, a call to #sign will sign appropriately.
	 *
	 * @note The digest method (hash method) set here is for the signing function only.
	 * Different hash methods can be used for reference elements.
	 *
	 * @param doc The document the Signature DOM structure will be inserted into.
	 * @param canonicalizationAlgorithmURI The canonicalisation method to use.
	 * @param signatureAlgorithmURI The Signature algorithm (defined by URI) to use
	 * @returns The newly created \<Signature\> element that the caller should insert in
	 * the document.
	 */

	XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *createBlankSignature(
		XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc,
		const XMLCh * canonicalizationAlgorithmURI,
		const XMLCh * signatureAlgorithmURI
	);

	/**
	 * \brief Create a \<Signature\> DOM structure.
	 *
	 * <p>The DOM structure created is still divorced from the document.  The callee
	 * needs to take the returned \<Signature\> Element node and insert it at the
	 * appropriate place in their document.</p>
	 *
	 * <p>The signature is a skeleton only.  There are no references or KeyInfo
	 * elements inserted.  However the DSIGSignature structures are set up with the
	 * new information, so once an element has been created and a signing key has been
	 * set, a call to #sign will sign appropriately.
	 *
	 * @note The digest method (hash method) set here is for the signing function only.
	 * Different hash methods can be used for reference elements.
	 *
	 * @param doc The document the Signature DOM structure will be inserted into.
	 * @param cm The canonicalisation method to use.
	 * @param sm The signature algorithm to be used.
	 * @param hm The Digest function to be used for the actual signatures.
	 * @returns The newly created \<Signature\> element that the caller should insert in
	 * the document.
	 * @deprecated Use the URI based creation method instead, as this supports 
	 * signature algorithms that are not known to the library directly.
	 */

	XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *createBlankSignature(
		XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc,
		canonicalizationMethod cm = CANON_C14N_NOC,
		signatureMethod	sm = SIGNATURE_DSA,
		hashMethod hm = HASH_SHA1
	);

	/**
	 * \brief Add a new reference to the end of the list of \<Reference\> nodes.
	 *
	 * <p>Creates a new DSIGReference, adds it to the list of references handled
	 * by the owning DSIGSignature and also creates the skeleton DOM structure into
	 * the document.</p>
	 *
	 * @note The XSEC Library currently makes very little use of <em>type</em>
	 * attributes in \<Reference\> Elements.  However this may of use to calling
	 * applications.
	 *
	 * @see DSIGReference
	 * @param URI The Data that this Reference node refers to.
	 * @param hm The hashing (digest) method to be used for this reference
	 * @param type A "type" string (as defined in XML Signature).
	 * @returns The newly created DSIGReference element.
	 * @deprecated Use the URI based creation method instead
	 *
	 */

	
	DSIGReference * createReference(
		const XMLCh * URI,
		hashMethod hm = HASH_SHA1, 
		char * type = NULL
	);

	/**
	 * \brief Add a new reference to the end of the list of \<Reference\> nodes.
	 *
	 * <p>Creates a new DSIGReference, adds it to the list of references handled
	 * by the owning DSIGSignature and also creates the skeleton DOM structure into
	 * the document.</p>
	 *
	 * @note The XSEC Library currently makes very little use of <em>type</em>
	 * attributes in \<Reference\> Elements.  However this may of use to calling
	 * applications.
	 *
	 * @see DSIGReference
	 * @param URI The Data that this Reference node refers to.
	 * @param hm The hashing (digest) method to be used for this reference
	 * @param type A "type" string (as defined in XML Signature).
	 * @returns The newly created DSIGReference element.
	 * @deprecated Use the URI based creation method instead
	 *
	 */

	DSIGReference * createReference(
		const XMLCh * URI,
		const XMLCh * hashAlgorithmURI, 
		const XMLCh * type = NULL
	);
	//@}

	/** @name General and Information functions. */
	//@{

	/**
	 * \brief Get the hash of the Signed Value
	 * 
	 * Function to calculate and return the hash of the \<SignedInfo\>
	 * structures (after the canonicalization defined by
	 * \<CanonicalizationMethod\> and the reference hashes have been performed).
	 *
	 * @param hashBuf Buffer to place the raw hash in.
	 * @param hashBufLen The length of the buffer
	 * @returns The length of the hash that was placed in hashBuf
	 *
	 */

	unsigned int calculateSignedInfoAndReferenceHash(unsigned char * hashBuf, 
													unsigned int hashBufLen);

	/**
	 * \brief Get the hash of the Signed Value
	 * 
	 * Function to calculate and return the hash of the \<SignedInfo\>
	 * structures (after the canonicalization defined by
	 * \<CanonicalizationMethod\> has been performed).
	 *
	 * @param hashBuf Buffer to place the raw hash in.
	 * @param hashBufLen The length of the buffer
	 * @returns The length of the hash that was placed in hashBuf
	 *
	 */

	unsigned int calculateSignedInfoHash(unsigned char * hashBuf, 
										unsigned int hashBufLen);

	/**
	 * \brief Return the reference list for outside use.
	 *
	 * Returns a pointer to the list of references which can
	 * then be read by the caller.
	 *
	 * @returns The referenceList
	 */

	DSIGReferenceList * getReferenceList(void);

	/**
	 * \brief Return the reference list for outside use.
	 *
	 * Returns a pointer to the list of references which can
	 * then be read by the caller.
	 *
	 * @returns The referenceList
	 */

	const DSIGReferenceList * getReferenceList(void) const;

	/**
	 * \brief Create an input stream from SignedInfo.
	 *
	 * This method allows applications to read the fully canonicalised
	 * byte stream that is hashed and signed.
	 *
	 * All transforms are performed up to the point where they would
	 * normally be fed into the Digest function.
	 *
	 * @returns A BinInputSource of the canonicalised SignedInfo
	 */


	XSECBinTXFMInputStream * makeBinInputStream(void) const;


	/**
	 * \brief Get the Error messages from the last #verify.
	 *
	 * Returns a list of text error messages from the last Signature
	 * operation.  Each error that occurred is in the buffer, separated
	 * by new-lines.
	 *
	 * @note The buffer is owned by the DSIGSignature object - do not delete it
	 *
	 * @returns A pointer to the buffer containing the error strings.
	 *
	 */

	const XMLCh * getErrMsgs(void) const;

	/**
	 * \brief Get the NS Prefix being used for DSIG elements.
	 *
	 * @returns A pointer to the buffer holding the prefix
	 * @see #setDSIGNSPrefix
	 *
	 */

	const XMLCh * getDSIGNSPrefix() const;

	/**
	 * \brief Get the NS being used for EC nodes
	 *
	 * @returns A pointer to the buffer holding the prefix
	 * @see #setECNSPrefix
	 */

	const XMLCh * getECNSPrefix() const;

	/**
	 * \brief Get the NS being used for XPath Filter2 nodes
	 *
	 * @returns A pointer to the buffer holding the prefix
	 * @see #setXPFNSPrefix
	 */

	const XMLCh * getXPFNSPrefix() const;

	/**
	 * \brief
	 *
	 * Get the DOM_Document that this Signature is operating within.
	 *
	 * Mainly used by the library itself.
	 *
	 * @returns The DOM_Document node.
	 */

	XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getParentDocument() const
		{return mp_doc;}

	/**
	 * \brief Get canonicalisation algorithm
	 *
	 * Returns the canonicalisation algorithm that will be/is used
	 * to canonicalise the \<SignedInfo\> element prior to hash/sign
	 *
	 * @returns The canonicalisation method
	 */

	canonicalizationMethod getCanonicalizationMethod(void) const
	{return (mp_signedInfo != NULL ? 
			 mp_signedInfo->getCanonicalizationMethod() : CANON_NONE);}


	/**
	 * \brief Get the hash method
	 *
	 * Obtain the hash (digest) algorithm that is used to generate a hash
	 * of the canonicalised \<SignedInfo\> element.
	 *
	 * @returns the Hash (digest) Method
	 */

	hashMethod getHashMethod(void) const
	{return (mp_signedInfo != NULL ? 
			 mp_signedInfo->getHashMethod() : HASH_NONE);}

	/**
	 * \brief Get the signature method
	 *
	 * Obtain the algorithm that will be used to generate/check the signature
	 * of the canonicalised and hashed \<SignedInfo\> element.
	 *
	 * @returns the Signature method
	 */

	signatureMethod getSignatureMethod(void) const
	{return (mp_signedInfo != NULL ? 
			 mp_signedInfo->getSignatureMethod() : SIGNATURE_NONE);}

	/**
	 * \brief Get the Signature Value
	 *
	 * Returns the base64 string holding the signature value for this signature
	 * 
	 * @returns the signature value string
	 */

	const XMLCh * getSignatureValue(void) const;
		 
	/**
	 * \brief Helper function for sub Classes.
	 *
	 * Returns the pointer to the formatter being used within the Signature
	 *
	 */

	XSECSafeBufferFormatter * getSBFormatter(void) {return mp_formatter;}

	/**
	 * \brief Set the interlocking references flag
	 *
	 * This flag controls whether the library will cater for "interlocking"
	 * Reference nodes - where the hash of one reference depends on the
	 * hash of another.
	 *
	 * As of Version 1.3, this is, by default, set to false, as it is 
	 * fairly unusual to find a Reference node that has as an input the
	 * digest value of another reference node.  By setting this value to
	 * true, the library will first calculate all hash values, and then
	 * verify the hash values.  If any are incorrect (caused by one 
	 * the value of one reference being changed *after* it was used as 
	 * the input to another), then the hash values are recalculated.  This
	 * is repeated until the reference list "settles".
	 *
	 * @param flag true for interlocking references, false for standalone
	 */

	void setInterlockingReferences(bool flag) {m_interlockingReferences = flag;}


	/**
	 * \brief Get the interlocking references flag
	 *
	 * This flag controls whether the library will cater for "interlocking"
	 * Reference nodes - where the hash of one reference depends on the
	 * hash of another.
	 *
	 * As of Version 1.3, this is, by default, set to false, as it is 
	 * fairly unusual to find a Reference node that has as an input the
	 * digest value of another reference node.  By setting this value to
	 * true, the library will first calculate all hash values, and then
	 * verify the hash values.  If any are incorrect (caused by one 
	 * the value of one reference being changed *after* it was used as 
	 * the input to another), then the hash values are recalculated.  This
	 * is repeated until the reference list "settles".
	 *
	 * @return Value of flag - true for interlocking references, false for standalone
	 */

	bool getInterlockingReferences(void) const {return m_interlockingReferences;}

	//@}

	/** @name Resolver manipulation */
	//@{

	/**
	 * \brief Register a URIResolver 
	 *
	 * Registers a URIResolver to be used by the Signature when dereferencing
	 * a URI in a Reference element
	 *
	 */

	void setURIResolver(XSECURIResolver * resolver);

	/**
	 * \brief Return a pointer to the resolver being used
	 *
	 * @returns A pointer to the URIResolver registered in this signature
	 */

	XSECURIResolver * getURIResolver(void) const;

	/**
	 * \brief Register a KeyInfoResolver 
	 *
	 * Registers a KeyInfoResolver to be used by the Signature when 
	 * it needs to find a key to be used to validate a signature
	 *
	 */

	void setKeyInfoResolver(XSECKeyInfoResolver * resolver);

	/**
	 * \brief Return a pointer to the resolver being used
	 *
	 * @returns A pointer to the KeyInfoResolver registered in this signature
	 */

	XSECKeyInfoResolver * getKeyInfoResolver(void) const;

	//@}

	/** @name KeyInfo Element Manipulation */
	
	//@{

	/**
	 * \brief Get the list of \<KeyInfo\> elements.
	 *
	 * <p>This function recovers list that contains the KeyInfo elements
	 * read in from the DOM document.</p>
	 *
	 * <p>This list should be used by calling applications to determine what key
	 * is appropriate for validating (or even signing) the Signature.</p>
	 *
	 * @todo The KeyInfo process is very primitive.  An interface needs to be
	 * created to allow application developers to install an object into the Signature
	 * that the Signature can call on to translate KeyInfo lists into a Key.
	 * @returns A pointer to the DSIGKeyInfoList object held by the DSIGSignature
	 */
	
	DSIGKeyInfoList * getKeyInfoList() {return &m_keyInfoList;}

	/**
	 * \brief Get the list of \<KeyInfo\> elements.
	 *
	 * <p>This function recovers list that contains the KeyInfo elements
	 * read in from the DOM document.</p>
	 *
	 * <p>This list should be used by calling applications to determine what key
	 * is appropriate for validating (or even signing) the Signature.</p>
	 *
	 * @todo The KeyInfo process is very primitive.  An interface needs to be
	 * created to allow application developers to install an object into the Signature
	 * that the Signature can call on to translate KeyInfo lists into a Key.
	 * @returns A pointer to the DSIGKeyInfoList object held by the DSIGSignature
	 */
	
	const DSIGKeyInfoList * getKeyInfoList() const {return &m_keyInfoList;}

	/**
	 * \brief Clear out all KeyInfo elements in the signature.
	 *
	 * This function will delete all KeyInfo elements from both the DSIGSignature
	 * object <em>and the associated DOM</em>.
	 *
	 */

	void clearKeyInfo(void);

	/**
	 * \brief Append a DSA KeyValue element 
	 *
	 * Add a new KeyInfo element for a DSA Value
	 *
	 * @param P Base64 encoded value of P
	 * @param Q Base64 encoded value of Q
	 * @param G Base64 encoded value of G
	 * @param Y Base64 encoded value of Y
	 * @returns A pointer to the created object.
	 */

	DSIGKeyInfoValue * appendDSAKeyValue(const XMLCh * P, 
						   const XMLCh * Q, 
						   const XMLCh * G, 
						   const XMLCh * Y);

	/**
	 * \brief Append a RSA KeyValue element 
	 *
	 * Add a new KeyInfo element for a RSA Value
	 *
	 * @param modulus Base64 encoded value of the modulus
	 * @param exponent Base64 encoded value of exponent
	 * @returns A pointer to the created object.
	 */

	DSIGKeyInfoValue * appendRSAKeyValue(const XMLCh * modulus, 
						   const XMLCh * exponent);

	/**
	 * \brief Append a X509Data element.
	 *
	 * Add a new KeyInfo element for X509 data.
	 *
	 * @note The added element is empty.  The caller must make use of the
	 * returned object to set the required values.
	 *
	 * @returns A pointer to the created object.
	 */

	DSIGKeyInfoX509 * appendX509Data(void);

	/**
	 * \brief Append a KeyName element.
	 *
	 * Add a new KeyInfo element for a key name.
	 *
	 * @param name The name of the key to set in the XML
	 * @param isDName Treat the name as a Distinguished name and encode accordingly
	 * @returns A pointer to the created object
	 */

	DSIGKeyInfoName * appendKeyName(const XMLCh * name, bool isDName = false);

	/**
	 * \brief Append a PGPData element.
	 *
	 * Add a new KeyInfo element for a PGP key.
	 *
	 * @param id The ID of the key to set in the XML (base64 encoded - NULL if none)
	 * @param packet The Packet information to set in the XML (base64 encoded -
	 * NULL if none)
	 * @returns A pointer to the created object
	 */

	DSIGKeyInfoPGPData * appendPGPData(const XMLCh * id, const XMLCh * packet);

	/**
	 * \brief Append a SPKIData element
	 *
	 * Add a new KeyInfo element for a set of SPKI S-expressions
	 *
	 * @param sexp The initial S-expression to set in the SPKIData element
	 * @returns A pointer to the created object
	 */

	DSIGKeyInfoSPKIData * appendSPKIData(const XMLCh * sexp);

	/**
	 * \brief Append a MgmtData element
	 *
	 * Add a new KeyInfo element for Management Data
	 *
	 * @param data The string to set in the MgmtData element
	 * @returns A pointer to the created object
	 */

	DSIGKeyInfoMgmtData * appendMgmtData(const XMLCh * data);

	//@}

	/** @name Object handling */
	//@{

	/**
	 * \brief Append an object container
	 *
	 * Create a new Object (i.e. a Signature \<Object\> which is a container
	 * element used to hold information that needs to be signed within the
	 * signature - i.e. in enveloping mode
	 *
	 * @returns the newly created DSIGObject
	 */

	DSIGObject * appendObject(void);

	/**
	 * \brief Find the number of ds:Object nodes within the Signature
	 *
	 * @returns the number of ds:Object nodes held in the Signature, 0 if none
	 */

	int getObjectLength(void) const;

	/**
	 * \brief Get a particular ds:Object from within the Signature
	 *
	 * @returns the ith Object from the list of ds:Object nodes in the signature.
	 * Items are ordered in tree order.
	 */

	DSIGObject * getObjectItem(int i);

	/**
	 * \brief Get a particular ds:Object from within the Signature
	 *
	 * @returns the ith Object from the list of ds:Object nodes in the signature.
	 * Items are ordered in tree order.
	 */

	const DSIGObject * getObjectItem(int i) const;

	//@}

	/** @name ID handling */
	
	//@{

	/**
	 * \brief Set Id finding behaviour
	 *
	 * The library de-references "#obj" URI references to ID attributes within
	 * a DOM document.  Currently, the library first uses DOM calls to find if
	 * the Id has been properly set within the document via the parser or one
	 * of the DOM Level 3 calls to set an Id.
	 *
	 * If no Id is found of the correct name, the library then starts searching
	 * for attributes of a given name with the required value.  This list defaults
	 * to "id" and "Id", but can be modified via a call to addIdAttributeName()
	 *
	 * The setIdByAttributeName call enables or disables the second part of the Id
	 * search.  I.e. when the Id doesn't exist as an attribute of Type=ID, whether or
	 * not to search for an attribute of a name in the list of names.  By default
	 * this behaviour is enabled.
	 *
	 * @warning This is currently enabled by default for backwards compatibility
	 * reasons only.  Future version may reverse this and ship disabled by default, as
	 * this behaviour is a potential security risk.
	 *
	 * @param flag Enable (true) or Disable (false) searching for Id attributes by name
	 */

	void setIdByAttributeName(bool flag);

	/**
	 * \brief Determine Id finding behaviour
	 *
	 * Allows a caller to determine whether the library is currently searching for
	 * Id attributes by name
	 *
	 * @returns The value of the IdByAttributeName flag
	 */

	bool getIdByAttributeName(void) const;

	/**
	 * \brief Add an attribute name to be searched for when looking for Id attributes
	 *
	 * This allows a user to add an attribute name to be used to identify Id attributes
	 * when they are not set to be of Type=ID in the DOM
	 *
	 * @note Two names are registered by default - "Id" and "id".  These can be
	 * removed by calling deregisterIdAttributeName
	 *
	 * @param name Name to append to the list of those used to find Id attributes
	 */

	void registerIdAttributeName(const XMLCh * name);

	/**
	 * \brief Remove an attribute name to be searched for when looking for Id attributes
	 *
	 * This allows a user to de-register a particular name to be used to identify Id
	 * attributes.
	 *
	 * @param name Name to remove from the list of those used to find Id attributes
	 * @returns true if found and removed, false if was not in the list
	 */

	bool deregisterIdAttributeName(const XMLCh * name);

	/**
	 * \brief Add an attribute name within a particular Namespace
	 * to be searched for when looking for Id attributes
	 *
	 * This allows a user to add an attribute name to be used to identify Id attributes
	 * when they are not set to be of Type=ID in the DOM
	 *
	 * @note Two names are registered by default - "Id" and "id".  These can be
	 * removed by calling deregisterIdAttributeName
	 *
	 * @param ns Namespace in which attribute will reside
	 * @param name Name to append to the list of those used to find Id attributes
	 */

	void registerIdAttributeNameNS(const XMLCh * ns, const XMLCh * name);

	/**
	 * \brief Remove an attribute name and ns to be searched for when looking for Id attributes
	 *
	 * This allows a user to de-register a particular name to be used to identify Id
	 * attributes.
	 *
	 * @param ns Namespace in which attribute will reside
	 * @param name Name to remove from the list of those used to find Id attributes
	 * @returns true if found and removed, false if was not in the list
	 */

	bool deregisterIdAttributeNameNS(const XMLCh * ns, const XMLCh * name);

	//@}

	friend class XSECProvider;

private:

	// For holding DSIGObject nodes
#if defined(XSEC_NO_NAMESPACES)
	typedef vector<DSIGObject *>			ObjectVectorType;
#else
	typedef std::vector<DSIGObject *>		ObjectVectorType;
#endif


	// Internal functions
	void createKeyInfoElement(void);
	bool verifySignatureOnlyInternal(void);
	TXFMChain * getSignedInfoInput(void);

	// Initialisation
	static void Initialise(void);

	XSECSafeBufferFormatter		* mp_formatter;
	bool						m_loaded;				// Have we already loaded?
	XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument					
								* mp_doc;
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode						
								* mp_sigNode;
	DSIGSignedInfo				* mp_signedInfo;
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode						
								* mp_signatureValueNode;
	safeBuffer					m_signatureValueSB;
	DSIGKeyInfoList				m_keyInfoList;
	XERCES_CPP_NAMESPACE_QUALIFIER DOMNode						
								* mp_KeyInfoNode;
	safeBuffer			        m_errStr;

	// Environment
	XSECEnv						* mp_env;
	
	// The signing/verifying key
	mutable XSECCryptoKey		* mp_signingKey;

	// Resolvers
	XSECKeyInfoResolver			* mp_KeyInfoResolver;

	// Objects

	ObjectVectorType			m_objects;

	// Interlocking references
	bool						m_interlockingReferences;

	// Not implemented constructors

	DSIGSignature();
	
	friend class XSECPlatformUtils;

	/*\@}*/
};

#endif /* DSIGSIGNATURE_INCLUDE */