WSSecurityTokenSerializer.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. //
  2. // WSSecurityTokenSerializer.cs
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. // Copyright (C) 2006-2007 Novell, Inc. http://www.novell.com
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Collections.Generic;
  30. using System.IdentityModel.Selectors;
  31. using System.IdentityModel.Tokens;
  32. using System.Security.Cryptography.X509Certificates;
  33. using System.Security.Cryptography.Xml;
  34. using System.ServiceModel.Security.Tokens;
  35. using System.Text;
  36. using System.Xml;
  37. namespace System.ServiceModel.Security
  38. {
  39. public class WSSecurityTokenSerializer : SecurityTokenSerializer
  40. {
  41. static WSSecurityTokenSerializer default_instance =
  42. new WSSecurityTokenSerializer ();
  43. public static WSSecurityTokenSerializer DefaultInstance {
  44. get { return default_instance; }
  45. }
  46. const int defaultOffset = 64,
  47. defaultLabelLength = 128,
  48. defaultNonceLength = 128;
  49. public WSSecurityTokenSerializer ()
  50. : this (false)
  51. {
  52. }
  53. public WSSecurityTokenSerializer (bool emitBspRequiredAttributes)
  54. : this (SecurityVersion.WSSecurity11, emitBspRequiredAttributes)
  55. {
  56. }
  57. public WSSecurityTokenSerializer (SecurityVersion securityVersion)
  58. : this (securityVersion, false)
  59. {
  60. }
  61. public WSSecurityTokenSerializer (SecurityVersion securityVersion, bool emitBspRequiredAttributes)
  62. : this (securityVersion, emitBspRequiredAttributes, new SamlSerializer ())
  63. {
  64. }
  65. public WSSecurityTokenSerializer (
  66. SecurityVersion securityVersion,
  67. bool emitBspRequiredAttributes,
  68. SamlSerializer samlSerializer)
  69. : this (securityVersion, emitBspRequiredAttributes,
  70. samlSerializer, null, null)
  71. {
  72. }
  73. public WSSecurityTokenSerializer (
  74. SecurityVersion securityVersion,
  75. bool emitBspRequiredAttributes,
  76. SamlSerializer samlSerializer,
  77. SecurityStateEncoder securityStateEncoder,
  78. IEnumerable<Type> knownTypes)
  79. : this (securityVersion, emitBspRequiredAttributes,
  80. samlSerializer, securityStateEncoder,
  81. knownTypes, defaultOffset, defaultLabelLength,
  82. defaultNonceLength)
  83. {
  84. }
  85. public WSSecurityTokenSerializer (
  86. SecurityVersion securityVersion,
  87. bool emitBspRequiredAttributes,
  88. SamlSerializer samlSerializer,
  89. SecurityStateEncoder securityStateEncoder,
  90. IEnumerable<Type> knownTypes,
  91. int maximumKeyDerivationOffset,
  92. int maximumKeyDerivationLabelLength,
  93. int maximumKeyDerivationNonceLength)
  94. {
  95. security_version = securityVersion;
  96. emit_bsp = emitBspRequiredAttributes;
  97. saml_serializer = samlSerializer;
  98. encoder = securityStateEncoder;
  99. known_types = new List<Type> (knownTypes ?? Type.EmptyTypes);
  100. max_offset = maximumKeyDerivationOffset;
  101. max_label_length = maximumKeyDerivationLabelLength;
  102. max_nonce_length = maximumKeyDerivationNonceLength;
  103. if (encoder == null)
  104. encoder = new DataProtectionSecurityStateEncoder ();
  105. }
  106. SecurityVersion security_version;
  107. bool emit_bsp;
  108. SamlSerializer saml_serializer;
  109. SecurityStateEncoder encoder;
  110. List<Type> known_types;
  111. int max_offset, max_label_length, max_nonce_length;
  112. bool WSS1_0 {
  113. get { return SecurityVersion == SecurityVersion.WSSecurity10; }
  114. }
  115. public bool EmitBspRequiredAttributes {
  116. get { return emit_bsp; }
  117. }
  118. public SecurityVersion SecurityVersion {
  119. get { return security_version; }
  120. }
  121. [MonoTODO]
  122. public int MaximumKeyDerivationOffset {
  123. get { return max_offset; }
  124. }
  125. [MonoTODO]
  126. public int MaximumKeyDerivationLabelLength {
  127. get { return max_label_length; }
  128. }
  129. [MonoTODO]
  130. public int MaximumKeyDerivationNonceLength {
  131. get { return max_nonce_length; }
  132. }
  133. protected virtual string GetTokenTypeUri (Type tokenType)
  134. {
  135. if (tokenType == typeof (WrappedKeySecurityToken))
  136. return Constants.WSSEncryptedKeyToken;
  137. if (tokenType == typeof (X509SecurityToken))
  138. return Constants.WSSX509Token;
  139. // if (tokenType == typeof (RsaSecurityToken))
  140. // return null;
  141. if (tokenType == typeof (SamlSecurityToken))
  142. return Constants.WSSSamlToken;
  143. if (tokenType == typeof (SecurityContextSecurityToken))
  144. return Constants.WsscContextToken;
  145. // if (tokenType == typeof (huh))
  146. // return ServiceModelSecurityTokenTypes.SecureConversation;
  147. // if (tokenType == typeof (hah))
  148. // return ServiceModelSecurityTokenTypes.MutualSslnego;
  149. // if (tokenType == typeof (whoa))
  150. // return ServiceModelSecurityTokenTypes.AnonymousSslnego;
  151. if (tokenType == typeof (UserNameSecurityToken))
  152. return Constants.WSSUserNameToken;
  153. // if (tokenType == typeof (uhoh))
  154. // return ServiceModelSecurityTokenTypes.Spnego;
  155. // if (tokenType == typeof (SspiSecurityToken))
  156. // return ServiceModelSecurityTokenTypes.SspiCredential;
  157. if (tokenType == typeof (KerberosRequestorSecurityToken))
  158. return Constants.WSSKerberosToken;
  159. return null;
  160. }
  161. [MonoTODO]
  162. protected override bool CanReadKeyIdentifierClauseCore (XmlReader reader)
  163. {
  164. reader.MoveToContent ();
  165. switch (reader.NamespaceURI) {
  166. case EncryptedXml.XmlEncNamespaceUrl:
  167. switch (reader.LocalName) {
  168. case "EncryptedKey":
  169. return true;
  170. }
  171. break;
  172. case Constants.WssNamespace:
  173. switch (reader.LocalName) {
  174. case "SecurityTokenReference":
  175. return true;
  176. }
  177. break;
  178. }
  179. return false;
  180. }
  181. [MonoTODO]
  182. protected override bool CanReadKeyIdentifierCore (XmlReader reader)
  183. {
  184. throw new NotImplementedException ();
  185. }
  186. [MonoTODO]
  187. protected override bool CanReadTokenCore (XmlReader reader)
  188. {
  189. reader.MoveToContent ();
  190. switch (reader.NamespaceURI) {
  191. case Constants.WssNamespace:
  192. switch (reader.LocalName) {
  193. case "BinarySecurityToken":
  194. case "BinarySecret":
  195. case "UsernameToken":
  196. return true;
  197. }
  198. break;
  199. case Constants.WsscNamespace:
  200. switch (reader.LocalName) {
  201. case "DerivedKeyToken":
  202. case "SecurityContextToken":
  203. return true;
  204. }
  205. break;
  206. case EncryptedXml.XmlEncNamespaceUrl:
  207. switch (reader.LocalName) {
  208. case "EncryptedKey":
  209. return true;
  210. }
  211. break;
  212. }
  213. return false;
  214. }
  215. [MonoTODO]
  216. public virtual SecurityKeyIdentifierClause CreateKeyIdentifierClauseFromTokenXml (
  217. XmlElement tokenXml, SecurityTokenReferenceStyle referenceStyle)
  218. {
  219. throw new NotImplementedException ();
  220. }
  221. [MonoTODO]
  222. protected override SecurityKeyIdentifier ReadKeyIdentifierCore (
  223. XmlReader reader)
  224. {
  225. throw new NotImplementedException ();
  226. }
  227. [MonoTODO]
  228. protected override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore (XmlReader reader)
  229. {
  230. reader.MoveToContent ();
  231. switch (reader.NamespaceURI) {
  232. case EncryptedXml.XmlEncNamespaceUrl:
  233. switch (reader.LocalName) {
  234. case "EncryptedKey":
  235. return ReadEncryptedKeyIdentifierClause (reader);
  236. }
  237. break;
  238. case Constants.WssNamespace:
  239. switch (reader.LocalName) {
  240. case "SecurityTokenReference":
  241. return ReadSecurityTokenReference (reader);
  242. }
  243. break;
  244. }
  245. throw new NotImplementedException (String.Format ("Security key identifier clause element '{0}' in namespace '{1}' is either not implemented or not supported.", reader.LocalName, reader.NamespaceURI));
  246. }
  247. SecurityKeyIdentifierClause ReadSecurityTokenReference (XmlReader reader)
  248. {
  249. reader.ReadStartElement ();
  250. reader.MoveToContent ();
  251. if (reader.NamespaceURI == SignedXml.XmlDsigNamespaceUrl) {
  252. KeyInfoX509Data x509 = new KeyInfoX509Data ();
  253. x509.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement);
  254. if (x509.IssuerSerials.Count == 0)
  255. throw new XmlException ("'X509IssuerSerial' element is expected inside 'X509Data' element");
  256. X509IssuerSerial s = (X509IssuerSerial) x509.IssuerSerials [0];
  257. reader.MoveToContent ();
  258. reader.ReadEndElement ();
  259. return new X509IssuerSerialKeyIdentifierClause (s.IssuerName, s.SerialNumber);
  260. }
  261. if (reader.NamespaceURI != Constants.WssNamespace)
  262. throw new XmlException (String.Format ("Unexpected SecurityTokenReference content: expected local name 'Reference' and namespace URI '{0}' but found local name '{1}' and namespace '{2}'.", Constants.WssNamespace, reader.LocalName, reader.NamespaceURI));
  263. switch (reader.LocalName) {
  264. case "Reference":
  265. Type ownerType = null;
  266. // FIXME: there could be more token types.
  267. if (reader.MoveToAttribute ("ValueType")) {
  268. switch (reader.Value) {
  269. case Constants.WSSEncryptedKeyToken:
  270. ownerType = typeof (WrappedKeySecurityToken);
  271. break;
  272. case Constants.WSSX509Token:
  273. ownerType = typeof (X509SecurityToken);
  274. break;
  275. case Constants.WsscContextToken:
  276. ownerType = typeof (SecurityContextSecurityToken);
  277. break;
  278. default:
  279. throw new XmlException (String.Format ("Unexpected ValueType in 'Reference' element: '{0}'", reader.Value));
  280. }
  281. }
  282. reader.MoveToElement ();
  283. string uri = reader.GetAttribute ("URI");
  284. if (String.IsNullOrEmpty (uri))
  285. uri = "#";
  286. SecurityKeyIdentifierClause ic = null;
  287. if (ownerType == typeof (SecurityContextSecurityToken) && uri [0] != '#')
  288. // FIXME: Generation?
  289. ic = new SecurityContextKeyIdentifierClause (new UniqueId (uri));
  290. else
  291. ic = new LocalIdKeyIdentifierClause (uri.Substring (1), ownerType);
  292. reader.Skip ();
  293. reader.MoveToContent ();
  294. reader.ReadEndElement ();
  295. return ic;
  296. case "KeyIdentifier":
  297. string valueType = reader.GetAttribute ("ValueType");
  298. string value = reader.ReadElementContentAsString ();
  299. reader.MoveToContent ();
  300. reader.ReadEndElement (); // consume </Reference>
  301. switch (valueType) {
  302. case Constants.WssKeyIdentifierX509Thumbptint:
  303. return new X509ThumbprintKeyIdentifierClause (Convert.FromBase64String (value));
  304. case Constants.WssKeyIdentifierEncryptedKey:
  305. return new InternalEncryptedKeyIdentifierClause (Convert.FromBase64String (value));
  306. case Constants.WssKeyIdentifierSamlAssertion:
  307. return new SamlAssertionKeyIdentifierClause (value);
  308. default:
  309. // It is kinda weird but it throws XmlException here ...
  310. throw new XmlException (String.Format ("KeyIdentifier type '{0}' is not supported in WSSecurityTokenSerializer.", valueType));
  311. }
  312. default:
  313. throw new XmlException (String.Format ("Unexpected SecurityTokenReference content: expected local name 'Reference' and namespace URI '{0}' but found local name '{1}' and namespace '{2}'.", Constants.WssNamespace, reader.LocalName, reader.NamespaceURI));
  314. }
  315. }
  316. EncryptedKeyIdentifierClause ReadEncryptedKeyIdentifierClause (
  317. XmlReader reader)
  318. {
  319. string encNS = EncryptedXml.XmlEncNamespaceUrl;
  320. string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
  321. reader.Read ();
  322. reader.MoveToContent ();
  323. string encMethod = reader.GetAttribute ("Algorithm");
  324. bool isEmpty = reader.IsEmptyElement;
  325. reader.ReadStartElement ("EncryptionMethod", encNS);
  326. string digMethod = null;
  327. if (!isEmpty) {
  328. reader.MoveToContent ();
  329. if (reader.LocalName == "DigestMethod" && reader.NamespaceURI == SignedXml.XmlDsigNamespaceUrl)
  330. digMethod = reader.GetAttribute ("Algorithm");
  331. while (reader.NodeType != XmlNodeType.EndElement) {
  332. reader.Skip ();
  333. reader.MoveToContent ();
  334. }
  335. reader.ReadEndElement ();
  336. }
  337. reader.MoveToContent ();
  338. SecurityKeyIdentifier ki = null;
  339. if (!reader.IsEmptyElement) {
  340. reader.ReadStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
  341. reader.MoveToContent ();
  342. SecurityKeyIdentifierClause kic = ReadKeyIdentifierClauseCore (reader);
  343. ki = new SecurityKeyIdentifier ();
  344. ki.Add (kic);
  345. reader.MoveToContent ();
  346. reader.ReadEndElement (); // </ds:KeyInfo>
  347. reader.MoveToContent ();
  348. }
  349. byte [] keyValue = null;
  350. if (!reader.IsEmptyElement) {
  351. reader.ReadStartElement ("CipherData", encNS);
  352. reader.MoveToContent ();
  353. keyValue = Convert.FromBase64String (reader.ReadElementContentAsString ("CipherValue", encNS));
  354. reader.MoveToContent ();
  355. reader.ReadEndElement (); // CipherData
  356. }
  357. string carriedKeyName = null;
  358. if (!reader.IsEmptyElement && reader.LocalName == "CarriedKeyName" && reader.NamespaceURI == encNS) {
  359. carriedKeyName = reader.ReadElementContentAsString ();
  360. reader.MoveToContent ();
  361. }
  362. // FIXME: handle derived keys??
  363. return new EncryptedKeyIdentifierClause (keyValue, encMethod, ki, carriedKeyName);
  364. }
  365. [MonoTODO]
  366. protected override SecurityToken ReadTokenCore (
  367. XmlReader reader,
  368. SecurityTokenResolver tokenResolver)
  369. {
  370. if (!CanReadToken (reader))
  371. throw new XmlException (String.Format ("Cannot read security token from {0} node of name '{1}' and namespace URI '{2}'", reader.NodeType, reader.LocalName, reader.NamespaceURI));
  372. switch (reader.NamespaceURI) {
  373. case Constants.WssNamespace:
  374. switch (reader.LocalName) {
  375. case "BinarySecurityToken":
  376. return ReadX509TokenCore (reader, tokenResolver);
  377. case "BinarySecret":
  378. return ReadBinarySecretTokenCore (reader, tokenResolver);
  379. case "UsernameToken":
  380. return ReadUserNameTokenCore (reader, tokenResolver);
  381. }
  382. break;
  383. case Constants.WsscNamespace:
  384. if (reader.LocalName == "DerivedKeyToken")
  385. return ReadDerivedKeyToken (reader, tokenResolver);
  386. if (reader.LocalName == "SecurityContextToken")
  387. return ReadSecurityContextToken (reader, tokenResolver);
  388. break;
  389. case EncryptedXml.XmlEncNamespaceUrl:
  390. switch (reader.LocalName) {
  391. case "EncryptedKey":
  392. return ReadWrappedKeySecurityTokenCore (reader, tokenResolver);
  393. }
  394. break;
  395. }
  396. throw new NotImplementedException ();
  397. }
  398. DerivedKeySecurityToken ReadDerivedKeyToken (
  399. XmlReader reader, SecurityTokenResolver tokenResolver)
  400. {
  401. try {
  402. return ReadDerivedKeyTokenCore (reader, tokenResolver);
  403. } catch (XmlException) {
  404. throw;
  405. } catch (Exception ex) {
  406. throw new XmlException ("Cannot read DerivedKeyToken", ex);
  407. }
  408. }
  409. DerivedKeySecurityToken ReadDerivedKeyTokenCore (
  410. XmlReader reader, SecurityTokenResolver tokenResolver)
  411. {
  412. if (tokenResolver == null)
  413. throw new ArgumentNullException ("tokenResolver");
  414. string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
  415. string algorithm = reader.MoveToAttribute ("Algorithm") ? reader.Value : null;
  416. reader.MoveToElement ();
  417. reader.ReadStartElement ();
  418. reader.MoveToContent ();
  419. SecurityKeyIdentifierClause kic = ReadKeyIdentifierClause (reader);
  420. int? generation = null, offset = null, length = null;
  421. byte [] nonce = null;
  422. string name = null, label = null;
  423. for (reader.MoveToContent ();
  424. reader.NodeType != XmlNodeType.EndElement;
  425. reader.MoveToContent ())
  426. switch (reader.LocalName) {
  427. case "Properties":
  428. reader.ReadStartElement ("Properties", Constants.WsscNamespace);
  429. for (reader.MoveToContent ();
  430. reader.NodeType != XmlNodeType.EndElement;
  431. reader.MoveToContent ())
  432. switch (reader.LocalName) {
  433. case "Name":
  434. name = reader.ReadElementContentAsString ("Name", Constants.WsscNamespace);
  435. break;
  436. case "Label":
  437. label = reader.ReadElementContentAsString ("Label", Constants.WsscNamespace);
  438. break;
  439. case "Nonce":
  440. nonce = Convert.FromBase64String (reader.ReadElementContentAsString ("Nonce", Constants.WsscNamespace));
  441. break;
  442. }
  443. reader.ReadEndElement ();
  444. break;
  445. case "Offset":
  446. offset = reader.ReadElementContentAsInt ("Offset", Constants.WsscNamespace);
  447. break;
  448. case "Length":
  449. length = reader.ReadElementContentAsInt ("Length", Constants.WsscNamespace);
  450. break;
  451. case "Nonce":
  452. nonce = Convert.FromBase64String (reader.ReadElementContentAsString ("Nonce", Constants.WsscNamespace));
  453. break;
  454. case "Label":
  455. label = reader.ReadElementContentAsString ("Label", Constants.WsscNamespace);
  456. break;
  457. }
  458. reader.ReadEndElement ();
  459. // resolve key reference
  460. SymmetricSecurityKey key = tokenResolver.ResolveSecurityKey (kic) as SymmetricSecurityKey;
  461. if (key == null)
  462. throw new XmlException ("Cannot resolve the security key referenced by the DerivedKeyToken as a symmetric key");
  463. return new DerivedKeySecurityToken (id, algorithm, kic, key, name, generation, offset, length, label, nonce);
  464. }
  465. // since it cannot consume RequestSecurityTokenResponse,
  466. // the token information cannot be complete.
  467. SecurityContextSecurityToken ReadSecurityContextToken (
  468. XmlReader reader, SecurityTokenResolver tokenResolver)
  469. {
  470. string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
  471. reader.Read ();
  472. // The input dnse:Cookie value is encrypted by the
  473. // server's SecurityStateEncoder
  474. // (setting error-raising encoder to ServiceCredentials.
  475. // SecureConversationAuthentication.SecurityStateEncoder
  476. // shows it).
  477. UniqueId cid = null;
  478. byte [] cookie = null;
  479. while (true) {
  480. reader.MoveToContent ();
  481. if (reader.NodeType != XmlNodeType.Element)
  482. break;
  483. switch (reader.NamespaceURI) {
  484. case Constants.WsscNamespace:
  485. switch (reader.LocalName) {
  486. case "Identifier":
  487. cid = new UniqueId (reader.ReadElementContentAsString ());
  488. continue;
  489. }
  490. break;
  491. case Constants.MSTlsnegoTokenContent:
  492. switch (reader.LocalName) {
  493. case "Cookie":
  494. cookie = Convert.FromBase64String (reader.ReadElementContentAsString ());
  495. continue;
  496. }
  497. break;
  498. }
  499. throw new XmlException (String.Format ("Unexpected element {0} in namespace {1}", reader.LocalName, reader.NamespaceURI));
  500. }
  501. reader.ReadEndElement ();
  502. // LAMESPEC: at client side there is no way to specify
  503. // SecurityStateEncoder, so it must be guessed from
  504. // its cookie content itself.
  505. if (encoder == null) throw new Exception ();
  506. byte [] decoded =
  507. cookie != null && cookie.Length > 154 ?
  508. encoder.DecodeSecurityState (cookie) :
  509. cookie;
  510. return SslnegoCookieResolver.ResolveCookie (decoded, cookie);
  511. }
  512. WrappedKeySecurityToken ReadWrappedKeySecurityTokenCore (
  513. XmlReader reader, SecurityTokenResolver tokenResolver)
  514. {
  515. if (tokenResolver == null)
  516. throw new ArgumentNullException ("tokenResolver");
  517. EncryptedKey ek = new EncryptedKey ();
  518. ek.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement);
  519. SecurityKeyIdentifier ki = new SecurityKeyIdentifier ();
  520. foreach (KeyInfoClause kic in ek.KeyInfo)
  521. ki.Add (ReadKeyIdentifierClause (new XmlNodeReader (kic.GetXml ())));
  522. SecurityToken token = tokenResolver.ResolveToken (ki);
  523. string alg = ek.EncryptionMethod.KeyAlgorithm;
  524. foreach (SecurityKey skey in token.SecurityKeys)
  525. if (skey.IsSupportedAlgorithm (alg)) {
  526. byte [] key = skey.DecryptKey (alg, ek.CipherData.CipherValue);
  527. WrappedKeySecurityToken wk =
  528. new WrappedKeySecurityToken (ek.Id, key, alg, token, ki);
  529. // FIXME: This should not be required.
  530. wk.SetWrappedKey (ek.CipherData.CipherValue);
  531. wk.ReferenceList = ek.ReferenceList;
  532. return wk;
  533. }
  534. throw new InvalidOperationException (String.Format ("Cannot resolve security key with the resolved SecurityToken specified by the key identifier in the EncryptedKey XML. The key identifier is: {0}", ki));
  535. }
  536. X509SecurityToken ReadX509TokenCore (
  537. XmlReader reader, SecurityTokenResolver resolver)
  538. {
  539. string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
  540. byte [] raw = Convert.FromBase64String (reader.ReadElementContentAsString ());
  541. return new X509SecurityToken (new X509Certificate2 (raw), id);
  542. }
  543. UserNameSecurityToken ReadUserNameTokenCore (
  544. XmlReader reader, SecurityTokenResolver resolver)
  545. {
  546. string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
  547. if (reader.IsEmptyElement)
  548. throw new XmlException ("At least UsernameToken must contain Username");
  549. reader.Read ();
  550. reader.MoveToContent ();
  551. string user = reader.ReadElementContentAsString ("Username", Constants.WssNamespace);
  552. reader.MoveToContent ();
  553. string pass = null;
  554. if (reader.LocalName == "Password" && reader.NamespaceURI == Constants.WssNamespace) {
  555. pass = reader.ReadElementContentAsString ("Password", Constants.WssNamespace);
  556. reader.MoveToContent ();
  557. }
  558. reader.ReadEndElement ();
  559. return id != null ?
  560. new UserNameSecurityToken (user, pass, id) :
  561. new UserNameSecurityToken (user, pass);
  562. }
  563. BinarySecretSecurityToken ReadBinarySecretTokenCore (
  564. XmlReader reader, SecurityTokenResolver resolver)
  565. {
  566. string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
  567. byte [] data = Convert.FromBase64String (reader.ReadElementContentAsString ());
  568. return new BinarySecretSecurityToken (id, data);
  569. }
  570. [MonoTODO]
  571. protected override bool CanWriteKeyIdentifierCore (
  572. SecurityKeyIdentifier keyIdentifier)
  573. {
  574. throw new NotImplementedException ();
  575. }
  576. [MonoTODO]
  577. protected override bool CanWriteKeyIdentifierClauseCore (
  578. SecurityKeyIdentifierClause keyIdentifierClause)
  579. {
  580. if (keyIdentifierClause == null)
  581. throw new ArgumentNullException ("keyIdentifierClause");
  582. if (keyIdentifierClause is LocalIdKeyIdentifierClause ||
  583. keyIdentifierClause is SecurityContextKeyIdentifierClause ||
  584. keyIdentifierClause is X509IssuerSerialKeyIdentifierClause ||
  585. (keyIdentifierClause is X509ThumbprintKeyIdentifierClause && !WSS1_0) ||
  586. keyIdentifierClause is EncryptedKeyIdentifierClause ||
  587. keyIdentifierClause is BinarySecretKeyIdentifierClause ||
  588. keyIdentifierClause is InternalEncryptedKeyIdentifierClause ||
  589. keyIdentifierClause is SamlAssertionKeyIdentifierClause)
  590. return true;
  591. else
  592. return false;
  593. }
  594. [MonoTODO]
  595. protected override bool CanWriteTokenCore (SecurityToken token)
  596. {
  597. throw new NotImplementedException ();
  598. }
  599. [MonoTODO]
  600. protected override void WriteKeyIdentifierCore (
  601. XmlWriter writer,
  602. SecurityKeyIdentifier keyIdentifier)
  603. {
  604. throw new NotImplementedException ();
  605. }
  606. [MonoTODO]
  607. protected override void WriteKeyIdentifierClauseCore (
  608. XmlWriter writer,
  609. SecurityKeyIdentifierClause keyIdentifierClause)
  610. {
  611. string errorReason = null;
  612. if (keyIdentifierClause == null)
  613. throw new ArgumentNullException ("keyIdentifierClause");
  614. if (keyIdentifierClause is LocalIdKeyIdentifierClause)
  615. WriteLocalIdKeyIdentifierClause (writer, (LocalIdKeyIdentifierClause) keyIdentifierClause);
  616. else if (keyIdentifierClause is SecurityContextKeyIdentifierClause)
  617. WriteSecurityContextKeyIdentifierClause (writer, (SecurityContextKeyIdentifierClause) keyIdentifierClause);
  618. else if (keyIdentifierClause is X509IssuerSerialKeyIdentifierClause)
  619. WriteX509IssuerSerialKeyIdentifierClause (writer, (X509IssuerSerialKeyIdentifierClause) keyIdentifierClause);
  620. else if (keyIdentifierClause is X509ThumbprintKeyIdentifierClause) {
  621. if (WSS1_0)
  622. errorReason = String.Format ("Security key identifier clause '{0}' is not supported in this serializer.", keyIdentifierClause.GetType ());
  623. else
  624. WriteX509ThumbprintKeyIdentifierClause (writer, (X509ThumbprintKeyIdentifierClause) keyIdentifierClause);
  625. }
  626. else if (keyIdentifierClause is EncryptedKeyIdentifierClause)
  627. WriteEncryptedKeyIdentifierClause (writer, (EncryptedKeyIdentifierClause) keyIdentifierClause);
  628. else if (keyIdentifierClause is BinarySecretKeyIdentifierClause)
  629. WriteBinarySecretKeyIdentifierClause (writer, (BinarySecretKeyIdentifierClause) keyIdentifierClause);
  630. else if (keyIdentifierClause is InternalEncryptedKeyIdentifierClause)
  631. WriteInternalEncryptedKeyIdentifierClause (writer, (InternalEncryptedKeyIdentifierClause) keyIdentifierClause);
  632. else if (keyIdentifierClause is SamlAssertionKeyIdentifierClause)
  633. WriteSamlAssertionKeyIdentifierClause (writer, (SamlAssertionKeyIdentifierClause) keyIdentifierClause);
  634. else
  635. throw new NotImplementedException (String.Format ("Security key identifier clause '{0}' is not either implemented or supported.", keyIdentifierClause.GetType ()));
  636. if (errorReason != null)
  637. throw new InvalidOperationException (errorReason);
  638. }
  639. void WriteX509IssuerSerialKeyIdentifierClause (
  640. XmlWriter w, X509IssuerSerialKeyIdentifierClause ic)
  641. {
  642. w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
  643. w.WriteStartElement ("X509Data", Constants.XmlDsig);
  644. w.WriteStartElement ("X509IssuerSerial", Constants.XmlDsig);
  645. w.WriteStartElement ("X509IssuerName", Constants.XmlDsig);
  646. w.WriteString (ic.IssuerName);
  647. w.WriteEndElement ();
  648. w.WriteStartElement ("X509SerialNumber", Constants.XmlDsig);
  649. w.WriteString (ic.IssuerSerialNumber);
  650. w.WriteEndElement ();
  651. w.WriteEndElement ();
  652. w.WriteEndElement ();
  653. w.WriteEndElement ();
  654. }
  655. void WriteX509ThumbprintKeyIdentifierClause (
  656. XmlWriter w, X509ThumbprintKeyIdentifierClause ic)
  657. {
  658. w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
  659. w.WriteStartElement ("o", "KeyIdentifier", Constants.WssNamespace);
  660. w.WriteAttributeString ("ValueType", Constants.WssKeyIdentifierX509Thumbptint);
  661. if (EmitBspRequiredAttributes)
  662. w.WriteAttributeString ("EncodingType", Constants.WssBase64BinaryEncodingType);
  663. w.WriteString (Convert.ToBase64String (ic.GetX509Thumbprint ()));
  664. w.WriteEndElement ();
  665. w.WriteEndElement ();
  666. }
  667. void WriteLocalIdKeyIdentifierClause (
  668. XmlWriter w, LocalIdKeyIdentifierClause ic)
  669. {
  670. w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
  671. w.WriteStartElement ("o", "Reference", Constants.WssNamespace);
  672. if (EmitBspRequiredAttributes && ic.OwnerType != null) {
  673. string vt = GetTokenTypeUri (ic.OwnerType);
  674. if (vt != null)
  675. w.WriteAttributeString ("ValueType", vt);
  676. }
  677. w.WriteAttributeString ("URI", "#" + ic.LocalId);
  678. w.WriteEndElement ();
  679. w.WriteEndElement ();
  680. }
  681. void WriteSecurityContextKeyIdentifierClause (
  682. XmlWriter w, SecurityContextKeyIdentifierClause ic)
  683. {
  684. w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
  685. w.WriteStartElement ("o", "Reference", Constants.WssNamespace);
  686. w.WriteAttributeString ("URI", ic.ContextId.ToString ());
  687. string vt = GetTokenTypeUri (typeof (SecurityContextSecurityToken));
  688. w.WriteAttributeString ("ValueType", vt);
  689. w.WriteEndElement ();
  690. w.WriteEndElement ();
  691. }
  692. void WriteEncryptedKeyIdentifierClause (
  693. XmlWriter w, EncryptedKeyIdentifierClause ic)
  694. {
  695. w.WriteStartElement ("e", "EncryptedKey", EncryptedXml.XmlEncNamespaceUrl);
  696. w.WriteStartElement ("EncryptionMethod", EncryptedXml.XmlEncNamespaceUrl);
  697. w.WriteAttributeString ("Algorithm", ic.EncryptionMethod);
  698. w.WriteEndElement ();
  699. if (ic.EncryptingKeyIdentifier != null) {
  700. w.WriteStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
  701. foreach (SecurityKeyIdentifierClause ckic in ic.EncryptingKeyIdentifier)
  702. WriteKeyIdentifierClause (w, ckic);
  703. w.WriteEndElement ();
  704. }
  705. w.WriteStartElement ("CipherData", EncryptedXml.XmlEncNamespaceUrl);
  706. w.WriteStartElement ("CipherValue", EncryptedXml.XmlEncNamespaceUrl);
  707. w.WriteString (Convert.ToBase64String (ic.GetEncryptedKey ()));
  708. w.WriteEndElement ();
  709. w.WriteEndElement ();
  710. if (ic.CarriedKeyName != null)
  711. w.WriteElementString ("CarriedKeyName", EncryptedXml.XmlEncNamespaceUrl, ic.CarriedKeyName);
  712. w.WriteEndElement ();
  713. }
  714. void WriteBinarySecretKeyIdentifierClause (
  715. XmlWriter w, BinarySecretKeyIdentifierClause ic)
  716. {
  717. w.WriteStartElement ("t", "BinarySecret", Constants.WstNamespace);
  718. w.WriteString (Convert.ToBase64String (ic.GetBuffer ()));
  719. w.WriteEndElement ();
  720. }
  721. void WriteInternalEncryptedKeyIdentifierClause (
  722. XmlWriter w, InternalEncryptedKeyIdentifierClause ic)
  723. {
  724. w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
  725. w.WriteStartElement ("o", "KeyIdentifier", Constants.WssNamespace);
  726. w.WriteAttributeString ("ValueType", Constants.WssKeyIdentifierEncryptedKey);
  727. w.WriteString (Convert.ToBase64String (ic.GetBuffer ()));
  728. w.WriteEndElement ();
  729. w.WriteEndElement ();
  730. }
  731. void WriteSamlAssertionKeyIdentifierClause (XmlWriter w, SamlAssertionKeyIdentifierClause ic)
  732. {
  733. w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
  734. w.WriteStartElement ("o", "KeyIdentifier", Constants.WssNamespace);
  735. w.WriteAttributeString ("ValueType", Constants.WssKeyIdentifierSamlAssertion);
  736. w.WriteString (ic.AssertionId);
  737. w.WriteEndElement ();
  738. w.WriteEndElement ();
  739. }
  740. [MonoTODO]
  741. protected override void WriteTokenCore (
  742. XmlWriter writer, SecurityToken token)
  743. {
  744. // WSSecurity supports:
  745. // - UsernameToken : S.IM.T.UserNameSecurityToken
  746. // - X509SecurityToken : S.IM.T.X509SecurityToken
  747. // - SAML Assertion : S.IM.T.SamlSecurityToken
  748. // - Kerberos : S.IM.T.KerberosRequestorSecurityToken
  749. // - Rights Expression Language (REL) : N/A
  750. // - SOAP with Attachments : N/A
  751. // they are part of standards support:
  752. // - WrappedKey (EncryptedKey)
  753. // - BinarySecret (WS-Trust)
  754. // - SecurityContext (WS-SecureConversation)
  755. // additionally there are extra token types in WCF:
  756. // - GenericXml
  757. // - Windows
  758. // - Sspi
  759. // not supported in this class:
  760. // - Rsa
  761. if (token is UserNameSecurityToken)
  762. WriteUserNameSecurityToken (writer, ((UserNameSecurityToken) token));
  763. else if (token is X509SecurityToken)
  764. WriteX509SecurityToken (writer, ((X509SecurityToken) token));
  765. else if (token is BinarySecretSecurityToken)
  766. WriteBinarySecretSecurityToken (writer, ((BinarySecretSecurityToken) token));
  767. else if (token is SamlSecurityToken)
  768. throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
  769. else if (token is GenericXmlSecurityToken)
  770. ((GenericXmlSecurityToken) token).TokenXml.WriteTo (writer);
  771. else if (token is WrappedKeySecurityToken)
  772. WriteWrappedKeySecurityToken (writer, (WrappedKeySecurityToken) token);
  773. else if (token is DerivedKeySecurityToken)
  774. WriteDerivedKeySecurityToken (writer, (DerivedKeySecurityToken) token);
  775. else if (token is SecurityContextSecurityToken)
  776. WriteSecurityContextSecurityToken (writer, (SecurityContextSecurityToken) token);
  777. else if (token is SspiSecurityToken)
  778. throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
  779. else if (token is KerberosRequestorSecurityToken)
  780. throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
  781. else if (token is WindowsSecurityToken)
  782. throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
  783. else
  784. throw new InvalidOperationException (String.Format ("This SecurityTokenSerializer does not support security token '{0}'.", token));
  785. }
  786. void WriteUserNameSecurityToken (XmlWriter w, UserNameSecurityToken token)
  787. {
  788. w.WriteStartElement ("o", "UsernameToken", Constants.WssNamespace);
  789. w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
  790. w.WriteStartElement ("o", "Username", Constants.WssNamespace);
  791. w.WriteString (token.UserName);
  792. w.WriteEndElement ();
  793. w.WriteStartElement ("o", "Password", Constants.WssNamespace);
  794. w.WriteString (token.Password);
  795. w.WriteEndElement ();
  796. w.WriteEndElement ();
  797. }
  798. void WriteX509SecurityToken (XmlWriter w, X509SecurityToken token)
  799. {
  800. w.WriteStartElement ("o", "BinarySecurityToken", Constants.WssNamespace);
  801. w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
  802. w.WriteAttributeString ("ValueType", Constants.WSSX509Token);
  803. w.WriteString (Convert.ToBase64String (token.Certificate.RawData));
  804. w.WriteEndElement ();
  805. }
  806. void WriteBinarySecretSecurityToken (XmlWriter w, BinarySecretSecurityToken token)
  807. {
  808. w.WriteStartElement ("t", "BinarySecret", Constants.WstNamespace);
  809. w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
  810. w.WriteString (Convert.ToBase64String (token.GetKeyBytes ()));
  811. w.WriteEndElement ();
  812. }
  813. void WriteDerivedKeySecurityToken (XmlWriter w, DerivedKeySecurityToken token)
  814. {
  815. string ns = Constants.WsscNamespace;
  816. w.WriteStartElement ("c", "DerivedKeyToken", ns);
  817. w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
  818. WriteKeyIdentifierClause (w, token.TokenReference);
  819. if (token.Name != null) {
  820. w.WriteStartElement ("Properties", ns);
  821. w.WriteElementString ("Name", ns, token.Name);
  822. w.WriteEndElement ();
  823. }
  824. if (token.Offset != null)
  825. w.WriteElementString ("Offset", ns, Convert.ToString (token.Offset));
  826. if (token.Length != null)
  827. w.WriteElementString ("Length", ns, Convert.ToString (token.Length));
  828. if (token.Label != null)
  829. w.WriteElementString ("Label", ns, token.Label);
  830. w.WriteElementString ("Nonce", ns, Convert.ToBase64String (token.Nonce));
  831. w.WriteEndElement ();
  832. }
  833. void WriteWrappedKeySecurityToken (XmlWriter w, WrappedKeySecurityToken token)
  834. {
  835. string encNS = EncryptedXml.XmlEncNamespaceUrl;
  836. w.WriteStartElement ("e", "EncryptedKey", encNS);
  837. w.WriteAttributeString ("Id", token.Id);
  838. w.WriteStartElement ("EncryptionMethod", encNS);
  839. w.WriteAttributeString ("Algorithm", token.WrappingAlgorithm);
  840. w.WriteStartElement ("DigestMethod", SignedXml.XmlDsigNamespaceUrl);
  841. w.WriteAttributeString ("Algorithm", SignedXml.XmlDsigSHA1Url);
  842. w.WriteEndElement ();
  843. w.WriteEndElement ();
  844. w.WriteStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
  845. if (token.WrappingTokenReference != null)
  846. foreach (SecurityKeyIdentifierClause kic in token.WrappingTokenReference)
  847. WriteKeyIdentifierClause (w, kic);
  848. w.WriteEndElement ();
  849. w.WriteStartElement ("CipherData", encNS);
  850. w.WriteStartElement ("CipherValue", encNS);
  851. w.WriteString (Convert.ToBase64String (token.GetWrappedKey ()));
  852. w.WriteEndElement ();
  853. w.WriteEndElement ();
  854. if (token.ReferenceList != null) {
  855. w.WriteStartElement ("e", "ReferenceList", encNS);
  856. foreach (DataReference er in token.ReferenceList) {
  857. w.WriteStartElement ("DataReference", encNS);
  858. w.WriteAttributeString ("URI", er.Uri);
  859. w.WriteEndElement ();
  860. }
  861. w.WriteEndElement ();
  862. }
  863. w.WriteEndElement ();
  864. }
  865. void WriteSecurityContextSecurityToken (XmlWriter w, SecurityContextSecurityToken token)
  866. {
  867. string ns = Constants.WsscNamespace;
  868. w.WriteStartElement ("c", "SecurityContextToken", ns);
  869. w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
  870. w.WriteElementString ("Identifier", ns, token.ContextId.ToString ());
  871. // FIXME: add Cookie output (from CreateCookieSecurityContextToken() method)
  872. if (token.Cookie != null)
  873. w.WriteElementString ("dnse", "Cookie", Constants.MSTlsnegoTokenContent, Convert.ToBase64String (token.Cookie));
  874. w.WriteEndElement ();
  875. }
  876. }
  877. }