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