From 6523cd5be50e33fc218c1d9eb6c9ad16a9513df0 Mon Sep 17 00:00:00 2001
From: Marek Habersack <grendel@twistedcode.net>
Date: Wed, 1 Dec 2010 01:59:07 +0100
Subject: [PATCH 4/5] [asp.net] Part of fix for bug #649546. A partial rewrite of the web/script resource handler.
     Backport of commit a9cb57cc131f41baf48dce03d1149aa4d5f40dac

    * System.Web/System.Web.Handlers/AssemblyResourceLoader.cs: AssemblyResourceLoader/ScriptResourceHandler must
      always generate the same URL for every assembly+resource pair, or otherwise the browser would re-fetch
      the resource in situations where it is not desired (e.g. during an async request to the server to update
      a panel).
      The generated URLs are not encrypted using real encryption, just hashed.
      In addition, the handler code got modernized a bit.

    * System.Web.Extensions/System.Web.UI/ScriptManager.cs: scriptStartupBlock is a 3.5+ thing

    * System.Web.Extensions_1.0/Makefile: use the 1.0 Microsoft AJAX library for this compat assembly

    * System.Web/System.Web.Util/MachineKeySectionUtils.cs: made GetValidationKey public
---
 .../System.Web.UI/ScriptManager.cs                 |    4 +
 .../MachineKeyValidation.cs                        |    6 -
 .../MachineKeySection.cs                           |   56 ---
 .../MachineKeyValidationConverter.cs               |   29 --
 .../System.Web.Handlers/AssemblyResourceLoader.cs  |  385 ++++++++++++++------
 .../System.Web.Security/SqlMembershipProvider.cs   |   12 -
 mcs/class/System.Web/System.Web.UI/LosFormatter.cs |   11 +-
 .../System.Web.Util/MachineKeySectionUtils.cs      |   43 +--
 .../MachineKeySectionTest.cs                       |  112 ------
 .../MachineKeyValidationConverterTest.cs           |   46 ---
 .../Test/System.Web.UI/LosFormatterTest.cs         |   24 +-
 .../System.Web.Util/MachineKeySectionUtilsTest.cs  |   97 -----
 12 files changed, 279 insertions(+), 546 deletions(-)

diff --git a/mcs/class/System.Web.Extensions/System.Web.UI/ScriptManager.cs b/mcs/class/System.Web.Extensions/System.Web.UI/ScriptManager.cs
index 72c80c2..8251082 100644
--- a/mcs/class/System.Web.Extensions/System.Web.UI/ScriptManager.cs
+++ b/mcs/class/System.Web.Extensions/System.Web.UI/ScriptManager.cs
@@ -62,7 +62,9 @@ namespace System.Web.UI
 		const string hiddenField = "hiddenField";
 		const string arrayDeclaration = "arrayDeclaration";
 		const string scriptBlock = "scriptBlock";
+#if NET_3_5
 		const string scriptStartupBlock = "scriptStartupBlock";
+#endif
 		const string expando = "expando";
 		const string onSubmit = "onSubmit";
 		const string asyncPostBackControlIDs = "asyncPostBackControlIDs";
@@ -1282,12 +1284,14 @@ namespace System.Web.UI
 						else
 							WriteCallbackOutput (output, scriptBlock, scriptContentWithTags, SerializeScriptBlock (scriptEntry));
 						break;
+#if NET_3_5
 					case RegisteredScriptType.ClientStartupScript:
 						if (scriptEntry.AddScriptTags)
 							WriteCallbackOutput (output, scriptStartupBlock, scriptContentNoTags, scriptEntry.Script);
 						else
 							WriteCallbackOutput (output, scriptStartupBlock, scriptContentWithTags, SerializeScriptBlock (scriptEntry));
 						break;
+#endif
 					case RegisteredScriptType.ClientScriptInclude:
 						WriteCallbackOutput (output, scriptBlock, scriptPath, scriptEntry.Url);
 						break;
diff --git a/mcs/class/System.Web/System.Web.Configuration/MachineKeyValidation.cs b/mcs/class/System.Web/System.Web.Configuration/MachineKeyValidation.cs
index eb7dfe1..d0da3ac 100644
--- a/mcs/class/System.Web/System.Web.Configuration/MachineKeyValidation.cs
+++ b/mcs/class/System.Web/System.Web.Configuration/MachineKeyValidation.cs
@@ -39,12 +39,6 @@ namespace System.Web.Configuration
 		SHA1 = 1,
 		TripleDES = 2,
 		AES = 3,
-#if NET_4_0
-		HMACSHA256 = 4,
-		HMACSHA384 = 5,
-		HMACSHA512 = 6,
-		Custom = 7
-#endif
 	}
 }
 
diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeySection.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeySection.cs
index 70ce7fd..13382fd 100644
--- a/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeySection.cs
+++ b/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeySection.cs
@@ -47,9 +47,6 @@ namespace System.Web.Configuration {
 		static ConfigurationProperty validationKeyProp;
 		static ConfigurationPropertyCollection properties;
 		static MachineKeyValidationConverter converter = new MachineKeyValidationConverter ();
-#if NET_4_0
-		MachineKeyValidation validation;
-#endif
 
 		static MachineKeySection ()
 		{
@@ -61,17 +58,10 @@ namespace System.Web.Configuration {
 								       PropertyHelper.WhiteSpaceTrimStringConverter,
 								       PropertyHelper.NonEmptyStringValidator,
 								       ConfigurationPropertyOptions.None);
-#if NET_4_0
-			validationProp = new ConfigurationProperty ("validation", typeof (string), "HMACSHA256",
-								    PropertyHelper.WhiteSpaceTrimStringConverter,
-								    PropertyHelper.NonEmptyStringValidator,
-								    ConfigurationPropertyOptions.None);
-#else
 			validationProp = new ConfigurationProperty ("validation", typeof (MachineKeyValidation), 
 								    MachineKeyValidation.SHA1, converter,
 								    PropertyHelper.DefaultValidator,
 								    ConfigurationPropertyOptions.None);
-#endif
 			validationKeyProp = new ConfigurationProperty ("validationKey", typeof (string), "AutoGenerate,IsolateApps",
 								       PropertyHelper.WhiteSpaceTrimStringConverter,
 								       PropertyHelper.NonEmptyStringValidator,
@@ -88,19 +78,6 @@ namespace System.Web.Configuration {
 			Config.AutoGenerate (MachineKeyRegistryStorage.KeyType.Validation);
 		}
 
-#if NET_4_0
-		public MachineKeySection ()
-		{
-			// get DefaultValue from ValidationAlgorithm
-			validation = (MachineKeyValidation) converter.ConvertFrom (null, null, ValidationAlgorithm);
-		}
-
-		[MonoTODO]
-		public MachineKeyCompatibilityMode CompatibilityMode {
-			get; set;
-		}
-#endif
-
 		protected override void Reset (ConfigurationElement parentElement)
 		{
 			base.Reset (parentElement);
@@ -132,45 +109,12 @@ namespace System.Web.Configuration {
 			}
 		}
 
-#if NET_4_0
-		// property exists for backward compatibility
-		public MachineKeyValidation Validation {
-			get { return validation; }
-			set {
-				if (value == MachineKeyValidation.Custom)
-					throw new ArgumentException ();
-
-				string algo = value.ToString ();
-				// enum and accept values differs for TripleDES
-				ValidationAlgorithm = (algo == "TripleDES") ? "3DES" : algo;
-			}
-		}
-
-		[StringValidator (MinLength = 1)]
-		[TypeConverter (typeof (WhiteSpaceTrimStringConverter))]
-		[ConfigurationProperty ("validation", DefaultValue = "HMACSHA256")]
-		public string ValidationAlgorithm {
-			get { return (string) base [validationProp];}
-			set {
-				if (value == null)
-					return;
-
-				if (value.StartsWith ("alg:"))
-					validation = MachineKeyValidation.Custom;
-				else
-					validation = (MachineKeyValidation) converter.ConvertFrom (null, null, value);
-
-				base[validationProp] = value;
-			}
-		}
-#else
 		[TypeConverter (typeof (MachineKeyValidationConverter))]
 		[ConfigurationProperty ("validation", DefaultValue = "SHA1")]
 		public MachineKeyValidation Validation {
 			get { return (MachineKeyValidation) base [validationProp];}
 			set { base[validationProp] = value; }
 		}
-#endif
 
 		[TypeConverter (typeof (WhiteSpaceTrimStringConverter))]
 		[StringValidator (MinLength = 1)]
diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeyValidationConverter.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeyValidationConverter.cs
index 698509c..4d4df19 100644
--- a/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeyValidationConverter.cs
+++ b/mcs/class/System.Web/System.Web.Configuration_2.0/MachineKeyValidationConverter.cs
@@ -39,11 +39,7 @@ namespace System.Web.Configuration {
 
 	public sealed class MachineKeyValidationConverter : ConfigurationConverterBase
 	{
-#if NET_4_0
-		const string InvalidValue = "The enumeration value must be one of the following: SHA1, MD5, 3DES, AES, HMACSHA256, HMACSHA384, HMACSHA512."; 
-#else
 		const string InvalidValue = "The enumeration value must be one of the following: SHA1, MD5, 3DES, AES."; 
-#endif
 		public MachineKeyValidationConverter ()
 		{
 		}
@@ -59,14 +55,6 @@ namespace System.Web.Configuration {
 				return MachineKeyValidation.TripleDES;
 			case "AES":
 				return MachineKeyValidation.AES;
-#if NET_4_0
-			case "HMACSHA256":
-				return MachineKeyValidation.HMACSHA256;
-			case "HMACSHA384":
-				return MachineKeyValidation.HMACSHA384;
-			case "HMACSHA512":
-				return MachineKeyValidation.HMACSHA512;
-#endif
 			default:
 				throw new ArgumentException (InvalidValue);
 			}
@@ -74,15 +62,10 @@ namespace System.Web.Configuration {
 
 		public override object ConvertTo (ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type)
 		{
-#if NET_4_0
-			if ((value == null) || (value.GetType () != typeof (MachineKeyValidation)))
-				throw new ArgumentException (InvalidValue);
-#else
 			if (value.GetType () != typeof (MachineKeyValidation)) {
 				/* MS throws this exception on an invalid */
 				throw new FormatException (InvalidValue);
 			}				
-#endif
 
 			switch ((MachineKeyValidation) value) {
 			case MachineKeyValidation.MD5:
@@ -93,21 +76,9 @@ namespace System.Web.Configuration {
 				return "3DES";
 			case MachineKeyValidation.AES:
 				return "AES";
-#if NET_4_0
-			case MachineKeyValidation.HMACSHA256:
-				return "HMACSHA256";
-			case MachineKeyValidation.HMACSHA384:
-				return "HMACSHA384";
-			case MachineKeyValidation.HMACSHA512:
-				return "HMACSHA512";
-			default:
-				// includes MachineKeyValidation.Custom
-				throw new ArgumentException (InvalidValue);
-#else
 			default:
 				/* MS throws this exception on an invalid */
 				throw new FormatException (InvalidValue);
-#endif
 			}
 		}
 	}
diff --git a/mcs/class/System.Web/System.Web.Handlers/AssemblyResourceLoader.cs b/mcs/class/System.Web/System.Web.Handlers/AssemblyResourceLoader.cs
index 88ce576..f396206 100644
--- a/mcs/class/System.Web/System.Web.Handlers/AssemblyResourceLoader.cs
+++ b/mcs/class/System.Web/System.Web.Handlers/AssemblyResourceLoader.cs
@@ -3,9 +3,10 @@
 //
 // Authors:
 //	Ben Maurer (bmaurer@users.sourceforge.net)
+//	Marek Habersack <grendel@twistedcode.net>
 //
 // (C) 2003 Ben Maurer
-//
+// (C) 2010 Novell, Inc (http://novell.com/)
 
 //
 // Permission is hereby granted, free of charge, to any person obtaining
@@ -34,11 +35,16 @@ using System.Reflection;
 using System.IO;
 using System.Resources;
 using System.Collections;
+using System.Collections.Generic;
+using System.Security.Cryptography;
 using System.Text;
 using System.Text.RegularExpressions;
+using System.Threading;
 using System.Web.Configuration;
+using System.Web.Util;
 
-namespace System.Web.Handlers {
+namespace System.Web.Handlers
+{
 #if SYSTEM_WEB_EXTENSIONS
 	partial class ScriptResourceHandler
 	{
@@ -50,31 +56,69 @@ namespace System.Web.Handlers {
 	#else
 	internal // since this is in the .config file, we need to support it, since we dont have versoned support.
 	#endif
-	class AssemblyResourceLoader : IHttpHandler {		
+	class AssemblyResourceLoader : IHttpHandler
+	{
 		const string HandlerFileName = "WebResource.axd";
 		static Assembly currAsm = typeof (AssemblyResourceLoader).Assembly;
 #endif
 		const char QueryParamSeparator = '&';
-
-		static readonly Hashtable _embeddedResources = Hashtable.Synchronized (new Hashtable ());
-
-		static void InitEmbeddedResourcesUrls (Assembly assembly, Hashtable hashtable)
+#if NET_2_0
+		static readonly Dictionary <string, AssemblyEmbeddedResources> _embeddedResources = new Dictionary <string, AssemblyEmbeddedResources> (StringComparer.Ordinal);
+#else
+		static readonly Hashtable _embeddedResources = new Hashtable ();
+#endif
+		static readonly ReaderWriterLock _embeddedResourcesLock = new ReaderWriterLock ();
+		static string GetStringHash (KeyedHashAlgorithm kha, string str)
+		{
+			if (str == null || str.Length == 0)
+				return String.Empty;
+			
+			return Convert.ToBase64String (kha.ComputeHash (Encoding.UTF8.GetBytes (str)));
+		}
+		
+		static void InitEmbeddedResourcesUrls (KeyedHashAlgorithm kha, Assembly assembly, string assemblyName, string assemblyHash, AssemblyEmbeddedResources entry)
 		{
 			WebResourceAttribute [] attrs = (WebResourceAttribute []) assembly.GetCustomAttributes (typeof (WebResourceAttribute), false);
+			WebResourceAttribute attr;
+			string apath = assembly.Location;
 			for (int i = 0; i < attrs.Length; i++) {
-				string resourceName = attrs [i].WebResource;
-				if (resourceName != null && resourceName.Length > 0) {
+				attr = attrs [i];
+				string resourceName = attr.WebResource;
+				if (resourceName == null || resourceName.Length == 0) {
+					string resourceNameHash = GetStringHash (kha, resourceName);
 #if SYSTEM_WEB_EXTENSIONS
-					ResourceKey rkNoNotify = new ResourceKey (resourceName, false);
-					ResourceKey rkNotify = new ResourceKey (resourceName, true);
+					bool debug = resourceName.EndsWith (".debug.js", StringComparison.OrdinalIgnoreCase);
+					string dbgTail = debug ? "d" : String.Empty;
+					string rkNoNotify = resourceNameHash + "f" + dbgTail;
+					string rkNotify = resourceNameHash + "t" + dbgTail;
 
-					if (!hashtable.Contains (rkNoNotify))
-						hashtable.Add (rkNoNotify, CreateResourceUrl (assembly, resourceName, false));
-					if (!hashtable.Contains (rkNotify))
-						hashtable.Add (rkNotify, CreateResourceUrl (assembly, resourceName, true));
+					if (!entry.Resources.ContainsKey (rkNoNotify)) {
+						var er = new EmbeddedResource () {
+							Name = resourceName,
+							Attribute = attr, 
+							Url = CreateResourceUrl (kha, assemblyName, assemblyHash, apath, rkNoNotify, debug, false)
+						};
+						
+						entry.Resources.Add (rkNoNotify, er);
+					}
+					
+					if (!entry.Resources.ContainsKey (rkNotify)) {
+						var er = new EmbeddedResource () {
+							Name = resourceName,
+							Attribute = attr, 
+							Url = CreateResourceUrl (kha, assemblyName, assemblyHash, apath, rkNotify, debug, true)
+						};
+						
+						entry.Resources.Add (rkNotify, er);
+					}
 #else
-					if (!hashtable.Contains (resourceName))
-						hashtable.Add (resourceName, CreateResourceUrl (assembly, resourceName, false));
+					if (!entry.Resources.ContainsKey (resourceNameHash)) {
+						EmbeddedResource er = new EmbeddedResource ();
+						er.Name = resourceName;
+						er.Attribute = attr;
+						er.Url = CreateResourceUrl (kha, assemblyName, assemblyHash, apath, resourceNameHash, false, false);
+						entry.Resources.Add (resourceNameHash, er);
+					}
 #endif
 				}
 			}
@@ -86,90 +130,155 @@ namespace System.Web.Handlers {
 			return GetResourceUrl (type.Assembly, resourceName, false);
 		}
 #endif
-		static string EncryptAssemblyResource (string asmName, string resName)
+		static EmbeddedResource DecryptAssemblyResource (string val, out AssemblyEmbeddedResources entry)
 		{
-			byte[] bytes = Encoding.UTF8.GetBytes (String.Concat (asmName, ";", resName));
-			bytes = MachineKeySectionUtils.Encrypt (
+			entry = null;
+                       
+			string[] parts = val.Split ('_');
+			if (parts.Length != 3)
+				return null;
+
+			Encoding enc = Encoding.UTF8;
+			string asmNameHash = parts [0];
+			string resNameHash = parts [1];
+			bool debug = parts [2] == "t";
+
+			try {
+				_embeddedResourcesLock.AcquireReaderLock (-1);
+#if NET_2_0				
+				if (!_embeddedResources.TryGetValue (asmNameHash, out entry) || entry == null)
+					return null;
+#else
+				
+				if ((entry = _embeddedResources [asmNameHash] as AssemblyEmbeddedResources) == null)
+					return null;
+#endif
+				EmbeddedResource res;
 #if NET_2_0
-				MachineKeySection.Config,
+				if (!entry.Resources.TryGetValue (resNameHash, out res) || res == null)
 #else
-				MachineKeyConfig.Config,
+				if ((res = entry.Resources [resNameHash] as EmbeddedResource) == null)
 #endif
-				bytes);
-			return Convert.ToBase64String (bytes);
+				{
+#if SYSTEM_WEB_EXTENSIONS
+					if (!debug)
+						return null;
+					if (!entry.Resources.TryGetValue (resNameHash.Substring (0, resNameHash.Length - 1), out res))
+						return null;
+#else
+					return null;
+#endif
+				}
+				return res;
+			} finally {
+				_embeddedResourcesLock.ReleaseReaderLock ();
+			}
 		}
 
-		static void DecryptAssemblyResource (string val, out string asmName, out string resName)
+		internal static string GetResourceUrl (Assembly assembly, string resourceName, bool notifyScriptLoaded)
 		{
-			byte[] bytes = Convert.FromBase64String (val);
-
-			asmName = null;
-			resName = null;			
-
-			byte[] result = MachineKeySectionUtils.Decrypt (
+			if (assembly == null)
+				return String.Empty;
 #if NET_2_0
-				MachineKeySection.Config,
+			MachineKeySection mks = MachineKeySection.Config;
 #else
-				MachineKeyConfig.Config,
+			MachineKeyConfig mks = MachineKeyConfig.Config;
 #endif
-				bytes);
-			bytes = null;
-
-			// null will be returned if, for any reason, decryption fails
-			if (result == null)
-				return;
-
-			string data = Encoding.UTF8.GetString (result);
-			result = null;
-
-			string[] parts = data.Split (';');
-			if (parts.Length != 2)
-				return;
-			
-			asmName = parts [0];
-			resName = parts [1];
+			using (KeyedHashAlgorithm kha = MachineKeySectionUtils.GetValidationAlgorithm (mks)) {
+				kha.Key = MachineKeySectionUtils.GetValidationKey (mks);
+				return GetResourceUrl (kha, assembly, resourceName, notifyScriptLoaded);
+			}
 		}
 
-		internal static string GetResourceUrl (Assembly assembly, string resourceName, bool notifyScriptLoaded)
+		static string GetResourceUrl (KeyedHashAlgorithm kha, Assembly assembly, string resourceName, bool notifyScriptLoaded)
 		{
-			Hashtable hashtable = (Hashtable)_embeddedResources [assembly];
-			if (hashtable == null) {
-				hashtable = new Hashtable ();
-				InitEmbeddedResourcesUrls (assembly, hashtable);
-				_embeddedResources [assembly] = hashtable;
-			}
+			string assemblyName = assembly == currAsm ? "s" : assembly.GetName ().FullName;
+			string assemblyNameHash = GetStringHash (kha, assemblyName);
+			string resourceNameHash = GetStringHash (kha, resourceName);
+			bool debug = false;
+			string url;
+			AssemblyEmbeddedResources entry;
+
+			try {
+				_embeddedResourcesLock.AcquireReaderLock (-1);
+#if NET_2_0
+				if (!_embeddedResources.TryGetValue (assemblyNameHash, out entry) || entry == null)
+#else
+				if ((entry = _embeddedResources [assemblyNameHash] as AssemblyEmbeddedResources) == null)
+#endif
+				{
+					LockCookie lc = new LockCookie ();
+					try {
+						lc = _embeddedResourcesLock.UpgradeToWriterLock (-1);
+						entry = new AssemblyEmbeddedResources ();
+						entry.AssemblyName = assemblyName;
+						InitEmbeddedResourcesUrls (kha, assembly, assemblyName, assemblyNameHash, entry);
+						_embeddedResources.Add (assemblyNameHash, entry);
+					} finally {
+						_embeddedResourcesLock.DowngradeFromWriterLock (ref lc);
+					}
+				}
+				string lookupKey;
 #if SYSTEM_WEB_EXTENSIONS
-			string url = (string) hashtable [new ResourceKey (resourceName, notifyScriptLoaded)];
+				debug = resourceName.EndsWith (".debug.js", StringComparison.OrdinalIgnoreCase);
+				string dbgTail = debug ? "d" : String.Empty;
+				lookupKey = resourceNameHash + (notifyScriptLoaded ? "t" : "f") + dbgTail;
 #else
-			string url = (string) hashtable [resourceName];
+				lookupKey = resourceNameHash;
 #endif
-			if (url == null)
-				url = CreateResourceUrl (assembly, resourceName, notifyScriptLoaded);
-			return url;
+				EmbeddedResource res;
+#if NET_2_0
+				if (entry.Resources.TryGetValue (lookupKey, out res) && res != null)
+#else
+				if ((res = entry.Resources [lookupKey] as EmbeddedResource) != null)
+#endif
+					url = res.Url;
+				else {
+#if SYSTEM_WEB_EXTENSIONS
+					if (debug) {
+						resourceNameHash = GetStringHash (kha, resourceName.Substring (0, resourceName.Length - 9) + ".js");
+						lookupKey = resourceNameHash + (notifyScriptLoaded ? "t" : "f");
+                                       
+						if (entry.Resources.TryGetValue (lookupKey, out res) && res != null)
+							url = res.Url;
+						else
+							url = null;
+					} else
+#endif
+						url = null;
+				}
+			} finally {
+				_embeddedResourcesLock.ReleaseReaderLock ();
+			}
+
+                        if (url == null)
+				url = CreateResourceUrl (kha, assemblyName, assemblyNameHash, assembly.Location, resourceNameHash, debug, notifyScriptLoaded);
+
+                        return url;
 		}
 		
-		static string CreateResourceUrl (Assembly assembly, string resourceName, bool notifyScriptLoaded)
+		static string CreateResourceUrl (KeyedHashAlgorithm kha, string assemblyName, string assemblyNameHash, string assemblyPath, string resourceNameHash, bool debug, bool notifyScriptLoaded)
 		{
-
-			string aname = assembly == currAsm ? "s" : assembly.GetName ().FullName;
-			string apath = assembly.Location;
 			string atime = String.Empty;
 			string extra = String.Empty;
 #if SYSTEM_WEB_EXTENSIONS
-			extra = String.Concat (QueryParamSeparator, "n=", notifyScriptLoaded ? "t" : "f");
+			extra = QueryParamSeparator + "n=" + (notifyScriptLoaded ? "t" : "f");
 #endif
 
 #if TARGET_JVM
-			atime = String.Format ("{0}t={1}", QueryParamSeparator, assembly.GetHashCode ());
+			atime = QueryParamSeparator + "t=" + assemblyName.GetHashCode ();
 #else
-			if (apath != String.Empty)
-				atime = String.Concat (QueryParamSeparator, "t=", File.GetLastWriteTimeUtc (apath).Ticks);
+			if ((assemblyPath != null && assemblyPath.Length > 0) && File.Exists (assemblyPath))
+				atime = QueryParamSeparator + "t=" + File.GetLastWriteTimeUtc (assemblyPath).Ticks;
+			else
+				atime = QueryParamSeparator + "t=" + DateTime.UtcNow.Ticks;
 #endif
-			string href = HandlerFileName + "?d=" + EncryptAssemblyResource (aname, resourceName) + atime + extra;
-
+			string d = assemblyNameHash + "_" + resourceNameHash +  (debug ? "_t" : "_f");
+			string href = HandlerFileName + "?d=" + d + atime + extra;
 			HttpContext ctx = HttpContext.Current;
-			if (ctx != null && ctx.Request != null) {
-				string appPath = VirtualPathUtility.AppendTrailingSlash (ctx.Request.ApplicationPath);
+			HttpRequest req = ctx != null ? ctx.Request : null;
+			if (req != null) {
+				string appPath = VirtualPathUtility.AppendTrailingSlash (req.ApplicationPath);
 				href = appPath + href;
 			}
 			
@@ -180,70 +289,96 @@ namespace System.Web.Handlers {
 #if SYSTEM_WEB_EXTENSIONS
 		protected virtual void ProcessRequest (HttpContext context)
 #else
-		[MonoTODO ("Substitution not implemented")]
 		void System.Web.IHttpHandler.ProcessRequest (HttpContext context)
 #endif
 		{
-			string resourceName;
-			string asmName;
-			Assembly assembly;
+			HttpRequest request = context.Request;
 
-			// val is URL-decoded, which means every + has been replaced with ' ', we
+			// val is URL-encoded, which means every + has been replaced with ' ', we
 			// need to revert that or the base64 conversion will fail.
-			string d = context.Request.QueryString ["d"];
+			string d = request.QueryString ["d"];
 			if (d != null && d.Length > 0)
 				d = d.Replace (' ', '+');
 
-			DecryptAssemblyResource (d, out asmName, out resourceName);
-			if (resourceName == null)
-				throw new HttpException (404, "No resource name given");
-			
-			if (asmName == null || asmName == "s")
+			AssemblyEmbeddedResources entry;
+			EmbeddedResource res = DecryptAssemblyResource (d, out entry);
+			WebResourceAttribute wra = res != null ? res.Attribute : null;
+			if (wra == null)
+				throw new HttpException (404, "Resource not found");
+                       
+			Assembly assembly;
+			if (entry.AssemblyName == "s")
 				assembly = currAsm;
 			else
-				assembly = Assembly.Load (asmName);
+				assembly = Assembly.Load (entry.AssemblyName);
 			
-			WebResourceAttribute wra = null;
-			WebResourceAttribute [] attrs = (WebResourceAttribute []) assembly.GetCustomAttributes (typeof (WebResourceAttribute), false);
-			for (int i = 0; i < attrs.Length; i++) {
-				if (attrs [i].WebResource == resourceName) {
-					wra = attrs [i];
-					break;
-				}
-			}
-#if SYSTEM_WEB_EXTENSIONS
-			if (wra == null && resourceName.Length > 9 && resourceName.EndsWith (".debug.js", StringComparison.OrdinalIgnoreCase)) {
-				resourceName = String.Concat (resourceName.Substring (0, resourceName.Length - 9), ".js");
-				for (int i = 0; i < attrs.Length; i++) {
-					if (attrs [i].WebResource == resourceName) {
-						wra = attrs [i];
-						break;
+			HttpResponse response = context.Response;
+			string req_cache = request.Headers ["Cache-Control"];
+			if (String.Compare (req_cache, "max-age=0"
+#if NET_2_0
+					    , StringComparison.Ordinal
+#endif
+			    ) == 0) {
+				long atime;
+#if NET_2_0
+				if (Int64.TryParse (request.QueryString ["t"], out atime)) {
+#else
+				atime = -1;
+				try {
+					atime = Int64.Parse (request.QueryString ["t"]);
+				} catch {}
+				if (atime > -1) {
+#endif
+					if (atime == File.GetLastWriteTimeUtc (assembly.Location).Ticks) {
+						response.StatusCode = 304;
+						return;
 					}
 				}
 			}
+			string modif_since = request.Headers ["If-Modified-Since"];
+			if (modif_since != null && modif_since.Length > 0) {
+				try {
+					DateTime modif;
+#if NET_2_0
+					if (DateTime.TryParseExact (modif_since, "r", null, 0, out modif))
+#else
+						try {
+							modif = DateTime.Parse (modif_since);
+						} catch {
+							modif = DateTime.MinValue;
+						}
+
+					if (modif != DateTime.MinValue)
 #endif
-			if (wra == null)
-				throw new HttpException (404, String.Concat ("Resource ", resourceName, " not found"));
-			
-			context.Response.ContentType = wra.ContentType;
+					{
+						if (File.GetLastWriteTimeUtc (assembly.Location) <= modif) {
+							response.StatusCode = 304;
+							return;
+						}
+					}
+				} catch {}
+			}
+
+			response.ContentType = wra.ContentType;
 
-			/* tell the client they can cache resources for 1 year */
-			context.Response.ExpiresAbsolute = DateTime.Now.AddYears (1);
-			context.Response.CacheControl = "private";
+			DateTime utcnow = DateTime.UtcNow;
+			response.AddHeader ("Last-Modified", utcnow.ToString ("r"));
+			response.ExpiresAbsolute = utcnow.AddYears (1);
+			response.CacheControl = "public";
 
-			Stream s = assembly.GetManifestResourceStream (resourceName);
+			Stream s = assembly.GetManifestResourceStream (res.Name);
 			if (s == null)
-				throw new HttpException (404, String.Concat ("Resource ", resourceName, " not found"));
+				throw new HttpException (404, "Resource " + res.Name + " not found");
 
 			if (wra.PerformSubstitution) {
 				using (StreamReader r = new StreamReader (s)) {
-					TextWriter w = context.Response.Output;
+					TextWriter w = response.Output;
 					new PerformSubstitutionHelper (assembly).PerformSubstitution (r, w);
 				}
 			}
 			else {
 				byte [] buf = new byte [1024];
-				Stream output = context.Response.OutputStream;
+				Stream output = response.OutputStream;
 				int c;
 				do {
 					c = s.Read (buf, 0, 1024);
@@ -251,9 +386,9 @@ namespace System.Web.Handlers {
 				} while (c > 0);
 			}
 #if SYSTEM_WEB_EXTENSIONS
-			TextWriter writer = context.Response.Output;
+			TextWriter writer = response.Output;
 			foreach (ScriptResourceAttribute sra in assembly.GetCustomAttributes (typeof (ScriptResourceAttribute), false)) {
-				if (sra.ScriptName == resourceName) {
+				if (String.Compare (sra.ScriptName, res.Name, StringComparison.Ordinal) == 0) {
 					string scriptResourceName = sra.ScriptResourceName;
 					ResourceSet rset = null;
 					try {
@@ -282,15 +417,15 @@ namespace System.Web.Handlers {
 						writer.WriteLine ("Type.registerNamespace('" + ns.Substring (0, indx) + "')");
 					writer.Write ("{0}={{", sra.TypeName);
 					bool first = true;
-					foreach (DictionaryEntry entry in rset) {
-						string value = entry.Value as string;
+					foreach (DictionaryEntry de in rset) {
+						string value = de.Value as string;
 						if (value != null) {
 							if (first)
 								first = false;
 							else
 								writer.Write (',');
 							writer.WriteLine ();
-							writer.Write ("{0}:{1}", GetScriptStringLiteral ((string) entry.Key), GetScriptStringLiteral (value));
+							writer.Write ("{0}:{1}", GetScriptStringLiteral ((string) de.Key), GetScriptStringLiteral (value));
 						}
 					}
 					writer.WriteLine ();
@@ -299,7 +434,7 @@ namespace System.Web.Handlers {
 				}
 			}
 
-			bool notifyScriptLoaded = context.Request.QueryString ["n"] == "t";
+			bool notifyScriptLoaded = request.QueryString ["n"] == "t";
 			if (notifyScriptLoaded) {
 				writer.WriteLine ();
 				writer.WriteLine ("if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();");
@@ -339,6 +474,22 @@ namespace System.Web.Handlers {
 #if !SYSTEM_WEB_EXTENSIONS
 		bool System.Web.IHttpHandler.IsReusable { get { return true; } }
 #endif
+		sealed class EmbeddedResource
+		{
+			public string Name;
+			public string Url;
+			public WebResourceAttribute Attribute;
+		}
+		
+		sealed class AssemblyEmbeddedResources
+		{
+			public string AssemblyName = String.Empty;
+#if NET_2_0
+			public Dictionary <string, EmbeddedResource> Resources = new Dictionary <string, EmbeddedResource> (StringComparer.Ordinal);
+#else
+			public Hashtable Resources = new Hashtable ();
+#endif
+		}
 	}
 }
 
diff --git a/mcs/class/System.Web/System.Web.Security/SqlMembershipProvider.cs b/mcs/class/System.Web/System.Web.Security/SqlMembershipProvider.cs
index 1774a87..1350b72 100644
--- a/mcs/class/System.Web/System.Web.Security/SqlMembershipProvider.cs
+++ b/mcs/class/System.Web/System.Web.Security/SqlMembershipProvider.cs
@@ -1050,20 +1050,8 @@ namespace System.Web.Security {
 					string alg_type = section.HashAlgorithmType;
 					if (alg_type.Length == 0) {
 						alg_type = MachineKeySection.Config.Validation.ToString ();
-#if NET_4_0
-						// support new (4.0) custom algorithms
-						if (alg_type.StartsWith ("alg:"))
-							alg_type = alg_type.Substring (4);
-#endif
 					}
 					using (HashAlgorithm hash = HashAlgorithm.Create (alg_type)) {
-#if NET_4_0
-						// for compatibility (with 2.0) we'll allow MD5 and SHA1 not to map to HMACMD5 and HMACSHA1
-						// but that won't work with new (4.0) algorithms, like HMACSHA256|384|512 or custom, won't work without using the key
-						KeyedHashAlgorithm kha = (hash as KeyedHashAlgorithm);
-						if (kha != null)
-							kha.Key = MachineKeySection.Config.GetValidationKey ();
-#endif
 						hash.TransformFinalBlock (hashBytes, 0, hashBytes.Length);
 						return Convert.ToBase64String (hash.Hash);
 					}
diff --git a/mcs/class/System.Web/System.Web.UI/LosFormatter.cs b/mcs/class/System.Web/System.Web.UI/LosFormatter.cs
index 4fdb00b..1f25188 100644
--- a/mcs/class/System.Web/System.Web.UI/LosFormatter.cs
+++ b/mcs/class/System.Web/System.Web.UI/LosFormatter.cs
@@ -96,11 +96,7 @@ namespace System.Web.UI {
 		{
 			if (stream == null)
 				throw new ArgumentNullException ("stream");
-#if NET_4_0
-			using (StreamReader sr = new StreamReader (stream)) {
-				return Deserialize (sr.ReadToEnd ());
-			}
-#else
+
 			long streamLength = -1;
 			if (stream.CanSeek)
 				streamLength = stream.Length;
@@ -121,7 +117,6 @@ namespace System.Web.UI {
 			string b64 = Encoding.ASCII.GetString (ms.GetBuffer (),
 				0, (int) streamLength);
 			return Deserialize (b64);
-#endif
 		}
 
 		public object Deserialize (TextReader input)
@@ -149,10 +144,6 @@ namespace System.Web.UI {
 		{
 			if (stream == null)
 				throw new ArgumentNullException ("stream");
-#if NET_4_0
-			if (!stream.CanSeek)
-				throw new NotSupportedException ();
-#endif
 			string b64 = SerializeToBase64 (value);
 			byte [] bytes = Encoding.ASCII.GetBytes (b64);
 			stream.Write (bytes, 0, bytes.Length);
diff --git a/mcs/class/System.Web/System.Web.Util/MachineKeySectionUtils.cs b/mcs/class/System.Web/System.Web.Util/MachineKeySectionUtils.cs
index 4c95076..80292a9 100644
--- a/mcs/class/System.Web/System.Web.Util/MachineKeySectionUtils.cs
+++ b/mcs/class/System.Web/System.Web.Util/MachineKeySectionUtils.cs
@@ -101,11 +101,6 @@ namespace System.Web.Util {
 				sa = TripleDES.Create ();
 				break;
 			default:
-#if NET_4_0
-				if (name.StartsWith ("alg:"))
-					sa = SymmetricAlgorithm.Create (name.Substring (4));
-				else
-#endif
 				{
 #if NET_2_0
 					throw new ConfigurationErrorsException ();
@@ -113,9 +108,6 @@ namespace System.Web.Util {
 					throw new HttpException ("Unknown encryption algorithm name.");
 #endif
 				}
-#if NET_4_0
-				break;
-#endif
 			}
 			return sa;
 		}
@@ -138,23 +130,11 @@ namespace System.Web.Util {
 #else
 				section.ValidationType
 #endif
-#if NET_4_0
-				, section
-#endif
 			);
 		}
-#if NET_4_0
+
 		public static KeyedHashAlgorithm GetValidationAlgorithm (MachineKeyValidation validation)
 		{
-			return GetValidationAlgorithm (validation, null);
-		}
-#endif
-		public static KeyedHashAlgorithm GetValidationAlgorithm (MachineKeyValidation validation
-#if NET_4_0
-									 , MachineKeySection section
-#endif
-		)
-		{
 			KeyedHashAlgorithm kha = null;
 			switch (validation) {
 			case MachineKeyValidation.MD5:
@@ -169,23 +149,6 @@ namespace System.Web.Util {
 			case MachineKeyValidation.SHA1:
 				kha = new HMACSHA1 ();
 				break;
-#if NET_4_0
-			case MachineKeyValidation.HMACSHA256:
-				kha = new HMACSHA256 ();
-				break;
-			case MachineKeyValidation.HMACSHA384:
-				kha = new HMACSHA384 ();
-				break;
-			case MachineKeyValidation.HMACSHA512:
-				kha = new HMACSHA512 ();
-				break;
-			case MachineKeyValidation.Custom:
-				// remove the "alg:" from the start of the string
-				string algo = section.ValidationAlgorithm;
-				if (algo.StartsWith ("alg:"))
-					kha = KeyedHashAlgorithm.Create (algo.Substring (4));
-				break;
-#endif
 			}
 			return kha;
 		}
@@ -219,7 +182,7 @@ namespace System.Web.Util {
 			return decryption_key;
 		}
 
-		static byte [] GetValidationKey (
+		public static byte [] GetValidationKey (
 #if NET_2_0
 			MachineKeySection section
 #else
@@ -254,7 +217,7 @@ namespace System.Web.Util {
 			return section.GetDecryptionKey ();
 		}
 
-		static byte [] GetValidationKey (
+		internal static byte [] GetValidationKey (
 #if NET_2_0
 			MachineKeySection section
 #else
diff --git a/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeySectionTest.cs b/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeySectionTest.cs
index 4f9fbd5..847aa81 100644
--- a/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeySectionTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeySectionTest.cs
@@ -40,26 +40,14 @@ namespace MonoTests.System.Web.Configuration {
 		public void DefaultValues ()
 		{
 			MachineKeySection section = new MachineKeySection ();
-#if NET_4_0
-			Assert.AreEqual (MachineKeyCompatibilityMode.Framework20SP1, section.CompatibilityMode, "CompatibilityMode");
-#endif
 			Assert.AreEqual ("Auto", section.Decryption, "Decryption");
 			Assert.AreEqual ("AutoGenerate,IsolateApps", section.DecryptionKey, "DecryptionKey");
-#if NET_4_0
-			Assert.AreEqual (MachineKeyValidation.HMACSHA256, section.Validation, "Validation");
-			Assert.AreEqual ("HMACSHA256", section.ValidationAlgorithm, "ValidationAlgorithm");
-#else
 			Assert.AreEqual (MachineKeyValidation.SHA1, section.Validation, "Validation");
-#endif
 			Assert.AreEqual ("AutoGenerate,IsolateApps", section.ValidationKey, "ValidationKey");
 		}
 
 		[Test]
-#if NET_4_0
-		[ExpectedException (typeof (NullReferenceException))]
-#else
 		[ExpectedException (typeof (ConfigurationErrorsException))]
-#endif
 		public void Decryption_Null ()
 		{
 			MachineKeySection section = new MachineKeySection ();
@@ -73,106 +61,6 @@ namespace MonoTests.System.Web.Configuration {
 			MachineKeySection section = new MachineKeySection ();
 			section.Decryption = String.Empty;
 		}
-#if NET_4_0
-		[Test]
-		public void Decryption_RC2 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			Assert.AreEqual ("Auto", section.Decryption, "before");
-
-			section.Decryption = "alg:RC2";
-			Assert.AreEqual ("alg:RC2", section.Decryption, "after");
-		}
-
-		[Test]
-		public void Decryption_InvalidName ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			Assert.AreEqual ("Auto", section.Decryption, "before");
-
-			section.Decryption = "alg:UnexistingType";
-			// looks like the problem is found (much) later
-			Assert.AreEqual ("alg:UnexistingType", section.Decryption, "Decryption");
-		}
-
-		[Test]
-		public void ValidationAlgorithm_Null ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.ValidationAlgorithm = null;
-			Assert.AreEqual ("HMACSHA256", section.ValidationAlgorithm, "ValidationAlgorithm");
-		}
-
-		[Test]
-		[ExpectedException (typeof (ArgumentException))]
-		public void ValidationAlgorithm_Empty ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.ValidationAlgorithm = String.Empty;
-		}
-
-		[Test]
-		[ExpectedException (typeof (ArgumentException))]
-		public void Validation_Custom ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.Custom;
-			// cannot be set directly
-		}
-
-		[Test]
-		public void Validation ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.AES;
-			Assert.AreEqual ("AES", section.ValidationAlgorithm, "AES");
-			section.Validation = MachineKeyValidation.HMACSHA256;
-			Assert.AreEqual ("HMACSHA256", section.ValidationAlgorithm, "HMACSHA256");
-			section.Validation = MachineKeyValidation.HMACSHA384;
-			Assert.AreEqual ("HMACSHA384", section.ValidationAlgorithm, "HMACSHA384");
-			section.Validation = MachineKeyValidation.HMACSHA512;
-			Assert.AreEqual ("HMACSHA512", section.ValidationAlgorithm, "HMACSHA512");
-			section.Validation = MachineKeyValidation.MD5;
-			Assert.AreEqual ("MD5", section.ValidationAlgorithm, "MD5");
-			section.Validation = MachineKeyValidation.SHA1;
-			Assert.AreEqual ("SHA1", section.ValidationAlgorithm, "SHA1");
-			// special case, enum value and algorithm names differs
-			section.Validation = MachineKeyValidation.TripleDES;
-			Assert.AreEqual ("3DES", section.ValidationAlgorithm, "3DES");
-		}
-
-		[Test]
-		[ExpectedException (typeof (ArgumentException))]
-		public void ValidationAlgorithm ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.ValidationAlgorithm = "HMACRIPEMD160";
-			// syntax is: alg:something-deriving-from-KeyedHashAlgorithm
-		}
-
-		[Test]
-		public void ValidationAlgorithm_RIPEMD160 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			Assert.AreEqual (MachineKeyValidation.HMACSHA256, section.Validation, "before");
-
-			section.ValidationAlgorithm = "alg:HMACRIPEMD160";
-			Assert.AreEqual (MachineKeyValidation.Custom, section.Validation, "after");
-			Assert.AreEqual ("alg:HMACRIPEMD160", section.ValidationAlgorithm, "ValidationAlgorithm");
-		}
-
-		[Test]
-		public void ValidationAlgorithm_InvalidName ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			Assert.AreEqual (MachineKeyValidation.HMACSHA256, section.Validation, "before");
-
-			section.ValidationAlgorithm = "alg:UnexistingType";
-			// looks like the problem is found (much) later
-			Assert.AreEqual (MachineKeyValidation.Custom, section.Validation, "after");
-			Assert.AreEqual ("alg:UnexistingType", section.ValidationAlgorithm, "ValidationAlgorithm");
-		}
-#endif
 	}
 }
 
diff --git a/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeyValidationConverterTest.cs b/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeyValidationConverterTest.cs
index 3df6feb..5a2dd7b 100644
--- a/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeyValidationConverterTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.Configuration/MachineKeyValidationConverterTest.cs
@@ -78,27 +78,7 @@ namespace MonoTests.System.Web.Configuration {
 
 			o = cv.ConvertFrom (null, null, "AES");
 			Assert.AreEqual ("AES", o.ToString (), "AES");
-#if NET_4_0
-			o = cv.ConvertFrom (null, null, "HMACSHA256");
-			Assert.AreEqual ("HMACSHA256", o.ToString (), "HMACSHA256");
-
-			o = cv.ConvertFrom (null, null, "HMACSHA384");
-			Assert.AreEqual ("HMACSHA384", o.ToString (), "HMACSHA384");
-
-			o = cv.ConvertFrom (null, null, "HMACSHA512");
-			Assert.AreEqual ("HMACSHA512", o.ToString (), "HMACSHA512");
-#endif
-		}
-
-#if NET_4_0
-		[Test]
-		[ExpectedException (typeof (ArgumentException))]
-		public void ConvertFrom_Custom ()
-		{
-			MachineKeyValidationConverter cv = new MachineKeyValidationConverter ();
-			cv.ConvertFrom (null, null, "Custom");
 		}
-#endif
 
 		[Test]
 		[ExpectedException (typeof (ArgumentException))]
@@ -127,29 +107,11 @@ namespace MonoTests.System.Web.Configuration {
 			Assert.AreEqual ("MD5", cv.ConvertTo (null, null, MachineKeyValidation.MD5, typeof (string)), "A1");
 			Assert.AreEqual ("SHA1", cv.ConvertTo (null, null, MachineKeyValidation.SHA1, typeof (string)), "A2");
 			Assert.AreEqual ("3DES", cv.ConvertTo (null, null, MachineKeyValidation.TripleDES, typeof (string)), "A3");
-#if NET_4_0
-			Assert.AreEqual ("HMACSHA256", cv.ConvertTo (null, null, MachineKeyValidation.HMACSHA256, typeof (string)), "HMACSHA256");
-			Assert.AreEqual ("HMACSHA384", cv.ConvertTo (null, null, MachineKeyValidation.HMACSHA384, typeof (string)), "HMACSHA384");
-			Assert.AreEqual ("HMACSHA512", cv.ConvertTo (null, null, MachineKeyValidation.HMACSHA512, typeof (string)), "HMACSHA512");
-#endif
 		}
 
-#if NET_4_0
 		[Test]
-		[ExpectedException (typeof (ArgumentException))]
-		public void ConvertTo_Custom ()
-		{
-			MachineKeyValidationConverter cv = new MachineKeyValidationConverter ();
-			cv.ConvertTo (null, null, MachineKeyValidation.Custom, typeof (string));
-		}
-#endif
 
-		[Test]
-#if NET_4_0
-		[ExpectedException (typeof (ArgumentException))]
-#else
 		[ExpectedException (typeof (NullReferenceException))]
-#endif
 		public void ConvertTo_NullError ()
 		{
 			MachineKeyValidationConverter cv = new MachineKeyValidationConverter ();
@@ -158,11 +120,7 @@ namespace MonoTests.System.Web.Configuration {
 		}
 
 		[Test]
-#if NET_4_0
-		[ExpectedException (typeof (ArgumentException))]
-#else
 		[ExpectedException (typeof (FormatException))]
-#endif
 		public void ConvertTo_TypeError1 ()
 		{
 			MachineKeyValidationConverter cv = new MachineKeyValidationConverter ();
@@ -180,11 +138,7 @@ namespace MonoTests.System.Web.Configuration {
 		}
 
 		[Test]
-#if NET_4_0
-		[ExpectedException (typeof (ArgumentException))]
-#else
 		[ExpectedException (typeof (FormatException))]
-#endif
 		public void ConvertTo_TypeError3 ()
 		{
 			MachineKeyValidationConverter cv = new MachineKeyValidationConverter ();
diff --git a/mcs/class/System.Web/Test/System.Web.UI/LosFormatterTest.cs b/mcs/class/System.Web/Test/System.Web.UI/LosFormatterTest.cs
index 36e1748..d15f9b7 100644
--- a/mcs/class/System.Web/Test/System.Web.UI/LosFormatterTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.UI/LosFormatterTest.cs
@@ -82,13 +82,9 @@ namespace MonoTests.System.Web.UI
 			byte [] data = Convert.FromBase64String (expected);
 			byte [] signed_data = Convert.FromBase64String (signed);
 			Assert.IsTrue (BitConverter.ToString (signed_data).StartsWith (BitConverter.ToString (data)), "4 / same data");
-#if NET_4_0
-			// 32 bytes == 256 bits -> match HMACSHA256 as default
-			Assert.AreEqual (32, signed_data.Length - data.Length, "signature length");
-#else
+
 			// 20 bytes == 160 bits -> match HMACSHA1 as default
 			Assert.AreEqual (20, signed_data.Length - data.Length, "signature length");
-#endif
 		}
 #endif
 		[Test]
@@ -115,10 +111,7 @@ namespace MonoTests.System.Web.UI
 			byte [] data = Convert.FromBase64String (expected);
 			byte [] signed_data = Convert.FromBase64String (signed);
 			Assert.IsTrue (BitConverter.ToString (signed_data).StartsWith (BitConverter.ToString (data)), "5 / same data");
-#if NET_4_0
-			// 32 bytes == 256 bits -> match HMACSHA256 as default
-			Assert.AreEqual (32, signed_data.Length - data.Length, "signature length");
-#elif NET_2_0
+#if NET_2_0
 			// 20 bytes == 160 bits -> match HMACSHA1 as default
 			Assert.AreEqual (20, signed_data.Length - data.Length, "signature length");
 #else
@@ -171,17 +164,6 @@ namespace MonoTests.System.Web.UI
 			Assert.AreNotEqual (r4, r5, "r4-r5");
 		}
 
-#if NET_4_0
-		[Test]
-		[ExpectedException (typeof (NotSupportedException))]
-		public void Deserialize_Stream_NonSeekable ()
-		{
-			string s1 = "Hello world";
-			NonSeekableStream ns = new NonSeekableStream ();
-			LosFormatter lf = new LosFormatter ();
-			lf.Serialize (ns, s1);
-		}
-#else
 		[Test] // bug #411115
 		public void Deserialize_Stream_NonSeekable ()
 		{
@@ -193,7 +175,7 @@ namespace MonoTests.System.Web.UI
 			string s2 = lf.Deserialize (ns) as string;
 			Assert.AreEqual (s1, s2);
 		}
-#endif
+
 		[Test] // bug #324526
 		public void Serialize ()
 		{
diff --git a/mcs/class/System.Web/Test/System.Web.Util/MachineKeySectionUtilsTest.cs b/mcs/class/System.Web/Test/System.Web.Util/MachineKeySectionUtilsTest.cs
index 75d187f..414b860 100644
--- a/mcs/class/System.Web/Test/System.Web.Util/MachineKeySectionUtilsTest.cs
+++ b/mcs/class/System.Web/Test/System.Web.Util/MachineKeySectionUtilsTest.cs
@@ -92,39 +92,7 @@ namespace MonoTests.System.Web.Configuration {
 			section.Validation = MachineKeyValidation.SHA1;
 			Encrypt_RoundTrip (section);
 		}
-#if NET_4_0
-		[Test]
-		public void Encrypt_RoundTrip_HMACSHA256 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA256;
-			EncryptSign_RoundTrip (section);
-		}
-
-		[Test]
-		public void Encrypt_RoundTrip_HMACSHA384 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA384;
-			EncryptSign_RoundTrip (section);
-		}
 
-		[Test]
-		public void Encrypt_RoundTrip_HMACSHA512 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA512;
-			EncryptSign_RoundTrip (section);
-		}
-
-		[Test]
-		public void Encrypt_RoundTrip_Custom_RIPEMD160 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.ValidationAlgorithm = "alg:HMACRIPEMD160";
-			EncryptSign_RoundTrip (section);
-		}
-#endif
 		public void EncryptSign_RoundTrip (MachineKeySection section)
 		{
 			byte [] data = new byte [14];
@@ -181,39 +149,7 @@ namespace MonoTests.System.Web.Configuration {
 			section.Validation = MachineKeyValidation.SHA1;
 			EncryptSign_RoundTrip (section);
 		}
-#if NET_4_0
-		[Test]
-		public void EncryptSign_RoundTrip_HMACSHA256 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA256;
-			EncryptSign_RoundTrip (section);
-		}
-
-		[Test]
-		public void EncryptSign_RoundTrip_HMACSHA384 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA384;
-			EncryptSign_RoundTrip (section);
-		}
-
-		[Test]
-		public void EncryptSign_RoundTrip_HMACSHA512 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA512;
-			EncryptSign_RoundTrip (section);
-		}
 
-		[Test]
-		public void EncryptSign_RoundTrip_Custom_RIPEMD160 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.ValidationAlgorithm = "alg:HMACRIPEMD160";
-			EncryptSign_RoundTrip (section);
-		}
-#endif
 		public void Validation_RoundTrip (MachineKeySection section)
 		{
 			byte [] data = new byte [] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 };
@@ -267,39 +203,6 @@ namespace MonoTests.System.Web.Configuration {
 			Validation_RoundTrip (section);
 		}
 
-#if NET_4_0
-		[Test]
-		public void Validation_RoundTrip_HMACSHA256 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA256;
-			Validation_RoundTrip (section);
-		}
-
-		[Test]
-		public void Validation_RoundTrip_HMACSHA384 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA384;
-			Validation_RoundTrip (section);
-		}
-
-		[Test]
-		public void Validation_RoundTrip_HMACSHA512 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.Validation = MachineKeyValidation.HMACSHA512;
-			Validation_RoundTrip (section);
-		}
-
-		[Test]
-		public void Validation_RoundTrip_Custom_RIPEMD160 ()
-		{
-			MachineKeySection section = new MachineKeySection ();
-			section.ValidationAlgorithm = "alg:HMACRIPEMD160";
-			Validation_RoundTrip (section);
-		}
-#endif
 		[Test]
 		public void GetHexString ()
 		{
-- 
1.7.3.2

