1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.ServiceModel.Security
8 using System.ServiceModel;
9 using System.ServiceModel.Description;
10 using System.ServiceModel.Dispatcher;
11 using System.Collections;
12 using System.Collections.Generic;
13 using System.Collections.ObjectModel;
14 using System.Diagnostics;
15 using System.Globalization;
18 using System.Threading;
21 using System.Security.Cryptography;
22 using System.IdentityModel.Claims;
23 using System.IdentityModel.Policy;
24 using System.IdentityModel.Selectors;
25 using System.IdentityModel.Tokens;
26 using System.Security.Cryptography.X509Certificates;
27 using System.ServiceModel.Security.Tokens;
28 using HexBinary = System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary;
29 using System.ServiceModel.Channels;
30 using System.ServiceModel.Security;
31 using System.Runtime.Serialization;
33 using KeyIdentifierEntry = WSSecurityTokenSerializer.KeyIdentifierEntry;
34 using KeyIdentifierClauseEntry = WSSecurityTokenSerializer.KeyIdentifierClauseEntry;
35 using TokenEntry = WSSecurityTokenSerializer.TokenEntry;
36 using StrEntry = WSSecurityTokenSerializer.StrEntry;
37 using Psha1DerivedKeyGenerator = System.IdentityModel.Psha1DerivedKeyGenerator;
39 abstract class WSTrust : WSSecurityTokenSerializer.SerializerEntries
41 WSSecurityTokenSerializer tokenSerializer;
43 public WSTrust(WSSecurityTokenSerializer tokenSerializer)
45 this.tokenSerializer = tokenSerializer;
48 public WSSecurityTokenSerializer WSSecurityTokenSerializer
50 get { return this.tokenSerializer; }
53 public abstract TrustDictionary SerializerDictionary
58 public override void PopulateTokenEntries(IList<TokenEntry> tokenEntryList)
60 tokenEntryList.Add(new BinarySecretTokenEntry(this));
63 class BinarySecretTokenEntry : TokenEntry
66 TrustDictionary otherDictionary;
68 public BinarySecretTokenEntry(WSTrust parent)
71 this.otherDictionary = null;
73 if (parent.SerializerDictionary is TrustDec2005Dictionary)
75 this.otherDictionary = XD.TrustFeb2005Dictionary;
78 if (parent.SerializerDictionary is TrustFeb2005Dictionary)
80 this.otherDictionary = DXD.TrustDec2005Dictionary;
83 // always set it, so we don't have to worry about null
84 if (this.otherDictionary == null)
85 this.otherDictionary = this.parent.SerializerDictionary;
88 protected override XmlDictionaryString LocalName { get { return parent.SerializerDictionary.BinarySecret; } }
89 protected override XmlDictionaryString NamespaceUri { get { return parent.SerializerDictionary.Namespace; } }
90 protected override Type[] GetTokenTypesCore() { return new Type[] { typeof(BinarySecretSecurityToken) }; }
91 public override string TokenTypeUri { get { return null; } }
92 protected override string ValueTypeUri { get { return null; } }
94 public override bool CanReadTokenCore(XmlElement element)
96 string valueTypeUri = null;
98 if (element.HasAttribute(SecurityJan2004Strings.ValueType, null))
100 valueTypeUri = element.GetAttribute(SecurityJan2004Strings.ValueType, null);
103 return element.LocalName == LocalName.Value && (element.NamespaceURI == NamespaceUri.Value || element.NamespaceURI == this.otherDictionary.Namespace.Value) && valueTypeUri == this.ValueTypeUri;
106 public override bool CanReadTokenCore(XmlDictionaryReader reader)
108 return (reader.IsStartElement(this.LocalName, this.NamespaceUri) || reader.IsStartElement(this.LocalName, this.otherDictionary.Namespace)) &&
109 reader.GetAttribute(XD.SecurityJan2004Dictionary.ValueType, null) == this.ValueTypeUri;
113 public override SecurityKeyIdentifierClause CreateKeyIdentifierClauseFromTokenXmlCore(XmlElement issuedTokenXml,
114 SecurityTokenReferenceStyle tokenReferenceStyle)
116 TokenReferenceStyleHelper.Validate(tokenReferenceStyle);
118 switch (tokenReferenceStyle)
120 case SecurityTokenReferenceStyle.Internal:
121 return CreateDirectReference(issuedTokenXml, UtilityStrings.IdAttribute, UtilityStrings.Namespace, typeof(GenericXmlSecurityToken));
122 case SecurityTokenReferenceStyle.External:
123 // Binary Secret tokens aren't referred to externally
126 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("tokenReferenceStyle"));
130 public override SecurityToken ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)
132 string secretType = reader.GetAttribute(XD.SecurityJan2004Dictionary.TypeAttribute, null);
133 string id = reader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);
134 bool isNonce = false;
136 if (secretType != null && secretType.Length > 0)
138 if (secretType == parent.SerializerDictionary.NonceBinarySecret.Value || secretType == otherDictionary.NonceBinarySecret.Value)
142 else if (secretType != parent.SerializerDictionary.SymmetricKeyBinarySecret.Value && secretType != otherDictionary.SymmetricKeyBinarySecret.Value)
144 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnexpectedBinarySecretType, parent.SerializerDictionary.SymmetricKeyBinarySecret.Value, secretType)));
148 byte[] secret = reader.ReadElementContentAsBase64();
151 return new NonceToken(id, secret);
155 return new BinarySecretSecurityToken(id, secret);
159 public override void WriteTokenCore(XmlDictionaryWriter writer, SecurityToken token)
161 BinarySecretSecurityToken simpleToken = token as BinarySecretSecurityToken;
162 byte[] secret = simpleToken.GetKeyBytes();
163 writer.WriteStartElement(parent.SerializerDictionary.Prefix.Value, parent.SerializerDictionary.BinarySecret, parent.SerializerDictionary.Namespace);
164 if (simpleToken.Id != null)
166 writer.WriteAttributeString(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace, simpleToken.Id);
168 if (token is NonceToken)
170 writer.WriteAttributeString(XD.SecurityJan2004Dictionary.TypeAttribute, null, parent.SerializerDictionary.NonceBinarySecret.Value);
172 writer.WriteBase64(secret, 0, secret.Length);
173 writer.WriteEndElement();
178 public abstract class Driver : TrustDriver
180 static readonly string base64Uri = SecurityJan2004Strings.EncodingTypeValueBase64Binary;
181 static readonly string hexBinaryUri = SecurityJan2004Strings.EncodingTypeValueHexBinary;
184 SecurityStandardsManager standardsManager;
185 List<SecurityTokenAuthenticator> entropyAuthenticators;
187 public Driver(SecurityStandardsManager standardsManager)
189 this.standardsManager = standardsManager;
190 this.entropyAuthenticators = new List<SecurityTokenAuthenticator>(2);
193 public abstract TrustDictionary DriverDictionary
198 public override XmlDictionaryString RequestSecurityTokenAction
202 return DriverDictionary.RequestSecurityTokenIssuance;
206 public override XmlDictionaryString RequestSecurityTokenResponseAction
210 return DriverDictionary.RequestSecurityTokenIssuanceResponse;
214 public override string RequestTypeIssue
218 return DriverDictionary.RequestTypeIssue.Value;
222 public override string ComputedKeyAlgorithm
224 get { return DriverDictionary.Psha1ComputedKeyUri.Value; }
227 public override SecurityStandardsManager StandardsManager
231 return this.standardsManager;
235 public override XmlDictionaryString Namespace
237 get { return DriverDictionary.Namespace; }
240 public override RequestSecurityToken CreateRequestSecurityToken(XmlReader xmlReader)
242 XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
243 reader.MoveToStartElement(DriverDictionary.RequestSecurityToken, DriverDictionary.Namespace);
244 string context = null;
245 string tokenTypeUri = null;
246 string requestType = null;
248 XmlDocument doc = new XmlDocument();
249 XmlElement rstXml = (doc.ReadNode(reader) as XmlElement);
250 SecurityKeyIdentifierClause renewTarget = null;
251 SecurityKeyIdentifierClause closeTarget = null;
252 for (int i = 0; i < rstXml.Attributes.Count; ++i)
254 XmlAttribute attr = rstXml.Attributes[i];
255 if (attr.LocalName == DriverDictionary.Context.Value)
257 context = attr.Value;
260 for (int i = 0; i < rstXml.ChildNodes.Count; ++i)
262 XmlElement child = (rstXml.ChildNodes[i] as XmlElement);
265 if (child.LocalName == DriverDictionary.TokenType.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
266 tokenTypeUri = XmlHelper.ReadTextElementAsTrimmedString(child);
267 else if (child.LocalName == DriverDictionary.RequestType.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
268 requestType = XmlHelper.ReadTextElementAsTrimmedString(child);
269 else if (child.LocalName == DriverDictionary.KeySize.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
270 keySize = Int32.Parse(XmlHelper.ReadTextElementAsTrimmedString(child), NumberFormatInfo.InvariantInfo);
274 ReadTargets(rstXml, out renewTarget, out closeTarget);
276 RequestSecurityToken rst = new RequestSecurityToken(standardsManager, rstXml, context, tokenTypeUri, requestType, keySize, renewTarget, closeTarget);
280 System.IdentityModel.XmlBuffer GetIssuedTokenBuffer(System.IdentityModel.XmlBuffer rstrBuffer)
282 System.IdentityModel.XmlBuffer issuedTokenBuffer = null;
283 using (XmlDictionaryReader reader = rstrBuffer.GetReader(0))
285 reader.ReadFullStartElement();
286 while (reader.IsStartElement())
288 if (reader.IsStartElement(this.DriverDictionary.RequestedSecurityToken, this.DriverDictionary.Namespace))
290 reader.ReadStartElement();
291 reader.MoveToContent();
292 issuedTokenBuffer = new System.IdentityModel.XmlBuffer(Int32.MaxValue);
293 using (XmlDictionaryWriter writer = issuedTokenBuffer.OpenSection(reader.Quotas))
295 writer.WriteNode(reader, false);
296 issuedTokenBuffer.CloseSection();
297 issuedTokenBuffer.Close();
299 reader.ReadEndElement();
308 return issuedTokenBuffer;
311 public override RequestSecurityTokenResponse CreateRequestSecurityTokenResponse(XmlReader xmlReader)
313 if (xmlReader == null)
315 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("xmlReader");
317 XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
318 if (reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponse, DriverDictionary.Namespace) == false)
320 XmlHelper.OnRequiredElementMissing(DriverDictionary.RequestSecurityTokenResponse.Value, DriverDictionary.Namespace.Value);
323 System.IdentityModel.XmlBuffer rstrBuffer = new System.IdentityModel.XmlBuffer(Int32.MaxValue);
324 using (XmlDictionaryWriter writer = rstrBuffer.OpenSection(reader.Quotas))
326 writer.WriteNode(reader, false);
327 rstrBuffer.CloseSection();
330 XmlDocument doc = new XmlDocument();
332 using (XmlReader reader2 = rstrBuffer.GetReader(0))
334 rstrXml = (doc.ReadNode(reader2) as XmlElement);
337 System.IdentityModel.XmlBuffer issuedTokenBuffer = GetIssuedTokenBuffer(rstrBuffer);
338 string context = null;
339 string tokenTypeUri = null;
341 SecurityKeyIdentifierClause requestedAttachedReference = null;
342 SecurityKeyIdentifierClause requestedUnattachedReference = null;
343 bool computeKey = false;
344 DateTime created = DateTime.UtcNow;
345 DateTime expires = SecurityUtils.MaxUtcDateTime;
346 bool isRequestedTokenClosed = false;
347 for (int i = 0; i < rstrXml.Attributes.Count; ++i)
349 XmlAttribute attr = rstrXml.Attributes[i];
350 if (attr.LocalName == DriverDictionary.Context.Value)
352 context = attr.Value;
356 for (int i = 0; i < rstrXml.ChildNodes.Count; ++i)
358 XmlElement child = (rstrXml.ChildNodes[i] as XmlElement);
361 if (child.LocalName == DriverDictionary.TokenType.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
362 tokenTypeUri = XmlHelper.ReadTextElementAsTrimmedString(child);
363 else if (child.LocalName == DriverDictionary.KeySize.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
364 keySize = Int32.Parse(XmlHelper.ReadTextElementAsTrimmedString(child), NumberFormatInfo.InvariantInfo);
365 else if (child.LocalName == DriverDictionary.RequestedProofToken.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
367 XmlElement proofXml = XmlHelper.GetChildElement(child);
368 if (proofXml.LocalName == DriverDictionary.ComputedKey.Value && proofXml.NamespaceURI == DriverDictionary.Namespace.Value)
370 string computedKeyAlgorithm = XmlHelper.ReadTextElementAsTrimmedString(proofXml);
371 if (computedKeyAlgorithm != this.DriverDictionary.Psha1ComputedKeyUri.Value)
373 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.UnknownComputedKeyAlgorithm, computedKeyAlgorithm)));
378 else if (child.LocalName == DriverDictionary.Lifetime.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
380 XmlElement createdXml = XmlHelper.GetChildElement(child, UtilityStrings.CreatedElement, UtilityStrings.Namespace);
381 if (createdXml != null)
383 created = DateTime.ParseExact(XmlHelper.ReadTextElementAsTrimmedString(createdXml),
384 WSUtilitySpecificationVersion.AcceptedDateTimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
386 XmlElement expiresXml = XmlHelper.GetChildElement(child, UtilityStrings.ExpiresElement, UtilityStrings.Namespace);
387 if (expiresXml != null)
389 expires = DateTime.ParseExact(XmlHelper.ReadTextElementAsTrimmedString(expiresXml),
390 WSUtilitySpecificationVersion.AcceptedDateTimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
396 isRequestedTokenClosed = ReadRequestedTokenClosed(rstrXml);
397 ReadReferences(rstrXml, out requestedAttachedReference, out requestedUnattachedReference);
399 return new RequestSecurityTokenResponse(standardsManager, rstrXml, context, tokenTypeUri, keySize, requestedAttachedReference, requestedUnattachedReference,
400 computeKey, created, expires, isRequestedTokenClosed, issuedTokenBuffer);
403 public override RequestSecurityTokenResponseCollection CreateRequestSecurityTokenResponseCollection(XmlReader xmlReader)
405 XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(xmlReader);
406 List<RequestSecurityTokenResponse> rstrCollection = new List<RequestSecurityTokenResponse>(2);
407 string rootName = reader.Name;
408 reader.ReadStartElement(DriverDictionary.RequestSecurityTokenResponseCollection, DriverDictionary.Namespace);
409 while (reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponse.Value, DriverDictionary.Namespace.Value))
411 RequestSecurityTokenResponse rstr = this.CreateRequestSecurityTokenResponse(reader);
412 rstrCollection.Add(rstr);
414 reader.ReadEndElement();
415 if (rstrCollection.Count == 0)
416 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.NoRequestSecurityTokenResponseElements)));
417 return new RequestSecurityTokenResponseCollection(rstrCollection.AsReadOnly(), this.StandardsManager);
420 XmlElement GetAppliesToElement(XmlElement rootElement)
422 if (rootElement == null)
426 for (int i = 0; i < rootElement.ChildNodes.Count; ++i)
428 XmlElement elem = (rootElement.ChildNodes[i] as XmlElement);
431 if (elem.LocalName == DriverDictionary.AppliesTo.Value && elem.NamespaceURI == Namespaces.WSPolicy)
440 T GetAppliesTo<T>(XmlElement rootXml, XmlObjectSerializer serializer)
442 XmlElement appliesToElement = GetAppliesToElement(rootXml);
443 if (appliesToElement != null)
445 using (XmlReader reader = new XmlNodeReader(appliesToElement))
447 reader.ReadStartElement();
450 return (T)serializer.ReadObject(reader);
456 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoAppliesToPresent)));
460 public override T GetAppliesTo<T>(RequestSecurityToken rst, XmlObjectSerializer serializer)
463 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
465 return GetAppliesTo<T>(rst.RequestSecurityTokenXml, serializer);
468 public override T GetAppliesTo<T>(RequestSecurityTokenResponse rstr, XmlObjectSerializer serializer)
471 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
473 return GetAppliesTo<T>(rstr.RequestSecurityTokenResponseXml, serializer);
476 public override bool IsAppliesTo(string localName, string namespaceUri)
478 return (localName == DriverDictionary.AppliesTo.Value && namespaceUri == Namespaces.WSPolicy);
481 void GetAppliesToQName(XmlElement rootElement, out string localName, out string namespaceUri)
483 localName = namespaceUri = null;
484 XmlElement appliesToElement = GetAppliesToElement(rootElement);
485 if (appliesToElement != null)
487 using (XmlReader reader = new XmlNodeReader(appliesToElement))
489 reader.ReadStartElement();
490 reader.MoveToContent();
491 localName = reader.LocalName;
492 namespaceUri = reader.NamespaceURI;
497 public override void GetAppliesToQName(RequestSecurityToken rst, out string localName, out string namespaceUri)
500 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
502 GetAppliesToQName(rst.RequestSecurityTokenXml, out localName, out namespaceUri);
505 public override void GetAppliesToQName(RequestSecurityTokenResponse rstr, out string localName, out string namespaceUri)
508 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
510 GetAppliesToQName(rstr.RequestSecurityTokenResponseXml, out localName, out namespaceUri);
513 public override byte[] GetAuthenticator(RequestSecurityTokenResponse rstr)
515 if (rstr != null && rstr.RequestSecurityTokenResponseXml != null && rstr.RequestSecurityTokenResponseXml.ChildNodes != null)
517 for (int i = 0; i < rstr.RequestSecurityTokenResponseXml.ChildNodes.Count; ++i)
519 XmlElement element = rstr.RequestSecurityTokenResponseXml.ChildNodes[i] as XmlElement;
522 if (element.LocalName == DriverDictionary.Authenticator.Value && element.NamespaceURI == DriverDictionary.Namespace.Value)
524 XmlElement combinedHashElement = XmlHelper.GetChildElement(element);
525 if (combinedHashElement.LocalName == DriverDictionary.CombinedHash.Value && combinedHashElement.NamespaceURI == DriverDictionary.Namespace.Value)
527 string authenticatorString = XmlHelper.ReadTextElementAsTrimmedString(combinedHashElement);
528 return Convert.FromBase64String(authenticatorString);
537 public override BinaryNegotiation GetBinaryNegotiation(RequestSecurityTokenResponse rstr)
540 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
542 return GetBinaryNegotiation(rstr.RequestSecurityTokenResponseXml);
545 public override BinaryNegotiation GetBinaryNegotiation(RequestSecurityToken rst)
548 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
550 return GetBinaryNegotiation(rst.RequestSecurityTokenXml);
553 BinaryNegotiation GetBinaryNegotiation(XmlElement rootElement)
555 if (rootElement == null)
559 for (int i = 0; i < rootElement.ChildNodes.Count; ++i)
561 XmlElement elem = rootElement.ChildNodes[i] as XmlElement;
564 if (elem.LocalName == DriverDictionary.BinaryExchange.Value && elem.NamespaceURI == DriverDictionary.Namespace.Value)
566 return ReadBinaryNegotiation(elem);
573 public override SecurityToken GetEntropy(RequestSecurityToken rst, SecurityTokenResolver resolver)
576 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
578 return GetEntropy(rst.RequestSecurityTokenXml, resolver);
581 public override SecurityToken GetEntropy(RequestSecurityTokenResponse rstr, SecurityTokenResolver resolver)
584 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
586 return GetEntropy(rstr.RequestSecurityTokenResponseXml, resolver);
589 SecurityToken GetEntropy(XmlElement rootElement, SecurityTokenResolver resolver)
591 if (rootElement == null || rootElement.ChildNodes == null)
595 for (int i = 0; i < rootElement.ChildNodes.Count; ++i)
597 XmlElement element = rootElement.ChildNodes[i] as XmlElement;
600 if (element.LocalName == DriverDictionary.Entropy.Value && element.NamespaceURI == DriverDictionary.Namespace.Value)
602 XmlElement tokenXml = XmlHelper.GetChildElement(element);
603 string valueTypeUri = element.GetAttribute(SecurityJan2004Strings.ValueType);
604 if (valueTypeUri.Length == 0)
606 return standardsManager.SecurityTokenSerializer.ReadToken(new XmlNodeReader(tokenXml), resolver);
613 void GetIssuedAndProofXml(RequestSecurityTokenResponse rstr, out XmlElement issuedTokenXml, out XmlElement proofTokenXml)
615 issuedTokenXml = null;
616 proofTokenXml = null;
617 if ((rstr.RequestSecurityTokenResponseXml != null) && (rstr.RequestSecurityTokenResponseXml.ChildNodes != null))
619 for (int i = 0; i < rstr.RequestSecurityTokenResponseXml.ChildNodes.Count; ++i)
621 XmlElement elem = rstr.RequestSecurityTokenResponseXml.ChildNodes[i] as XmlElement;
624 if (elem.LocalName == DriverDictionary.RequestedSecurityToken.Value && elem.NamespaceURI == DriverDictionary.Namespace.Value)
626 if (issuedTokenXml != null)
628 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RstrHasMultipleIssuedTokens)));
630 issuedTokenXml = XmlHelper.GetChildElement(elem);
632 else if (elem.LocalName == DriverDictionary.RequestedProofToken.Value && elem.NamespaceURI == DriverDictionary.Namespace.Value)
634 if (proofTokenXml != null)
636 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RstrHasMultipleProofTokens)));
638 proofTokenXml = XmlHelper.GetChildElement(elem);
646 /// The algorithm for computing the key is:
647 /// 1. If there is requestorEntropy:
648 /// a. If there is no <RequestedProofToken> use the requestorEntropy as the key
649 /// b. If there is a <RequestedProofToken> with a ComputedKeyUri, combine the client and server entropies
650 /// c. Anything else, throw
651 /// 2. If there is no requestorEntropy:
652 /// a. THere has to be a <RequestedProofToken> that contains the proof key
654 public override GenericXmlSecurityToken GetIssuedToken(RequestSecurityTokenResponse rstr, SecurityTokenResolver resolver, IList<SecurityTokenAuthenticator> allowedAuthenticators, SecurityKeyEntropyMode keyEntropyMode, byte[] requestorEntropy, string expectedTokenType,
655 ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, int defaultKeySize, bool isBearerKeyType)
658 SecurityKeyEntropyModeHelper.Validate(keyEntropyMode);
660 if (defaultKeySize < 0)
662 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("defaultKeySize", SR.GetString(SR.ValueMustBeNonNegative)));
666 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
669 if (rstr.TokenType != null)
671 if (expectedTokenType != null && expectedTokenType != rstr.TokenType)
673 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BadIssuedTokenType, rstr.TokenType, expectedTokenType)));
675 tokenType = rstr.TokenType;
679 tokenType = expectedTokenType;
682 // search the response elements for licenseXml, proofXml, and lifetime
683 DateTime created = rstr.ValidFrom;
684 DateTime expires = rstr.ValidTo;
686 XmlElement issuedTokenXml;
687 GetIssuedAndProofXml(rstr, out issuedTokenXml, out proofXml);
689 if (issuedTokenXml == null)
690 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoLicenseXml)));
694 if (proofXml != null)
695 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BearerKeyTypeCannotHaveProofKey)));
697 return new GenericXmlSecurityToken(issuedTokenXml, null, created, expires, rstr.RequestedAttachedReference, rstr.RequestedUnattachedReference, authorizationPolicies);
700 SecurityToken proofToken;
701 SecurityToken entropyToken = GetEntropy(rstr, resolver);
702 if (keyEntropyMode == SecurityKeyEntropyMode.ClientEntropy)
704 if (requestorEntropy == null)
706 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresRequestorEntropy, keyEntropyMode)));
708 // enforce that there is no entropy or proof token in the RSTR
709 if (proofXml != null || entropyToken != null)
711 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveProofTokenOrIssuerEntropy, keyEntropyMode)));
713 proofToken = new BinarySecretSecurityToken(requestorEntropy);
715 else if (keyEntropyMode == SecurityKeyEntropyMode.ServerEntropy)
717 if (requestorEntropy != null)
719 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveRequestorEntropy, keyEntropyMode)));
721 if (rstr.ComputeKey || entropyToken != null)
723 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveComputedKey, keyEntropyMode)));
725 if (proofXml == null)
727 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresProofToken, keyEntropyMode)));
729 string valueTypeUri = proofXml.GetAttribute(SecurityJan2004Strings.ValueType);
730 if (valueTypeUri.Length == 0)
732 proofToken = standardsManager.SecurityTokenSerializer.ReadToken(new XmlNodeReader(proofXml), resolver);
736 if (!rstr.ComputeKey)
738 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresComputedKey, keyEntropyMode)));
740 if (entropyToken == null)
742 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresIssuerEntropy, keyEntropyMode)));
744 if (requestorEntropy == null)
746 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresRequestorEntropy, keyEntropyMode)));
748 if (rstr.KeySize == 0 && defaultKeySize == 0)
750 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.RstrKeySizeNotProvided)));
752 int issuedKeySize = (rstr.KeySize != 0) ? rstr.KeySize : defaultKeySize;
753 byte[] issuerEntropy;
754 if (entropyToken is BinarySecretSecurityToken)
755 issuerEntropy = ((BinarySecretSecurityToken)entropyToken).GetKeyBytes();
756 else if (entropyToken is WrappedKeySecurityToken)
757 issuerEntropy = ((WrappedKeySecurityToken)entropyToken).GetWrappedKey();
759 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.UnsupportedIssuerEntropyType)));
760 // compute the PSHA1 derived key
761 byte[] issuedKey = RequestSecurityTokenResponse.ComputeCombinedKey(requestorEntropy, issuerEntropy, issuedKeySize);
762 proofToken = new BinarySecretSecurityToken(issuedKey);
765 SecurityKeyIdentifierClause internalReference = rstr.RequestedAttachedReference;
766 SecurityKeyIdentifierClause externalReference = rstr.RequestedUnattachedReference;
768 return new BufferedGenericXmlSecurityToken(issuedTokenXml, proofToken, created, expires, internalReference, externalReference, authorizationPolicies, rstr.IssuedTokenBuffer);
771 public override GenericXmlSecurityToken GetIssuedToken(RequestSecurityTokenResponse rstr, string expectedTokenType,
772 ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies, RSA clientKey)
775 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("rstr"));
778 if (rstr.TokenType != null)
780 if (expectedTokenType != null && expectedTokenType != rstr.TokenType)
782 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BadIssuedTokenType, rstr.TokenType, expectedTokenType)));
784 tokenType = rstr.TokenType;
788 tokenType = expectedTokenType;
791 // search the response elements for licenseXml, proofXml, and lifetime
792 DateTime created = rstr.ValidFrom;
793 DateTime expires = rstr.ValidTo;
795 XmlElement issuedTokenXml;
796 GetIssuedAndProofXml(rstr, out issuedTokenXml, out proofXml);
798 if (issuedTokenXml == null)
799 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoLicenseXml)));
801 // enforce that there is no proof token in the RSTR
802 if (proofXml != null)
804 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ProofTokenXmlUnexpectedInRstr)));
806 SecurityKeyIdentifierClause internalReference = rstr.RequestedAttachedReference;
807 SecurityKeyIdentifierClause externalReference = rstr.RequestedUnattachedReference;
809 SecurityToken proofToken = new RsaSecurityToken(clientKey);
810 return new BufferedGenericXmlSecurityToken(issuedTokenXml, proofToken, created, expires, internalReference, externalReference, authorizationPolicies, rstr.IssuedTokenBuffer);
813 public override bool IsAtRequestSecurityTokenResponse(XmlReader reader)
816 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
818 return reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponse.Value, DriverDictionary.Namespace.Value);
821 public override bool IsAtRequestSecurityTokenResponseCollection(XmlReader reader)
824 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
826 return reader.IsStartElement(DriverDictionary.RequestSecurityTokenResponseCollection.Value, DriverDictionary.Namespace.Value);
829 public override bool IsRequestedSecurityTokenElement(string name, string nameSpace)
831 return (name == DriverDictionary.RequestedSecurityToken.Value && nameSpace == DriverDictionary.Namespace.Value);
834 public override bool IsRequestedProofTokenElement(string name, string nameSpace)
836 return (name == DriverDictionary.RequestedProofToken.Value && nameSpace == DriverDictionary.Namespace.Value);
839 public static BinaryNegotiation ReadBinaryNegotiation(XmlElement elem)
842 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elem");
844 // get the encoding and valueType attributes
845 string encodingUri = null;
846 string valueTypeUri = null;
847 byte[] negotiationData = null;
848 if (elem.Attributes != null)
850 for (int i = 0; i < elem.Attributes.Count; ++i)
852 XmlAttribute attr = elem.Attributes[i];
853 if (attr.LocalName == SecurityJan2004Strings.EncodingType && attr.NamespaceURI.Length == 0)
855 encodingUri = attr.Value;
856 if (encodingUri != base64Uri && encodingUri != hexBinaryUri)
858 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.UnsupportedBinaryEncoding, encodingUri)));
861 else if (attr.LocalName == SecurityJan2004Strings.ValueType && attr.NamespaceURI.Length == 0)
863 valueTypeUri = attr.Value;
865 // ignore all other attributes
868 if (encodingUri == null)
870 XmlHelper.OnRequiredAttributeMissing("EncodingType", elem.Name);
872 if (valueTypeUri == null)
874 XmlHelper.OnRequiredAttributeMissing("ValueType", elem.Name);
876 string encodedBlob = XmlHelper.ReadTextElementAsTrimmedString(elem);
877 if (encodingUri == base64Uri)
879 negotiationData = Convert.FromBase64String(encodedBlob);
883 negotiationData = HexBinary.Parse(encodedBlob).Value;
885 return new BinaryNegotiation(valueTypeUri, negotiationData);
888 // Note in Apr2004, internal & external references aren't supported -
889 // our strategy is to see if there's a token reference (and use it for external ref) and backup is to scan the token xml to compute reference
890 protected virtual void ReadReferences(XmlElement rstrXml, out SecurityKeyIdentifierClause requestedAttachedReference,
891 out SecurityKeyIdentifierClause requestedUnattachedReference)
893 XmlElement issuedTokenXml = null;
894 requestedAttachedReference = null;
895 requestedUnattachedReference = null;
896 for (int i = 0; i < rstrXml.ChildNodes.Count; ++i)
898 XmlElement child = rstrXml.ChildNodes[i] as XmlElement;
901 if (child.LocalName == DriverDictionary.RequestedSecurityToken.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
903 issuedTokenXml = XmlHelper.GetChildElement(child);
905 else if (child.LocalName == DriverDictionary.RequestedTokenReference.Value && child.NamespaceURI == DriverDictionary.Namespace.Value)
907 requestedUnattachedReference = GetKeyIdentifierXmlReferenceClause(XmlHelper.GetChildElement(child));
912 if (issuedTokenXml != null)
914 requestedAttachedReference = standardsManager.CreateKeyIdentifierClauseFromTokenXml(issuedTokenXml, SecurityTokenReferenceStyle.Internal);
915 if (requestedUnattachedReference == null)
919 requestedUnattachedReference = standardsManager.CreateKeyIdentifierClauseFromTokenXml(issuedTokenXml, SecurityTokenReferenceStyle.External);
923 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.TrustDriverIsUnableToCreatedNecessaryAttachedOrUnattachedReferences, issuedTokenXml.ToString())));
929 internal bool TryReadKeyIdentifierClause(XmlNodeReader reader, out SecurityKeyIdentifierClause keyIdentifierClause)
931 keyIdentifierClause = null;
935 keyIdentifierClause = standardsManager.SecurityTokenSerializer.ReadKeyIdentifierClause(reader);
937 catch (XmlException e)
944 keyIdentifierClause = null;
954 keyIdentifierClause = null;
961 internal SecurityKeyIdentifierClause CreateGenericXmlSecurityKeyIdentifierClause(XmlNodeReader reader, XmlElement keyIdentifierReferenceXmlElement)
963 SecurityKeyIdentifierClause keyIdentifierClause = null;
964 XmlDictionaryReader localReader = XmlDictionaryReader.CreateDictionaryReader(reader);
965 string strId = localReader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);
966 keyIdentifierClause = new GenericXmlSecurityKeyIdentifierClause(keyIdentifierReferenceXmlElement);
967 if (!String.IsNullOrEmpty(strId))
969 keyIdentifierClause.Id = strId;
971 return keyIdentifierClause;
974 internal SecurityKeyIdentifierClause GetKeyIdentifierXmlReferenceClause(XmlElement keyIdentifierReferenceXmlElement)
976 SecurityKeyIdentifierClause keyIdentifierClause = null;
977 XmlNodeReader reader = new XmlNodeReader(keyIdentifierReferenceXmlElement);
978 if (!this.TryReadKeyIdentifierClause(reader, out keyIdentifierClause))
980 keyIdentifierClause = CreateGenericXmlSecurityKeyIdentifierClause(new XmlNodeReader(keyIdentifierReferenceXmlElement), keyIdentifierReferenceXmlElement);
983 return keyIdentifierClause;
986 protected virtual bool ReadRequestedTokenClosed(XmlElement rstrXml)
991 protected virtual void ReadTargets(XmlElement rstXml, out SecurityKeyIdentifierClause renewTarget, out SecurityKeyIdentifierClause closeTarget)
997 public override void OnRSTRorRSTRCMissingException()
999 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ExpectedOneOfTwoElementsFromNamespace,
1000 DriverDictionary.RequestSecurityTokenResponse, DriverDictionary.RequestSecurityTokenResponseCollection,
1001 DriverDictionary.Namespace)));
1004 void WriteAppliesTo(object appliesTo, Type appliesToType, XmlObjectSerializer serializer, XmlWriter xmlWriter)
1006 XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
1007 writer.WriteStartElement(Namespaces.WSPolicyPrefix, DriverDictionary.AppliesTo.Value, Namespaces.WSPolicy);
1010 serializer.WriteObject(writer, appliesTo);
1012 writer.WriteEndElement();
1015 public void WriteBinaryNegotiation(BinaryNegotiation negotiation, XmlWriter xmlWriter)
1017 if (negotiation == null)
1018 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("negotiation");
1020 XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
1021 negotiation.WriteTo(writer, this.DriverDictionary.Prefix.Value,
1022 this.DriverDictionary.BinaryExchange, this.DriverDictionary.Namespace,
1023 XD.SecurityJan2004Dictionary.ValueType, null);
1026 public override void WriteRequestSecurityToken(RequestSecurityToken rst, XmlWriter xmlWriter)
1030 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rst");
1032 if (xmlWriter == null)
1034 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("xmlWriter");
1036 XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
1039 rst.WriteTo(writer);
1042 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestSecurityToken, DriverDictionary.Namespace);
1043 XmlHelper.AddNamespaceDeclaration(writer, DriverDictionary.Prefix.Value, DriverDictionary.Namespace);
1044 if (rst.Context != null)
1045 writer.WriteAttributeString(DriverDictionary.Context, null, rst.Context);
1047 rst.OnWriteCustomAttributes(writer);
1048 if (rst.TokenType != null)
1050 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.TokenType, DriverDictionary.Namespace);
1051 writer.WriteString(rst.TokenType);
1052 writer.WriteEndElement();
1054 if (rst.RequestType != null)
1056 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestType, DriverDictionary.Namespace);
1057 writer.WriteString(rst.RequestType);
1058 writer.WriteEndElement();
1061 if (rst.AppliesTo != null)
1063 WriteAppliesTo(rst.AppliesTo, rst.AppliesToType, rst.AppliesToSerializer, writer);
1066 SecurityToken entropyToken = rst.GetRequestorEntropy();
1067 if (entropyToken != null)
1069 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Entropy, DriverDictionary.Namespace);
1070 standardsManager.SecurityTokenSerializer.WriteToken(writer, entropyToken);
1071 writer.WriteEndElement();
1074 if (rst.KeySize != 0)
1076 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.KeySize, DriverDictionary.Namespace);
1077 writer.WriteValue(rst.KeySize);
1078 writer.WriteEndElement();
1081 BinaryNegotiation negotiationData = rst.GetBinaryNegotiation();
1082 if (negotiationData != null)
1083 WriteBinaryNegotiation(negotiationData, writer);
1085 WriteTargets(rst, writer);
1087 if (rst.RequestProperties != null)
1089 foreach (XmlElement property in rst.RequestProperties)
1091 property.WriteTo(writer);
1095 rst.OnWriteCustomElements(writer);
1096 writer.WriteEndElement();
1099 protected virtual void WriteTargets(RequestSecurityToken rst, XmlDictionaryWriter writer)
1103 // Note in Apr2004, internal & external references aren't supported - our strategy is to generate the external ref as the TokenReference.
1104 protected virtual void WriteReferences(RequestSecurityTokenResponse rstr, XmlDictionaryWriter writer)
1106 if (rstr.RequestedUnattachedReference != null)
1108 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestedTokenReference, DriverDictionary.Namespace);
1109 standardsManager.SecurityTokenSerializer.WriteKeyIdentifierClause(writer, rstr.RequestedUnattachedReference);
1110 writer.WriteEndElement();
1114 protected virtual void WriteRequestedTokenClosed(RequestSecurityTokenResponse rstr, XmlDictionaryWriter writer)
1118 public override void WriteRequestSecurityTokenResponse(RequestSecurityTokenResponse rstr, XmlWriter xmlWriter)
1121 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
1122 if (xmlWriter == null)
1123 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("xmlWriter");
1124 XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
1125 if (rstr.IsReceiver)
1127 rstr.WriteTo(writer);
1130 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestSecurityTokenResponse, DriverDictionary.Namespace);
1131 if (rstr.Context != null)
1133 writer.WriteAttributeString(DriverDictionary.Context, null, rstr.Context);
1135 // define WSUtility at the top level to avoid multiple definitions below
1136 XmlHelper.AddNamespaceDeclaration(writer, UtilityStrings.Prefix, XD.UtilityDictionary.Namespace);
1137 rstr.OnWriteCustomAttributes(writer);
1139 if (rstr.TokenType != null)
1140 writer.WriteElementString(DriverDictionary.Prefix.Value, DriverDictionary.TokenType, DriverDictionary.Namespace, rstr.TokenType);
1142 if (rstr.RequestedSecurityToken != null)
1144 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestedSecurityToken, DriverDictionary.Namespace);
1145 standardsManager.SecurityTokenSerializer.WriteToken(writer, rstr.RequestedSecurityToken);
1146 writer.WriteEndElement();
1149 if (rstr.AppliesTo != null)
1151 WriteAppliesTo(rstr.AppliesTo, rstr.AppliesToType, rstr.AppliesToSerializer, writer);
1154 WriteReferences(rstr, writer);
1156 if (rstr.ComputeKey || rstr.RequestedProofToken != null)
1158 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestedProofToken, DriverDictionary.Namespace);
1159 if (rstr.ComputeKey)
1161 writer.WriteElementString(DriverDictionary.Prefix.Value, DriverDictionary.ComputedKey, DriverDictionary.Namespace, DriverDictionary.Psha1ComputedKeyUri.Value);
1165 standardsManager.SecurityTokenSerializer.WriteToken(writer, rstr.RequestedProofToken);
1167 writer.WriteEndElement();
1170 SecurityToken entropyToken = rstr.GetIssuerEntropy();
1171 if (entropyToken != null)
1173 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Entropy, DriverDictionary.Namespace);
1174 standardsManager.SecurityTokenSerializer.WriteToken(writer, entropyToken);
1175 writer.WriteEndElement();
1178 // To write out the lifetime, the following algorithm is used
1179 // 1. If the lifetime is explicitly set, write it out.
1180 // 2. Else, if a token/tokenbuilder has been set, use the lifetime in that.
1181 // 3. Else do not serialize lifetime
1182 if (rstr.IsLifetimeSet || rstr.RequestedSecurityToken != null)
1184 DateTime effectiveTime = SecurityUtils.MinUtcDateTime;
1185 DateTime expirationTime = SecurityUtils.MaxUtcDateTime;
1187 if (rstr.IsLifetimeSet)
1189 effectiveTime = rstr.ValidFrom.ToUniversalTime();
1190 expirationTime = rstr.ValidTo.ToUniversalTime();
1192 else if (rstr.RequestedSecurityToken != null)
1194 effectiveTime = rstr.RequestedSecurityToken.ValidFrom.ToUniversalTime();
1195 expirationTime = rstr.RequestedSecurityToken.ValidTo.ToUniversalTime();
1198 // write out the lifetime
1199 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Lifetime, DriverDictionary.Namespace);
1200 // write out Created
1201 writer.WriteStartElement(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.CreatedElement, XD.UtilityDictionary.Namespace);
1202 writer.WriteString(effectiveTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture.DateTimeFormat));
1203 writer.WriteEndElement(); // wsu:Created
1204 // write out Expires
1205 writer.WriteStartElement(XD.UtilityDictionary.Prefix.Value, XD.UtilityDictionary.ExpiresElement, XD.UtilityDictionary.Namespace);
1206 writer.WriteString(expirationTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ", CultureInfo.InvariantCulture.DateTimeFormat));
1207 writer.WriteEndElement(); // wsu:Expires
1208 writer.WriteEndElement(); // wsse:Lifetime
1211 byte[] authenticator = rstr.GetAuthenticator();
1212 if (authenticator != null)
1214 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.Authenticator, DriverDictionary.Namespace);
1215 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.CombinedHash, DriverDictionary.Namespace);
1216 writer.WriteBase64(authenticator, 0, authenticator.Length);
1217 writer.WriteEndElement();
1218 writer.WriteEndElement();
1221 if (rstr.KeySize > 0)
1223 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.KeySize, DriverDictionary.Namespace);
1224 writer.WriteValue(rstr.KeySize);
1225 writer.WriteEndElement();
1228 WriteRequestedTokenClosed(rstr, writer);
1230 BinaryNegotiation negotiationData = rstr.GetBinaryNegotiation();
1231 if (negotiationData != null)
1232 WriteBinaryNegotiation(negotiationData, writer);
1234 rstr.OnWriteCustomElements(writer);
1235 writer.WriteEndElement();
1238 public override void WriteRequestSecurityTokenResponseCollection(RequestSecurityTokenResponseCollection rstrCollection, XmlWriter xmlWriter)
1240 if (rstrCollection == null)
1241 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstrCollection");
1243 XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);
1244 writer.WriteStartElement(DriverDictionary.Prefix.Value, DriverDictionary.RequestSecurityTokenResponseCollection, DriverDictionary.Namespace);
1245 foreach (RequestSecurityTokenResponse rstr in rstrCollection.RstrCollection)
1247 rstr.WriteTo(writer);
1249 writer.WriteEndElement();
1252 protected void SetProtectionLevelForFederation(OperationDescriptionCollection operations)
1254 foreach (OperationDescription operation in operations)
1256 foreach (MessageDescription message in operation.Messages)
1258 if (message.Body.Parts.Count > 0)
1260 foreach (MessagePartDescription part in message.Body.Parts)
1262 part.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
1265 if (OperationFormatter.IsValidReturnValue(message.Body.ReturnValue))
1267 message.Body.ReturnValue.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;
1273 public override bool TryParseKeySizeElement(XmlElement element, out int keySize)
1275 if (element == null)
1276 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
1278 if (element.LocalName == this.DriverDictionary.KeySize.Value
1279 && element.NamespaceURI == this.DriverDictionary.Namespace.Value)
1281 keySize = Int32.Parse(XmlHelper.ReadTextElementAsTrimmedString(element), NumberFormatInfo.InvariantInfo);
1289 public override XmlElement CreateKeySizeElement(int keySize)
1293 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("keySize", SR.GetString(SR.ValueMustBeNonNegative)));
1295 XmlDocument doc = new XmlDocument();
1296 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.KeySize.Value,
1297 this.DriverDictionary.Namespace.Value);
1298 result.AppendChild(doc.CreateTextNode(keySize.ToString(System.Globalization.CultureInfo.InvariantCulture.NumberFormat)));
1302 public override XmlElement CreateKeyTypeElement(SecurityKeyType keyType)
1304 if (keyType == SecurityKeyType.SymmetricKey)
1305 return CreateSymmetricKeyTypeElement();
1306 else if (keyType == SecurityKeyType.AsymmetricKey)
1307 return CreatePublicKeyTypeElement();
1309 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToCreateKeyTypeElementForUnknownKeyType, keyType.ToString())));
1312 public override bool TryParseKeyTypeElement(XmlElement element, out SecurityKeyType keyType)
1314 if (element == null)
1315 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
1317 if (TryParseSymmetricKeyElement(element))
1319 keyType = SecurityKeyType.SymmetricKey;
1322 else if (TryParsePublicKeyElement(element))
1324 keyType = SecurityKeyType.AsymmetricKey;
1328 keyType = SecurityKeyType.SymmetricKey;
1333 public bool TryParseSymmetricKeyElement(XmlElement element)
1335 if (element == null)
1336 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
1338 return element.LocalName == this.DriverDictionary.KeyType.Value
1339 && element.NamespaceURI == this.DriverDictionary.Namespace.Value
1340 && element.InnerText == this.DriverDictionary.SymmetricKeyType.Value;
1343 XmlElement CreateSymmetricKeyTypeElement()
1345 XmlDocument doc = new XmlDocument();
1346 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.KeyType.Value,
1347 this.DriverDictionary.Namespace.Value);
1348 result.AppendChild(doc.CreateTextNode(this.DriverDictionary.SymmetricKeyType.Value));
1352 bool TryParsePublicKeyElement(XmlElement element)
1354 if (element == null)
1355 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
1357 return element.LocalName == this.DriverDictionary.KeyType.Value
1358 && element.NamespaceURI == this.DriverDictionary.Namespace.Value
1359 && element.InnerText == this.DriverDictionary.PublicKeyType.Value;
1362 XmlElement CreatePublicKeyTypeElement()
1364 XmlDocument doc = new XmlDocument();
1365 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.KeyType.Value,
1366 this.DriverDictionary.Namespace.Value);
1367 result.AppendChild(doc.CreateTextNode(this.DriverDictionary.PublicKeyType.Value));
1371 public override bool TryParseTokenTypeElement(XmlElement element, out string tokenType)
1373 if (element == null)
1374 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
1376 if (element.LocalName == this.DriverDictionary.TokenType.Value
1377 && element.NamespaceURI == this.DriverDictionary.Namespace.Value)
1379 tokenType = element.InnerText;
1387 public override XmlElement CreateTokenTypeElement(string tokenTypeUri)
1389 if (tokenTypeUri == null)
1391 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenTypeUri");
1393 XmlDocument doc = new XmlDocument();
1394 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.TokenType.Value,
1395 this.DriverDictionary.Namespace.Value);
1396 result.AppendChild(doc.CreateTextNode(tokenTypeUri));
1400 public override XmlElement CreateUseKeyElement(SecurityKeyIdentifier keyIdentifier, SecurityStandardsManager standardsManager)
1402 if (keyIdentifier == null)
1404 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("keyIdentifier");
1406 if (standardsManager == null)
1408 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("standardsManager");
1410 XmlDocument doc = new XmlDocument();
1411 XmlElement result = doc.CreateElement(this.DriverDictionary.UseKey.Value, this.DriverDictionary.Namespace.Value);
1412 MemoryStream stream = new MemoryStream();
1413 using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(new XmlTextWriter(stream, Encoding.UTF8)))
1415 #pragma warning suppress 56506 // standardsManager.SecurityTokenSerializer can never be null.
1416 standardsManager.SecurityTokenSerializer.WriteKeyIdentifier(writer, keyIdentifier);
1418 stream.Seek(0, SeekOrigin.Begin);
1420 using (XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader(new XmlTextReader(stream) { DtdProcessing = DtdProcessing.Prohibit }))
1422 reader.MoveToContent();
1423 skiNode = doc.ReadNode(reader);
1425 result.AppendChild(skiNode);
1430 public override XmlElement CreateSignWithElement(string signatureAlgorithm)
1432 if (signatureAlgorithm == null)
1434 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("signatureAlgorithm");
1436 XmlDocument doc = new XmlDocument();
1437 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.SignWith.Value,
1438 this.DriverDictionary.Namespace.Value);
1439 result.AppendChild(doc.CreateTextNode(signatureAlgorithm));
1443 internal override bool IsSignWithElement(XmlElement element, out string signatureAlgorithm)
1445 return CheckElement(element, this.DriverDictionary.SignWith.Value, this.DriverDictionary.Namespace.Value, out signatureAlgorithm);
1448 public override XmlElement CreateEncryptWithElement(string encryptionAlgorithm)
1450 if (encryptionAlgorithm == null)
1452 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptionAlgorithm");
1454 XmlDocument doc = new XmlDocument();
1455 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.EncryptWith.Value,
1456 this.DriverDictionary.Namespace.Value);
1457 result.AppendChild(doc.CreateTextNode(encryptionAlgorithm));
1461 public override XmlElement CreateEncryptionAlgorithmElement(string encryptionAlgorithm)
1463 if (encryptionAlgorithm == null)
1465 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptionAlgorithm");
1467 XmlDocument doc = new XmlDocument();
1468 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.EncryptionAlgorithm.Value,
1469 this.DriverDictionary.Namespace.Value);
1470 result.AppendChild(doc.CreateTextNode(encryptionAlgorithm));
1474 internal override bool IsEncryptWithElement(XmlElement element, out string encryptWithAlgorithm)
1476 return CheckElement(element, this.DriverDictionary.EncryptWith.Value, this.DriverDictionary.Namespace.Value, out encryptWithAlgorithm);
1479 internal override bool IsEncryptionAlgorithmElement(XmlElement element, out string encryptionAlgorithm)
1481 return CheckElement(element, this.DriverDictionary.EncryptionAlgorithm.Value, this.DriverDictionary.Namespace.Value, out encryptionAlgorithm);
1484 public override XmlElement CreateComputedKeyAlgorithmElement(string algorithm)
1486 if (algorithm == null)
1488 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("algorithm");
1490 XmlDocument doc = new XmlDocument();
1491 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.ComputedKeyAlgorithm.Value,
1492 this.DriverDictionary.Namespace.Value);
1493 result.AppendChild(doc.CreateTextNode(algorithm));
1497 public override XmlElement CreateCanonicalizationAlgorithmElement(string algorithm)
1499 if (algorithm == null)
1501 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("algorithm");
1503 XmlDocument doc = new XmlDocument();
1504 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.CanonicalizationAlgorithm.Value,
1505 this.DriverDictionary.Namespace.Value);
1506 result.AppendChild(doc.CreateTextNode(algorithm));
1510 internal override bool IsCanonicalizationAlgorithmElement(XmlElement element, out string canonicalizationAlgorithm)
1512 return CheckElement(element, this.DriverDictionary.CanonicalizationAlgorithm.Value, this.DriverDictionary.Namespace.Value, out canonicalizationAlgorithm);
1515 public override bool TryParseRequiredClaimsElement(XmlElement element, out System.Collections.ObjectModel.Collection<XmlElement> requiredClaims)
1517 if (element == null)
1518 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
1520 if (element.LocalName == this.DriverDictionary.Claims.Value
1521 && element.NamespaceURI == this.DriverDictionary.Namespace.Value)
1523 requiredClaims = new System.Collections.ObjectModel.Collection<XmlElement>();
1524 foreach (XmlNode node in element.ChildNodes)
1525 if (node is XmlElement)
1527 // PreSharp Bug: Parameter 'requiredClaims' to this public method must be validated: A null-dereference can occur here.
1528 #pragma warning suppress 56506
1529 requiredClaims.Add((XmlElement)node);
1534 requiredClaims = null;
1538 public override XmlElement CreateRequiredClaimsElement(IEnumerable<XmlElement> claimsList)
1540 if (claimsList == null)
1542 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claimsList");
1544 XmlDocument doc = new XmlDocument();
1545 XmlElement result = doc.CreateElement(this.DriverDictionary.Prefix.Value, this.DriverDictionary.Claims.Value,
1546 this.DriverDictionary.Namespace.Value);
1547 foreach (XmlElement claimElement in claimsList)
1549 XmlElement element = (XmlElement)doc.ImportNode(claimElement, true);
1550 result.AppendChild(element);
1555 internal static void ValidateRequestedKeySize(int keySize, SecurityAlgorithmSuite algorithmSuite)
1557 if ((keySize % 8 == 0) && algorithmSuite.IsSymmetricKeyLengthSupported(keySize))
1563 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidKeyLengthRequested, keySize)));
1567 static void ValidateRequestorEntropy(SecurityToken entropy, SecurityKeyEntropyMode mode)
1569 if ((mode == SecurityKeyEntropyMode.ClientEntropy || mode == SecurityKeyEntropyMode.CombinedEntropy)
1570 && (entropy == null))
1572 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.EntropyModeRequiresRequestorEntropy, mode)));
1574 if (mode == SecurityKeyEntropyMode.ServerEntropy && entropy != null)
1576 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.EntropyModeCannotHaveRequestorEntropy, mode)));
1580 internal static void ProcessRstAndIssueKey(RequestSecurityToken requestSecurityToken, SecurityTokenResolver resolver, SecurityKeyEntropyMode keyEntropyMode, SecurityAlgorithmSuite algorithmSuite, out int issuedKeySize, out byte[] issuerEntropy, out byte[] proofKey,
1581 out SecurityToken proofToken)
1583 SecurityToken requestorEntropyToken = requestSecurityToken.GetRequestorEntropy(resolver);
1584 ValidateRequestorEntropy(requestorEntropyToken, keyEntropyMode);
1585 byte[] requestorEntropy;
1586 if (requestorEntropyToken != null)
1588 if (requestorEntropyToken is BinarySecretSecurityToken)
1590 BinarySecretSecurityToken skToken = (BinarySecretSecurityToken)requestorEntropyToken;
1591 requestorEntropy = skToken.GetKeyBytes();
1593 else if (requestorEntropyToken is WrappedKeySecurityToken)
1595 requestorEntropy = ((WrappedKeySecurityToken)requestorEntropyToken).GetWrappedKey();
1599 throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR.GetString(SR.TokenCannotCreateSymmetricCrypto, requestorEntropyToken)));
1604 requestorEntropy = null;
1607 if (keyEntropyMode == SecurityKeyEntropyMode.ClientEntropy)
1609 if (requestorEntropy != null)
1611 // validate that the entropy length matches the algorithm suite
1612 ValidateRequestedKeySize(requestorEntropy.Length * 8, algorithmSuite);
1614 proofKey = requestorEntropy;
1615 issuerEntropy = null;
1621 if (requestSecurityToken.KeySize != 0)
1623 ValidateRequestedKeySize(requestSecurityToken.KeySize, algorithmSuite);
1624 issuedKeySize = requestSecurityToken.KeySize;
1628 issuedKeySize = algorithmSuite.DefaultSymmetricKeyLength;
1630 RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
1631 if (keyEntropyMode == SecurityKeyEntropyMode.ServerEntropy)
1633 proofKey = new byte[issuedKeySize / 8];
1634 // proof key is completely issued by the server
1635 random.GetNonZeroBytes(proofKey);
1636 issuerEntropy = null;
1637 proofToken = new BinarySecretSecurityToken(proofKey);
1641 issuerEntropy = new byte[issuedKeySize / 8];
1642 random.GetNonZeroBytes(issuerEntropy);
1643 proofKey = RequestSecurityTokenResponse.ComputeCombinedKey(requestorEntropy, issuerEntropy, issuedKeySize);
1651 protected static bool CheckElement(XmlElement element, string name, string ns, out string value)
1654 if (element.LocalName != name || element.NamespaceURI != ns)
1656 if (element.FirstChild is XmlText)
1658 value = ((XmlText)element.FirstChild).Value;