protected override void StartPrimarySignatureCore(SecurityToken token, SecurityKeyIdentifier keyIdentifier, MessagePartSpecification signatureParts, bool generateTargettableSignature) { SecurityAlgorithmSuite suite = AlgorithmSuite; string canonicalizationAlgorithm = suite.DefaultCanonicalizationAlgorithm; if (canonicalizationAlgorithm != SecurityAlgorithms.ExclusiveC14n) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new MessageSecurityException(SR.Format(SR.UnsupportedCanonicalizationAlgorithm, suite.DefaultCanonicalizationAlgorithm))); } string signatureAlgorithm; XmlDictionaryString signatureAlgorithmDictionaryString; SecurityKey signatureKey; suite.GetSignatureAlgorithmAndKey(token, out signatureAlgorithm, out signatureKey, out signatureAlgorithmDictionaryString); AsymmetricAlgorithm asymmetricAlgorithm = null; GetSigningAlgorithm(signatureKey, signatureAlgorithm, out _signingKey, out asymmetricAlgorithm); _signedXml = new SignedXml(); _signedXml.SignedInfo.CanonicalizationMethod = canonicalizationAlgorithm; _signedXml.SignedInfo.SignatureMethod = signatureAlgorithm; _signedXml.SigningKey = asymmetricAlgorithm; if (keyIdentifier != null) { var stream = new MemoryStream(); using (var xmlWriter = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false)) { StandardsManager.SecurityTokenSerializer.WriteKeyIdentifier(xmlWriter, keyIdentifier); } stream.Position = 0; XmlDocument doc = new XmlDocument(); doc.Load(stream); var keyInfo = new KeyInfo(); keyInfo.LoadXml(doc.DocumentElement); _signedXml.KeyInfo = keyInfo; } if (generateTargettableSignature) { _signedXml.Signature.Id = GenerateId(); } _effectiveSignatureParts = signatureParts; }
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); }