SecurityVersion.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Security
  5. {
  6. using System.Collections.Generic;
  7. using System.ServiceModel.Channels;
  8. using System.ServiceModel;
  9. using System.ServiceModel.Description;
  10. using System.IO;
  11. using System.IdentityModel.Claims;
  12. using System.IdentityModel.Policy;
  13. using System.ServiceModel.Security.Tokens;
  14. using System.Threading;
  15. using System.Globalization;
  16. using System.ServiceModel.Diagnostics;
  17. using System.Xml;
  18. using ISignatureValueSecurityElement = System.IdentityModel.ISignatureValueSecurityElement;
  19. public abstract class SecurityVersion
  20. {
  21. readonly XmlDictionaryString headerName;
  22. readonly XmlDictionaryString headerNamespace;
  23. readonly XmlDictionaryString headerPrefix;
  24. internal SecurityVersion(XmlDictionaryString headerName, XmlDictionaryString headerNamespace, XmlDictionaryString headerPrefix)
  25. {
  26. this.headerName = headerName;
  27. this.headerNamespace = headerNamespace;
  28. this.headerPrefix = headerPrefix;
  29. }
  30. internal XmlDictionaryString HeaderName
  31. {
  32. get { return this.headerName; }
  33. }
  34. internal XmlDictionaryString HeaderNamespace
  35. {
  36. get { return this.headerNamespace; }
  37. }
  38. internal XmlDictionaryString HeaderPrefix
  39. {
  40. get { return this.headerPrefix; }
  41. }
  42. internal abstract XmlDictionaryString FailedAuthenticationFaultCode
  43. {
  44. get;
  45. }
  46. internal abstract XmlDictionaryString InvalidSecurityTokenFaultCode
  47. {
  48. get;
  49. }
  50. internal abstract XmlDictionaryString InvalidSecurityFaultCode
  51. {
  52. get;
  53. }
  54. internal virtual bool SupportsSignatureConfirmation
  55. {
  56. get { return false; }
  57. }
  58. public static SecurityVersion WSSecurity10
  59. {
  60. get { return SecurityVersion10.Instance; }
  61. }
  62. public static SecurityVersion WSSecurity11
  63. {
  64. get { return SecurityVersion11.Instance; }
  65. }
  66. internal static SecurityVersion Default
  67. {
  68. get { return WSSecurity11; }
  69. }
  70. internal abstract ReceiveSecurityHeader CreateReceiveSecurityHeader(Message message,
  71. string actor, bool mustUnderstand, bool relay,
  72. SecurityStandardsManager standardsManager,
  73. SecurityAlgorithmSuite algorithmSuite,
  74. MessageDirection direction,
  75. int headerIndex);
  76. internal abstract SendSecurityHeader CreateSendSecurityHeader(Message message,
  77. string actor, bool mustUnderstand, bool relay,
  78. SecurityStandardsManager standardsManager,
  79. SecurityAlgorithmSuite algorithmSuite,
  80. MessageDirection direction);
  81. internal bool DoesMessageContainSecurityHeader(Message message)
  82. {
  83. return message.Headers.FindHeader(this.HeaderName.Value, this.HeaderNamespace.Value) >= 0;
  84. }
  85. internal int FindIndexOfSecurityHeader(Message message, string[] actors)
  86. {
  87. return message.Headers.FindHeader(this.HeaderName.Value, this.HeaderNamespace.Value, actors);
  88. }
  89. internal virtual bool IsReaderAtSignatureConfirmation(XmlDictionaryReader reader)
  90. {
  91. return false;
  92. }
  93. internal virtual ISignatureValueSecurityElement ReadSignatureConfirmation(XmlDictionaryReader reader)
  94. {
  95. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
  96. SR.GetString(SR.SignatureConfirmationNotSupported)));
  97. }
  98. // The security always look for Empty soap role. If not found, we will also look for Ultimate actors (next incl).
  99. // In the future, till we support intermediary scenario, we should refactor this api to do not take actor parameter.
  100. internal ReceiveSecurityHeader TryCreateReceiveSecurityHeader(Message message,
  101. string actor,
  102. SecurityStandardsManager standardsManager,
  103. SecurityAlgorithmSuite algorithmSuite, MessageDirection direction)
  104. {
  105. int headerIndex = message.Headers.FindHeader(this.HeaderName.Value, this.HeaderNamespace.Value, actor);
  106. if (headerIndex < 0 && String.IsNullOrEmpty(actor))
  107. {
  108. headerIndex = message.Headers.FindHeader(this.HeaderName.Value, this.HeaderNamespace.Value, message.Version.Envelope.UltimateDestinationActorValues);
  109. }
  110. if (headerIndex < 0)
  111. {
  112. return null;
  113. }
  114. MessageHeaderInfo headerInfo = message.Headers[headerIndex];
  115. return CreateReceiveSecurityHeader(message,
  116. headerInfo.Actor, headerInfo.MustUnderstand, headerInfo.Relay,
  117. standardsManager, algorithmSuite,
  118. direction, headerIndex);
  119. }
  120. internal virtual void WriteSignatureConfirmation(XmlDictionaryWriter writer, string id, byte[] signatureConfirmation)
  121. {
  122. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
  123. SR.GetString(SR.SignatureConfirmationNotSupported)));
  124. }
  125. internal void WriteStartHeader(XmlDictionaryWriter writer)
  126. {
  127. writer.WriteStartElement(this.HeaderPrefix.Value, this.HeaderName, this.HeaderNamespace);
  128. }
  129. class SecurityVersion10 : SecurityVersion
  130. {
  131. static readonly SecurityVersion10 instance = new SecurityVersion10();
  132. protected SecurityVersion10()
  133. : base(XD.SecurityJan2004Dictionary.Security, XD.SecurityJan2004Dictionary.Namespace, XD.SecurityJan2004Dictionary.Prefix)
  134. {
  135. }
  136. public static SecurityVersion10 Instance
  137. {
  138. get { return instance; }
  139. }
  140. internal override XmlDictionaryString FailedAuthenticationFaultCode
  141. {
  142. get { return XD.SecurityJan2004Dictionary.FailedAuthenticationFaultCode; }
  143. }
  144. internal override XmlDictionaryString InvalidSecurityTokenFaultCode
  145. {
  146. get { return XD.SecurityJan2004Dictionary.InvalidSecurityTokenFaultCode; }
  147. }
  148. internal override XmlDictionaryString InvalidSecurityFaultCode
  149. {
  150. get { return XD.SecurityJan2004Dictionary.InvalidSecurityFaultCode; }
  151. }
  152. internal override SendSecurityHeader CreateSendSecurityHeader(Message message,
  153. string actor, bool mustUnderstand, bool relay,
  154. SecurityStandardsManager standardsManager,
  155. SecurityAlgorithmSuite algorithmSuite,
  156. MessageDirection direction)
  157. {
  158. return new WSSecurityOneDotZeroSendSecurityHeader(message, actor, mustUnderstand, relay, standardsManager, algorithmSuite, direction);
  159. }
  160. internal override ReceiveSecurityHeader CreateReceiveSecurityHeader(Message message,
  161. string actor, bool mustUnderstand, bool relay,
  162. SecurityStandardsManager standardsManager,
  163. SecurityAlgorithmSuite algorithmSuite,
  164. MessageDirection direction,
  165. int headerIndex)
  166. {
  167. return new WSSecurityOneDotZeroReceiveSecurityHeader(
  168. message,
  169. actor, mustUnderstand, relay,
  170. standardsManager,
  171. algorithmSuite, headerIndex, direction);
  172. }
  173. public override string ToString()
  174. {
  175. return "WSSecurity10";
  176. }
  177. }
  178. sealed class SecurityVersion11 : SecurityVersion10
  179. {
  180. static readonly SecurityVersion11 instance = new SecurityVersion11();
  181. SecurityVersion11()
  182. : base()
  183. {
  184. }
  185. public new static SecurityVersion11 Instance
  186. {
  187. get { return instance; }
  188. }
  189. internal override bool SupportsSignatureConfirmation
  190. {
  191. get { return true; }
  192. }
  193. internal override ReceiveSecurityHeader CreateReceiveSecurityHeader(Message message,
  194. string actor, bool mustUnderstand, bool relay,
  195. SecurityStandardsManager standardsManager,
  196. SecurityAlgorithmSuite algorithmSuite,
  197. MessageDirection direction,
  198. int headerIndex)
  199. {
  200. return new WSSecurityOneDotOneReceiveSecurityHeader(
  201. message,
  202. actor, mustUnderstand, relay,
  203. standardsManager,
  204. algorithmSuite, headerIndex, direction);
  205. }
  206. internal override SendSecurityHeader CreateSendSecurityHeader(Message message,
  207. string actor, bool mustUnderstand, bool relay,
  208. SecurityStandardsManager standardsManager,
  209. SecurityAlgorithmSuite algorithmSuite, MessageDirection direction)
  210. {
  211. return new WSSecurityOneDotOneSendSecurityHeader(message, actor, mustUnderstand, relay, standardsManager, algorithmSuite, direction);
  212. }
  213. internal override bool IsReaderAtSignatureConfirmation(XmlDictionaryReader reader)
  214. {
  215. return reader.IsStartElement(XD.SecurityXXX2005Dictionary.SignatureConfirmation, XD.SecurityXXX2005Dictionary.Namespace);
  216. }
  217. internal override ISignatureValueSecurityElement ReadSignatureConfirmation(XmlDictionaryReader reader)
  218. {
  219. reader.MoveToStartElement(XD.SecurityXXX2005Dictionary.SignatureConfirmation, XD.SecurityXXX2005Dictionary.Namespace);
  220. bool isEmptyElement = reader.IsEmptyElement;
  221. string id = XmlHelper.GetRequiredNonEmptyAttribute(reader, XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);
  222. byte[] signatureValue = XmlHelper.GetRequiredBase64Attribute(reader, XD.SecurityXXX2005Dictionary.ValueAttribute, null);
  223. reader.ReadStartElement();
  224. if (!isEmptyElement)
  225. {
  226. reader.ReadEndElement();
  227. }
  228. return new SignatureConfirmationElement(id, signatureValue, this);
  229. }
  230. internal override void WriteSignatureConfirmation(XmlDictionaryWriter writer, string id, byte[] signature)
  231. {
  232. if (id == null)
  233. {
  234. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("id");
  235. }
  236. if (signature == null)
  237. {
  238. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("signature");
  239. }
  240. writer.WriteStartElement(XD.SecurityXXX2005Dictionary.Prefix.Value, XD.SecurityXXX2005Dictionary.SignatureConfirmation, XD.SecurityXXX2005Dictionary.Namespace);
  241. writer.WriteAttributeString(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace, id);
  242. writer.WriteStartAttribute(XD.SecurityXXX2005Dictionary.ValueAttribute, null);
  243. writer.WriteBase64(signature, 0, signature.Length);
  244. writer.WriteEndAttribute();
  245. writer.WriteEndElement();
  246. }
  247. public override string ToString()
  248. {
  249. return "WSSecurity11";
  250. }
  251. }
  252. }
  253. }