WSTrust.cs 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Security
  5. {
  6. using System;
  7. using System.ServiceModel;
  8. using System.ServiceModel.Description;
  9. using System.ServiceModel.Dispatcher;
  10. using System.Collections;
  11. using System.Collections.Generic;
  12. using System.Collections.ObjectModel;
  13. using System.Diagnostics;
  14. using System.Globalization;
  15. using System.IO;
  16. using System.Text;
  17. using System.Threading;
  18. using System.Xml;
  19. using System.Runtime;
  20. using System.Security.Cryptography;
  21. using System.IdentityModel.Claims;
  22. using System.IdentityModel.Policy;
  23. using System.IdentityModel.Selectors;
  24. using System.IdentityModel.Tokens;
  25. using System.Security.Cryptography.X509Certificates;
  26. using System.ServiceModel.Security.Tokens;
  27. using HexBinary = System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary;
  28. using System.ServiceModel.Channels;
  29. using System.ServiceModel.Security;
  30. using System.Runtime.Serialization;
  31. using KeyIdentifierEntry = WSSecurityTokenSerializer.KeyIdentifierEntry;
  32. using KeyIdentifierClauseEntry = WSSecurityTokenSerializer.KeyIdentifierClauseEntry;
  33. using TokenEntry = WSSecurityTokenSerializer.TokenEntry;
  34. using StrEntry = WSSecurityTokenSerializer.StrEntry;
  35. using Psha1DerivedKeyGenerator = System.IdentityModel.Psha1DerivedKeyGenerator;
  36. abstract class WSTrust : WSSecurityTokenSerializer.SerializerEntries
  37. {
  38. WSSecurityTokenSerializer tokenSerializer;
  39. public WSTrust(WSSecurityTokenSerializer tokenSerializer)
  40. {
  41. this.tokenSerializer = tokenSerializer;
  42. }
  43. public WSSecurityTokenSerializer WSSecurityTokenSerializer
  44. {
  45. get { return this.tokenSerializer; }
  46. }
  47. public abstract TrustDictionary SerializerDictionary
  48. {
  49. get;
  50. }
  51. public override void PopulateTokenEntries(IList<TokenEntry> tokenEntryList)
  52. {
  53. tokenEntryList.Add(new BinarySecretTokenEntry(this));
  54. }
  55. class BinarySecretTokenEntry : TokenEntry
  56. {
  57. WSTrust parent;
  58. TrustDictionary otherDictionary;
  59. public BinarySecretTokenEntry(WSTrust parent)
  60. {
  61. this.parent = parent;
  62. this.otherDictionary = null;
  63. if (parent.SerializerDictionary is TrustDec2005Dictionary)
  64. {
  65. this.otherDictionary = XD.TrustFeb2005Dictionary;
  66. }
  67. if (parent.SerializerDictionary is TrustFeb2005Dictionary)
  68. {
  69. this.otherDictionary = DXD.TrustDec2005Dictionary;
  70. }
  71. // always set it, so we don't have to worry about null
  72. if (this.otherDictionary == null)
  73. this.otherDictionary = this.parent.SerializerDictionary;
  74. }
  75. protected override XmlDictionaryString LocalName { get { return parent.SerializerDictionary.BinarySecret; } }
  76. protected override XmlDictionaryString NamespaceUri { get { return parent.SerializerDictionary.Namespace; } }
  77. protected override Type[] GetTokenTypesCore() { return new Type[] { typeof(BinarySecretSecurityToken) }; }
  78. public override string TokenTypeUri { get { return null; } }
  79. protected override string ValueTypeUri { get { return null; } }
  80. public override bool CanReadTokenCore(XmlElement element)
  81. {
  82. string valueTypeUri = null;
  83. if (element.HasAttribute(SecurityJan2004Strings.ValueType, null))
  84. {
  85. valueTypeUri = element.GetAttribute(SecurityJan2004Strings.ValueType, null);
  86. }
  87. return element.LocalName == LocalName.Value && (element.NamespaceURI == NamespaceUri.Value || element.NamespaceURI == this.otherDictionary.Namespace.Value) && valueTypeUri == this.ValueTypeUri;
  88. }
  89. public override bool CanReadTokenCore(XmlDictionaryReader reader)
  90. {
  91. return (reader.IsStartElement(this.LocalName, this.NamespaceUri) || reader.IsStartElement(this.LocalName, this.otherDictionary.Namespace)) &&
  92. reader.GetAttribute(XD.SecurityJan2004Dictionary.ValueType, null) == this.ValueTypeUri;
  93. }
  94. public override SecurityKeyIdentifierClause CreateKeyIdentifierClauseFromTokenXmlCore(XmlElement issuedTokenXml,
  95. SecurityTokenReferenceStyle tokenReferenceStyle)
  96. {
  97. TokenReferenceStyleHelper.Validate(tokenReferenceStyle);
  98. switch (tokenReferenceStyle)
  99. {
  100. case SecurityTokenReferenceStyle.Internal:
  101. return CreateDirectReference(issuedTokenXml, UtilityStrings.IdAttribute, UtilityStrings.Namespace, typeof(GenericXmlSecurityToken));
  102. case SecurityTokenReferenceStyle.External:
  103. // Binary Secret tokens aren't referred to externally
  104. return null;
  105. default:
  106. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("tokenReferenceStyle"));
  107. }
  108. }
  109. public override SecurityToken ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)
  110. {
  111. string secretType = reader.GetAttribute(XD.SecurityJan2004Dictionary.TypeAttribute, null);
  112. string id = reader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);
  113. bool isNonce = false;
  114. if (secretType != null && secretType.Length > 0)
  115. {
  116. if (secretType == parent.SerializerDictionary.NonceBinarySecret.Value || secretType == otherDictionary.NonceBinarySecret.Value)
  117. {
  118. isNonce = true;
  119. }
  120. else if (secretType != parent.SerializerDictionary.SymmetricKeyBinarySecret.Value && secretType != otherDictionary.SymmetricKeyBinarySecret.Value)
  121. {
  122. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnexpectedBinarySecretType, parent.SerializerDictionary.SymmetricKeyBinarySecret.Value, secretType)));
  123. }
  124. }
  125. byte[] secret = reader.ReadElementContentAsBase64();
  126. if (isNonce)
  127. {
  128. return new NonceToken(id, secret);
  129. }
  130. else
  131. {
  132. return new BinarySecretSecurityToken(id, secret);
  133. }
  134. }
  135. public override void WriteTokenCore(XmlDictionaryWriter writer, SecurityToken token)
  136. {
  137. BinarySecretSecurityToken simpleToken = token as BinarySecretSecurityToken;
  138. byte[] secret = simpleToken.GetKeyBytes();
  139. writer.WriteStartElement(parent.SerializerDictionary.Prefix.Value, parent.SerializerDictionary.BinarySecret, parent.SerializerDictionary.Namespace);
  140. if (simpleToken.Id != null)
  141. {
  142. writer.WriteAttributeString(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace, simpleToken.Id);
  143. }
  144. if (token is NonceToken)
  145. {
  146. writer.WriteAttributeString(XD.SecurityJan2004Dictionary.TypeAttribute, null, parent.SerializerDictionary.NonceBinarySecret.Value);
  147. }
  148. writer.WriteBase64(secret, 0, secret.Length);
  149. writer.WriteEndElement();
  150. }
  151. }
  152. public abstract class Driver : TrustDriver
  153. {
  154. static readonly string base64Uri = SecurityJan2004Strings.EncodingTypeValueBase64Binary;
  155. static readonly string hexBinaryUri = SecurityJan2004Strings.EncodingTypeValueHexBinary;
  156. SecurityStandardsManager standardsManager;
  157. List<SecurityTokenAuthenticator> entropyAuthenticators;
  158. public Driver(SecurityStandardsManager standardsManager)
  159. {
  160. this.standardsManager = standardsManager;
  161. this.entropyAuthenticators = new List<SecurityTokenAuthenticator>(2);
  162. }
  163. public abstract TrustDictionary DriverDictionary
  164. {
  165. get;
  166. }
  167. public override XmlDictionaryString RequestSecurityTokenAction
  168. {
  169. get
  170. {
  171. return DriverDictionary.RequestSecurityTokenIssuance;
  172. }
  173. }
  174. public override XmlDictionaryString RequestSecurityTokenResponseAction
  175. {
  176. get
  177. {
  178. return DriverDictionary.RequestSecurityTokenIssuanceResponse;
  179. }
  180. }
  181. public override string RequestTypeIssue
  182. {
  183. get
  184. {
  185. return DriverDictionary.RequestTypeIssue.Value;
  186. }
  187. }
  188. public override string ComputedKeyAlgorithm
  189. {
  190. get { return DriverDictionary.Psha1ComputedKeyUri.Value; }
  191. }
  192. public override SecurityStandardsManager StandardsManager
  193. {
  194. get
  195. {
  196. return this.standardsManager;
  197. }
  198. }
  199. public override XmlDictionaryString Namespace
  200. {
  201. get { return DriverDictionary.Namespace; }
  202. }
  203. public override RequestSecurityToken CreateRequestSecurityToken(XmlReader xmlReader)
  204. {
  205. XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
  206. reader.MoveToStartElement(DriverDictionary.RequestSecurityToken, DriverDictionary.Namespace);
  207. string context = null;
  208. string tokenTypeUri = null;
  209. string requestType = null;
  210. int keySize = 0;
  211. XmlDocument doc = new XmlDocument();
  212. XmlElement rstXml = (doc.ReadNode(reader) as XmlElement);
  213. SecurityKeyIdentifierClause renewTarget = null;
  214. SecurityKeyIdentifierClause closeTarget = null;
  215. for (int i = 0; i < rstXml.Attributes.Count; ++i)
  216. {
  217. XmlAttribute attr = rstXml.Attributes[i];
  218. if (attr.LocalName == DriverDictionary.Context.Value)
  219. {
  220. context = attr.Value;
  221. }
  222. }
  223. for (int i = 0; i < rstXml.ChildNodes.Count; ++i)
  224. {
  225. XmlElement child = (rstXml.ChildNodes[i] as XmlElement);
  226. if (child != null)
  227. {
  228. if (child.LocalName == DriverDictionary.TokenType.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  229. tokenTypeUri = XmlHelper.ReadTextElementAsTrimmedString(child);
  230. else if (child.LocalName == DriverDictionary.RequestType.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  231. requestType = XmlHelper.ReadTextElementAsTrimmedString(child);
  232. else if (child.LocalName == DriverDictionary.KeySize.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  233. keySize = Int32.Parse(XmlHelper.ReadTextElementAsTrimmedString(child), NumberFormatInfo.InvariantInfo);
  234. }
  235. }
  236. ReadTargets(rstXml, out renewTarget, out closeTarget);
  237. RequestSecurityToken rst = new RequestSecurityToken(standardsManager, rstXml, context, tokenTypeUri, requestType, keySize, renewTarget, closeTarget);
  238. return rst;
  239. }
  240. System.IdentityModel.XmlBuffer GetIssuedTokenBuffer(System.IdentityModel.XmlBuffer rstrBuffer)
  241. {
  242. System.IdentityModel.XmlBuffer issuedTokenBuffer = null;
  243. using (XmlDictionaryReader reader = rstrBuffer.GetReader(0))
  244. {
  245. reader.ReadFullStartElement();
  246. while (reader.IsStartElement())
  247. {
  248. if (reader.IsStartElement(this.DriverDictionary.RequestedSecurityToken, this.DriverDictionary.Namespace))
  249. {
  250. reader.ReadStartElement();
  251. reader.MoveToContent();
  252. issuedTokenBuffer = new System.IdentityModel.XmlBuffer(Int32.MaxValue);
  253. using (XmlDictionaryWriter writer = issuedTokenBuffer.OpenSection(reader.Quotas))
  254. {
  255. writer.WriteNode(reader, false);
  256. issuedTokenBuffer.CloseSection();
  257. issuedTokenBuffer.Close();
  258. }
  259. reader.ReadEndElement();
  260. break;
  261. }
  262. else
  263. {
  264. reader.Skip();
  265. }
  266. }
  267. }
  268. return issuedTokenBuffer;
  269. }
  270. public override RequestSecurityTokenResponse CreateRequestSecurityTokenResponse(XmlReader xmlReader)
  271. {
  272. if (xmlReader == null)
  273. {
  274. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("xmlReader");
  275. }
  276. XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
  277. if (reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponse, DriverDictionary.Namespace) == false)
  278. {
  279. XmlHelper.OnRequiredElementMissing(DriverDictionary.RequestSecurityTokenResponse.Value, DriverDictionary.Namespace.Value);
  280. }
  281. System.IdentityModel.XmlBuffer rstrBuffer = new System.IdentityModel.XmlBuffer(Int32.MaxValue);
  282. using (XmlDictionaryWriter writer = rstrBuffer.OpenSection(reader.Quotas))
  283. {
  284. writer.WriteNode(reader, false);
  285. rstrBuffer.CloseSection();
  286. rstrBuffer.Close();
  287. }
  288. XmlDocument doc = new XmlDocument();
  289. XmlElement rstrXml;
  290. using (XmlReader reader2 = rstrBuffer.GetReader(0))
  291. {
  292. rstrXml = (doc.ReadNode(reader2) as XmlElement);
  293. }
  294. System.IdentityModel.XmlBuffer issuedTokenBuffer = GetIssuedTokenBuffer(rstrBuffer);
  295. string context = null;
  296. string tokenTypeUri = null;
  297. int keySize = 0;
  298. SecurityKeyIdentifierClause requestedAttachedReference = null;
  299. SecurityKeyIdentifierClause requestedUnattachedReference = null;
  300. bool computeKey = false;
  301. DateTime created = DateTime.UtcNow;
  302. DateTime expires = SecurityUtils.MaxUtcDateTime;
  303. bool isRequestedTokenClosed = false;
  304. for (int i = 0; i < rstrXml.Attributes.Count; ++i)
  305. {
  306. XmlAttribute attr = rstrXml.Attributes[i];
  307. if (attr.LocalName == DriverDictionary.Context.Value)
  308. {
  309. context = attr.Value;
  310. }
  311. }
  312. for (int i = 0; i < rstrXml.ChildNodes.Count; ++i)
  313. {
  314. XmlElement child = (rstrXml.ChildNodes[i] as XmlElement);
  315. if (child != null)
  316. {
  317. if (child.LocalName == DriverDictionary.TokenType.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  318. tokenTypeUri = XmlHelper.ReadTextElementAsTrimmedString(child);
  319. else if (child.LocalName == DriverDictionary.KeySize.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  320. keySize = Int32.Parse(XmlHelper.ReadTextElementAsTrimmedString(child), NumberFormatInfo.InvariantInfo);
  321. else if (child.LocalName == DriverDictionary.RequestedProofToken.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  322. {
  323. XmlElement proofXml = XmlHelper.GetChildElement(child);
  324. if (proofXml.LocalName == DriverDictionary.ComputedKey.Value && proofXml.NamespaceURI == DriverDictionary.Namespace.Value)
  325. {
  326. string computedKeyAlgorithm = XmlHelper.ReadTextElementAsTrimmedString(proofXml);
  327. if (computedKeyAlgorithm != this.DriverDictionary.Psha1ComputedKeyUri.Value)
  328. {
  329. throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.UnknownComputedKeyAlgorithm, computedKeyAlgorithm)));
  330. }
  331. computeKey = true;
  332. }
  333. }
  334. else if (child.LocalName == DriverDictionary.Lifetime.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  335. {
  336. XmlElement createdXml = XmlHelper.GetChildElement(child, UtilityStrings.CreatedElement, UtilityStrings.Namespace);
  337. if (createdXml != null)
  338. {
  339. created = DateTime.ParseExact(XmlHelper.ReadTextElementAsTrimmedString(createdXml),
  340. WSUtilitySpecificationVersion.AcceptedDateTimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
  341. }
  342. XmlElement expiresXml = XmlHelper.GetChildElement(child, UtilityStrings.ExpiresElement, UtilityStrings.Namespace);
  343. if (expiresXml != null)
  344. {
  345. expires = DateTime.ParseExact(XmlHelper.ReadTextElementAsTrimmedString(expiresXml),
  346. WSUtilitySpecificationVersion.AcceptedDateTimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
  347. }
  348. }
  349. }
  350. }
  351. isRequestedTokenClosed = ReadRequestedTokenClosed(rstrXml);
  352. ReadReferences(rstrXml, out requestedAttachedReference, out requestedUnattachedReference);
  353. return new RequestSecurityTokenResponse(standardsManager, rstrXml, context, tokenTypeUri, keySize, requestedAttachedReference, requestedUnattachedReference,
  354. computeKey, created, expires, isRequestedTokenClosed, issuedTokenBuffer);
  355. }
  356. public override RequestSecurityTokenResponseCollection CreateRequestSecurityTokenResponseCollection(XmlReader xmlReader)
  357. {
  358. XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
  359. List<RequestSecurityTokenResponse> rstrCollection = new List<RequestSecurityTokenResponse>(2);
  360. string rootName = reader.Name;
  361. reader.ReadStartElement(DriverDictionary.RequestSecurityTokenResponseCollection, DriverDictionary.Namespace);
  362. while (reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponse.Value, DriverDictionary.Namespace.Value))
  363. {
  364. RequestSecurityTokenResponse rstr = this.CreateRequestSecurityTokenResponse(reader);
  365. rstrCollection.Add(rstr);
  366. }
  367. reader.ReadEndElement();
  368. if (rstrCollection.Count == 0)
  369. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.NoRequestSecurityTokenResponseElements)));
  370. return new RequestSecurityTokenResponseCollection(rstrCollection.AsReadOnly(), this.StandardsManager);
  371. }
  372. XmlElement GetAppliesToElement(XmlElement rootElement)
  373. {
  374. if (rootElement == null)
  375. {
  376. return null;
  377. }
  378. for (int i = 0; i < rootElement.ChildNodes.Count; ++i)
  379. {
  380. XmlElement elem = (rootElement.ChildNodes[i] as XmlElement);
  381. if (elem != null)
  382. {
  383. if (elem.LocalName == DriverDictionary.AppliesTo.Value && elem.NamespaceURI == Namespaces.WSPolicy)
  384. {
  385. return elem;
  386. }
  387. }
  388. }
  389. return null;
  390. }
  391. T GetAppliesTo<T>(XmlElement rootXml, XmlObjectSerializer serializer)
  392. {
  393. XmlElement appliesToElement = GetAppliesToElement(rootXml);
  394. if (appliesToElement != null)
  395. {
  396. using (XmlReader reader = new XmlNodeReader(appliesToElement))
  397. {
  398. reader.ReadStartElement();
  399. lock (serializer)
  400. {
  401. return (T)serializer.ReadObject(reader);
  402. }
  403. }
  404. }
  405. else
  406. {
  407. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoAppliesToPresent)));
  408. }
  409. }
  410. public override T GetAppliesTo<T>(RequestSecurityToken rst, XmlObjectSerializer serializer)
  411. {
  412. if (rst == null)
  413. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
  414. return GetAppliesTo<T>(rst.RequestSecurityTokenXml, serializer);
  415. }
  416. public override T GetAppliesTo<T>(RequestSecurityTokenResponse rstr, XmlObjectSerializer serializer)
  417. {
  418. if (rstr == null)
  419. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
  420. return GetAppliesTo<T>(rstr.RequestSecurityTokenResponseXml, serializer);
  421. }
  422. public override bool IsAppliesTo(string localName, string namespaceUri)
  423. {
  424. return (localName == DriverDictionary.AppliesTo.Value && namespaceUri == Namespaces.WSPolicy);
  425. }
  426. void GetAppliesToQName(XmlElement rootElement, out string localName, out string namespaceUri)
  427. {
  428. localName = namespaceUri = null;
  429. XmlElement appliesToElement = GetAppliesToElement(rootElement);
  430. if (appliesToElement != null)
  431. {
  432. using (XmlReader reader = new XmlNodeReader(appliesToElement))
  433. {
  434. reader.ReadStartElement();
  435. reader.MoveToContent();
  436. localName = reader.LocalName;
  437. namespaceUri = reader.NamespaceURI;
  438. }
  439. }
  440. }
  441. public override void GetAppliesToQName(RequestSecurityToken rst, out string localName, out string namespaceUri)
  442. {
  443. if (rst == null)
  444. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
  445. GetAppliesToQName(rst.RequestSecurityTokenXml, out localName, out namespaceUri);
  446. }
  447. public override void GetAppliesToQName(RequestSecurityTokenResponse rstr, out string localName, out string namespaceUri)
  448. {
  449. if (rstr == null)
  450. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
  451. GetAppliesToQName(rstr.RequestSecurityTokenResponseXml, out localName, out namespaceUri);
  452. }
  453. public override byte[] GetAuthenticator(RequestSecurityTokenResponse rstr)
  454. {
  455. if (rstr != null && rstr.RequestSecurityTokenResponseXml != null && rstr.RequestSecurityTokenResponseXml.ChildNodes != null)
  456. {
  457. for (int i = 0; i < rstr.RequestSecurityTokenResponseXml.ChildNodes.Count; ++i)
  458. {
  459. XmlElement element = rstr.RequestSecurityTokenResponseXml.ChildNodes[i] as XmlElement;
  460. if (element != null)
  461. {
  462. if (element.LocalName == DriverDictionary.Authenticator.Value && element.NamespaceURI == DriverDictionary.Namespace.Value)
  463. {
  464. XmlElement combinedHashElement = XmlHelper.GetChildElement(element);
  465. if (combinedHashElement.LocalName == DriverDictionary.CombinedHash.Value && combinedHashElement.NamespaceURI == DriverDictionary.Namespace.Value)
  466. {
  467. string authenticatorString = XmlHelper.ReadTextElementAsTrimmedString(combinedHashElement);
  468. return Convert.FromBase64String(authenticatorString);
  469. }
  470. }
  471. }
  472. }
  473. }
  474. return null;
  475. }
  476. public override BinaryNegotiation GetBinaryNegotiation(RequestSecurityTokenResponse rstr)
  477. {
  478. if (rstr == null)
  479. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
  480. return GetBinaryNegotiation(rstr.RequestSecurityTokenResponseXml);
  481. }
  482. public override BinaryNegotiation GetBinaryNegotiation(RequestSecurityToken rst)
  483. {
  484. if (rst == null)
  485. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
  486. return GetBinaryNegotiation(rst.RequestSecurityTokenXml);
  487. }
  488. BinaryNegotiation GetBinaryNegotiation(XmlElement rootElement)
  489. {
  490. if (rootElement == null)
  491. {
  492. return null;
  493. }
  494. for (int i = 0; i < rootElement.ChildNodes.Count; ++i)
  495. {
  496. XmlElement elem = rootElement.ChildNodes[i] as XmlElement;
  497. if (elem != null)
  498. {
  499. if (elem.LocalName == DriverDictionary.BinaryExchange.Value && elem.NamespaceURI == DriverDictionary.Namespace.Value)
  500. {
  501. return ReadBinaryNegotiation(elem);
  502. }
  503. }
  504. }
  505. return null;
  506. }
  507. public override SecurityToken GetEntropy(RequestSecurityToken rst, SecurityTokenResolver resolver)
  508. {
  509. if (rst == null)
  510. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
  511. return GetEntropy(rst.RequestSecurityTokenXml, resolver);
  512. }
  513. public override SecurityToken GetEntropy(RequestSecurityTokenResponse rstr, SecurityTokenResolver resolver)
  514. {
  515. if (rstr == null)
  516. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
  517. return GetEntropy(rstr.RequestSecurityTokenResponseXml, resolver);
  518. }
  519. SecurityToken GetEntropy(XmlElement rootElement, SecurityTokenResolver resolver)
  520. {
  521. if (rootElement == null || rootElement.ChildNodes == null)
  522. {
  523. return null;
  524. }
  525. for (int i = 0; i < rootElement.ChildNodes.Count; ++i)
  526. {
  527. XmlElement element = rootElement.ChildNodes[i] as XmlElement;
  528. if (element != null)
  529. {
  530. if (element.LocalName == DriverDictionary.Entropy.Value && element.NamespaceURI == DriverDictionary.Namespace.Value)
  531. {
  532. XmlElement tokenXml = XmlHelper.GetChildElement(element);
  533. string valueTypeUri = element.GetAttribute(SecurityJan2004Strings.ValueType);
  534. if (valueTypeUri.Length == 0)
  535. valueTypeUri = null;
  536. return standardsManager.SecurityTokenSerializer.ReadToken(new XmlNodeReader(tokenXml), resolver);
  537. }
  538. }
  539. }
  540. return null;
  541. }
  542. void GetIssuedAndProofXml(RequestSecurityTokenResponse rstr, out XmlElement issuedTokenXml, out XmlElement proofTokenXml)
  543. {
  544. issuedTokenXml = null;
  545. proofTokenXml = null;
  546. if ((rstr.RequestSecurityTokenResponseXml != null) && (rstr.RequestSecurityTokenResponseXml.ChildNodes != null))
  547. {
  548. for (int i = 0; i < rstr.RequestSecurityTokenResponseXml.ChildNodes.Count; ++i)
  549. {
  550. XmlElement elem = rstr.RequestSecurityTokenResponseXml.ChildNodes[i] as XmlElement;
  551. if (elem != null)
  552. {
  553. if (elem.LocalName == DriverDictionary.RequestedSecurityToken.Value && elem.NamespaceURI == DriverDictionary.Namespace.Value)
  554. {
  555. if (issuedTokenXml != null)
  556. {
  557. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RstrHasMultipleIssuedTokens)));
  558. }
  559. issuedTokenXml = XmlHelper.GetChildElement(elem);
  560. }
  561. else if (elem.LocalName == DriverDictionary.RequestedProofToken.Value && elem.NamespaceURI == DriverDictionary.Namespace.Value)
  562. {
  563. if (proofTokenXml != null)
  564. {
  565. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RstrHasMultipleProofTokens)));
  566. }
  567. proofTokenXml = XmlHelper.GetChildElement(elem);
  568. }
  569. }
  570. }
  571. }
  572. }
  573. /// <summary>
  574. /// The algorithm for computing the key is:
  575. /// 1. If there is requestorEntropy:
  576. /// a. If there is no <RequestedProofToken> use the requestorEntropy as the key
  577. /// b. If there is a <RequestedProofToken> with a ComputedKeyUri, combine the client and server entropies
  578. /// c. Anything else, throw
  579. /// 2. If there is no requestorEntropy:
  580. /// a. THere has to be a <RequestedProofToken> that contains the proof key
  581. /// </summary>
  582. public override GenericXmlSecurityToken GetIssuedToken(RequestSecurityTokenResponse rstr, SecurityTokenResolver resolver, IList<SecurityTokenAuthenticator> allowedAuthenticators, SecurityKeyEntropyMode keyEntropyMode, byte[] requestorEntropy, string expectedTokenType,
  583. ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, int defaultKeySize, bool isBearerKeyType)
  584. {
  585. SecurityKeyEntropyModeHelper.Validate(keyEntropyMode);
  586. if (defaultKeySize < 0)
  587. {
  588. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("defaultKeySize", SR.GetString(SR.ValueMustBeNonNegative)));
  589. }
  590. if (rstr == null)
  591. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
  592. string tokenType;
  593. if (rstr.TokenType != null)
  594. {
  595. if (expectedTokenType != null && expectedTokenType != rstr.TokenType)
  596. {
  597. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BadIssuedTokenType, rstr.TokenType, expectedTokenType)));
  598. }
  599. tokenType = rstr.TokenType;
  600. }
  601. else
  602. {
  603. tokenType = expectedTokenType;
  604. }
  605. // search the response elements for licenseXml, proofXml, and lifetime
  606. DateTime created = rstr.ValidFrom;
  607. DateTime expires = rstr.ValidTo;
  608. XmlElement proofXml;
  609. XmlElement issuedTokenXml;
  610. GetIssuedAndProofXml(rstr, out issuedTokenXml, out proofXml);
  611. if (issuedTokenXml == null)
  612. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoLicenseXml)));
  613. if (isBearerKeyType)
  614. {
  615. if (proofXml != null)
  616. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BearerKeyTypeCannotHaveProofKey)));
  617. return new GenericXmlSecurityToken(issuedTokenXml, null, created, expires, rstr.RequestedAttachedReference, rstr.RequestedUnattachedReference, authorizationPolicies);
  618. }
  619. SecurityToken proofToken;
  620. SecurityToken entropyToken = GetEntropy(rstr, resolver);
  621. if (keyEntropyMode == SecurityKeyEntropyMode.ClientEntropy)
  622. {
  623. if (requestorEntropy == null)
  624. {
  625. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresRequestorEntropy, keyEntropyMode)));
  626. }
  627. // enforce that there is no entropy or proof token in the RSTR
  628. if (proofXml != null || entropyToken != null)
  629. {
  630. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveProofTokenOrIssuerEntropy, keyEntropyMode)));
  631. }
  632. proofToken = new BinarySecretSecurityToken(requestorEntropy);
  633. }
  634. else if (keyEntropyMode == SecurityKeyEntropyMode.ServerEntropy)
  635. {
  636. if (requestorEntropy != null)
  637. {
  638. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveRequestorEntropy, keyEntropyMode)));
  639. }
  640. if (rstr.ComputeKey || entropyToken != null)
  641. {
  642. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveComputedKey, keyEntropyMode)));
  643. }
  644. if (proofXml == null)
  645. {
  646. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresProofToken, keyEntropyMode)));
  647. }
  648. string valueTypeUri = proofXml.GetAttribute(SecurityJan2004Strings.ValueType);
  649. if (valueTypeUri.Length == 0)
  650. valueTypeUri = null;
  651. proofToken = standardsManager.SecurityTokenSerializer.ReadToken(new XmlNodeReader(proofXml), resolver);
  652. }
  653. else
  654. {
  655. if (!rstr.ComputeKey)
  656. {
  657. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresComputedKey, keyEntropyMode)));
  658. }
  659. if (entropyToken == null)
  660. {
  661. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresIssuerEntropy, keyEntropyMode)));
  662. }
  663. if (requestorEntropy == null)
  664. {
  665. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresRequestorEntropy, keyEntropyMode)));
  666. }
  667. if (rstr.KeySize == 0 && defaultKeySize == 0)
  668. {
  669. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RstrKeySizeNotProvided)));
  670. }
  671. int issuedKeySize = (rstr.KeySize != 0) ? rstr.KeySize : defaultKeySize;
  672. byte[] issuerEntropy;
  673. if (entropyToken is BinarySecretSecurityToken)
  674. issuerEntropy = ((BinarySecretSecurityToken)entropyToken).GetKeyBytes();
  675. else if (entropyToken is WrappedKeySecurityToken)
  676. issuerEntropy = ((WrappedKeySecurityToken)entropyToken).GetWrappedKey();
  677. else
  678. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedIssuerEntropyType)));
  679. // compute the PSHA1 derived key
  680. byte[] issuedKey = RequestSecurityTokenResponse.ComputeCombinedKey(requestorEntropy, issuerEntropy, issuedKeySize);
  681. proofToken = new BinarySecretSecurityToken(issuedKey);
  682. }
  683. SecurityKeyIdentifierClause internalReference = rstr.RequestedAttachedReference;
  684. SecurityKeyIdentifierClause externalReference = rstr.RequestedUnattachedReference;
  685. return new BufferedGenericXmlSecurityToken(issuedTokenXml, proofToken, created, expires, internalReference, externalReference, authorizationPolicies, rstr.IssuedTokenBuffer);
  686. }
  687. public override GenericXmlSecurityToken GetIssuedToken(RequestSecurityTokenResponse rstr, string expectedTokenType,
  688. ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, RSA clientKey)
  689. {
  690. if (rstr == null)
  691. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("rstr"));
  692. string tokenType;
  693. if (rstr.TokenType != null)
  694. {
  695. if (expectedTokenType != null && expectedTokenType != rstr.TokenType)
  696. {
  697. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BadIssuedTokenType, rstr.TokenType, expectedTokenType)));
  698. }
  699. tokenType = rstr.TokenType;
  700. }
  701. else
  702. {
  703. tokenType = expectedTokenType;
  704. }
  705. // search the response elements for licenseXml, proofXml, and lifetime
  706. DateTime created = rstr.ValidFrom;
  707. DateTime expires = rstr.ValidTo;
  708. XmlElement proofXml;
  709. XmlElement issuedTokenXml;
  710. GetIssuedAndProofXml(rstr, out issuedTokenXml, out proofXml);
  711. if (issuedTokenXml == null)
  712. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoLicenseXml)));
  713. // enforce that there is no proof token in the RSTR
  714. if (proofXml != null)
  715. {
  716. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ProofTokenXmlUnexpectedInRstr)));
  717. }
  718. SecurityKeyIdentifierClause internalReference = rstr.RequestedAttachedReference;
  719. SecurityKeyIdentifierClause externalReference = rstr.RequestedUnattachedReference;
  720. SecurityToken proofToken = new RsaSecurityToken(clientKey);
  721. return new BufferedGenericXmlSecurityToken(issuedTokenXml, proofToken, created, expires, internalReference, externalReference, authorizationPolicies, rstr.IssuedTokenBuffer);
  722. }
  723. public override bool IsAtRequestSecurityTokenResponse(XmlReader reader)
  724. {
  725. if (reader == null)
  726. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
  727. return reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponse.Value, DriverDictionary.Namespace.Value);
  728. }
  729. public override bool IsAtRequestSecurityTokenResponseCollection(XmlReader reader)
  730. {
  731. if (reader == null)
  732. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
  733. return reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponseCollection.Value, DriverDictionary.Namespace.Value);
  734. }
  735. public override bool IsRequestedSecurityTokenElement(string name, string nameSpace)
  736. {
  737. return (name == DriverDictionary.RequestedSecurityToken.Value && nameSpace == DriverDictionary.Namespace.Value);
  738. }
  739. public override bool IsRequestedProofTokenElement(string name, string nameSpace)
  740. {
  741. return (name == DriverDictionary.RequestedProofToken.Value && nameSpace == DriverDictionary.Namespace.Value);
  742. }
  743. public static BinaryNegotiation ReadBinaryNegotiation(XmlElement elem)
  744. {
  745. if (elem == null)
  746. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elem");
  747. // get the encoding and valueType attributes
  748. string encodingUri = null;
  749. string valueTypeUri = null;
  750. byte[] negotiationData = null;
  751. if (elem.Attributes != null)
  752. {
  753. for (int i = 0; i < elem.Attributes.Count; ++i)
  754. {
  755. XmlAttribute attr = elem.Attributes[i];
  756. if (attr.LocalName == SecurityJan2004Strings.EncodingType && attr.NamespaceURI.Length == 0)
  757. {
  758. encodingUri = attr.Value;
  759. if (encodingUri != base64Uri && encodingUri != hexBinaryUri)
  760. {
  761. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.UnsupportedBinaryEncoding, encodingUri)));
  762. }
  763. }
  764. else if (attr.LocalName == SecurityJan2004Strings.ValueType && attr.NamespaceURI.Length == 0)
  765. {
  766. valueTypeUri = attr.Value;
  767. }
  768. // ignore all other attributes
  769. }
  770. }
  771. if (encodingUri == null)
  772. {
  773. XmlHelper.OnRequiredAttributeMissing("EncodingType", elem.Name);
  774. }
  775. if (valueTypeUri == null)
  776. {
  777. XmlHelper.OnRequiredAttributeMissing("ValueType", elem.Name);
  778. }
  779. string encodedBlob = XmlHelper.ReadTextElementAsTrimmedString(elem);
  780. if (encodingUri == base64Uri)
  781. {
  782. negotiationData = Convert.FromBase64String(encodedBlob);
  783. }
  784. else
  785. {
  786. negotiationData = HexBinary.Parse(encodedBlob).Value;
  787. }
  788. return new BinaryNegotiation(valueTypeUri, negotiationData);
  789. }
  790. // Note in Apr2004, internal & external references aren't supported -
  791. // our strategy is to see if there's a token reference (and use it for external ref) and backup is to scan the token xml to compute reference
  792. protected virtual void ReadReferences(XmlElement rstrXml, out SecurityKeyIdentifierClause requestedAttachedReference,
  793. out SecurityKeyIdentifierClause requestedUnattachedReference)
  794. {
  795. XmlElement issuedTokenXml = null;
  796. requestedAttachedReference = null;
  797. requestedUnattachedReference = null;
  798. for (int i = 0; i < rstrXml.ChildNodes.Count; ++i)
  799. {
  800. XmlElement child = rstrXml.ChildNodes[i] as XmlElement;
  801. if (child != null)
  802. {
  803. if (child.LocalName == DriverDictionary.RequestedSecurityToken.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  804. {
  805. issuedTokenXml = XmlHelper.GetChildElement(child);
  806. }
  807. else if (child.LocalName == DriverDictionary.RequestedTokenReference.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
  808. {
  809. requestedUnattachedReference = GetKeyIdentifierXmlReferenceClause(XmlHelper.GetChildElement(child));
  810. }
  811. }
  812. }
  813. if (issuedTokenXml != null)
  814. {
  815. requestedAttachedReference = standardsManager.CreateKeyIdentifierClauseFromTokenXml(issuedTokenXml, SecurityTokenReferenceStyle.Internal);
  816. if (requestedUnattachedReference == null)
  817. {
  818. try
  819. {
  820. requestedUnattachedReference = standardsManager.CreateKeyIdentifierClauseFromTokenXml(issuedTokenXml, SecurityTokenReferenceStyle.External);
  821. }
  822. catch (XmlException)
  823. {
  824. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.TrustDriverIsUnableToCreatedNecessaryAttachedOrUnattachedReferences, issuedTokenXml.ToString())));
  825. }
  826. }
  827. }
  828. }
  829. internal bool TryReadKeyIdentifierClause(XmlNodeReader reader, out SecurityKeyIdentifierClause keyIdentifierClause)
  830. {
  831. keyIdentifierClause = null;
  832. try
  833. {
  834. keyIdentifierClause = standardsManager.SecurityTokenSerializer.ReadKeyIdentifierClause(reader);
  835. }
  836. catch (XmlException e)
  837. {
  838. if (Fx.IsFatal(e))
  839. {
  840. throw;
  841. }
  842. keyIdentifierClause = null;
  843. return false;
  844. }
  845. catch (Exception e)
  846. {
  847. if (Fx.IsFatal(e))
  848. {
  849. throw;
  850. }
  851. keyIdentifierClause = null;
  852. return false;
  853. }
  854. return true;
  855. }
  856. internal SecurityKeyIdentifierClause CreateGenericXmlSecurityKeyIdentifierClause(XmlNodeReader reader, XmlElement keyIdentifierReferenceXmlElement)
  857. {
  858. SecurityKeyIdentifierClause keyIdentifierClause = null;
  859. XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader);
  860. string strId = localReader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);
  861. keyIdentifierClause = new GenericXmlSecurityKeyIdentifierClause(keyIdentifierReferenceXmlElement);
  862. if (!String.IsNullOrEmpty(strId))
  863. {
  864. keyIdentifierClause.Id = strId;
  865. }
  866. return keyIdentifierClause;
  867. }
  868. internal SecurityKeyIdentifierClause GetKeyIdentifierXmlReferenceClause(XmlElement keyIdentifierReferenceXmlElement)
  869. {
  870. SecurityKeyIdentifierClause keyIdentifierClause = null;
  871. XmlNodeReader reader = new XmlNodeReader(keyIdentifierReferenceXmlElement);
  872. if (!this.TryReadKeyIdentifierClause(reader, out keyIdentifierClause))
  873. {
  874. keyIdentifierClause = CreateGenericXmlSecurityKeyIdentifierClause(new XmlNodeReader(keyIdentifierReferenceXmlElement), keyIdentifierReferenceXmlElement);
  875. }
  876. return keyIdentifierClause;
  877. }
  878. protected virtual bool ReadRequestedTokenClosed(XmlElement rstrXml)
  879. {
  880. return false;
  881. }
  882. protected virtual void ReadTargets(XmlElement rstXml, out SecurityKeyIdentifierClause renewTarget, out SecurityKeyIdentifierClause closeTarget)
  883. {
  884. renewTarget = null;
  885. closeTarget = null;
  886. }
  887. public override void OnRSTRorRSTRCMissingException()
  888. {
  889. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ExpectedOneOfTwoElementsFromNamespace,
  890. DriverDictionary.RequestSecurityTokenResponse, DriverDictionary.RequestSecurityTokenResponseCollection,
  891. DriverDictionary.Namespace)));
  892. }
  893. void WriteAppliesTo(object appliesTo, Type appliesToType, XmlObjectSerializer serializer, XmlWriter xmlWriter)
  894. {
  895. XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
  896. writer.WriteStartElement(Namespaces.WSPolicyPrefix, DriverDictionary.AppliesTo.Value, Namespaces.WSPolicy);
  897. lock (serializer)
  898. {
  899. serializer.WriteObject(writer, appliesTo);
  900. }
  901. writer.WriteEndElement();
  902. }
  903. public void WriteBinaryNegotiation(BinaryNegotiation negotiation, XmlWriter xmlWriter)
  904. {
  905. if (negotiation == null)
  906. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("negotiation");
  907. XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
  908. negotiation.WriteTo(writer, this.DriverDictionary.Prefix.Value,
  909. this.DriverDictionary.BinaryExchange, this.DriverDictionary.Namespace,
  910. XD.SecurityJan2004Dictionary.ValueType, null);
  911. }
  912. public override void WriteRequestSecurityToken(RequestSecurityToken rst, XmlWriter xmlWriter)
  913. {
  914. if (rst == null)
  915. {
  916. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
  917. }
  918. if (xmlWriter == null)
  919. {
  920. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("xmlWriter");
  921. }
  922. XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
  923. if (rst.IsReceiver)
  924. {
  925. rst.WriteTo(writer);
  926. return;
  927. }
  928. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestSecurityToken, DriverDictionary.Namespace);
  929. XmlHelper.AddNamespaceDeclaration(writer, DriverDictionary.Prefix.Value, DriverDictionary.Namespace);
  930. if (rst.Context != null)
  931. writer.WriteAttributeString(DriverDictionary.Context, null, rst.Context);
  932. rst.OnWriteCustomAttributes(writer);
  933. if (rst.TokenType != null)
  934. {
  935. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.TokenType, DriverDictionary.Namespace);
  936. writer.WriteString(rst.TokenType);
  937. writer.WriteEndElement();
  938. }
  939. if (rst.RequestType != null)
  940. {
  941. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestType, DriverDictionary.Namespace);
  942. writer.WriteString(rst.RequestType);
  943. writer.WriteEndElement();
  944. }
  945. if (rst.AppliesTo != null)
  946. {
  947. WriteAppliesTo(rst.AppliesTo, rst.AppliesToType, rst.AppliesToSerializer, writer);
  948. }
  949. SecurityToken entropyToken = rst.GetRequestorEntropy();
  950. if (entropyToken != null)
  951. {
  952. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Entropy, DriverDictionary.Namespace);
  953. standardsManager.SecurityTokenSerializer.WriteToken(writer, entropyToken);
  954. writer.WriteEndElement();
  955. }
  956. if (rst.KeySize != 0)
  957. {
  958. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.KeySize, DriverDictionary.Namespace);
  959. writer.WriteValue(rst.KeySize);
  960. writer.WriteEndElement();
  961. }
  962. BinaryNegotiation negotiationData = rst.GetBinaryNegotiation();
  963. if (negotiationData != null)
  964. WriteBinaryNegotiation(negotiationData, writer);
  965. WriteTargets(rst, writer);
  966. if (rst.RequestProperties != null)
  967. {
  968. foreach (XmlElement property in rst.RequestProperties)
  969. {
  970. property.WriteTo(writer);
  971. }
  972. }
  973. rst.OnWriteCustomElements(writer);
  974. writer.WriteEndElement();
  975. }
  976. protected virtual void WriteTargets(RequestSecurityToken rst, XmlDictionaryWriter writer)
  977. {
  978. }
  979. // Note in Apr2004, internal & external references aren't supported - our strategy is to generate the external ref as the TokenReference.
  980. protected virtual void WriteReferences(RequestSecurityTokenResponse rstr, XmlDictionaryWriter writer)
  981. {
  982. if (rstr.RequestedUnattachedReference != null)
  983. {
  984. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestedTokenReference, DriverDictionary.Namespace);
  985. standardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, rstr.RequestedUnattachedReference);
  986. writer.WriteEndElement();
  987. }
  988. }
  989. protected virtual void WriteRequestedTokenClosed(RequestSecurityTokenResponse rstr, XmlDictionaryWriter writer)
  990. {
  991. }
  992. public override void WriteRequestSecurityTokenResponse(RequestSecurityTokenResponse rstr, XmlWriter xmlWriter)
  993. {
  994. if (rstr == null)
  995. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
  996. if (xmlWriter == null)
  997. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("xmlWriter");
  998. XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
  999. if (rstr.IsReceiver)
  1000. {
  1001. rstr.WriteTo(writer);
  1002. return;
  1003. }
  1004. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestSecurityTokenResponse, DriverDictionary.Namespace);
  1005. if (rstr.Context != null)
  1006. {
  1007. writer.WriteAttributeString(DriverDictionary.Context, null, rstr.Context);
  1008. }
  1009. // define WSUtility at the top level to avoid multiple definitions below
  1010. XmlHelper.AddNamespaceDeclaration(writer, UtilityStrings.Prefix, XD.UtilityDictionary.Namespace);
  1011. rstr.OnWriteCustomAttributes(writer);
  1012. if (rstr.TokenType != null)
  1013. writer.WriteElementString(DriverDictionary.Prefix.Value, DriverDictionary.TokenType, DriverDictionary.Namespace, rstr.TokenType);
  1014. if (rstr.RequestedSecurityToken != null)
  1015. {
  1016. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestedSecurityToken, DriverDictionary.Namespace);
  1017. standardsManager.SecurityTokenSerializer.WriteToken(writer, rstr.RequestedSecurityToken);
  1018. writer.WriteEndElement();
  1019. }
  1020. if (rstr.AppliesTo != null)
  1021. {
  1022. WriteAppliesTo(rstr.AppliesTo, rstr.AppliesToType, rstr.AppliesToSerializer, writer);
  1023. }
  1024. WriteReferences(rstr, writer);
  1025. if (rstr.ComputeKey || rstr.RequestedProofToken != null)
  1026. {
  1027. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestedProofToken, DriverDictionary.Namespace);
  1028. if (rstr.ComputeKey)
  1029. {
  1030. writer.WriteElementString(DriverDictionary.Prefix.Value, DriverDictionary.ComputedKey, DriverDictionary.Namespace, DriverDictionary.Psha1ComputedKeyUri.Value);
  1031. }
  1032. else
  1033. {
  1034. standardsManager.SecurityTokenSerializer.WriteToken(writer, rstr.RequestedProofToken);
  1035. }
  1036. writer.WriteEndElement();
  1037. }
  1038. SecurityToken entropyToken = rstr.GetIssuerEntropy();
  1039. if (entropyToken != null)
  1040. {
  1041. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Entropy, DriverDictionary.Namespace);
  1042. standardsManager.SecurityTokenSerializer.WriteToken(writer, entropyToken);
  1043. writer.WriteEndElement();
  1044. }
  1045. // To write out the lifetime, the following algorithm is used
  1046. // 1. If the lifetime is explicitly set, write it out.
  1047. // 2. Else, if a token/tokenbuilder has been set, use the lifetime in that.
  1048. // 3. Else do not serialize lifetime
  1049. if (rstr.IsLifetimeSet || rstr.RequestedSecurityToken != null)
  1050. {
  1051. DateTime effectiveTime = SecurityUtils.MinUtcDateTime;
  1052. DateTime expirationTime = SecurityUtils.MaxUtcDateTime;
  1053. if (rstr.IsLifetimeSet)
  1054. {
  1055. effectiveTime = rstr.ValidFrom.ToUniversalTime();
  1056. expirationTime = rstr.ValidTo.ToUniversalTime();
  1057. }
  1058. else if (rstr.RequestedSecurityToken != null)
  1059. {
  1060. effectiveTime = rstr.RequestedSecurityToken.ValidFrom.ToUniversalTime();
  1061. expirationTime = rstr.RequestedSecurityToken.ValidTo.ToUniversalTime();
  1062. }
  1063. // write out the lifetime
  1064. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Lifetime, DriverDictionary.Namespace);
  1065. // write out Created
  1066. writer.WriteStartElement(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.CreatedElement, XD.UtilityDictionary.Namespace);
  1067. writer.WriteString(effectiveTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture.DateTimeFormat));
  1068. writer.WriteEndElement(); // wsu:Created
  1069. // write out Expires
  1070. writer.WriteStartElement(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.ExpiresElement, XD.UtilityDictionary.Namespace);
  1071. writer.WriteString(expirationTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture.DateTimeFormat));
  1072. writer.WriteEndElement(); // wsu:Expires
  1073. writer.WriteEndElement(); // wsse:Lifetime
  1074. }
  1075. byte[] authenticator = rstr.GetAuthenticator();
  1076. if (authenticator != null)
  1077. {
  1078. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Authenticator, DriverDictionary.Namespace);
  1079. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.CombinedHash, DriverDictionary.Namespace);
  1080. writer.WriteBase64(authenticator, 0, authenticator.Length);
  1081. writer.WriteEndElement();
  1082. writer.WriteEndElement();
  1083. }
  1084. if (rstr.KeySize > 0)
  1085. {
  1086. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.KeySize, DriverDictionary.Namespace);
  1087. writer.WriteValue(rstr.KeySize);
  1088. writer.WriteEndElement();
  1089. }
  1090. WriteRequestedTokenClosed(rstr, writer);
  1091. BinaryNegotiation negotiationData = rstr.GetBinaryNegotiation();
  1092. if (negotiationData != null)
  1093. WriteBinaryNegotiation(negotiationData, writer);
  1094. rstr.OnWriteCustomElements(writer);
  1095. writer.WriteEndElement();
  1096. }
  1097. public override void WriteRequestSecurityTokenResponseCollection(RequestSecurityTokenResponseCollection rstrCollection, XmlWriter xmlWriter)
  1098. {
  1099. if (rstrCollection == null)
  1100. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstrCollection");
  1101. XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
  1102. writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestSecurityTokenResponseCollection, DriverDictionary.Namespace);
  1103. foreach (RequestSecurityTokenResponse rstr in rstrCollection.RstrCollection)
  1104. {
  1105. rstr.WriteTo(writer);
  1106. }
  1107. writer.WriteEndElement();
  1108. }
  1109. protected void SetProtectionLevelForFederation(OperationDescriptionCollection operations)
  1110. {
  1111. foreach (OperationDescription operation in operations)
  1112. {
  1113. foreach (MessageDescription message in operation.Messages)
  1114. {
  1115. if (message.Body.Parts.Count > 0)
  1116. {
  1117. foreach (MessagePartDescription part in message.Body.Parts)
  1118. {
  1119. part.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
  1120. }
  1121. }
  1122. if (OperationFormatter.IsValidReturnValue(message.Body.ReturnValue))
  1123. {
  1124. message.Body.ReturnValue.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
  1125. }
  1126. }
  1127. }
  1128. }
  1129. public override bool TryParseKeySizeElement(XmlElement element, out int keySize)
  1130. {
  1131. if (element == null)
  1132. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  1133. if (element.LocalName == this.DriverDictionary.KeySize.Value
  1134. && element.NamespaceURI == this.DriverDictionary.Namespace.Value)
  1135. {
  1136. keySize = Int32.Parse(XmlHelper.ReadTextElementAsTrimmedString(element), NumberFormatInfo.InvariantInfo);
  1137. return true;
  1138. }
  1139. keySize = 0;
  1140. return false;
  1141. }
  1142. public override XmlElement CreateKeySizeElement(int keySize)
  1143. {
  1144. if (keySize < 0)
  1145. {
  1146. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("keySize", SR.GetString(SR.ValueMustBeNonNegative)));
  1147. }
  1148. XmlDocument doc = new XmlDocument();
  1149. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.KeySize.Value,
  1150. this.DriverDictionary.Namespace.Value);
  1151. result.AppendChild(doc.CreateTextNode(keySize.ToString(System.Globalization.CultureInfo.InvariantCulture.NumberFormat)));
  1152. return result;
  1153. }
  1154. public override XmlElement CreateKeyTypeElement(SecurityKeyType keyType)
  1155. {
  1156. if (keyType == SecurityKeyType.SymmetricKey)
  1157. return CreateSymmetricKeyTypeElement();
  1158. else if (keyType == SecurityKeyType.AsymmetricKey)
  1159. return CreatePublicKeyTypeElement();
  1160. else
  1161. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToCreateKeyTypeElementForUnknownKeyType, keyType.ToString())));
  1162. }
  1163. public override bool TryParseKeyTypeElement(XmlElement element, out SecurityKeyType keyType)
  1164. {
  1165. if (element == null)
  1166. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  1167. if (TryParseSymmetricKeyElement(element))
  1168. {
  1169. keyType = SecurityKeyType.SymmetricKey;
  1170. return true;
  1171. }
  1172. else if (TryParsePublicKeyElement(element))
  1173. {
  1174. keyType = SecurityKeyType.AsymmetricKey;
  1175. return true;
  1176. }
  1177. keyType = SecurityKeyType.SymmetricKey;
  1178. return false;
  1179. }
  1180. public bool TryParseSymmetricKeyElement(XmlElement element)
  1181. {
  1182. if (element == null)
  1183. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  1184. return element.LocalName == this.DriverDictionary.KeyType.Value
  1185. && element.NamespaceURI == this.DriverDictionary.Namespace.Value
  1186. && element.InnerText == this.DriverDictionary.SymmetricKeyType.Value;
  1187. }
  1188. XmlElement CreateSymmetricKeyTypeElement()
  1189. {
  1190. XmlDocument doc = new XmlDocument();
  1191. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.KeyType.Value,
  1192. this.DriverDictionary.Namespace.Value);
  1193. result.AppendChild(doc.CreateTextNode(this.DriverDictionary.SymmetricKeyType.Value));
  1194. return result;
  1195. }
  1196. bool TryParsePublicKeyElement(XmlElement element)
  1197. {
  1198. if (element == null)
  1199. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  1200. return element.LocalName == this.DriverDictionary.KeyType.Value
  1201. && element.NamespaceURI == this.DriverDictionary.Namespace.Value
  1202. && element.InnerText == this.DriverDictionary.PublicKeyType.Value;
  1203. }
  1204. XmlElement CreatePublicKeyTypeElement()
  1205. {
  1206. XmlDocument doc = new XmlDocument();
  1207. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.KeyType.Value,
  1208. this.DriverDictionary.Namespace.Value);
  1209. result.AppendChild(doc.CreateTextNode(this.DriverDictionary.PublicKeyType.Value));
  1210. return result;
  1211. }
  1212. public override bool TryParseTokenTypeElement(XmlElement element, out string tokenType)
  1213. {
  1214. if (element == null)
  1215. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  1216. if (element.LocalName == this.DriverDictionary.TokenType.Value
  1217. && element.NamespaceURI == this.DriverDictionary.Namespace.Value)
  1218. {
  1219. tokenType = element.InnerText;
  1220. return true;
  1221. }
  1222. tokenType = null;
  1223. return false;
  1224. }
  1225. public override XmlElement CreateTokenTypeElement(string tokenTypeUri)
  1226. {
  1227. if (tokenTypeUri == null)
  1228. {
  1229. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenTypeUri");
  1230. }
  1231. XmlDocument doc = new XmlDocument();
  1232. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.TokenType.Value,
  1233. this.DriverDictionary.Namespace.Value);
  1234. result.AppendChild(doc.CreateTextNode(tokenTypeUri));
  1235. return result;
  1236. }
  1237. public override XmlElement CreateUseKeyElement(SecurityKeyIdentifier keyIdentifier, SecurityStandardsManager standardsManager)
  1238. {
  1239. if (keyIdentifier == null)
  1240. {
  1241. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
  1242. }
  1243. if (standardsManager == null)
  1244. {
  1245. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("standardsManager");
  1246. }
  1247. XmlDocument doc = new XmlDocument();
  1248. XmlElement result = doc.CreateElement(this.DriverDictionary.UseKey.Value, this.DriverDictionary.Namespace.Value);
  1249. MemoryStream stream = new MemoryStream();
  1250. using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(new XmlTextWriter(stream, Encoding.UTF8)))
  1251. {
  1252. #pragma warning suppress 56506 // standardsManager.SecurityTokenSerializer can never be null.
  1253. standardsManager.SecurityTokenSerializer.WriteKeyIdentifier(writer, keyIdentifier);
  1254. writer.Flush();
  1255. stream.Seek(0, SeekOrigin.Begin);
  1256. XmlNode skiNode;
  1257. using (XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(new XmlTextReader(stream)))
  1258. {
  1259. reader.MoveToContent();
  1260. skiNode = doc.ReadNode(reader);
  1261. }
  1262. result.AppendChild(skiNode);
  1263. }
  1264. return result;
  1265. }
  1266. public override XmlElement CreateSignWithElement(string signatureAlgorithm)
  1267. {
  1268. if (signatureAlgorithm == null)
  1269. {
  1270. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("signatureAlgorithm");
  1271. }
  1272. XmlDocument doc = new XmlDocument();
  1273. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.SignWith.Value,
  1274. this.DriverDictionary.Namespace.Value);
  1275. result.AppendChild(doc.CreateTextNode(signatureAlgorithm));
  1276. return result;
  1277. }
  1278. internal override bool IsSignWithElement(XmlElement element, out string signatureAlgorithm)
  1279. {
  1280. return CheckElement(element, this.DriverDictionary.SignWith.Value, this.DriverDictionary.Namespace.Value, out signatureAlgorithm);
  1281. }
  1282. public override XmlElement CreateEncryptWithElement(string encryptionAlgorithm)
  1283. {
  1284. if (encryptionAlgorithm == null)
  1285. {
  1286. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptionAlgorithm");
  1287. }
  1288. XmlDocument doc = new XmlDocument();
  1289. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.EncryptWith.Value,
  1290. this.DriverDictionary.Namespace.Value);
  1291. result.AppendChild(doc.CreateTextNode(encryptionAlgorithm));
  1292. return result;
  1293. }
  1294. public override XmlElement CreateEncryptionAlgorithmElement(string encryptionAlgorithm)
  1295. {
  1296. if (encryptionAlgorithm == null)
  1297. {
  1298. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptionAlgorithm");
  1299. }
  1300. XmlDocument doc = new XmlDocument();
  1301. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.EncryptionAlgorithm.Value,
  1302. this.DriverDictionary.Namespace.Value);
  1303. result.AppendChild(doc.CreateTextNode(encryptionAlgorithm));
  1304. return result;
  1305. }
  1306. internal override bool IsEncryptWithElement(XmlElement element, out string encryptWithAlgorithm)
  1307. {
  1308. return CheckElement(element, this.DriverDictionary.EncryptWith.Value, this.DriverDictionary.Namespace.Value, out encryptWithAlgorithm);
  1309. }
  1310. internal override bool IsEncryptionAlgorithmElement(XmlElement element, out string encryptionAlgorithm)
  1311. {
  1312. return CheckElement(element, this.DriverDictionary.EncryptionAlgorithm.Value, this.DriverDictionary.Namespace.Value, out encryptionAlgorithm);
  1313. }
  1314. public override XmlElement CreateComputedKeyAlgorithmElement(string algorithm)
  1315. {
  1316. if (algorithm == null)
  1317. {
  1318. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("algorithm");
  1319. }
  1320. XmlDocument doc = new XmlDocument();
  1321. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.ComputedKeyAlgorithm.Value,
  1322. this.DriverDictionary.Namespace.Value);
  1323. result.AppendChild(doc.CreateTextNode(algorithm));
  1324. return result;
  1325. }
  1326. public override XmlElement CreateCanonicalizationAlgorithmElement(string algorithm)
  1327. {
  1328. if (algorithm == null)
  1329. {
  1330. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("algorithm");
  1331. }
  1332. XmlDocument doc = new XmlDocument();
  1333. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.CanonicalizationAlgorithm.Value,
  1334. this.DriverDictionary.Namespace.Value);
  1335. result.AppendChild(doc.CreateTextNode(algorithm));
  1336. return result;
  1337. }
  1338. internal override bool IsCanonicalizationAlgorithmElement(XmlElement element, out string canonicalizationAlgorithm)
  1339. {
  1340. return CheckElement(element, this.DriverDictionary.CanonicalizationAlgorithm.Value, this.DriverDictionary.Namespace.Value, out canonicalizationAlgorithm);
  1341. }
  1342. public override bool TryParseRequiredClaimsElement(XmlElement element, out System.Collections.ObjectModel.Collection<XmlElement> requiredClaims)
  1343. {
  1344. if (element == null)
  1345. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  1346. if (element.LocalName == this.DriverDictionary.Claims.Value
  1347. && element.NamespaceURI == this.DriverDictionary.Namespace.Value)
  1348. {
  1349. requiredClaims = new System.Collections.ObjectModel.Collection<XmlElement>();
  1350. foreach (XmlNode node in element.ChildNodes)
  1351. if (node is XmlElement)
  1352. {
  1353. // PreSharp Bug: Parameter 'requiredClaims' to this public method must be validated: A null-dereference can occur here.
  1354. #pragma warning suppress 56506
  1355. requiredClaims.Add((XmlElement)node);
  1356. }
  1357. return true;
  1358. }
  1359. requiredClaims = null;
  1360. return false;
  1361. }
  1362. public override XmlElement CreateRequiredClaimsElement(IEnumerable<XmlElement> claimsList)
  1363. {
  1364. if (claimsList == null)
  1365. {
  1366. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claimsList");
  1367. }
  1368. XmlDocument doc = new XmlDocument();
  1369. XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.Claims.Value,
  1370. this.DriverDictionary.Namespace.Value);
  1371. foreach (XmlElement claimElement in claimsList)
  1372. {
  1373. XmlElement element = (XmlElement)doc.ImportNode(claimElement, true);
  1374. result.AppendChild(element);
  1375. }
  1376. return result;
  1377. }
  1378. internal static void ValidateRequestedKeySize(int keySize, SecurityAlgorithmSuite algorithmSuite)
  1379. {
  1380. if ((keySize % 8 == 0) && algorithmSuite.IsSymmetricKeyLengthSupported(keySize))
  1381. {
  1382. return;
  1383. }
  1384. else
  1385. {
  1386. throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidKeyLengthRequested, keySize)));
  1387. }
  1388. }
  1389. static void ValidateRequestorEntropy(SecurityToken entropy, SecurityKeyEntropyMode mode)
  1390. {
  1391. if ((mode == SecurityKeyEntropyMode.ClientEntropy || mode == SecurityKeyEntropyMode.CombinedEntropy)
  1392. && (entropy == null))
  1393. {
  1394. throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresRequestorEntropy, mode)));
  1395. }
  1396. if (mode == SecurityKeyEntropyMode.ServerEntropy && entropy != null)
  1397. {
  1398. throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveRequestorEntropy, mode)));
  1399. }
  1400. }
  1401. internal static void ProcessRstAndIssueKey(RequestSecurityToken requestSecurityToken, SecurityTokenResolver resolver, SecurityKeyEntropyMode keyEntropyMode, SecurityAlgorithmSuite algorithmSuite, out int issuedKeySize, out byte[] issuerEntropy, out byte[] proofKey,
  1402. out SecurityToken proofToken)
  1403. {
  1404. SecurityToken requestorEntropyToken = requestSecurityToken.GetRequestorEntropy(resolver);
  1405. ValidateRequestorEntropy(requestorEntropyToken, keyEntropyMode);
  1406. byte[] requestorEntropy;
  1407. if (requestorEntropyToken != null)
  1408. {
  1409. if (requestorEntropyToken is BinarySecretSecurityToken)
  1410. {
  1411. BinarySecretSecurityToken skToken = (BinarySecretSecurityToken)requestorEntropyToken;
  1412. requestorEntropy = skToken.GetKeyBytes();
  1413. }
  1414. else if (requestorEntropyToken is WrappedKeySecurityToken)
  1415. {
  1416. requestorEntropy = ((WrappedKeySecurityToken)requestorEntropyToken).GetWrappedKey();
  1417. }
  1418. else
  1419. {
  1420. throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.TokenCannotCreateSymmetricCrypto, requestorEntropyToken)));
  1421. }
  1422. }
  1423. else
  1424. {
  1425. requestorEntropy = null;
  1426. }
  1427. if (keyEntropyMode == SecurityKeyEntropyMode.ClientEntropy)
  1428. {
  1429. if (requestorEntropy != null)
  1430. {
  1431. // validate that the entropy length matches the algorithm suite
  1432. ValidateRequestedKeySize(requestorEntropy.Length * 8, algorithmSuite);
  1433. }
  1434. proofKey = requestorEntropy;
  1435. issuerEntropy = null;
  1436. issuedKeySize = 0;
  1437. proofToken = null;
  1438. }
  1439. else
  1440. {
  1441. if (requestSecurityToken.KeySize != 0)
  1442. {
  1443. ValidateRequestedKeySize(requestSecurityToken.KeySize, algorithmSuite);
  1444. issuedKeySize = requestSecurityToken.KeySize;
  1445. }
  1446. else
  1447. {
  1448. issuedKeySize = algorithmSuite.DefaultSymmetricKeyLength;
  1449. }
  1450. RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
  1451. if (keyEntropyMode == SecurityKeyEntropyMode.ServerEntropy)
  1452. {
  1453. proofKey = new byte[issuedKeySize / 8];
  1454. // proof key is completely issued by the server
  1455. random.GetNonZeroBytes(proofKey);
  1456. issuerEntropy = null;
  1457. proofToken = new BinarySecretSecurityToken(proofKey);
  1458. }
  1459. else
  1460. {
  1461. issuerEntropy = new byte[issuedKeySize / 8];
  1462. random.GetNonZeroBytes(issuerEntropy);
  1463. proofKey = RequestSecurityTokenResponse.ComputeCombinedKey(requestorEntropy, issuerEntropy, issuedKeySize);
  1464. proofToken = null;
  1465. }
  1466. }
  1467. }
  1468. }
  1469. protected static bool CheckElement(XmlElement element, string name, string ns, out string value)
  1470. {
  1471. value = null;
  1472. if (element.LocalName != name || element.NamespaceURI != ns)
  1473. return false;
  1474. if (element.FirstChild is XmlText)
  1475. {
  1476. value = ((XmlText)element.FirstChild).Value;
  1477. return true;
  1478. }
  1479. return false;
  1480. }
  1481. }
  1482. }