/// <summary> /// Looks for the first association type in a preferred-order list that is /// likely to be supported given a specific OpenID version and the security settings, /// and perhaps a matching Diffie-Hellman session type. /// </summary> /// <param name="protocol">The OpenID version that dictates which associations are available.</param> /// <param name="highSecurityIsBetter">A value indicating whether to consider higher strength security to be better. Use <c>true</c> for initial association requests from the Relying Party; use <c>false</c> from Providers when the Relying Party asks for an unrecognized association in order to pick a suggested alternative that is likely to be supported on both sides.</param> /// <param name="securityRequirements">The set of requirements the selected association type must comply to.</param> /// <param name="requireMatchingDHSessionType">Use <c>true</c> for HTTP associations, <c>false</c> for HTTPS associations.</param> /// <param name="associationType">The resulting association type's well known protocol name. (i.e. HMAC-SHA256)</param> /// <param name="sessionType">The resulting session type's well known protocol name, if a matching one is available. (i.e. DH-SHA256)</param> /// <returns> /// True if a qualifying association could be found; false otherwise. /// </returns> internal static bool TryFindBestAssociation(Protocol protocol, bool highSecurityIsBetter, SecuritySettings securityRequirements, bool requireMatchingDHSessionType, out string associationType, out string sessionType) { Requires.NotNull(protocol, "protocol"); Requires.NotNull(securityRequirements, "securityRequirements"); associationType = null; sessionType = null; // We use AsEnumerable() to avoid VerificationException (http://stackoverflow.com/questions/478422/why-does-simple-array-and-linq-generate-verificationexception-operation-could-de) IEnumerable <HmacSha> preferredOrder = highSecurityIsBetter ? hmacShaAssociationTypes.AsEnumerable() : hmacShaAssociationTypes.Reverse(); foreach (HmacSha sha in preferredOrder) { int hashSizeInBits = sha.SecretLength * 8; if (hashSizeInBits > securityRequirements.MaximumHashBitLength || hashSizeInBits < securityRequirements.MinimumHashBitLength) { continue; } if (OpenIdUtilities.IsDiffieHellmanPresent) { sessionType = DiffieHellmanUtilities.GetNameForSize(protocol, hashSizeInBits); } else { sessionType = requireMatchingDHSessionType ? null : protocol.Args.SessionType.NoEncryption; } if (requireMatchingDHSessionType && sessionType == null) { continue; } associationType = sha.GetAssociationType(protocol); if (associationType == null) { continue; } return(true); } return(false); }
/// <summary> /// Determines whether a named Diffie-Hellman session type and association type can be used together. /// </summary> /// <param name="protocol">The protocol carrying the names of the session and association types.</param> /// <param name="associationType">The value of the openid.assoc_type parameter.</param> /// <param name="sessionType">The value of the openid.session_type parameter.</param> /// <returns> /// <c>true</c> if the named association and session types are compatible; otherwise, <c>false</c>. /// </returns> internal static bool IsDHSessionCompatible(Protocol protocol, string associationType, string sessionType) { ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol"); ErrorUtilities.VerifyNonZeroLength(associationType, "associationType"); ErrorUtilities.VerifyArgumentNotNull(sessionType, "sessionType"); // All association types can work when no DH session is used at all. if (string.Equals(sessionType, protocol.Args.SessionType.NoEncryption, StringComparison.Ordinal)) { return(true); } // When there _is_ a DH session, it must match in hash length with the association type. int associationSecretLengthInBytes = GetSecretLength(protocol, associationType); int sessionHashLengthInBytes = DiffieHellmanUtilities.Lookup(protocol, sessionType).HashSize / 8; return(associationSecretLengthInBytes == sessionHashLengthInBytes); }
/// <summary> /// Determines whether a named Diffie-Hellman session type and association type can be used together. /// </summary> /// <param name="protocol">The protocol carrying the names of the session and association types.</param> /// <param name="associationType">The value of the openid.assoc_type parameter.</param> /// <param name="sessionType">The value of the openid.session_type parameter.</param> /// <returns> /// <c>true</c> if the named association and session types are compatible; otherwise, <c>false</c>. /// </returns> internal static bool IsDHSessionCompatible(Protocol protocol, string associationType, string sessionType) { Contract.Requires <ArgumentNullException>(protocol != null); Contract.Requires <ArgumentException>(!String.IsNullOrEmpty(associationType)); Contract.Requires <ArgumentNullException>(sessionType != null); // All association types can work when no DH session is used at all. if (string.Equals(sessionType, protocol.Args.SessionType.NoEncryption, StringComparison.Ordinal)) { return(true); } // When there _is_ a DH session, it must match in hash length with the association type. int associationSecretLengthInBytes = GetSecretLength(protocol, associationType); int sessionHashLengthInBytes = DiffieHellmanUtilities.Lookup(protocol, sessionType).HashSize / 8; return(associationSecretLengthInBytes == sessionHashLengthInBytes); }
/// <summary> /// Determines whether a named Diffie-Hellman session type and association type can be used together. /// </summary> /// <param name="protocol">The protocol carrying the names of the session and association types.</param> /// <param name="associationType">The value of the openid.assoc_type parameter.</param> /// <param name="sessionType">The value of the openid.session_type parameter.</param> /// <returns> /// <c>true</c> if the named association and session types are compatible; otherwise, <c>false</c>. /// </returns> internal static bool IsDHSessionCompatible(Protocol protocol, string associationType, string sessionType) { Requires.NotNull(protocol, "protocol"); Requires.NotNullOrEmpty(associationType, "associationType"); Requires.NotNull(sessionType, "sessionType"); // All association types can work when no DH session is used at all. if (string.Equals(sessionType, protocol.Args.SessionType.NoEncryption, StringComparison.Ordinal)) { return(true); } if (OpenIdUtilities.IsDiffieHellmanPresent) { // When there _is_ a DH session, it must match in hash length with the association type. int associationSecretLengthInBytes = GetSecretLength(protocol, associationType); int sessionHashLengthInBytes = DiffieHellmanUtilities.Lookup(protocol, sessionType).HashSize / 8; return(associationSecretLengthInBytes == sessionHashLengthInBytes); } else { return(false); } }