SecurityElementBase.cs 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. //------------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------------------------
  4. namespace System.ServiceModel.Configuration
  5. {
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.ComponentModel;
  9. using System.Configuration;
  10. using System.IdentityModel.Tokens;
  11. using System.Runtime;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Security;
  14. using System.ServiceModel.Security.Tokens;
  15. using System.Xml;
  16. using System.Linq;
  17. public partial class SecurityElementBase : BindingElementExtensionElement
  18. {
  19. internal const AuthenticationMode defaultAuthenticationMode = AuthenticationMode.SspiNegotiated;
  20. // if you add another variable, make sure to adjust: CopyFrom and UnMerge methods.
  21. SecurityBindingElement failedSecurityBindingElement = null;
  22. bool willX509IssuerReferenceAssertionBeWritten;
  23. SecurityKeyType templateKeyType = IssuedSecurityTokenParameters.defaultKeyType;
  24. internal SecurityElementBase()
  25. {
  26. }
  27. internal bool HasImportFailed { get { return this.failedSecurityBindingElement != null; } }
  28. internal bool IsSecurityElementBootstrap { get; set; } // Used in serialization path to optimize Xml representation
  29. [ConfigurationProperty(ConfigurationStrings.DefaultAlgorithmSuite, DefaultValue = SecurityBindingElement.defaultAlgorithmSuiteString)]
  30. [TypeConverter(typeof(SecurityAlgorithmSuiteConverter))]
  31. public SecurityAlgorithmSuite DefaultAlgorithmSuite
  32. {
  33. get { return (SecurityAlgorithmSuite)base[ConfigurationStrings.DefaultAlgorithmSuite]; }
  34. set { base[ConfigurationStrings.DefaultAlgorithmSuite] = value; }
  35. }
  36. [ConfigurationProperty(ConfigurationStrings.AllowSerializedSigningTokenOnReply, DefaultValue = AsymmetricSecurityBindingElement.defaultAllowSerializedSigningTokenOnReply)]
  37. public bool AllowSerializedSigningTokenOnReply
  38. {
  39. get { return (bool)base[ConfigurationStrings.AllowSerializedSigningTokenOnReply]; }
  40. set { base[ConfigurationStrings.AllowSerializedSigningTokenOnReply] = value; }
  41. }
  42. [ConfigurationProperty(ConfigurationStrings.EnableUnsecuredResponse, DefaultValue = SecurityBindingElement.defaultEnableUnsecuredResponse)]
  43. public bool EnableUnsecuredResponse
  44. {
  45. get { return (bool)base[ConfigurationStrings.EnableUnsecuredResponse]; }
  46. set { base[ConfigurationStrings.EnableUnsecuredResponse] = value; }
  47. }
  48. [ConfigurationProperty(ConfigurationStrings.AuthenticationMode, DefaultValue = defaultAuthenticationMode)]
  49. [ServiceModelEnumValidator(typeof(AuthenticationModeHelper))]
  50. public AuthenticationMode AuthenticationMode
  51. {
  52. get { return (AuthenticationMode)base[ConfigurationStrings.AuthenticationMode]; }
  53. set { base[ConfigurationStrings.AuthenticationMode] = value; }
  54. }
  55. public override Type BindingElementType
  56. {
  57. get { return typeof(SecurityBindingElement); }
  58. }
  59. [ConfigurationProperty(ConfigurationStrings.RequireDerivedKeys, DefaultValue = SecurityTokenParameters.defaultRequireDerivedKeys)]
  60. public bool RequireDerivedKeys
  61. {
  62. get { return (bool)base[ConfigurationStrings.RequireDerivedKeys]; }
  63. set { base[ConfigurationStrings.RequireDerivedKeys] = value; }
  64. }
  65. [ConfigurationProperty(ConfigurationStrings.SecurityHeaderLayout, DefaultValue = SecurityProtocolFactory.defaultSecurityHeaderLayout)]
  66. [ServiceModelEnumValidator(typeof(SecurityHeaderLayoutHelper))]
  67. public SecurityHeaderLayout SecurityHeaderLayout
  68. {
  69. get { return (SecurityHeaderLayout)base[ConfigurationStrings.SecurityHeaderLayout]; }
  70. set { base[ConfigurationStrings.SecurityHeaderLayout] = value; }
  71. }
  72. [ConfigurationProperty(ConfigurationStrings.IncludeTimestamp, DefaultValue = SecurityBindingElement.defaultIncludeTimestamp)]
  73. public bool IncludeTimestamp
  74. {
  75. get { return (bool)base[ConfigurationStrings.IncludeTimestamp]; }
  76. set { base[ConfigurationStrings.IncludeTimestamp] = value; }
  77. }
  78. [ConfigurationProperty(ConfigurationStrings.AllowInsecureTransport, DefaultValue = SecurityBindingElement.defaultAllowInsecureTransport)]
  79. public bool AllowInsecureTransport
  80. {
  81. get { return (bool)base[ConfigurationStrings.AllowInsecureTransport]; }
  82. set { base[ConfigurationStrings.AllowInsecureTransport] = value; }
  83. }
  84. [ConfigurationProperty(ConfigurationStrings.KeyEntropyMode, DefaultValue = System.ServiceModel.Security.AcceleratedTokenProvider.defaultKeyEntropyMode)]
  85. [ServiceModelEnumValidator(typeof(SecurityKeyEntropyModeHelper))]
  86. public SecurityKeyEntropyMode KeyEntropyMode
  87. {
  88. get { return (SecurityKeyEntropyMode)base[ConfigurationStrings.KeyEntropyMode]; }
  89. set { base[ConfigurationStrings.KeyEntropyMode] = value; }
  90. }
  91. [ConfigurationProperty(ConfigurationStrings.IssuedTokenParameters)]
  92. public IssuedTokenParametersElement IssuedTokenParameters
  93. {
  94. get { return (IssuedTokenParametersElement)base[ConfigurationStrings.IssuedTokenParameters]; }
  95. }
  96. [ConfigurationProperty(ConfigurationStrings.LocalClientSettings)]
  97. public LocalClientSecuritySettingsElement LocalClientSettings
  98. {
  99. get { return (LocalClientSecuritySettingsElement)base[ConfigurationStrings.LocalClientSettings]; }
  100. }
  101. [ConfigurationProperty(ConfigurationStrings.LocalServiceSettings)]
  102. public LocalServiceSecuritySettingsElement LocalServiceSettings
  103. {
  104. get { return (LocalServiceSecuritySettingsElement)base[ConfigurationStrings.LocalServiceSettings]; }
  105. }
  106. [ConfigurationProperty(ConfigurationStrings.MessageProtectionOrder, DefaultValue = SecurityBindingElement.defaultMessageProtectionOrder)]
  107. [ServiceModelEnumValidator(typeof(MessageProtectionOrderHelper))]
  108. public MessageProtectionOrder MessageProtectionOrder
  109. {
  110. get { return (MessageProtectionOrder)base[ConfigurationStrings.MessageProtectionOrder]; }
  111. set { base[ConfigurationStrings.MessageProtectionOrder] = value; }
  112. }
  113. [ConfigurationProperty(ConfigurationStrings.ProtectTokens, DefaultValue = false)]
  114. public bool ProtectTokens
  115. {
  116. get { return (bool)base[ConfigurationStrings.ProtectTokens]; }
  117. set { base[ConfigurationStrings.ProtectTokens] = value; }
  118. }
  119. [ConfigurationProperty(ConfigurationStrings.MessageSecurityVersion, DefaultValue = ConfigurationStrings.Default)]
  120. [TypeConverter(typeof(MessageSecurityVersionConverter))]
  121. public MessageSecurityVersion MessageSecurityVersion
  122. {
  123. get { return (MessageSecurityVersion)base[ConfigurationStrings.MessageSecurityVersion]; }
  124. set { base[ConfigurationStrings.MessageSecurityVersion] = value; }
  125. }
  126. [ConfigurationProperty(ConfigurationStrings.RequireSecurityContextCancellation, DefaultValue = SecureConversationSecurityTokenParameters.defaultRequireCancellation)]
  127. public bool RequireSecurityContextCancellation
  128. {
  129. get { return (bool)base[ConfigurationStrings.RequireSecurityContextCancellation]; }
  130. set { base[ConfigurationStrings.RequireSecurityContextCancellation] = value; }
  131. }
  132. [ConfigurationProperty(ConfigurationStrings.RequireSignatureConfirmation, DefaultValue = SecurityBindingElement.defaultRequireSignatureConfirmation)]
  133. public bool RequireSignatureConfirmation
  134. {
  135. get { return (bool)base[ConfigurationStrings.RequireSignatureConfirmation]; }
  136. set { base[ConfigurationStrings.RequireSignatureConfirmation] = value; }
  137. }
  138. [ConfigurationProperty(ConfigurationStrings.CanRenewSecurityContextToken, DefaultValue = SecureConversationSecurityTokenParameters.defaultCanRenewSession)]
  139. public bool CanRenewSecurityContextToken
  140. {
  141. get { return (bool)base[ConfigurationStrings.CanRenewSecurityContextToken]; }
  142. set { base[ConfigurationStrings.CanRenewSecurityContextToken] = value; }
  143. }
  144. public override void ApplyConfiguration(BindingElement bindingElement)
  145. {
  146. base.ApplyConfiguration(bindingElement);
  147. SecurityBindingElement sbe = (SecurityBindingElement)bindingElement;
  148. #pragma warning disable 56506 //[....]; base.CopyFrom() checks for 'from' being null
  149. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.DefaultAlgorithmSuite].ValueOrigin)
  150. sbe.DefaultAlgorithmSuite = this.DefaultAlgorithmSuite;
  151. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.IncludeTimestamp].ValueOrigin)
  152. sbe.IncludeTimestamp = this.IncludeTimestamp;
  153. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.MessageSecurityVersion].ValueOrigin)
  154. sbe.MessageSecurityVersion = this.MessageSecurityVersion;
  155. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.KeyEntropyMode].ValueOrigin)
  156. sbe.KeyEntropyMode = this.KeyEntropyMode;
  157. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.SecurityHeaderLayout].ValueOrigin)
  158. sbe.SecurityHeaderLayout = this.SecurityHeaderLayout;
  159. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.RequireDerivedKeys].ValueOrigin)
  160. sbe.SetKeyDerivation(this.RequireDerivedKeys);
  161. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.AllowInsecureTransport].ValueOrigin)
  162. sbe.AllowInsecureTransport = this.AllowInsecureTransport;
  163. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.EnableUnsecuredResponse].ValueOrigin)
  164. sbe.EnableUnsecuredResponse = this.EnableUnsecuredResponse;
  165. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.ProtectTokens].ValueOrigin)
  166. sbe.ProtectTokens = this.ProtectTokens;
  167. #pragma warning restore
  168. SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
  169. if (ssbe != null)
  170. {
  171. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.MessageProtectionOrder].ValueOrigin)
  172. ssbe.MessageProtectionOrder = this.MessageProtectionOrder;
  173. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.RequireSignatureConfirmation].ValueOrigin)
  174. ssbe.RequireSignatureConfirmation = this.RequireSignatureConfirmation;
  175. SecureConversationSecurityTokenParameters scParameters = ssbe.ProtectionTokenParameters as SecureConversationSecurityTokenParameters;
  176. if (scParameters != null)
  177. {
  178. scParameters.CanRenewSession = this.CanRenewSecurityContextToken;
  179. }
  180. }
  181. AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
  182. if (asbe != null)
  183. {
  184. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.MessageProtectionOrder].ValueOrigin)
  185. asbe.MessageProtectionOrder = this.MessageProtectionOrder;
  186. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.RequireSignatureConfirmation].ValueOrigin)
  187. asbe.RequireSignatureConfirmation = this.RequireSignatureConfirmation;
  188. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.AllowSerializedSigningTokenOnReply].ValueOrigin)
  189. asbe.AllowSerializedSigningTokenOnReply = this.AllowSerializedSigningTokenOnReply;
  190. }
  191. TransportSecurityBindingElement tsbe = sbe as TransportSecurityBindingElement;
  192. if (tsbe != null)
  193. {
  194. if (tsbe.EndpointSupportingTokenParameters.Endorsing.Count == 1)
  195. {
  196. SecureConversationSecurityTokenParameters scParameters = tsbe.EndpointSupportingTokenParameters.Endorsing[0] as SecureConversationSecurityTokenParameters;
  197. if (scParameters != null)
  198. {
  199. scParameters.CanRenewSession = this.CanRenewSecurityContextToken;
  200. }
  201. }
  202. }
  203. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.LocalClientSettings].ValueOrigin)
  204. {
  205. this.LocalClientSettings.ApplyConfiguration(sbe.LocalClientSettings);
  206. }
  207. if (PropertyValueOrigin.Default != this.ElementInformation.Properties[ConfigurationStrings.LocalServiceSettings].ValueOrigin)
  208. {
  209. this.LocalServiceSettings.ApplyConfiguration(sbe.LocalServiceSettings);
  210. }
  211. }
  212. public override void CopyFrom(ServiceModelExtensionElement from)
  213. {
  214. base.CopyFrom(from);
  215. SecurityElementBase source = (SecurityElementBase)from;
  216. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.AllowSerializedSigningTokenOnReply].ValueOrigin)
  217. this.AllowSerializedSigningTokenOnReply = source.AllowSerializedSigningTokenOnReply;
  218. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.DefaultAlgorithmSuite].ValueOrigin)
  219. this.DefaultAlgorithmSuite = source.DefaultAlgorithmSuite;
  220. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.EnableUnsecuredResponse].ValueOrigin)
  221. this.EnableUnsecuredResponse = source.EnableUnsecuredResponse;
  222. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.AllowInsecureTransport].ValueOrigin)
  223. this.AllowInsecureTransport = source.AllowInsecureTransport;
  224. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.RequireDerivedKeys].ValueOrigin)
  225. this.RequireDerivedKeys = source.RequireDerivedKeys;
  226. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.IncludeTimestamp].ValueOrigin)
  227. this.IncludeTimestamp = source.IncludeTimestamp;
  228. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.IssuedTokenParameters].ValueOrigin)
  229. this.IssuedTokenParameters.Copy(source.IssuedTokenParameters);
  230. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.MessageProtectionOrder].ValueOrigin)
  231. this.MessageProtectionOrder = source.MessageProtectionOrder;
  232. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.ProtectTokens].ValueOrigin)
  233. this.ProtectTokens = source.ProtectTokens;
  234. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.MessageSecurityVersion].ValueOrigin)
  235. this.MessageSecurityVersion = source.MessageSecurityVersion;
  236. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.RequireSignatureConfirmation].ValueOrigin)
  237. this.RequireSignatureConfirmation = source.RequireSignatureConfirmation;
  238. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.RequireSecurityContextCancellation].ValueOrigin)
  239. this.RequireSecurityContextCancellation = source.RequireSecurityContextCancellation;
  240. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.CanRenewSecurityContextToken].ValueOrigin)
  241. this.CanRenewSecurityContextToken = source.CanRenewSecurityContextToken;
  242. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.KeyEntropyMode].ValueOrigin)
  243. this.KeyEntropyMode = source.KeyEntropyMode;
  244. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.SecurityHeaderLayout].ValueOrigin)
  245. this.SecurityHeaderLayout = source.SecurityHeaderLayout;
  246. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.LocalClientSettings].ValueOrigin)
  247. this.LocalClientSettings.CopyFrom(source.LocalClientSettings);
  248. if (PropertyValueOrigin.Default != source.ElementInformation.Properties[ConfigurationStrings.LocalServiceSettings].ValueOrigin)
  249. this.LocalServiceSettings.CopyFrom(source.LocalServiceSettings);
  250. this.failedSecurityBindingElement = source.failedSecurityBindingElement;
  251. this.willX509IssuerReferenceAssertionBeWritten = source.willX509IssuerReferenceAssertionBeWritten;
  252. }
  253. protected internal override BindingElement CreateBindingElement()
  254. {
  255. return this.CreateBindingElement(false);
  256. }
  257. protected internal virtual BindingElement CreateBindingElement(bool createTemplateOnly)
  258. {
  259. SecurityBindingElement result;
  260. switch (this.AuthenticationMode)
  261. {
  262. case AuthenticationMode.AnonymousForCertificate:
  263. result = SecurityBindingElement.CreateAnonymousForCertificateBindingElement();
  264. break;
  265. case AuthenticationMode.AnonymousForSslNegotiated:
  266. result = SecurityBindingElement.CreateSslNegotiationBindingElement(false, this.RequireSecurityContextCancellation);
  267. break;
  268. case AuthenticationMode.CertificateOverTransport:
  269. result = SecurityBindingElement.CreateCertificateOverTransportBindingElement(this.MessageSecurityVersion);
  270. break;
  271. case AuthenticationMode.IssuedToken:
  272. result = SecurityBindingElement.CreateIssuedTokenBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType));
  273. break;
  274. case AuthenticationMode.IssuedTokenForCertificate:
  275. result = SecurityBindingElement.CreateIssuedTokenForCertificateBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType));
  276. break;
  277. case AuthenticationMode.IssuedTokenForSslNegotiated:
  278. result = SecurityBindingElement.CreateIssuedTokenForSslBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType), this.RequireSecurityContextCancellation);
  279. break;
  280. case AuthenticationMode.IssuedTokenOverTransport:
  281. result = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(this.IssuedTokenParameters.Create(createTemplateOnly, this.templateKeyType));
  282. break;
  283. case AuthenticationMode.Kerberos:
  284. result = SecurityBindingElement.CreateKerberosBindingElement();
  285. break;
  286. case AuthenticationMode.KerberosOverTransport:
  287. result = SecurityBindingElement.CreateKerberosOverTransportBindingElement();
  288. break;
  289. case AuthenticationMode.MutualCertificateDuplex:
  290. result = SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(this.MessageSecurityVersion);
  291. break;
  292. case AuthenticationMode.MutualCertificate:
  293. result = SecurityBindingElement.CreateMutualCertificateBindingElement(this.MessageSecurityVersion);
  294. break;
  295. case AuthenticationMode.MutualSslNegotiated:
  296. result = SecurityBindingElement.CreateSslNegotiationBindingElement(true, this.RequireSecurityContextCancellation);
  297. break;
  298. case AuthenticationMode.SspiNegotiated:
  299. result = SecurityBindingElement.CreateSspiNegotiationBindingElement(this.RequireSecurityContextCancellation);
  300. break;
  301. case AuthenticationMode.UserNameForCertificate:
  302. result = SecurityBindingElement.CreateUserNameForCertificateBindingElement();
  303. break;
  304. case AuthenticationMode.UserNameForSslNegotiated:
  305. result = SecurityBindingElement.CreateUserNameForSslBindingElement(this.RequireSecurityContextCancellation);
  306. break;
  307. case AuthenticationMode.UserNameOverTransport:
  308. result = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
  309. break;
  310. case AuthenticationMode.SspiNegotiatedOverTransport:
  311. result = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(this.RequireSecurityContextCancellation);
  312. break;
  313. default:
  314. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("AuthenticationMode", (int)this.AuthenticationMode, typeof(AuthenticationMode)));
  315. }
  316. this.ApplyConfiguration(result);
  317. return result;
  318. }
  319. protected void AddBindingTemplate(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates, AuthenticationMode mode)
  320. {
  321. this.AuthenticationMode = mode;
  322. try
  323. {
  324. bindingTemplates[mode] = (SecurityBindingElement)this.CreateBindingElement(true);
  325. }
  326. #pragma warning suppress 56500 // covered by FxCOP
  327. catch (Exception e)
  328. {
  329. if (Fx.IsFatal(e))
  330. {
  331. throw;
  332. }
  333. }
  334. }
  335. static bool AreTokenParametersMatching(SecurityTokenParameters p1, SecurityTokenParameters p2, bool skipRequireDerivedKeysComparison, bool exactMessageSecurityVersion)
  336. {
  337. if (p1 == null || p2 == null)
  338. return false;
  339. if (p1.GetType() != p2.GetType())
  340. return false;
  341. if (p1.InclusionMode != p2.InclusionMode)
  342. return false;
  343. if (skipRequireDerivedKeysComparison == false && p1.RequireDerivedKeys != p2.RequireDerivedKeys)
  344. return false;
  345. if (p1.ReferenceStyle != p2.ReferenceStyle)
  346. return false;
  347. // mutual ssl and anonymous ssl differ in the client cert requirement
  348. if (p1 is SslSecurityTokenParameters)
  349. {
  350. if (((SslSecurityTokenParameters)p1).RequireClientCertificate != ((SslSecurityTokenParameters)p2).RequireClientCertificate)
  351. return false;
  352. }
  353. else if (p1 is SecureConversationSecurityTokenParameters)
  354. {
  355. SecureConversationSecurityTokenParameters sc1 = (SecureConversationSecurityTokenParameters)p1;
  356. SecureConversationSecurityTokenParameters sc2 = (SecureConversationSecurityTokenParameters)p2;
  357. if (sc1.RequireCancellation != sc2.RequireCancellation)
  358. return false;
  359. if (sc1.CanRenewSession != sc2.CanRenewSession)
  360. return false;
  361. if (!AreBindingsMatching(sc1.BootstrapSecurityBindingElement, sc2.BootstrapSecurityBindingElement, exactMessageSecurityVersion))
  362. return false;
  363. }
  364. else if (p1 is IssuedSecurityTokenParameters)
  365. {
  366. if (((IssuedSecurityTokenParameters)p1).KeyType != ((IssuedSecurityTokenParameters)p2).KeyType)
  367. return false;
  368. }
  369. return true;
  370. }
  371. static bool AreTokenParameterCollectionsMatching(Collection<SecurityTokenParameters> c1, Collection<SecurityTokenParameters> c2, bool exactMessageSecurityVersion)
  372. {
  373. if (c1.Count != c2.Count)
  374. return false;
  375. for (int i = 0; i < c1.Count; i++)
  376. if (!AreTokenParametersMatching(c1[i], c2[i], true, exactMessageSecurityVersion))
  377. return false;
  378. return true;
  379. }
  380. internal static bool AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2)
  381. {
  382. return AreBindingsMatching(b1, b2, true);
  383. }
  384. internal static bool AreBindingsMatching(SecurityBindingElement b1, SecurityBindingElement b2, bool exactMessageSecurityVersion)
  385. {
  386. if (b1 == null || b2 == null)
  387. return b1 == b2;
  388. if (b1.GetType() != b2.GetType())
  389. return false;
  390. if (b1.MessageSecurityVersion != b2.MessageSecurityVersion)
  391. {
  392. // exactMessageSecurityVersion meant that BSP mismatch could be ignored
  393. if (exactMessageSecurityVersion)
  394. return false;
  395. if (b1.MessageSecurityVersion.SecurityVersion != b2.MessageSecurityVersion.SecurityVersion
  396. || b1.MessageSecurityVersion.TrustVersion != b2.MessageSecurityVersion.TrustVersion
  397. || b1.MessageSecurityVersion.SecureConversationVersion != b2.MessageSecurityVersion.SecureConversationVersion
  398. || b1.MessageSecurityVersion.SecurityPolicyVersion != b2.MessageSecurityVersion.SecurityPolicyVersion)
  399. {
  400. return false;
  401. }
  402. }
  403. if (b1.SecurityHeaderLayout != b2.SecurityHeaderLayout)
  404. return false;
  405. if (b1.DefaultAlgorithmSuite != b2.DefaultAlgorithmSuite)
  406. return false;
  407. if (b1.IncludeTimestamp != b2.IncludeTimestamp)
  408. return false;
  409. if (b1.SecurityHeaderLayout != b2.SecurityHeaderLayout)
  410. return false;
  411. if (b1.KeyEntropyMode != b2.KeyEntropyMode)
  412. return false;
  413. if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.Endorsing, b2.EndpointSupportingTokenParameters.Endorsing, exactMessageSecurityVersion))
  414. return false;
  415. if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.SignedEncrypted, b2.EndpointSupportingTokenParameters.SignedEncrypted, exactMessageSecurityVersion))
  416. return false;
  417. if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.Signed, b2.EndpointSupportingTokenParameters.Signed, exactMessageSecurityVersion))
  418. return false;
  419. if (!AreTokenParameterCollectionsMatching(b1.EndpointSupportingTokenParameters.SignedEndorsing, b2.EndpointSupportingTokenParameters.SignedEndorsing, exactMessageSecurityVersion))
  420. return false;
  421. if (b1.OperationSupportingTokenParameters.Count != b2.OperationSupportingTokenParameters.Count)
  422. return false;
  423. foreach (KeyValuePair<string, SupportingTokenParameters> operation1 in b1.OperationSupportingTokenParameters)
  424. {
  425. if (!b2.OperationSupportingTokenParameters.ContainsKey(operation1.Key))
  426. return false;
  427. SupportingTokenParameters stp2 = b2.OperationSupportingTokenParameters[operation1.Key];
  428. if (!AreTokenParameterCollectionsMatching(operation1.Value.Endorsing, stp2.Endorsing, exactMessageSecurityVersion))
  429. return false;
  430. if (!AreTokenParameterCollectionsMatching(operation1.Value.SignedEncrypted, stp2.SignedEncrypted, exactMessageSecurityVersion))
  431. return false;
  432. if (!AreTokenParameterCollectionsMatching(operation1.Value.Signed, stp2.Signed, exactMessageSecurityVersion))
  433. return false;
  434. if (!AreTokenParameterCollectionsMatching(operation1.Value.SignedEndorsing, stp2.SignedEndorsing, exactMessageSecurityVersion))
  435. return false;
  436. }
  437. SymmetricSecurityBindingElement ssbe1 = b1 as SymmetricSecurityBindingElement;
  438. if (ssbe1 != null)
  439. {
  440. SymmetricSecurityBindingElement ssbe2 = (SymmetricSecurityBindingElement)b2;
  441. if (ssbe1.MessageProtectionOrder != ssbe2.MessageProtectionOrder)
  442. return false;
  443. if (!AreTokenParametersMatching(ssbe1.ProtectionTokenParameters, ssbe2.ProtectionTokenParameters, false, exactMessageSecurityVersion))
  444. return false;
  445. }
  446. AsymmetricSecurityBindingElement asbe1 = b1 as AsymmetricSecurityBindingElement;
  447. if (asbe1 != null)
  448. {
  449. AsymmetricSecurityBindingElement asbe2 = (AsymmetricSecurityBindingElement)b2;
  450. if (asbe1.MessageProtectionOrder != asbe2.MessageProtectionOrder)
  451. return false;
  452. if (asbe1.RequireSignatureConfirmation != asbe2.RequireSignatureConfirmation)
  453. return false;
  454. if (!AreTokenParametersMatching(asbe1.InitiatorTokenParameters, asbe2.InitiatorTokenParameters, true, exactMessageSecurityVersion)
  455. || !AreTokenParametersMatching(asbe1.RecipientTokenParameters, asbe2.RecipientTokenParameters, true, exactMessageSecurityVersion))
  456. return false;
  457. }
  458. return true;
  459. }
  460. protected virtual void AddBindingTemplates(Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates)
  461. {
  462. AddBindingTemplate(bindingTemplates, AuthenticationMode.AnonymousForCertificate);
  463. AddBindingTemplate(bindingTemplates, AuthenticationMode.AnonymousForSslNegotiated);
  464. AddBindingTemplate(bindingTemplates, AuthenticationMode.CertificateOverTransport);
  465. if (this.templateKeyType == SecurityKeyType.SymmetricKey)
  466. {
  467. AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedToken);
  468. }
  469. AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedTokenForCertificate);
  470. AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedTokenForSslNegotiated);
  471. AddBindingTemplate(bindingTemplates, AuthenticationMode.IssuedTokenOverTransport);
  472. AddBindingTemplate(bindingTemplates, AuthenticationMode.Kerberos);
  473. AddBindingTemplate(bindingTemplates, AuthenticationMode.KerberosOverTransport);
  474. AddBindingTemplate(bindingTemplates, AuthenticationMode.MutualCertificate);
  475. AddBindingTemplate(bindingTemplates, AuthenticationMode.MutualCertificateDuplex);
  476. AddBindingTemplate(bindingTemplates, AuthenticationMode.MutualSslNegotiated);
  477. AddBindingTemplate(bindingTemplates, AuthenticationMode.SspiNegotiated);
  478. AddBindingTemplate(bindingTemplates, AuthenticationMode.UserNameForCertificate);
  479. AddBindingTemplate(bindingTemplates, AuthenticationMode.UserNameForSslNegotiated);
  480. AddBindingTemplate(bindingTemplates, AuthenticationMode.UserNameOverTransport);
  481. AddBindingTemplate(bindingTemplates, AuthenticationMode.SspiNegotiatedOverTransport);
  482. }
  483. bool TryInitializeAuthenticationMode(SecurityBindingElement sbe)
  484. {
  485. bool result;
  486. if (sbe.OperationSupportingTokenParameters.Count > 0)
  487. result = false;
  488. else
  489. {
  490. SetIssuedTokenKeyType(sbe);
  491. Dictionary<AuthenticationMode, SecurityBindingElement> bindingTemplates = new Dictionary<AuthenticationMode, SecurityBindingElement>();
  492. this.AddBindingTemplates(bindingTemplates);
  493. result = false;
  494. foreach (AuthenticationMode mode in bindingTemplates.Keys)
  495. {
  496. SecurityBindingElement candidate = bindingTemplates[mode];
  497. if (AreBindingsMatching(sbe, candidate))
  498. {
  499. this.AuthenticationMode = mode;
  500. result = true;
  501. break;
  502. }
  503. }
  504. }
  505. return result;
  506. }
  507. void SetIssuedTokenKeyType(SecurityBindingElement sbe)
  508. {
  509. // Set the keyType for building the template for IssuedToken binding.
  510. // The reason is the different supporting token is defined depending on keyType.
  511. if (sbe.EndpointSupportingTokenParameters.Endorsing.Count > 0 &&
  512. sbe.EndpointSupportingTokenParameters.Endorsing[0] is IssuedSecurityTokenParameters)
  513. {
  514. this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.Endorsing[0]).KeyType;
  515. }
  516. else if (sbe.EndpointSupportingTokenParameters.Signed.Count > 0 &&
  517. sbe.EndpointSupportingTokenParameters.Signed[0] is IssuedSecurityTokenParameters)
  518. {
  519. this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.Signed[0]).KeyType;
  520. }
  521. else if (sbe.EndpointSupportingTokenParameters.SignedEncrypted.Count > 0 &&
  522. sbe.EndpointSupportingTokenParameters.SignedEncrypted[0] is IssuedSecurityTokenParameters)
  523. {
  524. this.templateKeyType = ((IssuedSecurityTokenParameters)sbe.EndpointSupportingTokenParameters.SignedEncrypted[0]).KeyType;
  525. }
  526. else
  527. {
  528. this.templateKeyType = IssuedSecurityTokenParameters.defaultKeyType;
  529. }
  530. }
  531. protected virtual void InitializeNestedTokenParameterSettings(SecurityTokenParameters sp, bool initializeNestedBindings)
  532. {
  533. if (sp is SspiSecurityTokenParameters)
  534. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.RequireSecurityContextCancellation, ((SspiSecurityTokenParameters)sp).RequireCancellation);
  535. else if (sp is SslSecurityTokenParameters)
  536. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.RequireSecurityContextCancellation, ((SslSecurityTokenParameters)sp).RequireCancellation);
  537. else if (sp is IssuedSecurityTokenParameters)
  538. this.IssuedTokenParameters.InitializeFrom((IssuedSecurityTokenParameters)sp, initializeNestedBindings);
  539. }
  540. internal void InitializeFrom(BindingElement bindingElement, bool initializeNestedBindings)
  541. {
  542. if (bindingElement == null)
  543. {
  544. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElement");
  545. }
  546. SecurityBindingElement sbe = (SecurityBindingElement)bindingElement;
  547. // Can't apply default value optimization to properties like DefaultAlgorithmSuite because the defaults are computed at runtime and don't match config defaults
  548. this.DefaultAlgorithmSuite = sbe.DefaultAlgorithmSuite;
  549. this.IncludeTimestamp = sbe.IncludeTimestamp;
  550. if (sbe.MessageSecurityVersion != MessageSecurityVersion.Default)
  551. {
  552. this.MessageSecurityVersion = sbe.MessageSecurityVersion;
  553. }
  554. // Still safe to apply the optimization here because the runtime defaults are the same as config defaults in all cases
  555. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.KeyEntropyMode, sbe.KeyEntropyMode);
  556. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.SecurityHeaderLayout, sbe.SecurityHeaderLayout);
  557. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.ProtectTokens, sbe.ProtectTokens);
  558. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.AllowInsecureTransport, sbe.AllowInsecureTransport);
  559. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.EnableUnsecuredResponse, sbe.EnableUnsecuredResponse);
  560. Nullable<bool> requireDerivedKeys = new Nullable<bool>();
  561. if (sbe.EndpointSupportingTokenParameters.Endorsing.Count == 1)
  562. {
  563. this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.Endorsing[0], initializeNestedBindings);
  564. }
  565. else if (sbe.EndpointSupportingTokenParameters.SignedEncrypted.Count == 1)
  566. {
  567. this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.SignedEncrypted[0], initializeNestedBindings);
  568. }
  569. else if (sbe.EndpointSupportingTokenParameters.Signed.Count == 1)
  570. {
  571. this.InitializeNestedTokenParameterSettings(sbe.EndpointSupportingTokenParameters.Signed[0], initializeNestedBindings);
  572. }
  573. bool initializationFailure = false;
  574. foreach (SecurityTokenParameters t in sbe.EndpointSupportingTokenParameters.Endorsing)
  575. {
  576. if (t.HasAsymmetricKey == false)
  577. {
  578. if (requireDerivedKeys.HasValue && requireDerivedKeys.Value != t.RequireDerivedKeys)
  579. initializationFailure = true;
  580. else
  581. requireDerivedKeys = t.RequireDerivedKeys;
  582. }
  583. }
  584. SymmetricSecurityBindingElement ssbe = sbe as SymmetricSecurityBindingElement;
  585. if ( ssbe != null )
  586. {
  587. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.MessageProtectionOrder, ssbe.MessageProtectionOrder);
  588. this.RequireSignatureConfirmation = ssbe.RequireSignatureConfirmation;
  589. if ( ssbe.ProtectionTokenParameters != null )
  590. {
  591. this.InitializeNestedTokenParameterSettings( ssbe.ProtectionTokenParameters, initializeNestedBindings );
  592. if ( requireDerivedKeys.HasValue && requireDerivedKeys.Value != ssbe.ProtectionTokenParameters.RequireDerivedKeys )
  593. initializationFailure = true;
  594. else
  595. requireDerivedKeys = ssbe.ProtectionTokenParameters.RequireDerivedKeys;
  596. }
  597. }
  598. else
  599. {
  600. AsymmetricSecurityBindingElement asbe = sbe as AsymmetricSecurityBindingElement;
  601. if ( asbe != null )
  602. {
  603. SetPropertyValueIfNotDefaultValue(ConfigurationStrings.MessageProtectionOrder, asbe.MessageProtectionOrder);
  604. this.RequireSignatureConfirmation = asbe.RequireSignatureConfirmation;
  605. if ( asbe.InitiatorTokenParameters != null )
  606. {
  607. this.InitializeNestedTokenParameterSettings( asbe.InitiatorTokenParameters, initializeNestedBindings );
  608. //
  609. // Copy the derived key token bool flag from the token parameters. The token parameter was set from
  610. // importing WSDL during SecurityBindingElementImporter.ImportPolicy time
  611. //
  612. if ( requireDerivedKeys.HasValue && requireDerivedKeys.Value != asbe.InitiatorTokenParameters.RequireDerivedKeys )
  613. initializationFailure = true;
  614. else
  615. requireDerivedKeys = asbe.InitiatorTokenParameters.RequireDerivedKeys;
  616. }
  617. }
  618. }
  619. this.willX509IssuerReferenceAssertionBeWritten = DoesSecurityBindingElementContainClauseTypeofIssuerSerial(sbe);
  620. this.RequireDerivedKeys = requireDerivedKeys.GetValueOrDefault(SecurityTokenParameters.defaultRequireDerivedKeys);
  621. this.LocalClientSettings.InitializeFrom(sbe.LocalClientSettings);
  622. this.LocalServiceSettings.InitializeFrom(sbe.LocalServiceSettings);
  623. if (!initializationFailure)
  624. initializationFailure = !this.TryInitializeAuthenticationMode(sbe);
  625. if (initializationFailure)
  626. this.failedSecurityBindingElement = sbe;
  627. }
  628. protected internal override void InitializeFrom(BindingElement bindingElement)
  629. {
  630. this.InitializeFrom(bindingElement, true);
  631. }
  632. /// <summary>
  633. /// returns true if one of the xxxSupportingTokenParameters.yyy is of type IssuerSerial
  634. /// </summary>
  635. /// <param name="sbe"></param>
  636. /// <returns></returns>
  637. bool DoesSecurityBindingElementContainClauseTypeofIssuerSerial( SecurityBindingElement sbe )
  638. {
  639. if ( sbe == null )
  640. return false;
  641. if ( sbe is SymmetricSecurityBindingElement )
  642. {
  643. X509SecurityTokenParameters tokenParamameters = ( (SymmetricSecurityBindingElement)sbe ).ProtectionTokenParameters as X509SecurityTokenParameters;
  644. if ( tokenParamameters != null && tokenParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
  645. return true;
  646. }
  647. else if ( sbe is AsymmetricSecurityBindingElement )
  648. {
  649. X509SecurityTokenParameters initiatorParamameters = ( (AsymmetricSecurityBindingElement)sbe ).InitiatorTokenParameters as X509SecurityTokenParameters;
  650. if ( initiatorParamameters != null && initiatorParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
  651. return true;
  652. X509SecurityTokenParameters recepientParamameters = ( (AsymmetricSecurityBindingElement)sbe ).RecipientTokenParameters as X509SecurityTokenParameters;
  653. if ( recepientParamameters != null && recepientParamameters.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
  654. return true;
  655. }
  656. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.Endorsing ) )
  657. return true;
  658. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.Signed ) )
  659. return true;
  660. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.SignedEncrypted ) )
  661. return true;
  662. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.EndpointSupportingTokenParameters.SignedEndorsing ) )
  663. return true;
  664. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.Endorsing ) )
  665. return true;
  666. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.Signed ) )
  667. return true;
  668. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.SignedEncrypted ) )
  669. return true;
  670. if ( DoesX509TokenParametersContainClauseTypeofIssuerSerial( sbe.OptionalEndpointSupportingTokenParameters.SignedEndorsing ) )
  671. return true;
  672. return false;
  673. }
  674. bool DoesX509TokenParametersContainClauseTypeofIssuerSerial( Collection<SecurityTokenParameters> tokenParameters )
  675. {
  676. foreach ( SecurityTokenParameters tokenParameter in tokenParameters )
  677. {
  678. X509SecurityTokenParameters x509TokenParameter = tokenParameter as X509SecurityTokenParameters;
  679. if ( x509TokenParameter != null )
  680. {
  681. if ( x509TokenParameter.X509ReferenceStyle == X509KeyIdentifierClauseType.IssuerSerial )
  682. return true;
  683. }
  684. }
  685. return false;
  686. }
  687. protected override bool SerializeToXmlElement(XmlWriter writer, String elementName)
  688. {
  689. bool result;
  690. if (this.failedSecurityBindingElement != null && writer != null)
  691. {
  692. writer.WriteComment(SR.GetString(SR.ConfigurationSchemaInsuffientForSecurityBindingElementInstance));
  693. writer.WriteComment(this.failedSecurityBindingElement.ToString());
  694. result = true;
  695. }
  696. else
  697. {
  698. if ( writer != null && this.willX509IssuerReferenceAssertionBeWritten )
  699. writer.WriteComment( SR.GetString(SR.ConfigurationSchemaContainsX509IssuerSerialReference));
  700. result = base.SerializeToXmlElement(writer, elementName);
  701. }
  702. return result;
  703. }
  704. protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey)
  705. {
  706. bool nontrivial = base.SerializeElement(writer, serializeCollectionKey);
  707. // A SecurityElement can copy properties from a "bootstrap" SecurityBaseElement.
  708. // In this case, a trivial bootstrap (no properties set) is equivalent to not having one at all so we can omit it.
  709. Func<PropertyInformation, bool> nontrivialProperty = property => property.ValueOrigin == PropertyValueOrigin.SetHere;
  710. if (this.IsSecurityElementBootstrap && !this.ElementInformation.Properties.OfType<PropertyInformation>().Any(nontrivialProperty))
  711. {
  712. nontrivial = false;
  713. }
  714. return nontrivial;
  715. }
  716. protected override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
  717. {
  718. if ( sourceElement is SecurityElementBase )
  719. {
  720. this.failedSecurityBindingElement = ( (SecurityElementBase)sourceElement ).failedSecurityBindingElement;
  721. this.willX509IssuerReferenceAssertionBeWritten = ( (SecurityElementBase)sourceElement ).willX509IssuerReferenceAssertionBeWritten;
  722. }
  723. base.Unmerge(sourceElement, parentElement, saveMode);
  724. }
  725. }
  726. }