I found the problem and the solution.
The webservice uses an X509Certificate2 Certificate. The X509Certificate2 class constructors attempt to import the certificate into the user profile of the user account that the application runs in. Many times, ASP.NET and COM+ applications impersonate clients. When they do, they do not load the user profiles for the impersonated user for performance reasons. So, they cannot access the "User" certificate store for the impersonated user.
The same code will work when run from an interactive application or a Windows service that is running under a user account because the profile is loaded when the user is logged on or the service started.
An administrator on the machine where the ASP.NET/COM+ application runs should install the certificate in the machine certificate store, called the "Local Computer" store. This should be done when the ASP.NET/COM+ application is installed.
The administrator should set the permissions on the private key associated with the certificate to give the ASP.NET process and the impersonated users access to the key. This is needed because only the user account that installs the certificate or private key in the "Local Computer" store can later use the RSA private key associated with the certificate. Use WinHttpCertCfg.exe available from the Windows Resource Kit Tools (http://msdn2.microsoft.com/en-us/library/aa384088.aspx (http://msdn2.microsoft.com/en-us/library/aa384088.aspx) ) to configure the permissions.
The ASP.NET/COM+ application code should use the installed certificate rather than attempt to install one from a PFX file. Have the code locate the installed certificate using X509Store class.
See http://support.microsoft.com/kb/948154 for more information.