コード例 #1
0
        public override void MarkElements(ReceiveSecurityHeaderElementManager elementManager, bool messageSecurityMode)
        {
            bool primarySignatureFound = false;

            for (int position = 0; position < elementManager.Count; position++)
            {
                ReceiveSecurityHeaderEntry entry;
                elementManager.GetElementEntry(position, out entry);
                if (entry.elementCategory == ReceiveSecurityHeaderElementCategory.Signature)
                {
                    if (!messageSecurityMode)
                    {
                        elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Endorsing);
                        continue;
                    }
                    SignedXml          signedXml  = (SignedXml)entry.element;
                    StandardSignedInfo signedInfo = (StandardSignedInfo)signedXml.Signature.SignedInfo;
                    bool targetsSignature         = false;
                    if (signedInfo.ReferenceCount == 1)
                    {
                        string uri = signedInfo[0].Uri;
                        string id;
                        if (uri != null && uri.Length > 1 && uri[0] == '#')
                        {
                            id = uri.Substring(1);
                        }
                        else
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                      new MessageSecurityException(SR.GetString(SR.UnableToResolveReferenceUriForSignature, uri)));
                        }
                        for (int j = 0; j < elementManager.Count; j++)
                        {
                            ReceiveSecurityHeaderEntry inner;
                            elementManager.GetElementEntry(j, out inner);
                            if (j != position && inner.elementCategory == ReceiveSecurityHeaderElementCategory.Signature && inner.id == id)
                            {
                                targetsSignature = true;
                                break;
                            }
                        }
                    }
                    if (targetsSignature)
                    {
                        elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Endorsing);
                        continue;
                    }
                    else
                    {
                        if (primarySignatureFound)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.AtMostOnePrimarySignatureInReceiveSecurityHeader)));
                        }
                        primarySignatureFound = true;
                        elementManager.SetBindingMode(position, ReceiveSecurityHeaderBindingModes.Primary);
                        continue;
                    }
                }
            }
        }
コード例 #2
0
        protected override SecurityToken VerifySignature(SignedXml signedXml, bool isPrimarySignature,
                                                         SecurityHeaderTokenResolver resolver, object signatureTarget, string id)
        {
            if (TD.SignatureVerificationStartIsEnabled())
            {
                TD.SignatureVerificationStart(this.EventTraceActivity);
            }

            SecurityToken token = ResolveSignatureToken(signedXml.Signature.KeyIdentifier, resolver, isPrimarySignature);

            if (isPrimarySignature)
            {
                RecordSignatureToken(token);
            }
            ReadOnlyCollection <SecurityKey> keys = token.SecurityKeys;
            SecurityKey securityKey = (keys != null && keys.Count > 0) ? keys[0] : null;

            if (securityKey == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                                                                              SR.GetString(SR.UnableToCreateICryptoFromTokenForSignatureVerification, token)));
            }
            this.AlgorithmSuite.EnsureAcceptableSignatureKeySize(securityKey, token);
            this.AlgorithmSuite.EnsureAcceptableSignatureAlgorithm(securityKey, signedXml.Signature.SignedInfo.SignatureMethod);
            signedXml.StartSignatureVerification(securityKey);
            StandardSignedInfo signedInfo = (StandardSignedInfo)signedXml.Signature.SignedInfo;

            ValidateDigestsOfTargetsInSecurityHeader(signedInfo, this.Timestamp, isPrimarySignature, signatureTarget, id);

            if (!isPrimarySignature)
            {
                if ((!this.RequireMessageProtection) && (securityKey is AsymmetricSecurityKey) && (this.Version.Addressing != AddressingVersion.None))
                {
                    // For Transport Security using Asymmetric Keys verify that
                    // the 'To' header is signed.
                    int headerIndex = this.Message.Headers.FindHeader(XD.AddressingDictionary.To.Value, this.Message.Version.Addressing.Namespace);
                    if (headerIndex == -1)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageMissingToHeader)));
                    }
                    XmlDictionaryReader toHeaderReader = this.Message.Headers.GetReaderAtHeader(headerIndex);
                    id = toHeaderReader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);
                    if (id == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnsignedToHeaderInTransportSecuredMessage)));
                    }
                    signedXml.EnsureDigestValidity(id, toHeaderReader);
                }
                signedXml.CompleteSignatureVerification();
                return(token);
            }
            this.pendingSignature = signedXml;

            if (TD.SignatureVerificationSuccessIsEnabled())
            {
                TD.SignatureVerificationSuccess(this.EventTraceActivity);
            }

            return(token);
        }
        void ValidateDigestsOfTargetsInSecurityHeader(StandardSignedInfo signedInfo, SecurityTimestamp timestamp, bool isPrimarySignature, object signatureTarget, string id)
        {
            Fx.Assert(!isPrimarySignature || (isPrimarySignature && (signatureTarget == null)), "For primary signature we try to validate all the references.");

            for (int i = 0; i < signedInfo.ReferenceCount; i++)
            {
                Reference reference = signedInfo[i];
                this.AlgorithmSuite.EnsureAcceptableDigestAlgorithm(reference.DigestMethod);
                string referredId = reference.ExtractReferredId();
                if (isPrimarySignature || (id == referredId))
                {
                    if (timestamp != null && timestamp.Id == referredId && !reference.TransformChain.NeedsInclusiveContext &&
                        timestamp.DigestAlgorithm == reference.DigestMethod && timestamp.GetDigest() != null)
                    {
                        reference.EnsureDigestValidity(referredId, timestamp.GetDigest());
                        this.ElementManager.SetTimestampSigned(referredId);
                    }
                    else
                    {
                        if (signatureTarget != null)
                            reference.EnsureDigestValidity(id, signatureTarget);
                        else
                        {
                            int tokenIndex = -1;
                            XmlDictionaryReader reader = null;
                            if (reference.IsStrTranform())
                            {
                                if (this.ElementManager.TryGetTokenElementIndexFromStrId(referredId, out tokenIndex))
                                {
                                    ReceiveSecurityHeaderEntry entry;
                                    this.ElementManager.GetElementEntry(tokenIndex, out entry);
                                    bool isSignedToken = (entry.bindingMode == ReceiveSecurityHeaderBindingModes.Signed)
                                                       || (entry.bindingMode == ReceiveSecurityHeaderBindingModes.SignedEndorsing);
                                    // This means it is a protected(signed)primary token.
                                    if (!this.ElementManager.IsPrimaryTokenSigned)
                                    {
                                        this.ElementManager.IsPrimaryTokenSigned = entry.bindingMode == ReceiveSecurityHeaderBindingModes.Primary &&
                                                                                   entry.elementCategory == ReceiveSecurityHeaderElementCategory.Token;
                                    }
                                    this.ElementManager.SetSigned(tokenIndex);
                                    // We pass true if it is a signed supporting token, signed primary token or a SignedEndorsing token. We pass false if it is a SignedEncrypted Token. 
                                    reader = this.ElementManager.GetReader(tokenIndex, isSignedToken);
                                }
                            }
                            else
                                reader = this.ElementManager.GetSignatureVerificationReader(referredId, this.EncryptBeforeSignMode);

                            if (reader != null)
                            {
                                reference.EnsureDigestValidity(referredId, reader);
                                reader.Close();
                            }
                        }
                    }

                    if (!isPrimarySignature)
                    {
                        // We were given an id to verify and we have verified it. So just break out
                        // of the loop.
                        break;
                    }
                }
            }

              // This check makes sure that if RequireSignedPrimaryToken is true (ProtectTokens is enabled on sbe) then the incoming message 
            // should have the primary signature over the primary(signing)token.
            if (isPrimarySignature && this.RequireSignedPrimaryToken && !this.ElementManager.IsPrimaryTokenSigned)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotSigned, new IssuedSecurityTokenParameters())));
            }

            // NOTE: On both client and server side, WCF quietly consumes protected tokens even if protect token is not enabled on sbe. 
            // To change this behaviour add another check below and throw appropriate exception message.
        }
