예제 #1
0
        /// <summary>
        /// Creates a new association of a given type at an OpenID Provider.
        /// </summary>
        /// <param name="protocol">The protocol.</param>
        /// <param name="associationType">Type of the association (i.e. HMAC-SHA1 or HMAC-SHA256)</param>
        /// <param name="associationUse">A value indicating whether the new association will be used privately by the Provider for "dumb mode" authentication
        /// or shared with the Relying Party for "smart mode" authentication.</param>
        /// <param name="associationStore">The Provider's association store.</param>
        /// <param name="securitySettings">The security settings of the Provider.</param>
        /// <returns>
        /// The newly created association.
        /// </returns>
        /// <remarks>
        /// The new association is NOT automatically put into an association store.  This must be done by the caller.
        /// </remarks>
        internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, IProviderAssociationStore associationStore, ProviderSecuritySettings securitySettings)
        {
            Requires.NotNull(protocol, "protocol");
            Requires.NotNullOrEmpty(associationType, "associationType");
            Requires.NotNull(associationStore, "associationStore");
            Requires.NotNull(securitySettings, "securitySettings");

            int secretLength = HmacShaAssociation.GetSecretLength(protocol, associationType);

            // Generate the secret that will be used for signing
            byte[] secret = MessagingUtilities.GetCryptoRandomData(secretLength);

            TimeSpan lifetime;

            if (associationUse == AssociationRelyingPartyType.Smart)
            {
                if (!securitySettings.AssociationLifetimes.TryGetValue(associationType, out lifetime))
                {
                    lifetime = DefaultMaximumLifetime;
                }
            }
            else
            {
                lifetime = HmacShaAssociation.DumbSecretLifetime;
            }

            string handle = associationStore.Serialize(secret, DateTime.UtcNow + lifetime, associationUse == AssociationRelyingPartyType.Dumb);

            Assumes.True(protocol != null);             // All the way up to the method call, the condition holds, yet we get a Requires failure next
            Assumes.True(secret != null);
            Assumes.True(!string.IsNullOrEmpty(associationType));
            var result = HmacShaAssociation.Create(protocol, associationType, handle, secret, lifetime);

            return(result);
        }
예제 #2
0
        public virtual Association CreateAssociation(AssociationRelyingPartyType associationType, OpenIdProvider provider)
        {
            if (provider == null && associationType == AssociationRelyingPartyType.Smart)
            {
                throw new ArgumentNullException("provider", "For Smart associations, the provider must be given.");
            }

            string   assoc_type;
            Protocol associationProtocol;

            if (associationType == AssociationRelyingPartyType.Dumb)
            {
                // We'll just use the best association available.
                associationProtocol = Protocol.Default;
                assoc_type          = associationProtocol.Args.SignatureAlgorithm.Best;
            }
            else
            {
                associationProtocol = provider.Protocol;
                assoc_type          = Util.GetRequiredArg(provider.Query, provider.Protocol.openid.assoc_type);
                Debug.Assert(Array.IndexOf(provider.Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0, "This should have been checked by our caller.");
            }
            int secretLength = HmacShaAssociation.GetSecretLength(associationProtocol, assoc_type);

            RNGCryptoServiceProvider generator = new RNGCryptoServiceProvider();

            byte[]             secret     = new byte[secretLength];
            byte[]             uniq_bytes = new byte[4];
            string             uniq;
            string             handle;
            HmacShaAssociation assoc;

            generator.GetBytes(secret);
            generator.GetBytes(uniq_bytes);

            uniq = Convert.ToBase64String(uniq_bytes);

            double seconds = DateTime.UtcNow.Subtract(Association.UnixEpoch).TotalSeconds;

            handle = "{{" + assoc_type + "}{" + seconds + "}{" + uniq + "}";

            TimeSpan lifeSpan = associationType == AssociationRelyingPartyType.Dumb ? dumbSecretLifetime : smartAssociationLifetime;

            assoc = HmacShaAssociation.Create(secretLength, handle, secret, lifeSpan);

            store.StoreAssociation(associationType, assoc);

            return(assoc);
        }
        /// <summary>
        /// Gets an association to use for signing new data.
        /// </summary>
        /// <returns>
        /// The association, which may have previously existed or
        /// may have been created as a result of this call.
        /// </returns>
        private Association GetAssociation()
        {
            Association privateAssociation = this.store.GetAssociation(SecretUri, this.securitySettings);

            if (privateAssociation == null || !privateAssociation.HasUsefulLifeRemaining)
            {
                int    secretLength = HmacShaAssociation.GetSecretLength(Protocol.Default, Protocol.Default.Args.SignatureAlgorithm.Best);
                byte[] secret       = MessagingUtilities.GetCryptoRandomData(secretLength);
                privateAssociation = HmacShaAssociation.Create(this.CreateNewAssociationHandle(), secret, this.securitySettings.PrivateSecretMaximumAge);
                if (!privateAssociation.HasUsefulLifeRemaining)
                {
                    Logger.WarnFormat(
                        "Brand new private association has a shorter lifespan ({0}) than the maximum allowed authentication time for a user ({1}).  This may lead to login failures.",
                        this.securitySettings.PrivateSecretMaximumAge,
                        DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime);
                }

                this.store.StoreAssociation(SecretUri, privateAssociation);
            }

            return(privateAssociation);
        }