Home All Groups Group Topic Archive Search About

ClientCertificates and IIS5 with https://localhost

Author
25 Mar 2005 10:03 PM
Michel Gallant
I have seen a number of postings with problems similar to this:

W2k Pro  sp4 fully patched
IIS 5 web service:  ssl enabled; requiring client certificates
Running on same machine as client

Client .NET 1.1 console application in C#:
(certfile is also a valid certificate in CU MY store .. with associated private key available)

.....
X509Certificate jscert = X509Certificate.CreateFromCertFile(certfile);
HttpWebRequest  req = (HttpWebRequest)WebRequest.Create(url);
req.ClientCertificates.Add(jscert);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
... stream response

the url is specified as  https://localhost/somwebpage

but the C# client console application, running as current user, does not appear to have access to
the private key and  the SSL negotation for client certificate fails:

System.Net.WebException: The remote server returned an error: (403) Forbidden.

If I change the host name from "localhost" so "<mymachinename>" (as suggested by a previous
posting) there error message changes to:

System.Net.WebException: The underlying connection was closed: Could not establi sh trust relationship with remote server.

HOWEVER, exactly the same url, accessed from same machine and user context
with IE6 browser does properly raise the private key password access for same certificate.

Any ideas?  I haven't explicitly imported my certificate/pvk into the LocalMachine store (yet)
but I understand that  .NET 1.1 implementation of  req.GetResponse() when an SSL client cert
negotation is required is to (internally) check BOTH CU and LM stores for certificates-with-private-keys
matching the certificate file specified in CreateFromCertFile(certfile).

Are there any TEST SSL servers on the Internet which require client certificate authentication?

- Mitch Gallant

Author
27 Mar 2005 1:08 AM
Michel Gallant
I have done more testing on this and I'm almost certain the problem
is with a .NET 1.1 console application trying to negotiate the SSL handshake for
client-certificate and access to the associated private key in the CU /MY store.
I tried also using openssl  SSL server and same client cert:
  openssl s_server -accept 443  -cert server.pem -Verify 2 -WWW
