Пример #1
0
        /// <summary>
        /// Gets the <see cref="WsSerializationContext"/> to use when serializing the <see cref="WsTrustRequest"/>.
        /// </summary>
        /// <param name="trustRequest">The <see cref="WsTrustRequest"/> that will be serialized.
        /// <returns>The <see cref="WsSerializationContext"/> for the <see cref="WsTrustRequest"/>.</returns>
        private WsSerializationContext GetSerializationContext(WsTrustRequest trustRequest)
        {
            _ = trustRequest ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(trustRequest));
            if (trustRequest.WsTrustVersion == WsTrustVersion.TrustFeb2005)
            {
                if (_wsSerializationContextTrustFeb2005 == null)
                {
                    _wsSerializationContextTrustFeb2005 = new WsSerializationContext(trustRequest.WsTrustVersion);
                }

                return(_wsSerializationContextTrustFeb2005);
            }
            else if (trustRequest.WsTrustVersion == WsTrustVersion.Trust13)
            {
                if (_wsSerializationContextTrust1_3 == null)
                {
                    _wsSerializationContextTrust1_3 = new WsSerializationContext(trustRequest.WsTrustVersion);
                }

                return(_wsSerializationContextTrust1_3);
            }
            else if (trustRequest.WsTrustVersion == WsTrustVersion.Trust14)
            {
                if (_wsSerializationContextTrust1_4 == null)
                {
                    _wsSerializationContextTrust1_4 = new WsSerializationContext(trustRequest.WsTrustVersion);
                }

                return(_wsSerializationContextTrust1_4);
            }

            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetResourceString(SR.WsTrustVersionNotSupported, trustRequest.WsTrustVersion.ToString())));
        }
        private void WriteSecurityTokenReference(XmlDictionaryWriter writer, SecurityTokenReference reference, bool attached)
        {
            var context = new WsSerializationContext(_version);

            if (attached)
            {
                WsTrustSerializer.WriteRequestedAttachedReference(writer, context, reference);
            }
            else
            {
                WsTrustSerializer.WriteRequestedUnattachedReference(writer, context, reference);
            }
        }
Пример #3
0
 public override Claims ReadClaims(XmlDictionaryReader reader, WsSerializationContext serializationContext)
 {
     return(base.ReadClaims(reader, serializationContext));
 }