コード例 #4
0
        void ValidateDigestsOfTargetsInSecurityHeader(StandardSignedInfo signedInfo, SecurityTimestamp timestamp, bool isPrimarySignature, object signatureTarget, string id)
        {
            Fx.Assert(!isPrimarySignature || (isPrimarySignature && (signatureTarget == null)), "For primary signature we try to validate all the references.");

            for (int i = 0; i < signedInfo.ReferenceCount; i++)
            {
                Reference reference = signedInfo[i];
                this.AlgorithmSuite.EnsureAcceptableDigestAlgorithm(reference.DigestMethod);
                string referredId = reference.ExtractReferredId();
                if (isPrimarySignature || (id == referredId))
                {
                    if (timestamp != null && timestamp.Id == referredId && !reference.TransformChain.NeedsInclusiveContext &&
                        timestamp.DigestAlgorithm == reference.DigestMethod && timestamp.GetDigest() != null)
                    {
                        reference.EnsureDigestValidity(referredId, timestamp.GetDigest());
                        this.ElementManager.SetTimestampSigned(referredId);
                    }
                    else
                    {
                        if (signatureTarget != null)
                        {
                            reference.EnsureDigestValidity(id, signatureTarget);
                        }
                        else
                        {
                            int tokenIndex             = -1;
                            XmlDictionaryReader reader = null;
                            if (reference.IsStrTranform())
                            {
                                if (this.ElementManager.TryGetTokenElementIndexFromStrId(referredId, out tokenIndex))
                                {
                                    ReceiveSecurityHeaderEntry entry;
                                    this.ElementManager.GetElementEntry(tokenIndex, out entry);
                                    bool isSignedToken = (entry.bindingMode == ReceiveSecurityHeaderBindingModes.Signed) ||
                                                         (entry.bindingMode == ReceiveSecurityHeaderBindingModes.SignedEndorsing);
                                    // This means it is a protected(signed)primary token.
                                    if (!this.ElementManager.IsPrimaryTokenSigned)
                                    {
                                        this.ElementManager.IsPrimaryTokenSigned = entry.bindingMode == ReceiveSecurityHeaderBindingModes.Primary &&
                                                                                   entry.elementCategory == ReceiveSecurityHeaderElementCategory.Token;
                                    }
                                    this.ElementManager.SetSigned(tokenIndex);
                                    // We pass true if it is a signed supporting token, signed primary token or a SignedEndorsing token. We pass false if it is a SignedEncrypted Token.
                                    reader = this.ElementManager.GetReader(tokenIndex, isSignedToken);
                                }
                            }
                            else
                            {
                                reader = this.ElementManager.GetSignatureVerificationReader(referredId, this.EncryptBeforeSignMode);
                            }

                            if (reader != null)
                            {
                                reference.EnsureDigestValidity(referredId, reader);
                                reader.Close();
                            }
                        }
                    }

                    if (!isPrimarySignature)
                    {
                        // We were given an id to verify and we have verified it. So just break out
                        // of the loop.
                        break;
                    }
                }
            }

            // This check makes sure that if RequireSignedPrimaryToken is true (ProtectTokens is enabled on sbe) then the incoming message
            // should have the primary signature over the primary(signing)token.
            if (isPrimarySignature && this.RequireSignedPrimaryToken && !this.ElementManager.IsPrimaryTokenSigned)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.SupportingTokenIsNotSigned, new IssuedSecurityTokenParameters())));
            }

            // NOTE: On both client and server side, WCF quietly consumes protected tokens even if protect token is not enabled on sbe.
            // To change this behaviour add another check below and throw appropriate exception message.
        }
