2 // SignedXml.cs - SignedXml implementation for XML Signature
5 // Sebastien Pouliot <sebastien@ximian.com>
6 // Atsushi Enomoto <atsushi@ximian.com>
7 // Tim Coleman <tim@timcoleman.com>
9 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
10 // Copyright (C) Tim Coleman, 2004
11 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
35 using System
.Runtime
.InteropServices
;
36 using System
.Security
.Cryptography
;
37 using System
.Security
.Policy
;
43 using System
.Security
.Cryptography
.X509Certificates
;
46 namespace System
.Security
.Cryptography
.Xml
{
48 public class SignedXml
{
50 public const string XmlDsigCanonicalizationUrl
= "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
51 public const string XmlDsigCanonicalizationWithCommentsUrl
= XmlDsigCanonicalizationUrl
+ "#WithComments";
52 public const string XmlDsigDSAUrl
= XmlDsigNamespaceUrl
+ "dsa-sha1";
53 public const string XmlDsigHMACSHA1Url
= XmlDsigNamespaceUrl
+ "hmac-sha1";
54 public const string XmlDsigMinimalCanonicalizationUrl
= XmlDsigNamespaceUrl
+ "minimal";
55 public const string XmlDsigNamespaceUrl
= "http://www.w3.org/2000/09/xmldsig#";
56 public const string XmlDsigRSASHA1Url
= XmlDsigNamespaceUrl
+ "rsa-sha1";
57 public const string XmlDsigSHA1Url
= XmlDsigNamespaceUrl
+ "sha1";
60 public const string XmlDecryptionTransformUrl
= "http://www.w3.org/2002/07/decrypt#XML";
61 public const string XmlDsigBase64TransformUrl
= XmlDsigNamespaceUrl
+ "base64";
62 public const string XmlDsigC14NTransformUrl
= XmlDsigCanonicalizationUrl
;
63 public const string XmlDsigC14NWithCommentsTransformUrl
= XmlDsigCanonicalizationWithCommentsUrl
;
64 public const string XmlDsigEnvelopedSignatureTransformUrl
= XmlDsigNamespaceUrl
+ "enveloped-signature";
65 public const string XmlDsigExcC14NTransformUrl
= "http://www.w3.org/2001/10/xml-exc-c14n#";
66 public const string XmlDsigExcC14NWithCommentsTransformUrl
= XmlDsigExcC14NTransformUrl
+ "WithComments";
67 public const string XmlDsigXPathTransformUrl
= "http://www.w3.org/TR/1999/REC-xpath-19991116";
68 public const string XmlDsigXsltTransformUrl
= "http://www.w3.org/TR/1999/REC-xslt-19991116";
69 public const string XmlLicenseTransformUrl
= "urn:mpeg:mpeg21:2003:01-REL-R-NS:licenseTransform";
71 private EncryptedXml encryptedXml
;
74 protected Signature m_signature
;
75 private AsymmetricAlgorithm key
;
76 protected string m_strSigningKeyName
;
77 private XmlDocument envdoc
;
78 private IEnumerator pkEnumerator
;
79 private XmlElement signatureElement
;
80 private Hashtable hashes
;
81 // FIXME: enable it after CAS implementation
83 private XmlResolver xmlResolver
= new XmlSecureResolver (new XmlUrlResolver (), new Evidence ());
85 private XmlResolver xmlResolver
= new XmlUrlResolver ();
87 private ArrayList manifests
;
89 private IEnumerator _x509Enumerator
;
92 private static readonly char [] whitespaceChars
= new char [] {' ', '\r', '\n', '\t'}
;
96 m_signature
= new Signature ();
97 m_signature
.SignedInfo
= new SignedInfo ();
98 hashes
= new Hashtable (2); // 98% SHA1 for now
101 public SignedXml (XmlDocument document
) : this ()
103 if (document
== null)
104 throw new ArgumentNullException ("document");
108 public SignedXml (XmlElement elem
) : this ()
111 throw new ArgumentNullException ("elem");
112 envdoc
= new XmlDocument ();
113 envdoc
.LoadXml (elem
.OuterXml
);
118 public EncryptedXml EncryptedXml
{
119 get { return encryptedXml; }
120 set { encryptedXml = value; }
124 public KeyInfo KeyInfo
{
127 if (m_signature
.KeyInfo
== null)
128 m_signature
.KeyInfo
= new KeyInfo ();
130 return m_signature
.KeyInfo
;
132 set { m_signature.KeyInfo = value; }
135 public Signature Signature
{
136 get { return m_signature; }
139 public string SignatureLength
{
140 get { return m_signature.SignedInfo.SignatureLength; }
143 public string SignatureMethod
{
144 get { return m_signature.SignedInfo.SignatureMethod; }
147 public byte[] SignatureValue
{
148 get { return m_signature.SignatureValue; }
151 public SignedInfo SignedInfo
{
152 get { return m_signature.SignedInfo; }
155 public AsymmetricAlgorithm SigningKey
{
160 // NOTE: CryptoAPI related ? documented as fx internal
161 public string SigningKeyName
{
162 get { return m_strSigningKeyName; }
163 set { m_strSigningKeyName = value; }
166 public void AddObject (DataObject dataObject
)
168 m_signature
.AddObject (dataObject
);
171 public void AddReference (Reference reference
)
174 if (reference
== null)
175 throw new ArgumentNullException ("reference");
177 m_signature
.SignedInfo
.AddReference (reference
);
180 private Stream
ApplyTransform (Transform t
, XmlDocument input
)
182 // These transformer modify input document, which should
183 // not affect to the input itself.
184 if (t
is XmlDsigXPathTransform
185 || t
is XmlDsigEnvelopedSignatureTransform
187 || t
is XmlDecryptionTransform
190 input
= (XmlDocument
) input
.Clone ();
194 if (t
is XmlDsigEnvelopedSignatureTransform
)
195 // It returns XmlDocument for XmlDocument input.
196 return CanonicalizeOutput (t
.GetOutput ());
198 object obj
= t
.GetOutput ();
201 else if (obj
is XmlDocument
) {
202 MemoryStream ms
= new MemoryStream ();
203 XmlTextWriter xtw
= new XmlTextWriter (ms
, Encoding
.UTF8
);
204 ((XmlDocument
) obj
).WriteTo (xtw
);
208 // Rewind to the start of the stream
212 else if (obj
== null) {
213 throw new NotImplementedException ("This should not occur. Transform is " + t
+ ".");
216 // e.g. XmlDsigXPathTransform returns XmlNodeList
217 return CanonicalizeOutput (obj
);
221 private Stream
CanonicalizeOutput (object obj
)
223 Transform c14n
= GetC14NMethod ();
224 c14n
.LoadInput (obj
);
225 return (Stream
) c14n
.GetOutput ();
228 private XmlDocument
GetManifest (Reference r
)
230 XmlDocument doc
= new XmlDocument ();
231 doc
.PreserveWhitespace
= true;
233 if (r
.Uri
[0] == '#') {
235 if (signatureElement
!= null) {
236 XmlElement xel
= GetIdElement (signatureElement
.OwnerDocument
, r
.Uri
.Substring (1));
238 throw new CryptographicException ("Manifest targeted by Reference was not found: " + r
.Uri
.Substring (1));
239 doc
.LoadXml (xel
.OuterXml
);
240 FixupNamespaceNodes (xel
, doc
.DocumentElement
, false);
243 else if (xmlResolver
!= null) {
244 // TODO: need testing
245 Stream s
= (Stream
) xmlResolver
.GetEntity (new Uri (r
.Uri
), null, typeof (Stream
));
249 if (doc
.FirstChild
!= null) {
250 // keep a copy of the manifests to check their references later
251 if (manifests
== null)
252 manifests
= new ArrayList ();
260 private void FixupNamespaceNodes (XmlElement src
, XmlElement dst
, bool ignoreDefault
)
262 // add namespace nodes
263 foreach (XmlAttribute attr
in src
.SelectNodes ("namespace::*")) {
264 if (attr
.LocalName
== "xml")
266 if (ignoreDefault
&& attr
.LocalName
== "xmlns")
268 dst
.SetAttributeNode (dst
.OwnerDocument
.ImportNode (attr
, true) as XmlAttribute
);
272 private byte[] GetReferenceHash (Reference r
, bool check_hmac
)
275 XmlDocument doc
= null;
276 if (r
.Uri
== String
.Empty
) {
279 else if (r
.Type
== XmlSignature
.Uri
.Manifest
) {
280 doc
= GetManifest (r
);
283 doc
= new XmlDocument ();
284 doc
.PreserveWhitespace
= true;
285 string objectName
= null;
287 if (r
.Uri
.StartsWith ("#xpointer")) {
288 string uri
= string.Join ("", r
.Uri
.Substring (9).Split (whitespaceChars
));
289 if (uri
.Length
< 2 || uri
[0] != '(' || uri
[uri
.Length
- 1] != ')')
290 // FIXME: how to handle invalid xpointer?
293 uri
= uri
.Substring (1, uri
.Length
- 2);
296 else if (uri
.Length
> 6 && uri
.StartsWith ("id(") && uri
[uri
.Length
- 1] == ')')
297 // id('foo'), id("foo")
298 objectName
= uri
.Substring (4, uri
.Length
- 6);
300 else if (r
.Uri
[0] == '#') {
301 objectName
= r
.Uri
.Substring (1);
303 else if (xmlResolver
!= null) {
304 // TODO: test but doc says that Resolver = null -> no access
306 // no way to know if valid without throwing an exception
307 Uri uri
= new Uri (r
.Uri
);
308 s
= (Stream
) xmlResolver
.GetEntity (uri
, null, typeof (Stream
));
311 // may still be a local file (and maybe not xml)
312 s
= File
.OpenRead (r
.Uri
);
315 if (objectName
!= null) {
316 XmlElement found
= null;
317 foreach (DataObject obj
in m_signature
.ObjectList
) {
318 if (obj
.Id
== objectName
) {
319 found
= obj
.GetXml ();
320 found
.SetAttribute ("xmlns", SignedXml
.XmlDsigNamespaceUrl
);
321 doc
.LoadXml (found
.OuterXml
);
322 // FIXME: there should be theoretical justification of copying namespace declaration nodes this way.
323 foreach (XmlNode n
in found
.ChildNodes
)
324 // Do not copy default namespace as it must be xmldsig namespace for "Object" element.
325 if (n
.NodeType
== XmlNodeType
.Element
)
326 FixupNamespaceNodes (n
as XmlElement
, doc
.DocumentElement
, true);
330 if (found
== null && envdoc
!= null) {
331 found
= GetIdElement (envdoc
, objectName
);
333 doc
.LoadXml (found
.OuterXml
);
336 throw new CryptographicException (String
.Format ("Malformed reference object: {0}", objectName
));
340 if (r
.TransformChain
.Count
> 0) {
341 foreach (Transform t
in r
.TransformChain
) {
343 s
= ApplyTransform (t
, doc
);
347 object o
= t
.GetOutput ();
351 s
= CanonicalizeOutput (o
);
355 else if (s
== null) {
356 // we must not C14N references from outside the document
357 // e.g. non-xml documents
358 if (r
.Uri
[0] != '#') {
359 s
= new MemoryStream ();
363 // apply default C14N transformation
364 s
= ApplyTransform (new XmlDsigC14NTransform (), doc
);
367 HashAlgorithm digest
= GetHash (r
.DigestMethod
, check_hmac
);
368 return (digest
== null) ? null : digest
.ComputeHash (s
);
371 private void DigestReferences ()
373 // we must tell each reference which hash algorithm to use
374 // before asking for the SignedInfo XML !
375 foreach (Reference r
in m_signature
.SignedInfo
.References
) {
376 // assume SHA-1 if nothing is specified
377 if (r
.DigestMethod
== null)
378 r
.DigestMethod
= XmlDsigSHA1Url
;
379 r
.DigestValue
= GetReferenceHash (r
, false);
383 private Transform
GetC14NMethod ()
385 Transform t
= (Transform
) CryptoConfig
.CreateFromName (m_signature
.SignedInfo
.CanonicalizationMethod
);
387 throw new CryptographicException ("Unknown Canonicalization Method {0}", m_signature
.SignedInfo
.CanonicalizationMethod
);
391 private Stream
SignedInfoTransformed ()
393 Transform t
= GetC14NMethod ();
395 if (signatureElement
== null) {
396 // when creating signatures
397 XmlDocument doc
= new XmlDocument ();
398 doc
.PreserveWhitespace
= true;
399 doc
.LoadXml (m_signature
.SignedInfo
.GetXml ().OuterXml
);
401 foreach (XmlAttribute attr
in envdoc
.DocumentElement
.SelectNodes ("namespace::*")) {
402 if (attr
.LocalName
== "xml")
404 if (attr
.Prefix
== doc
.DocumentElement
.Prefix
)
406 doc
.DocumentElement
.SetAttributeNode (doc
.ImportNode (attr
, true) as XmlAttribute
);
411 // when verifying signatures
412 // TODO - check m_signature.SignedInfo.Id
413 XmlElement el
= signatureElement
.GetElementsByTagName (XmlSignature
.ElementNames
.SignedInfo
, XmlSignature
.NamespaceURI
) [0] as XmlElement
;
414 StringWriter sw
= new StringWriter ();
415 XmlTextWriter xtw
= new XmlTextWriter (sw
);
416 xtw
.WriteStartElement (el
.Prefix
, el
.LocalName
, el
.NamespaceURI
);
418 // context namespace nodes (except for "xmlns:xml")
419 XmlNodeList nl
= el
.SelectNodes ("namespace::*");
420 foreach (XmlAttribute attr
in nl
) {
421 if (attr
.ParentNode
== el
)
423 if (attr
.LocalName
== "xml")
425 if (attr
.Prefix
== el
.Prefix
)
429 foreach (XmlNode attr
in el
.Attributes
)
431 foreach (XmlNode n
in el
.ChildNodes
)
434 xtw
.WriteEndElement ();
435 byte [] si
= Encoding
.UTF8
.GetBytes (sw
.ToString ());
437 MemoryStream ms
= new MemoryStream ();
438 ms
.Write (si
, 0, si
.Length
);
443 // C14N and C14NWithComments always return a Stream in GetOutput
444 return (Stream
) t
.GetOutput ();
447 // reuse hash - most document will always use the same hash
448 private HashAlgorithm
GetHash (string algorithm
, bool check_hmac
)
450 HashAlgorithm hash
= (HashAlgorithm
) hashes
[algorithm
];
452 hash
= HashAlgorithm
.Create (algorithm
);
454 throw new CryptographicException ("Unknown hash algorithm: {0}", algorithm
);
455 hashes
.Add (algorithm
, hash
);
456 // now ready to be used
459 // important before reusing an hash object
462 // we can sign using any hash algorith, including HMAC, but we can only verify hash (MS compatibility)
463 if (check_hmac
&& (hash
is KeyedHashAlgorithm
))
468 public bool CheckSignature ()
470 return (CheckSignatureInternal (null) != null);
473 private bool CheckReferenceIntegrity (ArrayList referenceList
)
475 if (referenceList
== null)
478 // check digest (hash) for every reference
479 foreach (Reference r
in referenceList
) {
480 // stop at first broken reference
481 byte[] hash
= GetReferenceHash (r
, true);
482 if (! Compare (r
.DigestValue
, hash
))
488 public bool CheckSignature (AsymmetricAlgorithm key
)
491 throw new ArgumentNullException ("key");
492 return (CheckSignatureInternal (key
) != null);
495 private AsymmetricAlgorithm
CheckSignatureInternal (AsymmetricAlgorithm key
)
500 // check with supplied key
501 if (!CheckSignatureWithKey (key
))
505 if (Signature
.KeyInfo
== null)
508 if (Signature
.KeyInfo
== null)
509 throw new CryptographicException ("At least one KeyInfo is required.");
511 // no supplied key, iterates all KeyInfo
512 while ((key
= GetPublicKey ()) != null) {
513 if (CheckSignatureWithKey (key
)) {
522 // some parts may need to be downloaded
523 // so where doing it last
524 if (!CheckReferenceIntegrity (m_signature
.SignedInfo
.References
))
527 if (manifests
!= null) {
528 // do not use foreach as a manifest could contain manifests...
529 for (int i
=0; i
< manifests
.Count
; i
++) {
530 Manifest manifest
= new Manifest ((manifests
[i
] as XmlDocument
).DocumentElement
);
531 if (! CheckReferenceIntegrity (manifest
.References
))
538 // Is the signature (over SignedInfo) valid ?
539 private bool CheckSignatureWithKey (AsymmetricAlgorithm key
)
544 SignatureDescription sd
= (SignatureDescription
) CryptoConfig
.CreateFromName (m_signature
.SignedInfo
.SignatureMethod
);
548 AsymmetricSignatureDeformatter verifier
= (AsymmetricSignatureDeformatter
) CryptoConfig
.CreateFromName (sd
.DeformatterAlgorithm
);
549 if (verifier
== null)
553 verifier
.SetKey (key
);
554 verifier
.SetHashAlgorithm (sd
.DigestAlgorithm
);
556 HashAlgorithm hash
= GetHash (sd
.DigestAlgorithm
, true);
557 // get the hash of the C14N SignedInfo element
558 MemoryStream ms
= (MemoryStream
) SignedInfoTransformed ();
560 byte[] digest
= hash
.ComputeHash (ms
);
561 return verifier
.VerifySignature (digest
, m_signature
.SignatureValue
);
564 // e.g. SignatureMethod != AsymmetricAlgorithm type
569 private bool Compare (byte[] expected
, byte[] actual
)
571 bool result
= ((expected
!= null) && (actual
!= null));
573 int l
= expected
.Length
;
574 result
= (l
== actual
.Length
);
576 for (int i
=0; i
< l
; i
++) {
577 if (expected
[i
] != actual
[i
])
585 public bool CheckSignature (KeyedHashAlgorithm macAlg
)
588 throw new ArgumentNullException ("macAlg");
592 // Is the signature (over SignedInfo) valid ?
593 Stream s
= SignedInfoTransformed ();
597 byte[] actual
= macAlg
.ComputeHash (s
);
598 // HMAC signature may be partial and specified by <HMACOutputLength>
599 if (m_signature
.SignedInfo
.SignatureLength
!= null) {
600 int length
= Int32
.Parse (m_signature
.SignedInfo
.SignatureLength
);
601 // we only support signatures with a multiple of 8 bits
602 // and the value must match the signature length
603 if ((length
& 7) != 0)
604 throw new CryptographicException ("Signature length must be a multiple of 8 bits.");
606 // SignatureLength is in bits (and we works on bytes, only in multiple of 8 bits)
607 // and both values must match for a signature to be valid
609 if (length
!= m_signature
.SignatureValue
.Length
)
610 throw new CryptographicException ("Invalid signature length.");
612 // is the length "big" enough to make the signature meaningful ?
613 // we use a minimum of 80 bits (10 bytes) or half the HMAC normal output length
614 // e.g. HMACMD5 output 128 bits but our minimum is 80 bits (not 64 bits)
615 int minimum
= Math
.Max (10, actual
.Length
/ 2);
616 if (length
< minimum
)
617 throw new CryptographicException ("HMAC signature is too small");
619 if (length
< actual
.Length
) {
620 byte[] trunked
= new byte [length
];
621 Buffer
.BlockCopy (actual
, 0, trunked
, 0, length
);
626 if (Compare (m_signature
.SignatureValue
, actual
)) {
627 // some parts may need to be downloaded
628 // so where doing it last
629 return CheckReferenceIntegrity (m_signature
.SignedInfo
.References
);
637 public bool CheckSignature (X509Certificate2 certificate
, bool verifySignatureOnly
)
639 throw new NotImplementedException ();
643 public bool CheckSignatureReturningKey (out AsymmetricAlgorithm signingKey
)
645 signingKey
= CheckSignatureInternal (null);
646 return (signingKey
!= null);
649 public void ComputeSignature ()
652 if (m_signature
.SignedInfo
.SignatureMethod
== null)
653 // required before hashing
654 m_signature
.SignedInfo
.SignatureMethod
= key
.SignatureAlgorithm
;
655 else if (m_signature
.SignedInfo
.SignatureMethod
!= key
.SignatureAlgorithm
)
656 throw new CryptographicException ("Specified SignatureAlgorithm is not supported by the signing key.");
659 AsymmetricSignatureFormatter signer
= null;
660 // in need for a CryptoConfig factory
662 signer
= new DSASignatureFormatter (key
);
664 signer
= new RSAPKCS1SignatureFormatter (key
);
666 if (signer
!= null) {
667 SignatureDescription sd
= (SignatureDescription
) CryptoConfig
.CreateFromName (m_signature
.SignedInfo
.SignatureMethod
);
669 HashAlgorithm hash
= GetHash (sd
.DigestAlgorithm
, false);
670 // get the hash of the C14N SignedInfo element
671 byte[] digest
= hash
.ComputeHash (SignedInfoTransformed ());
673 signer
.SetHashAlgorithm ("SHA1");
674 m_signature
.SignatureValue
= signer
.CreateSignature (digest
);
678 throw new CryptographicException ("signing key is not specified");
681 public void ComputeSignature (KeyedHashAlgorithm macAlg
)
684 throw new ArgumentNullException ("macAlg");
686 string method
= null;
688 if (macAlg
is HMACSHA1
) {
689 method
= XmlDsigHMACSHA1Url
;
691 } else if (macAlg
is HMACSHA256
) {
692 method
= "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
693 } else if (macAlg
is HMACSHA384
) {
694 method
= "http://www.w3.org/2001/04/xmldsig-more#hmac-sha384";
695 } else if (macAlg
is HMACSHA512
) {
696 method
= "http://www.w3.org/2001/04/xmldsig-more#hmac-sha512";
697 } else if (macAlg
is HMACRIPEMD160
) {
698 method
= "http://www.w3.org/2001/04/xmldsig-more#hmac-ripemd160";
703 throw new CryptographicException ("unsupported algorithm");
706 m_signature
.SignedInfo
.SignatureMethod
= method
;
707 m_signature
.SignatureValue
= macAlg
.ComputeHash (SignedInfoTransformed ());
710 public virtual XmlElement
GetIdElement (XmlDocument document
, string idValue
)
712 if ((document
== null) || (idValue
== null))
715 // this works only if there's a DTD or XSD available to define the ID
716 XmlElement xel
= document
.GetElementById (idValue
);
718 // search an "undefined" ID
719 xel
= (XmlElement
) document
.SelectSingleNode ("//*[@Id='" + idValue
+ "']");
724 // According to book ".NET Framework Security" this method
725 // iterates all possible keys then return null
726 protected virtual AsymmetricAlgorithm
GetPublicKey ()
728 if (m_signature
.KeyInfo
== null)
731 if (pkEnumerator
== null) {
732 pkEnumerator
= m_signature
.KeyInfo
.GetEnumerator ();
735 #if NET_2_0 && SECURITY_DEP
736 if (_x509Enumerator
!= null) {
737 if (_x509Enumerator
.MoveNext ()) {
738 X509Certificate cert
= (X509Certificate
) _x509Enumerator
.Current
;
739 return new X509Certificate2 (cert
.GetRawCertData ()).PublicKey
.Key
;
741 _x509Enumerator
= null;
745 while (pkEnumerator
.MoveNext ()) {
746 AsymmetricAlgorithm key
= null;
747 KeyInfoClause kic
= (KeyInfoClause
) pkEnumerator
.Current
;
749 if (kic
is DSAKeyValue
)
751 else if (kic
is RSAKeyValue
)
755 key
.FromXmlString (kic
.GetXml ().InnerXml
);
759 #if NET_2_0 && SECURITY_DEP
760 if (kic
is KeyInfoX509Data
) {
761 _x509Enumerator
= ((KeyInfoX509Data
) kic
).Certificates
.GetEnumerator ();
762 if (_x509Enumerator
.MoveNext ()) {
763 X509Certificate cert
= (X509Certificate
) _x509Enumerator
.Current
;
764 return new X509Certificate2 (cert
.GetRawCertData ()).PublicKey
.Key
;
772 public XmlElement
GetXml ()
774 return m_signature
.GetXml (envdoc
);
777 public void LoadXml (XmlElement
value)
780 throw new ArgumentNullException ("value");
782 signatureElement
= value;
783 m_signature
.LoadXml (value);
785 // Need to give the EncryptedXml object to the
786 // XmlDecryptionTransform to give it a fighting
787 // chance at decrypting the document.
788 foreach (Reference r
in m_signature
.SignedInfo
.References
) {
789 foreach (Transform t
in r
.TransformChain
) {
790 if (t
is XmlDecryptionTransform
)
791 ((XmlDecryptionTransform
) t
).EncryptedXml
= EncryptedXml
;
799 public XmlResolver Resolver
{
800 set { xmlResolver = value; }