protected override ISignatureValueSecurityElement CreateSupportingSignature(SecurityToken token, SecurityKeyIdentifier identifier, ISecurityElement elementToSign) { string signatureAlgorithm; XmlDictionaryString signatureAlgorithmDictionaryString; SecurityKey signatureKey; AlgorithmSuite.GetSignatureAlgorithmAndKey(token, out signatureAlgorithm, out signatureKey, out signatureAlgorithmDictionaryString); SignedXml signedXml = new SignedXml(); SignedInfo signedInfo = signedXml.SignedInfo; signedInfo.CanonicalizationMethod = AlgorithmSuite.DefaultCanonicalizationAlgorithm; signedInfo.SignatureMethod = signatureAlgorithm; if (elementToSign.Id == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ElementToSignMustHaveId)); } MemoryStream stream = new MemoryStream(); XmlDictionaryWriter utf8Writer = TakeUtf8Writer(); utf8Writer.StartCanonicalization(stream, false, null); elementToSign.WriteTo(utf8Writer, ServiceModelDictionaryManager.Instance); utf8Writer.EndCanonicalization(); stream.Position = 0; AddReference("#" + elementToSign.Id, stream); AsymmetricAlgorithm asymmetricAlgorithm = null; KeyedHashAlgorithm keyedHashAlgorithm = null; GetSigningAlgorithm(signatureKey, signatureAlgorithm, out keyedHashAlgorithm, out asymmetricAlgorithm); if (keyedHashAlgorithm != null) { signedXml.ComputeSignature(keyedHashAlgorithm); } else { signedXml.SigningKey = asymmetricAlgorithm; signedXml.ComputeSignature(); } SetKeyInfo(signedXml, identifier); return(new SignatureValue(signedXml.Signature)); }
protected override SecurityToken VerifySignature(SignedXml signedXml, bool isPrimarySignature, SecurityHeaderTokenResolver resolver, object signatureTarget, string id) { SecurityKeyIdentifier securityKeyIdentifier = null; string keyInfoString = signedXml.Signature.KeyInfo.GetXml().OuterXml; using (var strReader = new StringReader(keyInfoString)) { XmlReader xmlReader = XmlReader.Create(strReader); securityKeyIdentifier = StandardsManager.SecurityTokenSerializer.ReadKeyIdentifier(xmlReader); } if (securityKeyIdentifier == null) { throw new Exception("SecurityKeyIdentifier is missing"); } SecurityToken token = ResolveSignatureToken(securityKeyIdentifier, 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.Format(SR.UnableToCreateICryptoFromTokenForSignatureVerification, token))); } // signedXml.SigningKey = securityKey; // signedXml.StartSignatureVerification(securityKey); // StandardSignedInfo signedInfo = (StandardSignedInfo)signedXml.Signature.SignedInfo; // ValidateDigestsOfTargetsInSecurityHeader(signedInfo, this.Timestamp, isPrimarySignature, signatureTarget, id); if (!isPrimarySignature) { //TODO securityKey is AsymmetricSecurityKey //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(); SecurityAlgorithmSuite suite = AlgorithmSuite; AlgorithmSuite.EnsureAcceptableSignatureKeySize(securityKey, token); AlgorithmSuite.EnsureAcceptableSignatureAlgorithm(securityKey, signedXml.Signature.SignedInfo.SignatureMethod); string canonicalizationAlgorithm = suite.DefaultCanonicalizationAlgorithm; suite.GetSignatureAlgorithmAndKey(token, out string signatureAlgorithm, out SecurityKey signatureKey, out XmlDictionaryString signatureAlgorithmDictionaryString); GetSigningAlgorithm(signatureKey, signatureAlgorithm, out _signingKey, out AsymmetricAlgorithm asymmetricAlgorithm); if (_signingKey != null) { if (!signedXml.CheckSignature(_signingKey)) { throw new Exception("Signature not valid."); } } else { if (!signedXml.CheckSignature(asymmetricAlgorithm)) { throw new Exception("Signature not valid."); } } } // this.pendingSignature = signedXml; //if (TD.SignatureVerificationSuccessIsEnabled()) //{ // TD.SignatureVerificationSuccess(this.EventTraceActivity); //} return(token); }
private void SignWithSupportingTokens() { SecurityToken[] endorsingTokens = ElementContainer.GetEndorsingSupportingTokens(); if (endorsingTokens != null) { for (int i = 0; i < endorsingTokens.Length; ++i) { SecurityToken source = endorsingTokens[i]; SecurityKeyIdentifierClause sourceKeyClause = _endorsingTokenParameters[i].CreateKeyIdentifierClause(source, GetTokenReferenceStyle(_endorsingTokenParameters[i])); if (sourceKeyClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.TokenManagerCannotCreateTokenReference)), Message); } SecurityToken signingToken; SecurityKeyIdentifierClause signingKeyClause; if (_endorsingTokenParameters[i].RequireDerivedKeys && !_endorsingTokenParameters[i].HasAsymmetricKey) { string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(StandardsManager.MessageSecurityVersion.SecureConversationVersion); DerivedKeySecurityToken dkt = new DerivedKeySecurityToken(-1, 0, AlgorithmSuite.GetSignatureKeyDerivationLength(source, StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, source, sourceKeyClause, derivationAlgorithm, GenerateId()); signingToken = dkt; signingKeyClause = new LocalIdKeyIdentifierClause(dkt.Id, dkt.GetType()); ElementContainer.AddEndorsingDerivedSupportingToken(dkt); } else { signingToken = source; signingKeyClause = sourceKeyClause; } SignWithSupportingToken(signingToken, signingKeyClause); } } SecurityToken[] signedEndorsingSupportingTokens = ElementContainer.GetSignedEndorsingSupportingTokens(); if (signedEndorsingSupportingTokens != null) { for (int i = 0; i < signedEndorsingSupportingTokens.Length; ++i) { SecurityToken source = signedEndorsingSupportingTokens[i]; SecurityKeyIdentifierClause sourceKeyClause = _signedEndorsingTokenParameters[i].CreateKeyIdentifierClause(source, GetTokenReferenceStyle(_signedEndorsingTokenParameters[i])); if (sourceKeyClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.Format(SR.TokenManagerCannotCreateTokenReference)), Message); } SecurityToken signingToken; SecurityKeyIdentifierClause signingKeyClause; if (_signedEndorsingTokenParameters[i].RequireDerivedKeys && !_signedEndorsingTokenParameters[i].HasAsymmetricKey) { string derivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(StandardsManager.MessageSecurityVersion.SecureConversationVersion); DerivedKeySecurityToken dkt = new DerivedKeySecurityToken(-1, 0, AlgorithmSuite.GetSignatureKeyDerivationLength(source, StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, source, sourceKeyClause, derivationAlgorithm, GenerateId()); signingToken = dkt; signingKeyClause = new LocalIdKeyIdentifierClause(dkt.Id, dkt.GetType()); ElementContainer.AddSignedEndorsingDerivedSupportingToken(dkt); } else { signingToken = source; signingKeyClause = sourceKeyClause; } SignWithSupportingToken(signingToken, signingKeyClause); } } }
private void StartSignature() { if (ElementContainer.SourceSigningToken == null) { return; } // determine the key identifier clause to use for the source SecurityTokenReferenceStyle sourceSigningKeyReferenceStyle = GetTokenReferenceStyle(SigningTokenParameters); SecurityKeyIdentifierClause sourceSigningKeyIdentifierClause = SigningTokenParameters.CreateKeyIdentifierClause(ElementContainer.SourceSigningToken, sourceSigningKeyReferenceStyle); if (sourceSigningKeyIdentifierClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.TokenManagerCannotCreateTokenReference), Message); } SecurityToken signingToken; SecurityKeyIdentifierClause signingKeyIdentifierClause; // determine if a token needs to be derived if (SigningTokenParameters.RequireDerivedKeys && !SigningTokenParameters.HasAsymmetricKey) { string derivationAlgorithm = AlgorithmSuite.GetSignatureKeyDerivationAlgorithm(ElementContainer.SourceSigningToken, StandardsManager.MessageSecurityVersion.SecureConversationVersion); string expectedDerivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(StandardsManager.MessageSecurityVersion.SecureConversationVersion); if (derivationAlgorithm == expectedDerivationAlgorithm) { DerivedKeySecurityToken derivedSigningToken = new DerivedKeySecurityToken(-1, 0, AlgorithmSuite.GetSignatureKeyDerivationLength(ElementContainer.SourceSigningToken, StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, ElementContainer.SourceSigningToken, sourceSigningKeyIdentifierClause, derivationAlgorithm, GenerateId()); signingToken = ElementContainer.DerivedSigningToken = derivedSigningToken; signingKeyIdentifierClause = new LocalIdKeyIdentifierClause(signingToken.Id, signingToken.GetType()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.UnsupportedCryptoAlgorithm, derivationAlgorithm))); } } else { signingToken = ElementContainer.SourceSigningToken; signingKeyIdentifierClause = sourceSigningKeyIdentifierClause; } SecurityKeyIdentifier signingKeyIdentifier = new SecurityKeyIdentifier(signingKeyIdentifierClause); if (_signatureConfirmationsToSend != null && _signatureConfirmationsToSend.Count > 0) { ISecurityElement[] signatureConfirmationElements; signatureConfirmationElements = CreateSignatureConfirmationElements(_signatureConfirmationsToSend); for (int i = 0; i < signatureConfirmationElements.Length; ++i) { SendSecurityHeaderElement sigConfElement = new SendSecurityHeaderElement(signatureConfirmationElements[i].Id, signatureConfirmationElements[i]) { MarkedForEncryption = _signatureConfirmationsToSend.IsMarkedForEncryption }; ElementContainer.AddSignatureConfirmation(sigConfElement); } } bool generateTargettablePrimarySignature = ((_endorsingTokenParameters != null) || (_signedEndorsingTokenParameters != null)); StartPrimarySignatureCore(signingToken, signingKeyIdentifier, _signatureParts, generateTargettablePrimarySignature); }
private void StartEncryption() { if (ElementContainer.SourceEncryptionToken == null) { return; } // determine the key identifier clause to use for the source SecurityTokenReferenceStyle sourceEncryptingKeyReferenceStyle = GetTokenReferenceStyle(_encryptingTokenParameters); bool encryptionTokenSerialized = sourceEncryptingKeyReferenceStyle == SecurityTokenReferenceStyle.Internal; SecurityKeyIdentifierClause sourceEncryptingKeyIdentifierClause = _encryptingTokenParameters.CreateKeyIdentifierClause(ElementContainer.SourceEncryptionToken, sourceEncryptingKeyReferenceStyle); if (sourceEncryptingKeyIdentifierClause == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.TokenManagerCannotCreateTokenReference), Message); } SecurityToken sourceToken; SecurityKeyIdentifierClause sourceTokenIdentifierClause; // if the source token cannot do symmetric crypto, create a wrapped key if (!SecurityUtils.HasSymmetricSecurityKey(ElementContainer.SourceEncryptionToken)) { int keyLength = Math.Max(128, AlgorithmSuite.DefaultSymmetricKeyLength); CryptoHelper.ValidateSymmetricKeyLength(keyLength, AlgorithmSuite); byte[] key = new byte[keyLength / 8]; CryptoHelper.FillRandomBytes(key); AlgorithmSuite.GetKeyWrapAlgorithm(ElementContainer.SourceEncryptionToken, out string keyWrapAlgorithm, out XmlDictionaryString keyWrapAlgorithmDictionaryString); WrappedKeySecurityToken wrappedKey = new WrappedKeySecurityToken(GenerateId(), key, keyWrapAlgorithm, keyWrapAlgorithmDictionaryString, ElementContainer.SourceEncryptionToken, new SecurityKeyIdentifier(sourceEncryptingKeyIdentifierClause)); ElementContainer.WrappedEncryptionToken = wrappedKey; sourceToken = wrappedKey; sourceTokenIdentifierClause = new LocalIdKeyIdentifierClause(wrappedKey.Id, wrappedKey.GetType()); encryptionTokenSerialized = true; } else { sourceToken = ElementContainer.SourceEncryptionToken; sourceTokenIdentifierClause = sourceEncryptingKeyIdentifierClause; } // determine if a key needs to be derived SecurityKeyIdentifierClause encryptingKeyIdentifierClause; // determine if a token needs to be derived if (_encryptingTokenParameters.RequireDerivedKeys) { string derivationAlgorithm = AlgorithmSuite.GetEncryptionKeyDerivationAlgorithm(sourceToken, StandardsManager.MessageSecurityVersion.SecureConversationVersion); string expectedDerivationAlgorithm = SecurityUtils.GetKeyDerivationAlgorithm(StandardsManager.MessageSecurityVersion.SecureConversationVersion); if (derivationAlgorithm == expectedDerivationAlgorithm) { DerivedKeySecurityToken derivedEncryptingToken = new DerivedKeySecurityToken(-1, 0, AlgorithmSuite.GetEncryptionKeyDerivationLength(sourceToken, StandardsManager.MessageSecurityVersion.SecureConversationVersion), null, DerivedKeySecurityToken.DefaultNonceLength, sourceToken, sourceTokenIdentifierClause, derivationAlgorithm, GenerateId()); _encryptingToken = ElementContainer.DerivedEncryptionToken = derivedEncryptingToken; encryptingKeyIdentifierClause = new LocalIdKeyIdentifierClause(derivedEncryptingToken.Id, derivedEncryptingToken.GetType()); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.Format(SR.UnsupportedCryptoAlgorithm, derivationAlgorithm))); } } else { _encryptingToken = sourceToken; encryptingKeyIdentifierClause = sourceTokenIdentifierClause; } _skipKeyInfoForEncryption = encryptionTokenSerialized && EncryptedKeyContainsReferenceList && (_encryptingToken is WrappedKeySecurityToken) && _signThenEncrypt; SecurityKeyIdentifier identifier; if (_skipKeyInfoForEncryption) { identifier = null; } else { identifier = new SecurityKeyIdentifier(encryptingKeyIdentifierClause); } StartEncryptionCore(_encryptingToken, identifier); }