コード例 #5
0
        protected override SecurityToken VerifySignature(SignedXml signedXml, bool isPrimarySignature,
                                                         SecurityHeaderTokenResolver resolver, object signatureTarget, string id)
        {
            if (TD.SignatureVerificationStartIsEnabled())
            {
                TD.SignatureVerificationStart(this.EventTraceActivity);
            }

            SecurityToken token = ResolveSignatureToken(signedXml.Signature.KeyIdentifier, resolver, isPrimarySignature);

            if (isPrimarySignature)
            {
                RecordSignatureToken(token);
            }
            ReadOnlyCollection <SecurityKey> keys = token.SecurityKeys;
            SecurityKey securityKey = (keys != null && keys.Count > 0) ? keys[0] : null;

            if (securityKey == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(
                                                                              SR.GetString(SR.UnableToCreateICryptoFromTokenForSignatureVerification, token)));
            }
            this.AlgorithmSuite.EnsureAcceptableSignatureKeySize(securityKey, token);
            this.AlgorithmSuite.EnsureAcceptableSignatureAlgorithm(securityKey, signedXml.Signature.SignedInfo.SignatureMethod);
            signedXml.StartSignatureVerification(securityKey);
            StandardSignedInfo signedInfo = (StandardSignedInfo)signedXml.Signature.SignedInfo;

            ValidateDigestsOfTargetsInSecurityHeader(signedInfo, this.Timestamp, isPrimarySignature, signatureTarget, id);

            if (!isPrimarySignature)
            {
                if ((!this.RequireMessageProtection) && (securityKey is AsymmetricSecurityKey) && (this.Version.Addressing != AddressingVersion.None))
                {
                    // For Transport Security using Asymmetric Keys verify that
                    // the 'To' header is signed.
                    int headerIndex = this.Message.Headers.FindHeader(XD.AddressingDictionary.To.Value, this.Message.Version.Addressing.Namespace);
                    if (headerIndex == -1)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageMissingToHeader)));
                    }
                    XmlDictionaryReader toHeaderReader = this.Message.Headers.GetReaderAtHeader(headerIndex);
                    id = toHeaderReader.GetAttribute(XD.UtilityDictionary.IdAttribute, XD.UtilityDictionary.Namespace);

                    // DevDiv:938534 - We added a flag that allow unsigned headers. If this is set, we do not throw an Exception but move on to CompleteSignatureVerification()
                    if (LocalAppContextSwitches.AllowUnsignedToHeader)
                    {
                        // The lack of an id indicates that the sender did not wish to sign the header. We can safely assume that null indicates this header is not signed.
                        // If id is not null, then we need to validate the Digest and ensure signature is valid. The exception is thrown deeper in the System.IdentityModel stack.
                        if (id != null)
                        {
                            signedXml.EnsureDigestValidityIfIdMatches(id, toHeaderReader);
                        }
                    }
                    else
                    {
                        // default behavior for all platforms
                        if (id == null)
                        {
                            //
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.UnsignedToHeaderInTransportSecuredMessage)));
                        }
                        signedXml.EnsureDigestValidity(id, toHeaderReader);
                    }
                }
                signedXml.CompleteSignatureVerification();
                return(token);
            }
            this.pendingSignature = signedXml;

            if (TD.SignatureVerificationSuccessIsEnabled())
            {
                TD.SignatureVerificationSuccess(this.EventTraceActivity);
            }

            return(token);
        }