2 // MessageSecurityGenerator.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.Globalization;
33 using System.IdentityModel.Selectors;
34 using System.IdentityModel.Tokens;
35 using System.Runtime.Serialization;
36 using System.Security.Cryptography;
37 using System.Security.Cryptography.X509Certificates;
38 using System.Security.Cryptography.Xml;
39 using System.ServiceModel;
40 using System.ServiceModel.Channels;
41 using System.ServiceModel.Description;
42 using System.ServiceModel.Security;
43 using System.ServiceModel.Security.Tokens;
46 using System.Xml.XPath;
48 using ReqType = System.ServiceModel.Security.Tokens.ServiceModelSecurityTokenRequirement;
50 namespace System.ServiceModel.Channels
52 internal class InitiatorMessageSecurityGenerator : MessageSecurityGenerator
54 EndpointAddress message_to;
55 InitiatorMessageSecurityBindingSupport security;
57 public InitiatorMessageSecurityGenerator (
59 InitiatorMessageSecurityBindingSupport security,
60 EndpointAddress messageTo)
61 : base (msg, security)
63 // FIXME: I believe it should be done at channel
64 // creation phase, but WinFX does not.
65 // if (!security.InitiatorParameters.InternalHasAsymmetricKey)
66 // throw new InvalidOperationException ("Wrong security token parameters: it must have an asymmetric key (HasAsymmetricKey). There is likely a misconfiguration in the custom security binding element.");
68 this.security = security;
69 this.message_to = messageTo;
72 public override SecurityRequestContext RequestContext {
76 public override UniqueId RelatesTo {
80 public override SecurityTokenParameters Parameters {
81 get { return security.InitiatorParameters; }
84 public override SecurityTokenParameters CounterParameters {
85 get { return security.RecipientParameters; }
88 public override MessageDirection Direction {
89 get { return MessageDirection.Input; }
92 public override EndpointAddress MessageTo {
93 get { return message_to; }
96 public override bool ShouldIncludeToken (SecurityTokenInclusionMode mode, bool isInitialized)
99 case SecurityTokenInclusionMode.Never:
100 case SecurityTokenInclusionMode.AlwaysToInitiator:
102 case SecurityTokenInclusionMode.AlwaysToRecipient:
104 case SecurityTokenInclusionMode.Once:
105 return !isInitialized;
107 throw new Exception ("Internal Error: should not happen.");
110 public override ScopedMessagePartSpecification SignatureParts {
111 get { return Security.ChannelRequirements.IncomingSignatureParts; }
114 public override ScopedMessagePartSpecification EncryptionParts {
115 get { return Security.ChannelRequirements.IncomingEncryptionParts; }
119 internal class RecipientMessageSecurityGenerator : MessageSecurityGenerator
121 RecipientMessageSecurityBindingSupport security;
122 SecurityRequestContext req_ctx;
124 public RecipientMessageSecurityGenerator (
126 SecurityRequestContext requestContext,
127 RecipientMessageSecurityBindingSupport security)
128 : base (msg, security)
130 this.security = security;
131 req_ctx = requestContext;
132 SecurityMessageProperty secprop =
133 (SecurityMessageProperty) req_ctx.RequestMessage.Properties.Security.CreateCopy ();
134 msg.Properties.Security = secprop;
137 public override SecurityRequestContext RequestContext {
138 get { return req_ctx; }
141 public override UniqueId RelatesTo {
142 get { return req_ctx.RequestMessage.Headers.MessageId; }
145 public override SecurityTokenParameters Parameters {
146 get { return security.RecipientParameters; }
149 public override SecurityTokenParameters CounterParameters {
150 get { return security.InitiatorParameters; }
153 public override MessageDirection Direction {
154 get { return MessageDirection.Output; }
157 public override EndpointAddress MessageTo {
161 public override bool ShouldIncludeToken (SecurityTokenInclusionMode mode, bool isInitialized)
164 case SecurityTokenInclusionMode.Never:
165 case SecurityTokenInclusionMode.AlwaysToRecipient:
167 case SecurityTokenInclusionMode.AlwaysToInitiator:
169 case SecurityTokenInclusionMode.Once:
170 return !isInitialized;
172 throw new Exception ("Internal Error: should not happen.");
175 public override ScopedMessagePartSpecification SignatureParts {
176 get { return Security.ChannelRequirements.OutgoingSignatureParts; }
179 public override ScopedMessagePartSpecification EncryptionParts {
180 get { return Security.ChannelRequirements.OutgoingEncryptionParts; }
184 internal abstract class MessageSecurityGenerator
187 SecurityMessageProperty secprop;
188 MessageSecurityBindingSupport security;
191 public MessageSecurityGenerator (Message msg,
192 MessageSecurityBindingSupport security)
195 this.security = security;
198 public Message Message {
202 public MessageSecurityBindingSupport Security {
203 get { return security; }
206 public abstract SecurityTokenParameters Parameters { get; }
208 public abstract SecurityTokenParameters CounterParameters { get; }
210 public abstract MessageDirection Direction { get; }
212 public abstract EndpointAddress MessageTo { get; }
214 public abstract ScopedMessagePartSpecification SignatureParts { get; }
216 public abstract ScopedMessagePartSpecification EncryptionParts { get; }
218 public MessagePartSpecification SignaturePart {
220 MessagePartSpecification spec;
221 if (!SignatureParts.TryGetParts (GetAction (), false, out spec))
222 spec = SignatureParts.ChannelParts;
227 public MessagePartSpecification EncryptionPart {
229 MessagePartSpecification spec;
230 if (!EncryptionParts.TryGetParts (GetAction (), false, out spec))
231 spec = EncryptionParts.ChannelParts;
236 public abstract bool ShouldIncludeToken (SecurityTokenInclusionMode mode, bool isInitialized);
238 public bool ShouldOutputEncryptedKey {
239 get { return RequestContext == null || RequestContext.RequestMessage.Properties.Security.ProtectionToken == null; } //security.Element is AsymmetricSecurityBindingElement; }
242 public abstract UniqueId RelatesTo { get; }
244 public abstract SecurityRequestContext RequestContext { get; }
246 public Message SecureMessage ()
248 secprop = Message.Properties.Security ?? new SecurityMessageProperty ();
250 SecurityToken encToken =
251 secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken;
252 // FIXME: it might be still incorrect.
253 SecurityToken signToken =
254 Parameters == CounterParameters ? null :
255 security.SigningToken;
256 MessageProtectionOrder protectionOrder =
257 security.MessageProtectionOrder;
258 SecurityTokenSerializer serializer =
259 security.TokenSerializer;
260 SecurityBindingElement element =
262 SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite;
264 // FIXME: remove this hack
265 if (!ShouldOutputEncryptedKey)
266 encToken = new BinarySecretSecurityToken (secprop.EncryptionKey);
268 string messageId = "uuid-" + Guid.NewGuid ();
269 int identForMessageId = 1;
270 XmlDocument doc = new XmlDocument ();
271 doc.PreserveWhitespace = true;
273 UniqueId relatesTo = RelatesTo;
274 if (relatesTo != null)
275 msg.Headers.RelatesTo = relatesTo;
276 else // FIXME: probably it is always added when it is stateful ?
277 msg.Headers.MessageId = new UniqueId ("urn:" + messageId);
279 // FIXME: get correct ReplyTo value
280 if (Direction == MessageDirection.Input)
281 msg.Headers.Add (MessageHeader.CreateHeader ("ReplyTo", msg.Version.Addressing.Namespace, EndpointAddress10.FromEndpointAddress (new EndpointAddress (Constants.WsaAnonymousUri))));
283 if (MessageTo != null)
284 msg.Headers.Add (MessageHeader.CreateHeader ("To", msg.Version.Addressing.Namespace, MessageTo.Uri.AbsoluteUri, true));
287 WSSecurityMessageHeader header =
288 new WSSecurityMessageHeader (serializer);
289 msg.Headers.Add (header);
291 if (element.IncludeTimestamp) {
292 WsuTimestamp timestamp = new WsuTimestamp ();
293 timestamp.Id = messageId + "-" + identForMessageId++;
294 timestamp.Created = DateTime.Now;
295 // FIXME: on service side, use element.LocalServiceSettings.TimestampValidityDuration
296 timestamp.Expires = timestamp.Created.Add (element.LocalClientSettings.TimestampValidityDuration);
297 header.AddContent (timestamp);
300 XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
301 nsmgr.AddNamespace ("s", msg.Version.Envelope.Namespace);
302 nsmgr.AddNamespace ("o", Constants.WssNamespace);
303 nsmgr.AddNamespace ("u", Constants.WsuNamespace);
304 nsmgr.AddNamespace ("o11", Constants.Wss11Namespace);
306 /*WrappedKey*/SecurityToken primaryToken = null;
307 DerivedKeySecurityToken dkeyToken = null;
308 SecurityToken actualToken = null;
309 SecurityKeyIdentifierClause actualClause = null;
310 Signature sig = null;
312 List<DerivedKeySecurityToken> derivedKeys =
313 new List<DerivedKeySecurityToken> ();
315 SymmetricAlgorithm masterKey = new RijndaelManaged ();
316 masterKey.KeySize = suite.DefaultSymmetricKeyLength;
317 masterKey.Mode = CipherMode.CBC;
318 masterKey.Padding = PaddingMode.ISO10126;
319 SymmetricAlgorithm actualKey = masterKey;
321 // 2. [Encryption Token]
323 // SecurityTokenInclusionMode
324 // - Initiator or Recipient
325 // - done or notyet. FIXME: not implemented yet
326 // It also affects on key reference output
328 bool includeEncToken = // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false :
330 Security.RecipientParameters.InclusionMode, false);
331 bool includeSigToken = // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false :
333 Security.InitiatorParameters.InclusionMode, false);
335 SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ?
336 CounterParameters.CallCreateKeyIdentifierClause (encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null;
338 MessagePartSpecification sigSpec = SignaturePart;
339 MessagePartSpecification encSpec = EncryptionPart;
341 // encryption key (possibly also used for signing)
342 // FIXME: get correct SymmetricAlgorithm according to the algorithm suite
343 if (secprop.EncryptionKey != null)
344 actualKey.Key = secprop.EncryptionKey;
346 // FIXME: remove thid hack
347 if (!ShouldOutputEncryptedKey)
348 primaryToken = RequestContext.RequestMessage.Properties.Security.ProtectionToken.SecurityToken as WrappedKeySecurityToken;
351 // FIXME: remove this hack?
352 encToken is SecurityContextSecurityToken ? encToken :
353 new WrappedKeySecurityToken (messageId + "-" + identForMessageId++,
355 // security.DefaultKeyWrapAlgorithm,
356 Parameters.InternalHasAsymmetricKey ?
357 suite.DefaultAsymmetricKeyWrapAlgorithm :
358 suite.DefaultSymmetricKeyWrapAlgorithm,
360 encClause != null ? new SecurityKeyIdentifier (encClause) : null);
362 // If it reuses request's encryption key, do not output.
363 if (ShouldOutputEncryptedKey)
364 header.AddContent (primaryToken);
366 actualToken = primaryToken;
368 // FIXME: I doubt it is correct...
369 WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken;
370 actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause)
371 new LocalIdKeyIdentifierClause (actualToken.Id, typeof (WrappedKeySecurityToken)) :
372 new InternalEncryptedKeyIdentifierClause (SHA1.Create ().ComputeHash (requestEncKey.GetWrappedKey ()));
374 // generate derived key if needed
375 if (CounterParameters.RequireDerivedKeys) {
376 RijndaelManaged deriv = new RijndaelManaged ();
377 deriv.KeySize = suite.DefaultEncryptionKeyDerivationLength;
378 deriv.Mode = CipherMode.CBC;
379 deriv.Padding = PaddingMode.ISO10126;
380 deriv.GenerateKey ();
381 dkeyToken = new DerivedKeySecurityToken (
385 new InMemorySymmetricSecurityKey (actualKey.Key),
392 derivedKeys.Add (dkeyToken);
393 actualToken = dkeyToken;
394 actualKey.Key = ((SymmetricSecurityKey) dkeyToken.SecurityKeys [0]).GetSymmetricKey ();
395 actualClause = new LocalIdKeyIdentifierClause (dkeyToken.Id);
396 header.AddContent (dkeyToken);
399 ReferenceList refList = new ReferenceList ();
400 // When encrypted with DerivedKeyToken, put references
401 // immediately after the derived token (not inside the
403 // Similarly, when we do not output EncryptedKey,
404 // output ReferenceList in the same way.
405 if (CounterParameters.RequireDerivedKeys ||
406 !ShouldOutputEncryptedKey)
407 header.AddContent (refList);
409 ((WrappedKeySecurityToken) primaryToken).ReferenceList = refList;
411 // [Signature Confirmation]
412 if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0)
413 foreach (string value in secprop.ConfirmedSignatures)
414 header.AddContent (new Wss11SignatureConfirmation (GenerateId (doc), value));
416 SupportingTokenInfoCollection tokenInfos =
417 Direction == MessageDirection.Input ?
418 security.CollectSupportingTokens (GetAction ()) :
419 new SupportingTokenInfoCollection (); // empty
421 foreach (SupportingTokenInfo tinfo in tokenInfos)
422 header.AddContent (tinfo.Token);
424 // populate DOM to sign.
425 XPathNavigator nav = doc.CreateNavigator ();
426 using (XmlWriter w = nav.AppendChild ()) {
427 msg.WriteMessage (w);
430 XmlElement body = doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement;
431 string bodyId = null;
432 XmlElement secElem = null;
433 Collection<WSSignedXml> endorsedSignatures =
434 new Collection<WSSignedXml> ();
435 bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature);
437 // Below are o:Security contents that are not signed...
438 if (includeSigToken && signToken != null)
439 header.AddContent (signToken);
441 switch (protectionOrder) {
442 case MessageProtectionOrder.EncryptBeforeSign:
444 throw new NotImplementedException ();
445 case MessageProtectionOrder.SignBeforeEncrypt:
446 case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature:
449 // see clause 8 of WS-SecurityPolicy C.2.2
450 WSSignedXml sxml = new WSSignedXml (doc);
451 SecurityTokenReferenceKeyInfo sigKeyInfo;
453 sig = sxml.Signature;
454 sig.SignedInfo.CanonicalizationMethod =
455 suite.DefaultCanonicalizationAlgorithm;
456 foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/u:Timestamp", nsmgr))
457 CreateReference (sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace));
458 foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr))
459 CreateReference (sig, elem, elem.GetAttribute ("Id", Constants.WsuNamespace));
460 foreach (SupportingTokenInfo tinfo in tokenInfos)
461 if (tinfo.Mode != SecurityTokenAttachmentMode.Endorsing) {
462 XmlElement el = sxml.GetIdElement (doc, tinfo.Token.Id);
463 CreateReference (sig, el, el.GetAttribute ("Id", Constants.WsuNamespace));
465 XmlNodeList nodes = doc.SelectNodes ("/s:Envelope/s:Header/*", nsmgr);
466 for (int i = 0; i < msg.Headers.Count; i++) {
467 MessageHeaderInfo h = msg.Headers [i];
468 if (h.Name == "Security" && h.Namespace == Constants.WssNamespace)
469 secElem = nodes [i] as XmlElement;
470 else if (sigSpec.HeaderTypes.Count == 0 ||
471 sigSpec.HeaderTypes.Contains (new XmlQualifiedName (h.Name, h.Namespace))) {
472 string id = GenerateId (doc);
474 CreateReference (sig, nodes [i] as XmlElement, id);
477 if (sigSpec.IsBodyIncluded) {
478 bodyId = GenerateId (doc);
479 CreateReference (sig, body.ParentNode as XmlElement, bodyId);
482 if (security.DefaultSignatureAlgorithm == SignedXml.XmlDsigHMACSHA1Url) {
483 // FIXME: use appropriate hash algorithm
484 sxml.ComputeSignature (new HMACSHA1 (actualKey.Key));
485 sigKeyInfo = new SecurityTokenReferenceKeyInfo (actualClause, serializer, doc);
488 SecurityKeyIdentifierClause signClause =
489 CounterParameters.CallCreateKeyIdentifierClause (signToken, includeSigToken ? CounterParameters.ReferenceStyle : SecurityTokenReferenceStyle.External);
490 AsymmetricSecurityKey signKey = (AsymmetricSecurityKey) signToken.ResolveKeyIdentifierClause (signClause);
491 sxml.SigningKey = signKey.GetAsymmetricAlgorithm (security.DefaultSignatureAlgorithm, true);
492 sxml.ComputeSignature ();
493 sigKeyInfo = new SecurityTokenReferenceKeyInfo (signClause, serializer, doc);
496 sxml.KeyInfo = new KeyInfo ();
497 sxml.KeyInfo.AddClause (sigKeyInfo);
499 if (!signatureProtection)
500 header.AddContent (sig);
502 // endorse the signature with (signed)endorsing
503 // supporting tokens.
505 foreach (SupportingTokenInfo tinfo in tokenInfos) {
506 switch (tinfo.Mode) {
507 case SecurityTokenAttachmentMode.Endorsing:
508 case SecurityTokenAttachmentMode.SignedEndorsing:
509 if (sxml.Signature.Id == null) {
510 sig.Id = GenerateId (doc);
511 secElem.AppendChild (sxml.GetXml ());
513 WSSignedXml ssxml = new WSSignedXml (doc);
514 ssxml.Signature.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm;
515 CreateReference (ssxml.Signature, doc, sig.Id);
516 SecurityToken sst = tinfo.Token;
517 SecurityKey ssk = sst.SecurityKeys [0]; // FIXME: could be different?
518 SecurityKeyIdentifierClause tclause = new LocalIdKeyIdentifierClause (sst.Id); // FIXME: could be different?
519 if (ssk is SymmetricSecurityKey) {
520 SymmetricSecurityKey signKey = (SymmetricSecurityKey) ssk;
521 ssxml.ComputeSignature (signKey.GetKeyedHashAlgorithm (suite.DefaultSymmetricSignatureAlgorithm));
523 AsymmetricSecurityKey signKey = (AsymmetricSecurityKey) ssk;
524 ssxml.SigningKey = signKey.GetAsymmetricAlgorithm (suite.DefaultAsymmetricSignatureAlgorithm, true);
525 ssxml.ComputeSignature ();
527 ssxml.KeyInfo.AddClause (new SecurityTokenReferenceKeyInfo (tclause, serializer, doc));
528 if (!signatureProtection)
529 header.AddContent (ssxml.Signature);
530 endorsedSignatures.Add (ssxml);
538 WSEncryptedXml exml = new WSEncryptedXml (doc);
540 EncryptedData edata = Encrypt (body, actualKey, actualToken.Id, refList, actualClause, exml, doc);
541 EncryptedXml.ReplaceElement (body, edata, false);
544 if (signatureProtection) {
545 XmlElement sigxml = sig.GetXml ();
546 edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc);
547 header.AddContent (edata);
549 foreach (WSSignedXml ssxml in endorsedSignatures) {
550 sigxml = ssxml.GetXml ();
551 edata = Encrypt (sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc);
552 header.AddContent (edata);
555 if (security.RequireSignatureConfirmation) {
556 Collection<Wss11SignatureConfirmation> confs = header.FindAll<Wss11SignatureConfirmation> ();
558 foreach (XmlElement elem in doc.SelectNodes ("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) {
559 edata = Encrypt (elem, actualKey, confs [count].Id, refList, actualClause, exml, doc);
560 EncryptedXml.ReplaceElement (elem, edata, false);
561 header.Contents.Insert (header.Contents.IndexOf (confs [count]), edata);
562 header.Contents.Remove (confs [count++]);
567 // encrypt Encrypted supporting tokens
568 foreach (SupportingTokenInfo tinfo in tokenInfos) {
569 if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted) {
570 XmlElement el = exml.GetIdElement (doc, tinfo.Token.Id);
571 tinfo.Encrypted = Encrypt (el, actualKey, actualToken.Id, refList, actualClause, exml, doc);
572 EncryptedXml.ReplaceElement (el, tinfo.Encrypted, false);
573 header.Contents.Insert (header.Contents.IndexOf (tinfo.Token), tinfo.Encrypted);
574 header.Contents.Remove (tinfo.Token);
580 Message ret = Message.CreateMessage (msg.Version, msg.Headers.Action, new XmlNodeReader (doc.SelectSingleNode ("/s:Envelope/s:Body/*", nsmgr) as XmlElement));
581 ret.Properties.Security = (SecurityMessageProperty) secprop.CreateCopy ();
582 ret.Properties.Security.EncryptionKey = masterKey.Key;
585 // FIXME: can we support TransportToken here?
586 if (element is AsymmetricSecurityBindingElement) {
587 ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (encToken, null); // FIXME: second argument
588 ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification (signToken, null); // FIXME: second argument
591 ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification (primaryToken, null);
593 ret.Headers.Clear ();
594 ret.Headers.CopyHeadersFrom (msg);
596 // Header contents are:
598 // - SignatureConfirmation if required
599 // - EncryptionToken if included
600 // - derived key token for EncryptionToken
601 // - ReferenceList for encrypted items
602 // - signed supporting tokens
603 // - signed endorsing supporting tokens
604 // (i.e. Signed/SignedEncrypted/SignedEndorsing)
605 // - Signature Token if different from enc token.
606 // - derived key token for sig token if different
609 // - supporting tokens (regardless of
611 // - message parts in SignedParts
612 // - SignatureToken if TokenProtection
613 // (regardless of its inclusion)
614 // - Signatures for the main signature (above),
615 // for every endorsing token and signed
619 //MessageBuffer zzz = ret.CreateBufferedCopy (100000);
620 //ret = zzz.CreateMessage ();
621 //Console.WriteLine (zzz.CreateMessage ());
625 void CreateReference (Signature sig, XmlElement el, string id)
627 CreateReference (sig, el.OwnerDocument, id);
629 if (el.GetAttribute ("Id", Constants.WsuNamespace) != id) {
630 XmlAttribute a = el.SetAttributeNode ("Id", Constants.WsuNamespace);
636 void CreateReference (Signature sig, XmlDocument doc, string id)
638 SecurityAlgorithmSuite suite = security.Element.DefaultAlgorithmSuite;
639 if (id == String.Empty)
640 id = GenerateId (doc);
641 Reference r = new Reference ("#" + id);
642 r.AddTransform (CreateTransform (suite.DefaultCanonicalizationAlgorithm));
643 r.DigestMethod = suite.DefaultDigestAlgorithm;
644 sig.SignedInfo.AddReference (r);
647 Transform CreateTransform (string url)
650 case SignedXml.XmlDsigC14NTransformUrl:
651 return new XmlDsigC14NTransform ();
652 case SignedXml.XmlDsigC14NWithCommentsTransformUrl:
653 return new XmlDsigC14NWithCommentsTransform ();
654 case SignedXml.XmlDsigExcC14NTransformUrl:
655 return new XmlDsigExcC14NTransform ();
656 case SignedXml.XmlDsigExcC14NWithCommentsTransformUrl:
657 return new XmlDsigExcC14NWithCommentsTransform ();
659 throw new Exception (String.Format ("INTERNAL ERROR: Invalid canonicalization URL: {0}", url));
662 EncryptedData Encrypt (XmlElement target, SymmetricAlgorithm actualKey, string ekeyId, ReferenceList refList, SecurityKeyIdentifierClause encClause, EncryptedXml exml, XmlDocument doc)
664 SecurityAlgorithmSuite suite = security.Element.DefaultAlgorithmSuite;
665 SecurityTokenSerializer serializer = security.TokenSerializer;
667 byte [] encrypted = exml.EncryptData (target, actualKey, false);
668 EncryptedData edata = new EncryptedData ();
669 edata.Id = GenerateId (doc);
670 edata.Type = EncryptedXml.XmlEncElementContentUrl;
671 edata.EncryptionMethod = new EncryptionMethod (suite.DefaultEncryptionAlgorithm);
672 // FIXME: here wsse:DigestMethod should be embedded
673 // inside EncryptionMethod. Since it is not possible
674 // with S.S.C.Xml.EncryptionMethod, we will have to
675 // build our own XML encryption classes.
677 edata.CipherData.CipherValue = encrypted;
679 DataReference dr = new DataReference ();
680 dr.Uri = "#" + edata.Id;
683 if (ShouldOutputEncryptedKey && !CounterParameters.RequireDerivedKeys)
684 edata.KeyInfo = null;
686 edata.KeyInfo = new KeyInfo ();
687 edata.KeyInfo.AddClause (new SecurityTokenReferenceKeyInfo (encClause, serializer, doc));
693 string GenerateId (XmlDocument doc)
696 return secprop.SenderIdPrefix + idbase;
699 public string GetAction ()
701 string ret = msg.Headers.Action;
703 HttpRequestMessageProperty reqprop =
704 msg.Properties ["Action"] as HttpRequestMessageProperty;
706 ret = reqprop.Headers ["Action"];