1 //
2 // IssuedSecurityTokenProviderTest.cs
3 //
4 // Author:
5 //	Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
27 //
28 #if !MOBILE && !XAMMAC_4_5
29 using System;
30 using System.Collections.Generic;
31 using System.Globalization;
32 using System.IO;
33 using System.Security.Cryptography;
34 using System.Security.Cryptography.X509Certificates;
35 using System.Security.Cryptography.Xml;
36 using System.ServiceModel;
37 using System.ServiceModel.Channels;
38 using System.ServiceModel.Security;
39 using System.ServiceModel.Security.Tokens;
40 using System.IdentityModel.Tokens;
41 using System.Text;
42 using System.Xml;
43 using NUnit.Framework;
44 
45 using MonoTests.System.ServiceModel.Channels;
46 
47 namespace MonoTests.System.ServiceModel.Security.Tokens
48 {
49 	[TestFixture]
50 	public class IssuedSecurityTokenProviderTest
51 	{
52 		[Test]
DefaultValues()53 		public void DefaultValues ()
54 		{
55 			IssuedSecurityTokenProvider p =
56 				new IssuedSecurityTokenProvider ();
57 			Assert.AreEqual (true, p.CacheIssuedTokens, "#1");
58 			Assert.AreEqual (TimeSpan.FromMinutes (1), p.DefaultOpenTimeout, "#2");
59 			Assert.AreEqual (TimeSpan.FromMinutes (1), p.DefaultCloseTimeout, "#3");
60 			Assert.IsNotNull (p.IdentityVerifier, "#4");
61 			Assert.AreEqual (60, p.IssuedTokenRenewalThresholdPercentage, "#5");
62 			Assert.IsNull (p.IssuerAddress, "#6");
63 			Assert.AreEqual (0, p.IssuerChannelBehaviors.Count, "#7");
64 			Assert.AreEqual (SecurityKeyEntropyMode.CombinedEntropy, p.KeyEntropyMode, "#8");
65 			Assert.AreEqual (TimeSpan.MaxValue, p.MaxIssuedTokenCachingTime, "#9");
66 			Assert.AreEqual (MessageSecurityVersion.Default,
67 				p.MessageSecurityVersion, "#10");
68 			Assert.IsNull (p.SecurityAlgorithmSuite, "#11");
69 			Assert.IsNull (p.SecurityTokenSerializer, "#12");
70 			Assert.IsNull (p.TargetAddress, "#13");
71 			Assert.AreEqual (true, p.SupportsTokenCancellation, "#14");
72 			Assert.AreEqual (0, p.TokenRequestParameters.Count, "#15");
73 			Assert.IsNull (p.IssuerBinding, "#16");
74 		}
75 
76 		[Test]
77 		[ExpectedException (typeof (InvalidOperationException))]
OpenWithoutSerializer()78 		public void OpenWithoutSerializer ()
79 		{
80 			IssuedSecurityTokenProvider p =
81 				new IssuedSecurityTokenProvider ();
82 			p.Open ();
83 		}
84 
85 		[Test]
86 		[ExpectedException (typeof (InvalidOperationException))]
OpenWithoutIssuerAddress()87 		public void OpenWithoutIssuerAddress ()
88 		{
89 			IssuedSecurityTokenProvider p =
90 				new IssuedSecurityTokenProvider ();
91 			p.SecurityTokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
92 			p.Open ();
93 		}
94 
95 		[Test]
96 		[ExpectedException (typeof (InvalidOperationException))]
OpenWithoutBinding()97 		public void OpenWithoutBinding ()
98 		{
99 			IssuedSecurityTokenProvider p =
100 				new IssuedSecurityTokenProvider ();
101 			p.SecurityTokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
102 			p.IssuerAddress = new EndpointAddress ("http://localhost:8080");
103 			p.Open ();
104 		}
105 
106 		[Test]
107 		[ExpectedException (typeof (InvalidOperationException))]
OpenWithoutTargetAddress()108 		public void OpenWithoutTargetAddress ()
109 		{
110 			IssuedSecurityTokenProvider p =
111 				new IssuedSecurityTokenProvider ();
112 			p.SecurityTokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
113 			p.IssuerAddress = new EndpointAddress ("http://localhost:8080");
114 			p.IssuerBinding = new BasicHttpBinding ();
115 
116 			// wiithout it indigo causes NRE
117 			p.SecurityAlgorithmSuite = SecurityAlgorithmSuite.Default;
118 			p.Open ();
119 		}
120 
121 		[Test]
122 		[Category ("NotWorking")]
Open()123 		public void Open ()
124 		{
125 			IssuedSecurityTokenProvider p = SetupProvider (new BasicHttpBinding ());
126 			try {
127 				p.Open ();
128 			} finally {
129 				if (p.State == CommunicationState.Opened)
130 					p.Close ();
131 			}
132 		}
133 
134 		[Test]
135 		[ExpectedException (typeof (InvalidOperationException))]
GetTokenWithoutOpen()136 		public void GetTokenWithoutOpen ()
137 		{
138 			IssuedSecurityTokenProvider p =
139 				new IssuedSecurityTokenProvider ();
140 			p.GetToken (TimeSpan.FromSeconds (10));
141 		}
142 
143 		// From WinFX beta2:
144 		// System.ServiceModel.Security.SecurityNegotiationException :
145 		// SOAP security negotiation with 'stream:dummy' for target
146 		// 'stream:dummy' failed. See inner exception for more details.
147 		// ----> System.InvalidOperationException : The request
148 		// message must be protected. This is required by an operation
149 		// of the contract ('IWsTrustFeb2005SecurityTokenService',
150 		// 'http://tempuri.org/'). The protection must be provided by
151 		// the binding ('BasicHttpBinding','http://tempuri.org/').
152 		[Test]
153 		[ExpectedException (typeof (SecurityNegotiationException))]
154 		[Category ("NotWorking")]
GetTokenNoSecureBinding()155 		public void GetTokenNoSecureBinding ()
156 		{
157 			IssuedSecurityTokenProvider p = SetupProvider (new BasicHttpBinding ());
158 			try {
159 				p.Open ();
160 				p.GetToken (TimeSpan.FromSeconds (10));
161 			} finally {
162 				if (p.State == CommunicationState.Opened)
163 					p.Close ();
164 			}
165 		}
166 
167 		[Test]
168 		// SymmetricSecurityBindingElement requires protection
169 		// token parameters to build a channel or listener factory.
170 		[ExpectedException (typeof (SecurityNegotiationException))]
171 		[Category ("NotWorking")]
GetTokenWithoutProtectionTokenParameters()172 		public void GetTokenWithoutProtectionTokenParameters ()
173 		{
174 			IssuedSecurityTokenProvider p = SetupProvider (CreateIssuerBinding (null, false));
175 			try {
176 				p.Open ();
177 				p.GetToken (TimeSpan.FromSeconds (10));
178 			} finally {
179 				if (p.State == CommunicationState.Opened)
180 					p.Close ();
181 			}
182 		}
183 
184 		// SecurityNegotiationException (InvalidOperationException (
185 		//   "The service certificate is not provided for target
186 		//   'stream:dummy'. Specify a service certificate in
187 		//   ClientCredentials."))
188 		[Test]
189 		[ExpectedException (typeof (SecurityNegotiationException))]
190 		[Category ("NotWorking")]
GetTokenWithoutServiceCertificate()191 		public void GetTokenWithoutServiceCertificate ()
192 		{
193 			IssuedSecurityTokenProvider p = SetupProvider (CreateIssuerBinding (null, true));
194 			p.IssuerAddress = new EndpointAddress ("stream:dummy");
195 			try {
196 				p.Open (TimeSpan.FromSeconds (5));
197 				p.GetToken (TimeSpan.FromSeconds (10));
198 			} finally {
199 				if (p.State == CommunicationState.Opened)
200 					p.Close ();
201 			}
202 		}
203 
204 		[Test]
205 		[Category ("NotWorking")]
206 		[ExpectedException (typeof (MyException))]
GetTokenWrongResponse()207 		public void GetTokenWrongResponse ()
208 		{
209 			IssuedSecurityTokenProvider p = SetupProvider (CreateIssuerBinding (new RequestSender (OnGetTokenWrongResponse), true));
210 			try {
211 				p.Open (TimeSpan.FromSeconds (5));
212 				p.GetToken (TimeSpan.FromSeconds (10));
213 			} finally {
214 				if (p.State == CommunicationState.Opened)
215 					p.Close ();
216 			}
217 		}
218 
219 		[Test]
220 		[Category ("NotWorking")]
221 		[ExpectedException (typeof (MessageSecurityException))]
GetTokenUnsignedReply()222 		public void GetTokenUnsignedReply ()
223 		{
224 			IssuedSecurityTokenProvider p = SetupProvider (CreateIssuerBinding (new RequestSender (OnGetTokenUnsignedReply), true));
225 			try {
226 				p.Open (TimeSpan.FromSeconds (5));
227 				p.GetToken (TimeSpan.FromSeconds (10));
228 			} finally {
229 				if (p.State == CommunicationState.Opened)
230 					p.Close ();
231 			}
232 		}
233 
234 		// InnerException: System.InvalidOperationException:
235 		// The issuer must provide a computed key in key entropy mode
236 		// 'CombinedEntropy'.
237 		[Test]
238 		[Ignore ("todo")]
239 		[ExpectedException (typeof (SecurityNegotiationException))]
GetTokenNoEntropyInResponseInCombinedMode()240 		public void GetTokenNoEntropyInResponseInCombinedMode ()
241 		{
242 			// FIXME: implement it after we get working token issuer.
243 			// In the reply, do not include Nonce
244 		}
245 
246 		// on the other hand, in Client entropy mode it must not
247 		// provide entropy.
248 		[Test]
249 		[Ignore ("todo")]
250 		[ExpectedException (typeof (SecurityNegotiationException))]
GetTokenIncludesEntropyInResponseInClientMode()251 		public void GetTokenIncludesEntropyInResponseInClientMode ()
252 		{
253 			// FIXME: implement it after we get working token issuer.
254 			// specify SecurityKeyEntropyMode.ClientEntropy on
255 			// client side. And in the reply, include Nonce.
256 		}
257 
258 		[Test]
259 		[Ignore ("need to implement response")]
260 		[Category ("NotWorking")]
GetToken()261 		public void GetToken ()
262 		{
263 			IssuedSecurityTokenProvider p = SetupProvider (CreateIssuerBinding (new RequestSender (OnGetToken), true));
264 			try {
265 				p.Open (TimeSpan.FromSeconds (5));
266 				p.GetToken (TimeSpan.FromSeconds (10));
267 			} finally {
268 				if (p.State == CommunicationState.Opened)
269 					p.Close ();
270 			}
271 		}
272 
273 		class MyException : Exception
274 		{
275 		}
276 
OnGetTokenWrongResponse(Message input)277 		Message OnGetTokenWrongResponse (Message input)
278 		{
279 			VerifyInput (input.CreateBufferedCopy (10000));
280 
281 			throw new MyException ();
282 		}
283 
OnGetTokenUnsignedReply(Message input)284 		Message OnGetTokenUnsignedReply (Message input)
285 		{
286 			XmlDocument doc = new XmlDocument ();
287 			doc.LoadXml ("<Response>RESPONSE</Response>");
288 
289 			Message msg = Message.CreateMessage (input.Version, "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/IssueResponse", doc.DocumentElement);
290 			msg.Headers.Add (MessageHeader.CreateHeader (
291 				"Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", null, true));
292 
293 			return msg;
294 		}
295 
OnGetToken(Message input)296 		Message OnGetToken (Message input)
297 		{
298 			MessageBuffer buf = input.CreateBufferedCopy (10000);
299 			VerifyInput2 (buf);
300 
301 			// FIXME: create response message (when I understand what I should return.)
302 //			throw new MyException ();
303 //*
304 			XmlDocument doc = new XmlDocument ();
305 			doc.LoadXml ("<Response>RESPONSE</Response>");
306 			X509Certificate2 cert = new X509Certificate2 ("Test/Resources/test.pfx", "mono");
307 			SignedXml sxml = new SignedXml (doc);
308 			MemoryStream ms = new MemoryStream (new byte [] {1, 2, 3});
309 			sxml.AddReference (new Reference (ms));
310 			sxml.SigningKey = cert.PrivateKey;
311 			sxml.ComputeSignature ();
312 
313 			Message msg = Message.CreateMessage (input.Version, "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue", sxml.GetXml ());
314 			msg.Headers.Add (MessageHeader.CreateHeader (
315 				"Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", null, true));
316 
317 			return msg;
318 //*/
319 		}
320 
VerifyInput(MessageBuffer buf)321 		void VerifyInput (MessageBuffer buf)
322 		{
323 			Message input = buf.CreateMessage ();
324 /*
325 XmlWriterSettings settings = new XmlWriterSettings ();
326 settings.Indent = true;
327 using (XmlWriter w = XmlWriter.Create (Console.Error, settings)) {
328 buf.CreateMessage ().WriteMessage (w);
329 }
330 Console.Error.WriteLine ("******************** DONE ********************");
331 Console.Error.Flush ();
332 */
333 
334 			Assert.AreEqual ("http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", input.Headers.Action, "GetToken.Request.Action");
335 			Assert.IsNotNull (input.Headers.MessageId, "GetToken.Request.MessageID");
336 			// in the raw Message it is "http://www.w3.org/2005/08/addressing/anonymous", but it is replaced by MessageHeaders implementation.
337 			Assert.AreEqual (new EndpointAddress ("http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous"), input.Headers.ReplyTo, "GetToken.Request.ReplyTo");
338 
339 			// o:Security
340 			// FIXME: test WSSecurity more
341 			// <o:Security>
342 			//  <u:Timestamp>
343 			//   <u:Created>...</u:Created>
344 			//   <u:Expires>...</u:Expires>
345 			//  </u:Timestamp>
346 			//  <o:BinarySecurityToken>...</o:BinarySecurityToken>
347 			//  <e:EncryptedKey>
348 			//   <e:EncryptionMethod><DigestMethod/></e:EncryptionMethod>
349 			//   <KeyInfo>
350 			//    <o:SecurityTokenReference><o:Reference/></o:SecurityTokenReference>
351 			//   </KeyInfo>
352 			//   <e:CipherData>
353 			//    <e:CipherValue>...</e:CipherValue>
354 			//   </e:CipherData>
355 			//  </e:EncryptedKey>
356 			//  [
357 			//  <c:DerivedKeyToken>
358 			//   <o:SecurityTokenReference><o:Reference/></o:SecurityTokenReference>
359 			//   <c:Offset>...</c:Offset>
360 			//   <c:Length>...</c:Length>
361 			//   <c:Nonce>...</c:Nonce>
362 			//  </c:DerivedKeyToken>
363 			//  ]
364 			//  <e:ReferenceList>
365 			//   [
366 			//   <e:DataReference>
367 			//   ]
368 			//  </e:ReferenceList>
369 			//  <e:EncryptedData>
370 			//   <e:EncryptionMethod/>
371 			//   <KeyInfo> {{....}} </KeyInfo>
372 			//   <e:CipherData> {{....}} </e:CipherData>
373 			//  </e:EncryptedData>
374 			// </o:Security>
375 			int i = input.Headers.FindHeader ("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
376 			Assert.IsTrue (i >= 0, "Security header existence");
377 			MessageHeaderInfo info = input.Headers [i];
378 			Assert.IsNotNull (info, "Security header item");
379 			XmlReader r = input.Headers.GetReaderAtHeader (i);
380 
381 			// FIXME: test WSSecurity more
382 			// <o:Security>
383 			r.MoveToContent ();
384 			r.ReadStartElement ("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
385 			//  <u:Timestamp>
386 			r.MoveToContent ();
387 			r.ReadStartElement ("Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
388 			//   <u:Created>...</u:Created>
389 			r.MoveToContent ();
390 			r.ReadStartElement ("Created", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
391 			r.ReadString ();
392 			r.MoveToContent ();
393 			r.ReadEndElement ();
394 			//   <u:Expires>...</u:Expires>
395 			r.MoveToContent ();
396 			r.ReadStartElement ("Expires", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
397 			r.ReadString ();
398 			r.MoveToContent ();
399 			r.ReadEndElement ();
400 			//  </u:Timestamp>
401 			r.MoveToContent ();
402 			r.ReadEndElement ();
403 			//  <o:BinarySecurityToken>...</o:BinarySecurityToken>
404 			r.MoveToContent ();
405 			r.ReadStartElement ("BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
406 			byte [] rawcert = Convert.FromBase64String (r.ReadString ());
407 			r.ReadEndElement ();
408 			X509Certificate2 cert = new X509Certificate2 (rawcert);
409 
410 			// FIXME: test EncryptedKey
411 			r.MoveToContent ();
412 			r.Skip ();
413 			//  <e:EncryptedKey>
414 			//   <e:EncryptionMethod><DigestMethod/></e:EncryptionMethod>
415 			//   <KeyInfo>
416 			//    <o:SecurityTokenReference><o:Reference/></o:SecurityTokenReference>
417 			//   </KeyInfo>
418 			//   <e:CipherData>
419 			//    <e:CipherValue>...</e:CipherValue>
420 			//   </e:CipherData>
421 			//  </e:EncryptedKey>
422 
423 			// FIXME: test DerivedKeyTokens
424 			r.MoveToContent ();
425 			while (r.LocalName == "DerivedKeyToken") {
426 				r.Skip ();
427 				r.MoveToContent ();
428 			}
429 			//  [
430 			//  <c:DerivedKeyToken>
431 			//   <o:SecurityTokenReference><o:Reference/></o:SecurityTokenReference>
432 			//   <c:Offset>...</c:Offset>
433 			//   <c:Length>...</c:Length>
434 			//   <c:Nonce>...</c:Nonce>
435 			//  </c:DerivedKeyToken>
436 			//  ]
437 
438 			//  <e:ReferenceList>
439 			//   [
440 			//   <e:DataReference>
441 			//   ]
442 			//  </e:ReferenceList>
443 			//  <e:EncryptedData>
444 			//   <e:EncryptionMethod/>
445 			//   <KeyInfo> {{....}} </KeyInfo>
446 			//   <e:CipherData> {{....}} </e:CipherData>
447 			//  </e:EncryptedData>
448 			// </o:Security>
449 
450 			// SOAP Body
451 			r = input.GetReaderAtBodyContents (); // just verifying itself ;)
452 		}
453 
VerifyInput2(MessageBuffer buf)454 		XmlElement VerifyInput2 (MessageBuffer buf)
455 		{
456 			Message msg2 = buf.CreateMessage ();
457 			StringWriter sw = new StringWriter ();
458 			using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw))) {
459 				msg2.WriteMessage (w);
460 			}
461 			XmlDocument doc = new XmlDocument ();
462 			doc.PreserveWhitespace = true;
463 			doc.LoadXml (sw.ToString ());
464 
465 			// decrypt the key with service certificate privkey
466 			PaddingMode mode = PaddingMode.PKCS7; // not sure which is correct ... ANSIX923, ISO10126, PKCS7, Zeros, None.
467 			EncryptedXml encXml = new EncryptedXml (doc);
468 			encXml.Padding = mode;
469 			X509Certificate2 cert2 = new X509Certificate2 ("Test/Resources/test.pfx", "mono");
470 			XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
471 			nsmgr.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
472 			nsmgr.AddNamespace ("c", "http://schemas.xmlsoap.org/ws/2005/02/sc");
473 			nsmgr.AddNamespace ("o", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
474 			nsmgr.AddNamespace ("e", "http://www.w3.org/2001/04/xmlenc#");
475 			nsmgr.AddNamespace ("dsig", "http://www.w3.org/2000/09/xmldsig#");
476 			XmlNode n = doc.SelectSingleNode ("//o:Security/e:EncryptedKey/e:CipherData/e:CipherValue", nsmgr);
477 			Assert.IsNotNull (n, "premise: enckey does not exist");
478 			string raw = n.InnerText;
479 			byte [] rawbytes = Convert.FromBase64String (raw);
480 			RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) cert2.PrivateKey;
481 			byte [] decryptedKey = EncryptedXml.DecryptKey (rawbytes, rsa, true);//rsa.Decrypt (rawbytes, true);
482 
483 #if false
484 			// create derived keys
485 			Dictionary<string,byte[]> keys = new Dictionary<string,byte[]> ();
486 			InMemorySymmetricSecurityKey skey =
487 				new InMemorySymmetricSecurityKey (decryptedKey);
488 			foreach (XmlElement el in doc.SelectNodes ("//o:Security/c:DerivedKeyToken", nsmgr)) {
489 				n = el.SelectSingleNode ("c:Offset", nsmgr);
490 				int offset = (n == null) ? 0 :
491 					int.Parse (n.InnerText, CultureInfo.InvariantCulture);
492 				n = el.SelectSingleNode ("c:Length", nsmgr);
493 				int length = (n == null) ? 32 :
494 					int.Parse (n.InnerText, CultureInfo.InvariantCulture);
495 				n = el.SelectSingleNode ("c:Label", nsmgr);
496 				byte [] label = (n == null) ? decryptedKey :
497 					Convert.FromBase64String (n.InnerText);
498 				n = el.SelectSingleNode ("c:Nonce", nsmgr);
499 				byte [] nonce = (n == null) ? new byte [0] :
500 					Convert.FromBase64String (n.InnerText);
501 				byte [] derkey = skey.GenerateDerivedKey (
502 					//SecurityAlgorithms.Psha1KeyDerivation,
503 					"http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1",
504 // FIXME: maybe due to the label, this key resolution somehow does not seem to work.
505 					label,
506 					nonce,
507 					length * 8,
508 					offset);
509 
510 				keys [el.GetAttribute ("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")] = derkey;
511 			}
512 #endif
513 
514 			// decrypt the signature with the decrypted key
515 #if true
516 			n = doc.SelectSingleNode ("//o:Security/e:EncryptedData/e:CipherData/e:CipherValue", nsmgr);
517 			Assert.IsNotNull (n, "premise: encdata does not exist");
518 			raw = n.InnerText;
519 			rawbytes = Convert.FromBase64String (raw);
520 			Rijndael aes = RijndaelManaged.Create ();
521 //			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
522 			aes.Key = decryptedKey;
523 			aes.Mode = CipherMode.CBC;
524 			aes.Padding = mode;
525 			MemoryStream ms = new MemoryStream ();
526 			CryptoStream cs = new CryptoStream (ms, aes.CreateDecryptor (), CryptoStreamMode.Write);
527 			cs.Write (rawbytes, 0, rawbytes.Length);
528 			cs.Close ();
529 			byte [] decryptedSignature = ms.ToArray ();
530 #else
531 			Rijndael aes = RijndaelManaged.Create ();
532 //			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
533 			aes.Key = decryptedKey;
534 			aes.Mode = CipherMode.CBC;
535 			aes.Padding = mode;
536 
537 			EncryptedData ed = new EncryptedData ();
538 			n = doc.SelectSingleNode ("//o:Security/e:EncryptedData", nsmgr);
539 			Assert.IsNotNull (n, "premise: encdata does not exist");
540 			ed.LoadXml (n as XmlElement);
541 			byte [] decryptedSignature = encXml.DecryptData (ed, aes);
542 #endif
543 //Console.Error.WriteLine (Encoding.UTF8.GetString (decryptedSignature));
544 //Console.Error.WriteLine ("============= Decrypted Signature End ===========");
545 
546 			// decrypt the body with the decrypted key
547 #if true
548 			n = doc.SelectSingleNode ("//s:Body/e:EncryptedData/e:CipherData/e:CipherValue", nsmgr);
549 			Assert.IsNotNull (n, "premise: encdata does not exist");
550 			raw = n.InnerText;
551 			rawbytes = Convert.FromBase64String (raw);
552 //			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
553 			aes.Key = decryptedKey;
554 			ms = new MemoryStream ();
555 			cs = new CryptoStream (ms, aes.CreateDecryptor (), CryptoStreamMode.Write);
556 			cs.Write (rawbytes, 0, rawbytes.Length);
557 			cs.Close ();
558 			byte [] decryptedBody = ms.ToArray ();
559 #else
560 			// decrypt the body with the decrypted key
561 			EncryptedData ed2 = new EncryptedData ();
562 			XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/e:EncryptedData", nsmgr) as XmlElement;
563 			ed2.LoadXml (el);
564 //			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
565 			aes.Key = decryptedKey;
566 			byte [] decryptedBody = encXml.DecryptData (ed2, aes);
567 #endif
568 //foreach (byte b in decryptedBody) Console.Error.Write ("{0:X02} ", b);
569 Console.Error.WriteLine (Encoding.UTF8.GetString (decryptedBody));
570 Console.Error.WriteLine ("============= Decrypted Body End ===========");
571 
572 			// FIXME: find out what first 16 bytes mean.
573 			for (int mmm = 0; mmm < 16; mmm++) decryptedBody [mmm] = 0x20;
574 			doc.LoadXml (Encoding.UTF8.GetString (decryptedBody));
575 			Assert.AreEqual ("RequestSecurityToken", doc.DocumentElement.LocalName, "#b-1");
576 			Assert.AreEqual ("http://schemas.xmlsoap.org/ws/2005/02/trust", doc.DocumentElement.NamespaceURI, "#b-2");
577 
578 			return doc.DocumentElement;
579 		}
580 
CreateIssuerBinding(RequestSender handler, bool tokenParams)581 		Binding CreateIssuerBinding (RequestSender handler, bool tokenParams)
582 		{
583 			SymmetricSecurityBindingElement sbe =
584 				new SymmetricSecurityBindingElement ();
585 			if (tokenParams)
586 				sbe.ProtectionTokenParameters = new X509SecurityTokenParameters ();
587 			sbe.LocalServiceSettings.NegotiationTimeout = TimeSpan.FromSeconds (5);
588 			sbe.KeyEntropyMode = SecurityKeyEntropyMode.ClientEntropy;
589 			//sbe.IncludeTimestamp = false;
590 			//sbe.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
591 
592 			// for ease of decryption, let's remove DerivedKeyToken.
593 			sbe.SetKeyDerivation (false);
594 
595 			return new CustomBinding (
596 //				new DebugBindingElement (),
597 				sbe,
598 				new TextMessageEncodingBindingElement (),
599 				new HandlerTransportBindingElement (handler));
600 		}
601 
GetSecureEndpointAddress(string uri)602 		EndpointAddress GetSecureEndpointAddress (string uri)
603 		{
604 			return new EndpointAddress (new Uri (uri),
605 				new X509CertificateEndpointIdentity (
606 					new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
607 		}
608 
SetupProvider(Binding binding)609 		IssuedSecurityTokenProvider SetupProvider (Binding binding)
610 		{
611 			IssuedSecurityTokenProvider p =
612 				new IssuedSecurityTokenProvider ();
613 			p.SecurityTokenSerializer = WSSecurityTokenSerializer.DefaultInstance;
614 			p.IssuerAddress = GetSecureEndpointAddress ("stream:dummy");
615 			p.IssuerBinding = binding;
616 
617 			// wiithout it indigo causes NRE
618 			p.SecurityAlgorithmSuite = SecurityAlgorithmSuite.Default;
619 
620 			p.TargetAddress = new EndpointAddress ("http://localhost:9090");
621 			return p;
622 		}
623 	}
624 }
625 #endif
626 
627