| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947 |
- //
- // WSSecurityTokenSerializer.cs
- //
- // Author:
- // Atsushi Enomoto <[email protected]>
- //
- // Copyright (C) 2006-2007 Novell, Inc. http://www.novell.com
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Collections.Generic;
- using System.IdentityModel.Selectors;
- using System.IdentityModel.Tokens;
- using System.Security.Cryptography.X509Certificates;
- using System.Security.Cryptography.Xml;
- using System.ServiceModel.Security.Tokens;
- using System.Text;
- using System.Xml;
- namespace System.ServiceModel.Security
- {
- public class WSSecurityTokenSerializer : SecurityTokenSerializer
- {
- static WSSecurityTokenSerializer default_instance =
- new WSSecurityTokenSerializer ();
- public static WSSecurityTokenSerializer DefaultInstance {
- get { return default_instance; }
- }
- const int defaultOffset = 64,
- defaultLabelLength = 128,
- defaultNonceLength = 128;
- public WSSecurityTokenSerializer ()
- : this (false)
- {
- }
- public WSSecurityTokenSerializer (bool emitBspRequiredAttributes)
- : this (SecurityVersion.WSSecurity11, emitBspRequiredAttributes)
- {
- }
- public WSSecurityTokenSerializer (SecurityVersion securityVersion)
- : this (securityVersion, false)
- {
- }
- public WSSecurityTokenSerializer (SecurityVersion securityVersion, bool emitBspRequiredAttributes)
- : this (securityVersion, emitBspRequiredAttributes, new SamlSerializer ())
- {
- }
- public WSSecurityTokenSerializer (
- SecurityVersion securityVersion,
- bool emitBspRequiredAttributes,
- SamlSerializer samlSerializer)
- : this (securityVersion, emitBspRequiredAttributes,
- samlSerializer, null, null)
- {
- }
- public WSSecurityTokenSerializer (
- SecurityVersion securityVersion,
- bool emitBspRequiredAttributes,
- SamlSerializer samlSerializer,
- SecurityStateEncoder securityStateEncoder,
- IEnumerable<Type> knownTypes)
- : this (securityVersion, emitBspRequiredAttributes,
- samlSerializer, securityStateEncoder,
- knownTypes, defaultOffset, defaultLabelLength,
- defaultNonceLength)
- {
- }
-
- public WSSecurityTokenSerializer (
- SecurityVersion securityVersion,
- bool emitBspRequiredAttributes,
- SamlSerializer samlSerializer,
- SecurityStateEncoder securityStateEncoder,
- IEnumerable<Type> knownTypes,
- int maximumKeyDerivationOffset,
- int maximumKeyDerivationLabelLength,
- int maximumKeyDerivationNonceLength)
- {
- security_version = securityVersion;
- emit_bsp = emitBspRequiredAttributes;
- saml_serializer = samlSerializer;
- encoder = securityStateEncoder;
- known_types = new List<Type> (knownTypes ?? Type.EmptyTypes);
- max_offset = maximumKeyDerivationOffset;
- max_label_length = maximumKeyDerivationLabelLength;
- max_nonce_length = maximumKeyDerivationNonceLength;
- if (encoder == null)
- encoder = new DataProtectionSecurityStateEncoder ();
- }
- SecurityVersion security_version;
- bool emit_bsp;
- SamlSerializer saml_serializer;
- SecurityStateEncoder encoder;
- List<Type> known_types;
- int max_offset, max_label_length, max_nonce_length;
- bool WSS1_0 {
- get { return SecurityVersion == SecurityVersion.WSSecurity10; }
- }
- public bool EmitBspRequiredAttributes {
- get { return emit_bsp; }
- }
- public SecurityVersion SecurityVersion {
- get { return security_version; }
- }
- [MonoTODO]
- public int MaximumKeyDerivationOffset {
- get { return max_offset; }
- }
- [MonoTODO]
- public int MaximumKeyDerivationLabelLength {
- get { return max_label_length; }
- }
- [MonoTODO]
- public int MaximumKeyDerivationNonceLength {
- get { return max_nonce_length; }
- }
- protected virtual string GetTokenTypeUri (Type tokenType)
- {
- if (tokenType == typeof (WrappedKeySecurityToken))
- return Constants.WSSEncryptedKeyToken;
- if (tokenType == typeof (X509SecurityToken))
- return Constants.WSSX509Token;
- // if (tokenType == typeof (RsaSecurityToken))
- // return null;
- if (tokenType == typeof (SamlSecurityToken))
- return Constants.WSSSamlToken;
- if (tokenType == typeof (SecurityContextSecurityToken))
- return Constants.WsscContextToken;
- // if (tokenType == typeof (huh))
- // return ServiceModelSecurityTokenTypes.SecureConversation;
- // if (tokenType == typeof (hah))
- // return ServiceModelSecurityTokenTypes.MutualSslnego;
- // if (tokenType == typeof (whoa))
- // return ServiceModelSecurityTokenTypes.AnonymousSslnego;
- if (tokenType == typeof (UserNameSecurityToken))
- return Constants.WSSUserNameToken;
- // if (tokenType == typeof (uhoh))
- // return ServiceModelSecurityTokenTypes.Spnego;
- // if (tokenType == typeof (SspiSecurityToken))
- // return ServiceModelSecurityTokenTypes.SspiCredential;
- if (tokenType == typeof (KerberosRequestorSecurityToken))
- return Constants.WSSKerberosToken;
- return null;
- }
- [MonoTODO]
- protected override bool CanReadKeyIdentifierClauseCore (XmlReader reader)
- {
- reader.MoveToContent ();
- switch (reader.NamespaceURI) {
- case EncryptedXml.XmlEncNamespaceUrl:
- switch (reader.LocalName) {
- case "EncryptedKey":
- return true;
- }
- break;
- case Constants.WssNamespace:
- switch (reader.LocalName) {
- case "SecurityTokenReference":
- return true;
- }
- break;
- }
- return false;
- }
- [MonoTODO]
- protected override bool CanReadKeyIdentifierCore (XmlReader reader)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected override bool CanReadTokenCore (XmlReader reader)
- {
- reader.MoveToContent ();
- switch (reader.NamespaceURI) {
- case Constants.WssNamespace:
- switch (reader.LocalName) {
- case "BinarySecurityToken":
- case "BinarySecret":
- case "UsernameToken":
- return true;
- }
- break;
- case Constants.WsscNamespace:
- switch (reader.LocalName) {
- case "DerivedKeyToken":
- case "SecurityContextToken":
- return true;
- }
- break;
- case EncryptedXml.XmlEncNamespaceUrl:
- switch (reader.LocalName) {
- case "EncryptedKey":
- return true;
- }
- break;
- }
- return false;
- }
- [MonoTODO]
- public virtual SecurityKeyIdentifierClause CreateKeyIdentifierClauseFromTokenXml (
- XmlElement tokenXml, SecurityTokenReferenceStyle referenceStyle)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected override SecurityKeyIdentifier ReadKeyIdentifierCore (
- XmlReader reader)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected override SecurityKeyIdentifierClause ReadKeyIdentifierClauseCore (XmlReader reader)
- {
- reader.MoveToContent ();
- switch (reader.NamespaceURI) {
- case EncryptedXml.XmlEncNamespaceUrl:
- switch (reader.LocalName) {
- case "EncryptedKey":
- return ReadEncryptedKeyIdentifierClause (reader);
- }
- break;
- case Constants.WssNamespace:
- switch (reader.LocalName) {
- case "SecurityTokenReference":
- return ReadSecurityTokenReference (reader);
- }
- break;
- }
- 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));
- }
- SecurityKeyIdentifierClause ReadSecurityTokenReference (XmlReader reader)
- {
- reader.ReadStartElement ();
- reader.MoveToContent ();
- if (reader.NamespaceURI == SignedXml.XmlDsigNamespaceUrl) {
- KeyInfoX509Data x509 = new KeyInfoX509Data ();
- x509.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement);
- if (x509.IssuerSerials.Count == 0)
- throw new XmlException ("'X509IssuerSerial' element is expected inside 'X509Data' element");
- X509IssuerSerial s = (X509IssuerSerial) x509.IssuerSerials [0];
- reader.MoveToContent ();
- reader.ReadEndElement ();
- return new X509IssuerSerialKeyIdentifierClause (s.IssuerName, s.SerialNumber);
- }
- if (reader.NamespaceURI != Constants.WssNamespace)
- 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));
- switch (reader.LocalName) {
- case "Reference":
- Type ownerType = null;
- // FIXME: there could be more token types.
- if (reader.MoveToAttribute ("ValueType")) {
- switch (reader.Value) {
- case Constants.WSSEncryptedKeyToken:
- ownerType = typeof (WrappedKeySecurityToken);
- break;
- case Constants.WSSX509Token:
- ownerType = typeof (X509SecurityToken);
- break;
- case Constants.WsscContextToken:
- ownerType = typeof (SecurityContextSecurityToken);
- break;
- default:
- throw new XmlException (String.Format ("Unexpected ValueType in 'Reference' element: '{0}'", reader.Value));
- }
- }
- reader.MoveToElement ();
- string uri = reader.GetAttribute ("URI");
- if (String.IsNullOrEmpty (uri))
- uri = "#";
- SecurityKeyIdentifierClause ic = null;
- if (ownerType == typeof (SecurityContextSecurityToken) && uri [0] != '#')
- // FIXME: Generation?
- ic = new SecurityContextKeyIdentifierClause (new UniqueId (uri));
- else
- ic = new LocalIdKeyIdentifierClause (uri.Substring (1), ownerType);
- reader.Skip ();
- reader.MoveToContent ();
- reader.ReadEndElement ();
- return ic;
- case "KeyIdentifier":
- string valueType = reader.GetAttribute ("ValueType");
- string value = reader.ReadElementContentAsString ();
- reader.MoveToContent ();
- reader.ReadEndElement (); // consume </Reference>
- switch (valueType) {
- case Constants.WssKeyIdentifierX509Thumbptint:
- return new X509ThumbprintKeyIdentifierClause (Convert.FromBase64String (value));
- case Constants.WssKeyIdentifierEncryptedKey:
- return new InternalEncryptedKeyIdentifierClause (Convert.FromBase64String (value));
- case Constants.WssKeyIdentifierSamlAssertion:
- return new SamlAssertionKeyIdentifierClause (value);
- default:
- // It is kinda weird but it throws XmlException here ...
- throw new XmlException (String.Format ("KeyIdentifier type '{0}' is not supported in WSSecurityTokenSerializer.", valueType));
- }
- default:
- 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));
- }
- }
- EncryptedKeyIdentifierClause ReadEncryptedKeyIdentifierClause (
- XmlReader reader)
- {
- string encNS = EncryptedXml.XmlEncNamespaceUrl;
- string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
- reader.Read ();
- reader.MoveToContent ();
- string encMethod = reader.GetAttribute ("Algorithm");
- bool isEmpty = reader.IsEmptyElement;
- reader.ReadStartElement ("EncryptionMethod", encNS);
- string digMethod = null;
- if (!isEmpty) {
- reader.MoveToContent ();
- if (reader.LocalName == "DigestMethod" && reader.NamespaceURI == SignedXml.XmlDsigNamespaceUrl)
- digMethod = reader.GetAttribute ("Algorithm");
- while (reader.NodeType != XmlNodeType.EndElement) {
- reader.Skip ();
- reader.MoveToContent ();
- }
- reader.ReadEndElement ();
- }
- reader.MoveToContent ();
- SecurityKeyIdentifier ki = null;
- if (!reader.IsEmptyElement) {
- reader.ReadStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
- reader.MoveToContent ();
- SecurityKeyIdentifierClause kic = ReadKeyIdentifierClauseCore (reader);
- ki = new SecurityKeyIdentifier ();
- ki.Add (kic);
- reader.MoveToContent ();
- reader.ReadEndElement (); // </ds:KeyInfo>
- reader.MoveToContent ();
- }
- byte [] keyValue = null;
- if (!reader.IsEmptyElement) {
- reader.ReadStartElement ("CipherData", encNS);
- reader.MoveToContent ();
- keyValue = Convert.FromBase64String (reader.ReadElementContentAsString ("CipherValue", encNS));
- reader.MoveToContent ();
- reader.ReadEndElement (); // CipherData
- }
- string carriedKeyName = null;
- if (!reader.IsEmptyElement && reader.LocalName == "CarriedKeyName" && reader.NamespaceURI == encNS) {
- carriedKeyName = reader.ReadElementContentAsString ();
- reader.MoveToContent ();
- }
- // FIXME: handle derived keys??
- return new EncryptedKeyIdentifierClause (keyValue, encMethod, ki, carriedKeyName);
- }
- [MonoTODO]
- protected override SecurityToken ReadTokenCore (
- XmlReader reader,
- SecurityTokenResolver tokenResolver)
- {
- if (!CanReadToken (reader))
- 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));
- switch (reader.NamespaceURI) {
- case Constants.WssNamespace:
- switch (reader.LocalName) {
- case "BinarySecurityToken":
- return ReadX509TokenCore (reader, tokenResolver);
- case "BinarySecret":
- return ReadBinarySecretTokenCore (reader, tokenResolver);
- case "UsernameToken":
- return ReadUserNameTokenCore (reader, tokenResolver);
- }
- break;
- case Constants.WsscNamespace:
- if (reader.LocalName == "DerivedKeyToken")
- return ReadDerivedKeyToken (reader, tokenResolver);
- if (reader.LocalName == "SecurityContextToken")
- return ReadSecurityContextToken (reader, tokenResolver);
- break;
- case EncryptedXml.XmlEncNamespaceUrl:
- switch (reader.LocalName) {
- case "EncryptedKey":
- return ReadWrappedKeySecurityTokenCore (reader, tokenResolver);
- }
- break;
- }
- throw new NotImplementedException ();
- }
- DerivedKeySecurityToken ReadDerivedKeyToken (
- XmlReader reader, SecurityTokenResolver tokenResolver)
- {
- try {
- return ReadDerivedKeyTokenCore (reader, tokenResolver);
- } catch (XmlException) {
- throw;
- } catch (Exception ex) {
- throw new XmlException ("Cannot read DerivedKeyToken", ex);
- }
- }
-
- DerivedKeySecurityToken ReadDerivedKeyTokenCore (
- XmlReader reader, SecurityTokenResolver tokenResolver)
- {
- if (tokenResolver == null)
- throw new ArgumentNullException ("tokenResolver");
- string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
- string algorithm = reader.MoveToAttribute ("Algorithm") ? reader.Value : null;
- reader.MoveToElement ();
- reader.ReadStartElement ();
- reader.MoveToContent ();
- SecurityKeyIdentifierClause kic = ReadKeyIdentifierClause (reader);
- int? generation = null, offset = null, length = null;
- byte [] nonce = null;
- string name = null, label = null;
- for (reader.MoveToContent ();
- reader.NodeType != XmlNodeType.EndElement;
- reader.MoveToContent ())
- switch (reader.LocalName) {
- case "Properties":
- reader.ReadStartElement ("Properties", Constants.WsscNamespace);
- for (reader.MoveToContent ();
- reader.NodeType != XmlNodeType.EndElement;
- reader.MoveToContent ())
- switch (reader.LocalName) {
- case "Name":
- name = reader.ReadElementContentAsString ("Name", Constants.WsscNamespace);
- break;
- case "Label":
- label = reader.ReadElementContentAsString ("Label", Constants.WsscNamespace);
- break;
- case "Nonce":
- nonce = Convert.FromBase64String (reader.ReadElementContentAsString ("Nonce", Constants.WsscNamespace));
- break;
- }
- reader.ReadEndElement ();
- break;
- case "Offset":
- offset = reader.ReadElementContentAsInt ("Offset", Constants.WsscNamespace);
- break;
- case "Length":
- length = reader.ReadElementContentAsInt ("Length", Constants.WsscNamespace);
- break;
- case "Nonce":
- nonce = Convert.FromBase64String (reader.ReadElementContentAsString ("Nonce", Constants.WsscNamespace));
- break;
- case "Label":
- label = reader.ReadElementContentAsString ("Label", Constants.WsscNamespace);
- break;
- }
- reader.ReadEndElement ();
- // resolve key reference
- SymmetricSecurityKey key = tokenResolver.ResolveSecurityKey (kic) as SymmetricSecurityKey;
- if (key == null)
- throw new XmlException ("Cannot resolve the security key referenced by the DerivedKeyToken as a symmetric key");
- return new DerivedKeySecurityToken (id, algorithm, kic, key, name, generation, offset, length, label, nonce);
- }
- // since it cannot consume RequestSecurityTokenResponse,
- // the token information cannot be complete.
- SecurityContextSecurityToken ReadSecurityContextToken (
- XmlReader reader, SecurityTokenResolver tokenResolver)
- {
- string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
- reader.Read ();
- // The input dnse:Cookie value is encrypted by the
- // server's SecurityStateEncoder
- // (setting error-raising encoder to ServiceCredentials.
- // SecureConversationAuthentication.SecurityStateEncoder
- // shows it).
- UniqueId cid = null;
- byte [] cookie = null;
- while (true) {
- reader.MoveToContent ();
- if (reader.NodeType != XmlNodeType.Element)
- break;
- switch (reader.NamespaceURI) {
- case Constants.WsscNamespace:
- switch (reader.LocalName) {
- case "Identifier":
- cid = new UniqueId (reader.ReadElementContentAsString ());
- continue;
- }
- break;
- case Constants.MSTlsnegoTokenContent:
- switch (reader.LocalName) {
- case "Cookie":
- cookie = Convert.FromBase64String (reader.ReadElementContentAsString ());
- continue;
- }
- break;
- }
- throw new XmlException (String.Format ("Unexpected element {0} in namespace {1}", reader.LocalName, reader.NamespaceURI));
- }
- reader.ReadEndElement ();
- // LAMESPEC: at client side there is no way to specify
- // SecurityStateEncoder, so it must be guessed from
- // its cookie content itself.
- if (encoder == null) throw new Exception ();
- byte [] decoded =
- cookie != null && cookie.Length > 154 ?
- encoder.DecodeSecurityState (cookie) :
- cookie;
- return SslnegoCookieResolver.ResolveCookie (decoded, cookie);
- }
- WrappedKeySecurityToken ReadWrappedKeySecurityTokenCore (
- XmlReader reader, SecurityTokenResolver tokenResolver)
- {
- if (tokenResolver == null)
- throw new ArgumentNullException ("tokenResolver");
- EncryptedKey ek = new EncryptedKey ();
- ek.LoadXml (new XmlDocument ().ReadNode (reader) as XmlElement);
- SecurityKeyIdentifier ki = new SecurityKeyIdentifier ();
- foreach (KeyInfoClause kic in ek.KeyInfo)
- ki.Add (ReadKeyIdentifierClause (new XmlNodeReader (kic.GetXml ())));
- SecurityToken token = tokenResolver.ResolveToken (ki);
- string alg = ek.EncryptionMethod.KeyAlgorithm;
- foreach (SecurityKey skey in token.SecurityKeys)
- if (skey.IsSupportedAlgorithm (alg)) {
- byte [] key = skey.DecryptKey (alg, ek.CipherData.CipherValue);
- WrappedKeySecurityToken wk =
- new WrappedKeySecurityToken (ek.Id, key, alg, token, ki);
- // FIXME: This should not be required.
- wk.SetWrappedKey (ek.CipherData.CipherValue);
- wk.ReferenceList = ek.ReferenceList;
- return wk;
- }
- 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));
- }
- X509SecurityToken ReadX509TokenCore (
- XmlReader reader, SecurityTokenResolver resolver)
- {
- string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
- byte [] raw = Convert.FromBase64String (reader.ReadElementContentAsString ());
- return new X509SecurityToken (new X509Certificate2 (raw), id);
- }
- UserNameSecurityToken ReadUserNameTokenCore (
- XmlReader reader, SecurityTokenResolver resolver)
- {
- string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
- if (reader.IsEmptyElement)
- throw new XmlException ("At least UsernameToken must contain Username");
- reader.Read ();
- reader.MoveToContent ();
- string user = reader.ReadElementContentAsString ("Username", Constants.WssNamespace);
- reader.MoveToContent ();
- string pass = null;
- if (reader.LocalName == "Password" && reader.NamespaceURI == Constants.WssNamespace) {
- pass = reader.ReadElementContentAsString ("Password", Constants.WssNamespace);
- reader.MoveToContent ();
- }
- reader.ReadEndElement ();
- return id != null ?
- new UserNameSecurityToken (user, pass, id) :
- new UserNameSecurityToken (user, pass);
- }
- BinarySecretSecurityToken ReadBinarySecretTokenCore (
- XmlReader reader, SecurityTokenResolver resolver)
- {
- string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
- byte [] data = Convert.FromBase64String (reader.ReadElementContentAsString ());
- return new BinarySecretSecurityToken (id, data);
- }
- [MonoTODO]
- protected override bool CanWriteKeyIdentifierCore (
- SecurityKeyIdentifier keyIdentifier)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected override bool CanWriteKeyIdentifierClauseCore (
- SecurityKeyIdentifierClause keyIdentifierClause)
- {
- if (keyIdentifierClause == null)
- throw new ArgumentNullException ("keyIdentifierClause");
- if (keyIdentifierClause is LocalIdKeyIdentifierClause ||
- keyIdentifierClause is SecurityContextKeyIdentifierClause ||
- keyIdentifierClause is X509IssuerSerialKeyIdentifierClause ||
- (keyIdentifierClause is X509ThumbprintKeyIdentifierClause && !WSS1_0) ||
- keyIdentifierClause is EncryptedKeyIdentifierClause ||
- keyIdentifierClause is BinarySecretKeyIdentifierClause ||
- keyIdentifierClause is InternalEncryptedKeyIdentifierClause ||
- keyIdentifierClause is SamlAssertionKeyIdentifierClause)
- return true;
- else
- return false;
- }
- [MonoTODO]
- protected override bool CanWriteTokenCore (SecurityToken token)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected override void WriteKeyIdentifierCore (
- XmlWriter writer,
- SecurityKeyIdentifier keyIdentifier)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- protected override void WriteKeyIdentifierClauseCore (
- XmlWriter writer,
- SecurityKeyIdentifierClause keyIdentifierClause)
- {
- string errorReason = null;
- if (keyIdentifierClause == null)
- throw new ArgumentNullException ("keyIdentifierClause");
- if (keyIdentifierClause is LocalIdKeyIdentifierClause)
- WriteLocalIdKeyIdentifierClause (writer, (LocalIdKeyIdentifierClause) keyIdentifierClause);
- else if (keyIdentifierClause is SecurityContextKeyIdentifierClause)
- WriteSecurityContextKeyIdentifierClause (writer, (SecurityContextKeyIdentifierClause) keyIdentifierClause);
- else if (keyIdentifierClause is X509IssuerSerialKeyIdentifierClause)
- WriteX509IssuerSerialKeyIdentifierClause (writer, (X509IssuerSerialKeyIdentifierClause) keyIdentifierClause);
- else if (keyIdentifierClause is X509ThumbprintKeyIdentifierClause) {
- if (WSS1_0)
- errorReason = String.Format ("Security key identifier clause '{0}' is not supported in this serializer.", keyIdentifierClause.GetType ());
- else
- WriteX509ThumbprintKeyIdentifierClause (writer, (X509ThumbprintKeyIdentifierClause) keyIdentifierClause);
- }
- else if (keyIdentifierClause is EncryptedKeyIdentifierClause)
- WriteEncryptedKeyIdentifierClause (writer, (EncryptedKeyIdentifierClause) keyIdentifierClause);
- else if (keyIdentifierClause is BinarySecretKeyIdentifierClause)
- WriteBinarySecretKeyIdentifierClause (writer, (BinarySecretKeyIdentifierClause) keyIdentifierClause);
- else if (keyIdentifierClause is InternalEncryptedKeyIdentifierClause)
- WriteInternalEncryptedKeyIdentifierClause (writer, (InternalEncryptedKeyIdentifierClause) keyIdentifierClause);
- else if (keyIdentifierClause is SamlAssertionKeyIdentifierClause)
- WriteSamlAssertionKeyIdentifierClause (writer, (SamlAssertionKeyIdentifierClause) keyIdentifierClause);
- else
- throw new NotImplementedException (String.Format ("Security key identifier clause '{0}' is not either implemented or supported.", keyIdentifierClause.GetType ()));
- if (errorReason != null)
- throw new InvalidOperationException (errorReason);
- }
- void WriteX509IssuerSerialKeyIdentifierClause (
- XmlWriter w, X509IssuerSerialKeyIdentifierClause ic)
- {
- w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
- w.WriteStartElement ("X509Data", Constants.XmlDsig);
- w.WriteStartElement ("X509IssuerSerial", Constants.XmlDsig);
- w.WriteStartElement ("X509IssuerName", Constants.XmlDsig);
- w.WriteString (ic.IssuerName);
- w.WriteEndElement ();
- w.WriteStartElement ("X509SerialNumber", Constants.XmlDsig);
- w.WriteString (ic.IssuerSerialNumber);
- w.WriteEndElement ();
- w.WriteEndElement ();
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- void WriteX509ThumbprintKeyIdentifierClause (
- XmlWriter w, X509ThumbprintKeyIdentifierClause ic)
- {
- w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
- w.WriteStartElement ("o", "KeyIdentifier", Constants.WssNamespace);
- w.WriteAttributeString ("ValueType", Constants.WssKeyIdentifierX509Thumbptint);
- if (EmitBspRequiredAttributes)
- w.WriteAttributeString ("EncodingType", Constants.WssBase64BinaryEncodingType);
- w.WriteString (Convert.ToBase64String (ic.GetX509Thumbprint ()));
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- void WriteLocalIdKeyIdentifierClause (
- XmlWriter w, LocalIdKeyIdentifierClause ic)
- {
- w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
- w.WriteStartElement ("o", "Reference", Constants.WssNamespace);
- if (EmitBspRequiredAttributes && ic.OwnerType != null) {
- string vt = GetTokenTypeUri (ic.OwnerType);
- if (vt != null)
- w.WriteAttributeString ("ValueType", vt);
- }
- w.WriteAttributeString ("URI", "#" + ic.LocalId);
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- void WriteSecurityContextKeyIdentifierClause (
- XmlWriter w, SecurityContextKeyIdentifierClause ic)
- {
- w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
- w.WriteStartElement ("o", "Reference", Constants.WssNamespace);
- w.WriteAttributeString ("URI", ic.ContextId.ToString ());
- string vt = GetTokenTypeUri (typeof (SecurityContextSecurityToken));
- w.WriteAttributeString ("ValueType", vt);
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- void WriteEncryptedKeyIdentifierClause (
- XmlWriter w, EncryptedKeyIdentifierClause ic)
- {
- w.WriteStartElement ("e", "EncryptedKey", EncryptedXml.XmlEncNamespaceUrl);
- w.WriteStartElement ("EncryptionMethod", EncryptedXml.XmlEncNamespaceUrl);
- w.WriteAttributeString ("Algorithm", ic.EncryptionMethod);
- w.WriteEndElement ();
- if (ic.EncryptingKeyIdentifier != null) {
- w.WriteStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
- foreach (SecurityKeyIdentifierClause ckic in ic.EncryptingKeyIdentifier)
- WriteKeyIdentifierClause (w, ckic);
- w.WriteEndElement ();
- }
- w.WriteStartElement ("CipherData", EncryptedXml.XmlEncNamespaceUrl);
- w.WriteStartElement ("CipherValue", EncryptedXml.XmlEncNamespaceUrl);
- w.WriteString (Convert.ToBase64String (ic.GetEncryptedKey ()));
- w.WriteEndElement ();
- w.WriteEndElement ();
- if (ic.CarriedKeyName != null)
- w.WriteElementString ("CarriedKeyName", EncryptedXml.XmlEncNamespaceUrl, ic.CarriedKeyName);
- w.WriteEndElement ();
- }
- void WriteBinarySecretKeyIdentifierClause (
- XmlWriter w, BinarySecretKeyIdentifierClause ic)
- {
- w.WriteStartElement ("t", "BinarySecret", Constants.WstNamespace);
- w.WriteString (Convert.ToBase64String (ic.GetBuffer ()));
- w.WriteEndElement ();
- }
- void WriteInternalEncryptedKeyIdentifierClause (
- XmlWriter w, InternalEncryptedKeyIdentifierClause ic)
- {
- w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
- w.WriteStartElement ("o", "KeyIdentifier", Constants.WssNamespace);
- w.WriteAttributeString ("ValueType", Constants.WssKeyIdentifierEncryptedKey);
- w.WriteString (Convert.ToBase64String (ic.GetBuffer ()));
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- void WriteSamlAssertionKeyIdentifierClause (XmlWriter w, SamlAssertionKeyIdentifierClause ic)
- {
- w.WriteStartElement ("o", "SecurityTokenReference", Constants.WssNamespace);
- w.WriteStartElement ("o", "KeyIdentifier", Constants.WssNamespace);
- w.WriteAttributeString ("ValueType", Constants.WssKeyIdentifierSamlAssertion);
- w.WriteString (ic.AssertionId);
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- [MonoTODO]
- protected override void WriteTokenCore (
- XmlWriter writer, SecurityToken token)
- {
- // WSSecurity supports:
- // - UsernameToken : S.IM.T.UserNameSecurityToken
- // - X509SecurityToken : S.IM.T.X509SecurityToken
- // - SAML Assertion : S.IM.T.SamlSecurityToken
- // - Kerberos : S.IM.T.KerberosRequestorSecurityToken
- // - Rights Expression Language (REL) : N/A
- // - SOAP with Attachments : N/A
- // they are part of standards support:
- // - WrappedKey (EncryptedKey)
- // - BinarySecret (WS-Trust)
- // - SecurityContext (WS-SecureConversation)
- // additionally there are extra token types in WCF:
- // - GenericXml
- // - Windows
- // - Sspi
- // not supported in this class:
- // - Rsa
- if (token is UserNameSecurityToken)
- WriteUserNameSecurityToken (writer, ((UserNameSecurityToken) token));
- else if (token is X509SecurityToken)
- WriteX509SecurityToken (writer, ((X509SecurityToken) token));
- else if (token is BinarySecretSecurityToken)
- WriteBinarySecretSecurityToken (writer, ((BinarySecretSecurityToken) token));
- else if (token is SamlSecurityToken)
- throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
- else if (token is GenericXmlSecurityToken)
- ((GenericXmlSecurityToken) token).TokenXml.WriteTo (writer);
- else if (token is WrappedKeySecurityToken)
- WriteWrappedKeySecurityToken (writer, (WrappedKeySecurityToken) token);
- else if (token is DerivedKeySecurityToken)
- WriteDerivedKeySecurityToken (writer, (DerivedKeySecurityToken) token);
- else if (token is SecurityContextSecurityToken)
- WriteSecurityContextSecurityToken (writer, (SecurityContextSecurityToken) token);
- else if (token is SspiSecurityToken)
- throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
- else if (token is KerberosRequestorSecurityToken)
- throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
- else if (token is WindowsSecurityToken)
- throw new NotImplementedException ("WriteTokenCore() is not implemented for " + token);
- else
- throw new InvalidOperationException (String.Format ("This SecurityTokenSerializer does not support security token '{0}'.", token));
- }
- void WriteUserNameSecurityToken (XmlWriter w, UserNameSecurityToken token)
- {
- w.WriteStartElement ("o", "UsernameToken", Constants.WssNamespace);
- w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
- w.WriteStartElement ("o", "Username", Constants.WssNamespace);
- w.WriteString (token.UserName);
- w.WriteEndElement ();
- w.WriteStartElement ("o", "Password", Constants.WssNamespace);
- w.WriteString (token.Password);
- w.WriteEndElement ();
- w.WriteEndElement ();
- }
- void WriteX509SecurityToken (XmlWriter w, X509SecurityToken token)
- {
- w.WriteStartElement ("o", "BinarySecurityToken", Constants.WssNamespace);
- w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
- w.WriteAttributeString ("ValueType", Constants.WSSX509Token);
- w.WriteString (Convert.ToBase64String (token.Certificate.RawData));
- w.WriteEndElement ();
- }
- void WriteBinarySecretSecurityToken (XmlWriter w, BinarySecretSecurityToken token)
- {
- w.WriteStartElement ("t", "BinarySecret", Constants.WstNamespace);
- w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
- w.WriteString (Convert.ToBase64String (token.GetKeyBytes ()));
- w.WriteEndElement ();
- }
- void WriteDerivedKeySecurityToken (XmlWriter w, DerivedKeySecurityToken token)
- {
- string ns = Constants.WsscNamespace;
- w.WriteStartElement ("c", "DerivedKeyToken", ns);
- w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
- WriteKeyIdentifierClause (w, token.TokenReference);
- if (token.Name != null) {
- w.WriteStartElement ("Properties", ns);
- w.WriteElementString ("Name", ns, token.Name);
- w.WriteEndElement ();
- }
- if (token.Offset != null)
- w.WriteElementString ("Offset", ns, Convert.ToString (token.Offset));
- if (token.Length != null)
- w.WriteElementString ("Length", ns, Convert.ToString (token.Length));
- if (token.Label != null)
- w.WriteElementString ("Label", ns, token.Label);
- w.WriteElementString ("Nonce", ns, Convert.ToBase64String (token.Nonce));
- w.WriteEndElement ();
- }
- void WriteWrappedKeySecurityToken (XmlWriter w, WrappedKeySecurityToken token)
- {
- string encNS = EncryptedXml.XmlEncNamespaceUrl;
- w.WriteStartElement ("e", "EncryptedKey", encNS);
- w.WriteAttributeString ("Id", token.Id);
- w.WriteStartElement ("EncryptionMethod", encNS);
- w.WriteAttributeString ("Algorithm", token.WrappingAlgorithm);
- w.WriteStartElement ("DigestMethod", SignedXml.XmlDsigNamespaceUrl);
- w.WriteAttributeString ("Algorithm", SignedXml.XmlDsigSHA1Url);
- w.WriteEndElement ();
- w.WriteEndElement ();
- w.WriteStartElement ("KeyInfo", SignedXml.XmlDsigNamespaceUrl);
- if (token.WrappingTokenReference != null)
- foreach (SecurityKeyIdentifierClause kic in token.WrappingTokenReference)
- WriteKeyIdentifierClause (w, kic);
- w.WriteEndElement ();
- w.WriteStartElement ("CipherData", encNS);
- w.WriteStartElement ("CipherValue", encNS);
- w.WriteString (Convert.ToBase64String (token.GetWrappedKey ()));
- w.WriteEndElement ();
- w.WriteEndElement ();
- if (token.ReferenceList != null) {
- w.WriteStartElement ("e", "ReferenceList", encNS);
- foreach (DataReference er in token.ReferenceList) {
- w.WriteStartElement ("DataReference", encNS);
- w.WriteAttributeString ("URI", er.Uri);
- w.WriteEndElement ();
- }
- w.WriteEndElement ();
- }
- w.WriteEndElement ();
- }
- void WriteSecurityContextSecurityToken (XmlWriter w, SecurityContextSecurityToken token)
- {
- string ns = Constants.WsscNamespace;
- w.WriteStartElement ("c", "SecurityContextToken", ns);
- w.WriteAttributeString ("u", "Id", Constants.WsuNamespace, token.Id);
- w.WriteElementString ("Identifier", ns, token.ContextId.ToString ());
- // FIXME: add Cookie output (from CreateCookieSecurityContextToken() method)
- if (token.Cookie != null)
- w.WriteElementString ("dnse", "Cookie", Constants.MSTlsnegoTokenContent, Convert.ToBase64String (token.Cookie));
- w.WriteEndElement ();
- }
- }
- }
|