IssuedSecurityTokenParameters.cs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Security.Tokens
  5. {
  6. using System.Collections.ObjectModel;
  7. using System.Globalization;
  8. using System.IdentityModel.Selectors;
  9. using System.IdentityModel.Tokens;
  10. using System.Runtime;
  11. using System.ServiceModel;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Security;
  14. using System.Text;
  15. using System.Xml;
  16. public class IssuedSecurityTokenParameters : SecurityTokenParameters
  17. {
  18. const string wsidPrefix = "wsid";
  19. const string wsidNamespace = "http://schemas.xmlsoap.org/ws/2005/05/identity";
  20. static readonly string wsidPPIClaim = String.Format(CultureInfo.InvariantCulture, "{0}/claims/privatepersonalidentifier", wsidNamespace);
  21. internal const SecurityKeyType defaultKeyType = SecurityKeyType.SymmetricKey;
  22. internal const bool defaultUseStrTransform = false;
  23. internal struct AlternativeIssuerEndpoint
  24. {
  25. public EndpointAddress IssuerAddress;
  26. public EndpointAddress IssuerMetadataAddress;
  27. public Binding IssuerBinding;
  28. }
  29. Collection<XmlElement> additionalRequestParameters = new Collection<XmlElement>();
  30. Collection<AlternativeIssuerEndpoint> alternativeIssuerEndpoints = new Collection<AlternativeIssuerEndpoint>();
  31. MessageSecurityVersion defaultMessageSecurityVersion;
  32. EndpointAddress issuerAddress;
  33. EndpointAddress issuerMetadataAddress;
  34. Binding issuerBinding;
  35. int keySize;
  36. SecurityKeyType keyType = defaultKeyType;
  37. Collection<ClaimTypeRequirement> claimTypeRequirements = new Collection<ClaimTypeRequirement>();
  38. bool useStrTransform = defaultUseStrTransform;
  39. string tokenType;
  40. protected IssuedSecurityTokenParameters(IssuedSecurityTokenParameters other)
  41. : base(other)
  42. {
  43. this.defaultMessageSecurityVersion = other.defaultMessageSecurityVersion;
  44. this.issuerAddress = other.issuerAddress;
  45. this.keyType = other.keyType;
  46. this.tokenType = other.tokenType;
  47. this.keySize = other.keySize;
  48. this.useStrTransform = other.useStrTransform;
  49. foreach (XmlElement parameter in other.additionalRequestParameters)
  50. {
  51. this.additionalRequestParameters.Add((XmlElement)parameter.Clone());
  52. }
  53. foreach (ClaimTypeRequirement c in other.claimTypeRequirements)
  54. {
  55. this.claimTypeRequirements.Add(c);
  56. }
  57. if (other.issuerBinding != null)
  58. {
  59. this.issuerBinding = new CustomBinding(other.issuerBinding);
  60. }
  61. this.issuerMetadataAddress = other.issuerMetadataAddress;
  62. }
  63. public IssuedSecurityTokenParameters()
  64. : this(null, null, null)
  65. {
  66. // empty
  67. }
  68. public IssuedSecurityTokenParameters(string tokenType)
  69. : this(tokenType, null, null)
  70. {
  71. // empty
  72. }
  73. public IssuedSecurityTokenParameters(string tokenType, EndpointAddress issuerAddress)
  74. : this(tokenType, issuerAddress, null)
  75. {
  76. // empty
  77. }
  78. public IssuedSecurityTokenParameters(string tokenType, EndpointAddress issuerAddress, Binding issuerBinding)
  79. : base()
  80. {
  81. this.tokenType = tokenType;
  82. this.issuerAddress = issuerAddress;
  83. this.issuerBinding = issuerBinding;
  84. }
  85. internal protected override bool HasAsymmetricKey { get { return this.KeyType == SecurityKeyType.AsymmetricKey; } }
  86. public Collection<XmlElement> AdditionalRequestParameters
  87. {
  88. get
  89. {
  90. return this.additionalRequestParameters;
  91. }
  92. }
  93. public MessageSecurityVersion DefaultMessageSecurityVersion
  94. {
  95. get
  96. {
  97. return this.defaultMessageSecurityVersion;
  98. }
  99. set
  100. {
  101. defaultMessageSecurityVersion = value;
  102. }
  103. }
  104. internal Collection<AlternativeIssuerEndpoint> AlternativeIssuerEndpoints
  105. {
  106. get
  107. {
  108. return this.alternativeIssuerEndpoints;
  109. }
  110. }
  111. public EndpointAddress IssuerAddress
  112. {
  113. get
  114. {
  115. return this.issuerAddress;
  116. }
  117. set
  118. {
  119. this.issuerAddress = value;
  120. }
  121. }
  122. public EndpointAddress IssuerMetadataAddress
  123. {
  124. get
  125. {
  126. return this.issuerMetadataAddress;
  127. }
  128. set
  129. {
  130. this.issuerMetadataAddress = value;
  131. }
  132. }
  133. public Binding IssuerBinding
  134. {
  135. get
  136. {
  137. return this.issuerBinding;
  138. }
  139. set
  140. {
  141. this.issuerBinding = value;
  142. }
  143. }
  144. public SecurityKeyType KeyType
  145. {
  146. get
  147. {
  148. return this.keyType;
  149. }
  150. set
  151. {
  152. SecurityKeyTypeHelper.Validate(value);
  153. this.keyType = value;
  154. }
  155. }
  156. public int KeySize
  157. {
  158. get
  159. {
  160. return this.keySize;
  161. }
  162. set
  163. {
  164. if (value < 0)
  165. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", SR.GetString(SR.ValueMustBeNonNegative)));
  166. this.keySize = value;
  167. }
  168. }
  169. public bool UseStrTransform
  170. {
  171. get
  172. {
  173. return this.useStrTransform;
  174. }
  175. set
  176. {
  177. this.useStrTransform = value;
  178. }
  179. }
  180. public Collection<ClaimTypeRequirement> ClaimTypeRequirements
  181. {
  182. get
  183. {
  184. return this.claimTypeRequirements;
  185. }
  186. }
  187. public string TokenType
  188. {
  189. get
  190. {
  191. return this.tokenType;
  192. }
  193. set
  194. {
  195. this.tokenType = value;
  196. }
  197. }
  198. internal protected override bool SupportsClientAuthentication { get { return true; } }
  199. internal protected override bool SupportsServerAuthentication { get { return true; } }
  200. internal protected override bool SupportsClientWindowsIdentity { get { return false; } }
  201. protected override SecurityTokenParameters CloneCore()
  202. {
  203. return new IssuedSecurityTokenParameters(this);
  204. }
  205. internal protected override SecurityKeyIdentifierClause CreateKeyIdentifierClause(SecurityToken token, SecurityTokenReferenceStyle referenceStyle)
  206. {
  207. if (token is GenericXmlSecurityToken)
  208. return base.CreateGenericXmlTokenKeyIdentifierClause(token, referenceStyle);
  209. else
  210. return this.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause, SamlAssertionKeyIdentifierClause>(token, referenceStyle);
  211. }
  212. internal void SetRequestParameters(Collection<XmlElement> requestParameters, TrustDriver trustDriver)
  213. {
  214. if (requestParameters == null)
  215. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("requestParameters");
  216. if (trustDriver == null)
  217. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("trustDriver");
  218. Collection<XmlElement> unknownRequestParameters = new Collection<XmlElement>();
  219. foreach (XmlElement element in requestParameters)
  220. {
  221. int keySize;
  222. string tokenType;
  223. SecurityKeyType keyType;
  224. Collection<XmlElement> requiredClaims;
  225. if (trustDriver.TryParseKeySizeElement(element, out keySize))
  226. this.keySize = keySize;
  227. else if (trustDriver.TryParseKeyTypeElement(element, out keyType))
  228. this.KeyType = keyType;
  229. else if (trustDriver.TryParseTokenTypeElement(element, out tokenType))
  230. this.TokenType = tokenType;
  231. // Only copy RP policy to client policy for TrustFeb2005
  232. else if (trustDriver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005)
  233. {
  234. if (trustDriver.TryParseRequiredClaimsElement(element, out requiredClaims))
  235. {
  236. Collection<XmlElement> unrecognizedRequiredClaims = new Collection<XmlElement>();
  237. foreach (XmlElement claimRequirement in requiredClaims)
  238. {
  239. if (claimRequirement.LocalName == "ClaimType" && claimRequirement.NamespaceURI == wsidNamespace)
  240. {
  241. string claimValue = claimRequirement.GetAttribute("Uri", string.Empty);
  242. if (!string.IsNullOrEmpty(claimValue))
  243. {
  244. ClaimTypeRequirement claimTypeRequirement;
  245. string optional = claimRequirement.GetAttribute("Optional", string.Empty);
  246. if (String.IsNullOrEmpty(optional))
  247. {
  248. claimTypeRequirement = new ClaimTypeRequirement(claimValue);
  249. }
  250. else
  251. {
  252. claimTypeRequirement = new ClaimTypeRequirement(claimValue, XmlConvert.ToBoolean(optional));
  253. }
  254. this.claimTypeRequirements.Add(claimTypeRequirement);
  255. }
  256. }
  257. else
  258. {
  259. unrecognizedRequiredClaims.Add(claimRequirement);
  260. }
  261. }
  262. if (unrecognizedRequiredClaims.Count > 0)
  263. unknownRequestParameters.Add(trustDriver.CreateRequiredClaimsElement(unrecognizedRequiredClaims));
  264. }
  265. else
  266. {
  267. unknownRequestParameters.Add(element);
  268. }
  269. }
  270. }
  271. unknownRequestParameters = trustDriver.ProcessUnknownRequestParameters(unknownRequestParameters, requestParameters);
  272. if (unknownRequestParameters.Count > 0)
  273. {
  274. for (int i = 0; i < unknownRequestParameters.Count; ++i)
  275. this.AdditionalRequestParameters.Add(unknownRequestParameters[i]);
  276. }
  277. }
  278. public Collection<XmlElement> CreateRequestParameters(MessageSecurityVersion messageSecurityVersion, SecurityTokenSerializer securityTokenSerializer)
  279. {
  280. return CreateRequestParameters(SecurityUtils.CreateSecurityStandardsManager(messageSecurityVersion, securityTokenSerializer).TrustDriver);
  281. }
  282. internal Collection<XmlElement> CreateRequestParameters(TrustDriver driver)
  283. {
  284. if (driver == null)
  285. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("driver");
  286. Collection<XmlElement> result = new Collection<XmlElement>();
  287. if (this.tokenType != null)
  288. {
  289. result.Add(driver.CreateTokenTypeElement(tokenType));
  290. }
  291. result.Add(driver.CreateKeyTypeElement(this.keyType));
  292. if (this.keySize != 0)
  293. {
  294. result.Add(driver.CreateKeySizeElement(keySize));
  295. }
  296. if (this.claimTypeRequirements.Count > 0)
  297. {
  298. Collection<XmlElement> claimsElements = new Collection<XmlElement>();
  299. XmlDocument doc = new XmlDocument();
  300. foreach (ClaimTypeRequirement claimType in this.claimTypeRequirements)
  301. {
  302. XmlElement element = doc.CreateElement(wsidPrefix, "ClaimType", wsidNamespace);
  303. XmlAttribute attr = doc.CreateAttribute("Uri");
  304. attr.Value = claimType.ClaimType;
  305. element.Attributes.Append(attr);
  306. if (claimType.IsOptional != ClaimTypeRequirement.DefaultIsOptional)
  307. {
  308. attr = doc.CreateAttribute("Optional");
  309. attr.Value = XmlConvert.ToString(claimType.IsOptional);
  310. element.Attributes.Append(attr);
  311. }
  312. claimsElements.Add(element);
  313. }
  314. result.Add(driver.CreateRequiredClaimsElement(claimsElements));
  315. }
  316. if (this.additionalRequestParameters.Count > 0)
  317. {
  318. Collection<XmlElement> trustNormalizedParameters = NormalizeAdditionalParameters(this.additionalRequestParameters,
  319. driver,
  320. (this.claimTypeRequirements.Count > 0));
  321. foreach (XmlElement parameter in trustNormalizedParameters)
  322. {
  323. result.Add(parameter);
  324. }
  325. }
  326. return result;
  327. }
  328. private Collection<XmlElement> NormalizeAdditionalParameters(Collection<XmlElement> additionalParameters,
  329. TrustDriver driver,
  330. bool clientSideClaimTypeRequirementsSpecified)
  331. {
  332. // Ensure STS trust version is one of the currently supported versions: Feb 05 / Trust 1.3
  333. Fx.Assert(((driver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005) ||
  334. (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13)),
  335. "Unsupported trust version specified for the STS.");
  336. // We have a mismatch. Make a local copy of additionalParameters for making any potential modifications
  337. // as part of normalization
  338. Collection<XmlElement> tmpCollection = new Collection<XmlElement>();
  339. foreach (XmlElement e in additionalParameters)
  340. {
  341. tmpCollection.Add(e);
  342. }
  343. // 1. For Trust 1.3 EncryptionAlgorithm, CanonicalizationAlgorithm and KeyWrapAlgorithm should not be
  344. // specified as top-level element if "SecondaryParameters" element already specifies this.
  345. if (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13)
  346. {
  347. Fx.Assert(driver.GetType() == typeof(WSTrustDec2005.DriverDec2005), "Invalid Trust Driver specified for Trust 1.3.");
  348. XmlElement encryptionAlgorithmElement = null;
  349. XmlElement canonicalizationAlgorithmElement = null;
  350. XmlElement keyWrapAlgorithmElement = null;
  351. XmlElement secondaryParameter = null;
  352. for (int i = 0; i < tmpCollection.Count; ++i)
  353. {
  354. string algorithm;
  355. if (driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithm))
  356. {
  357. encryptionAlgorithmElement = tmpCollection[i];
  358. }
  359. else if (driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithm))
  360. {
  361. canonicalizationAlgorithmElement = tmpCollection[i];
  362. }
  363. else if (driver.IsKeyWrapAlgorithmElement(tmpCollection[i], out algorithm))
  364. {
  365. keyWrapAlgorithmElement = tmpCollection[i];
  366. }
  367. else if (((WSTrustDec2005.DriverDec2005)driver).IsSecondaryParametersElement(tmpCollection[i]))
  368. {
  369. secondaryParameter = tmpCollection[i];
  370. }
  371. }
  372. if (secondaryParameter != null)
  373. {
  374. foreach (XmlNode node in secondaryParameter.ChildNodes)
  375. {
  376. XmlElement child = node as XmlElement;
  377. if (child != null)
  378. {
  379. string algorithm = null;
  380. if (driver.IsEncryptionAlgorithmElement(child, out algorithm) && (encryptionAlgorithmElement != null))
  381. {
  382. tmpCollection.Remove(encryptionAlgorithmElement);
  383. }
  384. else if (driver.IsCanonicalizationAlgorithmElement(child, out algorithm) && (canonicalizationAlgorithmElement != null))
  385. {
  386. tmpCollection.Remove(canonicalizationAlgorithmElement);
  387. }
  388. else if (driver.IsKeyWrapAlgorithmElement(child, out algorithm) && (keyWrapAlgorithmElement != null))
  389. {
  390. tmpCollection.Remove(keyWrapAlgorithmElement);
  391. }
  392. }
  393. }
  394. }
  395. }
  396. // 2. Check for Mismatch.
  397. // a. Trust Feb 2005 -> Trust 1.3. do the following,
  398. // (i) Copy EncryptionAlgorithm and CanonicalizationAlgorithm as the top-level elements.
  399. // Note, this is in contradiction to step 1. But we don't have a choice here as we cannot say from the
  400. // Additional Parameters section in the config what came from the service and what came from the client.
  401. // (ii) Convert SignWith and EncryptWith elements to Trust 1.3 namespace.
  402. // b. For Trust 1.3 -> Trust Feb 2005, do the following,
  403. // (i) Find EncryptionAlgorithm, CanonicalizationAlgorithm from inside the "SecondaryParameters" element.
  404. // If found, then promote these as the top-level elements replacing the existing values.
  405. // (ii) Convert the SignWith and EncryptWith elements to the Trust Feb 2005 namespace and drop the KeyWrapAlgorithm
  406. // element.
  407. // make an optimistic check to detect mismatched trust-versions between STS and RP
  408. bool mismatch = (((driver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005) &&
  409. !CollectionContainsElementsWithTrustNamespace(additionalParameters, TrustFeb2005Strings.Namespace)) ||
  410. ((driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) &&
  411. !CollectionContainsElementsWithTrustNamespace(additionalParameters, TrustDec2005Strings.Namespace)));
  412. // if no mismatch, return unmodified collection
  413. if (!mismatch)
  414. {
  415. return tmpCollection;
  416. }
  417. // 2.a
  418. // If we are talking to a Trust 1.3 STS, replace any Feb '05 algorithm parameters with their Trust 1.3 counterparts
  419. if (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13)
  420. {
  421. SecurityStandardsManager trustFeb2005StandardsManager = SecurityStandardsManager.DefaultInstance;
  422. // the following cast is guaranteed to succeed
  423. WSTrustFeb2005.DriverFeb2005 trustFeb2005Driver = (WSTrustFeb2005.DriverFeb2005)trustFeb2005StandardsManager.TrustDriver;
  424. for (int i = 0; i < tmpCollection.Count; i++)
  425. {
  426. string algorithmParameter = string.Empty;
  427. if (trustFeb2005Driver.IsSignWithElement(tmpCollection[i], out algorithmParameter))
  428. {
  429. tmpCollection[i] = driver.CreateSignWithElement(algorithmParameter);
  430. }
  431. else if (trustFeb2005Driver.IsEncryptWithElement(tmpCollection[i], out algorithmParameter))
  432. {
  433. tmpCollection[i] = driver.CreateEncryptWithElement(algorithmParameter);
  434. }
  435. else if (trustFeb2005Driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithmParameter))
  436. {
  437. tmpCollection[i] = driver.CreateEncryptionAlgorithmElement(algorithmParameter);
  438. }
  439. else if (trustFeb2005Driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithmParameter))
  440. {
  441. tmpCollection[i] = driver.CreateCanonicalizationAlgorithmElement(algorithmParameter);
  442. }
  443. }
  444. }
  445. else
  446. {
  447. // 2.b
  448. // We are talking to a Feb 05 STS. Filter out any SecondaryParameters element.
  449. Collection<XmlElement> childrenToPromote = null;
  450. WSSecurityTokenSerializer trust13Serializer = new WSSecurityTokenSerializer(SecurityVersion.WSSecurity11,
  451. TrustVersion.WSTrust13,
  452. SecureConversationVersion.WSSecureConversation13,
  453. true, null, null, null);
  454. SecurityStandardsManager trust13StandardsManager = new SecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12, trust13Serializer);
  455. // the following cast is guaranteed to succeed
  456. WSTrustDec2005.DriverDec2005 trust13Driver = (WSTrustDec2005.DriverDec2005)trust13StandardsManager.TrustDriver;
  457. foreach (XmlElement parameter in tmpCollection)
  458. {
  459. // check if SecondaryParameters is present
  460. if (trust13Driver.IsSecondaryParametersElement(parameter))
  461. {
  462. childrenToPromote = new Collection<XmlElement>();
  463. // walk SecondaryParameters and collect any 'non-standard' children
  464. foreach (XmlNode innerNode in parameter.ChildNodes)
  465. {
  466. XmlElement innerElement = innerNode as XmlElement;
  467. if ((innerElement != null) && CanPromoteToRoot(innerElement, trust13Driver, clientSideClaimTypeRequirementsSpecified))
  468. {
  469. childrenToPromote.Add(innerElement);
  470. }
  471. }
  472. // remove SecondaryParameters element
  473. tmpCollection.Remove(parameter);
  474. // we are done - break out of the loop
  475. break;
  476. }
  477. }
  478. // Probe of standard Trust elements and remember them.
  479. if ((childrenToPromote != null) && (childrenToPromote.Count > 0))
  480. {
  481. XmlElement encryptionElement = null;
  482. string encryptionAlgorithm = String.Empty;
  483. XmlElement canonicalizationElement = null;
  484. string canonicalizationAlgoritm = String.Empty;
  485. XmlElement requiredClaimsElement = null;
  486. Collection<XmlElement> requiredClaims = null;
  487. Collection<XmlElement> processedElements = new Collection<XmlElement>();
  488. foreach (XmlElement e in childrenToPromote)
  489. {
  490. if ((encryptionElement == null) && trust13Driver.IsEncryptionAlgorithmElement(e, out encryptionAlgorithm))
  491. {
  492. encryptionElement = driver.CreateEncryptionAlgorithmElement(encryptionAlgorithm);
  493. processedElements.Add(e);
  494. }
  495. else if ((canonicalizationElement == null) && trust13Driver.IsCanonicalizationAlgorithmElement(e, out canonicalizationAlgoritm))
  496. {
  497. canonicalizationElement = driver.CreateCanonicalizationAlgorithmElement(canonicalizationAlgoritm);
  498. processedElements.Add(e);
  499. }
  500. else if ((requiredClaimsElement == null) && trust13Driver.TryParseRequiredClaimsElement(e, out requiredClaims))
  501. {
  502. requiredClaimsElement = driver.CreateRequiredClaimsElement(requiredClaims);
  503. processedElements.Add(e);
  504. }
  505. }
  506. for (int i = 0; i < processedElements.Count; ++i)
  507. {
  508. childrenToPromote.Remove(processedElements[i]);
  509. }
  510. XmlElement keyWrapAlgorithmElement = null;
  511. // Replace the appropriate elements.
  512. for (int i = 0; i < tmpCollection.Count; ++i)
  513. {
  514. string algorithmParameter;
  515. Collection<XmlElement> reqClaims;
  516. if (trust13Driver.IsSignWithElement(tmpCollection[i], out algorithmParameter))
  517. {
  518. tmpCollection[i] = driver.CreateSignWithElement(algorithmParameter);
  519. }
  520. else if (trust13Driver.IsEncryptWithElement(tmpCollection[i], out algorithmParameter))
  521. {
  522. tmpCollection[i] = driver.CreateEncryptWithElement(algorithmParameter);
  523. }
  524. else if (trust13Driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithmParameter) && (encryptionElement != null))
  525. {
  526. tmpCollection[i] = encryptionElement;
  527. encryptionElement = null;
  528. }
  529. else if (trust13Driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithmParameter) && (canonicalizationElement != null))
  530. {
  531. tmpCollection[i] = canonicalizationElement;
  532. canonicalizationElement = null;
  533. }
  534. else if (trust13Driver.IsKeyWrapAlgorithmElement(tmpCollection[i], out algorithmParameter) && (keyWrapAlgorithmElement == null))
  535. {
  536. keyWrapAlgorithmElement = tmpCollection[i];
  537. }
  538. else if (trust13Driver.TryParseRequiredClaimsElement(tmpCollection[i], out reqClaims) && (requiredClaimsElement != null))
  539. {
  540. tmpCollection[i] = requiredClaimsElement;
  541. requiredClaimsElement = null;
  542. }
  543. }
  544. if (keyWrapAlgorithmElement != null)
  545. {
  546. // Remove KeyWrapAlgorithmElement as this is not define in Trust Feb 2005.
  547. tmpCollection.Remove(keyWrapAlgorithmElement);
  548. }
  549. // Add the remaining elements to the additionaParameters list to the end.
  550. if (encryptionElement != null) tmpCollection.Add(encryptionElement);
  551. if (canonicalizationElement != null) tmpCollection.Add(canonicalizationElement);
  552. if (requiredClaimsElement != null) tmpCollection.Add(requiredClaimsElement);
  553. if (childrenToPromote.Count > 0)
  554. {
  555. // There are some non-standard elements. Just bump them to the top-level element.
  556. for (int i = 0; i < childrenToPromote.Count; ++i)
  557. {
  558. tmpCollection.Add(childrenToPromote[i]);
  559. }
  560. }
  561. }
  562. }
  563. return tmpCollection;
  564. }
  565. private bool CollectionContainsElementsWithTrustNamespace(Collection<XmlElement> collection, string trustNamespace)
  566. {
  567. for (int i = 0; i < collection.Count; i++)
  568. {
  569. if ((collection[i] != null) && (collection[i].NamespaceURI == trustNamespace))
  570. {
  571. return true;
  572. }
  573. }
  574. return false;
  575. }
  576. private bool CanPromoteToRoot(XmlElement innerElement, WSTrustDec2005.DriverDec2005 trust13Driver, bool clientSideClaimTypeRequirementsSpecified)
  577. {
  578. SecurityKeyType dummyOutParamForKeyType;
  579. int dummyOutParamForKeySize;
  580. string dummyStringOutParam;
  581. Collection<XmlElement> dummyOutParamForRequiredClaims = null;
  582. // check if SecondaryParameters has claim requirements specified
  583. if (trust13Driver.TryParseRequiredClaimsElement(innerElement, out dummyOutParamForRequiredClaims))
  584. {
  585. // if client has not specified any claim requirements, promote claim requirements
  586. // in SecondaryParameters to root level (and subsequently fix up the trust namespace)
  587. return !clientSideClaimTypeRequirementsSpecified;
  588. }
  589. // KeySize, KeyType and TokenType were converted to top-level property values when the WSDL was
  590. // imported, so drop it here. We check for EncryptWith and SignWith as these are Client specific algorithm values and we
  591. // don't have to promote the service specified values. KeyWrapAlgorithm was never sent in the RST
  592. // in V1 and hence we are dropping it here as well.
  593. return (!trust13Driver.TryParseKeyTypeElement(innerElement, out dummyOutParamForKeyType) &&
  594. !trust13Driver.TryParseKeySizeElement(innerElement, out dummyOutParamForKeySize) &&
  595. !trust13Driver.TryParseTokenTypeElement(innerElement, out dummyStringOutParam) &&
  596. !trust13Driver.IsSignWithElement(innerElement, out dummyStringOutParam) &&
  597. !trust13Driver.IsEncryptWithElement(innerElement, out dummyStringOutParam) &&
  598. !trust13Driver.IsKeyWrapAlgorithmElement(innerElement, out dummyStringOutParam));
  599. }
  600. internal void AddAlgorithmParameters(SecurityAlgorithmSuite algorithmSuite, SecurityStandardsManager standardsManager, SecurityKeyType issuedKeyType)
  601. {
  602. this.additionalRequestParameters.Insert(0, standardsManager.TrustDriver.CreateEncryptionAlgorithmElement(algorithmSuite.DefaultEncryptionAlgorithm));
  603. this.additionalRequestParameters.Insert(0, standardsManager.TrustDriver.CreateCanonicalizationAlgorithmElement(algorithmSuite.DefaultCanonicalizationAlgorithm));
  604. if (this.keyType == SecurityKeyType.BearerKey)
  605. {
  606. // As the client does not have a proof token in the Bearer case
  607. // we don't have any specific algorithms to request for.
  608. return;
  609. }
  610. string signWithAlgorithm = (this.keyType == SecurityKeyType.SymmetricKey) ? algorithmSuite.DefaultSymmetricSignatureAlgorithm : algorithmSuite.DefaultAsymmetricSignatureAlgorithm;
  611. this.additionalRequestParameters.Insert(0, standardsManager.TrustDriver.CreateSignWithElement(signWithAlgorithm));
  612. string encryptWithAlgorithm;
  613. if (issuedKeyType == SecurityKeyType.SymmetricKey)
  614. {
  615. encryptWithAlgorithm = algorithmSuite.DefaultEncryptionAlgorithm;
  616. }
  617. else
  618. {
  619. encryptWithAlgorithm = algorithmSuite.DefaultAsymmetricKeyWrapAlgorithm;
  620. }
  621. this.additionalRequestParameters.Insert(0, standardsManager.TrustDriver.CreateEncryptWithElement(encryptWithAlgorithm));
  622. if (standardsManager.TrustVersion != TrustVersion.WSTrustFeb2005)
  623. {
  624. this.additionalRequestParameters.Insert(0, ((WSTrustDec2005.DriverDec2005)standardsManager.TrustDriver).CreateKeyWrapAlgorithmElement(algorithmSuite.DefaultAsymmetricKeyWrapAlgorithm));
  625. }
  626. return;
  627. }
  628. internal bool DoAlgorithmsMatch(SecurityAlgorithmSuite algorithmSuite, SecurityStandardsManager standardsManager, out Collection<XmlElement> otherRequestParameters)
  629. {
  630. bool doesSignWithAlgorithmMatch = false;
  631. bool doesEncryptWithAlgorithmMatch = false;
  632. bool doesEncryptionAlgorithmMatch = false;
  633. bool doesCanonicalizationAlgorithmMatch = false;
  634. bool doesKeyWrapAlgorithmMatch = false;
  635. otherRequestParameters = new Collection<XmlElement>();
  636. bool trustNormalizationPerformed = false;
  637. Collection<XmlElement> trustVersionNormalizedParameterCollection;
  638. // For Trust 1.3 we move all the additional parameters into the secondaryParameters
  639. // element. So the list contains just one element called SecondaryParameters that
  640. // contains all the other elements as child elements.
  641. if ((standardsManager.TrustVersion == TrustVersion.WSTrust13) &&
  642. (this.AdditionalRequestParameters.Count == 1) &&
  643. (((WSTrustDec2005.DriverDec2005)standardsManager.TrustDriver).IsSecondaryParametersElement(this.AdditionalRequestParameters[0])))
  644. {
  645. trustNormalizationPerformed = true;
  646. trustVersionNormalizedParameterCollection = new Collection<XmlElement>();
  647. foreach (XmlElement innerElement in this.AdditionalRequestParameters[0])
  648. {
  649. trustVersionNormalizedParameterCollection.Add(innerElement);
  650. }
  651. }
  652. else
  653. {
  654. trustVersionNormalizedParameterCollection = this.AdditionalRequestParameters;
  655. }
  656. for (int i = 0; i < trustVersionNormalizedParameterCollection.Count; i++)
  657. {
  658. string algorithm;
  659. XmlElement element = trustVersionNormalizedParameterCollection[i];
  660. if (standardsManager.TrustDriver.IsCanonicalizationAlgorithmElement(element, out algorithm))
  661. {
  662. if (algorithmSuite.DefaultCanonicalizationAlgorithm != algorithm)
  663. {
  664. return false;
  665. }
  666. doesCanonicalizationAlgorithmMatch = true;
  667. }
  668. else if (standardsManager.TrustDriver.IsSignWithElement(element, out algorithm))
  669. {
  670. if ((this.keyType == SecurityKeyType.SymmetricKey && algorithm != algorithmSuite.DefaultSymmetricSignatureAlgorithm)
  671. || (this.keyType == SecurityKeyType.AsymmetricKey && algorithm != algorithmSuite.DefaultAsymmetricSignatureAlgorithm))
  672. {
  673. return false;
  674. }
  675. doesSignWithAlgorithmMatch = true;
  676. }
  677. else if (standardsManager.TrustDriver.IsEncryptWithElement(element, out algorithm))
  678. {
  679. if ((this.keyType == SecurityKeyType.SymmetricKey && algorithm != algorithmSuite.DefaultEncryptionAlgorithm)
  680. || (this.keyType == SecurityKeyType.AsymmetricKey && algorithm != algorithmSuite.DefaultAsymmetricKeyWrapAlgorithm))
  681. {
  682. return false;
  683. }
  684. doesEncryptWithAlgorithmMatch = true;
  685. }
  686. else if (standardsManager.TrustDriver.IsEncryptionAlgorithmElement(element, out algorithm))
  687. {
  688. if (algorithm != algorithmSuite.DefaultEncryptionAlgorithm)
  689. {
  690. return false;
  691. }
  692. doesEncryptionAlgorithmMatch = true;
  693. }
  694. else if (standardsManager.TrustDriver.IsKeyWrapAlgorithmElement(element, out algorithm))
  695. {
  696. if (algorithm != algorithmSuite.DefaultAsymmetricKeyWrapAlgorithm)
  697. {
  698. return false;
  699. }
  700. doesKeyWrapAlgorithmMatch = true;
  701. }
  702. else
  703. {
  704. otherRequestParameters.Add(element);
  705. }
  706. }
  707. // Undo normalization if performed
  708. // move all back into secondaryParameters
  709. if (trustNormalizationPerformed)
  710. {
  711. otherRequestParameters = this.AdditionalRequestParameters;
  712. }
  713. if (this.keyType == SecurityKeyType.BearerKey)
  714. {
  715. // As the client does not have a proof token in the Bearer case
  716. // we don't have any specific algorithms to request for.
  717. return true;
  718. }
  719. if (standardsManager.TrustVersion == TrustVersion.WSTrustFeb2005)
  720. {
  721. // For V1 compatibility check all algorithms
  722. return (doesSignWithAlgorithmMatch && doesCanonicalizationAlgorithmMatch && doesEncryptionAlgorithmMatch && doesEncryptWithAlgorithmMatch);
  723. }
  724. else
  725. {
  726. return (doesSignWithAlgorithmMatch && doesCanonicalizationAlgorithmMatch && doesEncryptionAlgorithmMatch && doesEncryptWithAlgorithmMatch && doesKeyWrapAlgorithmMatch);
  727. }
  728. }
  729. internal static IssuedSecurityTokenParameters CreateInfoCardParameters(SecurityStandardsManager standardsManager, SecurityAlgorithmSuite algorithm)
  730. {
  731. IssuedSecurityTokenParameters result = new IssuedSecurityTokenParameters(SecurityXXX2005Strings.SamlTokenType);
  732. result.KeyType = SecurityKeyType.AsymmetricKey;
  733. result.ClaimTypeRequirements.Add(new ClaimTypeRequirement(wsidPPIClaim));
  734. result.IssuerAddress = null;
  735. result.AddAlgorithmParameters(algorithm, standardsManager, result.KeyType);
  736. return result;
  737. }
  738. internal static bool IsInfoCardParameters(IssuedSecurityTokenParameters parameters, SecurityStandardsManager standardsManager)
  739. {
  740. if (parameters == null)
  741. return false;
  742. if (parameters.TokenType != SecurityXXX2005Strings.SamlTokenType)
  743. return false;
  744. if (parameters.KeyType != SecurityKeyType.AsymmetricKey)
  745. return false;
  746. if (parameters.ClaimTypeRequirements.Count == 1)
  747. {
  748. ClaimTypeRequirement claimTypeRequirement = parameters.ClaimTypeRequirements[0] as ClaimTypeRequirement;
  749. if (claimTypeRequirement == null)
  750. return false;
  751. if (claimTypeRequirement.ClaimType != wsidPPIClaim)
  752. return false;
  753. }
  754. else if ((parameters.AdditionalRequestParameters != null) && (parameters.AdditionalRequestParameters.Count > 0))
  755. {
  756. // Check the AdditionalRequest Parameters to see if ClaimTypeRequirements got imported there.
  757. bool claimTypeRequirementMatched = false;
  758. XmlElement claimTypeRequirement = GetClaimTypeRequirement(parameters.AdditionalRequestParameters, standardsManager);
  759. if (claimTypeRequirement != null && claimTypeRequirement.ChildNodes.Count == 1)
  760. {
  761. XmlElement claimTypeElement = claimTypeRequirement.ChildNodes[0] as XmlElement;
  762. if (claimTypeElement != null)
  763. {
  764. XmlNode claimType = claimTypeElement.Attributes.GetNamedItem("Uri");
  765. if (claimType != null && claimType.Value == wsidPPIClaim)
  766. {
  767. claimTypeRequirementMatched = true;
  768. }
  769. }
  770. }
  771. if (!claimTypeRequirementMatched)
  772. {
  773. return false;
  774. }
  775. }
  776. else
  777. {
  778. return false;
  779. }
  780. if (parameters.IssuerAddress != null)
  781. return false;
  782. if (parameters.AlternativeIssuerEndpoints != null && parameters.AlternativeIssuerEndpoints.Count > 0)
  783. {
  784. return false;
  785. }
  786. return true;
  787. }
  788. // The method walks through the entire set of AdditionalRequestParameters and return the Claims Type requirement alone.
  789. internal static XmlElement GetClaimTypeRequirement(Collection<XmlElement> additionalRequestParameters, SecurityStandardsManager standardsManager)
  790. {
  791. foreach (XmlElement requestParameter in additionalRequestParameters)
  792. {
  793. if ((requestParameter.LocalName == ((System.ServiceModel.Security.WSTrust.Driver)standardsManager.TrustDriver).DriverDictionary.Claims.Value) &&
  794. (requestParameter.NamespaceURI == ((System.ServiceModel.Security.WSTrust.Driver)standardsManager.TrustDriver).DriverDictionary.Namespace.Value))
  795. {
  796. return requestParameter;
  797. }
  798. if ((requestParameter.LocalName == DXD.TrustDec2005Dictionary.SecondaryParameters.Value) &&
  799. (requestParameter.NamespaceURI == DXD.TrustDec2005Dictionary.Namespace.Value))
  800. {
  801. Collection<XmlElement> secondaryParameters = new Collection<XmlElement>();
  802. foreach (XmlNode node in requestParameter.ChildNodes)
  803. {
  804. XmlElement nodeAsElement = node as XmlElement;
  805. if (nodeAsElement != null)
  806. {
  807. secondaryParameters.Add(nodeAsElement);
  808. }
  809. }
  810. XmlElement claimTypeRequirement = GetClaimTypeRequirement(secondaryParameters, standardsManager);
  811. if (claimTypeRequirement != null)
  812. {
  813. return claimTypeRequirement;
  814. }
  815. }
  816. }
  817. return null;
  818. }
  819. public override string ToString()
  820. {
  821. StringBuilder sb = new StringBuilder();
  822. sb.AppendLine(base.ToString());
  823. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "TokenType: {0}", this.tokenType == null ? "null" : this.tokenType));
  824. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "KeyType: {0}", this.keyType.ToString()));
  825. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "KeySize: {0}", this.keySize.ToString(CultureInfo.InvariantCulture)));
  826. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IssuerAddress: {0}", this.issuerAddress == null ? "null" : this.issuerAddress.ToString()));
  827. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IssuerMetadataAddress: {0}", this.issuerMetadataAddress == null ? "null" : this.issuerMetadataAddress.ToString()));
  828. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "DefaultMessgeSecurityVersion: {0}", this.defaultMessageSecurityVersion == null ? "null" : this.defaultMessageSecurityVersion.ToString()));
  829. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "UseStrTransform: {0}", this.useStrTransform.ToString()));
  830. if (this.issuerBinding == null)
  831. {
  832. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IssuerBinding: null"));
  833. }
  834. else
  835. {
  836. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "IssuerBinding:"));
  837. BindingElementCollection bindingElements = this.issuerBinding.CreateBindingElements();
  838. for (int i = 0; i < bindingElements.Count; i++)
  839. {
  840. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, " BindingElement[{0}]:", i.ToString(CultureInfo.InvariantCulture)));
  841. sb.AppendLine(" " + bindingElements[i].ToString().Trim().Replace("\n", "\n "));
  842. }
  843. }
  844. if (this.claimTypeRequirements.Count == 0)
  845. {
  846. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "ClaimTypeRequirements: none"));
  847. }
  848. else
  849. {
  850. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "ClaimTypeRequirements:"));
  851. for (int i = 0; i < this.claimTypeRequirements.Count; i++)
  852. {
  853. sb.AppendLine(String.Format(CultureInfo.InvariantCulture, " {0}, optional={1}", this.claimTypeRequirements[i].ClaimType, this.claimTypeRequirements[i].IsOptional));
  854. }
  855. }
  856. return sb.ToString().Trim();
  857. }
  858. protected internal override void InitializeSecurityTokenRequirement(SecurityTokenRequirement requirement)
  859. {
  860. requirement.TokenType = this.TokenType;
  861. requirement.RequireCryptographicToken = true;
  862. requirement.KeyType = this.KeyType;
  863. ServiceModelSecurityTokenRequirement serviceModelSecurityTokenRequirement = requirement as ServiceModelSecurityTokenRequirement;
  864. if (serviceModelSecurityTokenRequirement != null)
  865. {
  866. serviceModelSecurityTokenRequirement.DefaultMessageSecurityVersion = this.DefaultMessageSecurityVersion;
  867. }
  868. else
  869. {
  870. requirement.Properties[ServiceModelSecurityTokenRequirement.DefaultMessageSecurityVersionProperty] = this.DefaultMessageSecurityVersion;
  871. }
  872. if (this.KeySize > 0)
  873. {
  874. requirement.KeySize = this.KeySize;
  875. }
  876. requirement.Properties[ServiceModelSecurityTokenRequirement.IssuerAddressProperty] = this.IssuerAddress;
  877. if (this.IssuerBinding != null)
  878. {
  879. requirement.Properties[ServiceModelSecurityTokenRequirement.IssuerBindingProperty] = this.IssuerBinding;
  880. }
  881. requirement.Properties[ServiceModelSecurityTokenRequirement.IssuedSecurityTokenParametersProperty] = this.Clone();
  882. }
  883. }
  884. }