with essentially identical (failed to provide client certificate) results.
The .NET client console app refuses to send a certificate (yet, IE 6 running
on same machine, using SAME client certificate, works fine with
either IIS 5 or Openssl  running as SSL servers requiring client certs.

Also tried moving the client cert/key to the LM / MY store, but still no success.
Also, installed fresh .NET 1.1 runtime on a clean XP sp2 system,  imported from pfx
the same client cert/key into CU / MY store and ran  the same .NET 1.1 client app
again .. still same problem.

Is there some issue with user profile or impersonation when using a .NET 1.1
console application? The following article discusses this, but for asp.net
applications which is different :
  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secmod/html/secmod27.asp

Here is a very simple .NET 1.1 SSL client code:
   http://www.jensign.com/cryptodev/clientcert.txt

Any suggestions on changes?  Can someone else compile and test this against an SSL server?

Thanks,
- Mitch

Show quoteHide quote
"Michel Gallant" <neut***@istar.ca> wrote in message news:%23IxS2ZYMFHA.1268@TK2MSFTNGP14.phx.gbl...
> I have seen a number of postings with problems similar to this:
>
> W2k Pro  sp4 fully patched
> IIS 5 web service:  ssl enabled; requiring client certificates
> Running on same machine as client
>
> Client .NET 1.1 console application in C#:
>  (certfile is also a valid certificate in CU MY store .. with associated private key available)
>
>  .....
>  X509Certificate jscert = X509Certificate.CreateFromCertFile(certfile);
>  HttpWebRequest  req = (HttpWebRequest)WebRequest.Create(url);
>  req.ClientCertificates.Add(jscert);
>  HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
>  ... stream response
>
> the url is specified as  https://localhost/somwebpage
>
> but the C# client console application, running as current user, does not appear to have access to
> the private key and  the SSL negotation for client certificate fails:
>
> System.Net.WebException: The remote server returned an error: (403) Forbidden.
>
> If I change the host name from "localhost" so "<mymachinename>" (as suggested by a previous
> posting) there error message changes to:
>
> System.Net.WebException: The underlying connection was closed: Could not establi sh trust relationship with remote server.
>
> HOWEVER, exactly the same url, accessed from same machine and user context
> with IE6 browser does properly raise the private key password access for same certificate.
>
> Any ideas?  I haven't explicitly imported my certificate/pvk into the LocalMachine store (yet)
> but I understand that  .NET 1.1 implementation of  req.GetResponse() when an SSL client cert
> negotation is required is to (internally) check BOTH CU and LM stores for certificates-with-private-keys
> matching the certificate file specified in CreateFromCertFile(certfile).
>
> Are there any TEST SSL servers on the Internet which require client certificate authentication?
>
> - Mitch Gallant
>
>
Author
27 Mar 2005 7:50 PM
Michel Gallant
With the kind help of Joe Kaplan, I think we have made some
progress on this problem. Joe was looking at .NET code with
Reflector and noticed that the CryptAcquireCertificatePrivateKey()
call  was using a "silent" flag!

This suggested that a call to access a client cert with *Strong* protection
(i.e. password protected access via DPAPI to private key) would fail.
So, I removed my client cert from CU / MY store (which I always protect with
Strong import protection) and reimported without the extra pswd protection and
VOILA ... the .NET client works properly.

So, the upshot of this is that it appears that the .NET 1.1 sp1 underlying class
implementation of the following code, for a SSL request to an SSL server requiring client-certificate :

   req.ClientCertificates.Add(jscert);
   resp = (HttpWebResponse)req.GetResponse();

will fail, if the private key access for jscert is password protected (i.e. Strong
protection on import).
It is easy to understand why this may have been implemented (for asp.net processes where
no UI is available).
Further, the client cert (and matching private key) must be loaded to the Current User
store (and NOT the Local Machine store).

So this clearly calls for better documentation on the ClientCertificates.Add and
HttpWebResponse.GetResponse() methods for the case of SSL with required client
certificates. Specifically,  how the .NET underlying implementation has changed
with release level:

  .NET 1.0
  .NET 1.1
  .NET 1.1 sp1
  .NET 2.0  beta

I noticed via google searches that some earlier postings *did* report seeing the password
dialogs.  So it would be interesting to note what .NET fcl those were using .. e.g.
http://groups-beta.google.com/group/microsoft.public.dotnet.framework/browse_frm/thread/2b51994cc7d4e9b4/732dc492b164eb31?q=ClientCertificates++HttpWebResponse+group:microsoft.public.dotnet.*&rnum=5#732dc492b164eb31

Cheers,
- Mitch Gallant
   MVP Security
   www.jensign.com


Show quoteHide quote
"Michel Gallant" <neut***@istar.ca> wrote in message news:uIIhdlmMFHA.1392@TK2MSFTNGP10.phx.gbl...
> I have done more testing on this and I'm almost certain the problem
> is with a .NET 1.1 console application trying to negotiate the SSL handshake for
> client-certificate and access to the associated private key in the CU /MY store.
> I tried also using openssl  SSL server and same client cert:
>   openssl s_server -accept 443  -cert server.pem -Verify 2 -WWW
> with essentially identical (failed to provide client certificate) results.
> The .NET client console app refuses to send a certificate (yet, IE 6 running
> on same machine, using SAME client certificate, works fine with
> either IIS 5 or Openssl  running as SSL servers requiring client certs.
>
> Also tried moving the client cert/key to the LM / MY store, but still no success.
> Also, installed fresh .NET 1.1 runtime on a clean XP sp2 system,  imported from pfx
> the same client cert/key into CU / MY store and ran  the same .NET 1.1 client app
> again .. still same problem.
>
> Is there some issue with user profile or impersonation when using a .NET 1.1
> console application? The following article discusses this, but for asp.net
> applications which is different :
>   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secmod/html/secmod27.asp
>
> Here is a very simple .NET 1.1 SSL client code:
>    http://www.jensign.com/cryptodev/clientcert.txt
>
> Any suggestions on changes?  Can someone else compile and test this against an SSL server?
>
> Thanks,
>  - Mitch
>
> "Michel Gallant" <neut***@istar.ca> wrote in message news:%23IxS2ZYMFHA.1268@TK2MSFTNGP14.phx.gbl...
> > I have seen a number of postings with problems similar to this:
> >
> > W2k Pro  sp4 fully patched
> > IIS 5 web service:  ssl enabled; requiring client certificates
> > Running on same machine as client
> >
> > Client .NET 1.1 console application in C#:
> >  (certfile is also a valid certificate in CU MY store .. with associated private key available)
> >
> >  .....
> >  X509Certificate jscert = X509Certificate.CreateFromCertFile(certfile);
> >  HttpWebRequest  req = (HttpWebRequest)WebRequest.Create(url);
> >  req.ClientCertificates.Add(jscert);
> >  HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
> >  ... stream response
> >
> > the url is specified as  https://localhost/somwebpage
> >
> > but the C# client console application, running as current user, does not appear to have access to
> > the private key and  the SSL negotation for client certificate fails:
> >
> > System.Net.WebException: The remote server returned an error: (403) Forbidden.
> >
> > If I change the host name from "localhost" so "<mymachinename>" (as suggested by a previous
> > posting) there error message changes to:
> >
> > System.Net.WebException: The underlying connection was closed: Could not establi sh trust relationship with remote server.
> >
> > HOWEVER, exactly the same url, accessed from same machine and user context
> > with IE6 browser does properly raise the private key password access for same certificate.
> >
> > Any ideas?  I haven't explicitly imported my certificate/pvk into the LocalMachine store (yet)
> > but I understand that  .NET 1.1 implementation of  req.GetResponse() when an SSL client cert
> > negotation is required is to (internally) check BOTH CU and LM stores for certificates-with-private-keys
> > matching the certificate file specified in CreateFromCertFile(certfile).
> >
> > Are there any TEST SSL servers on the Internet which require client certificate authentication?
> >
> > - Mitch Gallant
> >
> >
>
>
Author
28 Mar 2005 2:40 PM
Joe Kaplan (MVP - ADSI)
I would also be curious to find out whether it is really possible to get 1.1
SP1 to allow a client certificate to be used from the machine store.  Based
on my examination of the code, it would appear that the prevalidation of
client certificates only runs against the MY store.

Can anyone verify?

Joe K.

Show quoteHide quote
"Michel Gallant" <neut***@istar.ca> wrote in message
news:%239o4AZwMFHA.508@TK2MSFTNGP12.phx.gbl...
> With the kind help of Joe Kaplan, I think we have made some
> progress on this problem. Joe was looking at .NET code with
> Reflector and noticed that the CryptAcquireCertificatePrivateKey()
> call  was using a "silent" flag!
>
> This suggested that a call to access a client cert with *Strong*
> protection
> (i.e. password protected access via DPAPI to private key) would fail.
> So, I removed my client cert from CU / MY store (which I always protect
> with
> Strong import protection) and reimported without the extra pswd protection
> and
> VOILA ... the .NET client works properly.
>
> So, the upshot of this is that it appears that the .NET 1.1 sp1 underlying
> class
> implementation of the following code, for a SSL request to an SSL server
> requiring client-certificate :
>
>   req.ClientCertificates.Add(jscert);
>   resp = (HttpWebResponse)req.GetResponse();
>
> will fail, if the private key access for jscert is password protected
> (i.e. Strong
> protection on import).
> It is easy to understand why this may have been implemented (for asp.net
> processes where
> no UI is available).
> Further, the client cert (and matching private key) must be loaded to the
> Current User
> store (and NOT the Local Machine store).
>
> So this clearly calls for better documentation on the
> ClientCertificates.Add and
> HttpWebResponse.GetResponse() methods for the case of SSL with required
> client
> certificates. Specifically,  how the .NET underlying implementation has
> changed
> with release level:
>
>  .NET 1.0
>  .NET 1.1
>  .NET 1.1 sp1
>  .NET 2.0  beta
>
> I noticed via google searches that some earlier postings *did* report
> seeing the password
> dialogs.  So it would be interesting to note what .NET fcl those were
> using .. e.g.
> http://groups-beta.google.com/group/microsoft.public.dotnet.framework/browse_frm/thread/2b51994cc7d4e9b4/732dc492b164eb31?q=ClientCertificates++HttpWebResponse+group:microsoft.public.dotnet.*&rnum=5#732dc492b164eb31
>
> Cheers,
> - Mitch Gallant
>   MVP Security
>   www.jensign.com
>
>
> "Michel Gallant" <neut***@istar.ca> wrote in message
> news:uIIhdlmMFHA.1392@TK2MSFTNGP10.phx.gbl...
>> I have done more testing on this and I'm almost certain the problem
>> is with a .NET 1.1 console application trying to negotiate the SSL
>> handshake for
>> client-certificate and access to the associated private key in the CU /MY
>> store.
>> I tried also using openssl  SSL server and same client cert:
>>   openssl s_server -accept 443  -cert server.pem -Verify 2 -WWW
>> with essentially identical (failed to provide client certificate)
>> results.
>> The .NET client console app refuses to send a certificate (yet, IE 6
>> running
>> on same machine, using SAME client certificate, works fine with
>> either IIS 5 or Openssl  running as SSL servers requiring client certs.
>>
>> Also tried moving the client cert/key to the LM / MY store, but still no
>> success.
>> Also, installed fresh .NET 1.1 runtime on a clean XP sp2 system,
>> imported from pfx
>> the same client cert/key into CU / MY store and ran  the same .NET 1.1
>> client app
>> again .. still same problem.
>>
>> Is there some issue with user profile or impersonation when using a .NET
>> 1.1
>> console application? The following article discusses this, but for
>> asp.net
>> applications which is different :
>>
>> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secmod/html/secmod27.asp
>>
>> Here is a very simple .NET 1.1 SSL client code:
>>    http://www.jensign.com/cryptodev/clientcert.txt
>>
>> Any suggestions on changes?  Can someone else compile and test this
>> against an SSL server?
>>
>> Thanks,
>>  - Mitch
>>
>> "Michel Gallant" <neut***@istar.ca> wrote in message
>> news:%23IxS2ZYMFHA.1268@TK2MSFTNGP14.phx.gbl...
>> > I have seen a number of postings with problems similar to this:
>> >
>> > W2k Pro  sp4 fully patched
>> > IIS 5 web service:  ssl enabled; requiring client certificates
>> > Running on same machine as client
>> >
>> > Client .NET 1.1 console application in C#:
>> >  (certfile is also a valid certificate in CU MY store .. with
>> > associated private key available)
>> >
>> >  .....
>> >  X509Certificate jscert = X509Certificate.CreateFromCertFile(certfile);
>> >  HttpWebRequest  req = (HttpWebRequest)WebRequest.Create(url);
>> >  req.ClientCertificates.Add(jscert);
>> >  HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
>> >  ... stream response
>> >
>> > the url is specified as  https://localhost/somwebpage
>> >
>> > but the C# client console application, running as current user, does
>> > not appear to have access to
>> > the private key and  the SSL negotation for client certificate fails:
>> >
>> > System.Net.WebException: The remote server returned an error: (403)
>> > Forbidden.
>> >
>> > If I change the host name from "localhost" so "<mymachinename>" (as
>> > suggested by a previous
>> > posting) there error message changes to:
>> >
>> > System.Net.WebException: The underlying connection was closed: Could
>> > not establi sh trust relationship with remote server.
>> >
>> > HOWEVER, exactly the same url, accessed from same machine and user
>> > context
>> > with IE6 browser does properly raise the private key password access
>> > for same certificate.
>> >
>> > Any ideas?  I haven't explicitly imported my certificate/pvk into the
>> > LocalMachine store (yet)
>> > but I understand that  .NET 1.1 implementation of  req.GetResponse()
>> > when an SSL client cert
>> > negotation is required is to (internally) check BOTH CU and LM stores
>> > for certificates-with-private-keys
>> > matching the certificate file specified in
>> > CreateFromCertFile(certfile).
>> >
>> > Are there any TEST SSL servers on the Internet which require client
>> > certificate authentication?
>> >
>> > - Mitch Gallant
>> >
>> >
>>
>>
>
>
Author
28 Mar 2005 4:35 PM
Michel Gallant
Based on my testing, looks like not .. at least for a client application
using .NET 1.1 sp1.
I removed my clientt cert, reinstalled it in LM / MY store (which of course
does NOT allow importing with Strong protection) and ..
the client application (running as current user) does not recognize that certificate.
This is also how  IE operates for SSL client-cert-required scenarios .. if you
have several acceptable SSL client certificate, IE pops you a "select cert" dialog,
but the certs are ONLY selected from the CU/MY store  .. not the LM store.

However, for an asp.net application, the situation is probably different depending
on what user context is loaded and underlying .NET code implemention.

However, I must say that imo client-certs for SSL SHOULD be strongly protected.
Why?  well these certs would typically also be used for signed and encrypted email,
and I personally don't want to provide all processes, running as my user context to
have access to that private key without my explicit requesting (i.e. Strong protection
with password prompting).

- Mitch


Show quoteHide quote
"Joe Kaplan (MVP - ADSI)" <joseph.e.kap***@removethis.accenture.com> wrote in message news:%23P8gVQ6MFHA.164@TK2MSFTNGP12.phx.gbl...
> I would also be curious to find out whether it is really possible to get 1.1
> SP1 to allow a client certificate to be used from the machine store.  Based
> on my examination of the code, it would appear that the prevalidation of
> client certificates only runs against the MY store.
>
> Can anyone verify?
>
> Joe K.
>
> "Michel Gallant" <neut***@istar.ca> wrote in message
> news:%239o4AZwMFHA.508@TK2MSFTNGP12.phx.gbl...
> > With the kind help of Joe Kaplan, I think we have made some
> > progress on this problem. Joe was looking at .NET code with
> > Reflector and noticed that the CryptAcquireCertificatePrivateKey()
> > call  was using a "silent" flag!
> >
> > This suggested that a call to access a client cert with *Strong*
> > protection
> > (i.e. password protected access via DPAPI to private key) would fail.
> > So, I removed my client cert from CU / MY store (which I always protect
> > with
> > Strong import protection) and reimported without the extra pswd protection
> > and
> > VOILA ... the .NET client works properly.
> >
> > So, the upshot of this is that it appears that the .NET 1.1 sp1 underlying
> > class
> > implementation of the following code, for a SSL request to an SSL server
> > requiring client-certificate :
> >
> >   req.ClientCertificates.Add(jscert);
> >   resp = (HttpWebResponse)req.GetResponse();
> >
> > will fail, if the private key access for jscert is password protected
> > (i.e. Strong
> > protection on import).
> > It is easy to understand why this may have been implemented (for asp.net
> > processes where
> > no UI is available).
> > Further, the client cert (and matching private key) must be loaded to the
> > Current User
> > store (and NOT the Local Machine store).
> >
> > So this clearly calls for better documentation on the
> > ClientCertificates.Add and
> > HttpWebResponse.GetResponse() methods for the case of SSL with required
> > client
> > certificates. Specifically,  how the .NET underlying implementation has
> > changed
> > with release level:
> >
> >  .NET 1.0
> >  .NET 1.1
> >  .NET 1.1 sp1
> >  .NET 2.0  beta
> >
> > I noticed via google searches that some earlier postings *did* report
> > seeing the password
> > dialogs.  So it would be interesting to note what .NET fcl those were
> > using .. e.g.
> >
http://groups-beta.google.com/group/microsoft.public.dotnet.framework/browse_frm/thread/2b51994cc7d4e9b4/732dc492b164eb31?q=ClientCertificates++HttpWebResponse+group:microsoft.public.dotnet.*&rnum=5#732dc492b164eb31
Show quoteHide quote
> >
> > Cheers,
> > - Mitch Gallant
> >   MVP Security
> >   www.jensign.com
> >
> >
> > "Michel Gallant" <neut***@istar.ca> wrote in message
> > news:uIIhdlmMFHA.1392@TK2MSFTNGP10.phx.gbl...
> >> I have done more testing on this and I'm almost certain the problem
> >> is with a .NET 1.1 console application trying to negotiate the SSL
> >> handshake for
> >> client-certificate and access to the associated private key in the CU /MY
> >> store.
> >> I tried also using openssl  SSL server and same client cert:
> >>   openssl s_server -accept 443  -cert server.pem -Verify 2 -WWW
> >> with essentially identical (failed to provide client certificate)
> >> results.
> >> The .NET client console app refuses to send a certificate (yet, IE 6
> >> running
> >> on same machine, using SAME client certificate, works fine with
> >> either IIS 5 or Openssl  running as SSL servers requiring client certs.
> >>
> >> Also tried moving the client cert/key to the LM / MY store, but still no
> >> success.
> >> Also, installed fresh .NET 1.1 runtime on a clean XP sp2 system,
> >> imported from pfx
> >> the same client cert/key into CU / MY store and ran  the same .NET 1.1
> >> client app
> >> again .. still same problem.
> >>
> >> Is there some issue with user profile or impersonation when using a .NET
> >> 1.1
> >> console application? The following article discusses this, but for
> >> asp.net
> >> applications which is different :
> >>
> >> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secmod/html/secmod27.asp
> >>
> >> Here is a very simple .NET 1.1 SSL client code:
> >>    http://www.jensign.com/cryptodev/clientcert.txt
> >>
> >> Any suggestions on changes?  Can someone else compile and test this
> >> against an SSL server?
> >>
> >> Thanks,
> >>  - Mitch
> >>
> >> "Michel Gallant" <neut***@istar.ca> wrote in message
> >> news:%23IxS2ZYMFHA.1268@TK2MSFTNGP14.phx.gbl...
> >> > I have seen a number of postings with problems similar to this:
> >> >
> >> > W2k Pro  sp4 fully patched
> >> > IIS 5 web service:  ssl enabled; requiring client certificates
> >> > Running on same machine as client
> >> >
> >> > Client .NET 1.1 console application in C#:
> >> >  (certfile is also a valid certificate in CU MY store .. with
> >> > associated private key available)
> >> >
> >> >  .....
> >> >  X509Certificate jscert = X509Certificate.CreateFromCertFile(certfile);
> >> >  HttpWebRequest  req = (HttpWebRequest)WebRequest.Create(url);
> >> >  req.ClientCertificates.Add(jscert);
> >> >  HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
> >> >  ... stream response
> >> >
> >> > the url is specified as  https://localhost/somwebpage
> >> >
> >> > but the C# client console application, running as current user, does
> >> > not appear to have access to
> >> > the private key and  the SSL negotation for client certificate fails:
> >> >
> >> > System.Net.WebException: The remote server returned an error: (403)
> >> > Forbidden.
> >> >
> >> > If I change the host name from "localhost" so "<mymachinename>" (as
> >> > suggested by a previous
> >> > posting) there error message changes to:
> >> >
> >> > System.Net.WebException: The underlying connection was closed: Could
> >> > not establi sh trust relationship with remote server.
> >> >
> >> > HOWEVER, exactly the same url, accessed from same machine and user
> >> > context
> >> > with IE6 browser does properly raise the private key password access
> >> > for same certificate.
> >> >
> >> > Any ideas?  I haven't explicitly imported my certificate/pvk into the
> >> > LocalMachine store (yet)
> >> > but I understand that  .NET 1.1 implementation of  req.GetResponse()
> >> > when an SSL client cert
> >> > negotation is required is to (internally) check BOTH CU and LM stores
> >> > for certificates-with-private-keys
> >> > matching the certificate file specified in
> >> > CreateFromCertFile(certfile).
> >> >
> >> > Are there any TEST SSL servers on the Internet which require client
> >> > certificate authentication?
> >> >
> >> > - Mitch Gallant
> >> >
> >> >
> >>
> >>
> >
> >
>
>
Author
31 Mar 2005 12:32 AM
Michel Gallant
Installed .NET 2.0 Framework beta 1 on XP-sp2 system, recompiled C# source
and ran the console app. to check for client-certificate implementation:

- for imported client cert with Strong protection, a DPAPI native
   dialog DOES appear, and SSL client-cert required connection succeeds

-  .NET 1.1 sp1 compiled code, on same XP-sp2, executed against .NET 1.1 sp1 FCL,
    fails (as described below) with 403 Forbidden, for Strong protected keys.

- Mitch

Show quoteHide quote
"Michel Gallant" <neut***@istar.ca> wrote in message news:%239o4AZwMFHA.508@TK2MSFTNGP12.phx.gbl...
> With the kind help of Joe Kaplan, I think we have made some
> progress on this problem. Joe was looking at .NET code with
> Reflector and noticed that the CryptAcquireCertificatePrivateKey()
> call  was using a "silent" flag!
>
> This suggested that a call to access a client cert with *Strong* protection
> (i.e. password protected access via DPAPI to private key) would fail.
> So, I removed my client cert from CU / MY store (which I always protect with
> Strong import protection) and reimported without the extra pswd protection and
> VOILA ... the .NET client works properly.
>
> So, the upshot of this is that it appears that the .NET 1.1 sp1 underlying class
> implementation of the following code, for a SSL request to an SSL server requiring client-certificate :
>
>    req.ClientCertificates.Add(jscert);
>    resp = (HttpWebResponse)req.GetResponse();
>
> will fail, if the private key access for jscert is password protected (i.e. Strong
> protection on import).
> It is easy to understand why this may have been implemented (for asp.net processes where
> no UI is available).
> Further, the client cert (and matching private key) must be loaded to the Current User
> store (and NOT the Local Machine store).
>
> So this clearly calls for better documentation on the ClientCertificates.Add and
> HttpWebResponse.GetResponse() methods for the case of SSL with required client
> certificates. Specifically,  how the .NET underlying implementation has changed
> with release level:
>
>   .NET 1.0
>   .NET 1.1
>   .NET 1.1 sp1
>   .NET 2.0  beta
>
> I noticed via google searches that some earlier postings *did* report seeing the password
> dialogs.  So it would be interesting to note what .NET fcl those were using .. e.g.
>
http://groups-beta.google.com/group/microsoft.public.dotnet.framework/browse_frm/thread/2b51994cc7d4e9b4/732dc492b164eb31?q=ClientCertificates++HttpWebResponse+group:microsoft.public.dotnet.*&rnum=5#732dc492b164eb31
Show quoteHide quote
>
> Cheers,
>  - Mitch Gallant
>    MVP Security
>    www.jensign.com
>
>
> "Michel Gallant" <neut***@istar.ca> wrote in message news:uIIhdlmMFHA.1392@TK2MSFTNGP10.phx.gbl...
> > I have done more testing on this and I'm almost certain the problem
> > is with a .NET 1.1 console application trying to negotiate the SSL handshake for
> > client-certificate and access to the associated private key in the CU /MY store.
> > I tried also using openssl  SSL server and same client cert:
> >   openssl s_server -accept 443  -cert server.pem -Verify 2 -WWW
> > with essentially identical (failed to provide client certificate) results.
> > The .NET client console app refuses to send a certificate (yet, IE 6 running
> > on same machine, using SAME client certificate, works fine with
> > either IIS 5 or Openssl  running as SSL servers requiring client certs.
> >
> > Also tried moving the client cert/key to the LM / MY store, but still no success.
> > Also, installed fresh .NET 1.1 runtime on a clean XP sp2 system,  imported from pfx
> > the same client cert/key into CU / MY store and ran  the same .NET 1.1 client app
> > again .. still same problem.
> >
> > Is there some issue with user profile or impersonation when using a .NET 1.1
> > console application? The following article discusses this, but for asp.net
> > applications which is different :
> >   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secmod/html/secmod27.asp
> >
> > Here is a very simple .NET 1.1 SSL client code:
> >    http://www.jensign.com/cryptodev/clientcert.txt
> >
> > Any suggestions on changes?  Can someone else compile and test this against an SSL server?
> >
> > Thanks,
> >  - Mitch
> >
> > "Michel Gallant" <neut***@istar.ca> wrote in message news:%23IxS2ZYMFHA.1268@TK2MSFTNGP14.phx.gbl...
> > > I have seen a number of postings with problems similar to this:
> > >
> > > W2k Pro  sp4 fully patched
> > > IIS 5 web service:  ssl enabled; requiring client certificates
> > > Running on same machine as client
> > >
> > > Client .NET 1.1 console application in C#:
> > >  (certfile is also a valid certificate in CU MY store .. with associated private key available)
> > >
> > >  .....
> > >  X509Certificate jscert = X509Certificate.CreateFromCertFile(certfile);
> > >  HttpWebRequest  req = (HttpWebRequest)WebRequest.Create(url);
> > >  req.ClientCertificates.Add(jscert);
> > >  HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
> > >  ... stream response
> > >
> > > the url is specified as  https://localhost/somwebpage
> > >
> > > but the C# client console application, running as current user, does not appear to have access to
> > > the private key and  the SSL negotation for client certificate fails:
> > >
> > > System.Net.WebException: The remote server returned an error: (403) Forbidden.
> > >
> > > If I change the host name from "localhost" so "<mymachinename>" (as suggested by a previous
> > > posting) there error message changes to:
> > >
> > > System.Net.WebException: The underlying connection was closed: Could not establi sh trust relationship with remote server.
> > >
> > > HOWEVER, exactly the same url, accessed from same machine and user context
> > > with IE6 browser does properly raise the private key password access for same certificate.
> > >
> > > Any ideas?  I haven't explicitly imported my certificate/pvk into the LocalMachine store (yet)
> > > but I understand that  .NET 1.1 implementation of  req.GetResponse() when an SSL client cert
> > > negotation is required is to (internally) check BOTH CU and LM stores for certificates-with-private-keys
> > > matching the certificate file specified in CreateFromCertFile(certfile).
> > >
> > > Are there any TEST SSL servers on the Internet which require client certificate authentication?
> > >
> > > - Mitch Gallant
> > >
> > >
> >
> >
>
>
Author
31 Mar 2005 4:49 AM
Joe Kaplan (MVP - ADSI)
This is good news.  Let's try again with the new beta and make sure it stays
that way.  I'd really like to hear MS comment on this as the change in 1.1
SP1 does seem to break some common scenarios.

Joe K.

Show quoteHide quote
"Michel Gallant" <neut***@istar.ca> wrote in message
news:%23xsEwkYNFHA.1476@TK2MSFTNGP09.phx.gbl...
> Installed .NET 2.0 Framework beta 1 on XP-sp2 system, recompiled C# source
> and ran the console app. to check for client-certificate implementation:
>
> - for imported client cert with Strong protection, a DPAPI native
>   dialog DOES appear, and SSL client-cert required connection succeeds
>
> -  .NET 1.1 sp1 compiled code, on same XP-sp2, executed against .NET 1.1
> sp1 FCL,
>    fails (as described below) with 403 Forbidden, for Strong protected
> keys.
>
> - Mitch
>