//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.OAuth.ChannelElements { using System; using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using DotNetOpenAuth.Logging; using DotNetOpenAuth.Messaging; using Validation; /// /// A binding element that signs outgoing messages and verifies the signature on incoming messages. /// [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha", Justification = "Acronym")] public class RsaSha1ServiceProviderSigningBindingElement : RsaSha1SigningBindingElement { /// /// The token manager for the service provider. /// private IServiceProviderTokenManager tokenManager; /// /// Initializes a new instance of the class. /// /// The token manager. public RsaSha1ServiceProviderSigningBindingElement(IServiceProviderTokenManager tokenManager) { Requires.NotNull(tokenManager, "tokenManager"); this.tokenManager = tokenManager; } /// /// Determines whether the signature on some message is valid. /// /// The message to check the signature on. /// /// true if the signature on the message is valid; otherwise, false. /// protected override bool IsSignatureValid(ITamperResistantOAuthMessage message) { ErrorUtilities.VerifyInternal(this.tokenManager != null, "No token manager available for fetching Consumer public certificates."); string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); byte[] data = Encoding.ASCII.GetBytes(signatureBaseString); byte[] carriedSignature = Convert.FromBase64String(message.Signature); X509Certificate2 cert = this.tokenManager.GetConsumer(message.ConsumerKey).Certificate; if (cert == null) { Logger.Signatures.WarnFormat("Incoming message from consumer '{0}' could not be matched with an appropriate X.509 certificate for signature verification.", message.ConsumerKey); return false; } var provider = (RSACryptoServiceProvider)cert.PublicKey.Key; bool valid = provider.VerifyData(data, "SHA1", carriedSignature); return valid; } /// /// Calculates a signature for a given message. /// /// The message to sign. /// /// The signature for the message. /// protected override string GetSignature(ITamperResistantOAuthMessage message) { throw new NotImplementedException(); } /// /// Clones this instance. /// /// /// A new instance of the binding element. /// protected override ITamperProtectionChannelBindingElement Clone() { return new RsaSha1ServiceProviderSigningBindingElement(this.tokenManager); } } }