Пример #4
0
        /// Get a proof token from a WsTrust request/response pair based on section 4.4.3 of the WS-Trust 1.3 spec.
        /// How the proof token is retrieved depends on whether the requester or issuer provide key material:
        /// Requester   |   Issuer                  | Results
        /// -------------------------------------------------
        /// Entropy     | No key material           | No proof token returned, requester entropy used
        /// Entropy     | Entropy                   | Computed key algorithm returned and key computed based on request and response entropy
        /// Entropy     | Rejects requester entropy | Proof token in response used as key
        /// No entropy  | Issues key                | Proof token in response used as key
        /// No entropy  | No key material           | No proof token
        /// </summary>
        /// <param name="request">The WS-Trust request (RST).</param>
        /// <param name="response">The WS-Trust response (RSTR).</param>
        /// <returns>The proof token or null if there is no proof token.</returns>
        internal static BinarySecretSecurityToken GetProofToken(WsTrustRequest request, RequestSecurityTokenResponse response, WsSerializationContext serializationContext, SecurityAlgorithmSuite algorithmSuite)
        {
            // According to the WS-Trust 1.3 spec, symmetric is the default key type
            string keyType = response.KeyType ?? request.KeyType ?? serializationContext.TrustKeyTypes.Symmetric;

            // Encrypted keys and encrypted entropy are not supported, currently, as they should
            // only be needed by unsupported message security scenarios.
            if (response.RequestedProofToken?.EncryptedKey != null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new NotSupportedException(SR.GetResourceString(SR.EncryptedKeysForProofTokensNotSupported)), EventLevel.Error);
            }

            // Bearer scenarios have no proof token
            if (string.Equals(keyType, serializationContext.TrustKeyTypes.Bearer, StringComparison.Ordinal))
            {
                if (response.RequestedProofToken != null || response.Entropy != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetResourceString(SR.BearerKeyShouldNotIincludeAProofToken)), EventLevel.Error);
                }

                return(null);
            }

            // If the response includes a proof token, use it as the security token's proof.
            // This scenario will occur if the request does not include entropy or if the issuer rejects the requester's entropy.
            if (response.RequestedProofToken?.BinarySecret != null)
            {
                // Confirm that a computed key algorithm isn't also specified
                if (!string.IsNullOrEmpty(response.RequestedProofToken.ComputedKeyAlgorithm) || response.Entropy != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetResourceString(SR.RSTRProofTokenShouldNotHaveAComputedKeyAlgorithmOrIssuerEntropy)), EventLevel.Error);
                }

                return(new BinarySecretSecurityToken(response.RequestedProofToken.BinarySecret.Data));
            }
            // If the response includes a computed key algorithm, compute the proof token based on requester and issuer entropy.
            // This scenario will occur if the requester and issuer both provide key material.
            else if (response.RequestedProofToken?.ComputedKeyAlgorithm != null)
            {
                if (!string.Equals(keyType, serializationContext.TrustKeyTypes.Symmetric, StringComparison.Ordinal))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetResourceString(SR.ComputedKeyProofTokensAreOnlySupportedWithSymmetricKeyTypes)), EventLevel.Error);
                }

                if (string.Equals(response.RequestedProofToken.ComputedKeyAlgorithm, serializationContext.TrustKeyTypes.PSHA1, StringComparison.Ordinal))
                {
                    // Confirm that no encrypted entropy was provided as that is currently not supported.
                    // If we wish to support it in the future, most of the work will be in the WSTrust serializer;
                    // this code would just have to use protected key's .Secret property to get the key material.
                    if (response.Entropy?.ProtectedKey != null || request.Entropy?.ProtectedKey != null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new NotSupportedException(SR.GetResourceString(SR.ProtectedKeyEntropyIsNotSupported)), EventLevel.Error);
                    }

                    // Get issuer and requester entropy
                    byte[] issuerEntropy = response.Entropy?.BinarySecret?.Data;
                    if (issuerEntropy == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetResourceString(SR.ComputedKeyProofTokensRequireIssuerToSupplyKeyMaterialViaEntropy)), EventLevel.Error);
                    }

                    byte[] requestorEntropy = request.Entropy?.BinarySecret?.Data;
                    if (requestorEntropy == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetResourceString(SR.ComputedKeyProofTokensRequireRequesterToSupplyKeyMaterialViaEntropy)), EventLevel.Error);
                    }

                    // Get key size
                    int keySizeInBits = response.KeySizeInBits ?? 0; // RSTR key size has precedence
                    if (keySizeInBits == 0)
                    {
                        keySizeInBits = request.KeySizeInBits ?? 0; // Followed by RST
                    }
                    if (keySizeInBits == 0)
                    {
                        keySizeInBits = algorithmSuite?.DefaultSymmetricKeyLength ?? 0; // Symmetric keys should default to a length corresponding to the algorithm in use
                    }
                    if (keySizeInBits == 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new InvalidOperationException(SR.GetResourceString(SR.NoKeySizeProvided)), EventLevel.Error);
                    }

                    return(new BinarySecretSecurityToken(Psha1KeyGenerator.ComputeCombinedKey(issuerEntropy, requestorEntropy, keySizeInBits)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new NotSupportedException(SR.GetResourceString(SR.OnlyPSHA1ComputedKeysAreSupported)), EventLevel.Error);
                }
            }
            // If the response does not have a proof token or computed key value, but the request proposed entropy,
            // then the requester's entropy is used as the proof token.
            else if (request.Entropy != null)
            {
                if (request.Entropy.ProtectedKey != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelper(new NotSupportedException(SR.GetResourceString(SR.ProtectedKeyEntropyIsNotSupported)), EventLevel.Error);
                }

                if (request.Entropy.BinarySecret != null)
                {
                    return(new BinarySecretSecurityToken(request.Entropy.BinarySecret.Data));
                }
            }

            // If we get here, then no key material has been supplied (by either issuer or requester), so there is no proof token.
            return(null);
        }
Пример #5
0
        internal static WCFSecurityToken CreateGenericXmlSecurityToken(WsTrustRequest request, WsTrustResponse trustResponse, WsSerializationContext serializationContext, SecurityAlgorithmSuite algorithmSuite)
        {
            // Create GenericXmlSecurityToken
            // Assumes that token is first and Saml2SecurityToken.
            RequestSecurityTokenResponse response = trustResponse.RequestSecurityTokenResponseCollection[0];

            // Get attached and unattached references
            GenericXmlSecurityKeyIdentifierClause internalSecurityKeyIdentifierClause = null;

            if (response.AttachedReference != null)
            {
                internalSecurityKeyIdentifierClause = GetSecurityKeyIdentifierForTokenReference(response.AttachedReference);
            }

            GenericXmlSecurityKeyIdentifierClause externalSecurityKeyIdentifierClause = null;

            if (response.UnattachedReference != null)
            {
                externalSecurityKeyIdentifierClause = GetSecurityKeyIdentifierForTokenReference(response.UnattachedReference);
            }

            // Get proof token
            WCFSecurityToken proofToken = GetProofToken(request, response, serializationContext, algorithmSuite);

            // Get lifetime
            DateTime created = response.Lifetime?.Created ?? DateTime.UtcNow;
            DateTime expires = response.Lifetime?.Expires ?? created.AddDays(1);

            return(new GenericXmlSecurityToken(response.RequestedSecurityToken.TokenElement,
                                               proofToken,
                                               created,
                                               expires,
                                               internalSecurityKeyIdentifierClause,
                                               externalSecurityKeyIdentifierClause,
                                               null));
        }